Skip to content

Commit

Permalink
Cache responses to addr requests
Browse files Browse the repository at this point in the history
Prevents a spy from scraping victim's AddrMan by
reconnecting and re-requesting addrs.

Github-Pull: bitcoin#18991
Rebased-From: a5cd709
  • Loading branch information
naumenkogs authored and luke-jr committed Jun 15, 2020
1 parent 9980371 commit c217d9b
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 5 deletions.
13 changes: 11 additions & 2 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2489,9 +2489,18 @@ void CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddres
addrman.Add(vAddr, addrFrom, nTimePenalty);
}

std::vector<CAddress> CConnman::GetAddresses()
std::vector<CAddress> CConnman::GetAddresses(bool from_cache)
{
return addrman.GetAddr();
if (from_cache) {
const std::chrono::microseconds current_time = GetTime<std::chrono::microseconds>();
if (m_update_addr_response < current_time) {
m_addrs_response_cache = addrman.GetAddr();
m_update_addr_response = current_time + std::chrono::hours(24) + GetRandMillis(std::chrono::hours(3));
}
return m_addrs_response_cache;
} else {
return addrman.GetAddr();
}
}

bool CConnman::AddNode(const std::string& strNode)
Expand Down
11 changes: 10 additions & 1 deletion src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,9 @@ class CConnman
void SetServices(const CService &addr, ServiceFlags nServices);
void MarkAddressGood(const CAddress& addr);
void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
std::vector<CAddress> GetAddresses();
// Cache is used to minimize topology leaks, so it should
// be used for all non-trusted calls, for example, p2p.
std::vector<CAddress> GetAddresses(bool from_cache);

// This allows temporarily exceeding m_max_outbound_full_relay, with the goal of finding
// a peer that is better than all our current peers.
Expand Down Expand Up @@ -424,6 +426,13 @@ class CConnman
std::atomic<NodeId> nLastNodeId{0};
unsigned int nPrevNodeCount{0};

// Cache responses to addr requests to minimize privacy leak.
// Attack example: scraping addrs in real-time may allow an attacker
// to infer new connections of the victim by detecting new records
// with fresh timestamps (per self-announcement).
std::vector<CAddress> m_addrs_response_cache;
std::chrono::microseconds m_update_addr_response{0};

/**
* Services this instance offers.
*
Expand Down
2 changes: 1 addition & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3324,7 +3324,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
pfrom->fSentAddr = true;

pfrom->vAddrToSend.clear();
std::vector<CAddress> vAddr = connman->GetAddresses();
std::vector<CAddress> vAddr = connman->GetAddresses(true);
FastRandomContext insecure_rand;
for (const CAddress &addr : vAddr) {
if (!banman->IsBanned(addr)) {
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
}
}
// returns a shuffled list of CAddress
std::vector<CAddress> vAddr = g_rpc_node->connman->GetAddresses();
std::vector<CAddress> vAddr = g_rpc_node->connman->GetAddresses(false);
UniValue ret(UniValue::VARR);

int address_return_count = std::min<int>(count, vAddr.size());
Expand Down

0 comments on commit c217d9b

Please sign in to comment.