aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/epee/include/net/net_utils_base.h3
-rw-r--r--src/p2p/net_node.inl21
-rw-r--r--src/p2p/net_peerlist.cpp12
-rw-r--r--src/p2p/net_peerlist.h26
-rw-r--r--tests/unit_tests/epee_utils.cpp1
5 files changed, 48 insertions, 15 deletions
diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h
index d86c62c17..722206ee1 100644
--- a/contrib/epee/include/net/net_utils_base.h
+++ b/contrib/epee/include/net/net_utils_base.h
@@ -236,6 +236,7 @@ namespace net_utils
virtual address_type get_type_id() const = 0;
virtual zone get_zone() const = 0;
virtual bool is_blockable() const = 0;
+ virtual std::uint16_t port() const = 0;
};
template<typename T>
@@ -266,6 +267,7 @@ namespace net_utils
virtual address_type get_type_id() const override { return value.get_type_id(); }
virtual zone get_zone() const override { return value.get_zone(); }
virtual bool is_blockable() const override { return value.is_blockable(); }
+ virtual std::uint16_t port() const override { return value.port(); }
};
std::shared_ptr<interface> self;
@@ -312,6 +314,7 @@ namespace net_utils
address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; }
zone get_zone() const { return self ? self->get_zone() : zone::invalid; }
bool is_blockable() const { return self ? self->is_blockable() : false; }
+ std::uint16_t port() const { return self ? self->port() : 0; }
template<typename Type> const Type &as() const { return as_mutable<const Type>(); }
BEGIN_KV_SERIALIZE_MAP()
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index eb920d6ce..b8cf2d124 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -269,9 +269,17 @@ namespace nodetool
peerlist_entry pe{};
pe.adr = addr;
- zone.second.m_peerlist.remove_from_peer_white(pe);
- zone.second.m_peerlist.remove_from_peer_gray(pe);
- zone.second.m_peerlist.remove_from_peer_anchor(addr);
+ if (addr.port() == 0)
+ {
+ zone.second.m_peerlist.evict_host_from_peerlist(true, pe);
+ zone.second.m_peerlist.evict_host_from_peerlist(false, pe);
+ }
+ else
+ {
+ zone.second.m_peerlist.remove_from_peer_white(pe);
+ zone.second.m_peerlist.remove_from_peer_gray(pe);
+ zone.second.m_peerlist.remove_from_peer_anchor(addr);
+ }
for (const auto &c: conns)
zone.second.m_net_server.get_config_object().close(c);
@@ -331,6 +339,13 @@ namespace nodetool
for (const auto &c: conns)
zone.second.m_net_server.get_config_object().close(c);
+ for (int i = 0; i < 2; ++i)
+ zone.second.m_peerlist.filter(i == 0, [&subnet](const peerlist_entry &pe){
+ if (pe.adr.get_type_id() != epee::net_utils::ipv4_network_address::get_type_id())
+ return false;
+ return subnet.matches(pe.adr.as<const epee::net_utils::ipv4_network_address>());
+ });
+
conns.clear();
}
diff --git a/src/p2p/net_peerlist.cpp b/src/p2p/net_peerlist.cpp
index 42ab9727d..50dc6da77 100644
--- a/src/p2p/net_peerlist.cpp
+++ b/src/p2p/net_peerlist.cpp
@@ -289,17 +289,9 @@ namespace nodetool
copy_peers(peers.anchor, m_peers_anchor.get<by_addr>());
}
- void peerlist_manager::evict_host_from_white_peerlist(const peerlist_entry& pr)
+ void peerlist_manager::evict_host_from_peerlist(bool use_white, 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;
- }
+ filter(use_white, [&pr](const peerlist_entry& pe){ return pe.adr.is_same_host(pr.adr); });
}
}
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index c794b0f3b..61cc56935 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -109,7 +109,7 @@ namespace nodetool
bool get_white_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);
- void evict_host_from_white_peerlist(const peerlist_entry& pr);
+ void evict_host_from_peerlist(bool 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_anchor(const anchor_peerlist_entry& ple);
@@ -120,6 +120,7 @@ namespace nodetool
bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
bool remove_from_peer_anchor(const epee::net_utils::network_address& addr);
bool remove_from_peer_white(const peerlist_entry& pe);
+ template<typename F> size_t filter(bool white, const F &f); // f returns true: drop, false: keep
private:
struct by_time{};
@@ -346,7 +347,7 @@ namespace nodetool
if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
{
//put new record into white list
- evict_host_from_white_peerlist(ple);
+ evict_host_from_peerlist(true, ple);
m_peers_white.insert(ple);
trim_white_peerlist();
}else
@@ -519,5 +520,26 @@ namespace nodetool
CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false);
}
//--------------------------------------------------------------------------------------------------
+ template<typename F> size_t peerlist_manager::filter(bool white, const F &f)
+ {
+ size_t filtered = 0;
+ TRY_ENTRY();
+ CRITICAL_REGION_LOCAL(m_peerlist_lock);
+ peers_indexed::index<by_addr>::type& sorted_index = white ? m_peers_gray.get<by_addr>() : m_peers_white.get<by_addr>();
+ auto i = sorted_index.begin();
+ while (i != sorted_index.end())
+ {
+ if (f(*i))
+ {
+ i = sorted_index.erase(i);
+ ++filtered;
+ }
+ else
+ ++i;
+ }
+ CATCH_ENTRY_L0("peerlist_manager::filter()", filtered);
+ return filtered;
+ }
+ //--------------------------------------------------------------------------------------------------
}
diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp
index 8c89968b9..7ba9c26fa 100644
--- a/tests/unit_tests/epee_utils.cpp
+++ b/tests/unit_tests/epee_utils.cpp
@@ -1503,6 +1503,7 @@ TEST(NetUtils, NetworkAddress)
constexpr static epee::net_utils::address_type get_type_id() noexcept { return epee::net_utils::address_type(-1); }
constexpr static epee::net_utils::zone get_zone() noexcept { return epee::net_utils::zone::invalid; }
constexpr static bool is_blockable() noexcept { return false; }
+ constexpr static uint16_t port() { return 0; }
};
const epee::net_utils::network_address empty;