This commit is contained in:
John Smith
2022-02-06 21:18:42 -05:00
parent d660d86884
commit 70960fa592
53 changed files with 2062 additions and 2316 deletions
+7 -15
View File
@@ -1,6 +1,6 @@
use crate::core_context::*;
use crate::intf::*;
use crate::veilid_api::*;
use crate::veilid_core::*;
use crate::xx::*;
use log::{set_boxed_logger, set_max_level, Level, LevelFilter, Log, Metadata, Record};
use once_cell::sync::OnceCell;
@@ -23,20 +23,12 @@ impl ApiLogger {
fn new_inner(level: LevelFilter, update_callback: UpdateCallback) -> ApiLoggerInner {
let (tx, rx) = async_channel::unbounded::<(VeilidLogLevel, String)>();
let _join_handle: JoinHandle<()> = spawn(async move {
loop {
match rx.recv().await {
Ok(v) => {
(update_callback)(VeilidUpdate::Log {
log_level: v.0,
message: v.1,
})
.await;
}
Err(_) => {
// Nothing to be done here...
break;
}
}
while let Ok(v) = rx.recv().await {
(update_callback)(VeilidUpdate::Log {
log_level: v.0,
message: v.1,
})
.await;
}
});
ApiLoggerInner {
+15 -20
View File
@@ -6,9 +6,10 @@ use crate::xx::*;
use crate::*;
use core::convert::TryFrom;
use core::fmt;
use serde::*;
state_machine! {
derive(Debug, PartialEq, Eq, Clone, Copy)
derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)
pub Attachment(Detached)
//---
Detached(AttachRequested) => Attaching [StartAttachment],
@@ -102,8 +103,6 @@ impl TryFrom<String> for AttachmentState {
pub struct AttachmentManagerInner {
config: VeilidConfig,
table_store: TableStore,
crypto: Crypto,
attachment_machine: CallbackStateMachine<Attachment>,
network_manager: NetworkManager,
maintain_peers: bool,
@@ -125,8 +124,6 @@ impl AttachmentManager {
) -> AttachmentManagerInner {
AttachmentManagerInner {
config: config.clone(),
table_store: table_store.clone(),
crypto: crypto.clone(),
attachment_machine: CallbackStateMachine::new(),
network_manager: NetworkManager::new(config, table_store, crypto),
maintain_peers: false,
@@ -145,14 +142,6 @@ impl AttachmentManager {
self.inner.lock().config.clone()
}
pub fn table_store(&self) -> TableStore {
self.inner.lock().table_store.clone()
}
pub fn crypto(&self) -> Crypto {
self.inner.lock().crypto.clone()
}
pub fn network_manager(&self) -> NetworkManager {
self.inner.lock().network_manager.clone()
}
@@ -274,20 +263,26 @@ impl AttachmentManager {
&self,
state_change_callback: StateChangeCallback<Attachment>,
) -> Result<(), String> {
let inner = self.inner.lock();
inner
.attachment_machine
.set_state_change_callback(state_change_callback);
let network_manager = {
let inner = self.inner.lock();
inner
.attachment_machine
.set_state_change_callback(state_change_callback);
inner.network_manager.clone()
};
inner.network_manager.init().await?;
network_manager.init().await?;
Ok(())
}
pub async fn terminate(&self) {
// Ensure we detached
self.detach().await;
let inner = self.inner.lock();
inner.network_manager.terminate().await;
let network_manager = {
let inner = self.inner.lock();
inner.network_manager.clone()
};
network_manager.terminate().await;
}
fn attach(&self) {
+197
View File
@@ -0,0 +1,197 @@
use crate::api_logger::*;
use crate::attachment_manager::*;
use crate::dht::crypto::Crypto;
use crate::intf::*;
use crate::veilid_api::*;
use crate::veilid_config::*;
use crate::xx::*;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) -> SystemPinBoxFuture<()>>;
} else {
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) -> SystemPinBoxFuture<()> + Send + Sync>;
}
}
pub struct VeilidCoreSetup {
pub update_callback: UpdateCallback,
pub config_callback: ConfigCallback,
}
pub struct VeilidCoreContext {
pub config: VeilidConfig,
pub protected_store: ProtectedStore,
pub table_store: TableStore,
pub block_store: BlockStore,
pub crypto: Crypto,
pub attachment_manager: AttachmentManager,
}
impl VeilidCoreContext {
async fn new(setup: VeilidCoreSetup) -> Result<VeilidCoreContext, VeilidAPIError> {
// Start up api logging early if it's in the config
let api_log_level: VeilidConfigLogLevel =
*(setup.config_callback)("api_log_level".to_owned())
.map_err(|e| VeilidAPIError::ParseError {
message: "Failed to get api_log_level".to_owned(),
value: e,
})?
.downcast()
.map_err(|e| VeilidAPIError::ParseError {
message: "Incorrect type for key 'api_log_level'".to_owned(),
value: format!("Invalid type: {:?}", e.type_id()),
})?;
if api_log_level != VeilidConfigLogLevel::Off {
ApiLogger::init(
api_log_level.to_level_filter(),
setup.update_callback.clone(),
);
for ig in crate::DEFAULT_LOG_IGNORE_LIST {
ApiLogger::add_filter_ignore_str(ig);
}
}
trace!("VeilidCoreContext::new starting");
cfg_if! {
if #[cfg(target_os = "android")] {
if utils::android::ANDROID_GLOBALS.lock().is_none() {
error!("Android globals are not set up");
return Err("Android globals are not set up".to_owned());
}
}
}
// Set up config
trace!("VeilidCoreContext::new init config");
let mut config = VeilidConfig::new();
if let Err(e) = config.init(setup.config_callback).await {
ApiLogger::terminate();
return Err(VeilidAPIError::Internal(e));
}
// Set up protected store
trace!("VeilidCoreContext::new init protected store");
let protected_store = ProtectedStore::new(config.clone());
if let Err(e) = protected_store.init().await {
config.terminate().await;
ApiLogger::terminate();
return Err(VeilidAPIError::Internal(e));
}
// Init node id from config now that protected store is set up
if let Err(e) = config.init_node_id(protected_store.clone()).await {
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
return Err(VeilidAPIError::Internal(e));
}
// Set up tablestore
trace!("VeilidCoreContext::new init table store");
let table_store = TableStore::new(config.clone());
if let Err(e) = table_store.init().await {
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
return Err(VeilidAPIError::Internal(e));
}
// Set up crypto
trace!("VeilidCoreContext::new init crypto");
let crypto = Crypto::new(config.clone(), table_store.clone());
if let Err(e) = crypto.init().await {
table_store.terminate().await;
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
return Err(VeilidAPIError::Internal(e));
}
// Set up block store
trace!("VeilidCoreContext::new init block store");
let block_store = BlockStore::new(config.clone());
if let Err(e) = block_store.init().await {
crypto.terminate().await;
table_store.terminate().await;
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
return Err(VeilidAPIError::Internal(e));
}
// Set up attachment manager
trace!("VeilidCoreContext::new init attachment manager");
let cb = setup.update_callback;
let attachment_manager =
AttachmentManager::new(config.clone(), table_store.clone(), crypto.clone());
if let Err(e) = attachment_manager
.init(Arc::new(
move |_old_state: AttachmentState, new_state: AttachmentState| {
cb(VeilidUpdate::Attachment(new_state))
},
))
.await
{
block_store.terminate().await;
crypto.terminate().await;
table_store.terminate().await;
protected_store.terminate().await;
config.terminate().await;
ApiLogger::terminate();
return Err(VeilidAPIError::Internal(e));
}
Ok(VeilidCoreContext {
config,
protected_store,
table_store,
block_store,
crypto,
attachment_manager,
})
}
async fn shutdown(self) {
trace!("VeilidCoreContext::terminate_core_context starting");
self.attachment_manager.terminate().await;
self.block_store.terminate().await;
self.crypto.terminate().await;
self.table_store.terminate().await;
self.protected_store.terminate().await;
self.config.terminate().await;
trace!("VeilidCoreContext::shutdown complete");
ApiLogger::terminate();
}
}
/////////////////////////////////////////////////////////////////////////////
static INITIALIZED: AsyncMutex<bool> = AsyncMutex::new(false);
pub async fn api_startup(setup: VeilidCoreSetup) -> Result<VeilidAPI, VeilidAPIError> {
// See if we have an API started up already
let mut initialized_lock = INITIALIZED.lock().await;
if *initialized_lock {
return Err(VeilidAPIError::AlreadyInitialized);
}
// Create core context
let context = VeilidCoreContext::new(setup).await?;
// Return an API object around our context
let veilid_api = VeilidAPI::new(context);
*initialized_lock = true;
Ok(veilid_api)
}
pub async fn api_shutdown(context: VeilidCoreContext) {
let mut initialized_lock = INITIALIZED.lock().await;
context.shutdown().await;
*initialized_lock = false;
}
+40 -39
View File
@@ -94,38 +94,43 @@ impl Crypto {
trace!("Crypto::init");
// make local copy of node id for easy access
let mut inner = self.inner.lock();
let c = self.config.get();
inner.node_id = c.network.node_id;
inner.node_id_secret = c.network.node_id_secret;
let (table_store, node_id) = {
let mut inner = self.inner.lock();
let c = self.config.get();
inner.node_id = c.network.node_id;
inner.node_id_secret = c.network.node_id_secret;
(inner.table_store.clone(), c.network.node_id)
};
// load caches if they are valid for this node id
let mut db = inner.table_store.open("crypto_caches", 1).await?;
let mut db = table_store.open("crypto_caches", 1).await?;
let caches_valid = match db.load(0, b"node_id").await? {
Some(v) => v.as_slice() == inner.node_id.bytes,
Some(v) => v.as_slice() == node_id.bytes,
None => false,
};
if caches_valid {
if let Some(b) = db.load(0, b"dh_cache").await? {
let mut inner = self.inner.lock();
bytes_to_cache(&b, &mut inner.dh_cache);
}
} else {
drop(db);
inner.table_store.delete("crypto_caches").await?;
db = inner.table_store.open("crypto_caches", 1).await?;
db.store(0, b"node_id", &inner.node_id.bytes).await?;
table_store.delete("crypto_caches").await?;
db = table_store.open("crypto_caches", 1).await?;
db.store(0, b"node_id", &node_id.bytes).await?;
}
// Schedule flushing
let this = self.clone();
inner.flush_future = Some(Box::pin(interval(60000, move || {
let flush_future = interval(60000, move || {
let this = this.clone();
async move {
if let Err(e) = this.flush().await {
warn!("flush failed: {}", e);
}
}
})));
});
self.inner.lock().flush_future = Some(flush_future);
Ok(())
}
@@ -161,21 +166,23 @@ impl Crypto {
};
}
fn ed25519_to_x25519_pk(key: &ed::PublicKey) -> Result<xd::PublicKey, ()> {
fn ed25519_to_x25519_pk(key: &ed::PublicKey) -> Result<xd::PublicKey, String> {
let bytes = key.to_bytes();
let compressed = cd::edwards::CompressedEdwardsY(bytes);
let point = compressed.decompress().ok_or(())?;
let point = compressed
.decompress()
.ok_or_else(fn_string!("ed25519_to_x25519_pk failed"))?;
let mp = point.to_montgomery();
Ok(xd::PublicKey::from(mp.to_bytes()))
}
fn ed25519_to_x25519_sk(key: &ed::SecretKey) -> Result<xd::StaticSecret, ()> {
fn ed25519_to_x25519_sk(key: &ed::SecretKey) -> Result<xd::StaticSecret, String> {
let exp = ed::ExpandedSecretKey::from(key);
let bytes: [u8; ed::EXPANDED_SECRET_KEY_LENGTH] = exp.to_bytes();
let lowbytes: [u8; 32] = bytes[0..32].try_into().map_err(drop)?;
let lowbytes: [u8; 32] = bytes[0..32].try_into().map_err(map_to_string)?;
Ok(xd::StaticSecret::from(lowbytes))
}
pub fn cached_dh(&self, key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, ()> {
pub fn cached_dh(&self, key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, String> {
if let Some(c) = self
.inner
.lock()
@@ -197,24 +204,12 @@ impl Crypto {
///////////
// These are safe to use regardless of initialization status
pub fn compute_dh(key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, ()> {
pub fn compute_dh(key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, String> {
assert!(key.valid);
assert!(secret.valid);
let pk_ed = match ed::PublicKey::from_bytes(&key.bytes) {
Ok(v) => v,
Err(e) => {
trace!("compute_dh error: {:?}", e);
return Err(());
}
};
let pk_ed = ed::PublicKey::from_bytes(&key.bytes).map_err(map_to_string)?;
let pk_xd = Self::ed25519_to_x25519_pk(&pk_ed)?;
let sk_ed = match ed::SecretKey::from_bytes(&secret.bytes) {
Ok(v) => v,
Err(e) => {
trace!("compute_dh error: {:?}", e);
return Err(());
}
};
let sk_ed = ed::SecretKey::from_bytes(&secret.bytes).map_err(map_to_string)?;
let sk_xd = Self::ed25519_to_x25519_sk(&sk_ed)?;
Ok(sk_xd.diffie_hellman(&pk_xd).to_bytes())
}
@@ -236,12 +231,13 @@ impl Crypto {
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> Result<(), ()> {
) -> Result<(), String> {
let key = ch::Key::from(*shared_secret);
let xnonce = ch::XNonce::from(*nonce);
let aead = ch::XChaCha20Poly1305::new(&key);
aead.decrypt_in_place(&xnonce, associated_data.unwrap_or(b""), body)
.map_err(|e| trace!("decryption failure: {}", e))
.map_err(map_to_string)
.map_err(logthru_crypto!())
}
pub fn decrypt(
@@ -249,9 +245,11 @@ impl Crypto {
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> Result<Vec<u8>, ()> {
) -> Result<Vec<u8>, String> {
let mut out = body.to_vec();
Self::decrypt_in_place(&mut out, nonce, shared_secret, associated_data)?;
Self::decrypt_in_place(&mut out, nonce, shared_secret, associated_data)
.map_err(map_to_string)
.map_err(logthru_crypto!())?;
Ok(out)
}
@@ -260,13 +258,14 @@ impl Crypto {
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> Result<(), ()> {
) -> Result<(), String> {
let key = ch::Key::from(*shared_secret);
let xnonce = ch::XNonce::from(*nonce);
let aead = ch::XChaCha20Poly1305::new(&key);
aead.encrypt_in_place(&xnonce, associated_data.unwrap_or(b""), body)
.map_err(|e| trace!("encryption failure: {}", e))
.map_err(map_to_string)
.map_err(logthru_crypto!())
}
pub fn encrypt(
@@ -274,9 +273,11 @@ impl Crypto {
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> Result<Vec<u8>, ()> {
) -> Result<Vec<u8>, String> {
let mut out = body.to_vec();
Self::encrypt_in_place(&mut out, nonce, shared_secret, associated_data)?;
Self::encrypt_in_place(&mut out, nonce, shared_secret, associated_data)
.map_err(map_to_string)
.map_err(logthru_crypto!())?;
Ok(out)
}
}
+1 -1
View File
@@ -172,7 +172,7 @@ impl Envelope {
crypto: Crypto,
data: &[u8],
node_id_secret: &DHTKeySecret,
) -> Result<Vec<u8>, ()> {
) -> Result<Vec<u8>, String> {
// Get DH secret
let dh_secret = crypto.cached_dh(&self.sender_id, node_id_secret)?;
+30 -2
View File
@@ -1,2 +1,30 @@
//use crate::intf::*;
//use crate::xx::*;
use crate::intf::*;
use crate::*;
struct BlockStoreInner {
//
}
#[derive(Clone)]
pub struct BlockStore {
config: VeilidConfig,
inner: Arc<Mutex<BlockStoreInner>>,
}
impl BlockStore {
fn new_inner() -> BlockStoreInner {
BlockStoreInner {}
}
pub fn new(config: VeilidConfig) -> Self {
Self {
config,
inner: Arc::new(Mutex::new(Self::new_inner())),
}
}
pub async fn init(&self) -> Result<(), String> {
Ok(())
}
pub async fn terminate(&self) {}
}
+1 -1
View File
@@ -2,7 +2,7 @@ mod block_store;
mod network;
mod protected_store;
mod system;
pub mod table_store;
mod table_store;
pub mod utils;
pub use block_store::*;
@@ -44,8 +44,8 @@ impl ProtectedStore {
}
pub async fn init(&self) -> Result<(), String> {
let c = self.config.get();
{
let delete = {
let c = self.config.get();
let mut inner = self.inner.lock();
if !c.protected_store.always_use_insecure_storage {
cfg_if! {
@@ -74,9 +74,10 @@ impl ProtectedStore {
if inner.keyring_manager.is_none() {
return Err("Could not initialize the protected store.".to_owned());
}
}
c.protected_store.delete
};
if c.protected_store.delete {
if delete {
self.delete_all().await?;
}
@@ -24,29 +24,6 @@ lazy_static! {
}
pub fn veilid_core_setup_android_no_log<'a>(env: JNIEnv<'a>, ctx: JObject<'a>) {
panic::set_hook(Box::new(|panic_info| {
let bt = Backtrace::new();
if let Some(location) = panic_info.location() {
error!(
"panic occurred in file '{}' at line {}",
location.file(),
location.line(),
);
} else {
error!("panic occurred but can't get location information...");
}
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
error!("panic payload: {:?}", s);
} else if let Some(s) = panic_info.payload().downcast_ref::<String>() {
error!("panic payload: {:?}", s);
} else if let Some(a) = panic_info.payload().downcast_ref::<std::fmt::Arguments>() {
error!("panic payload: {:?}", a);
} else {
error!("no panic payload");
}
error!("Backtrace:\n{:?}", bt);
}));
*ANDROID_GLOBALS.lock() = Some(AndroidGlobals {
vm: env.get_java_vm().unwrap(),
ctx: env.new_global_ref(ctx).unwrap(),
@@ -70,6 +47,29 @@ pub fn veilid_core_setup_android<'a>(
),
);
panic::set_hook(Box::new(|panic_info| {
let bt = Backtrace::new();
if let Some(location) = panic_info.location() {
error!(
"panic occurred in file '{}' at line {}",
location.file(),
location.line(),
);
} else {
error!("panic occurred but can't get location information...");
}
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
error!("panic payload: {:?}", s);
} else if let Some(s) = panic_info.payload().downcast_ref::<String>() {
error!("panic payload: {:?}", s);
} else if let Some(a) = panic_info.payload().downcast_ref::<std::fmt::Arguments>() {
error!("panic payload: {:?}", a);
} else {
error!("no panic payload");
}
error!("Backtrace:\n{:?}", bt);
}));
veilid_core_setup_android_no_log(env, ctx);
}
+30
View File
@@ -1 +1,31 @@
use crate::intf::*;
use crate::*;
struct BlockStoreInner {
//
}
#[derive(Clone)]
pub struct BlockStore {
config: VeilidConfig,
inner: Arc<Mutex<BlockStoreInner>>,
}
impl BlockStore {
fn new_inner() -> BlockStoreInner {
BlockStoreInner {}
}
pub fn new(config: VeilidConfig) -> Self {
Self {
config,
inner: Arc::new(Mutex::new(Self::new_inner())),
}
}
pub async fn init(&self) -> Result<(), String> {
Ok(())
}
pub async fn terminate(&self) {}
}
@@ -78,7 +78,7 @@ impl WebsocketProtocolHandler {
assert!(local_address.is_none());
// Split dial info up
let (tls, scheme) = match &dial_info {
let (_tls, scheme) = match &dial_info {
DialInfo::WS(_) => (false, "ws"),
DialInfo::WSS(_) => (true, "wss"),
_ => panic!("invalid dialinfo for WS/WSS protocol"),
+3 -3
View File
@@ -9,6 +9,7 @@ mod attachment_manager;
mod callback_state_machine;
mod connection_manager;
mod connection_table;
mod core_context;
mod dht;
mod intf;
mod lease_manager;
@@ -19,16 +20,15 @@ mod routing_table;
mod rpc_processor;
mod veilid_api;
mod veilid_config;
mod veilid_core;
mod veilid_rng;
#[macro_use]
pub mod xx;
pub use self::attachment_manager::AttachmentState;
pub use self::core_context::{api_startup, VeilidCoreSetup};
pub use self::veilid_api::*;
pub use self::veilid_config::*;
pub use self::veilid_core::{VeilidCore, VeilidCoreSetup};
pub mod veilid_capnp {
include!(concat!(env!("OUT_DIR"), "/proto/veilid_capnp.rs"));
@@ -47,7 +47,7 @@ pub fn veilid_version() -> (u32, u32, u32) {
)
}
pub static DEFAULT_LOG_IGNORE_LIST: [&'static str; 8] = [
pub static DEFAULT_LOG_IGNORE_LIST: [&str; 8] = [
"async_std",
"async_io",
"polling",
+5 -3
View File
@@ -170,10 +170,12 @@ impl NetworkManager {
Ok(())
}
pub async fn terminate(&self) {
let mut inner = self.inner.lock();
if let Some(routing_table) = &inner.routing_table {
let routing_table = {
let mut inner = self.inner.lock();
inner.routing_table.take()
};
if let Some(routing_table) = routing_table {
routing_table.terminate().await;
inner.routing_table = None;
}
}
+4 -6
View File
@@ -19,10 +19,9 @@ fn setup_veilid_core() -> VeilidCoreSetup {
}
}
async fn startup(core: VeilidCore) -> VeilidAPI {
async fn startup() -> VeilidAPI {
trace!("test_table_store: starting");
let api = core
.startup(setup_veilid_core())
let api = api_startup(setup_veilid_core())
.await
.expect("startup failed");
api
@@ -130,9 +129,8 @@ pub async fn test_dh(crypto: Crypto) {
}
pub async fn test_all() {
let core = VeilidCore::new();
let api = startup(core.clone()).await;
let crypto = core.crypto();
let api = startup().await;
let crypto = api.crypto().unwrap();
test_enc_dec().await;
test_dh(crypto).await;
shutdown(api.clone()).await;
@@ -8,13 +8,12 @@ use crate::*;
pub async fn test_envelope_round_trip() {
info!("--- test envelope round trip ---");
let veilid_core = VeilidCore::new();
let api = veilid_core
.startup(setup_veilid_core())
let api = api_startup(setup_veilid_core())
.await
.expect("startup failed");
// Get crypto
let crypto = veilid_core.crypto();
let crypto = api.crypto().unwrap();
// Create envelope
let ts = 0x12345678ABCDEF69u64;
@@ -16,9 +16,9 @@ fn setup_veilid_core() -> VeilidCoreSetup {
}
}
async fn startup(core: VeilidCore) -> VeilidAPI {
async fn startup() -> VeilidAPI {
trace!("test_table_store: starting");
core.startup(setup_veilid_core())
api_startup(setup_veilid_core())
.await
.expect("startup failed")
}
@@ -93,10 +93,8 @@ pub async fn test_protected_store(ps: ProtectedStore) {
}
pub async fn test_all() {
let core = VeilidCore::new();
let api = startup(core.clone()).await;
let ps = core.protected_store();
let api = startup().await;
let ps = api.protected_store().unwrap();
test_protected_store(ps.clone()).await;
shutdown(api).await;
@@ -17,9 +17,9 @@ fn setup_veilid_core() -> VeilidCoreSetup {
}
}
async fn startup(core: VeilidCore) -> VeilidAPI {
async fn startup() -> VeilidAPI {
trace!("test_table_store: starting");
core.startup(setup_veilid_core())
api_startup(setup_veilid_core())
.await
.expect("startup failed")
}
@@ -169,10 +169,8 @@ pub async fn test_cbor(ts: TableStore) {
}
pub async fn test_all() {
let core = VeilidCore::new();
let api = startup(core.clone()).await;
let ts = core.table_store();
let api = startup().await;
let ts = api.table_store().unwrap();
test_delete_open_delete(ts.clone()).await;
test_store_delete_load(ts.clone()).await;
test_cbor(ts.clone()).await;
@@ -4,9 +4,7 @@ use crate::*;
pub async fn test_startup_shutdown() {
trace!("test_startup_shutdown: starting");
let veilid_core = VeilidCore::new();
let api = veilid_core
.startup(setup_veilid_core())
let api = api_startup(setup_veilid_core())
.await
.expect("startup failed");
trace!("test_startup_shutdown: shutting down");
@@ -15,11 +13,8 @@ pub async fn test_startup_shutdown() {
}
pub async fn test_attach_detach() {
let veilid_core = VeilidCore::new();
info!("--- test normal order ---");
let api = veilid_core
.startup(setup_veilid_core())
let api = api_startup(setup_veilid_core())
.await
.expect("startup failed");
api.attach().await.unwrap();
@@ -31,8 +26,7 @@ pub async fn test_attach_detach() {
api.shutdown().await;
info!("--- test auto detach ---");
let api = veilid_core
.startup(setup_veilid_core())
let api = api_startup(setup_veilid_core())
.await
.expect("startup failed");
api.attach().await.unwrap();
@@ -40,8 +34,7 @@ pub async fn test_attach_detach() {
api.shutdown().await;
info!("--- test detach without attach ---");
let api = veilid_core
.startup(setup_veilid_core())
let api = api_startup(setup_veilid_core())
.await
.expect("startup failed");
api.detach().await.unwrap();
+1
View File
@@ -2,6 +2,7 @@
// Debugging
use super::*;
use routing_table::*;
fn get_bucket_entry_state(text: &str) -> Option<BucketEntryState> {
if text == "dead" {
+134 -101
View File
@@ -3,28 +3,38 @@
mod debug;
pub use debug::*;
pub use crate::rpc_processor::InfoAnswer;
use crate::*;
use api_logger::*;
use attachment_manager::*;
use core::fmt;
use network_manager::NetworkManager;
use routing_table::*;
use rpc_processor::{RPCError, RPCProcessor};
use xx::*;
pub use crate::dht::key::{generate_secret, DHTKey, DHTKeySecret};
pub use crate::xx::{
IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, SystemPinBoxFuture,
ToSocketAddrs,
};
pub use alloc::string::ToString;
pub use attachment_manager::AttachmentManager;
pub use core::str::FromStr;
pub use dht::crypto::Crypto;
pub use dht::key::{generate_secret, DHTKey, DHTKeySecret};
pub use intf::BlockStore;
pub use intf::ProtectedStore;
pub use intf::TableStore;
pub use network_manager::NetworkManager;
pub use routing_table::RoutingTable;
pub use rpc_processor::InfoAnswer;
use api_logger::*;
use core::fmt;
use core_context::{api_shutdown, VeilidCoreContext};
use rpc_processor::{RPCError, RPCProcessor};
use serde::*;
use xx::*;
/////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Ord)]
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize)]
#[serde(tag = "kind")]
pub enum VeilidAPIError {
NotInitialized,
AlreadyInitialized,
Timeout,
Shutdown,
NodeNotFound(NodeId),
@@ -49,6 +59,8 @@ pub enum VeilidAPIError {
impl fmt::Display for VeilidAPIError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
VeilidAPIError::NotInitialized => write!(f, "VeilidAPIError::NotInitialized"),
VeilidAPIError::AlreadyInitialized => write!(f, "VeilidAPIError::AlreadyInitialized"),
VeilidAPIError::Timeout => write!(f, "VeilidAPIError::Timeout"),
VeilidAPIError::Shutdown => write!(f, "VeilidAPIError::Shutdown"),
VeilidAPIError::NodeNotFound(ni) => write!(f, "VeilidAPIError::NodeNotFound({})", ni),
@@ -107,7 +119,7 @@ macro_rules! parse_error {
/////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum VeilidLogLevel {
Error = 1,
Warn,
@@ -128,7 +140,8 @@ impl VeilidLogLevel {
}
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind")]
pub enum VeilidUpdate {
Log {
log_level: VeilidLogLevel,
@@ -137,14 +150,14 @@ pub enum VeilidUpdate {
Attachment(AttachmentState),
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VeilidState {
pub attachment: AttachmentState,
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
///
#[derive(Clone, Debug, Default, PartialOrd, PartialEq, Eq, Ord)]
#[derive(Clone, Debug, Default, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize)]
pub struct NodeId {
pub key: DHTKey,
}
@@ -160,7 +173,7 @@ impl fmt::Display for NodeId {
}
}
#[derive(Clone, Debug, Default, PartialOrd, PartialEq, Eq, Ord)]
#[derive(Clone, Debug, Default, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize)]
pub struct ValueKey {
pub key: DHTKey,
pub subkey: Option<String>,
@@ -181,7 +194,7 @@ impl ValueKey {
}
}
#[derive(Clone, Debug, Default, PartialOrd, PartialEq, Eq, Ord)]
#[derive(Clone, Debug, Default, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize)]
pub struct BlockId {
pub key: DHTKey,
}
@@ -193,12 +206,12 @@ impl BlockId {
/////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default, Serialize, Deserialize)]
pub struct SenderInfo {
pub socket_address: Option<SocketAddress>,
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct NodeInfo {
pub can_route: bool,
pub will_route: bool,
@@ -212,7 +225,7 @@ pub struct NodeInfo {
pub will_validate_dial_info: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize)]
// The derived ordering here is the order of preference, lower is preferred for connections
// Must match DialInfo order
pub enum ProtocolType {
@@ -222,13 +235,13 @@ pub enum ProtocolType {
WSS,
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize)]
pub enum AddressType {
IPV4,
IPV6,
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize)]
pub enum Address {
IPV4(Ipv4Addr),
IPV6(Ipv6Addr),
@@ -310,7 +323,9 @@ impl FromStr for Address {
}
}
#[derive(Copy, Default, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
#[derive(
Copy, Default, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize,
)]
pub struct SocketAddress {
address: Address,
port: u16,
@@ -366,7 +381,7 @@ impl FromStr for SocketAddress {
//////////////////////////////////////////////////////////////////
#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct DialInfoFilter {
pub peer_scope: PeerScope,
pub protocol_type: Option<ProtocolType>,
@@ -435,29 +450,30 @@ pub trait MatchesDialInfoFilter {
fn matches_filter(&self, filter: &DialInfoFilter) -> bool;
}
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize)]
pub struct DialInfoUDP {
pub socket_address: SocketAddress,
}
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize)]
pub struct DialInfoTCP {
pub socket_address: SocketAddress,
}
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize)]
pub struct DialInfoWS {
pub socket_address: SocketAddress,
pub request: String,
}
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Clone, Default, Debug, PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize)]
pub struct DialInfoWSS {
pub socket_address: SocketAddress,
pub request: String,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize)]
#[serde(tag = "kind")]
// The derived ordering here is the order of preference, lower is preferred for connections
// Must match ProtocolType order
pub enum DialInfo {
@@ -706,7 +722,7 @@ impl MatchesDialInfoFilter for DialInfo {
//////////////////////////////////////////////////////////////////////////
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
pub enum PeerScope {
All,
Global,
@@ -718,13 +734,13 @@ impl Default for PeerScope {
}
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct PeerInfo {
pub node_id: NodeId,
pub dial_infos: Vec<DialInfo>,
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub struct PeerAddress {
pub socket_address: SocketAddress,
pub protocol_type: ProtocolType,
@@ -747,7 +763,7 @@ impl PeerAddress {
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct ConnectionDescriptor {
pub remote: PeerAddress,
pub local: Option<SocketAddress>,
@@ -802,7 +818,7 @@ impl MatchesDialInfoFilter for ConnectionDescriptor {
//////////////////////////////////////////////////////////////////////////
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct NodeDialInfo {
pub node_id: NodeId,
pub dial_info: DialInfo,
@@ -837,20 +853,20 @@ impl FromStr for NodeDialInfo {
}
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct LatencyStats {
pub fastest: u64, // fastest latency in the ROLLING_LATENCIES_SIZE last latencies
pub average: u64, // average latency over the ROLLING_LATENCIES_SIZE last latencies
pub slowest: u64, // slowest latency in the ROLLING_LATENCIES_SIZE last latencies
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct TransferStatsDownUp {
pub down: TransferStats,
pub up: TransferStats,
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct TransferStats {
pub total: u64, // total amount transferred ever
pub maximum: u64, // maximum rate over the ROLLING_TRANSFERS_SIZE last amounts
@@ -858,7 +874,7 @@ pub struct TransferStats {
pub minimum: u64, // minimum rate over the ROLLING_TRANSFERS_SIZE last amounts
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct PingStats {
pub in_flight: u32, // number of pings issued that have yet to be answered
pub total_sent: u32, // number of pings that have been sent in the total_time range
@@ -869,7 +885,7 @@ pub struct PingStats {
pub recent_lost_pings: u32, // number of pings that have been lost since we lost reliability
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct PeerStats {
pub time_added: u64, // when the peer was added to the routing table
pub last_seen: Option<u64>, // when the peer was last seen for any reason, including when we first attempted to reach out to it
@@ -889,7 +905,7 @@ cfg_if! {
}
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Ord)]
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize)]
pub enum TunnelMode {
Raw,
Turn,
@@ -897,7 +913,7 @@ pub enum TunnelMode {
type TunnelId = u64;
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TunnelEndpoint {
pub node_id: NodeId, // the node id of the tunnel endpoint
pub dial_info: Vec<DialInfo>, // multiple ways of how to get to the node
@@ -914,7 +930,7 @@ impl Default for TunnelEndpoint {
}
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct FullTunnel {
pub id: TunnelId,
pub timeout: u64,
@@ -922,7 +938,7 @@ pub struct FullTunnel {
pub remote: TunnelEndpoint,
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct PartialTunnel {
pub id: TunnelId,
pub timeout: u64,
@@ -931,12 +947,12 @@ pub struct PartialTunnel {
/////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct RouteHopSpec {
pub dial_info: NodeDialInfo,
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct PrivateRouteSpec {
//
pub public_key: DHTKey,
@@ -944,7 +960,7 @@ pub struct PrivateRouteSpec {
pub hops: Vec<RouteHopSpec>,
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct SafetyRouteSpec {
pub public_key: DHTKey,
pub secret_key: DHTKeySecret,
@@ -962,7 +978,7 @@ impl SafetyRouteSpec {
}
}
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct RoutingContextOptions {
pub safety_route_spec: Option<SafetyRouteSpec>,
pub private_route_spec: Option<PrivateRouteSpec>,
@@ -970,7 +986,7 @@ pub struct RoutingContextOptions {
/////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct SearchDHTAnswer {
pub node_id: NodeId,
pub dial_info: Vec<DialInfo>,
@@ -1051,26 +1067,19 @@ impl RoutingContext {
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct VeilidAPIInner {
core: Option<VeilidCore>,
context: Option<VeilidCoreContext>,
}
impl fmt::Debug for VeilidAPIInner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"VeilidAPIInner: {}",
match self.core {
Some(_) => "active",
None => "shutdown",
}
)
write!(f, "VeilidAPIInner")
}
}
impl Drop for VeilidAPIInner {
fn drop(&mut self) {
if let Some(core) = self.core.take() {
intf::spawn_local(core.shutdown()).detach();
if let Some(context) = self.context.take() {
intf::spawn_local(api_shutdown(context)).detach();
}
}
}
@@ -1080,59 +1089,83 @@ pub struct VeilidAPI {
inner: Arc<Mutex<VeilidAPIInner>>,
}
#[derive(Clone, Debug, Default)]
pub struct VeilidAPIWeak {
inner: Weak<Mutex<VeilidAPIInner>>,
}
impl VeilidAPIWeak {
pub fn upgrade(&self) -> Option<VeilidAPI> {
self.inner.upgrade().map(|v| VeilidAPI { inner: v })
}
}
impl VeilidAPI {
pub(crate) fn new(core: VeilidCore) -> Self {
pub(crate) fn new(context: VeilidCoreContext) -> Self {
Self {
inner: Arc::new(Mutex::new(VeilidAPIInner { core: Some(core) })),
inner: Arc::new(Mutex::new(VeilidAPIInner {
context: Some(context),
})),
}
}
pub fn weak(&self) -> VeilidAPIWeak {
VeilidAPIWeak {
inner: Arc::downgrade(&self.inner),
}
}
fn core(&self) -> Result<VeilidCore, VeilidAPIError> {
Ok(self
.inner
.lock()
.core
.as_ref()
.ok_or(VeilidAPIError::Shutdown)?
.clone())
}
fn config(&self) -> Result<VeilidConfig, VeilidAPIError> {
Ok(self.core()?.config())
}
fn attachment_manager(&self) -> Result<AttachmentManager, VeilidAPIError> {
Ok(self.core()?.attachment_manager())
}
fn network_manager(&self) -> Result<NetworkManager, VeilidAPIError> {
Ok(self.attachment_manager()?.network_manager())
}
fn rpc_processor(&self) -> Result<RPCProcessor, VeilidAPIError> {
Ok(self.network_manager()?.rpc_processor())
}
pub async fn shutdown(self) {
let core = { self.inner.lock().core.take() };
if let Some(core) = core {
core.shutdown().await;
let context = { self.inner.lock().context.take() };
if let Some(context) = context {
api_shutdown(context).await;
}
}
pub fn is_shutdown(&self) -> bool {
self.inner.lock().core.is_none()
self.inner.lock().context.is_none()
}
////////////////////////////////////////////////////////////////
// Accessors
pub fn config(&self) -> Result<VeilidConfig, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.config.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn crypto(&self) -> Result<Crypto, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.crypto.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn table_store(&self) -> Result<TableStore, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.table_store.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn block_store(&self) -> Result<BlockStore, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.block_store.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn protected_store(&self) -> Result<ProtectedStore, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.protected_store.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn attachment_manager(&self) -> Result<AttachmentManager, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn network_manager(&self) -> Result<NetworkManager, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn rpc_processor(&self) -> Result<RPCProcessor, VeilidAPIError> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager().rpc_processor());
}
Err(VeilidAPIError::NotInitialized)
}
////////////////////////////////////////////////////////////////
+4 -2
View File
@@ -2,6 +2,8 @@ use crate::dht::key;
use crate::intf;
use crate::xx::*;
use serde::*;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub type ConfigCallbackReturn = Result<Box<dyn core::any::Any>, String>;
@@ -9,7 +11,7 @@ cfg_if! {
} else {
pub type ConfigCallbackReturn = Result<Box<dyn core::any::Any + Send>, String>;
pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn + Send>;
pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn + Send + Sync>;
}
}
@@ -172,7 +174,7 @@ pub struct VeilidConfigCapabilities {
pub protocol_accept_wss: bool,
}
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum VeilidConfigLogLevel {
Off,
Error,
-241
View File
@@ -1,241 +0,0 @@
use crate::api_logger::*;
use crate::attachment_manager::*;
use crate::dht::crypto::Crypto;
use crate::intf::*;
use crate::veilid_api::*;
use crate::veilid_config::*;
use crate::xx::*;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) -> SystemPinBoxFuture<()>>;
} else {
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) -> SystemPinBoxFuture<()> + Send + Sync>;
}
}
pub struct VeilidCoreSetup {
pub update_callback: UpdateCallback,
pub config_callback: ConfigCallback,
}
struct VeilidCoreInner {
config: Option<VeilidConfig>,
protected_store: Option<ProtectedStore>,
table_store: Option<TableStore>,
crypto: Option<Crypto>,
attachment_manager: Option<AttachmentManager>,
api: VeilidAPIWeak,
}
#[derive(Clone)]
pub struct VeilidCore {
inner: Arc<Mutex<VeilidCoreInner>>,
}
impl Default for VeilidCore {
fn default() -> Self {
Self::new()
}
}
impl VeilidCore {
fn new_inner() -> VeilidCoreInner {
VeilidCoreInner {
config: None,
table_store: None,
protected_store: None,
crypto: None,
attachment_manager: None,
api: VeilidAPIWeak::default(),
}
}
pub fn new() -> Self {
Self {
inner: Arc::new(Mutex::new(Self::new_inner())),
}
}
pub(crate) fn config(&self) -> VeilidConfig {
self.inner.lock().config.as_ref().unwrap().clone()
}
pub(crate) fn table_store(&self) -> TableStore {
self.inner.lock().table_store.as_ref().unwrap().clone()
}
pub(crate) fn protected_store(&self) -> ProtectedStore {
self.inner.lock().protected_store.as_ref().unwrap().clone()
}
pub(crate) fn crypto(&self) -> Crypto {
self.inner.lock().crypto.as_ref().unwrap().clone()
}
pub(crate) fn attachment_manager(&self) -> AttachmentManager {
self.inner
.lock()
.attachment_manager
.as_ref()
.unwrap()
.clone()
}
// internal startup
async fn internal_startup(
&self,
inner: &mut VeilidCoreInner,
setup: VeilidCoreSetup,
) -> Result<VeilidAPI, String> {
// Start up api logging early if it's in the config
let api_log_level: VeilidConfigLogLevel =
*(setup.config_callback)("api_log_level".to_owned())?
.downcast()
.map_err(|_| "incorrect type for key 'api_log_level'".to_owned())?;
if api_log_level != VeilidConfigLogLevel::Off {
ApiLogger::init(
api_log_level.to_level_filter(),
setup.update_callback.clone(),
);
for ig in crate::DEFAULT_LOG_IGNORE_LIST {
ApiLogger::add_filter_ignore_str(ig);
}
}
trace!("VeilidCore::internal_startup starting");
cfg_if! {
if #[cfg(target_os = "android")] {
if utils::android::ANDROID_GLOBALS.lock().is_none() {
error!("Android globals are not set up");
return Err("Android globals are not set up".to_owned());
}
}
}
// Set up config
trace!("VeilidCore::internal_startup init config");
let mut config = VeilidConfig::new();
config.init(setup.config_callback).await?;
inner.config = Some(config.clone());
// Set up protected store
trace!("VeilidCore::internal_startup init protected store");
let protected_store = ProtectedStore::new(config.clone());
protected_store.init().await?;
inner.protected_store = Some(protected_store.clone());
// Init node id from config now that protected store is set up
config.init_node_id(protected_store).await?;
// Set up tablestore
trace!("VeilidCore::internal_startup init table store");
let table_store = TableStore::new(config.clone());
table_store.init().await?;
inner.table_store = Some(table_store.clone());
// Set up crypto
trace!("VeilidCore::internal_startup init crypto");
let crypto = Crypto::new(config.clone(), table_store.clone());
crypto.init().await?;
inner.crypto = Some(crypto.clone());
// Set up block store
// trace!("VeilidCore::internal_startup init block store");
// let block_store = BlockStore::new(config.clone());
// block_store.init().await?;
// inner.block_store = Some(block_store.clone();)
// Set up attachment manager
trace!("VeilidCore::internal_startup init attachment manager");
let cb = setup.update_callback;
let attachment_manager =
AttachmentManager::new(config.clone(), table_store.clone(), crypto.clone());
attachment_manager
.init(Arc::new(
move |_old_state: AttachmentState, new_state: AttachmentState| {
cb(VeilidUpdate::Attachment(new_state))
},
))
.await?;
inner.attachment_manager = Some(attachment_manager.clone());
// Set up the API
trace!("VeilidCore::internal_startup init API");
let this = self.clone();
let veilid_api = VeilidAPI::new(this);
inner.api = veilid_api.weak();
trace!("VeilidCore::internal_startup complete");
Ok(veilid_api)
}
// called once at the beginning to start the node
pub async fn startup(&self, setup: VeilidCoreSetup) -> Result<VeilidAPI, String> {
// See if we have an API started up already
let mut inner = self.inner.lock();
if inner.api.upgrade().is_some() {
// If so, return an error because we shouldn't try to do this more than once
return Err("Veilid API is started".to_owned());
}
// Ensure we never end up partially initialized
match self.internal_startup(&mut *inner, setup).await {
Ok(v) => Ok(v),
Err(e) => {
Self::internal_shutdown(&mut *inner).await;
Err(e)
}
}
}
async fn internal_shutdown(inner: &mut VeilidCoreInner) {
trace!("VeilidCore::internal_shutdown starting");
// Detach the API object
inner.api = VeilidAPIWeak::default();
// Shut down up attachment manager
if let Some(attachment_manager) = &inner.attachment_manager {
attachment_manager.terminate().await;
inner.attachment_manager = None;
}
// Shut down crypto
if let Some(crypto) = &inner.crypto {
crypto.terminate().await;
inner.crypto = None;
}
// Shut down table store
if let Some(table_store) = &inner.table_store {
table_store.terminate().await;
inner.table_store = None;
}
// Shut down protected store
if let Some(protected_store) = &inner.protected_store {
protected_store.terminate().await;
inner.protected_store = None;
}
// Shut down config
if let Some(config) = &inner.config {
config.terminate().await;
inner.config = None;
}
trace!("VeilidCore::shutdown complete");
ApiLogger::terminate();
}
// stop the node gracefully because the veilid api was dropped
pub(crate) async fn shutdown(self) {
let mut inner = self.inner.lock();
Self::internal_shutdown(&mut *inner).await;
}
//
}
+12
View File
@@ -158,6 +158,18 @@ macro_rules! logthru_pstore {
logthru!($($level)? "pstore", $fmt, $($arg),+)
}
}
#[macro_export]
macro_rules! logthru_crypto {
($($level:ident)?) => {
logthru!($($level)? "crypto")
};
($($level:ident)? $text:literal) => {
logthru!($($level)? "crypto", $text)
};
($($level:ident)? $fmt:literal, $($arg:expr),+) => {
logthru!($($level)? "crypto", $fmt, $($arg),+)
}
}
#[macro_export]
macro_rules! logthru {