aboutsummaryrefslogtreecommitdiff
path: root/src/p2p/net_peerlist.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/p2p/net_peerlist.h')
-rw-r--r--src/p2p/net_peerlist.h25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index f4fa921e2..c65b9dd82 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -278,6 +278,9 @@ namespace nodetool
// was moved to the gray list (if it's not accessibe, which the attacker can check if
// the address accepts incoming connections) or it was the oldest to still fit in the 250 items,
// so its last_seen is old.
+ //
+ // See Cao, Tong et al. "Exploring the Monero Peer-to-Peer Network". https://eprint.iacr.org/2019/411
+ //
const uint32_t pick_depth = anonymize ? depth + depth / 5 : depth;
bs_head.reserve(pick_depth);
for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
@@ -290,7 +293,7 @@ namespace nodetool
if (anonymize)
{
- std::random_shuffle(bs_head.begin(), bs_head.end());
+ std::shuffle(bs_head.begin(), bs_head.end(), crypto::random_device{});
if (bs_head.size() > depth)
bs_head.resize(depth);
for (auto &e: bs_head)
@@ -344,8 +347,14 @@ namespace nodetool
trim_white_peerlist();
}else
{
- //update record in white list
- m_peers_white.replace(by_addr_it_wt, ple);
+ //update record in white list
+ peerlist_entry new_ple = ple;
+ if (by_addr_it_wt->pruning_seed && ple.pruning_seed == 0) // guard against older nodes not passing pruning info around
+ new_ple.pruning_seed = by_addr_it_wt->pruning_seed;
+ if (by_addr_it_wt->rpc_port && ple.rpc_port == 0) // guard against older nodes not passing RPC port around
+ new_ple.rpc_port = by_addr_it_wt->rpc_port;
+ new_ple.last_seen = by_addr_it_wt->last_seen; // do not overwrite the last seen timestamp, incoming peer list are untrusted
+ m_peers_white.replace(by_addr_it_wt, new_ple);
}
//remove from gray list, if need
auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
@@ -379,8 +388,14 @@ namespace nodetool
trim_gray_peerlist();
}else
{
- //update record in white list
- m_peers_gray.replace(by_addr_it_gr, ple);
+ //update record in gray list
+ peerlist_entry new_ple = ple;
+ if (by_addr_it_gr->pruning_seed && ple.pruning_seed == 0) // guard against older nodes not passing pruning info around
+ new_ple.pruning_seed = by_addr_it_gr->pruning_seed;
+ if (by_addr_it_gr->rpc_port && ple.rpc_port == 0) // guard against older nodes not passing RPC port around
+ new_ple.rpc_port = by_addr_it_gr->rpc_port;
+ new_ple.last_seen = by_addr_it_gr->last_seen; // do not overwrite the last seen timestamp, incoming peer list are untrusted
+ m_peers_gray.replace(by_addr_it_gr, new_ple);
}
return true;
CATCH_ENTRY_L0("peerlist_manager::append_with_peer_gray()", false);