veilid/veilid-core/src/veilid_api/api.rs

299 lines
9.7 KiB
Rust
Raw Normal View History

2022-11-26 16:17:30 -05:00
use super::*;
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct VeilidAPIInner {
context: Option<VeilidCoreContext>,
}
impl fmt::Debug for VeilidAPIInner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "VeilidAPIInner")
}
}
impl Drop for VeilidAPIInner {
fn drop(&mut self) {
if let Some(context) = self.context.take() {
2022-11-26 21:37:23 -05:00
spawn_detached(api_shutdown(context));
2022-11-26 16:17:30 -05:00
}
}
}
#[derive(Clone, Debug)]
pub struct VeilidAPI {
inner: Arc<Mutex<VeilidAPIInner>>,
}
impl VeilidAPI {
#[instrument(skip_all)]
pub(crate) fn new(context: VeilidCoreContext) -> Self {
Self {
inner: Arc::new(Mutex::new(VeilidAPIInner {
context: Some(context),
})),
}
}
#[instrument(skip_all)]
pub async fn shutdown(self) {
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().context.is_none()
}
////////////////////////////////////////////////////////////////
// Accessors
2023-05-29 15:24:57 -04:00
pub fn config(&self) -> VeilidAPIResult<VeilidConfig> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.config.clone());
}
Err(VeilidAPIError::NotInitialized)
}
2023-05-29 15:24:57 -04:00
pub fn crypto(&self) -> VeilidAPIResult<Crypto> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.crypto.clone());
}
Err(VeilidAPIError::NotInitialized)
}
2023-05-29 15:24:57 -04:00
pub fn table_store(&self) -> VeilidAPIResult<TableStore> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.table_store.clone());
}
Err(VeilidAPIError::not_initialized())
}
2023-06-04 21:22:55 -04:00
#[cfg(feature = "unstable-blockstore")]
2023-05-29 15:24:57 -04:00
pub fn block_store(&self) -> VeilidAPIResult<BlockStore> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.block_store.clone());
}
Err(VeilidAPIError::not_initialized())
}
2023-05-29 15:24:57 -04:00
pub fn protected_store(&self) -> VeilidAPIResult<ProtectedStore> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.protected_store.clone());
}
Err(VeilidAPIError::not_initialized())
}
2023-05-29 15:24:57 -04:00
pub fn attachment_manager(&self) -> VeilidAPIResult<AttachmentManager> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.clone());
}
Err(VeilidAPIError::not_initialized())
}
2023-05-29 15:24:57 -04:00
pub fn network_manager(&self) -> VeilidAPIResult<NetworkManager> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager());
}
Err(VeilidAPIError::not_initialized())
}
2023-05-29 15:24:57 -04:00
pub fn rpc_processor(&self) -> VeilidAPIResult<RPCProcessor> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager().rpc_processor());
}
Err(VeilidAPIError::NotInitialized)
}
2023-05-29 15:24:57 -04:00
pub fn routing_table(&self) -> VeilidAPIResult<RoutingTable> {
2022-11-26 16:17:30 -05:00
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager().routing_table());
}
Err(VeilidAPIError::NotInitialized)
}
2023-05-29 15:24:57 -04:00
pub fn storage_manager(&self) -> VeilidAPIResult<StorageManager> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.storage_manager.clone());
}
Err(VeilidAPIError::NotInitialized)
}
2022-11-26 16:17:30 -05:00
////////////////////////////////////////////////////////////////
// Attach/Detach
2023-02-17 17:47:21 -05:00
/// Get a full copy of the current state
2023-05-29 15:24:57 -04:00
pub async fn get_state(&self) -> VeilidAPIResult<VeilidState> {
2022-11-26 16:17:30 -05:00
let attachment_manager = self.attachment_manager()?;
let network_manager = attachment_manager.network_manager();
let config = self.config()?;
let attachment = attachment_manager.get_veilid_state();
let network = network_manager.get_veilid_state();
let config = config.get_veilid_state();
Ok(VeilidState {
attachment,
network,
config,
})
}
2023-02-17 17:47:21 -05:00
/// Connect to the network
2022-11-26 16:17:30 -05:00
#[instrument(level = "debug", err, skip_all)]
2023-05-29 15:24:57 -04:00
pub async fn attach(&self) -> VeilidAPIResult<()> {
2022-11-26 16:17:30 -05:00
let attachment_manager = self.attachment_manager()?;
2022-12-26 16:33:48 -05:00
if !attachment_manager.attach().await {
apibail_generic!("Already attached");
}
Ok(())
2022-11-26 16:17:30 -05:00
}
2023-02-17 17:47:21 -05:00
/// Disconnect from the network
2022-11-26 16:17:30 -05:00
#[instrument(level = "debug", err, skip_all)]
2023-05-29 15:24:57 -04:00
pub async fn detach(&self) -> VeilidAPIResult<()> {
2022-11-26 16:17:30 -05:00
let attachment_manager = self.attachment_manager()?;
2022-12-26 16:33:48 -05:00
if !attachment_manager.detach().await {
apibail_generic!("Already detached");
}
Ok(())
2022-11-26 16:17:30 -05:00
}
////////////////////////////////////////////////////////////////
// Routing Context
#[instrument(level = "debug", skip(self))]
pub fn routing_context(&self) -> RoutingContext {
RoutingContext::new(self.clone())
}
////////////////////////////////////////////////////////////////
// Private route allocation
2023-02-17 17:47:21 -05:00
/// Allocate a new private route set with default cryptography and network options
2023-02-25 22:02:13 -05:00
/// Returns a route id and a publishable 'blob' with the route encrypted with each crypto kind
2023-02-20 20:37:52 -05:00
/// Those nodes importing the blob will have their choice of which crypto kind to use
2022-11-26 16:17:30 -05:00
#[instrument(level = "debug", skip(self))]
2023-05-29 15:24:57 -04:00
pub async fn new_private_route(&self) -> VeilidAPIResult<(RouteId, Vec<u8>)> {
2023-02-15 18:18:08 -05:00
self.new_custom_private_route(
&VALID_CRYPTO_KINDS,
Stability::default(),
Sequencing::default(),
)
.await
2022-11-26 16:17:30 -05:00
}
2023-02-17 17:47:21 -05:00
///
2022-11-26 16:17:30 -05:00
#[instrument(level = "debug", skip(self))]
pub async fn new_custom_private_route(
&self,
2023-02-15 18:18:08 -05:00
crypto_kinds: &[CryptoKind],
2022-11-26 16:17:30 -05:00
stability: Stability,
sequencing: Sequencing,
2023-05-29 15:24:57 -04:00
) -> VeilidAPIResult<(RouteId, Vec<u8>)> {
2022-11-26 16:17:30 -05:00
let default_route_hop_count: usize = {
let config = self.config()?;
let c = config.get();
c.network.rpc.default_route_hop_count.into()
};
let rss = self.routing_table()?.route_spec_store();
let r = rss
.allocate_route(
2023-02-15 18:18:08 -05:00
&crypto_kinds,
2022-11-26 16:17:30 -05:00
stability,
sequencing,
default_route_hop_count,
Direction::Inbound.into(),
&[],
)
.map_err(VeilidAPIError::internal)?;
2023-02-25 22:02:13 -05:00
let Some(route_id) = r else {
2022-11-26 16:17:30 -05:00
apibail_generic!("unable to allocate route");
};
if !rss
2023-02-25 22:02:13 -05:00
.test_route(route_id.clone())
2022-11-26 16:17:30 -05:00
.await
.map_err(VeilidAPIError::no_connection)?
{
2023-02-25 22:02:13 -05:00
rss.release_route(route_id);
2022-11-26 16:17:30 -05:00
apibail_generic!("allocated route failed to test");
}
2023-02-25 22:02:13 -05:00
let private_routes = rss
.assemble_private_routes(&route_id, Some(true))
2022-11-26 16:17:30 -05:00
.map_err(VeilidAPIError::generic)?;
2023-02-25 22:02:13 -05:00
let blob = match RouteSpecStore::private_routes_to_blob(&private_routes) {
2022-11-26 16:17:30 -05:00
Ok(v) => v,
Err(e) => {
2023-02-25 22:02:13 -05:00
rss.release_route(route_id);
2022-11-26 16:17:30 -05:00
apibail_internal!(e);
}
};
2023-02-25 22:02:13 -05:00
rss.mark_route_published(&route_id, true)
2022-11-26 16:17:30 -05:00
.map_err(VeilidAPIError::internal)?;
2023-02-25 22:02:13 -05:00
Ok((route_id, blob))
2022-11-26 16:17:30 -05:00
}
#[instrument(level = "debug", skip(self))]
2023-05-29 15:24:57 -04:00
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> VeilidAPIResult<RouteId> {
2022-11-26 16:17:30 -05:00
let rss = self.routing_table()?.route_spec_store();
rss.import_remote_private_route(blob)
.map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob"))
}
#[instrument(level = "debug", skip(self))]
2023-05-29 15:24:57 -04:00
pub fn release_private_route(&self, route_id: RouteId) -> VeilidAPIResult<()> {
2022-11-26 16:17:30 -05:00
let rss = self.routing_table()?.route_spec_store();
2023-02-25 22:02:13 -05:00
if !rss.release_route(route_id) {
apibail_invalid_argument!("release_private_route", "key", route_id);
2022-11-26 16:17:30 -05:00
}
2023-02-25 22:02:13 -05:00
Ok(())
2022-11-26 16:17:30 -05:00
}
////////////////////////////////////////////////////////////////
// App Calls
#[instrument(level = "debug", skip(self))]
2023-05-29 15:24:57 -04:00
pub async fn app_call_reply(&self, id: OperationId, message: Vec<u8>) -> VeilidAPIResult<()> {
2022-11-26 16:17:30 -05:00
let rpc_processor = self.rpc_processor()?;
rpc_processor
.app_call_reply(id, message)
.await
.map_err(|e| e.into())
}
////////////////////////////////////////////////////////////////
// Tunnel Building
2023-06-03 18:33:27 -04:00
#[cfg(feature = "unstable-tunnels")]
2022-11-26 16:17:30 -05:00
#[instrument(level = "debug", err, skip(self))]
pub async fn start_tunnel(
&self,
_endpoint_mode: TunnelMode,
_depth: u8,
2023-05-29 15:24:57 -04:00
) -> VeilidAPIResult<PartialTunnel> {
2022-11-26 16:17:30 -05:00
panic!("unimplemented");
}
2023-06-03 18:33:27 -04:00
#[cfg(feature = "unstable-tunnels")]
2022-11-26 16:17:30 -05:00
#[instrument(level = "debug", err, skip(self))]
pub async fn complete_tunnel(
&self,
_endpoint_mode: TunnelMode,
_depth: u8,
_partial_tunnel: PartialTunnel,
2023-05-29 15:24:57 -04:00
) -> VeilidAPIResult<FullTunnel> {
2022-11-26 16:17:30 -05:00
panic!("unimplemented");
}
2023-06-03 18:33:27 -04:00
#[cfg(feature = "unstable-tunnels")]
2022-11-26 16:17:30 -05:00
#[instrument(level = "debug", err, skip(self))]
2023-05-29 15:24:57 -04:00
pub async fn cancel_tunnel(&self, _tunnel_id: TunnelId) -> VeilidAPIResult<bool> {
2022-11-26 16:17:30 -05:00
panic!("unimplemented");
}
}