Merge pull request #6897
2abdbf6
Add support for i2p and tor seed nodes (vtnerd)
This commit is contained in:
commit
52006df9bb
|
@ -164,6 +164,7 @@ namespace nodetool
|
||||||
network_zone()
|
network_zone()
|
||||||
: m_connect(nullptr),
|
: m_connect(nullptr),
|
||||||
m_net_server(epee::net_utils::e_connection_type_P2P),
|
m_net_server(epee::net_utils::e_connection_type_P2P),
|
||||||
|
m_seed_nodes(),
|
||||||
m_bind_ip(),
|
m_bind_ip(),
|
||||||
m_bind_ipv6_address(),
|
m_bind_ipv6_address(),
|
||||||
m_port(),
|
m_port(),
|
||||||
|
@ -175,7 +176,9 @@ namespace nodetool
|
||||||
m_proxy_address(),
|
m_proxy_address(),
|
||||||
m_current_number_of_out_peers(0),
|
m_current_number_of_out_peers(0),
|
||||||
m_current_number_of_in_peers(0),
|
m_current_number_of_in_peers(0),
|
||||||
m_can_pingback(false)
|
m_seed_nodes_lock(),
|
||||||
|
m_can_pingback(false),
|
||||||
|
m_seed_nodes_initialized(false)
|
||||||
{
|
{
|
||||||
set_config_defaults();
|
set_config_defaults();
|
||||||
}
|
}
|
||||||
|
@ -183,6 +186,7 @@ namespace nodetool
|
||||||
network_zone(boost::asio::io_service& public_service)
|
network_zone(boost::asio::io_service& public_service)
|
||||||
: m_connect(nullptr),
|
: m_connect(nullptr),
|
||||||
m_net_server(public_service, epee::net_utils::e_connection_type_P2P),
|
m_net_server(public_service, epee::net_utils::e_connection_type_P2P),
|
||||||
|
m_seed_nodes(),
|
||||||
m_bind_ip(),
|
m_bind_ip(),
|
||||||
m_bind_ipv6_address(),
|
m_bind_ipv6_address(),
|
||||||
m_port(),
|
m_port(),
|
||||||
|
@ -194,13 +198,16 @@ namespace nodetool
|
||||||
m_proxy_address(),
|
m_proxy_address(),
|
||||||
m_current_number_of_out_peers(0),
|
m_current_number_of_out_peers(0),
|
||||||
m_current_number_of_in_peers(0),
|
m_current_number_of_in_peers(0),
|
||||||
m_can_pingback(false)
|
m_seed_nodes_lock(),
|
||||||
|
m_can_pingback(false),
|
||||||
|
m_seed_nodes_initialized(false)
|
||||||
{
|
{
|
||||||
set_config_defaults();
|
set_config_defaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
connect_func* m_connect;
|
connect_func* m_connect;
|
||||||
net_server m_net_server;
|
net_server m_net_server;
|
||||||
|
std::vector<epee::net_utils::network_address> m_seed_nodes;
|
||||||
std::string m_bind_ip;
|
std::string m_bind_ip;
|
||||||
std::string m_bind_ipv6_address;
|
std::string m_bind_ipv6_address;
|
||||||
std::string m_port;
|
std::string m_port;
|
||||||
|
@ -212,7 +219,9 @@ namespace nodetool
|
||||||
boost::asio::ip::tcp::endpoint m_proxy_address;
|
boost::asio::ip::tcp::endpoint m_proxy_address;
|
||||||
std::atomic<unsigned int> m_current_number_of_out_peers;
|
std::atomic<unsigned int> m_current_number_of_out_peers;
|
||||||
std::atomic<unsigned int> m_current_number_of_in_peers;
|
std::atomic<unsigned int> m_current_number_of_in_peers;
|
||||||
|
boost::shared_mutex m_seed_nodes_lock;
|
||||||
bool m_can_pingback;
|
bool m_can_pingback;
|
||||||
|
bool m_seed_nodes_initialized;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_config_defaults() noexcept
|
void set_config_defaults() noexcept
|
||||||
|
@ -383,9 +392,10 @@ namespace nodetool
|
||||||
void record_addr_failed(const epee::net_utils::network_address& addr);
|
void record_addr_failed(const epee::net_utils::network_address& addr);
|
||||||
bool is_addr_recently_failed(const epee::net_utils::network_address& addr);
|
bool is_addr_recently_failed(const epee::net_utils::network_address& addr);
|
||||||
bool is_priority_node(const epee::net_utils::network_address& na);
|
bool is_priority_node(const epee::net_utils::network_address& na);
|
||||||
std::set<std::string> get_seed_nodes(cryptonote::network_type nettype) const;
|
std::set<std::string> get_ip_seed_nodes() const;
|
||||||
std::set<std::string> get_seed_nodes();
|
std::set<std::string> get_dns_seed_nodes();
|
||||||
bool connect_to_seed();
|
std::set<std::string> get_seed_nodes(epee::net_utils::zone);
|
||||||
|
bool connect_to_seed(epee::net_utils::zone);
|
||||||
|
|
||||||
template <class Container>
|
template <class Container>
|
||||||
bool connect_to_peerlist(const Container& peers);
|
bool connect_to_peerlist(const Container& peers);
|
||||||
|
@ -467,9 +477,6 @@ namespace nodetool
|
||||||
|
|
||||||
std::list<epee::net_utils::network_address> m_priority_peers;
|
std::list<epee::net_utils::network_address> m_priority_peers;
|
||||||
std::vector<epee::net_utils::network_address> m_exclusive_peers;
|
std::vector<epee::net_utils::network_address> m_exclusive_peers;
|
||||||
std::vector<epee::net_utils::network_address> m_seed_nodes;
|
|
||||||
bool m_seed_nodes_initialized = false;
|
|
||||||
boost::shared_mutex m_seed_nodes_lock;
|
|
||||||
std::atomic_flag m_fallback_seed_nodes_added;
|
std::atomic_flag m_fallback_seed_nodes_added;
|
||||||
std::vector<nodetool::peerlist_entry> m_command_line_peers;
|
std::vector<nodetool::peerlist_entry> m_command_line_peers;
|
||||||
uint64_t m_peer_livetime;
|
uint64_t m_peer_livetime;
|
||||||
|
|
|
@ -435,9 +435,9 @@ namespace nodetool
|
||||||
|
|
||||||
if (command_line::has_arg(vm, arg_p2p_seed_node))
|
if (command_line::has_arg(vm, arg_p2p_seed_node))
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::shared_mutex> lock(m_seed_nodes_lock);
|
boost::unique_lock<boost::shared_mutex> lock(public_zone.m_seed_nodes_lock);
|
||||||
|
|
||||||
if (!parse_peers_and_add_to_container(vm, arg_p2p_seed_node, m_seed_nodes))
|
if (!parse_peers_and_add_to_container(vm, arg_p2p_seed_node, public_zone.m_seed_nodes))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,21 +598,21 @@ namespace nodetool
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
std::set<std::string> node_server<t_payload_net_handler>::get_seed_nodes(cryptonote::network_type nettype) const
|
std::set<std::string> node_server<t_payload_net_handler>::get_ip_seed_nodes() const
|
||||||
{
|
{
|
||||||
std::set<std::string> full_addrs;
|
std::set<std::string> full_addrs;
|
||||||
if (nettype == cryptonote::TESTNET)
|
if (m_nettype == cryptonote::TESTNET)
|
||||||
{
|
{
|
||||||
full_addrs.insert("212.83.175.67:28080");
|
full_addrs.insert("212.83.175.67:28080");
|
||||||
full_addrs.insert("212.83.172.165:28080");
|
full_addrs.insert("212.83.172.165:28080");
|
||||||
full_addrs.insert("192.110.160.146:28080");
|
full_addrs.insert("192.110.160.146:28080");
|
||||||
}
|
}
|
||||||
else if (nettype == cryptonote::STAGENET)
|
else if (m_nettype == cryptonote::STAGENET)
|
||||||
{
|
{
|
||||||
full_addrs.insert("162.210.173.150:38080");
|
full_addrs.insert("162.210.173.150:38080");
|
||||||
full_addrs.insert("192.110.160.146:38080");
|
full_addrs.insert("192.110.160.146:38080");
|
||||||
}
|
}
|
||||||
else if (nettype == cryptonote::FAKECHAIN)
|
else if (m_nettype == cryptonote::FAKECHAIN)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -630,7 +630,7 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
std::set<std::string> node_server<t_payload_net_handler>::get_seed_nodes()
|
std::set<std::string> node_server<t_payload_net_handler>::get_dns_seed_nodes()
|
||||||
{
|
{
|
||||||
if (!m_exclusive_peers.empty() || m_offline)
|
if (!m_exclusive_peers.empty() || m_offline)
|
||||||
{
|
{
|
||||||
|
@ -638,11 +638,11 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
if (m_nettype == cryptonote::TESTNET)
|
if (m_nettype == cryptonote::TESTNET)
|
||||||
{
|
{
|
||||||
return get_seed_nodes(cryptonote::TESTNET);
|
return get_ip_seed_nodes();
|
||||||
}
|
}
|
||||||
if (m_nettype == cryptonote::STAGENET)
|
if (m_nettype == cryptonote::STAGENET)
|
||||||
{
|
{
|
||||||
return get_seed_nodes(cryptonote::STAGENET);
|
return get_ip_seed_nodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> full_addrs;
|
std::set<std::string> full_addrs;
|
||||||
|
@ -730,7 +730,7 @@ namespace nodetool
|
||||||
else
|
else
|
||||||
MINFO("Not enough DNS seed nodes found, using fallback defaults too");
|
MINFO("Not enough DNS seed nodes found, using fallback defaults too");
|
||||||
|
|
||||||
for (const auto &peer: get_seed_nodes(cryptonote::MAINNET))
|
for (const auto &peer: get_ip_seed_nodes())
|
||||||
full_addrs.insert(peer);
|
full_addrs.insert(peer);
|
||||||
m_fallback_seed_nodes_added.test_and_set();
|
m_fallback_seed_nodes_added.test_and_set();
|
||||||
}
|
}
|
||||||
|
@ -739,6 +739,23 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
|
std::set<std::string> node_server<t_payload_net_handler>::get_seed_nodes(epee::net_utils::zone zone)
|
||||||
|
{
|
||||||
|
switch (zone)
|
||||||
|
{
|
||||||
|
case epee::net_utils::zone::public_:
|
||||||
|
return get_dns_seed_nodes();
|
||||||
|
case epee::net_utils::zone::tor:
|
||||||
|
return {};
|
||||||
|
case epee::net_utils::zone::i2p:
|
||||||
|
return {};
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw std::logic_error{"Bad zone given to get_seed_nodes"};
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
typename node_server<t_payload_net_handler>::network_zone& node_server<t_payload_net_handler>::add_zone(const epee::net_utils::zone zone)
|
typename node_server<t_payload_net_handler>::network_zone& node_server<t_payload_net_handler>::add_zone(const epee::net_utils::zone zone)
|
||||||
{
|
{
|
||||||
const auto zone_ = m_network_zones.lower_bound(zone);
|
const auto zone_ = m_network_zones.lower_bound(zone);
|
||||||
|
@ -1541,56 +1558,59 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::connect_to_seed()
|
bool node_server<t_payload_net_handler>::connect_to_seed(epee::net_utils::zone zone)
|
||||||
{
|
{
|
||||||
boost::upgrade_lock<boost::shared_mutex> seed_nodes_upgrade_lock(m_seed_nodes_lock);
|
network_zone& server = m_network_zones.at(zone);
|
||||||
|
boost::upgrade_lock<boost::shared_mutex> seed_nodes_upgrade_lock(server.m_seed_nodes_lock);
|
||||||
|
|
||||||
if (!m_seed_nodes_initialized)
|
if (!server.m_seed_nodes_initialized)
|
||||||
{
|
{
|
||||||
|
const std::uint16_t default_port = cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT;
|
||||||
boost::upgrade_to_unique_lock<boost::shared_mutex> seed_nodes_lock(seed_nodes_upgrade_lock);
|
boost::upgrade_to_unique_lock<boost::shared_mutex> seed_nodes_lock(seed_nodes_upgrade_lock);
|
||||||
m_seed_nodes_initialized = true;
|
server.m_seed_nodes_initialized = true;
|
||||||
for (const auto& full_addr : get_seed_nodes())
|
for (const auto& full_addr : get_seed_nodes(zone))
|
||||||
{
|
{
|
||||||
|
// seeds should have hostname converted to IP already
|
||||||
MDEBUG("Seed node: " << full_addr);
|
MDEBUG("Seed node: " << full_addr);
|
||||||
append_net_address(m_seed_nodes, full_addr, cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT);
|
server.m_seed_nodes.push_back(MONERO_UNWRAP(net::get_network_address(full_addr, default_port)));
|
||||||
}
|
}
|
||||||
MDEBUG("Number of seed nodes: " << m_seed_nodes.size());
|
MDEBUG("Number of seed nodes: " << server.m_seed_nodes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_seed_nodes.empty() || m_offline || !m_exclusive_peers.empty())
|
if (server.m_seed_nodes.empty() || m_offline || !m_exclusive_peers.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
size_t try_count = 0;
|
size_t try_count = 0;
|
||||||
bool is_connected_to_at_least_one_seed_node = false;
|
bool is_connected_to_at_least_one_seed_node = false;
|
||||||
size_t current_index = crypto::rand_idx(m_seed_nodes.size());
|
size_t current_index = crypto::rand_idx(server.m_seed_nodes.size());
|
||||||
const net_server& server = m_network_zones.at(epee::net_utils::zone::public_).m_net_server;
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(server.is_stop_signal_sent())
|
if(server.m_net_server.is_stop_signal_sent())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
peerlist_entry pe_seed{};
|
peerlist_entry pe_seed{};
|
||||||
pe_seed.adr = m_seed_nodes[current_index];
|
pe_seed.adr = server.m_seed_nodes[current_index];
|
||||||
if (is_peer_used(pe_seed))
|
if (is_peer_used(pe_seed))
|
||||||
is_connected_to_at_least_one_seed_node = true;
|
is_connected_to_at_least_one_seed_node = true;
|
||||||
else if (try_to_connect_and_handshake_with_new_peer(m_seed_nodes[current_index], true))
|
else if (try_to_connect_and_handshake_with_new_peer(server.m_seed_nodes[current_index], true))
|
||||||
break;
|
break;
|
||||||
if(++try_count > m_seed_nodes.size())
|
if(++try_count > server.m_seed_nodes.size())
|
||||||
{
|
{
|
||||||
if (!m_fallback_seed_nodes_added.test_and_set())
|
// only IP zone has fallback (to direct IP) seeds
|
||||||
|
if (zone == epee::net_utils::zone::public_ && !m_fallback_seed_nodes_added.test_and_set())
|
||||||
{
|
{
|
||||||
MWARNING("Failed to connect to any of seed peers, trying fallback seeds");
|
MWARNING("Failed to connect to any of seed peers, trying fallback seeds");
|
||||||
current_index = m_seed_nodes.size() - 1;
|
current_index = server.m_seed_nodes.size() - 1;
|
||||||
{
|
{
|
||||||
boost::upgrade_to_unique_lock<boost::shared_mutex> seed_nodes_lock(seed_nodes_upgrade_lock);
|
boost::upgrade_to_unique_lock<boost::shared_mutex> seed_nodes_lock(seed_nodes_upgrade_lock);
|
||||||
|
|
||||||
for (const auto &peer: get_seed_nodes(m_nettype))
|
for (const auto &peer: get_ip_seed_nodes())
|
||||||
{
|
{
|
||||||
MDEBUG("Fallback seed node: " << peer);
|
MDEBUG("Fallback seed node: " << peer);
|
||||||
append_net_address(m_seed_nodes, peer, cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT);
|
append_net_address(server.m_seed_nodes, peer, cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (current_index == m_seed_nodes.size() - 1)
|
if (current_index == server.m_seed_nodes.size() - 1)
|
||||||
{
|
{
|
||||||
MWARNING("No fallback seeds, continuing without seeds");
|
MWARNING("No fallback seeds, continuing without seeds");
|
||||||
break;
|
break;
|
||||||
|
@ -1604,7 +1624,7 @@ namespace nodetool
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(++current_index >= m_seed_nodes.size())
|
if(++current_index >= server.m_seed_nodes.size())
|
||||||
current_index = 0;
|
current_index = 0;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1620,20 +1640,21 @@ namespace nodetool
|
||||||
|
|
||||||
if (!m_exclusive_peers.empty()) return true;
|
if (!m_exclusive_peers.empty()) return true;
|
||||||
|
|
||||||
// Only have seeds in the public zone right now.
|
bool one_succeeded = false;
|
||||||
|
|
||||||
size_t start_conn_count = get_public_outgoing_connections_count();
|
|
||||||
if(!get_public_white_peers_count() && !connect_to_seed())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!connect_to_peerlist(m_priority_peers)) return false;
|
|
||||||
|
|
||||||
for(auto& zone : m_network_zones)
|
for(auto& zone : m_network_zones)
|
||||||
{
|
{
|
||||||
|
size_t start_conn_count = get_outgoing_connections_count(zone.second);
|
||||||
|
if(!zone.second.m_peerlist.get_white_peers_count() && !connect_to_seed(zone.first))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zone.first == zone_type::public_ && !connect_to_peerlist(m_priority_peers)) continue;
|
||||||
|
|
||||||
size_t base_expected_white_connections = (zone.second.m_config.m_net_config.max_out_connection_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
|
size_t base_expected_white_connections = (zone.second.m_config.m_net_config.max_out_connection_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
|
||||||
|
|
||||||
|
// carefully avoid `continue` in nested loop
|
||||||
|
|
||||||
size_t conn_count = get_outgoing_connections_count(zone.second);
|
size_t conn_count = get_outgoing_connections_count(zone.second);
|
||||||
while(conn_count < zone.second.m_config.m_net_config.max_out_connection_count)
|
while(conn_count < zone.second.m_config.m_net_config.max_out_connection_count)
|
||||||
{
|
{
|
||||||
|
@ -1670,16 +1691,17 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
conn_count = new_conn_count;
|
conn_count = new_conn_count;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (start_conn_count == get_public_outgoing_connections_count() && start_conn_count < m_network_zones.at(zone_type::public_).m_config.m_net_config.max_out_connection_count)
|
if (start_conn_count == get_outgoing_connections_count(zone.second) && start_conn_count < zone.second.m_config.m_net_config.max_out_connection_count)
|
||||||
{
|
{
|
||||||
MINFO("Failed to connect to any, trying seeds");
|
MINFO("Failed to connect to any, trying seeds");
|
||||||
if (!connect_to_seed())
|
if (!connect_to_seed(zone.first))
|
||||||
return false;
|
continue;
|
||||||
|
}
|
||||||
|
one_succeeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return one_succeeded;
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
|
|
Loading…
Reference in New Issue