Skip to content

Commit d90351f

Browse files
committed
More comments on the design of AttemptToEvictConnection.
Some developers clearly don't get this and have been posting "improvements" that create clear vulnerabilities. It should have been better explained in the code, since the design is somewhat subtle and getting it right is important.
1 parent 20f9ecd commit d90351f

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

src/net.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,14 @@ class CompareNetGroupKeyed
877877
}
878878
};
879879

880+
/** Try to find a connection to evict when the node is full.
881+
* Extreme care must be taken to avoid opening the node to attacker
882+
* triggered network partitioning.
883+
* The strategy used here is to protect a small number of peers
884+
* for each of several distinct characteristics which are difficult
885+
* to forge. In order to partition a node the attacker must be
886+
* simultaneously better at all of them than honest peers.
887+
*/
880888
static bool AttemptToEvictConnection(bool fPreferNewConnection) {
881889
std::vector<CNodeRef> vEvictionCandidates;
882890
{
@@ -905,15 +913,15 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
905913

906914
if (vEvictionCandidates.empty()) return false;
907915

908-
// Protect the 8 nodes with the best ping times.
916+
// Protect the 8 nodes with the lowest minimum ping time.
909917
// An attacker cannot manipulate this metric without physically moving nodes closer to the target.
910918
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
911919
vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
912920

913921
if (vEvictionCandidates.empty()) return false;
914922

915923
// Protect the half of the remaining nodes which have been connected the longest.
916-
// This replicates the existing implicit behavior.
924+
// This replicates the non-eviction implicit behavior, and precludes attacks that start later.
917925
std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
918926
vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
919927

@@ -941,6 +949,7 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
941949
vEvictionCandidates = mapAddrCounts[naMostConnections];
942950

943951
// Do not disconnect peers if there is only one unprotected connection from their network group.
952+
// This step excessively favors netgroup diversity, and should be removed once more protective criteria are established.
944953
if (vEvictionCandidates.size() <= 1)
945954
// unless we prefer the new connection (for whitelisted peers)
946955
if (!fPreferNewConnection)

0 commit comments

Comments
 (0)