checkpoint
This commit is contained in:
parent
e672ae0319
commit
592c83d83a
@ -1210,18 +1210,16 @@ impl NetworkManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Node A is our own node
|
// Node A is our own node
|
||||||
let node_a = routing_table.get_own_node_info(routing_domain);
|
let peer_a = routing_table.get_own_peer_info(routing_domain);
|
||||||
let node_a_id = routing_table.node_id();
|
|
||||||
|
|
||||||
// Node B is the target node
|
// Node B is the target node
|
||||||
let node_b = match target_node_ref.node_info(routing_domain) {
|
let peer_b = match target_node_ref.make_peer_info(routing_domain) {
|
||||||
Some(ni) => ni,
|
Some(ni) => ni,
|
||||||
None => {
|
None => {
|
||||||
log_net!("no node info for node {:?}", target_node_ref);
|
log_net!("no node info for node {:?}", target_node_ref);
|
||||||
return Ok(NodeContactMethod::Unreachable);
|
return Ok(NodeContactMethod::Unreachable);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let node_b_id = target_node_ref.node_id();
|
|
||||||
|
|
||||||
// Dial info filter comes from the target node ref
|
// Dial info filter comes from the target node ref
|
||||||
let dial_info_filter = target_node_ref.dial_info_filter();
|
let dial_info_filter = target_node_ref.dial_info_filter();
|
||||||
@ -1229,10 +1227,8 @@ impl NetworkManager {
|
|||||||
|
|
||||||
let cm = routing_table.get_contact_method(
|
let cm = routing_table.get_contact_method(
|
||||||
routing_domain,
|
routing_domain,
|
||||||
&node_a_id,
|
&peer_a,
|
||||||
&node_a,
|
&peer_b,
|
||||||
&node_b_id,
|
|
||||||
&node_b,
|
|
||||||
dial_info_filter,
|
dial_info_filter,
|
||||||
sequencing,
|
sequencing,
|
||||||
);
|
);
|
||||||
|
@ -348,24 +348,30 @@ impl RoutingTable {
|
|||||||
.node_info_is_valid_in_routing_domain(routing_domain, node_info)
|
.node_info_is_valid_in_routing_domain(routing_domain, node_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn signed_node_info_is_valid_in_routing_domain(
|
||||||
|
&self,
|
||||||
|
routing_domain: RoutingDomain,
|
||||||
|
signed_node_info: &SignedNodeInfo,
|
||||||
|
) -> bool {
|
||||||
|
self.inner
|
||||||
|
.read()
|
||||||
|
.signed_node_info_is_valid_in_routing_domain(routing_domain, signed_node_info)
|
||||||
|
}
|
||||||
|
|
||||||
/// Look up the best way for two nodes to reach each other over a specific routing domain
|
/// Look up the best way for two nodes to reach each other over a specific routing domain
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[instrument(level = "trace", skip(self), ret)]
|
||||||
pub fn get_contact_method(
|
pub fn get_contact_method(
|
||||||
&self,
|
&self,
|
||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
node_a_id: &DHTKey,
|
peer_a: &PeerInfo,
|
||||||
node_a: &NodeInfo,
|
peer_b: &PeerInfo,
|
||||||
node_b_id: &DHTKey,
|
|
||||||
node_b: &NodeInfo,
|
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
) -> ContactMethod {
|
) -> ContactMethod {
|
||||||
self.inner.read().get_contact_method(
|
self.inner.read().get_contact_method(
|
||||||
routing_domain,
|
routing_domain,
|
||||||
node_a_id,
|
peer_a,
|
||||||
node_a,
|
peer_b,
|
||||||
node_b_id,
|
|
||||||
node_b,
|
|
||||||
dial_info_filter,
|
dial_info_filter,
|
||||||
sequencing,
|
sequencing,
|
||||||
)
|
)
|
||||||
@ -381,16 +387,6 @@ impl RoutingTable {
|
|||||||
self.inner.read().get_own_peer_info(routing_domain)
|
self.inner.read().get_own_peer_info(routing_domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a copy of our node's signednodeinfo
|
|
||||||
pub fn get_own_signed_node_info(&self, routing_domain: RoutingDomain) -> SignedDirectNodeInfo {
|
|
||||||
self.inner.read().get_own_signed_node_info(routing_domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a copy of our node's nodeinfo
|
|
||||||
pub fn get_own_node_info(&self, routing_domain: RoutingDomain) -> NodeInfo {
|
|
||||||
self.inner.read().get_own_node_info(routing_domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If we have a valid network class in this routing domain, then our 'NodeInfo' is valid
|
/// If we have a valid network class in this routing domain, then our 'NodeInfo' is valid
|
||||||
pub fn has_valid_own_node_info(&self, routing_domain: RoutingDomain) -> bool {
|
pub fn has_valid_own_node_info(&self, routing_domain: RoutingDomain) -> bool {
|
||||||
self.inner.read().has_valid_own_node_info(routing_domain)
|
self.inner.read().has_valid_own_node_info(routing_domain)
|
||||||
@ -525,7 +521,7 @@ impl RoutingTable {
|
|||||||
&self,
|
&self,
|
||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
node_id: DHTKey,
|
node_id: DHTKey,
|
||||||
signed_node_info: SignedDirectNodeInfo,
|
signed_node_info: SignedNodeInfo,
|
||||||
allow_invalid: bool,
|
allow_invalid: bool,
|
||||||
) -> Option<NodeRef> {
|
) -> Option<NodeRef> {
|
||||||
self.inner.write().register_node_with_signed_node_info(
|
self.inner.write().register_node_with_signed_node_info(
|
||||||
|
@ -116,10 +116,10 @@ pub trait NodeRefBase: Sized {
|
|||||||
e.update_node_status(node_status);
|
e.update_node_status(node_status);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fn min_max_version(&self) -> Option<(u8, u8)> {
|
fn min_max_version(&self) -> Option<VersionRange> {
|
||||||
self.operate(|_rti, e| e.min_max_version())
|
self.operate(|_rti, e| e.min_max_version())
|
||||||
}
|
}
|
||||||
fn set_min_max_version(&self, min_max_version: (u8, u8)) {
|
fn set_min_max_version(&self, min_max_version: VersionRange) {
|
||||||
self.operate_mut(|_rti, e| e.set_min_max_version(min_max_version))
|
self.operate_mut(|_rti, e| e.set_min_max_version(min_max_version))
|
||||||
}
|
}
|
||||||
fn state(&self, cur_ts: u64) -> BucketEntryState {
|
fn state(&self, cur_ts: u64) -> BucketEntryState {
|
||||||
@ -170,11 +170,9 @@ pub trait NodeRefBase: Sized {
|
|||||||
}
|
}
|
||||||
fn relay(&self, routing_domain: RoutingDomain) -> Option<NodeRef> {
|
fn relay(&self, routing_domain: RoutingDomain) -> Option<NodeRef> {
|
||||||
self.operate_mut(|rti, e| {
|
self.operate_mut(|rti, e| {
|
||||||
let opt_target_rpi = e
|
e.signed_node_info(routing_domain)
|
||||||
.node_info(routing_domain)
|
.and_then(|n| n.relay_peer_info())
|
||||||
.map(|n| n.relay_peer_info.as_ref().map(|pi| pi.as_ref().clone()))
|
.and_then(|t| {
|
||||||
.flatten();
|
|
||||||
opt_target_rpi.and_then(|t| {
|
|
||||||
// If relay is ourselves, then return None, because we can't relay through ourselves
|
// If relay is ourselves, then return None, because we can't relay through ourselves
|
||||||
// and to contact this node we should have had an existing inbound connection
|
// and to contact this node we should have had an existing inbound connection
|
||||||
if t.node_id.key == rti.unlocked_inner.node_id {
|
if t.node_id.key == rti.unlocked_inner.node_id {
|
||||||
@ -301,8 +299,8 @@ pub trait NodeRefBase: Sized {
|
|||||||
fn has_any_dial_info(&self) -> bool {
|
fn has_any_dial_info(&self) -> bool {
|
||||||
self.operate(|_rti, e| {
|
self.operate(|_rti, e| {
|
||||||
for rtd in RoutingDomain::all() {
|
for rtd in RoutingDomain::all() {
|
||||||
if let Some(ni) = e.node_info(rtd) {
|
if let Some(sni) = e.signed_node_info(rtd) {
|
||||||
if ni.has_any_dial_info() {
|
if sni.has_any_dial_info() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,10 +114,10 @@ fn route_hops_to_hop_cache(hops: &[DHTKey]) -> Vec<u8> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// get the hop cache key for a particular route permutation
|
/// get the hop cache key for a particular route permutation
|
||||||
fn route_permutation_to_hop_cache(nodes: &[(DHTKey, NodeInfo)], perm: &[usize]) -> Vec<u8> {
|
fn route_permutation_to_hop_cache(nodes: &[PeerInfo], perm: &[usize]) -> Vec<u8> {
|
||||||
let mut cache: Vec<u8> = Vec::with_capacity(perm.len() * DHT_KEY_LENGTH);
|
let mut cache: Vec<u8> = Vec::with_capacity(perm.len() * DHT_KEY_LENGTH);
|
||||||
for n in perm {
|
for n in perm {
|
||||||
cache.extend_from_slice(&nodes[*n].0.bytes)
|
cache.extend_from_slice(&nodes[*n].node_id.key.bytes)
|
||||||
}
|
}
|
||||||
cache
|
cache
|
||||||
}
|
}
|
||||||
@ -422,9 +422,9 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Exclude nodes with no publicinternet nodeinfo, or incompatible nodeinfo or node status won't route
|
// Exclude nodes with no publicinternet nodeinfo, or incompatible nodeinfo or node status won't route
|
||||||
v.with(rti, move |_rti, e| {
|
v.with(rti, move |_rti, e| {
|
||||||
let node_info_ok = if let Some(ni) = e.node_info(RoutingDomain::PublicInternet)
|
let node_info_ok =
|
||||||
{
|
if let Some(sni) = e.signed_node_info(RoutingDomain::PublicInternet) {
|
||||||
ni.has_sequencing_matched_dial_info(sequencing)
|
sni.has_sequencing_matched_dial_info(sequencing)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
@ -495,19 +495,14 @@ impl RouteSpecStore {
|
|||||||
});
|
});
|
||||||
cmpout
|
cmpout
|
||||||
};
|
};
|
||||||
let transform = |rti: &RoutingTableInner,
|
let transform =
|
||||||
k: DHTKey,
|
|rti: &RoutingTableInner, k: DHTKey, v: Option<Arc<BucketEntry>>| -> PeerInfo {
|
||||||
v: Option<Arc<BucketEntry>>|
|
// Return the peerinfo for that key
|
||||||
-> (DHTKey, NodeInfo) {
|
|
||||||
// Return the key and the nodeinfo for that key
|
|
||||||
(
|
|
||||||
k,
|
|
||||||
v.unwrap().with(rti, |_rti, e| {
|
v.unwrap().with(rti, |_rti, e| {
|
||||||
e.node_info(RoutingDomain::PublicInternet.into())
|
e.make_peer_info(k, RoutingDomain::PublicInternet.into())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
}),
|
})
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pull the whole routing table in sorted order
|
// Pull the whole routing table in sorted order
|
||||||
@ -536,18 +531,15 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Ensure this route is viable by checking that each node can contact the next one
|
// Ensure this route is viable by checking that each node can contact the next one
|
||||||
if directions.contains(Direction::Outbound) {
|
if directions.contains(Direction::Outbound) {
|
||||||
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
|
let our_peer_info = rti.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
let our_node_id = rti.node_id();
|
let mut previous_node = &our_peer_info;
|
||||||
let mut previous_node = &(our_node_id, our_node_info);
|
|
||||||
let mut reachable = true;
|
let mut reachable = true;
|
||||||
for n in permutation {
|
for n in permutation {
|
||||||
let current_node = nodes.get(*n).unwrap();
|
let current_node = nodes.get(*n).unwrap();
|
||||||
let cm = rti.get_contact_method(
|
let cm = rti.get_contact_method(
|
||||||
RoutingDomain::PublicInternet,
|
RoutingDomain::PublicInternet,
|
||||||
&previous_node.0,
|
previous_node,
|
||||||
&previous_node.1,
|
current_node,
|
||||||
¤t_node.0,
|
|
||||||
¤t_node.1,
|
|
||||||
DialInfoFilter::all(),
|
DialInfoFilter::all(),
|
||||||
sequencing,
|
sequencing,
|
||||||
);
|
);
|
||||||
@ -562,18 +554,15 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if directions.contains(Direction::Inbound) {
|
if directions.contains(Direction::Inbound) {
|
||||||
let our_node_info = rti.get_own_node_info(RoutingDomain::PublicInternet);
|
let our_peer_info = rti.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
let our_node_id = rti.node_id();
|
let mut next_node = &our_peer_info;
|
||||||
let mut next_node = &(our_node_id, our_node_info);
|
|
||||||
let mut reachable = true;
|
let mut reachable = true;
|
||||||
for n in permutation.iter().rev() {
|
for n in permutation.iter().rev() {
|
||||||
let current_node = nodes.get(*n).unwrap();
|
let current_node = nodes.get(*n).unwrap();
|
||||||
let cm = rti.get_contact_method(
|
let cm = rti.get_contact_method(
|
||||||
RoutingDomain::PublicInternet,
|
RoutingDomain::PublicInternet,
|
||||||
&next_node.0,
|
next_node,
|
||||||
&next_node.1,
|
current_node,
|
||||||
¤t_node.0,
|
|
||||||
¤t_node.1,
|
|
||||||
DialInfoFilter::all(),
|
DialInfoFilter::all(),
|
||||||
sequencing,
|
sequencing,
|
||||||
);
|
);
|
||||||
@ -609,11 +598,11 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Got a unique route, lets build the detail, register it, and return it
|
// Got a unique route, lets build the detail, register it, and return it
|
||||||
let hops = route_nodes.iter().map(|v| nodes[*v].0).collect();
|
let hops: Vec<DHTKey> = route_nodes.iter().map(|v| nodes[*v].node_id.key).collect();
|
||||||
let hop_node_refs = route_nodes
|
let hop_node_refs = hops
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| {
|
.map(|k| {
|
||||||
rti.lookup_node_ref(self.unlocked_inner.routing_table.clone(), nodes[*v].0)
|
rti.lookup_node_ref(self.unlocked_inner.routing_table.clone(), *k)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -111,18 +111,31 @@ impl RoutingDomainDetailCommon {
|
|||||||
dial_info_detail_list: self.dial_info_details.clone(),
|
dial_info_detail_list: self.dial_info_details.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let relay_peer_info = self
|
let relay_info = self
|
||||||
.relay_node
|
.relay_node
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|rn| rn.locked(rti).make_peer_info(self.routing_domain));
|
.and_then(|rn| {
|
||||||
|
let opt_relay_pi = rn.locked(rti).make_peer_info(self.routing_domain);
|
||||||
|
if let Some(relay_pi) = opt_relay_pi {
|
||||||
|
match relay_pi.signed_node_info {
|
||||||
|
SignedNodeInfo::Direct(d) => Some((relay_pi.node_id, d)),
|
||||||
|
SignedNodeInfo::Relayed(_) => {
|
||||||
|
warn!("relay node should not have a relay itself! if this happens, a relay updated its signed node info and became a relay, which should cause the relay to be dropped");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let signed_node_info = match relay_peer_info {
|
let signed_node_info = match relay_info {
|
||||||
Some(relay_pi) => SignedNodeInfo::Relayed(
|
Some((relay_id, relay_sdni)) => SignedNodeInfo::Relayed(
|
||||||
SignedRelayedNodeInfo::with_secret(
|
SignedRelayedNodeInfo::with_secret(
|
||||||
NodeId::new(rti.unlocked_inner.node_id),
|
NodeId::new(rti.unlocked_inner.node_id),
|
||||||
node_info,
|
node_info,
|
||||||
relay_pi.node_id,
|
relay_id,
|
||||||
relay_pi.signed_node_info,
|
relay_sdni,
|
||||||
&rti.unlocked_inner.node_id_secret,
|
&rti.unlocked_inner.node_id_secret,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -133,7 +146,7 @@ impl RoutingDomainDetailCommon {
|
|||||||
node_info,
|
node_info,
|
||||||
&rti.unlocked_inner.node_id_secret,
|
&rti.unlocked_inner.node_id_secret,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,27 +160,8 @@ impl RoutingDomainDetailCommon {
|
|||||||
let mut cpi = self.cached_peer_info.lock();
|
let mut cpi = self.cached_peer_info.lock();
|
||||||
if cpi.is_none() {
|
if cpi.is_none() {
|
||||||
// Regenerate peer info
|
// Regenerate peer info
|
||||||
let pi = PeerInfo::new(
|
let pi = self.make_peer_info(rti);
|
||||||
NodeId::new(rti.unlocked_inner.node_id),
|
|
||||||
SignedDirectNodeInfo::with_secret(
|
|
||||||
NodeInfo {
|
|
||||||
network_class: self.network_class.unwrap_or(NetworkClass::Invalid),
|
|
||||||
outbound_protocols: self.outbound_protocols,
|
|
||||||
address_types: self.address_types,
|
|
||||||
min_version: MIN_CRYPTO_VERSION,
|
|
||||||
max_version: MAX_CRYPTO_VERSION,
|
|
||||||
dial_info_detail_list: self.dial_info_details.clone(),
|
|
||||||
relay_peer_info: self.relay_node.as_ref().and_then(|rn| {
|
|
||||||
rn.locked(rti)
|
|
||||||
.make_peer_info(self.routing_domain)
|
|
||||||
.map(Box::new)
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
NodeId::new(rti.unlocked_inner.node_id),
|
|
||||||
&rti.unlocked_inner.node_id_secret,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
// Cache the peer info
|
// Cache the peer info
|
||||||
*cpi = Some(pi);
|
*cpi = Some(pi);
|
||||||
}
|
}
|
||||||
@ -204,10 +198,8 @@ pub trait RoutingDomainDetail {
|
|||||||
fn get_contact_method(
|
fn get_contact_method(
|
||||||
&self,
|
&self,
|
||||||
rti: &RoutingTableInner,
|
rti: &RoutingTableInner,
|
||||||
node_a_id: &DHTKey,
|
peer_a: &PeerInfo,
|
||||||
node_a: &NodeInfo,
|
peer_b: &PeerInfo,
|
||||||
node_b_id: &DHTKey,
|
|
||||||
node_b: &NodeInfo,
|
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
) -> ContactMethod;
|
) -> ContactMethod;
|
||||||
@ -280,13 +272,15 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
|||||||
fn get_contact_method(
|
fn get_contact_method(
|
||||||
&self,
|
&self,
|
||||||
_rti: &RoutingTableInner,
|
_rti: &RoutingTableInner,
|
||||||
node_a_id: &DHTKey,
|
peer_a: &PeerInfo,
|
||||||
node_a: &NodeInfo,
|
peer_b: &PeerInfo,
|
||||||
node_b_id: &DHTKey,
|
|
||||||
node_b: &NodeInfo,
|
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
) -> ContactMethod {
|
) -> ContactMethod {
|
||||||
|
// Get the nodeinfos for convenience
|
||||||
|
let node_a = peer_a.signed_node_info.node_info();
|
||||||
|
let node_b = peer_b.signed_node_info.node_info();
|
||||||
|
|
||||||
// Get the best match dial info for node B if we have it
|
// Get the best match dial info for node B if we have it
|
||||||
if let Some(target_did) =
|
if let Some(target_did) =
|
||||||
first_filtered_dial_info_detail(node_a, node_b, &dial_info_filter, sequencing)
|
first_filtered_dial_info_detail(node_a, node_b, &dial_info_filter, sequencing)
|
||||||
@ -298,17 +292,18 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the target's inbound relay, it must have one or it is not reachable
|
// Get the target's inbound relay, it must have one or it is not reachable
|
||||||
if let Some(inbound_relay) = &node_b.relay_peer_info {
|
if let Some(node_b_relay) = peer_b.signed_node_info.relay_info() {
|
||||||
|
let node_b_relay_id = peer_b.signed_node_info.relay_id().unwrap();
|
||||||
// Note that relay_peer_info could be node_a, in which case a connection already exists
|
// Note that relay_peer_info could be node_a, in which case a connection already exists
|
||||||
// and we shouldn't have even gotten here
|
// and we shouldn't have even gotten here
|
||||||
if inbound_relay.node_id.key == *node_a_id {
|
if node_b_relay_id.key == peer_a.node_id.key {
|
||||||
return ContactMethod::Existing;
|
return ContactMethod::Existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can node A reach the inbound relay directly?
|
// Can node A reach the inbound relay directly?
|
||||||
if first_filtered_dial_info_detail(
|
if first_filtered_dial_info_detail(
|
||||||
node_a,
|
node_a,
|
||||||
&inbound_relay.signed_node_info.node_info,
|
node_b_relay,
|
||||||
&dial_info_filter,
|
&dial_info_filter,
|
||||||
sequencing,
|
sequencing,
|
||||||
)
|
)
|
||||||
@ -332,8 +327,8 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
|||||||
// Can we receive a direct reverse connection?
|
// Can we receive a direct reverse connection?
|
||||||
if !reverse_did.class.requires_signal() {
|
if !reverse_did.class.requires_signal() {
|
||||||
return ContactMethod::SignalReverse(
|
return ContactMethod::SignalReverse(
|
||||||
inbound_relay.node_id.key,
|
node_b_relay_id.key,
|
||||||
*node_b_id,
|
peer_b.node_id.key,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,8 +359,8 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
|||||||
{
|
{
|
||||||
// The target and ourselves have a udp dialinfo that they can reach
|
// The target and ourselves have a udp dialinfo that they can reach
|
||||||
return ContactMethod::SignalHolePunch(
|
return ContactMethod::SignalHolePunch(
|
||||||
inbound_relay.node_id.key,
|
node_b_relay_id.key,
|
||||||
*node_b_id,
|
peer_a.node_id.key,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -373,28 +368,30 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
|||||||
// Otherwise we have to inbound relay
|
// Otherwise we have to inbound relay
|
||||||
}
|
}
|
||||||
|
|
||||||
return ContactMethod::InboundRelay(inbound_relay.node_id.key);
|
return ContactMethod::InboundRelay(node_b_relay_id.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the node B has no direct dial info, it needs to have an inbound relay
|
// If the node B has no direct dial info, it needs to have an inbound relay
|
||||||
else if let Some(inbound_relay) = &node_b.relay_peer_info {
|
else if let Some(node_b_relay) = peer_b.signed_node_info.relay_info() {
|
||||||
|
let node_b_relay_id = peer_b.signed_node_info.relay_id().unwrap();
|
||||||
|
|
||||||
// Can we reach the full relay?
|
// Can we reach the full relay?
|
||||||
if first_filtered_dial_info_detail(
|
if first_filtered_dial_info_detail(
|
||||||
node_a,
|
node_a,
|
||||||
&inbound_relay.signed_node_info.node_info,
|
&node_b_relay,
|
||||||
&dial_info_filter,
|
&dial_info_filter,
|
||||||
sequencing,
|
sequencing,
|
||||||
)
|
)
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
return ContactMethod::InboundRelay(inbound_relay.node_id.key);
|
return ContactMethod::InboundRelay(node_b_relay_id.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If node A can't reach the node by other means, it may need to use its own relay
|
// If node A can't reach the node by other means, it may need to use its own relay
|
||||||
if let Some(outbound_relay) = &node_a.relay_peer_info {
|
if let Some(node_a_relay_id) = peer_a.signed_node_info.relay_id() {
|
||||||
return ContactMethod::OutboundRelay(outbound_relay.node_id.key);
|
return ContactMethod::OutboundRelay(node_a_relay_id.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactMethod::Unreachable
|
ContactMethod::Unreachable
|
||||||
@ -450,18 +447,16 @@ impl RoutingDomainDetail for LocalNetworkRoutingDomainDetail {
|
|||||||
fn get_contact_method(
|
fn get_contact_method(
|
||||||
&self,
|
&self,
|
||||||
_rti: &RoutingTableInner,
|
_rti: &RoutingTableInner,
|
||||||
_node_a_id: &DHTKey,
|
peer_a: &PeerInfo,
|
||||||
node_a: &NodeInfo,
|
peer_b: &PeerInfo,
|
||||||
_node_b_id: &DHTKey,
|
|
||||||
node_b: &NodeInfo,
|
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
) -> ContactMethod {
|
) -> ContactMethod {
|
||||||
// Scope the filter down to protocols node A can do outbound
|
// Scope the filter down to protocols node A can do outbound
|
||||||
let dial_info_filter = dial_info_filter.filtered(
|
let dial_info_filter = dial_info_filter.filtered(
|
||||||
&DialInfoFilter::all()
|
&DialInfoFilter::all()
|
||||||
.with_address_type_set(node_a.address_types)
|
.with_address_type_set(peer_a.signed_node_info.node_info().address_types)
|
||||||
.with_protocol_type_set(node_a.outbound_protocols),
|
.with_protocol_type_set(peer_a.signed_node_info.node_info().outbound_protocols),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get first filtered dialinfo
|
// Get first filtered dialinfo
|
||||||
@ -485,7 +480,7 @@ impl RoutingDomainDetail for LocalNetworkRoutingDomainDetail {
|
|||||||
|
|
||||||
let filter = |did: &DialInfoDetail| did.matches_filter(&dial_info_filter);
|
let filter = |did: &DialInfoDetail| did.matches_filter(&dial_info_filter);
|
||||||
|
|
||||||
let opt_target_did = node_b.first_filtered_dial_info_detail(sort, filter);
|
let opt_target_did = peer_b.signed_node_info.node_info().first_filtered_dial_info_detail(sort, filter);
|
||||||
if let Some(target_did) = opt_target_did {
|
if let Some(target_did) = opt_target_did {
|
||||||
return ContactMethod::Direct(target_did.dial_info);
|
return ContactMethod::Direct(target_did.dial_info);
|
||||||
}
|
}
|
||||||
|
@ -191,9 +191,20 @@ impl RoutingTableInner {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn signed_node_info_is_valid_in_routing_domain(
|
||||||
|
&self,
|
||||||
|
routing_domain: RoutingDomain,
|
||||||
|
signed_node_info: &SignedNodeInfo,
|
||||||
|
) -> bool {
|
||||||
|
if !self.node_info_is_valid_in_routing_domain(routing_domain, signed_node_info.node_info())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Ensure the relay is also valid in this routing domain if it is provided
|
// Ensure the relay is also valid in this routing domain if it is provided
|
||||||
if let Some(relay_peer_info) = node_info.relay_peer_info.as_ref() {
|
if let Some(relay_ni) = signed_node_info.relay_info() {
|
||||||
let relay_ni = &relay_peer_info.signed_node_info.node_info;
|
|
||||||
if !self.node_info_is_valid_in_routing_domain(routing_domain, relay_ni) {
|
if !self.node_info_is_valid_in_routing_domain(routing_domain, relay_ni) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -205,23 +216,13 @@ impl RoutingTableInner {
|
|||||||
pub fn get_contact_method(
|
pub fn get_contact_method(
|
||||||
&self,
|
&self,
|
||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
node_a_id: &DHTKey,
|
peer_a: &PeerInfo,
|
||||||
node_a: &NodeInfo,
|
peer_b: &PeerInfo,
|
||||||
node_b_id: &DHTKey,
|
|
||||||
node_b: &NodeInfo,
|
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
) -> ContactMethod {
|
) -> ContactMethod {
|
||||||
self.with_routing_domain(routing_domain, |rdd| {
|
self.with_routing_domain(routing_domain, |rdd| {
|
||||||
rdd.get_contact_method(
|
rdd.get_contact_method(self, peer_a, peer_b, dial_info_filter, sequencing)
|
||||||
self,
|
|
||||||
node_a_id,
|
|
||||||
node_a,
|
|
||||||
node_b_id,
|
|
||||||
node_b,
|
|
||||||
dial_info_filter,
|
|
||||||
sequencing,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,22 +253,6 @@ impl RoutingTableInner {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a copy of our node's signednodeinfo
|
|
||||||
pub fn get_own_signed_node_info(&self, routing_domain: RoutingDomain) -> SignedDirectNodeInfo {
|
|
||||||
self.with_routing_domain(routing_domain, |rdd| {
|
|
||||||
rdd.common()
|
|
||||||
.with_peer_info(self, |pi| pi.signed_node_info.clone())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a copy of our node's nodeinfo
|
|
||||||
pub fn get_own_node_info(&self, routing_domain: RoutingDomain) -> NodeInfo {
|
|
||||||
self.with_routing_domain(routing_domain, |rdd| {
|
|
||||||
rdd.common()
|
|
||||||
.with_peer_info(self, |pi| pi.signed_node_info.node_info.clone())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return our currently registered network class
|
/// Return our currently registered network class
|
||||||
pub fn has_valid_own_node_info(&self, routing_domain: RoutingDomain) -> bool {
|
pub fn has_valid_own_node_info(&self, routing_domain: RoutingDomain) -> bool {
|
||||||
self.with_routing_domain(routing_domain, |rdd| rdd.common().has_valid_own_node_info())
|
self.with_routing_domain(routing_domain, |rdd| rdd.common().has_valid_own_node_info())
|
||||||
@ -662,7 +647,7 @@ impl RoutingTableInner {
|
|||||||
outer_self: RoutingTable,
|
outer_self: RoutingTable,
|
||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
node_id: DHTKey,
|
node_id: DHTKey,
|
||||||
signed_node_info: SignedDirectNodeInfo,
|
signed_node_info: SignedNodeInfo,
|
||||||
allow_invalid: bool,
|
allow_invalid: bool,
|
||||||
) -> Option<NodeRef> {
|
) -> Option<NodeRef> {
|
||||||
// validate signed node info is not something malicious
|
// validate signed node info is not something malicious
|
||||||
@ -670,8 +655,8 @@ impl RoutingTableInner {
|
|||||||
log_rtab!(debug "can't register own node id in routing table");
|
log_rtab!(debug "can't register own node id in routing table");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if let Some(rpi) = &signed_node_info.node_info.relay_peer_info {
|
if let Some(relay_id) = signed_node_info.relay_id() {
|
||||||
if rpi.node_id.key == node_id {
|
if relay_id.key == node_id {
|
||||||
log_rtab!(debug "node can not be its own relay");
|
log_rtab!(debug "node can not be its own relay");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -683,8 +668,7 @@ impl RoutingTableInner {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// verify signed node info is valid in this routing domain
|
// verify signed node info is valid in this routing domain
|
||||||
if !self
|
if !self.signed_node_info_is_valid_in_routing_domain(routing_domain, &signed_node_info)
|
||||||
.node_info_is_valid_in_routing_domain(routing_domain, &signed_node_info.node_info)
|
|
||||||
{
|
{
|
||||||
log_rtab!(debug "signed node info for {} not valid in the {:?} routing domain", node_id, routing_domain);
|
log_rtab!(debug "signed node info for {} not valid in the {:?} routing domain", node_id, routing_domain);
|
||||||
return None;
|
return None;
|
||||||
|
@ -336,10 +336,14 @@ impl RPCProcessor {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// Determine if a NodeInfo can be placed into the specified routing domain
|
/// Determine if a SignedNodeInfo can be placed into the specified routing domain
|
||||||
fn filter_node_info(&self, routing_domain: RoutingDomain, node_info: &NodeInfo) -> bool {
|
fn filter_node_info(
|
||||||
|
&self,
|
||||||
|
routing_domain: RoutingDomain,
|
||||||
|
signed_node_info: &SignedNodeInfo,
|
||||||
|
) -> bool {
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
routing_table.node_info_is_valid_in_routing_domain(routing_domain, &node_info)
|
routing_table.signed_node_info_is_valid_in_routing_domain(routing_domain, &signed_node_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -619,7 +623,7 @@ impl RPCProcessor {
|
|||||||
// routing table caching when it is okay to do so
|
// routing table caching when it is okay to do so
|
||||||
// This is only done in the PublicInternet routing domain because
|
// This is only done in the PublicInternet routing domain because
|
||||||
// as far as we can tell this is the only domain that will really benefit
|
// as far as we can tell this is the only domain that will really benefit
|
||||||
fn get_sender_signed_node_info(&self, dest: &Destination) -> Option<SignedDirectNodeInfo> {
|
fn get_sender_signed_node_info(&self, dest: &Destination) -> Option<SignedNodeInfo> {
|
||||||
// Don't do this if the sender is to remain private
|
// Don't do this if the sender is to remain private
|
||||||
// Otherwise we would be attaching the original sender's identity to the final destination,
|
// Otherwise we would be attaching the original sender's identity to the final destination,
|
||||||
// thus defeating the purpose of the safety route entirely :P
|
// thus defeating the purpose of the safety route entirely :P
|
||||||
|
@ -50,10 +50,7 @@ impl RPCProcessor {
|
|||||||
|
|
||||||
// Verify peers are in the correct peer scope
|
// Verify peers are in the correct peer scope
|
||||||
for peer_info in &find_node_a.peers {
|
for peer_info in &find_node_a.peers {
|
||||||
if !self.filter_node_info(
|
if !self.filter_node_info(RoutingDomain::PublicInternet, &peer_info.signed_node_info) {
|
||||||
RoutingDomain::PublicInternet,
|
|
||||||
&peer_info.signed_node_info.node_info,
|
|
||||||
) {
|
|
||||||
return Err(RPCError::invalid_format(
|
return Err(RPCError::invalid_format(
|
||||||
"find_node response has invalid peer scope",
|
"find_node response has invalid peer scope",
|
||||||
));
|
));
|
||||||
|
@ -11,7 +11,8 @@ impl RPCProcessor {
|
|||||||
// Get the signed node info for the desired routing domain to send update with
|
// Get the signed node info for the desired routing domain to send update with
|
||||||
let signed_node_info = self
|
let signed_node_info = self
|
||||||
.routing_table()
|
.routing_table()
|
||||||
.get_own_signed_node_info(routing_domain);
|
.get_own_peer_info(routing_domain)
|
||||||
|
.signed_node_info;
|
||||||
let node_info_update = RPCOperationNodeInfoUpdate { signed_node_info };
|
let node_info_update = RPCOperationNodeInfoUpdate { signed_node_info };
|
||||||
let statement = RPCStatement::new(RPCStatementDetail::NodeInfoUpdate(node_info_update));
|
let statement = RPCStatement::new(RPCStatementDetail::NodeInfoUpdate(node_info_update));
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ impl RPCProcessor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Update our routing table with signed node info
|
// Update our routing table with signed node info
|
||||||
if !self.filter_node_info(routing_domain, &node_info_update.signed_node_info.node_info) {
|
if !self.filter_node_info(routing_domain, &node_info_update.signed_node_info) {
|
||||||
log_rpc!(debug "node info doesn't belong in {:?} routing domain: {}", routing_domain, sender_node_id);
|
log_rpc!(debug "node info doesn't belong in {:?} routing domain: {}", routing_domain, sender_node_id);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -775,6 +775,68 @@ pub struct NodeInfo {
|
|||||||
pub dial_info_detail_list: Vec<DialInfoDetail>,
|
pub dial_info_detail_list: Vec<DialInfoDetail>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NodeInfo {
|
||||||
|
pub fn first_filtered_dial_info_detail<S, F>(
|
||||||
|
&self,
|
||||||
|
sort: Option<S>,
|
||||||
|
filter: F,
|
||||||
|
) -> Option<DialInfoDetail>
|
||||||
|
where
|
||||||
|
S: Fn(&DialInfoDetail, &DialInfoDetail) -> std::cmp::Ordering,
|
||||||
|
F: Fn(&DialInfoDetail) -> bool,
|
||||||
|
{
|
||||||
|
if let Some(sort) = sort {
|
||||||
|
let mut dids = self.dial_info_detail_list.clone();
|
||||||
|
dids.sort_by(sort);
|
||||||
|
for did in dids {
|
||||||
|
if filter(&did) {
|
||||||
|
return Some(did);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for did in &self.dial_info_detail_list {
|
||||||
|
if filter(did) {
|
||||||
|
return Some(did.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_filtered_dial_info_details<S, F>(
|
||||||
|
&self,
|
||||||
|
sort: Option<S>,
|
||||||
|
filter: F,
|
||||||
|
) -> Vec<DialInfoDetail>
|
||||||
|
where
|
||||||
|
S: Fn(&DialInfoDetail, &DialInfoDetail) -> std::cmp::Ordering,
|
||||||
|
F: Fn(&DialInfoDetail) -> bool,
|
||||||
|
{
|
||||||
|
let mut dial_info_detail_list = Vec::new();
|
||||||
|
|
||||||
|
if let Some(sort) = sort {
|
||||||
|
let mut dids = self.dial_info_detail_list.clone();
|
||||||
|
dids.sort_by(sort);
|
||||||
|
for did in dids {
|
||||||
|
if filter(&did) {
|
||||||
|
dial_info_detail_list.push(did);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for did in &self.dial_info_detail_list {
|
||||||
|
if filter(did) {
|
||||||
|
dial_info_detail_list.push(did.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dial_info_detail_list
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_direct_dial_info(&self) -> bool {
|
||||||
|
!self.dial_info_detail_list.is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::derive_hash_xor_eq)]
|
#[allow(clippy::derive_hash_xor_eq)]
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
@ -2046,6 +2108,53 @@ impl SignedNodeInfo {
|
|||||||
SignedNodeInfo::Relayed(r) => Some(&r.relay_info.node_info),
|
SignedNodeInfo::Relayed(r) => Some(&r.relay_info.node_info),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn relay_peer_info(&self) -> Option<PeerInfo> {
|
||||||
|
match self {
|
||||||
|
SignedNodeInfo::Direct(d) => None,
|
||||||
|
SignedNodeInfo::Relayed(r) => Some(PeerInfo::new(
|
||||||
|
r.relay_id.clone(),
|
||||||
|
SignedNodeInfo::Direct(r.relay_info.clone()),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn has_any_dial_info(&self) -> bool {
|
||||||
|
self.node_info().has_direct_dial_info()
|
||||||
|
|| self
|
||||||
|
.relay_info()
|
||||||
|
.map(|relay_ni| relay_ni.has_direct_dial_info())
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_sequencing_matched_dial_info(&self, sequencing: Sequencing) -> bool {
|
||||||
|
// Check our dial info
|
||||||
|
for did in &self.node_info().dial_info_detail_list {
|
||||||
|
match sequencing {
|
||||||
|
Sequencing::NoPreference | Sequencing::PreferOrdered => return true,
|
||||||
|
Sequencing::EnsureOrdered => {
|
||||||
|
if did.dial_info.protocol_type().is_connection_oriented() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check our relay if we have one
|
||||||
|
return self
|
||||||
|
.relay_info()
|
||||||
|
.map(|relay_ni| {
|
||||||
|
for did in &relay_ni.dial_info_detail_list {
|
||||||
|
match sequencing {
|
||||||
|
Sequencing::NoPreference | Sequencing::PreferOrdered => return true,
|
||||||
|
Sequencing::EnsureOrdered => {
|
||||||
|
if did.dial_info.protocol_type().is_connection_oriented() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
@ -2066,103 +2175,8 @@ impl PeerInfo {
|
|||||||
|
|
||||||
impl PeerInfo {
|
impl PeerInfo {
|
||||||
/*
|
/*
|
||||||
pub fn first_filtered_dial_info_detail<S, F>(
|
|
||||||
&self,
|
|
||||||
sort: Option<S>,
|
|
||||||
filter: F,
|
|
||||||
) -> Option<DialInfoDetail>
|
|
||||||
where
|
|
||||||
S: Fn(&DialInfoDetail, &DialInfoDetail) -> std::cmp::Ordering,
|
|
||||||
F: Fn(&DialInfoDetail) -> bool,
|
|
||||||
{
|
|
||||||
if let Some(sort) = sort {
|
|
||||||
let mut dids = self.dial_info_detail_list.clone();
|
|
||||||
dids.sort_by(sort);
|
|
||||||
for did in dids {
|
|
||||||
if filter(&did) {
|
|
||||||
return Some(did);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for did in &self.dial_info_detail_list {
|
|
||||||
if filter(did) {
|
|
||||||
return Some(did.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn all_filtered_dial_info_details<S, F>(
|
xxx move these back to NodeInfo
|
||||||
&self,
|
|
||||||
sort: Option<S>,
|
|
||||||
filter: F,
|
|
||||||
) -> Vec<DialInfoDetail>
|
|
||||||
where
|
|
||||||
S: Fn(&DialInfoDetail, &DialInfoDetail) -> std::cmp::Ordering,
|
|
||||||
F: Fn(&DialInfoDetail) -> bool,
|
|
||||||
{
|
|
||||||
let mut dial_info_detail_list = Vec::new();
|
|
||||||
|
|
||||||
if let Some(sort) = sort {
|
|
||||||
let mut dids = self.dial_info_detail_list.clone();
|
|
||||||
dids.sort_by(sort);
|
|
||||||
for did in dids {
|
|
||||||
if filter(&did) {
|
|
||||||
dial_info_detail_list.push(did);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for did in &self.dial_info_detail_list {
|
|
||||||
if filter(did) {
|
|
||||||
dial_info_detail_list.push(did.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
dial_info_detail_list
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_any_dial_info(&self) -> bool {
|
|
||||||
!self.dial_info_detail_list.is_empty()
|
|
||||||
|| !self
|
|
||||||
.relay_peer_info
|
|
||||||
.as_ref()
|
|
||||||
.map(|rpi| rpi.signed_node_info.node_info.has_direct_dial_info())
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_sequencing_matched_dial_info(&self, sequencing: Sequencing) -> bool {
|
|
||||||
// Check our dial info
|
|
||||||
for did in &self.dial_info_detail_list {
|
|
||||||
match sequencing {
|
|
||||||
Sequencing::NoPreference | Sequencing::PreferOrdered => return true,
|
|
||||||
Sequencing::EnsureOrdered => {
|
|
||||||
if did.dial_info.protocol_type().is_connection_oriented() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check our relay if we have one
|
|
||||||
return self
|
|
||||||
.relay_peer_info
|
|
||||||
.as_ref()
|
|
||||||
.map(|rpi| {
|
|
||||||
let relay_ni = &rpi.signed_node_info.node_info;
|
|
||||||
for did in &relay_ni.dial_info_detail_list {
|
|
||||||
match sequencing {
|
|
||||||
Sequencing::NoPreference | Sequencing::PreferOrdered => return true,
|
|
||||||
Sequencing::EnsureOrdered => {
|
|
||||||
if did.dial_info.protocol_type().is_connection_oriented() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_direct_dial_info(&self) -> bool {
|
pub fn has_direct_dial_info(&self) -> bool {
|
||||||
!self.dial_info_detail_list.is_empty()
|
!self.dial_info_detail_list.is_empty()
|
||||||
|
Loading…
Reference in New Issue
Block a user