diff --git a/src/net.cpp b/src/net.cpp index 7f4e571c8d..91a1b05b81 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -948,6 +948,15 @@ static void EraseLastKElements( elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end()); } +void ProtectNoBanConnections(std::vector& eviction_candidates) +{ + eviction_candidates.erase(std::remove_if(eviction_candidates.begin(), eviction_candidates.end(), + [](NodeEvictionCandidate const& n) { + return n.m_noban; + }), + eviction_candidates.end()); +} + void ProtectEvictionCandidatesByRatio(std::vector& eviction_candidates) { // Protect the half of the remaining nodes which have been connected the longest. @@ -1025,6 +1034,8 @@ void ProtectEvictionCandidatesByRatio(std::vector& evicti { // Protect connections with certain characteristics + ProtectNoBanConnections(vEvictionCandidates); + // Deterministically select 4 peers to protect by netgroup. // An attacker cannot predict which netgroups will be protected EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4); @@ -1096,8 +1107,6 @@ bool CConnman::AttemptToEvictConnection() LOCK(m_nodes_mutex); for (const CNode* node : m_nodes) { - if (node->HasPermission(NetPermissionFlags::NoBan)) - continue; if (!node->IsInboundConn()) continue; if (node->fDisconnect) @@ -1115,6 +1124,7 @@ bool CConnman::AttemptToEvictConnection() Desig(prefer_evict) node->m_prefer_evict, Desig(m_is_local) node->addr.IsLocal(), Desig(m_network) node->ConnectedThroughNetwork(), + Desig(m_noban) node->HasPermission(NetPermissionFlags::NoBan), }; vEvictionCandidates.push_back(candidate); } diff --git a/src/net.h b/src/net.h index bf169649c0..e46933d972 100644 --- a/src/net.h +++ b/src/net.h @@ -1261,6 +1261,7 @@ struct NodeEvictionCandidate bool prefer_evict; bool m_is_local; Network m_network; + bool m_noban; }; /** diff --git a/src/test/fuzz/node_eviction.cpp b/src/test/fuzz/node_eviction.cpp index 6a363f00f7..d7721f1bf6 100644 --- a/src/test/fuzz/node_eviction.cpp +++ b/src/test/fuzz/node_eviction.cpp @@ -32,6 +32,7 @@ FUZZ_TARGET(node_eviction) /*prefer_evict=*/fuzzed_data_provider.ConsumeBool(), /*m_is_local=*/fuzzed_data_provider.ConsumeBool(), /*m_network=*/fuzzed_data_provider.PickValueInArray(ALL_NETWORKS), + /*m_noban=*/fuzzed_data_provider.ConsumeBool(), }); } // Make a copy since eviction_candidates may be in some valid but otherwise diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp index 62b770753a..26b3acc677 100644 --- a/src/test/util/net.cpp +++ b/src/test/util/net.cpp @@ -58,6 +58,7 @@ std::vector GetRandomNodeEvictionCandidates(int n_candida /*prefer_evict=*/random_context.randbool(), /*m_is_local=*/random_context.randbool(), /*m_network=*/ALL_NETWORKS[random_context.randrange(ALL_NETWORKS.size())], + /*m_noban=*/false, }); } return candidates;