more refactor
This commit is contained in:
@@ -13,15 +13,15 @@ impl RoutingTable {
|
||||
out
|
||||
}
|
||||
pub fn debug_info_dialinfo(&self) -> String {
|
||||
let ldis = self.local_dial_info();
|
||||
let gdis = self.global_dial_info();
|
||||
let ldis = self.local_dial_info_details();
|
||||
let gdis = self.global_dial_info_details();
|
||||
let mut out = String::new();
|
||||
|
||||
out += "Local Dial Info:\n";
|
||||
out += "Local Dial Info Details:\n";
|
||||
for (n, ldi) in ldis.iter().enumerate() {
|
||||
out += &format!(" {:>2}: {:?}\n", n, ldi);
|
||||
}
|
||||
out += "Global Dial Info:\n";
|
||||
out += "Global Dial Info Details:\n";
|
||||
for (n, gdi) in gdis.iter().enumerate() {
|
||||
out += &format!(" {:>2}: {:?}\n", n, gdi);
|
||||
}
|
||||
|
@@ -10,42 +10,18 @@ pub type FilterType = Box<dyn Fn(&(&DHTKey, Option<&mut BucketEntry>)) -> bool>;
|
||||
impl RoutingTable {
|
||||
// Retrieve the fastest nodes in the routing table with a particular kind of protocol address type
|
||||
// Returns noderefs are are scoped to that address type only
|
||||
pub fn get_fast_nodes_of_type(
|
||||
&self,
|
||||
protocol_address_type: ProtocolAddressType,
|
||||
) -> Vec<NodeRef> {
|
||||
pub fn get_fast_nodes_filtered(&self, dial_info_filter: &DialInfoFilter) -> Vec<NodeRef> {
|
||||
let dial_info_filter = dial_info_filter.clone();
|
||||
self.find_fastest_nodes(
|
||||
// filter
|
||||
Some(Box::new(
|
||||
move |params: &(&DHTKey, Option<&mut BucketEntry>)| {
|
||||
// Only interested in nodes with node info
|
||||
if let Some(node_info) = ¶ms.1.as_ref().unwrap().peer_stats().node_info {
|
||||
// Will the node validate dial info?
|
||||
// and does it have a UDPv4, public scope, dial info?
|
||||
if node_info.will_validate_dial_info
|
||||
&& params
|
||||
.1
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.dial_info_entries_as_ref()
|
||||
.iter()
|
||||
.find_map(|die| {
|
||||
if die.matches_peer_scope(PeerScope::Global)
|
||||
&& die.dial_info().protocol_address_type()
|
||||
== protocol_address_type
|
||||
{
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.is_some()
|
||||
{
|
||||
// If so return true and include this node
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
params
|
||||
.1
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.first_filtered_dial_info(|di| di.matches_filter(&dial_info_filter))
|
||||
.is_some()
|
||||
},
|
||||
)),
|
||||
// transform
|
||||
@@ -54,7 +30,7 @@ impl RoutingTable {
|
||||
self.clone(),
|
||||
*e.0,
|
||||
e.1.as_mut().unwrap(),
|
||||
protocol_address_type,
|
||||
dial_info_filter.clone(),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -63,13 +39,13 @@ impl RoutingTable {
|
||||
pub fn get_own_peer_info(&self, scope: PeerScope) -> PeerInfo {
|
||||
let dial_infos = match scope {
|
||||
PeerScope::All => {
|
||||
let mut divec = self.global_dial_info();
|
||||
divec.append(&mut self.local_dial_info());
|
||||
let mut divec = self.global_dial_info_details();
|
||||
divec.append(&mut self.local_dial_info_details());
|
||||
divec.dedup();
|
||||
divec
|
||||
}
|
||||
PeerScope::Global => self.global_dial_info(),
|
||||
PeerScope::Local => self.local_dial_info(),
|
||||
PeerScope::Global => self.global_dial_info_details(),
|
||||
PeerScope::Local => self.local_dial_info_details(),
|
||||
};
|
||||
|
||||
PeerInfo {
|
||||
|
@@ -1,7 +1,6 @@
|
||||
mod bucket;
|
||||
mod bucket_entry;
|
||||
mod debug;
|
||||
mod dial_info_entry;
|
||||
mod find_nodes;
|
||||
mod node_ref;
|
||||
mod stats_accounting;
|
||||
@@ -12,12 +11,10 @@ use crate::network_manager::*;
|
||||
use crate::rpc_processor::*;
|
||||
use crate::xx::*;
|
||||
use crate::*;
|
||||
use alloc::collections::VecDeque;
|
||||
use alloc::str::FromStr;
|
||||
use bucket::*;
|
||||
pub use bucket_entry::*;
|
||||
pub use debug::*;
|
||||
pub use dial_info_entry::*;
|
||||
pub use find_nodes::*;
|
||||
use futures_util::stream::{FuturesUnordered, StreamExt};
|
||||
pub use node_ref::*;
|
||||
@@ -157,42 +154,35 @@ impl RoutingTable {
|
||||
!inner.local_dial_info.is_empty()
|
||||
}
|
||||
|
||||
pub fn local_dial_info(&self) -> Vec<DialInfoDetail> {
|
||||
pub fn local_dial_info_details(&self) -> Vec<DialInfoDetail> {
|
||||
let inner = self.inner.lock();
|
||||
inner.local_dial_info.clone()
|
||||
}
|
||||
|
||||
pub fn local_dial_info_for_protocol(&self, protocol_type: ProtocolType) -> Vec<DialInfoDetail> {
|
||||
pub fn first_filtered_local_dial_info_details<F>(&self, filter: F) -> Option<DialInfoDetail>
|
||||
where
|
||||
F: Fn(&DialInfoDetail) -> bool,
|
||||
{
|
||||
let inner = self.inner.lock();
|
||||
inner
|
||||
.local_dial_info
|
||||
.iter()
|
||||
.filter_map(|di| {
|
||||
if di.dial_info.protocol_type() != protocol_type {
|
||||
None
|
||||
} else {
|
||||
Some(di.clone())
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
for did in &inner.local_dial_info {
|
||||
if filter(did) {
|
||||
return Some(did.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn local_dial_info_for_protocol_address_type(
|
||||
&self,
|
||||
protocol_address_type: ProtocolAddressType,
|
||||
) -> Vec<DialInfoDetail> {
|
||||
pub fn all_filtered_local_dial_info_details<F>(&self, filter: F) -> Vec<DialInfoDetail>
|
||||
where
|
||||
F: Fn(&DialInfoDetail) -> bool,
|
||||
{
|
||||
let inner = self.inner.lock();
|
||||
inner
|
||||
.local_dial_info
|
||||
.iter()
|
||||
.filter_map(|di| {
|
||||
if di.dial_info.protocol_address_type() != protocol_address_type {
|
||||
None
|
||||
} else {
|
||||
Some(di.clone())
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
let ret = Vec::new();
|
||||
for did in &inner.local_dial_info {
|
||||
if filter(did) {
|
||||
ret.push(did.clone());
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn register_local_dial_info(&self, dial_info: DialInfo, origin: DialInfoOrigin) {
|
||||
@@ -230,44 +220,35 @@ impl RoutingTable {
|
||||
!inner.global_dial_info.is_empty()
|
||||
}
|
||||
|
||||
pub fn global_dial_info(&self) -> Vec<DialInfoDetail> {
|
||||
pub fn global_dial_info_details(&self) -> Vec<DialInfoDetail> {
|
||||
let inner = self.inner.lock();
|
||||
inner.global_dial_info.clone()
|
||||
}
|
||||
|
||||
pub fn global_dial_info_for_protocol(
|
||||
&self,
|
||||
protocol_type: ProtocolType,
|
||||
) -> Vec<DialInfoDetail> {
|
||||
pub fn first_filtered_global_dial_info_details<F>(&self, filter: F) -> Option<DialInfoDetail>
|
||||
where
|
||||
F: Fn(&DialInfoDetail) -> bool,
|
||||
{
|
||||
let inner = self.inner.lock();
|
||||
inner
|
||||
.global_dial_info
|
||||
.iter()
|
||||
.filter_map(|di| {
|
||||
if di.dial_info.protocol_type() != protocol_type {
|
||||
None
|
||||
} else {
|
||||
Some(di.clone())
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
for did in &inner.global_dial_info {
|
||||
if filter(did) {
|
||||
return Some(did.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
pub fn global_dial_info_for_protocol_address_type(
|
||||
&self,
|
||||
protocol_address_type: ProtocolAddressType,
|
||||
) -> Vec<DialInfoDetail> {
|
||||
pub fn all_filtered_global_dial_info_details<F>(&self, filter: F) -> Vec<DialInfoDetail>
|
||||
where
|
||||
F: Fn(&DialInfoDetail) -> bool,
|
||||
{
|
||||
let inner = self.inner.lock();
|
||||
inner
|
||||
.global_dial_info
|
||||
.iter()
|
||||
.filter_map(|di| {
|
||||
if di.dial_info.protocol_address_type() != protocol_address_type {
|
||||
None
|
||||
} else {
|
||||
Some(di.clone())
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
let ret = Vec::new();
|
||||
for did in &inner.global_dial_info {
|
||||
if filter(did) {
|
||||
ret.push(did.clone());
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn register_global_dial_info(
|
||||
@@ -287,7 +268,7 @@ impl RoutingTable {
|
||||
});
|
||||
|
||||
info!(
|
||||
"Public Dial Info: {}",
|
||||
"Global Dial Info: {}",
|
||||
NodeDialInfoSingle {
|
||||
node_id: NodeId::new(inner.node_id),
|
||||
dial_info
|
||||
@@ -356,34 +337,6 @@ impl RoutingTable {
|
||||
*self.inner.lock() = Self::new_inner(self.network_manager());
|
||||
}
|
||||
|
||||
// Just match address and port to help sort dialinfoentries for buckets
|
||||
// because inbound connections will not have dialinfo associated with them
|
||||
// but should have ip addresses if they have changed
|
||||
fn dial_info_peer_address_match(dial_info: &DialInfo, peer_addr: &PeerAddress) -> bool {
|
||||
match dial_info {
|
||||
DialInfo::UDP(_) => {
|
||||
peer_addr.protocol_type == ProtocolType::UDP
|
||||
&& peer_addr.port == dial_info.port()
|
||||
&& peer_addr.address.address_string() == dial_info.address_string()
|
||||
}
|
||||
DialInfo::TCP(_) => {
|
||||
peer_addr.protocol_type == ProtocolType::TCP
|
||||
&& peer_addr.port == dial_info.port()
|
||||
&& peer_addr.address.address_string() == dial_info.address_string()
|
||||
}
|
||||
DialInfo::WS(_) => {
|
||||
peer_addr.protocol_type == ProtocolType::WS
|
||||
&& peer_addr.port == dial_info.port()
|
||||
&& peer_addr.address.address_string() == dial_info.address_string()
|
||||
}
|
||||
DialInfo::WSS(_) => {
|
||||
peer_addr.protocol_type == ProtocolType::WSS
|
||||
&& peer_addr.port == dial_info.port()
|
||||
&& peer_addr.address.address_string() == dial_info.address_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to settle buckets and remove entries down to the desired number
|
||||
// which may not be possible due extant NodeRefs
|
||||
fn kick_bucket(inner: &mut RoutingTableInner, idx: usize) {
|
||||
@@ -482,7 +435,7 @@ impl RoutingTable {
|
||||
) -> Result<NodeRef, String> {
|
||||
let nr = self.create_node_ref(node_id)?;
|
||||
nr.operate(move |e| -> Result<(), String> {
|
||||
e.update_dial_info(dial_infos);
|
||||
e.update_dial_infos(dial_infos);
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
@@ -604,6 +557,7 @@ impl RoutingTable {
|
||||
let mut bsmap: BTreeMap<DHTKey, Vec<DialInfo>> = BTreeMap::new();
|
||||
for b in bootstrap {
|
||||
let ndis = NodeDialInfoSingle::from_str(b.as_str())
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_rtab!("Invalid dial info in bootstrap entry: {}", b))?;
|
||||
let node_id = ndis.node_id.key;
|
||||
bsmap
|
||||
|
@@ -5,9 +5,7 @@ use alloc::fmt;
|
||||
pub struct NodeRef {
|
||||
routing_table: RoutingTable,
|
||||
node_id: DHTKey,
|
||||
// Filters
|
||||
protocol_type: Option<ProtocolType>,
|
||||
address_type: Option<AddressType>,
|
||||
dial_info_filter: DialInfoFilter,
|
||||
}
|
||||
|
||||
impl NodeRef {
|
||||
@@ -16,23 +14,20 @@ impl NodeRef {
|
||||
Self {
|
||||
routing_table,
|
||||
node_id: key,
|
||||
protocol_type: None,
|
||||
address_type: None,
|
||||
dial_info_filter: DialInfoFilter::default(),
|
||||
}
|
||||
}
|
||||
pub fn new_filtered(
|
||||
routing_table: RoutingTable,
|
||||
key: DHTKey,
|
||||
entry: &mut BucketEntry,
|
||||
protocol_type: Option<ProtocolType>,
|
||||
address_type: Option<AddressType>,
|
||||
dial_info_filter: DialInfoFilter,
|
||||
) -> Self {
|
||||
entry.ref_count += 1;
|
||||
Self {
|
||||
routing_table,
|
||||
node_id: key,
|
||||
protocol_type,
|
||||
address_type,
|
||||
dial_info_filter,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,20 +35,8 @@ impl NodeRef {
|
||||
self.node_id
|
||||
}
|
||||
|
||||
pub fn protocol_type(&self) -> Option<ProtocolType> {
|
||||
self.protocol_type
|
||||
}
|
||||
|
||||
pub fn set_protocol_type(&mut self, protocol_type: Option<ProtocolType>) {
|
||||
self.protocol_type = protocol_type;
|
||||
}
|
||||
|
||||
pub fn address_type(&self) -> Option<AddressType> {
|
||||
self.address_type
|
||||
}
|
||||
|
||||
pub fn set_address_type(&mut self, address_type: Option<AddressType>) {
|
||||
self.address_type = address_type;
|
||||
pub fn dial_info_filter(&self) -> DialInfoFilter {
|
||||
self.dial_info_filter.clone()
|
||||
}
|
||||
|
||||
pub fn operate<T, F>(&self, f: F) -> T
|
||||
@@ -63,28 +46,39 @@ impl NodeRef {
|
||||
self.routing_table.operate_on_bucket_entry(self.node_id, f)
|
||||
}
|
||||
|
||||
xxx fix the notion of 'best dial info' to sort by capability and udp/tcp/ws/wss preference order
|
||||
pub fn dial_info(&self) -> Option<DialInfo> {
|
||||
if self.protocol_type || self. {
|
||||
None => self.operate(|e| e.best_dial_info()),
|
||||
Some(pat) => self.operate(|e| {
|
||||
e.filtered_dial_info(|die| die.dial_info().protocol_address_type() == pat)
|
||||
}),
|
||||
// Returns the best dial info to attempt a connection to this node
|
||||
pub fn best_dial_info(&self) -> Option<DialInfo> {
|
||||
let nm = self.routing_table.network_manager();
|
||||
let protocol_config = nm.get_protocol_config();
|
||||
if protocol_config.is_none() {
|
||||
return None;
|
||||
}
|
||||
let protocol_config = protocol_config.unwrap();
|
||||
|
||||
self.operate(|e| {
|
||||
e.first_filtered_dial_info(|di| {
|
||||
// Does it match the dial info filter
|
||||
if !di.matches_filter(&self.dial_info_filter) {
|
||||
return false;
|
||||
}
|
||||
// Filter out dial infos that don't match our protocol config
|
||||
// for outbound connections. This routine filters on 'connect' settings
|
||||
// to ensure we connect using only the protocols we have enabled.
|
||||
protocol_config.is_protocol_type_connect_enabled(di.protocol_type())
|
||||
})
|
||||
})
|
||||
}
|
||||
pub fn last_connection(&self) -> Option<ConnectionDescriptor> {
|
||||
match self.operate(|e| e.last_connection()) {
|
||||
None => None,
|
||||
Some(c) => {
|
||||
if let Some(protocol_address_type) = self.protocol_address_type {
|
||||
if c.remote.protocol_address_type() == protocol_address_type {
|
||||
Some(c)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
Some(c)
|
||||
if !c.matches_filter(&self.dial_info_filter) {
|
||||
return None;
|
||||
}
|
||||
// We don't filter this out by protocol config because if a connection
|
||||
// succeeded, it's allowed to persist and be used for communication
|
||||
// regardless of any other configuration
|
||||
Some(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,17 +92,18 @@ impl Clone for NodeRef {
|
||||
Self {
|
||||
routing_table: self.routing_table.clone(),
|
||||
node_id: self.node_id,
|
||||
protocol_address_type: self.protocol_address_type,
|
||||
dial_info_filter: self.dial_info_filter.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for NodeRef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.protocol_address_type {
|
||||
None => write!(f, "{}", self.node_id.encode()),
|
||||
Some(pat) => write!(f, "{}#{:?}", self.node_id.encode(), pat),
|
||||
let out = format!("{}", self.node_id.encode());
|
||||
if !self.dial_info_filter.is_empty() {
|
||||
out += &format!("{:?}", self.dial_info_filter);
|
||||
}
|
||||
write!(f, "{}", out)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user