lifetime cleanup
This commit is contained in:
parent
92b22d5af5
commit
941cf9309e
@ -34,8 +34,8 @@ pub struct LowLevelPortInfo {
|
|||||||
pub low_level_protocol_ports: LowLevelProtocolPorts,
|
pub low_level_protocol_ports: LowLevelProtocolPorts,
|
||||||
pub protocol_to_port: ProtocolToPortMapping,
|
pub protocol_to_port: ProtocolToPortMapping,
|
||||||
}
|
}
|
||||||
pub type RoutingTableEntryFilter =
|
pub type RoutingTableEntryFilter<'t> =
|
||||||
Box<dyn for<'r> FnMut(&'r RoutingTableInner, DHTKey, Option<Arc<BucketEntry>>) -> bool + Send>;
|
Box<dyn FnMut(&RoutingTableInner, DHTKey, Option<Arc<BucketEntry>>) -> bool + Send + 't>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct RoutingTableHealth {
|
pub struct RoutingTableHealth {
|
||||||
@ -550,7 +550,7 @@ impl RoutingTable {
|
|||||||
pub fn make_inbound_dial_info_entry_filter<'a>(
|
pub fn make_inbound_dial_info_entry_filter<'a>(
|
||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
) -> RoutingTableEntryFilter {
|
) -> RoutingTableEntryFilter<'a> {
|
||||||
// does it have matching public dial info?
|
// does it have matching public dial info?
|
||||||
Box::new(move |rti, _k, e| {
|
Box::new(move |rti, _k, e| {
|
||||||
if let Some(e) = e {
|
if let Some(e) = e {
|
||||||
@ -575,10 +575,10 @@ impl RoutingTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a filter that finds nodes capable of dialing a particular outbound dialinfo
|
/// Makes a filter that finds nodes capable of dialing a particular outbound dialinfo
|
||||||
pub fn make_outbound_dial_info_entry_filter(
|
pub fn make_outbound_dial_info_entry_filter<'a>(
|
||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
dial_info: DialInfo,
|
dial_info: DialInfo,
|
||||||
) -> RoutingTableEntryFilter {
|
) -> RoutingTableEntryFilter<'a> {
|
||||||
// does the node's outbound capabilities match the dialinfo?
|
// does the node's outbound capabilities match the dialinfo?
|
||||||
Box::new(move |rti, _k, e| {
|
Box::new(move |rti, _k, e| {
|
||||||
if let Some(e) = e {
|
if let Some(e) = e {
|
||||||
|
@ -138,13 +138,17 @@ fn _get_route_permutation_count(hop_count: usize) -> usize {
|
|||||||
(3..hop_count).into_iter().fold(2usize, |acc, x| acc * x)
|
(3..hop_count).into_iter().fold(2usize, |acc, x| acc * x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PermFunc<'t> = Box<dyn Fn(&[usize]) -> Option<(Vec<usize>, Vec<u8>)> + Send + 't>;
|
||||||
|
|
||||||
/// get the route permutation at particular 'perm' index, starting at the 'start' index
|
/// get the route permutation at particular 'perm' index, starting at the 'start' index
|
||||||
/// for a set of 'hop_count' nodes. the first node is always fixed, and the maximum
|
/// for a set of 'hop_count' nodes. the first node is always fixed, and the maximum
|
||||||
/// number of permutations is given by get_route_permutation_count()
|
/// number of permutations is given by get_route_permutation_count()
|
||||||
fn with_route_permutations<F>(hop_count: usize, start: usize, mut f: F) -> bool
|
|
||||||
where
|
fn with_route_permutations(
|
||||||
F: FnMut(&[usize]) -> bool,
|
hop_count: usize,
|
||||||
{
|
start: usize,
|
||||||
|
f: &PermFunc,
|
||||||
|
) -> Option<(Vec<usize>, Vec<u8>)> {
|
||||||
if hop_count == 0 {
|
if hop_count == 0 {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
@ -159,20 +163,19 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// heaps algorithm, but skipping the first element
|
// heaps algorithm, but skipping the first element
|
||||||
fn heaps_permutation<F>(permutation: &mut [usize], size: usize, mut f: F) -> bool
|
fn heaps_permutation(
|
||||||
where
|
permutation: &mut [usize],
|
||||||
F: FnMut(&[usize]) -> bool,
|
size: usize,
|
||||||
{
|
f: &PermFunc,
|
||||||
|
) -> Option<(Vec<usize>, Vec<u8>)> {
|
||||||
if size == 1 {
|
if size == 1 {
|
||||||
if f(&permutation) {
|
return f(&permutation);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
if heaps_permutation(permutation, size - 1, &mut f) {
|
let out = heaps_permutation(permutation, size - 1, f);
|
||||||
return true;
|
if out.is_some() {
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
if size % 2 == 1 {
|
if size % 2 == 1 {
|
||||||
permutation.swap(1, size);
|
permutation.swap(1, size);
|
||||||
@ -180,7 +183,8 @@ where
|
|||||||
permutation.swap(1 + i, size);
|
permutation.swap(1 + i, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
// recurse
|
// recurse
|
||||||
@ -502,77 +506,81 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now go through nodes and try to build a route we haven't seen yet
|
// Now go through nodes and try to build a route we haven't seen yet
|
||||||
|
let perm_func = Box::new(|permutation: &[usize]| {
|
||||||
|
// Get the route cache key
|
||||||
|
let cache_key = route_permutation_to_hop_cache(&nodes, permutation);
|
||||||
|
|
||||||
|
// Skip routes we have already seen
|
||||||
|
if inner.cache.hop_cache.contains(&cache_key) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure this route is viable by checking that each node can contact the next one
|
||||||
|
if directions.contains(Direction::Outbound) {
|
||||||
|
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
|
||||||
|
let our_node_id = rti.node_id();
|
||||||
|
let mut previous_node = &(our_node_id, our_node_info);
|
||||||
|
let mut reachable = true;
|
||||||
|
for n in permutation {
|
||||||
|
let current_node = nodes.get(*n).unwrap();
|
||||||
|
let cm = rti.get_contact_method(
|
||||||
|
RoutingDomain::PublicInternet,
|
||||||
|
&previous_node.0,
|
||||||
|
&previous_node.1,
|
||||||
|
¤t_node.0,
|
||||||
|
¤t_node.1,
|
||||||
|
DialInfoFilter::all(),
|
||||||
|
sequencing,
|
||||||
|
);
|
||||||
|
if matches!(cm, ContactMethod::Unreachable) {
|
||||||
|
reachable = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previous_node = current_node;
|
||||||
|
}
|
||||||
|
if !reachable {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if directions.contains(Direction::Inbound) {
|
||||||
|
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
|
||||||
|
let our_node_id = rti.node_id();
|
||||||
|
let mut next_node = &(our_node_id, our_node_info);
|
||||||
|
let mut reachable = true;
|
||||||
|
for n in permutation.iter().rev() {
|
||||||
|
let current_node = nodes.get(*n).unwrap();
|
||||||
|
let cm = rti.get_contact_method(
|
||||||
|
RoutingDomain::PublicInternet,
|
||||||
|
&next_node.0,
|
||||||
|
&next_node.1,
|
||||||
|
¤t_node.0,
|
||||||
|
¤t_node.1,
|
||||||
|
DialInfoFilter::all(),
|
||||||
|
sequencing,
|
||||||
|
);
|
||||||
|
if matches!(cm, ContactMethod::Unreachable) {
|
||||||
|
reachable = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next_node = current_node;
|
||||||
|
}
|
||||||
|
if !reachable {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Keep this route
|
||||||
|
let route_nodes = permutation.to_vec();
|
||||||
|
Some((route_nodes, cache_key))
|
||||||
|
}) as PermFunc;
|
||||||
|
|
||||||
let mut route_nodes: Vec<usize> = Vec::new();
|
let mut route_nodes: Vec<usize> = Vec::new();
|
||||||
let mut cache_key: Vec<u8> = Vec::new();
|
let mut cache_key: Vec<u8> = Vec::new();
|
||||||
|
|
||||||
for start in 0..(nodes.len() - hop_count) {
|
for start in 0..(nodes.len() - hop_count) {
|
||||||
// Try the permutations available starting with 'start'
|
// Try the permutations available starting with 'start'
|
||||||
let done = with_route_permutations(hop_count, start, |permutation: &[usize]| {
|
if let Some((rn, ck)) = with_route_permutations(hop_count, start, &perm_func) {
|
||||||
// Get the route cache key
|
route_nodes = rn;
|
||||||
cache_key = route_permutation_to_hop_cache(&nodes, permutation);
|
cache_key = ck;
|
||||||
|
|
||||||
// Skip routes we have already seen
|
|
||||||
if inner.cache.hop_cache.contains(&cache_key) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure this route is viable by checking that each node can contact the next one
|
|
||||||
if directions.contains(Direction::Outbound) {
|
|
||||||
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
|
|
||||||
let our_node_id = rti.node_id();
|
|
||||||
let mut previous_node = &(our_node_id, our_node_info);
|
|
||||||
let mut reachable = true;
|
|
||||||
for n in permutation {
|
|
||||||
let current_node = nodes.get(*n).unwrap();
|
|
||||||
let cm = rti.get_contact_method(
|
|
||||||
RoutingDomain::PublicInternet,
|
|
||||||
&previous_node.0,
|
|
||||||
&previous_node.1,
|
|
||||||
¤t_node.0,
|
|
||||||
¤t_node.1,
|
|
||||||
DialInfoFilter::all(),
|
|
||||||
sequencing,
|
|
||||||
);
|
|
||||||
if matches!(cm, ContactMethod::Unreachable) {
|
|
||||||
reachable = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
previous_node = current_node;
|
|
||||||
}
|
|
||||||
if !reachable {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if directions.contains(Direction::Inbound) {
|
|
||||||
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
|
|
||||||
let our_node_id = rti.node_id();
|
|
||||||
let mut next_node = &(our_node_id, our_node_info);
|
|
||||||
let mut reachable = true;
|
|
||||||
for n in permutation.iter().rev() {
|
|
||||||
let current_node = nodes.get(*n).unwrap();
|
|
||||||
let cm = rti.get_contact_method(
|
|
||||||
RoutingDomain::PublicInternet,
|
|
||||||
&next_node.0,
|
|
||||||
&next_node.1,
|
|
||||||
¤t_node.0,
|
|
||||||
¤t_node.1,
|
|
||||||
DialInfoFilter::all(),
|
|
||||||
sequencing,
|
|
||||||
);
|
|
||||||
if matches!(cm, ContactMethod::Unreachable) {
|
|
||||||
reachable = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
next_node = current_node;
|
|
||||||
}
|
|
||||||
if !reachable {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Keep this route
|
|
||||||
route_nodes = permutation.to_vec();
|
|
||||||
true
|
|
||||||
});
|
|
||||||
if done {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -611,6 +619,8 @@ impl RouteSpecStore {
|
|||||||
sequencing,
|
sequencing,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
drop(perm_func);
|
||||||
|
|
||||||
// Add to cache
|
// Add to cache
|
||||||
Self::add_to_cache(&mut inner.cache, cache_key, &rsd);
|
Self::add_to_cache(&mut inner.cache, cache_key, &rsd);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user