|
27 | 27 | #include <atomic>
|
28 | 28 | #include <cstdint>
|
29 | 29 | #include <deque>
|
| 30 | +#include <map> |
30 | 31 | #include <thread>
|
31 | 32 | #include <memory>
|
32 | 33 | #include <condition_variable>
|
@@ -254,6 +255,13 @@ class CConnman
|
254 | 255 | void MarkAddressGood(const CAddress& addr);
|
255 | 256 | void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
|
256 | 257 | std::vector<CAddress> GetAddresses();
|
| 258 | + /** |
| 259 | + * Cache is used to minimize topology leaks, so it should |
| 260 | + * be used for all non-trusted calls, for example, p2p. |
| 261 | + * A non-malicious call (from RPC) should |
| 262 | + * call the function without a parameter to avoid using the cache. |
| 263 | + */ |
| 264 | + std::vector<CAddress> GetAddresses(Network requestor_network); |
257 | 265 |
|
258 | 266 | // This allows temporarily exceeding m_max_outbound_full_relay, with the goal of finding
|
259 | 267 | // a peer that is better than all our current peers.
|
@@ -418,6 +426,29 @@ class CConnman
|
418 | 426 | std::atomic<NodeId> nLastNodeId{0};
|
419 | 427 | unsigned int nPrevNodeCount{0};
|
420 | 428 |
|
| 429 | + /** |
| 430 | + * Cache responses to addr requests to minimize privacy leak. |
| 431 | + * Attack example: scraping addrs in real-time may allow an attacker |
| 432 | + * to infer new connections of the victim by detecting new records |
| 433 | + * with fresh timestamps (per self-announcement). |
| 434 | + */ |
| 435 | + struct CachedAddrResponse { |
| 436 | + std::vector<CAddress> m_addrs_response_cache; |
| 437 | + std::chrono::microseconds m_update_addr_response{0}; |
| 438 | + }; |
| 439 | + |
| 440 | + /** |
| 441 | + * Addr responses stored in different caches |
| 442 | + * per network prevent cross-network node identification. |
| 443 | + * If a node for example is multi-homed under Tor and IPv6, |
| 444 | + * a single cache (or no cache at all) would let an attacker |
| 445 | + * to easily detect that it is the same node by comparing responses. |
| 446 | + * The used memory equals to 1000 CAddress records (or around 32 bytes) per |
| 447 | + * distinct Network (up to 5) we have/had an inbound peer from, |
| 448 | + * resulting in at most ~160 KB. |
| 449 | + */ |
| 450 | + std::map<Network, CachedAddrResponse> m_addr_response_caches; |
| 451 | + |
421 | 452 | /**
|
422 | 453 | * Services this instance offers.
|
423 | 454 | *
|
|
0 commit comments