diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/p2p/net_node.inl | 21 | ||||
-rw-r--r-- | src/p2p/net_peerlist.cpp | 12 | ||||
-rw-r--r-- | src/p2p/net_peerlist.h | 26 |
3 files changed, 44 insertions, 15 deletions
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; + } + //-------------------------------------------------------------------------------------------------- } |