mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-10-01 01:26:08 -04:00
more refactor
This commit is contained in:
parent
e328bdc270
commit
1fba8831e8
@ -324,7 +324,7 @@ struct ValueData @0xb4b7416f169f2a3d {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct OperationGetValueQ @0xf88a5b6da5eda5d0 {
|
struct OperationGetValueQ @0xf88a5b6da5eda5d0 {
|
||||||
publicKey @0 :TypedKey; # the location of the value
|
key @0 :TypedKey; # the location of the value
|
||||||
subkey @1 :Subkey; # the index of the subkey (0 for the default subkey)
|
subkey @1 :Subkey; # the index of the subkey (0 for the default subkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +336,7 @@ struct OperationGetValueA @0xd896bb46f2e0249f {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct OperationSetValueQ @0xbac06191ff8bdbc5 {
|
struct OperationSetValueQ @0xbac06191ff8bdbc5 {
|
||||||
publicKey @0 :TypedKey; # the location of the value
|
key @0 :TypedKey; # the location of the value
|
||||||
subkey @1 :Subkey; # the index of the subkey (0 for the default subkey)
|
subkey @1 :Subkey; # the index of the subkey (0 for the default subkey)
|
||||||
value @2 :ValueData; # value or subvalue contents (older or equal seq number gets dropped)
|
value @2 :ValueData; # value or subvalue contents (older or equal seq number gets dropped)
|
||||||
}
|
}
|
||||||
@ -349,10 +349,10 @@ struct OperationSetValueA @0x9378d0732dc95be2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct OperationWatchValueQ @0xf9a5a6c547b9b228 {
|
struct OperationWatchValueQ @0xf9a5a6c547b9b228 {
|
||||||
publicKey @0 :TypedKey; # key for value to watch
|
key @0 :TypedKey; # key for value to watch
|
||||||
subkeys @1 :List(SubkeyRange); # subkey range to watch, if empty, watch everything
|
subkeys @1 :List(SubkeyRange); # subkey range to watch, if empty, watch everything
|
||||||
expiration @2 :UInt64; # requested timestamp when this watch will expire in usec since epoch (can be return less, 0 for max)
|
expiration @2 :UInt64; # requested timestamp when this watch will expire in usec since epoch (can be return less, 0 for max)
|
||||||
count @3 :UInt32; # requested number of changes to watch for (0 = continuous, 1 = single shot, 2+ = counter)
|
count @3 :UInt32; # requested number of changes to watch for (0 = cancel, 1 = single shot, 2+ = counter, UINT32_MAX = continuous)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OperationWatchValueA @0xa726cab7064ba893 {
|
struct OperationWatchValueA @0xa726cab7064ba893 {
|
||||||
@ -361,7 +361,7 @@ struct OperationWatchValueA @0xa726cab7064ba893 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct OperationValueChanged @0xd1c59ebdd8cc1bf6 {
|
struct OperationValueChanged @0xd1c59ebdd8cc1bf6 {
|
||||||
publicKey @0 :TypedKey; # key for value that changed
|
key @0 :TypedKey; # key for value that changed
|
||||||
subkeys @1 :List(SubkeyRange); # subkey range that changed (up to 512 ranges at a time)
|
subkeys @1 :List(SubkeyRange); # subkey range that changed (up to 512 ranges at a time)
|
||||||
count @2 :UInt32; # remaining changes left (0 means watch has expired)
|
count @2 :UInt32; # remaining changes left (0 means watch has expired)
|
||||||
value @3 :ValueData; # first value that changed (the rest can be gotten with getvalue)
|
value @3 :ValueData; # first value that changed (the rest can be gotten with getvalue)
|
||||||
|
@ -159,15 +159,9 @@ impl RoutingTable {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn debug_info_entry(&self, node_id: TypedKey) -> String {
|
pub(crate) fn debug_info_entry(&self, node_ref: NodeRef) -> String {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
out += &format!("Entry {:?}:\n", node_id);
|
out += &node_ref.operate(|_rt, e| format!("{:#?}\n", e));
|
||||||
if let Some(nr) = self.lookup_node_ref(node_id) {
|
|
||||||
out += &nr.operate(|_rt, e| format!("{:#?}\n", e));
|
|
||||||
} else {
|
|
||||||
out += "Entry not found\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ mod route_spec_store_cache;
|
|||||||
mod route_spec_store_content;
|
mod route_spec_store_content;
|
||||||
mod route_stats;
|
mod route_stats;
|
||||||
|
|
||||||
pub use permutation::*;
|
|
||||||
pub use remote_private_route_info::*;
|
pub use remote_private_route_info::*;
|
||||||
pub use route_set_spec_detail::*;
|
pub use route_set_spec_detail::*;
|
||||||
pub use route_spec_store::*;
|
pub use route_spec_store::*;
|
||||||
|
@ -1134,32 +1134,17 @@ impl RouteSpecStore {
|
|||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assemble private route for publication
|
fn assemble_private_route_inner(&self, inner: &RouteSpecStoreInner, key: &PublicKey, rsd: &RouteSpecDetail, optimized: bool) -> EyreResult<PrivateRoute>
|
||||||
/// Returns a PrivateRoute object for an allocated private route
|
{
|
||||||
#[instrument(level = "trace", skip(self), err)]
|
|
||||||
pub fn assemble_private_route(
|
|
||||||
&self,
|
|
||||||
key: &PublicKey,
|
|
||||||
optimized: Option<bool>,
|
|
||||||
) -> EyreResult<PrivateRoute> {
|
|
||||||
let inner = &*self.inner.lock();
|
|
||||||
let routing_table = self.unlocked_inner.routing_table.clone();
|
let routing_table = self.unlocked_inner.routing_table.clone();
|
||||||
let rti = &*routing_table.inner.read();
|
let rti = &*routing_table.inner.read();
|
||||||
|
|
||||||
// Get the route spec detail for the requested private route
|
|
||||||
let rsd = Self::detail(inner, key).ok_or_else(|| eyre!("route does not exist"))?;
|
|
||||||
|
|
||||||
// Ensure we get the crypto for it
|
// Ensure we get the crypto for it
|
||||||
let crypto = routing_table.network_manager().crypto();
|
let crypto = routing_table.network_manager().crypto();
|
||||||
let Some(vcrypto) = crypto.get(rsd.crypto_kind) else {
|
let Some(vcrypto) = crypto.get(rsd.crypto_kind) else {
|
||||||
bail!("crypto not supported for route");
|
bail!("crypto not supported for route");
|
||||||
};
|
};
|
||||||
|
|
||||||
// See if we can optimize this compilation yet
|
|
||||||
// We don't want to include full nodeinfo if we don't have to
|
|
||||||
let optimized = optimized
|
|
||||||
.unwrap_or(rsd.stats.last_tested_ts.is_some() || rsd.stats.last_received_ts.is_some());
|
|
||||||
|
|
||||||
// Make innermost route hop to our own node
|
// Make innermost route hop to our own node
|
||||||
let mut route_hop = RouteHop {
|
let mut route_hop = RouteHop {
|
||||||
node: if optimized {
|
node: if optimized {
|
||||||
@ -1235,6 +1220,58 @@ impl RouteSpecStore {
|
|||||||
Ok(private_route)
|
Ok(private_route)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Assemble a single private route for publication
|
||||||
|
/// Returns a PrivateRoute object for an allocated private route key
|
||||||
|
#[instrument(level = "trace", skip(self), err)]
|
||||||
|
pub fn assemble_private_route(
|
||||||
|
&self,
|
||||||
|
key: &PublicKey,
|
||||||
|
optimized: Option<bool>,
|
||||||
|
) -> EyreResult<PrivateRoute> {
|
||||||
|
let inner = &*self.inner.lock();
|
||||||
|
let Some(rsid) = inner.content.get_id_by_key(key) else {
|
||||||
|
bail!("route key does not exist");
|
||||||
|
};
|
||||||
|
let Some(rssd) = inner.content.get_detail(&rsid) else {
|
||||||
|
bail!("route id does not exist");
|
||||||
|
};
|
||||||
|
|
||||||
|
// See if we can optimize this compilation yet
|
||||||
|
// We don't want to include full nodeinfo if we don't have to
|
||||||
|
let optimized = optimized
|
||||||
|
.unwrap_or(rssd.get_stats().last_tested_ts.is_some() || rssd.get_stats().last_received_ts.is_some());
|
||||||
|
|
||||||
|
let rsd = rssd.get_route_by_key(key).expect("route key index is broken");
|
||||||
|
|
||||||
|
self.assemble_private_route_inner(inner, key, rsd, optimized)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Assemble private route set for publication
|
||||||
|
/// Returns a vec of PrivateRoute objects for an allocated private route
|
||||||
|
#[instrument(level = "trace", skip(self), err)]
|
||||||
|
pub fn assemble_private_routes(
|
||||||
|
&self,
|
||||||
|
id: &RouteId,
|
||||||
|
optimized: Option<bool>,
|
||||||
|
) -> EyreResult<Vec<PrivateRoute>> {
|
||||||
|
let inner = &*self.inner.lock();
|
||||||
|
let Some(rssd) = inner.content.get_detail(id) else {
|
||||||
|
bail!("route id does not exist");
|
||||||
|
};
|
||||||
|
|
||||||
|
// See if we can optimize this compilation yet
|
||||||
|
// We don't want to include full nodeinfo if we don't have to
|
||||||
|
let optimized = optimized
|
||||||
|
.unwrap_or(rssd.get_stats().last_tested_ts.is_some() || rssd.get_stats().last_received_ts.is_some());
|
||||||
|
|
||||||
|
let mut out = Vec::new();
|
||||||
|
for (key, rsd) in rssd.iter_route_set() {
|
||||||
|
out.push(self.assemble_private_route_inner(inner, key, rsd, optimized)?);
|
||||||
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|
||||||
/// Import a remote private route for compilation
|
/// Import a remote private route for compilation
|
||||||
/// It is safe to import the same route more than once and it will return the same route id
|
/// It is safe to import the same route more than once and it will return the same route id
|
||||||
/// Returns a route set id
|
/// Returns a route set id
|
||||||
@ -1407,7 +1444,7 @@ impl RouteSpecStore {
|
|||||||
/// Mark route as published
|
/// Mark route as published
|
||||||
/// When first deserialized, routes must be re-published in order to ensure they remain
|
/// When first deserialized, routes must be re-published in order to ensure they remain
|
||||||
/// in the RouteSpecStore.
|
/// in the RouteSpecStore.
|
||||||
pub fn mark_route_published(&self, id: &String, published: bool) -> EyreResult<()> {
|
pub fn mark_route_published(&self, id: &RouteId, published: bool) -> EyreResult<()> {
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
let Some(rssd) = inner.content.get_detail_mut(id) else {
|
let Some(rssd) = inner.content.get_detail_mut(id) else {
|
||||||
bail!("route does not exist");
|
bail!("route does not exist");
|
||||||
|
@ -162,6 +162,9 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
SafetySelection::Safe(safety_spec) => {
|
SafetySelection::Safe(safety_spec) => {
|
||||||
// Sent directly but with a safety route, respond to private route
|
// Sent directly but with a safety route, respond to private route
|
||||||
|
|
||||||
|
xxx continue here. ensure crypto kind makes sense with get_private_route_for_safety_spec and then make it work.
|
||||||
|
|
||||||
let ck = target.best_node_id().kind;
|
let ck = target.best_node_id().kind;
|
||||||
let Some(pr_key) = rss
|
let Some(pr_key) = rss
|
||||||
.get_private_route_for_safety_spec(ck, safety_spec, &target.node_ids())
|
.get_private_route_for_safety_spec(ck, safety_spec, &target.node_ids())
|
||||||
@ -222,7 +225,7 @@ impl RPCProcessor {
|
|||||||
|
|
||||||
// Determine if we can use optimized nodeinfo
|
// Determine if we can use optimized nodeinfo
|
||||||
let route_node = match rss
|
let route_node = match rss
|
||||||
.has_remote_private_route_seen_our_node_info(&private_route.public_key.key)
|
.has_remote_private_route_seen_our_node_info(&private_route_id)
|
||||||
{
|
{
|
||||||
true => {
|
true => {
|
||||||
if !routing_table.has_valid_own_node_info(RoutingDomain::PublicInternet) {
|
if !routing_table.has_valid_own_node_info(RoutingDomain::PublicInternet) {
|
||||||
@ -247,10 +250,10 @@ impl RPCProcessor {
|
|||||||
// Sent to a private route via a safety route, respond to private route
|
// Sent to a private route via a safety route, respond to private route
|
||||||
|
|
||||||
// Check for loopback test
|
// Check for loopback test
|
||||||
let pr_key = if safety_spec.preferred_route
|
let pr_key = if safety_spec.preferred_route == Some(private_route_id)
|
||||||
== Some(private_route.public_key.key)
|
|
||||||
{
|
{
|
||||||
// Private route is also safety route during loopback test
|
// Private route is also safety route during loopback test
|
||||||
|
xxx build loopback routine? get_private_route_for_loopback_test?
|
||||||
private_route.public_key.key
|
private_route.public_key.key
|
||||||
} else {
|
} else {
|
||||||
// Get the private route to respond to that matches the safety route spec we sent the request with
|
// Get the private route to respond to that matches the safety route spec we sent the request with
|
||||||
|
@ -165,10 +165,10 @@ impl VeilidAPI {
|
|||||||
// Private route allocation
|
// Private route allocation
|
||||||
|
|
||||||
/// Allocate a new private route set with default cryptography and network options
|
/// Allocate a new private route set with default cryptography and network options
|
||||||
/// Returns a set of keys and a publishable 'blob' with the route encrypted with each crypto kind
|
/// Returns a route id and a publishable 'blob' with the route encrypted with each crypto kind
|
||||||
/// Those nodes importing the blob will have their choice of which crypto kind to use
|
/// Those nodes importing the blob will have their choice of which crypto kind to use
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
pub async fn new_private_route(&self) -> Result<(TypedKeySet, Vec<u8>), VeilidAPIError> {
|
pub async fn new_private_route(&self) -> Result<(RouteId, Vec<u8>), VeilidAPIError> {
|
||||||
self.new_custom_private_route(
|
self.new_custom_private_route(
|
||||||
&VALID_CRYPTO_KINDS,
|
&VALID_CRYPTO_KINDS,
|
||||||
Stability::default(),
|
Stability::default(),
|
||||||
@ -184,7 +184,7 @@ impl VeilidAPI {
|
|||||||
crypto_kinds: &[CryptoKind],
|
crypto_kinds: &[CryptoKind],
|
||||||
stability: Stability,
|
stability: Stability,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
) -> Result<(TypedKeySet, Vec<u8>), VeilidAPIError> {
|
) -> Result<(RouteId, Vec<u8>), VeilidAPIError> {
|
||||||
let default_route_hop_count: usize = {
|
let default_route_hop_count: usize = {
|
||||||
let config = self.config()?;
|
let config = self.config()?;
|
||||||
let c = config.get();
|
let c = config.get();
|
||||||
@ -202,56 +202,48 @@ impl VeilidAPI {
|
|||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.map_err(VeilidAPIError::internal)?;
|
.map_err(VeilidAPIError::internal)?;
|
||||||
let Some(pr_keys) = r else {
|
let Some(route_id) = r else {
|
||||||
apibail_generic!("unable to allocate route");
|
apibail_generic!("unable to allocate route");
|
||||||
};
|
};
|
||||||
if !rss
|
if !rss
|
||||||
.test_route(&pr_keys)
|
.test_route(route_id.clone())
|
||||||
.await
|
.await
|
||||||
.map_err(VeilidAPIError::no_connection)?
|
.map_err(VeilidAPIError::no_connection)?
|
||||||
{
|
{
|
||||||
rss.release_route(&pr_pubkey);
|
rss.release_route(route_id);
|
||||||
apibail_generic!("allocated route failed to test");
|
apibail_generic!("allocated route failed to test");
|
||||||
}
|
}
|
||||||
let private_route = rss
|
let private_routes = rss
|
||||||
.assemble_private_route(&pr_pubkey, Some(true))
|
.assemble_private_routes(&route_id, Some(true))
|
||||||
.map_err(VeilidAPIError::generic)?;
|
.map_err(VeilidAPIError::generic)?;
|
||||||
let blob = match RouteSpecStore::private_route_to_blob(&private_route) {
|
let blob = match RouteSpecStore::private_routes_to_blob(&private_routes) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
rss.release_route(&pr_pubkey);
|
rss.release_route(route_id);
|
||||||
apibail_internal!(e);
|
apibail_internal!(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rss.mark_route_published(&pr_pubkey, true)
|
rss.mark_route_published(&route_id, true)
|
||||||
.map_err(VeilidAPIError::internal)?;
|
.map_err(VeilidAPIError::internal)?;
|
||||||
|
|
||||||
Ok((pr_pubkey, blob))
|
Ok((route_id, blob))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
pub fn import_remote_private_route(
|
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> Result<RouteId, VeilidAPIError> {
|
||||||
&self,
|
|
||||||
blob: Vec<u8>,
|
|
||||||
) -> Result<TypedKeySet, VeilidAPIError> {
|
|
||||||
let rss = self.routing_table()?.route_spec_store();
|
let rss = self.routing_table()?.route_spec_store();
|
||||||
rss.import_remote_private_route(blob)
|
rss.import_remote_private_route(blob)
|
||||||
.map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob"))
|
.map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
pub fn release_private_route(&self, key: &PublicKey) -> Result<(), VeilidAPIError> {
|
pub fn release_private_route(&self, route_id: RouteId) -> Result<(), VeilidAPIError> {
|
||||||
let rss = self.routing_table()?.route_spec_store();
|
let rss = self.routing_table()?.route_spec_store();
|
||||||
if rss.release_route(key) {
|
if !rss.release_route(route_id) {
|
||||||
Ok(())
|
apibail_invalid_argument!("release_private_route", "key", route_id);
|
||||||
} else {
|
|
||||||
Err(VeilidAPIError::invalid_argument(
|
|
||||||
"release_private_route",
|
|
||||||
"key",
|
|
||||||
key,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
@ -7,7 +7,7 @@ use routing_table::*;
|
|||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
struct DebugCache {
|
struct DebugCache {
|
||||||
imported_routes: Vec<TypedKeySet>,
|
imported_routes: Vec<RouteId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEBUG_CACHE: Mutex<DebugCache> = Mutex::new(DebugCache {
|
static DEBUG_CACHE: Mutex<DebugCache> = Mutex::new(DebugCache {
|
||||||
@ -30,12 +30,12 @@ fn get_string(text: &str) -> Option<String> {
|
|||||||
Some(text.to_owned())
|
Some(text.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_route_id(rss: RouteSpecStore) -> impl Fn(&str) -> Option<PublicKey> {
|
fn get_route_id(rss: RouteSpecStore) -> impl Fn(&str) -> Option<RouteId> {
|
||||||
return move |text: &str| {
|
return move |text: &str| {
|
||||||
if text.is_empty() {
|
if text.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match PublicKey::from_str(text).ok() {
|
match RouteId::from_str(text).ok() {
|
||||||
Some(key) => {
|
Some(key) => {
|
||||||
let routes = rss.list_allocated_routes(|k, _| Some(*k));
|
let routes = rss.list_allocated_routes(|k, _| Some(*k));
|
||||||
if routes.contains(&key) {
|
if routes.contains(&key) {
|
||||||
@ -128,38 +128,20 @@ fn get_destination(routing_table: RoutingTable) -> impl FnOnce(&str) -> Option<D
|
|||||||
}
|
}
|
||||||
if &text[0..1] == "#" {
|
if &text[0..1] == "#" {
|
||||||
// Private route
|
// Private route
|
||||||
let mut text = &text[1..];
|
let text = &text[1..];
|
||||||
let opt_crypto_kind = if text.len() > 5 {
|
|
||||||
let fcc = &text[0..4];
|
|
||||||
if &text[4..5] != ":" {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let ck = match FourCC::from_str(fcc) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
text = &text[5..];
|
|
||||||
Some(ck)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let n = get_number(text)?;
|
let n = get_number(text)?;
|
||||||
let mut dc = DEBUG_CACHE.lock();
|
let mut dc = DEBUG_CACHE.lock();
|
||||||
let pr_pubkey = match opt_crypto_kind {
|
let private_route_id = dc.imported_routes.get(n)?.clone();
|
||||||
Some(ck) => dc.imported_routes.get(n)?.get(ck)?,
|
|
||||||
None => dc.imported_routes.get(n)?.best()?,
|
|
||||||
};
|
|
||||||
let rss = routing_table.route_spec_store();
|
let rss = routing_table.route_spec_store();
|
||||||
let Some(private_route) = rss.get_remote_private_route(&pr_pubkey.key) else {
|
if !rss.is_valid_remote_private_route(&private_route_id) {
|
||||||
// Remove imported route
|
// Remove imported route
|
||||||
dc.imported_routes.remove(n);
|
dc.imported_routes.remove(n);
|
||||||
info!("removed dead imported route {}", n);
|
info!("removed dead imported route {}", n);
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(Destination::private_route(
|
Some(Destination::private_route(
|
||||||
private_route,
|
private_route_id,
|
||||||
ss.unwrap_or(SafetySelection::Unsafe(Sequencing::default())),
|
ss.unwrap_or(SafetySelection::Unsafe(Sequencing::default())),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@ -381,12 +363,19 @@ impl VeilidAPI {
|
|||||||
|
|
||||||
async fn debug_entry(&self, args: String) -> Result<String, VeilidAPIError> {
|
async fn debug_entry(&self, args: String) -> Result<String, VeilidAPIError> {
|
||||||
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
|
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
|
||||||
|
let routing_table = self.network_manager()?.routing_table();
|
||||||
|
|
||||||
let node_id = get_debug_argument_at(&args, 0, "debug_entry", "node_id", get_typed_key)?;
|
let node_ref = get_debug_argument_at(
|
||||||
|
&args,
|
||||||
|
0,
|
||||||
|
"debug_entry",
|
||||||
|
"node_id",
|
||||||
|
get_node_ref(routing_table),
|
||||||
|
)?;
|
||||||
|
|
||||||
// Dump routing table entry
|
// Dump routing table entry
|
||||||
let routing_table = self.network_manager()?.routing_table();
|
let routing_table = self.network_manager()?.routing_table();
|
||||||
Ok(routing_table.debug_info_entry(node_id))
|
Ok(routing_table.debug_info_entry(node_ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn debug_nodeinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
|
async fn debug_nodeinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
|
||||||
@ -655,10 +644,16 @@ impl VeilidAPI {
|
|||||||
let routing_table = netman.routing_table();
|
let routing_table = netman.routing_table();
|
||||||
let rss = routing_table.route_spec_store();
|
let rss = routing_table.route_spec_store();
|
||||||
|
|
||||||
let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?;
|
let route_id = get_debug_argument_at(
|
||||||
|
&args,
|
||||||
|
1,
|
||||||
|
"debug_route",
|
||||||
|
"route_id",
|
||||||
|
get_route_id(rss.clone()),
|
||||||
|
)?;
|
||||||
|
|
||||||
// Release route
|
// Release route
|
||||||
let out = match rss.release_route(&route_id) {
|
let out = match rss.release_route(route_id) {
|
||||||
true => "Released".to_owned(),
|
true => "Released".to_owned(),
|
||||||
false => "Route does not exist".to_owned(),
|
false => "Route does not exist".to_owned(),
|
||||||
};
|
};
|
||||||
@ -671,7 +666,13 @@ impl VeilidAPI {
|
|||||||
let routing_table = netman.routing_table();
|
let routing_table = netman.routing_table();
|
||||||
let rss = routing_table.route_spec_store();
|
let rss = routing_table.route_spec_store();
|
||||||
|
|
||||||
let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?;
|
let route_id = get_debug_argument_at(
|
||||||
|
&args,
|
||||||
|
1,
|
||||||
|
"debug_route",
|
||||||
|
"route_id",
|
||||||
|
get_route_id(rss.clone()),
|
||||||
|
)?;
|
||||||
let full = {
|
let full = {
|
||||||
if args.len() > 2 {
|
if args.len() > 2 {
|
||||||
let full_val = get_debug_argument_at(&args, 2, "debug_route", "full", get_string)?
|
let full_val = get_debug_argument_at(&args, 2, "debug_route", "full", get_string)?
|
||||||
@ -687,13 +688,13 @@ impl VeilidAPI {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Publish route
|
// Publish route
|
||||||
let out = match rss.assemble_private_route(&route_id, Some(!full)) {
|
let out = match rss.assemble_private_routes(&route_id, Some(!full)) {
|
||||||
Ok(private_route) => {
|
Ok(private_routes) => {
|
||||||
if let Err(e) = rss.mark_route_published(&route_id, true) {
|
if let Err(e) = rss.mark_route_published(&route_id, true) {
|
||||||
return Ok(format!("Couldn't mark route published: {}", e));
|
return Ok(format!("Couldn't mark route published: {}", e));
|
||||||
}
|
}
|
||||||
// Convert to blob
|
// Convert to blob
|
||||||
let blob_data = RouteSpecStore::private_route_to_blob(&private_route)
|
let blob_data = RouteSpecStore::private_routes_to_blob(&private_routes)
|
||||||
.map_err(VeilidAPIError::internal)?;
|
.map_err(VeilidAPIError::internal)?;
|
||||||
let out = BASE64URL_NOPAD.encode(&blob_data);
|
let out = BASE64URL_NOPAD.encode(&blob_data);
|
||||||
info!(
|
info!(
|
||||||
@ -717,7 +718,13 @@ impl VeilidAPI {
|
|||||||
let routing_table = netman.routing_table();
|
let routing_table = netman.routing_table();
|
||||||
let rss = routing_table.route_spec_store();
|
let rss = routing_table.route_spec_store();
|
||||||
|
|
||||||
let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_public_key)?;
|
let route_id = get_debug_argument_at(
|
||||||
|
&args,
|
||||||
|
1,
|
||||||
|
"debug_route",
|
||||||
|
"route_id",
|
||||||
|
get_route_id(rss.clone()),
|
||||||
|
)?;
|
||||||
|
|
||||||
// Unpublish route
|
// Unpublish route
|
||||||
let out = if let Err(e) = rss.mark_route_published(&route_id, false) {
|
let out = if let Err(e) = rss.mark_route_published(&route_id, false) {
|
||||||
@ -733,7 +740,13 @@ impl VeilidAPI {
|
|||||||
let routing_table = netman.routing_table();
|
let routing_table = netman.routing_table();
|
||||||
let rss = routing_table.route_spec_store();
|
let rss = routing_table.route_spec_store();
|
||||||
|
|
||||||
let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_public_key)?;
|
let route_id = get_debug_argument_at(
|
||||||
|
&args,
|
||||||
|
1,
|
||||||
|
"debug_route",
|
||||||
|
"route_id",
|
||||||
|
get_route_id(rss.clone()),
|
||||||
|
)?;
|
||||||
|
|
||||||
match rss.debug_route(&route_id) {
|
match rss.debug_route(&route_id) {
|
||||||
Some(s) => Ok(s),
|
Some(s) => Ok(s),
|
||||||
@ -771,14 +784,14 @@ impl VeilidAPI {
|
|||||||
.decode(blob.as_bytes())
|
.decode(blob.as_bytes())
|
||||||
.map_err(VeilidAPIError::generic)?;
|
.map_err(VeilidAPIError::generic)?;
|
||||||
let rss = self.routing_table()?.route_spec_store();
|
let rss = self.routing_table()?.route_spec_store();
|
||||||
let pr_pubkey = rss
|
let route_id = rss
|
||||||
.import_remote_private_route(blob_dec)
|
.import_remote_private_route(blob_dec)
|
||||||
.map_err(VeilidAPIError::generic)?;
|
.map_err(VeilidAPIError::generic)?;
|
||||||
|
|
||||||
let mut dc = DEBUG_CACHE.lock();
|
let mut dc = DEBUG_CACHE.lock();
|
||||||
let n = dc.imported_routes.len();
|
let n = dc.imported_routes.len();
|
||||||
let out = format!("Private route #{} imported: {}", n, pr_pubkey);
|
let out = format!("Private route #{} imported: {}", n, route_id);
|
||||||
dc.imported_routes.push(pr_pubkey);
|
dc.imported_routes.push(route_id);
|
||||||
|
|
||||||
return Ok(out);
|
return Ok(out);
|
||||||
}
|
}
|
||||||
@ -789,10 +802,16 @@ impl VeilidAPI {
|
|||||||
let routing_table = netman.routing_table();
|
let routing_table = netman.routing_table();
|
||||||
let rss = routing_table.route_spec_store();
|
let rss = routing_table.route_spec_store();
|
||||||
|
|
||||||
let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?;
|
let route_id = get_debug_argument_at(
|
||||||
|
&args,
|
||||||
|
1,
|
||||||
|
"debug_route",
|
||||||
|
"route_id",
|
||||||
|
get_route_id(rss.clone()),
|
||||||
|
)?;
|
||||||
|
|
||||||
let success = rss
|
let success = rss
|
||||||
.test_route(&route_id)
|
.test_route(route_id)
|
||||||
.await
|
.await
|
||||||
.map_err(VeilidAPIError::internal)?;
|
.map_err(VeilidAPIError::internal)?;
|
||||||
|
|
||||||
|
@ -66,9 +66,17 @@ macro_rules! apibail_no_connection {
|
|||||||
|
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! apibail_key_not_found {
|
macro_rules! apibail_invalid_target {
|
||||||
|
() => {
|
||||||
|
return Err(VeilidAPIError::invalid_target())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! apibail_route_not_found {
|
||||||
($x:expr) => {
|
($x:expr) => {
|
||||||
return Err(VeilidAPIError::key_not_found($x))
|
return Err(VeilidAPIError::route_not_found($x))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +115,8 @@ pub enum VeilidAPIError {
|
|||||||
TryAgain,
|
TryAgain,
|
||||||
#[error("Shutdown")]
|
#[error("Shutdown")]
|
||||||
Shutdown,
|
Shutdown,
|
||||||
#[error("Key not found: {key}")]
|
#[error("Invalid target")]
|
||||||
KeyNotFound { key: PublicKey },
|
InvalidTarget,
|
||||||
#[error("No connection: {message}")]
|
#[error("No connection: {message}")]
|
||||||
NoConnection { message: String },
|
NoConnection { message: String },
|
||||||
#[error("No peer info: {node_id}")]
|
#[error("No peer info: {node_id}")]
|
||||||
@ -147,8 +155,8 @@ impl VeilidAPIError {
|
|||||||
pub fn shutdown() -> Self {
|
pub fn shutdown() -> Self {
|
||||||
Self::Shutdown
|
Self::Shutdown
|
||||||
}
|
}
|
||||||
pub fn key_not_found(key: PublicKey) -> Self {
|
pub fn invalid_target() -> Self {
|
||||||
Self::KeyNotFound { key }
|
Self::InvalidTarget
|
||||||
}
|
}
|
||||||
pub fn no_connection<T: ToString>(msg: T) -> Self {
|
pub fn no_connection<T: ToString>(msg: T) -> Self {
|
||||||
Self::NoConnection {
|
Self::NoConnection {
|
||||||
|
@ -4,8 +4,8 @@ use super::*;
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Target {
|
pub enum Target {
|
||||||
NodeId(PublicKey), // Node by any of its public keys
|
NodeId(PublicKey), // Node by any of its public keys
|
||||||
PrivateRoute(RouteId), // Remote private route by its id
|
PrivateRoute(RouteId), // Remote private route by its id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RoutingContextInner {}
|
pub struct RoutingContextInner {}
|
||||||
@ -107,7 +107,7 @@ impl RoutingContext {
|
|||||||
// Resolve node
|
// Resolve node
|
||||||
let mut nr = match rpc_processor.resolve_node(node_id).await {
|
let mut nr = match rpc_processor.resolve_node(node_id).await {
|
||||||
Ok(Some(nr)) => nr,
|
Ok(Some(nr)) => nr,
|
||||||
Ok(None) => apibail_key_not_found!(node_id),
|
Ok(None) => apibail_invalid_target!(),
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
// Apply sequencing to match safety selection
|
// Apply sequencing to match safety selection
|
||||||
@ -121,10 +121,9 @@ impl RoutingContext {
|
|||||||
Target::PrivateRoute(rsid) => {
|
Target::PrivateRoute(rsid) => {
|
||||||
// Get remote private route
|
// Get remote private route
|
||||||
let rss = self.api.routing_table()?.route_spec_store();
|
let rss = self.api.routing_table()?.route_spec_store();
|
||||||
if !rss.is_valid_remote_private_route(&rsid)
|
if !rss.is_valid_remote_private_route(&rsid) {
|
||||||
else {
|
apibail_invalid_target!();
|
||||||
apibail_key_not_found!(pr);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
Ok(rpc_processor::Destination::PrivateRoute {
|
Ok(rpc_processor::Destination::PrivateRoute {
|
||||||
private_route_id: rsid,
|
private_route_id: rsid,
|
||||||
@ -197,27 +196,38 @@ impl RoutingContext {
|
|||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
/// DHT Values
|
/// DHT Values
|
||||||
|
|
||||||
pub async fn get_value(&self, _value_key: ValueKey) -> Result<Vec<u8>, VeilidAPIError> {
|
pub async fn get_value(
|
||||||
|
&self,
|
||||||
|
_key: TypedKey,
|
||||||
|
_subkey: ValueSubkey,
|
||||||
|
) -> Result<ValueData, VeilidAPIError> {
|
||||||
panic!("unimplemented");
|
panic!("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_value(
|
pub async fn set_value(
|
||||||
&self,
|
&self,
|
||||||
_value_key: ValueKey,
|
_key: TypedKey,
|
||||||
_value: Vec<u8>,
|
_subkey: ValueSubkey,
|
||||||
|
_value: ValueData,
|
||||||
) -> Result<bool, VeilidAPIError> {
|
) -> Result<bool, VeilidAPIError> {
|
||||||
panic!("unimplemented");
|
panic!("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn watch_value(
|
pub async fn watch_value(
|
||||||
&self,
|
&self,
|
||||||
_value_key: ValueKey,
|
_key: TypedKey,
|
||||||
_callback: ValueChangeCallback,
|
_subkeys: &[ValueSubkeyRange],
|
||||||
|
_expiration: Timestamp,
|
||||||
|
_count: u32,
|
||||||
) -> Result<bool, VeilidAPIError> {
|
) -> Result<bool, VeilidAPIError> {
|
||||||
panic!("unimplemented");
|
panic!("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cancel_watch_value(&self, _value_key: ValueKey) -> Result<bool, VeilidAPIError> {
|
pub async fn cancel_watch_value(
|
||||||
|
&self,
|
||||||
|
_key: TypedKey,
|
||||||
|
_subkeys: &[ValueSubkeyRange],
|
||||||
|
) -> Result<bool, VeilidAPIError> {
|
||||||
panic!("unimplemented");
|
panic!("unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,12 @@ pub type ByteCount = AlignedU64;
|
|||||||
pub type TunnelId = AlignedU64;
|
pub type TunnelId = AlignedU64;
|
||||||
/// Value schema
|
/// Value schema
|
||||||
pub type ValueSchema = FourCC;
|
pub type ValueSchema = FourCC;
|
||||||
|
/// Value subkey
|
||||||
|
pub type ValueSubkey = u32;
|
||||||
|
/// Value subkey range
|
||||||
|
pub type ValueSubkeyRange = (u32, u32);
|
||||||
|
/// Value sequence number
|
||||||
|
pub type ValueSeqNum = u32;
|
||||||
|
|
||||||
/// FOURCC code
|
/// FOURCC code
|
||||||
#[derive(
|
#[derive(
|
||||||
@ -291,6 +297,17 @@ pub struct VeilidStateConfig {
|
|||||||
pub config: VeilidConfigInner,
|
pub config: VeilidConfigInner,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
|
||||||
|
)]
|
||||||
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
|
pub struct VeilidValueChange {
|
||||||
|
key: TypedKey,
|
||||||
|
subkeys: Vec<ValueSubkey>,
|
||||||
|
count: u32,
|
||||||
|
value: ValueData,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
#[archive_attr(repr(u8), derive(CheckBytes))]
|
#[archive_attr(repr(u8), derive(CheckBytes))]
|
||||||
#[serde(tag = "kind")]
|
#[serde(tag = "kind")]
|
||||||
@ -302,6 +319,7 @@ pub enum VeilidUpdate {
|
|||||||
Network(VeilidStateNetwork),
|
Network(VeilidStateNetwork),
|
||||||
Config(VeilidStateConfig),
|
Config(VeilidStateConfig),
|
||||||
Route(VeilidStateRoute),
|
Route(VeilidStateRoute),
|
||||||
|
ValueChange(VeilidValueChange),
|
||||||
Shutdown,
|
Shutdown,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +350,7 @@ pub struct VeilidState {
|
|||||||
)]
|
)]
|
||||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
pub struct ValueData {
|
pub struct ValueData {
|
||||||
pub seq: u32,
|
pub seq: ValueSeqNum,
|
||||||
pub schema: ValueSchema,
|
pub schema: ValueSchema,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
@ -344,7 +362,7 @@ impl ValueData {
|
|||||||
data,
|
data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn new_with_seq(seq: u32, schema: ValueSchema, data: Vec<u8>) -> Self {
|
pub fn new_with_seq(seq: ValueSeqNum, schema: ValueSchema, data: Vec<u8>) -> Self {
|
||||||
Self { seq, schema, data }
|
Self { seq, schema, data }
|
||||||
}
|
}
|
||||||
pub fn change(&mut self, data: Vec<u8>) {
|
pub fn change(&mut self, data: Vec<u8>) {
|
||||||
@ -2378,10 +2396,6 @@ pub struct PeerStats {
|
|||||||
pub transfer: TransferStatsDownUp, // Stats for communications with the peer
|
pub transfer: TransferStatsDownUp, // Stats for communications with the peer
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ValueChangeCallback = Arc<
|
|
||||||
dyn Fn(TypedKey, Vec<(u32, u32)>, u32, Vec<u8>) -> SendPinBoxFuture<()> + Send + Sync + 'static,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
|
Loading…
Reference in New Issue
Block a user