aboutsummaryrefslogtreecommitdiff
path: root/src/net.h
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2021-03-30 15:52:09 +0200
committerWladimir J. van der Laan <laanwj@protonmail.com>2021-03-30 16:20:47 +0200
commitdede9eb9247363aacc3816c7352494a3609fa28b (patch)
treee10098c1697337d9e3fce8738be691c4ce2689da /src/net.h
parent1999baac30a1fc8328f3f175ad2a762c5114666d (diff)
parent0cca08a8ee33b4e05ff586ae4fd914f5ea860cea (diff)
downloadbitcoin-dede9eb9247363aacc3816c7352494a3609fa28b.tar.xz
Merge #20197: p2p: protect onions in AttemptToEvictConnection(), add eviction protection test coverage
0cca08a8ee33b4e05ff586ae4fd914f5ea860cea Add unit test coverage for our onion peer eviction protection (Jon Atack) caa21f586f951d626a67f391050c3644f1057f57 Protect onion+localhost peers in ProtectEvictionCandidatesByRatio() (Jon Atack) 8f1a53eb027727a4c0eaac6d82f0a8279549f638 Use EraseLastKElements() throughout SelectNodeToEvict() (Jon Atack) 8b1e156143740a5548dc7b601d40fb141e6aae1c Add m_inbound_onion to AttemptToEvictConnection() (Jon Atack) 72e30e8e03f880eba4bd1c3fc18b5558d8cef680 Add unit tests for ProtectEvictionCandidatesByRatio() (Jon Atack) ca63b53ecdf377ce777fd959d400748912266748 Use std::unordered_set instead of std::vector in IsEvicted() (Jon Atack) 41f84d5eccd4c2620bf6fee616f2f8f717dbd6f6 Move peer eviction tests to a separate test file (Jon Atack) f126cbd6de6e1a8fee0e900ecfbc14a88e362541 Extract ProtectEvictionCandidatesByRatio from SelectNodeToEvict (Jon Atack) Pull request description: Now that #19991 and #20210 have been merged, we can determine inbound onion peers using `CNode::m_inbound_onion` and add it to the localhost peers protection in `AttemptToEvictConnection`, which was added in #19670 to address issue #19500. Update 28 February 2021: I've updated this to follow gmaxwell's suggestion in https://github.com/bitcoin/bitcoin/pull/20197#issuecomment-713865992. This branch now protects up to 1/4 onion peers (connected via our tor control service), if any, sorted by longest uptime. If any (or all) onion slots remain after that operation, they are then allocated to protect localhost peers, or a minimum of 2 localhost peers in the case that no onion slots remain and 2 or more onion peers were protected, sorted as before by longest uptime. This patch also adds test coverage for the longest uptime, localhost, and onion peer eviction protection logic to build on the welcome initial unit testing of #20477. Suggest reviewing the commits that move code with `colorMoved = dimmed-zebra` and `colorMovedWs = allow-indentation-change`. Closes #11537. ACKs for top commit: laanwj: Code review ACK 0cca08a8ee33b4e05ff586ae4fd914f5ea860cea vasild: ACK 0cca08a8ee33b4e05ff586ae4fd914f5ea860cea Tree-SHA512: 2f5a63f942acaae7882920fc61f0185dcd51da85e5b736df9d1fc72343726dd17da740e02f30fa5dc5eb3b2d8345707aed96031bec143d48a2497a610aa19abd
Diffstat (limited to 'src/net.h')
-rw-r--r--src/net.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/net.h b/src/net.h
index 176fb3c74d..add48b11a4 100644
--- a/src/net.h
+++ b/src/net.h
@@ -425,6 +425,7 @@ public:
std::atomic<int64_t> nLastSend{0};
std::atomic<int64_t> nLastRecv{0};
+ //! Unix epoch time at peer connection, in seconds.
const int64_t nTimeConnected;
std::atomic<int64_t> nTimeOffset{0};
// Address of this peer
@@ -1278,8 +1279,39 @@ struct NodeEvictionCandidate
uint64_t nKeyedNetGroup;
bool prefer_evict;
bool m_is_local;
+ bool m_is_onion;
};
+/**
+ * Select an inbound peer to evict after filtering out (protecting) peers having
+ * distinct, difficult-to-forge characteristics. The protection logic picks out
+ * fixed numbers of desirable peers per various criteria, followed by (mostly)
+ * ratios of desirable or disadvantaged peers. If any eviction candidates
+ * remain, the selection logic chooses a peer to evict.
+ */
[[nodiscard]] std::optional<NodeId> SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates);
+/** Protect desirable or disadvantaged inbound peers from eviction by ratio.
+ *
+ * This function protects half of the peers which have been connected the
+ * longest, to replicate the non-eviction implicit behavior and preclude attacks
+ * that start later.
+ *
+ * Half of these protected spots (1/4 of the total) are reserved for onion peers
+ * connected via our tor control service, if any, sorted by longest uptime, even
+ * if they're not longest uptime overall. Any remaining slots of the 1/4 are
+ * then allocated to protect localhost peers, if any (or up to 2 localhost peers
+ * if no slots remain and 2 or more onion peers were protected), sorted by
+ * longest uptime, as manually configured hidden services not using
+ * `-bind=addr[:port]=onion` will not be detected as inbound onion connections.
+ *
+ * This helps protect onion peers, which tend to be otherwise disadvantaged
+ * under our eviction criteria for their higher min ping times relative to IPv4
+ * and IPv6 peers, and favorise the diversity of peer connections.
+ *
+ * This function was extracted from SelectNodeToEvict() to be able to test the
+ * ratio-based protection logic deterministically.
+ */
+void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& vEvictionCandidates);
+
#endif // BITCOIN_NET_H