keep only the last seen node on a given host in the white list

This commit is contained in:
moneromooo 2020-12-02 19:36:08 +00:00 committed by moneromooo-monero
parent c74d8ffd63
commit 89e984d93b
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
3 changed files with 48 additions and 0 deletions

View file

@ -6,6 +6,17 @@
#include "string_tools.h" #include "string_tools.h"
#include "net/local_ip.h" #include "net/local_ip.h"
static inline uint32_t make_address_v4_from_v6(const boost::asio::ip::address_v6& a)
{
const auto &bytes = a.to_bytes();
uint32_t v4 = 0;
v4 = (v4 << 8) | bytes[12];
v4 = (v4 << 8) | bytes[13];
v4 = (v4 << 8) | bytes[14];
v4 = (v4 << 8) | bytes[15];
return htonl(v4);
}
namespace epee { namespace net_utils namespace epee { namespace net_utils
{ {
bool ipv4_network_address::equal(const ipv4_network_address& other) const noexcept bool ipv4_network_address::equal(const ipv4_network_address& other) const noexcept
@ -83,6 +94,28 @@ namespace epee { namespace net_utils
network_address::interface const* const other_self = other.self.get(); network_address::interface const* const other_self = other.self.get();
if (self_ == other_self) return true; if (self_ == other_self) return true;
if (!self_ || !other_self) return false; if (!self_ || !other_self) return false;
const bool this_is_4 = get_type_id() == epee::net_utils::ipv4_network_address::get_type_id();
const bool this_is_6 = get_type_id() == epee::net_utils::ipv6_network_address::get_type_id();
const bool other_is_4 = other.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id();
const bool other_is_6 = other.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id();
if (this_is_4 && other_is_6)
{
const boost::asio::ip::address_v6 &actual_ip = other.as<const epee::net_utils::ipv6_network_address>().ip();
if (actual_ip.is_v4_mapped())
{
const uint32_t v4ip = make_address_v4_from_v6(actual_ip);
return is_same_host(ipv4_network_address(v4ip, 0));
}
}
else if (this_is_6 && other_is_4)
{
const boost::asio::ip::address_v6 &actual_ip = this->as<const epee::net_utils::ipv6_network_address>().ip();
if (actual_ip.is_v4_mapped())
{
const uint32_t v4ip = make_address_v4_from_v6(actual_ip);
return other.is_same_host(ipv4_network_address(v4ip, 0));
}
}
if (typeid(*self_) != typeid(*other_self)) return false; if (typeid(*self_) != typeid(*other_self)) return false;
return self_->is_same_host(*other_self); return self_->is_same_host(*other_self);
} }

View file

@ -288,6 +288,19 @@ namespace nodetool
copy_peers(peers.gray, m_peers_gray.get<by_addr>()); copy_peers(peers.gray, m_peers_gray.get<by_addr>());
copy_peers(peers.anchor, m_peers_anchor.get<by_addr>()); copy_peers(peers.anchor, m_peers_anchor.get<by_addr>());
} }
void peerlist_manager::evict_host_from_white_peerlist(const peerlist_entry& pr)
{
peers_indexed::index<by_time>::type& sorted_index=m_peers_white.get<by_time>();
auto i = sorted_index.begin();
while (i != sorted_index.end())
{
if (i->adr.is_same_host(pr.adr))
i = sorted_index.erase(i);
else
++i;
}
}
} }
BOOST_CLASS_VERSION(nodetool::peerlist_types, nodetool::CURRENT_PEERLIST_STORAGE_ARCHIVE_VER); BOOST_CLASS_VERSION(nodetool::peerlist_types, nodetool::CURRENT_PEERLIST_STORAGE_ARCHIVE_VER);

View file

@ -109,6 +109,7 @@ namespace nodetool
bool get_white_peer_by_index(peerlist_entry& p, size_t i); bool get_white_peer_by_index(peerlist_entry& p, size_t i);
bool get_gray_peer_by_index(peerlist_entry& p, size_t i); bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
template<typename F> bool foreach(bool white, const F &f); template<typename F> bool foreach(bool white, const F &f);
void evict_host_from_white_peerlist(const peerlist_entry& pr);
bool append_with_peer_white(const peerlist_entry& pr); bool append_with_peer_white(const peerlist_entry& pr);
bool append_with_peer_gray(const peerlist_entry& pr); bool append_with_peer_gray(const peerlist_entry& pr);
bool append_with_peer_anchor(const anchor_peerlist_entry& ple); bool append_with_peer_anchor(const anchor_peerlist_entry& ple);
@ -345,6 +346,7 @@ namespace nodetool
if(by_addr_it_wt == m_peers_white.get<by_addr>().end()) if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
{ {
//put new record into white list //put new record into white list
evict_host_from_white_peerlist(ple);
m_peers_white.insert(ple); m_peers_white.insert(ple);
trim_white_peerlist(); trim_white_peerlist();
}else }else