2021-11-22 16:28:30 +00:00
|
|
|
use super::*;
|
|
|
|
use crate::dht::*;
|
|
|
|
use alloc::fmt;
|
|
|
|
|
|
|
|
pub struct NodeRef {
|
|
|
|
routing_table: RoutingTable,
|
|
|
|
node_id: DHTKey,
|
2021-12-24 01:34:52 +00:00
|
|
|
dial_info_filter: DialInfoFilter,
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl NodeRef {
|
|
|
|
pub fn new(routing_table: RoutingTable, key: DHTKey, entry: &mut BucketEntry) -> Self {
|
|
|
|
entry.ref_count += 1;
|
|
|
|
Self {
|
2021-11-26 15:39:43 +00:00
|
|
|
routing_table,
|
2021-11-22 16:28:30 +00:00
|
|
|
node_id: key,
|
2021-12-24 01:34:52 +00:00
|
|
|
dial_info_filter: DialInfoFilter::default(),
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn new_filtered(
|
|
|
|
routing_table: RoutingTable,
|
|
|
|
key: DHTKey,
|
|
|
|
entry: &mut BucketEntry,
|
2021-12-24 01:34:52 +00:00
|
|
|
dial_info_filter: DialInfoFilter,
|
2021-11-22 16:28:30 +00:00
|
|
|
) -> Self {
|
|
|
|
entry.ref_count += 1;
|
|
|
|
Self {
|
2021-11-26 15:39:43 +00:00
|
|
|
routing_table,
|
2021-11-22 16:28:30 +00:00
|
|
|
node_id: key,
|
2021-12-24 01:34:52 +00:00
|
|
|
dial_info_filter,
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn node_id(&self) -> DHTKey {
|
|
|
|
self.node_id
|
|
|
|
}
|
|
|
|
|
2022-03-25 02:07:55 +00:00
|
|
|
pub fn dial_info_filter(&self) -> &DialInfoFilter {
|
|
|
|
&self.dial_info_filter
|
|
|
|
}
|
2021-11-22 16:28:30 +00:00
|
|
|
|
|
|
|
pub fn operate<T, F>(&self, f: F) -> T
|
|
|
|
where
|
|
|
|
F: FnOnce(&mut BucketEntry) -> T,
|
|
|
|
{
|
|
|
|
self.routing_table.operate_on_bucket_entry(self.node_id, f)
|
|
|
|
}
|
|
|
|
|
2022-03-25 02:07:55 +00:00
|
|
|
// Returns if this node has seen and acknowledged our node's dial info yet
|
|
|
|
pub fn has_seen_our_dial_info(&self) -> bool {
|
|
|
|
self.operate(|e| e.has_seen_our_dial_info())
|
|
|
|
}
|
|
|
|
pub fn set_seen_our_dial_info(&self) {
|
|
|
|
self.operate(|e| e.set_seen_our_dial_info(true));
|
|
|
|
}
|
|
|
|
|
2021-12-24 01:34:52 +00:00
|
|
|
// 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();
|
2021-12-24 23:02:53 +00:00
|
|
|
let protocol_config = nm.get_protocol_config()?;
|
2021-12-24 01:34:52 +00:00
|
|
|
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())
|
|
|
|
})
|
|
|
|
})
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
pub fn last_connection(&self) -> Option<ConnectionDescriptor> {
|
|
|
|
match self.operate(|e| e.last_connection()) {
|
|
|
|
None => None,
|
|
|
|
Some(c) => {
|
2021-12-24 01:34:52 +00:00
|
|
|
if !c.matches_filter(&self.dial_info_filter) {
|
|
|
|
return None;
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
2021-12-24 01:34:52 +00:00
|
|
|
// 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)
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for NodeRef {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
self.operate(move |e| {
|
|
|
|
e.ref_count += 1;
|
|
|
|
});
|
|
|
|
Self {
|
|
|
|
routing_table: self.routing_table.clone(),
|
2021-11-26 15:39:43 +00:00
|
|
|
node_id: self.node_id,
|
2021-12-24 01:34:52 +00:00
|
|
|
dial_info_filter: self.dial_info_filter.clone(),
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for NodeRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2021-12-24 23:02:53 +00:00
|
|
|
let mut out = self.node_id.encode();
|
2021-12-24 01:34:52 +00:00
|
|
|
if !self.dial_info_filter.is_empty() {
|
|
|
|
out += &format!("{:?}", self.dial_info_filter);
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
2021-12-24 01:34:52 +00:00
|
|
|
write!(f, "{}", out)
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for NodeRef {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
self.routing_table.drop_node_ref(self.node_id);
|
|
|
|
}
|
|
|
|
}
|