Add anchor connections
Based on https://eprint.iacr.org/2015/263.pdf 4. Anchor connections. Peer list serialisation version bumped to 5.
This commit is contained in:
parent
99ee3fd17e
commit
8277e67f11
|
@ -107,6 +107,7 @@
|
||||||
#define P2P_DEFAULT_INVOKE_TIMEOUT 60*2*1000 //2 minutes
|
#define P2P_DEFAULT_INVOKE_TIMEOUT 60*2*1000 //2 minutes
|
||||||
#define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds
|
#define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds
|
||||||
#define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT 70
|
#define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT 70
|
||||||
|
#define P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT 2
|
||||||
|
|
||||||
#define P2P_FAILED_ADDR_FORGET_SECONDS (60*60) //1 hour
|
#define P2P_FAILED_ADDR_FORGET_SECONDS (60*60) //1 hour
|
||||||
#define P2P_IP_BLOCKTIME (60*60*24) //24 hour
|
#define P2P_IP_BLOCKTIME (60*60*24) //24 hour
|
||||||
|
|
|
@ -155,6 +155,8 @@ namespace nodetool
|
||||||
CHAIN_INVOKE_MAP_TO_OBJ_FORCE_CONTEXT(m_payload_handler, typename t_payload_net_handler::connection_context&)
|
CHAIN_INVOKE_MAP_TO_OBJ_FORCE_CONTEXT(m_payload_handler, typename t_payload_net_handler::connection_context&)
|
||||||
END_INVOKE_MAP2()
|
END_INVOKE_MAP2()
|
||||||
|
|
||||||
|
enum PeerType { anchor = 0, white, gray };
|
||||||
|
|
||||||
//----------------- commands handlers ----------------------------------------------
|
//----------------- commands handlers ----------------------------------------------
|
||||||
int handle_handshake(int command, typename COMMAND_HANDSHAKE::request& arg, typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context);
|
int handle_handshake(int command, typename COMMAND_HANDSHAKE::request& arg, typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context);
|
||||||
int handle_timed_sync(int command, typename COMMAND_TIMED_SYNC::request& arg, typename COMMAND_TIMED_SYNC::response& rsp, p2p_connection_context& context);
|
int handle_timed_sync(int command, typename COMMAND_TIMED_SYNC::request& arg, typename COMMAND_TIMED_SYNC::response& rsp, p2p_connection_context& context);
|
||||||
|
@ -206,15 +208,17 @@ namespace nodetool
|
||||||
bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false);
|
bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false);
|
||||||
bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id);
|
bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id);
|
||||||
|
|
||||||
|
bool make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist);
|
||||||
bool make_new_connection_from_peerlist(bool use_white_list);
|
bool make_new_connection_from_peerlist(bool use_white_list);
|
||||||
bool try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, bool white = true);
|
bool try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, PeerType peer_type = white, uint64_t first_seen_stamp = 0);
|
||||||
size_t get_random_index_with_fixed_probability(size_t max_index);
|
size_t get_random_index_with_fixed_probability(size_t max_index);
|
||||||
bool is_peer_used(const peerlist_entry& peer);
|
bool is_peer_used(const peerlist_entry& peer);
|
||||||
|
bool is_peer_used(const anchor_peerlist_entry& peer);
|
||||||
bool is_addr_connected(const net_address& peer);
|
bool is_addr_connected(const net_address& peer);
|
||||||
template<class t_callback>
|
template<class t_callback>
|
||||||
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
|
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
|
||||||
bool try_get_support_flags(const p2p_connection_context& context, std::function<void(p2p_connection_context&, const uint32_t&)> f);
|
bool try_get_support_flags(const p2p_connection_context& context, std::function<void(p2p_connection_context&, const uint32_t&)> f);
|
||||||
bool make_expected_connections_count(bool white_list, size_t expected_connections);
|
bool make_expected_connections_count(PeerType peer_type, size_t expected_connections);
|
||||||
void cache_connect_fail_info(const net_address& addr);
|
void cache_connect_fail_info(const net_address& addr);
|
||||||
bool is_addr_recently_failed(const net_address& addr);
|
bool is_addr_recently_failed(const net_address& addr);
|
||||||
bool is_priority_node(const net_address& na);
|
bool is_priority_node(const net_address& na);
|
||||||
|
|
|
@ -847,6 +847,30 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
|
bool node_server<t_payload_net_handler>::is_peer_used(const anchor_peerlist_entry& peer)
|
||||||
|
{
|
||||||
|
if(m_config.m_peer_id == peer.id) {
|
||||||
|
return true;//dont make connections to ourself
|
||||||
|
}
|
||||||
|
|
||||||
|
bool used = false;
|
||||||
|
|
||||||
|
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
|
||||||
|
{
|
||||||
|
if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr.ip == cntxt.m_remote_ip && peer.adr.port == cntxt.m_remote_port))
|
||||||
|
{
|
||||||
|
used = true;
|
||||||
|
|
||||||
|
return false;//stop enumerating
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::is_addr_connected(const net_address& peer)
|
bool node_server<t_payload_net_handler>::is_addr_connected(const net_address& peer)
|
||||||
{
|
{
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
|
@ -873,7 +897,7 @@ namespace nodetool
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, bool white)
|
bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, PeerType peer_type, uint64_t first_seen_stamp)
|
||||||
{
|
{
|
||||||
if (m_current_number_of_out_peers == m_config.m_net_config.connections_count) // out peers limit
|
if (m_current_number_of_out_peers == m_config.m_net_config.connections_count) // out peers limit
|
||||||
{
|
{
|
||||||
|
@ -886,7 +910,7 @@ namespace nodetool
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MDEBUG("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":"
|
MDEBUG("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":"
|
||||||
<< epee::string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: "
|
<< epee::string_tools::num_to_string_fast(na.port) << "(peer_type=" << peer_type << ", last_seen: "
|
||||||
<< (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
|
<< (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
|
||||||
<< ")...");
|
<< ")...");
|
||||||
|
|
||||||
|
@ -936,6 +960,13 @@ namespace nodetool
|
||||||
m_peerlist.append_with_peer_white(pe_local);
|
m_peerlist.append_with_peer_white(pe_local);
|
||||||
//update last seen and push it to peerlist manager
|
//update last seen and push it to peerlist manager
|
||||||
|
|
||||||
|
anchor_peerlist_entry ape = AUTO_VAL_INIT(ape);
|
||||||
|
ape.adr = na;
|
||||||
|
ape.id = pi;
|
||||||
|
ape.first_seen = first_seen_stamp ? first_seen_stamp : time(nullptr);
|
||||||
|
|
||||||
|
m_peerlist.append_with_peer_anchor(ape);
|
||||||
|
|
||||||
LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK.");
|
LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1002,6 +1033,41 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
|
bool node_server<t_payload_net_handler>::make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist)
|
||||||
|
{
|
||||||
|
for (const auto& pe: anchor_peerlist) {
|
||||||
|
_note("Considering connecting (out) to peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port));
|
||||||
|
|
||||||
|
if(is_peer_used(pe)) {
|
||||||
|
_note("Peer is used");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_remote_ip_allowed(pe.adr.ip)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_addr_recently_failed(pe.adr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDEBUG("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
|
||||||
|
<< ":" << boost::lexical_cast<std::string>(pe.adr.port)
|
||||||
|
<< "[peer_type=" << anchor
|
||||||
|
<< "] first_seen: " << epee::misc_utils::get_time_interval_string(time(NULL) - pe.first_seen));
|
||||||
|
|
||||||
|
if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, 0, anchor, pe.first_seen)) {
|
||||||
|
_note("Handshake failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list)
|
bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list)
|
||||||
{
|
{
|
||||||
size_t local_peers_count = use_white_list ? m_peerlist.get_white_peers_count():m_peerlist.get_gray_peers_count();
|
size_t local_peers_count = use_white_list ? m_peerlist.get_white_peers_count():m_peerlist.get_gray_peers_count();
|
||||||
|
@ -1045,10 +1111,10 @@ namespace nodetool
|
||||||
|
|
||||||
MDEBUG("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
|
MDEBUG("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
|
||||||
<< ":" << boost::lexical_cast<std::string>(pe.adr.port)
|
<< ":" << boost::lexical_cast<std::string>(pe.adr.port)
|
||||||
<< "[white=" << use_white_list
|
<< "[peer_list=" << (use_white_list ? white : gray)
|
||||||
<< "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
|
<< "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
|
||||||
|
|
||||||
if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, pe.last_seen, use_white_list)) {
|
if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, pe.last_seen, use_white_list ? white : gray)) {
|
||||||
_note("Handshake failed");
|
_note("Handshake failed");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1095,19 +1161,22 @@ namespace nodetool
|
||||||
{
|
{
|
||||||
if(conn_count < expected_white_connections)
|
if(conn_count < expected_white_connections)
|
||||||
{
|
{
|
||||||
//start from white list
|
//start from anchor list
|
||||||
if(!make_expected_connections_count(true, expected_white_connections))
|
if(!make_expected_connections_count(anchor, P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT))
|
||||||
return false;
|
return false;
|
||||||
//and then do grey list
|
//then do white list
|
||||||
if(!make_expected_connections_count(false, m_config.m_net_config.connections_count))
|
if(!make_expected_connections_count(white, expected_white_connections))
|
||||||
|
return false;
|
||||||
|
//then do grey list
|
||||||
|
if(!make_expected_connections_count(gray, m_config.m_net_config.connections_count))
|
||||||
return false;
|
return false;
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
//start from grey list
|
//start from grey list
|
||||||
if(!make_expected_connections_count(false, m_config.m_net_config.connections_count))
|
if(!make_expected_connections_count(gray, m_config.m_net_config.connections_count))
|
||||||
return false;
|
return false;
|
||||||
//and then do white list
|
//and then do white list
|
||||||
if(!make_expected_connections_count(true, m_config.m_net_config.connections_count))
|
if(!make_expected_connections_count(white, m_config.m_net_config.connections_count))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1116,11 +1185,17 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::make_expected_connections_count(bool white_list, size_t expected_connections)
|
bool node_server<t_payload_net_handler>::make_expected_connections_count(PeerType peer_type, size_t expected_connections)
|
||||||
{
|
{
|
||||||
if (m_offline)
|
if (m_offline)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
std::vector<anchor_peerlist_entry> apl;
|
||||||
|
|
||||||
|
if (peer_type == anchor) {
|
||||||
|
m_peerlist.get_and_empty_anchor_peerlist(apl);
|
||||||
|
}
|
||||||
|
|
||||||
size_t conn_count = get_outgoing_connections_count();
|
size_t conn_count = get_outgoing_connections_count();
|
||||||
//add new connections from white peers
|
//add new connections from white peers
|
||||||
while(conn_count < expected_connections)
|
while(conn_count < expected_connections)
|
||||||
|
@ -1128,8 +1203,18 @@ namespace nodetool
|
||||||
if(m_net_server.is_stop_signal_sent())
|
if(m_net_server.is_stop_signal_sent())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!make_new_connection_from_peerlist(white_list))
|
if (peer_type == anchor && !make_new_connection_from_anchor_peerlist(apl)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer_type == white && !make_new_connection_from_peerlist(true)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer_type == gray && !make_new_connection_from_peerlist(false)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
conn_count = get_outgoing_connections_count();
|
conn_count = get_outgoing_connections_count();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1611,6 +1696,14 @@ namespace nodetool
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
void node_server<t_payload_net_handler>::on_connection_close(p2p_connection_context& context)
|
void node_server<t_payload_net_handler>::on_connection_close(p2p_connection_context& context)
|
||||||
{
|
{
|
||||||
|
if (!m_net_server.is_stop_signal_sent() && !context.m_is_income) {
|
||||||
|
nodetool::net_address na = AUTO_VAL_INIT(na);
|
||||||
|
na.ip = context.m_remote_ip;
|
||||||
|
na.port = context.m_remote_port;
|
||||||
|
|
||||||
|
m_peerlist.remove_from_peer_anchor(na);
|
||||||
|
}
|
||||||
|
|
||||||
MINFO("["<< epee::net_utils::print_connection_context(context) << "] CLOSE CONNECTION");
|
MINFO("["<< epee::net_utils::print_connection_context(context) << "] CLOSE CONNECTION");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
#include "net_peerlist_boost_serialization.h"
|
#include "net_peerlist_boost_serialization.h"
|
||||||
|
|
||||||
|
|
||||||
#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 4
|
#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 5
|
||||||
|
|
||||||
namespace nodetool
|
namespace nodetool
|
||||||
{
|
{
|
||||||
|
@ -77,13 +77,15 @@ namespace nodetool
|
||||||
bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
|
bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
|
||||||
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 set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port);
|
bool set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port);
|
||||||
bool set_peer_just_seen(peerid_type peer, const net_address& addr);
|
bool set_peer_just_seen(peerid_type peer, const net_address& addr);
|
||||||
bool set_peer_unreachable(const peerlist_entry& pr);
|
bool set_peer_unreachable(const peerlist_entry& pr);
|
||||||
bool is_ip_allowed(uint32_t ip);
|
bool is_ip_allowed(uint32_t ip);
|
||||||
bool get_random_gray_peer(peerlist_entry& pe);
|
bool get_random_gray_peer(peerlist_entry& pe);
|
||||||
bool remove_from_peer_gray(const peerlist_entry& pe);
|
bool remove_from_peer_gray(const peerlist_entry& pe);
|
||||||
|
bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
|
||||||
|
bool remove_from_peer_anchor(const net_address& addr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct by_time{};
|
struct by_time{};
|
||||||
|
@ -145,6 +147,16 @@ namespace nodetool
|
||||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
|
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
|
||||||
>
|
>
|
||||||
> peers_indexed_old;
|
> peers_indexed_old;
|
||||||
|
|
||||||
|
typedef boost::multi_index_container<
|
||||||
|
anchor_peerlist_entry,
|
||||||
|
boost::multi_index::indexed_by<
|
||||||
|
// access by anchor_peerlist_entry::net_adress
|
||||||
|
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<anchor_peerlist_entry,net_address,&anchor_peerlist_entry::adr> >,
|
||||||
|
// sort by anchor_peerlist_entry::first_seen
|
||||||
|
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<anchor_peerlist_entry,int64_t,&anchor_peerlist_entry::first_seen> >
|
||||||
|
>
|
||||||
|
> anchor_peers_indexed;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template <class Archive, class t_version_type>
|
template <class Archive, class t_version_type>
|
||||||
|
@ -161,8 +173,15 @@ namespace nodetool
|
||||||
peers_indexed_from_old(pio, m_peers_white);
|
peers_indexed_from_old(pio, m_peers_white);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
a & m_peers_white;
|
a & m_peers_white;
|
||||||
a & m_peers_gray;
|
a & m_peers_gray;
|
||||||
|
|
||||||
|
if(ver < 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
a & m_peers_anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -178,6 +197,7 @@ namespace nodetool
|
||||||
|
|
||||||
peers_indexed m_peers_gray;
|
peers_indexed m_peers_gray;
|
||||||
peers_indexed m_peers_white;
|
peers_indexed m_peers_white;
|
||||||
|
anchor_peers_indexed m_peers_anchor;
|
||||||
};
|
};
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
inline
|
inline
|
||||||
|
@ -398,6 +418,24 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
inline
|
inline
|
||||||
|
bool peerlist_manager::append_with_peer_anchor(const anchor_peerlist_entry& ple)
|
||||||
|
{
|
||||||
|
TRY_ENTRY();
|
||||||
|
|
||||||
|
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||||
|
|
||||||
|
auto by_addr_it_anchor = m_peers_anchor.get<by_addr>().find(ple.adr);
|
||||||
|
|
||||||
|
if(by_addr_it_anchor == m_peers_anchor.get<by_addr>().end()) {
|
||||||
|
m_peers_anchor.insert(ple);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CATCH_ENTRY_L0("peerlist_manager::append_with_peer_anchor()", false);
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
inline
|
||||||
bool peerlist_manager::get_random_gray_peer(peerlist_entry& pe)
|
bool peerlist_manager::get_random_gray_peer(peerlist_entry& pe)
|
||||||
{
|
{
|
||||||
TRY_ENTRY();
|
TRY_ENTRY();
|
||||||
|
@ -438,7 +476,46 @@ namespace nodetool
|
||||||
|
|
||||||
CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false);
|
CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false);
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
inline
|
||||||
|
bool peerlist_manager::get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl)
|
||||||
|
{
|
||||||
|
TRY_ENTRY();
|
||||||
|
|
||||||
|
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||||
|
|
||||||
|
auto begin = m_peers_anchor.get<by_time>().begin();
|
||||||
|
auto end = m_peers_anchor.get<by_time>().end();
|
||||||
|
|
||||||
|
std::for_each(begin, end, [&apl](const anchor_peerlist_entry &a) {
|
||||||
|
apl.push_back(a);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_peers_anchor.get<by_time>().clear();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CATCH_ENTRY_L0("peerlist_manager::get_and_empty_anchor_peerlist()", false);
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
inline
|
||||||
|
bool peerlist_manager::remove_from_peer_anchor(const net_address& addr)
|
||||||
|
{
|
||||||
|
TRY_ENTRY();
|
||||||
|
|
||||||
|
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||||
|
|
||||||
|
anchor_peers_indexed::index_iterator<by_addr>::type iterator = m_peers_anchor.get<by_addr>().find(addr);
|
||||||
|
|
||||||
|
if (iterator != m_peers_anchor.get<by_addr>().end()) {
|
||||||
|
m_peers_anchor.erase(iterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false);
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER)
|
BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER)
|
||||||
|
|
|
@ -49,6 +49,14 @@ namespace boost
|
||||||
a & pl.adr;
|
a & pl.adr;
|
||||||
a & pl.id;
|
a & pl.id;
|
||||||
a & pl.last_seen;
|
a & pl.last_seen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Archive, class ver_type>
|
||||||
|
inline void serialize(Archive &a, nodetool::anchor_peerlist_entry& pl, const ver_type ver)
|
||||||
|
{
|
||||||
|
a & pl.adr;
|
||||||
|
a & pl.id;
|
||||||
|
a & pl.first_seen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,13 @@ namespace nodetool
|
||||||
int64_t last_seen;
|
int64_t last_seen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct anchor_peerlist_entry
|
||||||
|
{
|
||||||
|
net_address adr;
|
||||||
|
peerid_type id;
|
||||||
|
int64_t first_seen;
|
||||||
|
};
|
||||||
|
|
||||||
struct connection_entry
|
struct connection_entry
|
||||||
{
|
{
|
||||||
net_address adr;
|
net_address adr;
|
||||||
|
|
Loading…
Reference in New Issue