This commit is contained in:
John Smith 2022-08-05 20:34:00 -04:00
parent ef096eb310
commit 0e047a0120
4 changed files with 101 additions and 8 deletions

View File

@ -112,7 +112,7 @@ struct ClientWhitelistEntry {
// Mechanism required to contact another node
#[derive(Clone, Debug)]
enum ContactMethod {
pub(crate) enum ContactMethod {
Unreachable, // Node is not reachable by any means
Direct(DialInfo), // Contact the node directly
SignalReverse(NodeRef, NodeRef), // Request via signal the node connect back directly
@ -1054,7 +1054,7 @@ impl NetworkManager {
// Figure out how to reach a node
#[instrument(level = "trace", skip(self), ret)]
fn get_contact_method(&self, target_node_ref: NodeRef) -> ContactMethod {
pub(crate) fn get_contact_method(&self, target_node_ref: NodeRef) -> ContactMethod {
// Try local first
let out = self.get_contact_method_local(target_node_ref.clone());
if !matches!(out, ContactMethod::Unreachable) {

View File

@ -165,7 +165,9 @@ impl BucketEntryInner {
pub fn set_last_connection(&mut self, last_connection: ConnectionDescriptor, timestamp: u64) {
self.last_connection = Some((last_connection, timestamp));
}
pub fn clear_last_connection(&mut self) {
self.last_connection = None;
}
pub fn last_connection(&self) -> Option<(ConnectionDescriptor, u64)> {
self.last_connection
}

View File

@ -370,17 +370,37 @@ impl RoutingTable {
// Attempt to empty the routing table
// should only be performed when there are no node_refs (detached)
pub fn purge(&self) {
pub fn purge_buckets(&self) {
let mut inner = self.inner.write();
log_rtab!(
"Starting routing table purge. Table currently has {} nodes",
"Starting routing table buckets purge. Table currently has {} nodes",
inner.bucket_entry_count
);
for bucket in &mut inner.buckets {
bucket.kick(0);
}
log_rtab!(debug
"Routing table purge complete. Routing table now has {} nodes",
"Routing table buckets purge complete. Routing table now has {} nodes",
inner.bucket_entry_count
);
}
// Attempt to remove last_connections from entries
pub fn purge_last_connections(&self) {
let mut inner = self.inner.write();
log_rtab!(
"Starting routing table last_connections purge. Table currently has {} nodes",
inner.bucket_entry_count
);
for bucket in &mut inner.buckets {
for entry in bucket.entries() {
entry.1.with_mut(|e| {
e.clear_last_connection();
});
}
}
log_rtab!(debug
"Routing table last_connections purge complete. Routing table now has {} nodes",
inner.bucket_entry_count
);
}

View File

@ -201,8 +201,20 @@ impl VeilidAPI {
) {
apibail_internal!("Must be detached to purge");
}
self.network_manager()?.routing_table().purge();
self.network_manager()?.routing_table().purge_buckets();
Ok("Buckets purged".to_owned())
} else if args[0] == "connections" {
// Purge connection table
let connection_manager = self.network_manager()?.connection_manager();
connection_manager.shutdown().await;
connection_manager.startup().await;
// Eliminate last_connections from routing table entries
self.network_manager()?
.routing_table()
.purge_last_connections();
Ok("Connections purged".to_owned())
} else {
Err(VeilidAPIError::InvalidArgument {
context: "debug_purge".to_owned(),
@ -244,6 +256,59 @@ impl VeilidAPI {
Ok("Detached".to_owned())
}
async fn debug_contact(&self, args: String) -> Result<String, VeilidAPIError> {
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 routing_table = network_manager.routing_table();
let nr = match routing_table.lookup_node_ref(node_id) {
Some(nr) => nr,
None => return Ok("Node id not found in routing table".to_owned()),
};
let cm = network_manager.get_contact_method(nr);
Ok(format!("{:#?}", cm))
}
async fn debug_ping(&self, args: String) -> Result<String, VeilidAPIError> {
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 routing_table = self.network_manager()?.routing_table();
let nr = match routing_table.lookup_node_ref(node_id) {
Some(nr) => nr,
None => return Ok("Node id not found in routing table".to_owned()),
};
let rpc = self.network_manager()?.rpc_processor();
// Dump routing table entry
let out = match rpc
.rpc_call_status(nr)
.await
.map_err(VeilidAPIError::internal)?
{
NetworkResult::Value(v) => v,
NetworkResult::Timeout => {
return Ok("Timeout".to_owned());
}
NetworkResult::NoConnection(e) => {
return Ok(format!("NoConnection({})", e));
}
NetworkResult::InvalidMessage(e) => {
return Ok(format!("InvalidMessage({})", e));
}
};
Ok(format!("{:#?}", out))
}
pub async fn debug_help(&self, _args: String) -> Result<String, VeilidAPIError> {
Ok(r#">>> Debug commands:
help
@ -253,10 +318,12 @@ impl VeilidAPI {
entry [node_id]
nodeinfo
config [key [new value]]
purge buckets
purge [buckets|connections]
attach
detach
restart network
ping [node_id]
contact [node_id]
"#
.to_owned())
}
@ -282,6 +349,10 @@ impl VeilidAPI {
self.debug_entries(rest).await
} else if arg == "entry" {
self.debug_entry(rest).await
} else if arg == "ping" {
self.debug_ping(rest).await
} else if arg == "contact" {
self.debug_contact(rest).await
} else if arg == "nodeinfo" {
self.debug_nodeinfo(rest).await
} else if arg == "purge" {