fixes
This commit is contained in:
parent
b2dd3bf9b7
commit
cd892d077a
@ -699,7 +699,11 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remove from end nodes cache
|
// Remove from end nodes cache
|
||||||
match inner.cache.used_nodes.entry(*detail.hops.last().unwrap()) {
|
match inner
|
||||||
|
.cache
|
||||||
|
.used_end_nodes
|
||||||
|
.entry(*detail.hops.last().unwrap())
|
||||||
|
{
|
||||||
std::collections::hash_map::Entry::Occupied(mut o) => {
|
std::collections::hash_map::Entry::Occupied(mut o) => {
|
||||||
*o.get_mut() -= 1;
|
*o.get_mut() -= 1;
|
||||||
if *o.get() == 0 {
|
if *o.get() == 0 {
|
||||||
@ -707,7 +711,7 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::collections::hash_map::Entry::Vacant(_) => {
|
std::collections::hash_map::Entry::Vacant(_) => {
|
||||||
panic!("used_nodes cache should have contained hop");
|
panic!("used_end_nodes cache should have contained hop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1161,12 +1165,24 @@ impl RouteSpecStore {
|
|||||||
let mut pr_builder = pr_message.init_root::<veilid_capnp::private_route::Builder>();
|
let mut pr_builder = pr_message.init_root::<veilid_capnp::private_route::Builder>();
|
||||||
encode_private_route(&private_route, &mut pr_builder)
|
encode_private_route(&private_route, &mut pr_builder)
|
||||||
.wrap_err("failed to encode private route")?;
|
.wrap_err("failed to encode private route")?;
|
||||||
builder_to_vec(pr_message).wrap_err("failed to convert builder to vec")
|
|
||||||
|
let mut buffer = vec![];
|
||||||
|
capnp::serialize_packed::write_message(&mut buffer, &pr_message)
|
||||||
|
.wrap_err("failed to convert builder to vec")?;
|
||||||
|
Ok(buffer)
|
||||||
|
|
||||||
|
// builder_to_vec(pr_message).wrap_err("failed to convert builder to vec")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert binary blob to private route
|
/// Convert binary blob to private route
|
||||||
pub fn blob_to_private_route(blob: Vec<u8>) -> EyreResult<PrivateRoute> {
|
pub fn blob_to_private_route(blob: Vec<u8>) -> EyreResult<PrivateRoute> {
|
||||||
let reader = ::capnp::message::Reader::new(RPCMessageData::new(blob), Default::default());
|
let reader = capnp::serialize_packed::read_message(
|
||||||
|
blob.as_slice(),
|
||||||
|
capnp::message::ReaderOptions::new(),
|
||||||
|
)
|
||||||
|
.wrap_err("failed to make message reader")?;
|
||||||
|
|
||||||
|
//let reader = ::capnp::message::Reader::new(RPCMessageData::new(blob), Default::default());
|
||||||
let pr_reader = reader
|
let pr_reader = reader
|
||||||
.get_root::<veilid_capnp::private_route::Reader>()
|
.get_root::<veilid_capnp::private_route::Reader>()
|
||||||
.wrap_err("failed to make reader for private_route")?;
|
.wrap_err("failed to make reader for private_route")?;
|
||||||
|
@ -30,7 +30,6 @@ pub use rpc_status::*;
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::crypto::*;
|
use crate::crypto::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use capnp::message::ReaderSegments;
|
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use network_manager::*;
|
use network_manager::*;
|
||||||
use receipt_manager::*;
|
use receipt_manager::*;
|
||||||
@ -98,18 +97,28 @@ impl RPCMessageData {
|
|||||||
pub fn new(contents: Vec<u8>) -> Self {
|
pub fn new(contents: Vec<u8>) -> Self {
|
||||||
Self { contents }
|
Self { contents }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ReaderSegments for RPCMessageData {
|
pub fn get_reader(
|
||||||
fn get_segment(&self, idx: u32) -> Option<&[u8]> {
|
&self,
|
||||||
if idx > 0 {
|
) -> Result<capnp::message::Reader<capnp::serialize::OwnedSegments>, RPCError> {
|
||||||
None
|
capnp::serialize_packed::read_message(
|
||||||
} else {
|
self.contents.as_slice(),
|
||||||
Some(self.contents.as_slice())
|
capnp::message::ReaderOptions::new(),
|
||||||
}
|
)
|
||||||
|
.map_err(RPCError::protocol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl ReaderSegments for RPCMessageData {
|
||||||
|
// fn get_segment(&self, idx: u32) -> Option<&[u8]> {
|
||||||
|
// if idx > 0 {
|
||||||
|
// None
|
||||||
|
// } else {
|
||||||
|
// Some(self.contents.as_slice())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct RPCMessageEncoded {
|
struct RPCMessageEncoded {
|
||||||
header: RPCMessageHeader,
|
header: RPCMessageHeader,
|
||||||
@ -127,12 +136,17 @@ pub fn builder_to_vec<'a, T>(builder: capnp::message::Builder<T>) -> Result<Vec<
|
|||||||
where
|
where
|
||||||
T: capnp::message::Allocator + 'a,
|
T: capnp::message::Allocator + 'a,
|
||||||
{
|
{
|
||||||
let wordvec = builder
|
let mut buffer = vec![];
|
||||||
.into_reader()
|
capnp::serialize_packed::write_message(&mut buffer, &builder)
|
||||||
.canonicalize()
|
|
||||||
.map_err(RPCError::protocol)
|
.map_err(RPCError::protocol)
|
||||||
.map_err(logthru_rpc!())?;
|
.map_err(logthru_rpc!())?;
|
||||||
Ok(capnp::Word::words_to_bytes(wordvec.as_slice()).to_vec())
|
Ok(buffer)
|
||||||
|
// let wordvec = builder
|
||||||
|
// .into_reader()
|
||||||
|
// .canonicalize()
|
||||||
|
// .map_err(RPCError::protocol)
|
||||||
|
// .map_err(logthru_rpc!())?;
|
||||||
|
// Ok(capnp::Word::words_to_bytes(wordvec.as_slice()).to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn reader_to_vec<'a, T>(reader: &capnp::message::Reader<T>) -> Result<Vec<u8>, RPCError>
|
// fn reader_to_vec<'a, T>(reader: &capnp::message::Reader<T>) -> Result<Vec<u8>, RPCError>
|
||||||
@ -899,7 +913,7 @@ impl RPCProcessor {
|
|||||||
|
|
||||||
// Decode the RPC message
|
// Decode the RPC message
|
||||||
let operation = {
|
let operation = {
|
||||||
let reader = capnp::message::Reader::new(encoded_msg.data, Default::default());
|
let reader = encoded_msg.data.get_reader()?;
|
||||||
let op_reader = reader
|
let op_reader = reader
|
||||||
.get_root::<veilid_capnp::operation::Reader>()
|
.get_root::<veilid_capnp::operation::Reader>()
|
||||||
.map_err(RPCError::protocol)
|
.map_err(RPCError::protocol)
|
||||||
@ -945,7 +959,7 @@ impl RPCProcessor {
|
|||||||
RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
|
RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
|
||||||
// Decode the RPC message
|
// Decode the RPC message
|
||||||
let operation = {
|
let operation = {
|
||||||
let reader = capnp::message::Reader::new(encoded_msg.data, Default::default());
|
let reader = encoded_msg.data.get_reader()?;
|
||||||
let op_reader = reader
|
let op_reader = reader
|
||||||
.get_root::<veilid_capnp::operation::Reader>()
|
.get_root::<veilid_capnp::operation::Reader>()
|
||||||
.map_err(RPCError::protocol)
|
.map_err(RPCError::protocol)
|
||||||
|
@ -325,15 +325,8 @@ impl RPCProcessor {
|
|||||||
.cached_dh(&route.safety_route.public_key, &node_id_secret)
|
.cached_dh(&route.safety_route.public_key, &node_id_secret)
|
||||||
.map_err(RPCError::protocol)?;
|
.map_err(RPCError::protocol)?;
|
||||||
let dec_blob_data = Crypto::decrypt_aead(blob_data, &d.nonce, &dh_secret, None)
|
let dec_blob_data = Crypto::decrypt_aead(blob_data, &d.nonce, &dh_secret, None)
|
||||||
.map_err(RPCError::map_internal(
|
.map_err(RPCError::protocol)?;
|
||||||
"decryption of safety route hop failed",
|
let dec_blob_reader = RPCMessageData::new(dec_blob_data).get_reader()?;
|
||||||
))?;
|
|
||||||
let dec_blob_reader = capnp::message::Reader::new(
|
|
||||||
RPCMessageData {
|
|
||||||
contents: dec_blob_data,
|
|
||||||
},
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Decode the blob appropriately
|
// Decode the blob appropriately
|
||||||
if blob_tag == 1 {
|
if blob_tag == 1 {
|
||||||
@ -387,15 +380,8 @@ impl RPCProcessor {
|
|||||||
.map_err(RPCError::protocol)?;
|
.map_err(RPCError::protocol)?;
|
||||||
let dec_blob_data =
|
let dec_blob_data =
|
||||||
Crypto::decrypt_aead(&next_hop.blob, &next_hop.nonce, &dh_secret, None)
|
Crypto::decrypt_aead(&next_hop.blob, &next_hop.nonce, &dh_secret, None)
|
||||||
.map_err(RPCError::map_internal(
|
.map_err(RPCError::protocol)?;
|
||||||
"decryption of private route hop failed",
|
let dec_blob_reader = RPCMessageData::new(dec_blob_data).get_reader()?;
|
||||||
))?;
|
|
||||||
let dec_blob_reader = capnp::message::Reader::new(
|
|
||||||
RPCMessageData {
|
|
||||||
contents: dec_blob_data,
|
|
||||||
},
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Decode next RouteHop
|
// Decode next RouteHop
|
||||||
let route_hop = {
|
let route_hop = {
|
||||||
|
@ -2,9 +2,19 @@
|
|||||||
// Debugging
|
// Debugging
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use data_encoding::BASE64URL_NOPAD;
|
||||||
use routing_table::*;
|
use routing_table::*;
|
||||||
use rpc_processor::*;
|
use rpc_processor::*;
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
struct DebugCache {
|
||||||
|
imported_routes: Vec<PrivateRoute>,
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEBUG_CACHE: Mutex<DebugCache> = Mutex::new(DebugCache {
|
||||||
|
imported_routes: Vec::new(),
|
||||||
|
});
|
||||||
|
|
||||||
fn get_bucket_entry_state(text: &str) -> Option<BucketEntryState> {
|
fn get_bucket_entry_state(text: &str) -> Option<BucketEntryState> {
|
||||||
if text == "dead" {
|
if text == "dead" {
|
||||||
Some(BucketEntryState::Dead)
|
Some(BucketEntryState::Dead)
|
||||||
@ -44,6 +54,126 @@ fn get_route_id(rss: RouteSpecStore) -> impl Fn(&str) -> Option<DHTKey> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_safety_selection(text: &str, rss: RouteSpecStore) -> Option<SafetySelection> {
|
||||||
|
if text.len() == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if &text[0..1] == "-" {
|
||||||
|
// Unsafe
|
||||||
|
let text = &text[1..];
|
||||||
|
let seq = get_sequencing(text).unwrap_or(Sequencing::NoPreference);
|
||||||
|
Some(SafetySelection::Unsafe(seq))
|
||||||
|
} else {
|
||||||
|
// Safe
|
||||||
|
let mut preferred_route = None;
|
||||||
|
let mut hop_count = 2;
|
||||||
|
let mut stability = Stability::LowLatency;
|
||||||
|
let mut sequencing = Sequencing::NoPreference;
|
||||||
|
for x in text.split(",") {
|
||||||
|
let x = x.trim();
|
||||||
|
if let Some(pr) = get_route_id(rss.clone())(x) {
|
||||||
|
preferred_route = Some(pr)
|
||||||
|
}
|
||||||
|
if let Some(n) = get_number(x) {
|
||||||
|
hop_count = n;
|
||||||
|
}
|
||||||
|
if let Some(s) = get_stability(x) {
|
||||||
|
stability = s;
|
||||||
|
}
|
||||||
|
if let Some(s) = get_sequencing(x) {
|
||||||
|
sequencing = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let ss = SafetySpec {
|
||||||
|
preferred_route,
|
||||||
|
hop_count,
|
||||||
|
stability,
|
||||||
|
sequencing,
|
||||||
|
};
|
||||||
|
Some(SafetySelection::Safe(ss))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_node_ref_modifiers(mut node_ref: NodeRef) -> impl FnOnce(&str) -> Option<NodeRef> {
|
||||||
|
move |text| {
|
||||||
|
for m in text.split("/") {
|
||||||
|
if let Some(pt) = get_protocol_type(m) {
|
||||||
|
node_ref.merge_filter(NodeRefFilter::new().with_protocol_type(pt));
|
||||||
|
} else if let Some(at) = get_address_type(m) {
|
||||||
|
node_ref.merge_filter(NodeRefFilter::new().with_address_type(at));
|
||||||
|
} else if let Some(rd) = get_routing_domain(m) {
|
||||||
|
node_ref.merge_filter(NodeRefFilter::new().with_routing_domain(rd));
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(node_ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_destination(routing_table: RoutingTable) -> impl FnOnce(&str) -> Option<Destination> {
|
||||||
|
move |text| {
|
||||||
|
// Safety selection
|
||||||
|
let (text, ss) = if let Some((first, second)) = text.split_once('+') {
|
||||||
|
let ss = get_safety_selection(second, routing_table.route_spec_store())?;
|
||||||
|
(first, Some(ss))
|
||||||
|
} else {
|
||||||
|
(text, None)
|
||||||
|
};
|
||||||
|
if text.len() == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if &text[0..1] == "#" {
|
||||||
|
// Private route
|
||||||
|
let text = &text[1..];
|
||||||
|
let n = get_number(text)?;
|
||||||
|
let dc = DEBUG_CACHE.lock();
|
||||||
|
let r = dc.imported_routes.get(n)?;
|
||||||
|
Some(Destination::private_route(
|
||||||
|
r.clone(),
|
||||||
|
ss.unwrap_or(SafetySelection::Unsafe(Sequencing::NoPreference)),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
let (text, mods) = text
|
||||||
|
.split_once('/')
|
||||||
|
.map(|x| (x.0, Some(x.1)))
|
||||||
|
.unwrap_or((text, None));
|
||||||
|
if let Some((first, second)) = text.split_once('@') {
|
||||||
|
// Relay
|
||||||
|
let relay_id = get_dht_key(second)?;
|
||||||
|
let mut relay_nr = routing_table.lookup_node_ref(relay_id)?;
|
||||||
|
let target_id = get_dht_key(first)?;
|
||||||
|
|
||||||
|
if let Some(mods) = mods {
|
||||||
|
relay_nr = get_node_ref_modifiers(relay_nr)(mods)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut d = Destination::relay(relay_nr, target_id);
|
||||||
|
if let Some(ss) = ss {
|
||||||
|
d = d.with_safety(ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(d)
|
||||||
|
} else {
|
||||||
|
// Direct
|
||||||
|
let target_id = get_dht_key(text)?;
|
||||||
|
let mut target_nr = routing_table.lookup_node_ref(target_id)?;
|
||||||
|
|
||||||
|
if let Some(mods) = mods {
|
||||||
|
target_nr = get_node_ref_modifiers(target_nr)(mods)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut d = Destination::direct(target_nr);
|
||||||
|
if let Some(ss) = ss {
|
||||||
|
d = d.with_safety(ss)
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_number(text: &str) -> Option<usize> {
|
fn get_number(text: &str) -> Option<usize> {
|
||||||
usize::from_str(text).ok()
|
usize::from_str(text).ok()
|
||||||
}
|
}
|
||||||
@ -51,6 +181,22 @@ fn get_dht_key(text: &str) -> Option<DHTKey> {
|
|||||||
DHTKey::try_decode(text).ok()
|
DHTKey::try_decode(text).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_node_ref(routing_table: RoutingTable) -> impl FnOnce(&str) -> Option<NodeRef> {
|
||||||
|
move |text| {
|
||||||
|
let (text, mods) = text
|
||||||
|
.split_once('/')
|
||||||
|
.map(|x| (x.0, Some(x.1)))
|
||||||
|
.unwrap_or((text, None));
|
||||||
|
|
||||||
|
let node_id = get_dht_key(text)?;
|
||||||
|
let mut nr = routing_table.lookup_node_ref(node_id)?;
|
||||||
|
if let Some(mods) = mods {
|
||||||
|
nr = get_node_ref_modifiers(nr)(mods)?;
|
||||||
|
}
|
||||||
|
Some(nr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_protocol_type(text: &str) -> Option<ProtocolType> {
|
fn get_protocol_type(text: &str) -> Option<ProtocolType> {
|
||||||
let lctext = text.to_ascii_lowercase();
|
let lctext = text.to_ascii_lowercase();
|
||||||
if lctext == "udp" {
|
if lctext == "udp" {
|
||||||
@ -366,55 +512,19 @@ impl VeilidAPI {
|
|||||||
async fn debug_contact(&self, args: String) -> Result<String, VeilidAPIError> {
|
async fn debug_contact(&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 node_id = get_debug_argument_at(&args, 0, "debug_contact", "node_id", get_dht_key)?;
|
|
||||||
|
|
||||||
let network_manager = self.network_manager()?;
|
let network_manager = self.network_manager()?;
|
||||||
let routing_table = network_manager.routing_table();
|
let routing_table = network_manager.routing_table();
|
||||||
|
|
||||||
let mut nr = match routing_table.lookup_node_ref(node_id) {
|
let node_ref = get_debug_argument_at(
|
||||||
Some(nr) => nr,
|
&args,
|
||||||
None => return Ok("Node id not found in routing table".to_owned()),
|
0,
|
||||||
};
|
"debug_contact",
|
||||||
|
"node_ref",
|
||||||
let mut ai = 1;
|
get_node_ref(routing_table),
|
||||||
let mut routing_domain = None;
|
)?;
|
||||||
while ai < args.len() {
|
|
||||||
if let Ok(pt) = get_debug_argument_at(
|
|
||||||
&args,
|
|
||||||
ai,
|
|
||||||
"debug_contact",
|
|
||||||
"protocol_type",
|
|
||||||
get_protocol_type,
|
|
||||||
) {
|
|
||||||
nr.merge_filter(NodeRefFilter::new().with_protocol_type(pt));
|
|
||||||
} else if let Ok(at) =
|
|
||||||
get_debug_argument_at(&args, ai, "debug_contact", "address_type", get_address_type)
|
|
||||||
{
|
|
||||||
nr.merge_filter(NodeRefFilter::new().with_address_type(at));
|
|
||||||
} else if let Ok(rd) = get_debug_argument_at(
|
|
||||||
&args,
|
|
||||||
ai,
|
|
||||||
"debug_contact",
|
|
||||||
"routing_domain",
|
|
||||||
get_routing_domain,
|
|
||||||
) {
|
|
||||||
if routing_domain.is_none() {
|
|
||||||
routing_domain = Some(rd);
|
|
||||||
} else {
|
|
||||||
return Ok("Multiple routing domains specified".to_owned());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Ok(format!("Invalid argument specified: {}", args[ai]));
|
|
||||||
}
|
|
||||||
ai += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(routing_domain) = routing_domain {
|
|
||||||
nr.merge_filter(NodeRefFilter::new().with_routing_domain(routing_domain))
|
|
||||||
}
|
|
||||||
|
|
||||||
let cm = network_manager
|
let cm = network_manager
|
||||||
.get_node_contact_method(nr)
|
.get_node_contact_method(node_ref)
|
||||||
.map_err(VeilidAPIError::internal)?;
|
.map_err(VeilidAPIError::internal)?;
|
||||||
|
|
||||||
Ok(format!("{:#?}", cm))
|
Ok(format!("{:#?}", cm))
|
||||||
@ -427,49 +537,17 @@ impl VeilidAPI {
|
|||||||
|
|
||||||
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 node_id = get_debug_argument_at(&args, 0, "debug_ping", "node_id", get_dht_key)?;
|
let dest = get_debug_argument_at(
|
||||||
|
&args,
|
||||||
let mut nr = match routing_table.lookup_node_ref(node_id) {
|
0,
|
||||||
Some(nr) => nr,
|
"debug_ping",
|
||||||
None => return Ok("Node id not found in routing table".to_owned()),
|
"destination",
|
||||||
};
|
get_destination(routing_table),
|
||||||
|
)?;
|
||||||
let mut ai = 1;
|
|
||||||
let mut routing_domain = None;
|
|
||||||
while ai < args.len() {
|
|
||||||
if let Ok(pt) =
|
|
||||||
get_debug_argument_at(&args, ai, "debug_ping", "protocol_type", get_protocol_type)
|
|
||||||
{
|
|
||||||
nr.merge_filter(NodeRefFilter::new().with_protocol_type(pt));
|
|
||||||
} else if let Ok(at) =
|
|
||||||
get_debug_argument_at(&args, ai, "debug_ping", "address_type", get_address_type)
|
|
||||||
{
|
|
||||||
nr.merge_filter(NodeRefFilter::new().with_address_type(at));
|
|
||||||
} else if let Ok(rd) = get_debug_argument_at(
|
|
||||||
&args,
|
|
||||||
ai,
|
|
||||||
"debug_ping",
|
|
||||||
"routing_domain",
|
|
||||||
get_routing_domain,
|
|
||||||
) {
|
|
||||||
if routing_domain.is_none() {
|
|
||||||
routing_domain = Some(rd);
|
|
||||||
} else {
|
|
||||||
return Ok("Multiple routing domains specified".to_owned());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Ok(format!("Invalid argument specified: {}", args[ai]));
|
|
||||||
}
|
|
||||||
ai += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(routing_domain) = routing_domain {
|
|
||||||
nr.merge_filter(NodeRefFilter::new().with_routing_domain(routing_domain))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump routing table entry
|
// Dump routing table entry
|
||||||
let out = match rpc
|
let out = match rpc
|
||||||
.rpc_call_status(Destination::direct(nr))
|
.rpc_call_status(dest)
|
||||||
.await
|
.await
|
||||||
.map_err(VeilidAPIError::internal)?
|
.map_err(VeilidAPIError::internal)?
|
||||||
{
|
{
|
||||||
@ -595,7 +673,14 @@ impl VeilidAPI {
|
|||||||
// Convert to blob
|
// Convert to blob
|
||||||
let blob_data = RouteSpecStore::private_route_to_blob(&private_route)
|
let blob_data = RouteSpecStore::private_route_to_blob(&private_route)
|
||||||
.map_err(VeilidAPIError::internal)?;
|
.map_err(VeilidAPIError::internal)?;
|
||||||
data_encoding::BASE64URL_NOPAD.encode(&blob_data)
|
let out = BASE64URL_NOPAD.encode(&blob_data);
|
||||||
|
info!(
|
||||||
|
"Published route {} as {} bytes:\n{}",
|
||||||
|
route_id.encode(),
|
||||||
|
blob_data.len(),
|
||||||
|
out
|
||||||
|
);
|
||||||
|
format!("Published route {}", route_id.encode())
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
format!("Couldn't assemble private route: {}", e)
|
format!("Couldn't assemble private route: {}", e)
|
||||||
@ -646,9 +731,21 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
async fn debug_route_import(&self, _args: Vec<String>) -> Result<String, VeilidAPIError> {
|
async fn debug_route_import(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
|
||||||
// <blob>
|
// <blob>
|
||||||
let out = format!("");
|
|
||||||
|
let blob = get_debug_argument_at(&args, 1, "debug_route", "blob", get_string)?;
|
||||||
|
let blob_dec = BASE64URL_NOPAD
|
||||||
|
.decode(blob.as_bytes())
|
||||||
|
.map_err(VeilidAPIError::generic)?;
|
||||||
|
let pr =
|
||||||
|
RouteSpecStore::blob_to_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.public_key);
|
||||||
|
dc.imported_routes.push(pr);
|
||||||
|
|
||||||
return Ok(out);
|
return Ok(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,22 +779,34 @@ impl VeilidAPI {
|
|||||||
buckets [dead|reliable]
|
buckets [dead|reliable]
|
||||||
dialinfo
|
dialinfo
|
||||||
entries [dead|reliable] [limit]
|
entries [dead|reliable] [limit]
|
||||||
entry <node_id>
|
entry <node>
|
||||||
nodeinfo
|
nodeinfo
|
||||||
config [key [new value]]
|
config [key [new value]]
|
||||||
purge <buckets|connections>
|
purge <buckets|connections>
|
||||||
attach
|
attach
|
||||||
detach
|
detach
|
||||||
restart network
|
restart network
|
||||||
ping <node_id> [protocol_type][address_type][routing_domain]
|
ping <destination>
|
||||||
contact <node_id> [protocol_type [address_type]]
|
contact <node>[<modifiers>]
|
||||||
route allocate [ord|*ord] [rel] [<count>] [in|out]
|
route allocate [ord|*ord] [rel] [<count>] [in|out]
|
||||||
route release <route id>
|
release <route>
|
||||||
route publish <route id> [full]
|
publish <route> [full]
|
||||||
route unpublish <route id>
|
unpublish <route>
|
||||||
route print <route id>
|
print <route>
|
||||||
route list
|
list
|
||||||
route import <blob>
|
import <blob>
|
||||||
|
|
||||||
|
<destination> is:
|
||||||
|
* direct: <node>[+<safety>][<modifiers>]
|
||||||
|
* relay: <relay>@<target>[+<safety>][<modifiers>]
|
||||||
|
* private: #<id>[+<safety>]
|
||||||
|
<safety> is:
|
||||||
|
* unsafe: -[ord|*ord]
|
||||||
|
* safe: [route][,ord|*ord][,rel][,<count>]
|
||||||
|
<modifiers> is: [/<protocoltype>][/<addresstype>][/<routingdomain>]
|
||||||
|
<protocoltype> is: udp|tcp|ws|wss
|
||||||
|
<addresstype> is: ipv4|ipv6
|
||||||
|
<routingdomain> is: public|local
|
||||||
"#
|
"#
|
||||||
.to_owned())
|
.to_owned())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user