fix wasm, flutter work

This commit is contained in:
John Smith 2022-01-20 22:32:22 -05:00
parent effc4aeeac
commit 2eeb8e52f2
11 changed files with 4588 additions and 180 deletions

View File

@ -1,5 +1,7 @@
use super::utils;
use crate::xx::*;
use crate::*;
use data_encoding::BASE64URL_NOPAD;
use js_sys::*;
use wasm_bindgen_futures::*;
use web_sys::*;
@ -14,172 +16,246 @@ extern "C" {
fn keytar_deletePassword(service: &str, account: &str) -> Result<Promise, JsValue>;
}
fn keyring_name(namespace: &str) -> String {
if namespace.len() == 0 {
"veilid".to_owned()
} else {
format!("veilid_{}", namespace)
}
#[derive(Clone)]
pub struct ProtectedStore {
config: VeilidConfig,
}
fn browser_key_name(namespace: &str, key: &str) -> String {
if namespace.len() == 0 {
format!("__veilid_secret_{}", key)
} else {
format!("__veilid_{}_secret_{}", namespace, key)
}
}
impl ProtectedStore {
pub async fn save_user_secret_string(
namespace: &str,
key: &str,
value: &str,
) -> Result<bool, String> {
if utils::is_nodejs() {
let prev = match JsFuture::from(
keytar_getPassword(keyring_name(namespace).as_str(), key)
.map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(v) => v.is_truthy(),
Err(_) => false,
pub fn new(config: VeilidConfig) -> Self {
Self {
config,
}
}
pub async fn delete_all(&self) -> Result<(), String> {
// Delete all known keys
if self.remove_user_secret_string("node_id").await? {
debug!("deleted protected_store key 'node_id'");
}
if self.remove_user_secret_string("node_id_secret").await? {
debug!("deleted protected_store key 'node_id_secret'");
}
if self.remove_user_secret_string("_test_key").await? {
debug!("deleted protected_store key '_test_key'");
}
Ok(())
}
pub async fn init(&self) -> Result<(), String> {
Ok(())
}
pub async fn terminate(&self) {}
fn keyring_name(&self) -> String {
let c = self.config.get();
if c.namespace.is_empty() {
"veilid_protected_store".to_owned()
} else {
format!("veilid_protected_store_{}", c.namespace)
}
}
fn browser_key_name(&self, key: &str) -> String {
let c = self.config.get();
if c.namespace.is_empty() {
format!("__veilid_protected_store_{}", key)
} else {
format!("__veilid_protected_store_{}_{}", c.namespace, key)
}
}
pub async fn save_user_secret_string(&self, key: &str, value: &str) -> Result<bool, String> {
if utils::is_nodejs() {
let prev = match JsFuture::from(
keytar_getPassword(self.keyring_name().as_str(), key)
.map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(v) => v.is_truthy(),
Err(_) => false,
};
match JsFuture::from(
keytar_setPassword(self.keyring_name().as_str(), key, value)
.map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(_) => {}
Err(_) => return Err("Failed to set password".to_owned()),
}
Ok(prev)
} else if utils::is_browser() {
let win = match window() {
Some(w) => w,
None => {
return Err("failed to get window".to_owned());
}
};
let ls = match win
.local_storage()
.map_err(|_| "exception getting local storage".to_owned())?
{
Some(l) => l,
None => {
return Err("failed to get local storage".to_owned());
}
};
let vkey = self.browser_key_name(key);
let prev = match ls
.get_item(&vkey)
.map_err(|_| "exception_thrown".to_owned())?
{
Some(_) => true,
None => false,
};
ls.set_item(&vkey, value)
.map_err(|_| "exception_thrown".to_owned())?;
Ok(prev)
} else {
Err("unimplemented".to_owned())
}
}
pub async fn load_user_secret_string(&self, key: &str) -> Result<Option<String>, String> {
if utils::is_nodejs() {
let prev = match JsFuture::from(
keytar_getPassword(self.keyring_name().as_str(), key)
.map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(p) => p,
Err(_) => JsValue::UNDEFINED,
};
if prev.is_undefined() || prev.is_null() {
return Ok(None);
}
Ok(prev.as_string())
} else if utils::is_browser() {
let win = match window() {
Some(w) => w,
None => {
return Err("failed to get window".to_owned());
}
};
let ls = match win
.local_storage()
.map_err(|_| "exception getting local storage".to_owned())?
{
Some(l) => l,
None => {
return Err("failed to get local storage".to_owned());
}
};
let vkey = self.browser_key_name(key);
ls.get_item(&vkey)
.map_err(|_| "exception_thrown".to_owned())
} else {
Err("unimplemented".to_owned())
}
}
pub async fn remove_user_secret_string(&self, key: &str) -> Result<bool, String> {
if utils::is_nodejs() {
match JsFuture::from(
keytar_deletePassword(self.keyring_name().as_str(), key).map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(v) => Ok(v.is_truthy()),
Err(_) => Err("Failed to delete".to_owned()),
}
} else if utils::is_browser() {
let win = match window() {
Some(w) => w,
None => {
return Err("failed to get window".to_owned());
}
};
let ls = match win
.local_storage()
.map_err(|_| "exception getting local storage".to_owned())?
{
Some(l) => l,
None => {
return Err("failed to get local storage".to_owned());
}
};
let vkey = self.browser_key_name(key);
match ls
.get_item(&vkey)
.map_err(|_| "exception_thrown".to_owned())?
{
Some(_) => {
ls.delete(&vkey)
.map_err(|_| "exception_thrown".to_owned())?;
Ok(true)
}
None => Ok(false),
}
} else {
Err("unimplemented".to_owned())
}
}
pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> Result<bool, String> {
let mut s = BASE64URL_NOPAD.encode(value);
s.push('!');
self.save_user_secret_string(key, s.as_str()).await
}
pub async fn load_user_secret(&self, key: &str) -> Result<Option<Vec<u8>>, String> {
let mut s = match self.load_user_secret_string(key).await? {
Some(s) => s,
None => {
return Ok(None);
}
};
match JsFuture::from(
keytar_setPassword(keyring_name(namespace).as_str(), key, value)
.map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(_) => {}
Err(_) => return Err("Failed to set password".to_owned()),
if s.pop() != Some('!') {
return Err("User secret is not a buffer".to_owned());
}
Ok(prev)
} else if utils::is_browser() {
let win = match window() {
Some(w) => w,
None => {
return Err("failed to get window".to_owned());
let mut bytes = Vec::<u8>::new();
let res = BASE64URL_NOPAD.decode_len(s.len());
match res {
Ok(l) => {
bytes.resize(l, 0u8);
}
};
let ls = match win
.local_storage()
.map_err(|_| "exception getting local storage".to_owned())?
{
Some(l) => l,
None => {
return Err("failed to get local storage".to_owned());
Err(_) => {
return Err("Failed to decode".to_owned());
}
};
let vkey = browser_key_name(namespace, key);
let prev = match ls
.get_item(&vkey)
.map_err(|_| "exception_thrown".to_owned())?
{
Some(_) => true,
None => false,
};
ls.set_item(&vkey, value)
.map_err(|_| "exception_thrown".to_owned())?;
Ok(prev)
} else {
Err("unimplemented".to_owned())
}
}
pub async fn load_user_secret_string(namespace: &str, key: &str) -> Result<Option<String>, String> {
if utils::is_nodejs() {
let prev = match JsFuture::from(
keytar_getPassword(keyring_name(namespace).as_str(), key)
.map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(p) => p,
Err(_) => JsValue::UNDEFINED,
};
if prev.is_undefined() || prev.is_null() {
return Ok(None);
}
Ok(prev.as_string())
} else if utils::is_browser() {
let win = match window() {
Some(w) => w,
None => {
return Err("failed to get window".to_owned());
}
};
let ls = match win
.local_storage()
.map_err(|_| "exception getting local storage".to_owned())?
{
Some(l) => l,
None => {
return Err("failed to get local storage".to_owned());
}
};
let vkey = browser_key_name(namespace, key);
ls.get_item(&vkey)
.map_err(|_| "exception_thrown".to_owned())
} else {
Err("unimplemented".to_owned())
}
}
pub async fn remove_user_secret_string(namespace: &str, key: &str) -> Result<bool, String> {
if utils::is_nodejs() {
match JsFuture::from(
keytar_deletePassword("veilid", key).map_err(|_| "exception thrown".to_owned())?,
)
.await
{
Ok(v) => Ok(v.is_truthy()),
Err(_) => Err("Failed to delete".to_owned()),
let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes);
match res {
Ok(_) => Ok(Some(bytes)),
Err(_) => Err("Failed to decode".to_owned()),
}
} else if utils::is_browser() {
let win = match window() {
Some(w) => w,
None => {
return Err("failed to get window".to_owned());
}
};
let ls = match win
.local_storage()
.map_err(|_| "exception getting local storage".to_owned())?
{
Some(l) => l,
None => {
return Err("failed to get local storage".to_owned());
}
};
let vkey = browser_key_name(namespace, key);
match ls
.get_item(&vkey)
.map_err(|_| "exception_thrown".to_owned())?
{
Some(_) => {
ls.delete(&vkey)
.map_err(|_| "exception_thrown".to_owned())?;
Ok(true)
}
None => Ok(false),
}
} else {
Err("unimplemented".to_owned())
}
}
pub async fn remove_user_secret(&self, key: &str) -> Result<bool, String> {
self.remove_user_secret_string(key).await
}
}

View File

@ -54,7 +54,7 @@ impl TableStore {
{
return Err(format!("table name '{}' is invalid", table));
}
let c = inner.config.get();
let c = self.config.get();
let namespace = c.namespace.clone();
Ok(if namespace.len() == 0 {
format!("{}", table)

View File

@ -64,7 +64,13 @@ wFAbkZY9eS/x6P7qrpd7dUA=
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub fn get_tablestore_path() -> String {
pub fn get_table_store_path() -> String {
String::new()
}
pub fn get_block_store_path() -> String {
String::new()
}
pub fn get_protected_store_path() -> String {
String::new()
}
pub fn get_certfile_path() -> String {
@ -103,6 +109,15 @@ cfg_if! {
out.into_os_string().into_string().unwrap()
}
pub fn get_block_store_path() -> String {
let mut out = get_data_dir();
std::fs::create_dir_all(&out).unwrap();
out.push("block_store");
out.into_os_string().into_string().unwrap()
}
pub fn get_protected_store_path() -> String {
let mut out = get_data_dir();
std::fs::create_dir_all(&out).unwrap();
@ -156,7 +171,7 @@ pub fn setup_veilid_core() -> VeilidCoreSetup {
}
}
pub fn config_callback(key: String) -> Result<Box<dyn core::any::Any>, String> {
pub fn config_callback(key: String) -> ConfigCallbackReturn {
match key.as_str() {
"program_name" => Ok(Box::new(String::from("Veilid"))),
"namespace" => Ok(Box::new(String::from(""))),
@ -168,9 +183,13 @@ pub fn config_callback(key: String) -> Result<Box<dyn core::any::Any>, String> {
"capabilities.protocol_connect_wss" => Ok(Box::new(true)),
"capabilities.protocol_accept_wss" => Ok(Box::new(true)),
"table_store.directory" => Ok(Box::new(get_table_store_path())),
"table_store.delete" => Ok(Box::new(false)),
"block_store.directory" => Ok(Box::new(get_block_store_path())),
"block_store.delete" => Ok(Box::new(false)),
"protected_store.allow_insecure_fallback" => Ok(Box::new(true)),
"protected_store.always_use_insecure_storage" => Ok(Box::new(false)),
"protected_store.insecure_fallback_directory" => Ok(Box::new(get_protected_store_path())),
"protected_store.delete" => Ok(Box::new(false)),
"network.max_connections" => Ok(Box::new(16u32)),
"network.connection_initial_timeout" => Ok(Box::new(2_000_000u64)),
"network.node_id" => Ok(Box::new(dht::key::DHTKey::default())),
@ -264,12 +283,16 @@ pub async fn test_config() {
assert_eq!(inner.capabilities.protocol_connect_wss, true);
assert_eq!(inner.capabilities.protocol_accept_wss, true);
assert_eq!(inner.table_store.directory, get_table_store_path());
assert_eq!(inner.table_store.delete, false);
assert_eq!(inner.block_store.directory, get_block_store_path());
assert_eq!(inner.block_store.delete, false);
assert_eq!(inner.protected_store.allow_insecure_fallback, true);
assert_eq!(inner.protected_store.always_use_insecure_storage, false);
assert_eq!(
inner.protected_store.insecure_fallback_directory,
get_protected_store_path()
);
assert_eq!(inner.protected_store.delete, false);
assert_eq!(inner.network.max_connections, 16);
assert_eq!(inner.network.connection_initial_timeout, 2_000_000u64);
assert!(!inner.network.node_id.valid);

View File

@ -4,9 +4,12 @@ use crate::xx::*;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub type ConfigCallback = Arc<dyn Fn(String) -> Result<Box<dyn core::any::Any>, String>>;
pub type ConfigCallbackReturn = Result<Box<dyn core::any::Any>, String>;
pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn>;
} else {
pub type ConfigCallback = Arc<dyn Fn(String) -> Result<Box<dyn core::any::Any>, String> + Send>;
pub type ConfigCallbackReturn = Result<Box<dyn core::any::Any + Send>, String>;
pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn + Send>;
}
}

View File

@ -0,0 +1,982 @@
// AUTO GENERATED FILE, DO NOT EDIT.
// Generated by `flutter_rust_bridge`.
// ignore_for_file: non_constant_identifier_names, unused_element, duplicate_ignore, directives_ordering, curly_braces_in_flow_control_structures, unnecessary_lambdas, slash_for_doc_comments, prefer_const_literals_to_create_immutables, implicit_dynamic_list_literal, duplicate_import, unused_import
import 'dart:convert';
import 'dart:typed_data';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';
import 'dart:ffi' as ffi;
part 'bridge_generated.freezed.dart';
abstract class VeilidFlutter {
Stream<VeilidUpdate> startupVeilidCore(
{required VeilidConfig config, dynamic hint});
Future<VeilidState> getVeilidState({dynamic hint});
Future<void> shutdownVeilidCore({dynamic hint});
}
enum AttachmentState {
Detached,
Attaching,
AttachedWeak,
AttachedGood,
AttachedStrong,
FullyAttached,
OverAttached,
Detaching,
}
class VeilidConfig {
final String programName;
final String namespace;
final VeilidConfigCapabilities capabilities;
final VeilidConfigProtectedStore protectedStore;
final VeilidConfigTableStore tableStore;
final VeilidConfigBlockStore blockStore;
final VeilidConfigNetwork network;
VeilidConfig({
required this.programName,
required this.namespace,
required this.capabilities,
required this.protectedStore,
required this.tableStore,
required this.blockStore,
required this.network,
});
}
class VeilidConfigBlockStore {
final String directory;
final bool delete;
VeilidConfigBlockStore({
required this.directory,
required this.delete,
});
}
class VeilidConfigCapabilities {
final bool protocolUdp;
final bool protocolConnectTcp;
final bool protocolAcceptTcp;
final bool protocolConnectWs;
final bool protocolAcceptWs;
final bool protocolConnectWss;
final bool protocolAcceptWss;
VeilidConfigCapabilities({
required this.protocolUdp,
required this.protocolConnectTcp,
required this.protocolAcceptTcp,
required this.protocolConnectWs,
required this.protocolAcceptWs,
required this.protocolConnectWss,
required this.protocolAcceptWss,
});
}
class VeilidConfigDHT {
final int? resolveNodeTimeout;
final int resolveNodeCount;
final int resolveNodeFanout;
final int maxFindNodeCount;
final int? getValueTimeout;
final int getValueCount;
final int getValueFanout;
final int? setValueTimeout;
final int setValueCount;
final int setValueFanout;
final int minPeerCount;
final int minPeerRefreshTime;
final int validateDialInfoReceiptTime;
VeilidConfigDHT({
this.resolveNodeTimeout,
required this.resolveNodeCount,
required this.resolveNodeFanout,
required this.maxFindNodeCount,
this.getValueTimeout,
required this.getValueCount,
required this.getValueFanout,
this.setValueTimeout,
required this.setValueCount,
required this.setValueFanout,
required this.minPeerCount,
required this.minPeerRefreshTime,
required this.validateDialInfoReceiptTime,
});
}
class VeilidConfigLeases {
final int maxServerSignalLeases;
final int maxServerRelayLeases;
final int maxClientSignalLeases;
final int maxClientRelayLeases;
VeilidConfigLeases({
required this.maxServerSignalLeases,
required this.maxServerRelayLeases,
required this.maxClientSignalLeases,
required this.maxClientRelayLeases,
});
}
class VeilidConfigNetwork {
final int maxConnections;
final int connectionInitialTimeout;
final String nodeId;
final String nodeIdSecret;
final List<String> bootstrap;
final VeilidConfigRPC rpc;
final VeilidConfigDHT dht;
final bool upnp;
final bool natpmp;
final bool enableLocalPeerScope;
final int restrictedNatRetries;
final VeilidConfigProtocol protocol;
final VeilidConfigLeases leases;
VeilidConfigNetwork({
required this.maxConnections,
required this.connectionInitialTimeout,
required this.nodeId,
required this.nodeIdSecret,
required this.bootstrap,
required this.rpc,
required this.dht,
required this.upnp,
required this.natpmp,
required this.enableLocalPeerScope,
required this.restrictedNatRetries,
required this.protocol,
required this.leases,
});
}
class VeilidConfigProtectedStore {
final bool allowInsecureFallback;
final bool alwaysUseInsecureStorage;
final String insecureFallbackDirectory;
final bool delete;
VeilidConfigProtectedStore({
required this.allowInsecureFallback,
required this.alwaysUseInsecureStorage,
required this.insecureFallbackDirectory,
required this.delete,
});
}
class VeilidConfigProtocol {
final VeilidConfigUDP udp;
final VeilidConfigTCP tcp;
final VeilidConfigWS ws;
final VeilidConfigWSS wss;
VeilidConfigProtocol({
required this.udp,
required this.tcp,
required this.ws,
required this.wss,
});
}
class VeilidConfigRPC {
final int concurrency;
final int queueSize;
final int? maxTimestampBehind;
final int? maxTimestampAhead;
final int timeout;
final int maxRouteHopCount;
VeilidConfigRPC({
required this.concurrency,
required this.queueSize,
this.maxTimestampBehind,
this.maxTimestampAhead,
required this.timeout,
required this.maxRouteHopCount,
});
}
class VeilidConfigTableStore {
final String directory;
final bool delete;
VeilidConfigTableStore({
required this.directory,
required this.delete,
});
}
class VeilidConfigTCP {
final bool connect;
final bool listen;
final int maxConnections;
final String listenAddress;
final String? publicAddress;
VeilidConfigTCP({
required this.connect,
required this.listen,
required this.maxConnections,
required this.listenAddress,
this.publicAddress,
});
}
class VeilidConfigUDP {
final bool enabled;
final int socketPoolSize;
final String listenAddress;
final String? publicAddress;
VeilidConfigUDP({
required this.enabled,
required this.socketPoolSize,
required this.listenAddress,
this.publicAddress,
});
}
class VeilidConfigWS {
final bool connect;
final bool listen;
final int maxConnections;
final String listenAddress;
final String path;
final String? url;
VeilidConfigWS({
required this.connect,
required this.listen,
required this.maxConnections,
required this.listenAddress,
required this.path,
this.url,
});
}
class VeilidConfigWSS {
final bool connect;
final int maxConnections;
VeilidConfigWSS({
required this.connect,
required this.maxConnections,
});
}
class VeilidState {
final AttachmentState attachment;
VeilidState({
required this.attachment,
});
}
@freezed
class VeilidUpdate with _$VeilidUpdate {
const factory VeilidUpdate.attachment(
AttachmentState field0,
) = Attachment;
}
class VeilidFlutterImpl extends FlutterRustBridgeBase<VeilidFlutterWire>
implements VeilidFlutter {
factory VeilidFlutterImpl(ffi.DynamicLibrary dylib) =>
VeilidFlutterImpl.raw(VeilidFlutterWire(dylib));
VeilidFlutterImpl.raw(VeilidFlutterWire inner) : super(inner);
Stream<VeilidUpdate> startupVeilidCore(
{required VeilidConfig config, dynamic hint}) =>
executeStream(FlutterRustBridgeTask(
callFfi: (port) => inner.wire_startup_veilid_core(
port, _api2wire_box_autoadd_veilid_config(config)),
parseSuccessData: _wire2api_veilid_update,
constMeta: const FlutterRustBridgeTaskConstMeta(
debugName: "startup_veilid_core",
argNames: ["config"],
),
argValues: [config],
hint: hint,
));
Future<VeilidState> getVeilidState({dynamic hint}) =>
executeNormal(FlutterRustBridgeTask(
callFfi: (port) => inner.wire_get_veilid_state(port),
parseSuccessData: _wire2api_veilid_state,
constMeta: const FlutterRustBridgeTaskConstMeta(
debugName: "get_veilid_state",
argNames: [],
),
argValues: [],
hint: hint,
));
Future<void> shutdownVeilidCore({dynamic hint}) =>
executeNormal(FlutterRustBridgeTask(
callFfi: (port) => inner.wire_shutdown_veilid_core(port),
parseSuccessData: _wire2api_unit,
constMeta: const FlutterRustBridgeTaskConstMeta(
debugName: "shutdown_veilid_core",
argNames: [],
),
argValues: [],
hint: hint,
));
// Section: api2wire
ffi.Pointer<wire_uint_8_list> _api2wire_String(String raw) {
return _api2wire_uint_8_list(utf8.encoder.convert(raw));
}
ffi.Pointer<wire_StringList> _api2wire_StringList(List<String> raw) {
final ans = inner.new_StringList(raw.length);
for (var i = 0; i < raw.length; i++) {
ans.ref.ptr[i] = _api2wire_String(raw[i]);
}
return ans;
}
int _api2wire_bool(bool raw) {
return raw ? 1 : 0;
}
ffi.Pointer<ffi.Uint64> _api2wire_box_autoadd_u64(int raw) {
return inner.new_box_autoadd_u64(raw);
}
ffi.Pointer<wire_VeilidConfig> _api2wire_box_autoadd_veilid_config(
VeilidConfig raw) {
final ptr = inner.new_box_autoadd_veilid_config();
_api_fill_to_wire_veilid_config(raw, ptr.ref);
return ptr;
}
ffi.Pointer<wire_uint_8_list> _api2wire_opt_String(String? raw) {
return raw == null ? ffi.nullptr : _api2wire_String(raw);
}
ffi.Pointer<ffi.Uint64> _api2wire_opt_box_autoadd_u64(int? raw) {
return raw == null ? ffi.nullptr : _api2wire_box_autoadd_u64(raw);
}
int _api2wire_u32(int raw) {
return raw;
}
int _api2wire_u64(int raw) {
return raw;
}
int _api2wire_u8(int raw) {
return raw;
}
ffi.Pointer<wire_uint_8_list> _api2wire_uint_8_list(Uint8List raw) {
final ans = inner.new_uint_8_list(raw.length);
ans.ref.ptr.asTypedList(raw.length).setAll(0, raw);
return ans;
}
// Section: api_fill_to_wire
void _api_fill_to_wire_box_autoadd_veilid_config(
VeilidConfig apiObj, ffi.Pointer<wire_VeilidConfig> wireObj) {
_api_fill_to_wire_veilid_config(apiObj, wireObj.ref);
}
void _api_fill_to_wire_veilid_config(
VeilidConfig apiObj, wire_VeilidConfig wireObj) {
wireObj.program_name = _api2wire_String(apiObj.programName);
wireObj.namespace = _api2wire_String(apiObj.namespace);
wireObj.capabilities =
_api2wire_veilid_config_capabilities(apiObj.capabilities);
wireObj.protected_store =
_api2wire_veilid_config_protected_store(apiObj.protectedStore);
wireObj.table_store =
_api2wire_veilid_config_table_store(apiObj.tableStore);
wireObj.block_store =
_api2wire_veilid_config_block_store(apiObj.blockStore);
wireObj.network = _api2wire_veilid_config_network(apiObj.network);
}
void _api_fill_to_wire_veilid_config_block_store(
VeilidConfigBlockStore apiObj, wire_VeilidConfigBlockStore wireObj) {
wireObj.directory = _api2wire_String(apiObj.directory);
wireObj.delete = _api2wire_bool(apiObj.delete);
}
void _api_fill_to_wire_veilid_config_capabilities(
VeilidConfigCapabilities apiObj, wire_VeilidConfigCapabilities wireObj) {
wireObj.protocol_udp = _api2wire_bool(apiObj.protocolUdp);
wireObj.protocol_connect_tcp = _api2wire_bool(apiObj.protocolConnectTcp);
wireObj.protocol_accept_tcp = _api2wire_bool(apiObj.protocolAcceptTcp);
wireObj.protocol_connect_ws = _api2wire_bool(apiObj.protocolConnectWs);
wireObj.protocol_accept_ws = _api2wire_bool(apiObj.protocolAcceptWs);
wireObj.protocol_connect_wss = _api2wire_bool(apiObj.protocolConnectWss);
wireObj.protocol_accept_wss = _api2wire_bool(apiObj.protocolAcceptWss);
}
void _api_fill_to_wire_veilid_config_dht(
VeilidConfigDHT apiObj, wire_VeilidConfigDHT wireObj) {
wireObj.resolve_node_timeout =
_api2wire_opt_box_autoadd_u64(apiObj.resolveNodeTimeout);
wireObj.resolve_node_count = _api2wire_u32(apiObj.resolveNodeCount);
wireObj.resolve_node_fanout = _api2wire_u32(apiObj.resolveNodeFanout);
wireObj.max_find_node_count = _api2wire_u32(apiObj.maxFindNodeCount);
wireObj.get_value_timeout =
_api2wire_opt_box_autoadd_u64(apiObj.getValueTimeout);
wireObj.get_value_count = _api2wire_u32(apiObj.getValueCount);
wireObj.get_value_fanout = _api2wire_u32(apiObj.getValueFanout);
wireObj.set_value_timeout =
_api2wire_opt_box_autoadd_u64(apiObj.setValueTimeout);
wireObj.set_value_count = _api2wire_u32(apiObj.setValueCount);
wireObj.set_value_fanout = _api2wire_u32(apiObj.setValueFanout);
wireObj.min_peer_count = _api2wire_u32(apiObj.minPeerCount);
wireObj.min_peer_refresh_time = _api2wire_u64(apiObj.minPeerRefreshTime);
wireObj.validate_dial_info_receipt_time =
_api2wire_u64(apiObj.validateDialInfoReceiptTime);
}
void _api_fill_to_wire_veilid_config_leases(
VeilidConfigLeases apiObj, wire_VeilidConfigLeases wireObj) {
wireObj.max_server_signal_leases =
_api2wire_u32(apiObj.maxServerSignalLeases);
wireObj.max_server_relay_leases =
_api2wire_u32(apiObj.maxServerRelayLeases);
wireObj.max_client_signal_leases =
_api2wire_u32(apiObj.maxClientSignalLeases);
wireObj.max_client_relay_leases =
_api2wire_u32(apiObj.maxClientRelayLeases);
}
void _api_fill_to_wire_veilid_config_network(
VeilidConfigNetwork apiObj, wire_VeilidConfigNetwork wireObj) {
wireObj.max_connections = _api2wire_u32(apiObj.maxConnections);
wireObj.connection_initial_timeout =
_api2wire_u64(apiObj.connectionInitialTimeout);
wireObj.node_id = _api2wire_String(apiObj.nodeId);
wireObj.node_id_secret = _api2wire_String(apiObj.nodeIdSecret);
wireObj.bootstrap = _api2wire_StringList(apiObj.bootstrap);
wireObj.rpc = _api2wire_veilid_config_rpc(apiObj.rpc);
wireObj.dht = _api2wire_veilid_config_dht(apiObj.dht);
wireObj.upnp = _api2wire_bool(apiObj.upnp);
wireObj.natpmp = _api2wire_bool(apiObj.natpmp);
wireObj.enable_local_peer_scope =
_api2wire_bool(apiObj.enableLocalPeerScope);
wireObj.restricted_nat_retries = _api2wire_u32(apiObj.restrictedNatRetries);
wireObj.protocol = _api2wire_veilid_config_protocol(apiObj.protocol);
wireObj.leases = _api2wire_veilid_config_leases(apiObj.leases);
}
void _api_fill_to_wire_veilid_config_protected_store(
VeilidConfigProtectedStore apiObj,
wire_VeilidConfigProtectedStore wireObj) {
wireObj.allow_insecure_fallback =
_api2wire_bool(apiObj.allowInsecureFallback);
wireObj.always_use_insecure_storage =
_api2wire_bool(apiObj.alwaysUseInsecureStorage);
wireObj.insecure_fallback_directory =
_api2wire_String(apiObj.insecureFallbackDirectory);
wireObj.delete = _api2wire_bool(apiObj.delete);
}
void _api_fill_to_wire_veilid_config_protocol(
VeilidConfigProtocol apiObj, wire_VeilidConfigProtocol wireObj) {
wireObj.udp = _api2wire_veilid_config_udp(apiObj.udp);
wireObj.tcp = _api2wire_veilid_config_tcp(apiObj.tcp);
wireObj.ws = _api2wire_veilid_config_ws(apiObj.ws);
wireObj.wss = _api2wire_veilid_config_wss(apiObj.wss);
}
void _api_fill_to_wire_veilid_config_rpc(
VeilidConfigRPC apiObj, wire_VeilidConfigRPC wireObj) {
wireObj.concurrency = _api2wire_u32(apiObj.concurrency);
wireObj.queue_size = _api2wire_u32(apiObj.queueSize);
wireObj.max_timestamp_behind =
_api2wire_opt_box_autoadd_u64(apiObj.maxTimestampBehind);
wireObj.max_timestamp_ahead =
_api2wire_opt_box_autoadd_u64(apiObj.maxTimestampAhead);
wireObj.timeout = _api2wire_u64(apiObj.timeout);
wireObj.max_route_hop_count = _api2wire_u8(apiObj.maxRouteHopCount);
}
void _api_fill_to_wire_veilid_config_table_store(
VeilidConfigTableStore apiObj, wire_VeilidConfigTableStore wireObj) {
wireObj.directory = _api2wire_String(apiObj.directory);
wireObj.delete = _api2wire_bool(apiObj.delete);
}
void _api_fill_to_wire_veilid_config_tcp(
VeilidConfigTCP apiObj, wire_VeilidConfigTCP wireObj) {
wireObj.connect = _api2wire_bool(apiObj.connect);
wireObj.listen = _api2wire_bool(apiObj.listen);
wireObj.max_connections = _api2wire_u32(apiObj.maxConnections);
wireObj.listen_address = _api2wire_String(apiObj.listenAddress);
wireObj.public_address = _api2wire_opt_String(apiObj.publicAddress);
}
void _api_fill_to_wire_veilid_config_udp(
VeilidConfigUDP apiObj, wire_VeilidConfigUDP wireObj) {
wireObj.enabled = _api2wire_bool(apiObj.enabled);
wireObj.socket_pool_size = _api2wire_u32(apiObj.socketPoolSize);
wireObj.listen_address = _api2wire_String(apiObj.listenAddress);
wireObj.public_address = _api2wire_opt_String(apiObj.publicAddress);
}
void _api_fill_to_wire_veilid_config_ws(
VeilidConfigWS apiObj, wire_VeilidConfigWS wireObj) {
wireObj.connect = _api2wire_bool(apiObj.connect);
wireObj.listen = _api2wire_bool(apiObj.listen);
wireObj.max_connections = _api2wire_u32(apiObj.maxConnections);
wireObj.listen_address = _api2wire_String(apiObj.listenAddress);
wireObj.path = _api2wire_String(apiObj.path);
wireObj.url = _api2wire_opt_String(apiObj.url);
}
void _api_fill_to_wire_veilid_config_wss(
VeilidConfigWSS apiObj, wire_VeilidConfigWSS wireObj) {
wireObj.connect = _api2wire_bool(apiObj.connect);
wireObj.max_connections = _api2wire_u32(apiObj.maxConnections);
}
}
// Section: wire2api
AttachmentState _wire2api_attachment_state(dynamic raw) {
return AttachmentState.values[raw];
}
void _wire2api_unit(dynamic raw) {
return;
}
VeilidState _wire2api_veilid_state(dynamic raw) {
final arr = raw as List<dynamic>;
if (arr.length != 1)
throw Exception('unexpected arr length: expect 1 but see ${arr.length}');
return VeilidState(
attachment: _wire2api_attachment_state(arr[0]),
);
}
VeilidUpdate _wire2api_veilid_update(dynamic raw) {
switch (raw[0]) {
case 0:
return Attachment(
_wire2api_attachment_state(raw[1]),
);
default:
throw Exception("unreachable");
}
}
// ignore_for_file: camel_case_types, non_constant_identifier_names, avoid_positional_boolean_parameters, annotate_overrides, constant_identifier_names
// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
/// generated by flutter_rust_bridge
class VeilidFlutterWire implements FlutterRustBridgeWireBase {
/// Holds the symbol lookup function.
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
_lookup;
/// The symbols are looked up in [dynamicLibrary].
VeilidFlutterWire(ffi.DynamicLibrary dynamicLibrary)
: _lookup = dynamicLibrary.lookup;
/// The symbols are looked up with [lookup].
VeilidFlutterWire.fromLookup(
ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
lookup)
: _lookup = lookup;
void wire_startup_veilid_core(
int port_,
ffi.Pointer<wire_VeilidConfig> config,
) {
return _wire_startup_veilid_core(
port_,
config,
);
}
late final _wire_startup_veilid_corePtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(ffi.Int64,
ffi.Pointer<wire_VeilidConfig>)>>('wire_startup_veilid_core');
late final _wire_startup_veilid_core = _wire_startup_veilid_corePtr
.asFunction<void Function(int, ffi.Pointer<wire_VeilidConfig>)>();
void wire_get_veilid_state(
int port_,
) {
return _wire_get_veilid_state(
port_,
);
}
late final _wire_get_veilid_statePtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64)>>(
'wire_get_veilid_state');
late final _wire_get_veilid_state =
_wire_get_veilid_statePtr.asFunction<void Function(int)>();
void wire_shutdown_veilid_core(
int port_,
) {
return _wire_shutdown_veilid_core(
port_,
);
}
late final _wire_shutdown_veilid_corePtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64)>>(
'wire_shutdown_veilid_core');
late final _wire_shutdown_veilid_core =
_wire_shutdown_veilid_corePtr.asFunction<void Function(int)>();
ffi.Pointer<wire_StringList> new_StringList(
int len,
) {
return _new_StringList(
len,
);
}
late final _new_StringListPtr = _lookup<
ffi.NativeFunction<ffi.Pointer<wire_StringList> Function(ffi.Int32)>>(
'new_StringList');
late final _new_StringList = _new_StringListPtr
.asFunction<ffi.Pointer<wire_StringList> Function(int)>();
ffi.Pointer<ffi.Uint64> new_box_autoadd_u64(
int value,
) {
return _new_box_autoadd_u64(
value,
);
}
late final _new_box_autoadd_u64Ptr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Uint64> Function(ffi.Uint64)>>(
'new_box_autoadd_u64');
late final _new_box_autoadd_u64 = _new_box_autoadd_u64Ptr
.asFunction<ffi.Pointer<ffi.Uint64> Function(int)>();
ffi.Pointer<wire_VeilidConfig> new_box_autoadd_veilid_config() {
return _new_box_autoadd_veilid_config();
}
late final _new_box_autoadd_veilid_configPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_VeilidConfig> Function()>>(
'new_box_autoadd_veilid_config');
late final _new_box_autoadd_veilid_config = _new_box_autoadd_veilid_configPtr
.asFunction<ffi.Pointer<wire_VeilidConfig> Function()>();
ffi.Pointer<wire_uint_8_list> new_uint_8_list(
int len,
) {
return _new_uint_8_list(
len,
);
}
late final _new_uint_8_listPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<wire_uint_8_list> Function(
ffi.Int32)>>('new_uint_8_list');
late final _new_uint_8_list = _new_uint_8_listPtr
.asFunction<ffi.Pointer<wire_uint_8_list> Function(int)>();
void free_WireSyncReturnStruct(
WireSyncReturnStruct val,
) {
return _free_WireSyncReturnStruct(
val,
);
}
late final _free_WireSyncReturnStructPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(WireSyncReturnStruct)>>(
'free_WireSyncReturnStruct');
late final _free_WireSyncReturnStruct = _free_WireSyncReturnStructPtr
.asFunction<void Function(WireSyncReturnStruct)>();
void store_dart_post_cobject(
DartPostCObjectFnType ptr,
) {
return _store_dart_post_cobject(
ptr,
);
}
late final _store_dart_post_cobjectPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(DartPostCObjectFnType)>>(
'store_dart_post_cobject');
late final _store_dart_post_cobject = _store_dart_post_cobjectPtr
.asFunction<void Function(DartPostCObjectFnType)>();
}
class wire_uint_8_list extends ffi.Struct {
external ffi.Pointer<ffi.Uint8> ptr;
@ffi.Int32()
external int len;
}
class wire_VeilidConfigCapabilities extends ffi.Struct {
@ffi.Uint8()
external int protocol_udp;
@ffi.Uint8()
external int protocol_connect_tcp;
@ffi.Uint8()
external int protocol_accept_tcp;
@ffi.Uint8()
external int protocol_connect_ws;
@ffi.Uint8()
external int protocol_accept_ws;
@ffi.Uint8()
external int protocol_connect_wss;
@ffi.Uint8()
external int protocol_accept_wss;
}
class wire_VeilidConfigProtectedStore extends ffi.Struct {
@ffi.Uint8()
external int allow_insecure_fallback;
@ffi.Uint8()
external int always_use_insecure_storage;
external ffi.Pointer<wire_uint_8_list> insecure_fallback_directory;
@ffi.Uint8()
external int delete_;
}
class wire_VeilidConfigTableStore extends ffi.Struct {
external ffi.Pointer<wire_uint_8_list> directory;
@ffi.Uint8()
external int delete_;
}
class wire_VeilidConfigBlockStore extends ffi.Struct {
external ffi.Pointer<wire_uint_8_list> directory;
@ffi.Uint8()
external int delete_;
}
class wire_StringList extends ffi.Struct {
external ffi.Pointer<ffi.Pointer<wire_uint_8_list>> ptr;
@ffi.Int32()
external int len;
}
class wire_VeilidConfigRPC extends ffi.Struct {
@ffi.Uint32()
external int concurrency;
@ffi.Uint32()
external int queue_size;
external ffi.Pointer<ffi.Uint64> max_timestamp_behind;
external ffi.Pointer<ffi.Uint64> max_timestamp_ahead;
@ffi.Uint64()
external int timeout;
@ffi.Uint8()
external int max_route_hop_count;
}
class wire_VeilidConfigDHT extends ffi.Struct {
external ffi.Pointer<ffi.Uint64> resolve_node_timeout;
@ffi.Uint32()
external int resolve_node_count;
@ffi.Uint32()
external int resolve_node_fanout;
@ffi.Uint32()
external int max_find_node_count;
external ffi.Pointer<ffi.Uint64> get_value_timeout;
@ffi.Uint32()
external int get_value_count;
@ffi.Uint32()
external int get_value_fanout;
external ffi.Pointer<ffi.Uint64> set_value_timeout;
@ffi.Uint32()
external int set_value_count;
@ffi.Uint32()
external int set_value_fanout;
@ffi.Uint32()
external int min_peer_count;
@ffi.Uint64()
external int min_peer_refresh_time;
@ffi.Uint64()
external int validate_dial_info_receipt_time;
}
class wire_VeilidConfigUDP extends ffi.Struct {
@ffi.Uint8()
external int enabled;
@ffi.Uint32()
external int socket_pool_size;
external ffi.Pointer<wire_uint_8_list> listen_address;
external ffi.Pointer<wire_uint_8_list> public_address;
}
class wire_VeilidConfigTCP extends ffi.Struct {
@ffi.Uint8()
external int connect;
@ffi.Uint8()
external int listen;
@ffi.Uint32()
external int max_connections;
external ffi.Pointer<wire_uint_8_list> listen_address;
external ffi.Pointer<wire_uint_8_list> public_address;
}
class wire_VeilidConfigWS extends ffi.Struct {
@ffi.Uint8()
external int connect;
@ffi.Uint8()
external int listen;
@ffi.Uint32()
external int max_connections;
external ffi.Pointer<wire_uint_8_list> listen_address;
external ffi.Pointer<wire_uint_8_list> path;
external ffi.Pointer<wire_uint_8_list> url;
}
class wire_VeilidConfigWSS extends ffi.Struct {
@ffi.Uint8()
external int connect;
@ffi.Uint32()
external int max_connections;
}
class wire_VeilidConfigProtocol extends ffi.Struct {
external wire_VeilidConfigUDP udp;
external wire_VeilidConfigTCP tcp;
external wire_VeilidConfigWS ws;
external wire_VeilidConfigWSS wss;
}
class wire_VeilidConfigLeases extends ffi.Struct {
@ffi.Uint32()
external int max_server_signal_leases;
@ffi.Uint32()
external int max_server_relay_leases;
@ffi.Uint32()
external int max_client_signal_leases;
@ffi.Uint32()
external int max_client_relay_leases;
}
class wire_VeilidConfigNetwork extends ffi.Struct {
@ffi.Uint32()
external int max_connections;
@ffi.Uint64()
external int connection_initial_timeout;
external ffi.Pointer<wire_uint_8_list> node_id;
external ffi.Pointer<wire_uint_8_list> node_id_secret;
external ffi.Pointer<wire_StringList> bootstrap;
external wire_VeilidConfigRPC rpc;
external wire_VeilidConfigDHT dht;
@ffi.Uint8()
external int upnp;
@ffi.Uint8()
external int natpmp;
@ffi.Uint8()
external int enable_local_peer_scope;
@ffi.Uint32()
external int restricted_nat_retries;
external wire_VeilidConfigProtocol protocol;
external wire_VeilidConfigLeases leases;
}
class wire_VeilidConfig extends ffi.Struct {
external ffi.Pointer<wire_uint_8_list> program_name;
external ffi.Pointer<wire_uint_8_list> namespace_;
external wire_VeilidConfigCapabilities capabilities;
external wire_VeilidConfigProtectedStore protected_store;
external wire_VeilidConfigTableStore table_store;
external wire_VeilidConfigBlockStore block_store;
external wire_VeilidConfigNetwork network;
}
typedef DartPostCObjectFnType = ffi.Pointer<
ffi.NativeFunction<ffi.Uint8 Function(DartPort, ffi.Pointer<ffi.Void>)>>;
typedef DartPort = ffi.Int64;

View File

@ -1,3 +1,5 @@
src/bridge_generated.rs
##############################################################################
### MacOS

3059
veilid-flutter/rust/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,13 @@ version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
crate-type = ["cdylib", "staticlib"]
[dependencies]
async-std = { version = "^1", features = ["unstable"] }
veilid-core = { path="../../veilid-core" }
flutter_rust_bridge = "^1"
log = "^0"
[build-dependencies]
cfg-if = "^1"

View File

@ -0,0 +1,87 @@
use cfg_if::*;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
fn resolve_llvm_path() -> Option<PathBuf> {
let paths: Vec<PathBuf> =
env::var_os("PATH").map(|paths| env::split_paths(&paths).collect())?;
cfg_if! {
if #[cfg(target_os="linux")] {
// build host is linux
// find clang
let d = paths.iter().find_map(|p| {
if p.join("clang").exists() {
if let Ok(real_clang_path) = fs::canonicalize(p.join("clang")) {
if let Some(llvmbindir) = real_clang_path.parent() {
if let Some(llvmdir) = llvmbindir.parent() {
return Some(llvmdir.to_owned());
}
}
}
}
None
});
d.or_else(|| {
["/usr/lib/llvm-13", "/usr/lib/llvm-12", "/usr/lib/llvm-11", "/usr/lib/llvm-10"].iter().map(Path::new).find_map(|p| if p.exists() { Some(p.to_owned()) } else { None } )
})
} else if #[cfg(target_os="macos")] {
// build host is mac
["/opt/homebrew/opt/llvm", "/usr/local/homebrew/opt/llvm"].iter().map(Path::new).find_map(|p| if p.exists() { Some(p.to_owned()) } else { None } )
} else {
// anywhere else, just use the default paths
llvm_path = None;
}
}
}
fn main() {
//let out_dir = env::var_os("OUT_DIR").unwrap();
let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
let input_path = Path::new(&manifest_dir).join("src").join("api.rs");
let output_path = Path::new(&manifest_dir)
.parent()
.unwrap()
.join("lib")
.join("bridge_generated.dart");
let llvm_path = resolve_llvm_path();
eprintln!("input_path: {:?}", input_path);
eprintln!("output_path: {:?}", output_path);
eprintln!("llvm_path: {:?}", llvm_path);
let mut command = Command::new("flutter_rust_bridge_codegen");
if let Some(llvm_path) = llvm_path {
command.args([
OsStr::new("--rust-input"),
input_path.as_os_str(),
OsStr::new("--dart-output"),
output_path.as_os_str(),
OsStr::new("--llvm-path"),
llvm_path.as_os_str(),
]);
} else {
command.args([
OsStr::new("--rust-input"),
input_path.as_os_str(),
OsStr::new("--dart-output"),
output_path.as_os_str(),
]);
}
let mut child = command
.spawn()
.expect("flutter_rust_bridge_codegen did not execute correctly");
child
.wait()
.expect("flutter_rust_bridge_codegen was not running");
println!("cargo:rerun-if-changed=src/api.c");
}

View File

@ -1,4 +1,7 @@
use std::sync::Arc;
use flutter_rust_bridge::*;
use log::*;
use std::collections::HashMap;
/////////////////////////////////////////
// Config Settings
@ -84,8 +87,8 @@ pub struct VeilidConfigLeases {
pub struct VeilidConfigNetwork {
pub max_connections: u32,
pub connection_initial_timeout: u64,
pub node_id: key::DHTKey,
pub node_id_secret: key::DHTKeySecret,
pub node_id: String,
pub node_id_secret: String,
pub bootstrap: Vec<String>,
pub rpc: VeilidConfigRPC,
pub dht: VeilidConfigDHT,
@ -93,7 +96,6 @@ pub struct VeilidConfigNetwork {
pub natpmp: bool,
pub enable_local_peer_scope: bool,
pub restricted_nat_retries: u32,
pub tls: VeilidConfigTLS,
pub protocol: VeilidConfigProtocol,
pub leases: VeilidConfigLeases,
}
@ -146,10 +148,10 @@ pub struct VeilidConfig {
/////////////////////////////////////////
#[derive(Debug)]
pub enum APIErrorKind {
pub enum VeilidAPIError {
AlreadyInitialized,
NotInitialized,
InvalidConfig,
InvalidConfig(String),
Timeout,
Shutdown,
NodeNotFound(String),
@ -171,10 +173,20 @@ pub enum APIErrorKind {
},
}
#[derive(Debug)]
pub struct VeilidAPIError {
kind: APIErrorKind,
message: String,
impl VeilidAPIError {
fn from_core(api_error: veilid_core::VeilidAPIError) -> Self {
match api_error {
veilid_core::VeilidAPIError::Timeout => VeilidAPIError::Timeout,
veilid_core::VeilidAPIError::Shutdown => VeilidAPIError::Shutdown,
veilid_core::VeilidAPIError::NodeNotFound(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
veilid_core::VeilidAPIError::NoDialInfo(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
veilid_core::VeilidAPIError::Internal(msg) => VeilidAPIError::Internal(msg.clone()),
veilid_core::VeilidAPIError::Unimplemented(msg)=> VeilidAPIError::Unimplemented(msg.clone()),
veilid_core::VeilidAPIError::ParseError{message, value} => VeilidAPIError::ParseError{ message: message.clone(), value: value.clone() },
veilid_core::VeilidAPIError::InvalidArgument { context, argument, value } => VeilidAPIError::InvalidArgument{ context: context.clone(), argument: argument.clone(), value: value.clone() },
veilid_core::VeilidAPIError::MissingArgument {context, argument } => VeilidAPIError::MissingArgument{ context: context.clone(), argument: argument.clone() },
}
}
}
#[derive(Debug)]
@ -189,25 +201,185 @@ pub enum AttachmentState {
Detaching,
}
impl AttachmentState {
fn from_core(attachment_state: veilid_core::AttachmentState) -> Self {
match attachment_state {
veilid_core::AttachmentState::Detached => AttachmentState::Detached,
veilid_core::AttachmentState::Attaching=> AttachmentState::Attaching,
veilid_core::AttachmentState::AttachedWeak=> AttachmentState::AttachedWeak,
veilid_core::AttachmentState::AttachedGood=> AttachmentState::AttachedGood,
veilid_core::AttachmentState::AttachedStrong=> AttachmentState::AttachedStrong,
veilid_core::AttachmentState::FullyAttached=> AttachmentState::FullyAttached,
veilid_core::AttachmentState::OverAttached=> AttachmentState::OverAttached,
veilid_core::AttachmentState::Detaching=> AttachmentState::Detaching,
}
}
}
#[derive(Debug)]
pub enum VeilidUpdate {
Attachment (AttachmentState),
}
/////////////////////////////////////////
///
pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig) -> Result<(), VeilidAPIError> {
let core = veilid_core::VeilidCore::new();
core.
impl VeilidUpdate {
fn from_core(veilid_update: veilid_core::VeilidUpdate) -> Self {
match veilid_update {
veilid_core::VeilidUpdate::Attachment(attachment) => Self::Attachment(AttachmentState::from_core(attachment))
}
}
}
pub fn get_veilid_state() -> Result<VeilidState, VeilidAPIError> {
#[derive(Debug)]
pub struct VeilidState {
attachment: AttachmentState,
}
impl VeilidState {
fn from_core(veilid_state: veilid_core::VeilidState) -> Self {
Self {
attachment: AttachmentState::from_core(veilid_state.attachment)
}
}
}
type Result<T> = std::result::Result<T, VeilidAPIError>;
/////////////////////////////////////////
pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig) -> Result<VeilidState> {
let core = veilid_core::VeilidCore::new();
// convert config to hashmap
let config_map = HashMap::<String, Box<dyn core::any::Any + 'static>>::new();
macro_rules! get_config {
($key:expr) => {
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($key.clone()));
}
}
macro_rules! default_config {
($key:expr, $default_value:expr) => {
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($default_value));
}
}
get_config!(config.program_name);
get_config!(config.namespace);
get_config!(config.capabilities.protocol_udp);
get_config!(config.capabilities.protocol_connect_tcp);
get_config!(config.capabilities.protocol_accept_tcp);
get_config!(config.capabilities.protocol_connect_ws);
get_config!(config.capabilities.protocol_accept_ws);
get_config!(config.capabilities.protocol_connect_wss);
get_config!(config.capabilities.protocol_accept_wss);
get_config!(config.table_store.directory);
get_config!(config.table_store.delete);
get_config!(config.block_store.directory);
get_config!(config.block_store.delete);
get_config!(config.protected_store.allow_insecure_fallback);
get_config!(config.protected_store.always_use_insecure_storage);
get_config!(config.protected_store.insecure_fallback_directory);
get_config!(config.protected_store.delete);
get_config!(config.network.node_id);
get_config!(config.network.node_id_secret);
get_config!(config.network.max_connections);
get_config!(config.network.connection_initial_timeout);
get_config!(config.network.bootstrap);
get_config!(config.network.dht.resolve_node_timeout);
get_config!(config.network.dht.resolve_node_count);
get_config!(config.network.dht.resolve_node_fanout);
get_config!(config.network.dht.max_find_node_count);
get_config!(config.network.dht.get_value_timeout);
get_config!(config.network.dht.get_value_count);
get_config!(config.network.dht.get_value_fanout);
get_config!(config.network.dht.set_value_timeout);
get_config!(config.network.dht.set_value_count);
get_config!(config.network.dht.set_value_fanout);
get_config!(config.network.dht.min_peer_count);
get_config!(config.network.dht.min_peer_refresh_time);
get_config!(config.network.dht.validate_dial_info_receipt_time);
get_config!(config.network.rpc.concurrency);
get_config!(config.network.rpc.queue_size);
get_config!(config.network.rpc.max_timestamp_behind);
get_config!(config.network.rpc.max_timestamp_ahead);
get_config!(config.network.rpc.timeout);
get_config!(config.network.rpc.max_route_hop_count);
get_config!(config.network.upnp);
get_config!(config.network.natpmp);
get_config!(config.network.enable_local_peer_scope);
get_config!(config.network.restricted_nat_retries);
default_config!(config.network.tls.certificate_path, "");
default_config!(config.network.tls.private_key_path, "");
default_config!(config.network.tls.connection_initial_timeout, 0u64);
default_config!(config.network.application.https.enabled, false);
default_config!(config.network.application.https.listen_address, "");
default_config!(config.network.application.https.path, "");
default_config!(config.network.application.https.url, Option::<String>::None);
default_config!(config.network.application.http.enabled, false);
default_config!(config.network.application.http.listen_address, "");
default_config!(config.network.application.http.path, "");
default_config!(config.network.application.http.url, Option::<String>::None);
get_config!(config.network.protocol.udp.enabled);
get_config!(config.network.protocol.udp.socket_pool_size);
get_config!(config.network.protocol.udp.listen_address);
get_config!(config.network.protocol.udp.public_address);
get_config!(config.network.protocol.tcp.connect);
get_config!(config.network.protocol.tcp.listen);
get_config!(config.network.protocol.tcp.max_connections);
get_config!(config.network.protocol.tcp.listen_address);
get_config!(config.network.protocol.tcp.public_address);
get_config!(config.network.protocol.ws.connect);
get_config!(config.network.protocol.ws.listen);
get_config!(config.network.protocol.ws.max_connections);
get_config!(config.network.protocol.ws.listen_address);
get_config!(config.network.protocol.ws.path);
get_config!(config.network.protocol.ws.url);
get_config!(config.network.protocol.wss.connect);
default_config!(config.network.protocol.wss.listen, false);
get_config!(config.network.protocol.wss.max_connections);
default_config!(config.network.protocol.wss.listen_address, "");
default_config!(config.network.protocol.wss.path, "");
default_config!(config.network.protocol.wss.url, Option::<String>::None);
get_config!(config.network.leases.max_server_signal_leases);
get_config!(config.network.leases.max_server_relay_leases);
get_config!(config.network.leases.max_client_signal_leases);
get_config!(config.network.leases.max_client_relay_leases);
let setup = veilid_core::VeilidCoreSetup {
update_callback: Arc::new(
move |update: veilid_core::VeilidUpdate| -> veilid_core::SystemPinBoxFuture<()> {
Box::pin(async move {
if !sink.add(VeilidUpdate::from_core(update)) {
error!("error sending veilid update callback");
}
})
},
),
config_callback: Arc::new(
move |key| {
config_map.get(&key).ok_or_else(|| {
let err = format!("config key '{}' doesn't exist", key);
error!("{}",err);
err
}).map(|v| {
*v.clone()
})
}
),
};
async_std::task::block_on( async {
let api = core.startup(setup).await.map_err(|e| VeilidAPIError::InvalidConfig(e.clone()))?;
let core_state = api.get_state().await.map_err(VeilidAPIError::from_core)?;
Ok(VeilidState::from_core(core_state))
})
}
pub fn get_veilid_state() -> Result<VeilidState> {
}
// xxx api functions
pub fn shutdown_veilid_core() -> Result<(), VeilidAPIError> {
pub fn shutdown_veilid_core() -> Result<()> {
}

View File

@ -744,7 +744,7 @@ impl Settings {
Arc::new(move |key: String| {
let inner = inner.read();
let out: Result<Box<dyn core::any::Any>, String> = match key.as_str() {
let out: Result<Box<dyn core::any::Any + Send>, String> = match key.as_str() {
"program_name" => Ok(Box::new("veilid-server".to_owned())),
"namespace" => Ok(Box::new(if inner.testing.subnode_index == 0 {
"".to_owned()