veilid/veilid-core/src/routing_table/node_ref.rs

115 lines
3.3 KiB
Rust
Raw Normal View History

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
}
2021-12-24 01:34:52 +00:00
pub fn dial_info_filter(&self) -> DialInfoFilter {
self.dial_info_filter.clone()
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)
}
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();
let protocol_config = nm.get_protocol_config();
if protocol_config.is_none() {
return None;
2021-11-22 16:28:30 +00:00
}
2021-12-24 01:34:52 +00:00
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())
})
})
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 01:34:52 +00:00
let out = format!("{}", self.node_id.encode());
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);
}
}