more refactor
This commit is contained in:
parent
e328bdc270
commit
1fba8831e8
@ -324,7 +324,7 @@ struct ValueData @0xb4b7416f169f2a3d {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@ -336,7 +336,7 @@ struct OperationGetValueA @0xd896bb46f2e0249f {
|
||||
}
|
||||
|
||||
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)
|
||||
value @2 :ValueData; # value or subvalue contents (older or equal seq number gets dropped)
|
||||
}
|
||||
@ -349,10 +349,10 @@ struct OperationSetValueA @0x9378d0732dc95be2 {
|
||||
}
|
||||
|
||||
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
|
||||
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 {
|
||||
@ -361,7 +361,7 @@ struct OperationWatchValueA @0xa726cab7064ba893 {
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
|
@ -159,15 +159,9 @@ impl RoutingTable {
|
||||
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();
|
||||
out += &format!("Entry {:?}:\n", node_id);
|
||||
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 += &node_ref.operate(|_rt, e| format!("{:#?}\n", e));
|
||||
out
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ mod route_spec_store_cache;
|
||||
mod route_spec_store_content;
|
||||
mod route_stats;
|
||||
|
||||
pub use permutation::*;
|
||||
pub use remote_private_route_info::*;
|
||||
pub use route_set_spec_detail::*;
|
||||
pub use route_spec_store::*;
|
||||
|
@ -1134,32 +1134,17 @@ impl RouteSpecStore {
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Assemble private route for publication
|
||||
/// 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();
|
||||
fn assemble_private_route_inner(&self, inner: &RouteSpecStoreInner, key: &PublicKey, rsd: &RouteSpecDetail, optimized: bool) -> EyreResult<PrivateRoute>
|
||||
{
|
||||
let routing_table = self.unlocked_inner.routing_table.clone();
|
||||
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
|
||||
let crypto = routing_table.network_manager().crypto();
|
||||
let Some(vcrypto) = crypto.get(rsd.crypto_kind) else {
|
||||
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
|
||||
let mut route_hop = RouteHop {
|
||||
node: if optimized {
|
||||
@ -1234,6 +1219,58 @@ impl RouteSpecStore {
|
||||
};
|
||||
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
|
||||
/// It is safe to import the same route more than once and it will return the same route id
|
||||
@ -1407,7 +1444,7 @@ impl RouteSpecStore {
|
||||
/// Mark route as published
|
||||
/// When first deserialized, routes must be re-published in order to ensure they remain
|
||||
/// 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 Some(rssd) = inner.content.get_detail_mut(id) else {
|
||||
bail!("route does not exist");
|
||||
|
@ -162,6 +162,9 @@ impl RPCProcessor {
|
||||
}
|
||||
SafetySelection::Safe(safety_spec) => {
|
||||
// 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 Some(pr_key) = rss
|
||||
.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
|
||||
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 => {
|
||||
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
|
||||
|
||||
// Check for loopback test
|
||||
let pr_key = if safety_spec.preferred_route
|
||||
== Some(private_route.public_key.key)
|
||||
let pr_key = if safety_spec.preferred_route == Some(private_route_id)
|
||||
{
|
||||
// Private route is also safety route during loopback test
|
||||
xxx build loopback routine? get_private_route_for_loopback_test?
|
||||
private_route.public_key.key
|
||||
} else {
|
||||
// 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
|
||||
|
||||
/// 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
|
||||
#[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(
|
||||
&VALID_CRYPTO_KINDS,
|
||||
Stability::default(),
|
||||
@ -184,7 +184,7 @@ impl VeilidAPI {
|
||||
crypto_kinds: &[CryptoKind],
|
||||
stability: Stability,
|
||||
sequencing: Sequencing,
|
||||
) -> Result<(TypedKeySet, Vec<u8>), VeilidAPIError> {
|
||||
) -> Result<(RouteId, Vec<u8>), VeilidAPIError> {
|
||||
let default_route_hop_count: usize = {
|
||||
let config = self.config()?;
|
||||
let c = config.get();
|
||||
@ -202,56 +202,48 @@ impl VeilidAPI {
|
||||
&[],
|
||||
)
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
let Some(pr_keys) = r else {
|
||||
let Some(route_id) = r else {
|
||||
apibail_generic!("unable to allocate route");
|
||||
};
|
||||
if !rss
|
||||
.test_route(&pr_keys)
|
||||
.test_route(route_id.clone())
|
||||
.await
|
||||
.map_err(VeilidAPIError::no_connection)?
|
||||
{
|
||||
rss.release_route(&pr_pubkey);
|
||||
rss.release_route(route_id);
|
||||
apibail_generic!("allocated route failed to test");
|
||||
}
|
||||
let private_route = rss
|
||||
.assemble_private_route(&pr_pubkey, Some(true))
|
||||
let private_routes = rss
|
||||
.assemble_private_routes(&route_id, Some(true))
|
||||
.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,
|
||||
Err(e) => {
|
||||
rss.release_route(&pr_pubkey);
|
||||
rss.release_route(route_id);
|
||||
apibail_internal!(e);
|
||||
}
|
||||
};
|
||||
|
||||
rss.mark_route_published(&pr_pubkey, true)
|
||||
rss.mark_route_published(&route_id, true)
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
|
||||
Ok((pr_pubkey, blob))
|
||||
Ok((route_id, blob))
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub fn import_remote_private_route(
|
||||
&self,
|
||||
blob: Vec<u8>,
|
||||
) -> Result<TypedKeySet, VeilidAPIError> {
|
||||
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> Result<RouteId, VeilidAPIError> {
|
||||
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))]
|
||||
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();
|
||||
if rss.release_route(key) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(VeilidAPIError::invalid_argument(
|
||||
"release_private_route",
|
||||
"key",
|
||||
key,
|
||||
))
|
||||
if !rss.release_route(route_id) {
|
||||
apibail_invalid_argument!("release_private_route", "key", route_id);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
@ -7,7 +7,7 @@ use routing_table::*;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct DebugCache {
|
||||
imported_routes: Vec<TypedKeySet>,
|
||||
imported_routes: Vec<RouteId>,
|
||||
}
|
||||
|
||||
static DEBUG_CACHE: Mutex<DebugCache> = Mutex::new(DebugCache {
|
||||
@ -30,12 +30,12 @@ fn get_string(text: &str) -> Option<String> {
|
||||
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| {
|
||||
if text.is_empty() {
|
||||
return None;
|
||||
}
|
||||
match PublicKey::from_str(text).ok() {
|
||||
match RouteId::from_str(text).ok() {
|
||||
Some(key) => {
|
||||
let routes = rss.list_allocated_routes(|k, _| Some(*k));
|
||||
if routes.contains(&key) {
|
||||
@ -128,38 +128,20 @@ fn get_destination(routing_table: RoutingTable) -> impl FnOnce(&str) -> Option<D
|
||||
}
|
||||
if &text[0..1] == "#" {
|
||||
// Private route
|
||||
let mut 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 text = &text[1..];
|
||||
let n = get_number(text)?;
|
||||
let mut dc = DEBUG_CACHE.lock();
|
||||
let pr_pubkey = match opt_crypto_kind {
|
||||
Some(ck) => dc.imported_routes.get(n)?.get(ck)?,
|
||||
None => dc.imported_routes.get(n)?.best()?,
|
||||
};
|
||||
let private_route_id = dc.imported_routes.get(n)?.clone();
|
||||
|
||||
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
|
||||
dc.imported_routes.remove(n);
|
||||
info!("removed dead imported route {}", n);
|
||||
return None;
|
||||
};
|
||||
Some(Destination::private_route(
|
||||
private_route,
|
||||
private_route_id,
|
||||
ss.unwrap_or(SafetySelection::Unsafe(Sequencing::default())),
|
||||
))
|
||||
} else {
|
||||
@ -381,12 +363,19 @@ impl VeilidAPI {
|
||||
|
||||
async fn debug_entry(&self, args: String) -> Result<String, VeilidAPIError> {
|
||||
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
|
||||
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> {
|
||||
@ -655,10 +644,16 @@ impl VeilidAPI {
|
||||
let routing_table = netman.routing_table();
|
||||
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
|
||||
let out = match rss.release_route(&route_id) {
|
||||
let out = match rss.release_route(route_id) {
|
||||
true => "Released".to_owned(),
|
||||
false => "Route does not exist".to_owned(),
|
||||
};
|
||||
@ -671,7 +666,13 @@ impl VeilidAPI {
|
||||
let routing_table = netman.routing_table();
|
||||
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 = {
|
||||
if args.len() > 2 {
|
||||
let full_val = get_debug_argument_at(&args, 2, "debug_route", "full", get_string)?
|
||||
@ -687,13 +688,13 @@ impl VeilidAPI {
|
||||
};
|
||||
|
||||
// Publish route
|
||||
let out = match rss.assemble_private_route(&route_id, Some(!full)) {
|
||||
Ok(private_route) => {
|
||||
let out = match rss.assemble_private_routes(&route_id, Some(!full)) {
|
||||
Ok(private_routes) => {
|
||||
if let Err(e) = rss.mark_route_published(&route_id, true) {
|
||||
return Ok(format!("Couldn't mark route published: {}", e));
|
||||
}
|
||||
// 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)?;
|
||||
let out = BASE64URL_NOPAD.encode(&blob_data);
|
||||
info!(
|
||||
@ -717,7 +718,13 @@ impl VeilidAPI {
|
||||
let routing_table = netman.routing_table();
|
||||
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
|
||||
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 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) {
|
||||
Some(s) => Ok(s),
|
||||
@ -771,14 +784,14 @@ impl VeilidAPI {
|
||||
.decode(blob.as_bytes())
|
||||
.map_err(VeilidAPIError::generic)?;
|
||||
let rss = self.routing_table()?.route_spec_store();
|
||||
let pr_pubkey = rss
|
||||
let route_id = rss
|
||||
.import_remote_private_route(blob_dec)
|
||||
.map_err(VeilidAPIError::generic)?;
|
||||
|
||||
let mut dc = DEBUG_CACHE.lock();
|
||||
let n = dc.imported_routes.len();
|
||||
let out = format!("Private route #{} imported: {}", n, pr_pubkey);
|
||||
dc.imported_routes.push(pr_pubkey);
|
||||
let out = format!("Private route #{} imported: {}", n, route_id);
|
||||
dc.imported_routes.push(route_id);
|
||||
|
||||
return Ok(out);
|
||||
}
|
||||
@ -789,10 +802,16 @@ impl VeilidAPI {
|
||||
let routing_table = netman.routing_table();
|
||||
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
|
||||
.test_route(&route_id)
|
||||
.test_route(route_id)
|
||||
.await
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
|
||||
|
@ -66,9 +66,17 @@ macro_rules! apibail_no_connection {
|
||||
|
||||
#[allow(unused_macros)]
|
||||
#[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) => {
|
||||
return Err(VeilidAPIError::key_not_found($x))
|
||||
return Err(VeilidAPIError::route_not_found($x))
|
||||
};
|
||||
}
|
||||
|
||||
@ -107,8 +115,8 @@ pub enum VeilidAPIError {
|
||||
TryAgain,
|
||||
#[error("Shutdown")]
|
||||
Shutdown,
|
||||
#[error("Key not found: {key}")]
|
||||
KeyNotFound { key: PublicKey },
|
||||
#[error("Invalid target")]
|
||||
InvalidTarget,
|
||||
#[error("No connection: {message}")]
|
||||
NoConnection { message: String },
|
||||
#[error("No peer info: {node_id}")]
|
||||
@ -147,8 +155,8 @@ impl VeilidAPIError {
|
||||
pub fn shutdown() -> Self {
|
||||
Self::Shutdown
|
||||
}
|
||||
pub fn key_not_found(key: PublicKey) -> Self {
|
||||
Self::KeyNotFound { key }
|
||||
pub fn invalid_target() -> Self {
|
||||
Self::InvalidTarget
|
||||
}
|
||||
pub fn no_connection<T: ToString>(msg: T) -> Self {
|
||||
Self::NoConnection {
|
||||
|
@ -4,8 +4,8 @@ use super::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Target {
|
||||
NodeId(PublicKey), // Node by any of its public keys
|
||||
PrivateRoute(RouteId), // Remote private route by its id
|
||||
NodeId(PublicKey), // Node by any of its public keys
|
||||
PrivateRoute(RouteId), // Remote private route by its id
|
||||
}
|
||||
|
||||
pub struct RoutingContextInner {}
|
||||
@ -66,7 +66,7 @@ impl RoutingContext {
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
pub fn with_sequencing(self, sequencing: Sequencing) -> Self {
|
||||
Self {
|
||||
api: self.api.clone(),
|
||||
@ -107,7 +107,7 @@ impl RoutingContext {
|
||||
// Resolve node
|
||||
let mut nr = match rpc_processor.resolve_node(node_id).await {
|
||||
Ok(Some(nr)) => nr,
|
||||
Ok(None) => apibail_key_not_found!(node_id),
|
||||
Ok(None) => apibail_invalid_target!(),
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
// Apply sequencing to match safety selection
|
||||
@ -121,10 +121,9 @@ impl RoutingContext {
|
||||
Target::PrivateRoute(rsid) => {
|
||||
// Get remote private route
|
||||
let rss = self.api.routing_table()?.route_spec_store();
|
||||
if !rss.is_valid_remote_private_route(&rsid)
|
||||
else {
|
||||
apibail_key_not_found!(pr);
|
||||
};
|
||||
if !rss.is_valid_remote_private_route(&rsid) {
|
||||
apibail_invalid_target!();
|
||||
};
|
||||
|
||||
Ok(rpc_processor::Destination::PrivateRoute {
|
||||
private_route_id: rsid,
|
||||
@ -197,27 +196,38 @@ impl RoutingContext {
|
||||
///////////////////////////////////
|
||||
/// 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");
|
||||
}
|
||||
|
||||
pub async fn set_value(
|
||||
&self,
|
||||
_value_key: ValueKey,
|
||||
_value: Vec<u8>,
|
||||
_key: TypedKey,
|
||||
_subkey: ValueSubkey,
|
||||
_value: ValueData,
|
||||
) -> Result<bool, VeilidAPIError> {
|
||||
panic!("unimplemented");
|
||||
}
|
||||
|
||||
pub async fn watch_value(
|
||||
&self,
|
||||
_value_key: ValueKey,
|
||||
_callback: ValueChangeCallback,
|
||||
_key: TypedKey,
|
||||
_subkeys: &[ValueSubkeyRange],
|
||||
_expiration: Timestamp,
|
||||
_count: u32,
|
||||
) -> Result<bool, VeilidAPIError> {
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,12 @@ pub type ByteCount = AlignedU64;
|
||||
pub type TunnelId = AlignedU64;
|
||||
/// Value schema
|
||||
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
|
||||
#[derive(
|
||||
@ -291,6 +297,17 @@ pub struct VeilidStateConfig {
|
||||
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)]
|
||||
#[archive_attr(repr(u8), derive(CheckBytes))]
|
||||
#[serde(tag = "kind")]
|
||||
@ -302,6 +319,7 @@ pub enum VeilidUpdate {
|
||||
Network(VeilidStateNetwork),
|
||||
Config(VeilidStateConfig),
|
||||
Route(VeilidStateRoute),
|
||||
ValueChange(VeilidValueChange),
|
||||
Shutdown,
|
||||
}
|
||||
|
||||
@ -332,7 +350,7 @@ pub struct VeilidState {
|
||||
)]
|
||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||
pub struct ValueData {
|
||||
pub seq: u32,
|
||||
pub seq: ValueSeqNum,
|
||||
pub schema: ValueSchema,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
@ -344,7 +362,7 @@ impl ValueData {
|
||||
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 }
|
||||
}
|
||||
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 type ValueChangeCallback = Arc<
|
||||
dyn Fn(TypedKey, Vec<(u32, u32)>, u32, Vec<u8>) -> SendPinBoxFuture<()> + Send + Sync + 'static,
|
||||
>;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||
|
Loading…
Reference in New Issue
Block a user