aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/topology
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-03 01:54:10 +0100
committertv <tv@krebsco.de>2026-11-03 01:54:10 +0100
commit5c96698de2c1d239985f3c0672b41f29a95ca13c (patch)
tree14989564181022dca9cb484544e4c9b5420d2dd0 /src/swarm/topology
parentc12ce1a67e387474d17419bb252211bf04b2e443 (diff)
swarm: links by whom we reach
Diffstat (limited to 'src/swarm/topology')
-rw-r--r--src/swarm/topology/mod.rs26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/swarm/topology/mod.rs b/src/swarm/topology/mod.rs
index e3479e3..992c448 100644
--- a/src/swarm/topology/mod.rs
+++ b/src/swarm/topology/mod.rs
@@ -142,6 +142,19 @@ pub(crate) fn intended_graph(state: &AppState) -> Option<BTreeMap<String, BTreeS
Some(graph)
}
+/// Whether we reach `peer` ourselves, as choosing neighbours judges it: on one of our
+/// transports, and not unanswered (three HELLOs, or dormant: `PeerState::is_unreachable`).
+/// One we have no word of yet counts as reached until it fails to answer.
+pub(crate) async fn reaches(state: &AppState, peer: &str) -> bool {
+ if !state.transport.can_reach(peer) {
+ return false;
+ }
+ match state.get_peer_state(peer).await {
+ Some(peer_state) => !peer_state.lock().await.is_unreachable(),
+ None => true,
+ }
+}
+
/// The transports `member` is on, by the member list (the schemes of its addresses);
/// ours as we are on them. None known: empty.
pub(crate) fn transports_of(state: &AppState, member: &str) -> BTreeSet<String> {
@@ -251,18 +264,15 @@ pub(crate) async fn refresh(state: &AppState) -> Option<NeighbourChange> {
if member == state.local_id() {
continue;
}
- if !state.transport.can_reach(member) {
+ if !reaches(state, member).await {
unreachable.insert(member.clone());
continue;
}
- let (gone, heard) = match state.get_peer_state(member).await {
- Some(peer_state) => {
- let peer_state = peer_state.lock().await;
- (peer_state.is_unreachable(), peer_state.last_seen.is_some())
- }
- None => (false, false),
+ let heard = match state.get_peer_state(member).await {
+ Some(peer_state) => peer_state.lock().await.last_seen.is_some(),
+ None => false,
};
- if gone || (!heard && !alive.contains(member)) {
+ if !heard && !alive.contains(member) {
unreachable.insert(member.clone());
}
}