From c1c9eeaaf720dd1309220e2d461677b99a42f91e Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 17 Mar 2017 23:39:47 +0000 Subject: [PATCH] p2p: use the fallback seed IPs when not enough seeds are found In case the DNS seed(s) is/are down, which would otherwise cause the fallback seeds to never be used. Also if the seeds resolve to too few IPs. --- src/p2p/net_node.h | 4 +- src/p2p/net_node.inl | 87 +++++++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index de0cf2c03..4582a3236 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -191,7 +191,6 @@ namespace nodetool bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr); bool handle_command_line( const boost::program_options::variables_map& vm - , bool testnet ); bool idle_worker(); bool handle_remote_peerlist(const std::list& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context); @@ -218,6 +217,7 @@ namespace nodetool void cache_connect_fail_info(const net_address& addr); bool is_addr_recently_failed(const net_address& addr); bool is_priority_node(const net_address& na); + std::set get_seed_nodes(bool testnet) const; template bool connect_to_peerlist(const Container& peers); @@ -321,6 +321,8 @@ namespace nodetool epee::critical_section m_ip_fails_score_lock; std::map m_ip_fails_score; + + bool m_testnet; }; } diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 99c4e9282..2e2dffab8 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -65,6 +65,7 @@ #define NET_MAKE_IP(b1,b2,b3,b4) ((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4)))) +#define MIN_WANTED_SEED_NODES 12 namespace nodetool { @@ -287,10 +288,9 @@ namespace nodetool template bool node_server::handle_command_line( const boost::program_options::variables_map& vm - , bool testnet ) { - auto p2p_bind_arg = testnet ? arg_testnet_p2p_bind_port : arg_p2p_bind_port; + auto p2p_bind_arg = m_testnet ? arg_testnet_p2p_bind_port : arg_p2p_bind_port; m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip); m_port = command_line::get_arg(vm, p2p_bind_arg); @@ -309,7 +309,7 @@ namespace nodetool bool r = parse_peer_from_string(pe.adr, pr_str); CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str); if (pe.adr.port == 0) - pe.adr.port = testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT; + pe.adr.port = m_testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT; m_command_line_peers.push_back(pe); } } @@ -398,14 +398,11 @@ namespace nodetool //----------------------------------------------------------------------------------- template - bool node_server::init(const boost::program_options::variables_map& vm) + std::set node_server::get_seed_nodes(bool testnet) const { std::set full_addrs; - bool testnet = command_line::get_arg(vm, command_line::arg_testnet_on); - if (testnet) { - memcpy(&m_network_id, &::config::testnet::NETWORK_ID, 16); full_addrs.insert("212.83.175.67:28080"); full_addrs.insert("5.9.100.248:28080"); full_addrs.insert("163.172.182.165:28080"); @@ -413,6 +410,32 @@ namespace nodetool full_addrs.insert("212.83.172.165:28080"); } else + { + full_addrs.insert("107.152.130.98:18080"); + full_addrs.insert("212.83.175.67:18080"); + full_addrs.insert("5.9.100.248:18080"); + full_addrs.insert("163.172.182.165:18080"); + full_addrs.insert("161.67.132.39:18080"); + full_addrs.insert("198.74.231.92:18080"); + full_addrs.insert("195.154.123.123:28080"); + full_addrs.insert("212.83.172.165:28080"); + } + return full_addrs; + } + + //----------------------------------------------------------------------------------- + template + bool node_server::init(const boost::program_options::variables_map& vm) + { + std::set full_addrs; + m_testnet = command_line::get_arg(vm, command_line::arg_testnet_on); + + if (m_testnet) + { + memcpy(&m_network_id, &::config::testnet::NETWORK_ID, 16); + full_addrs = get_seed_nodes(true); + } + else { memcpy(&m_network_id, &::config::NETWORK_ID, 16); // for each hostname in the seed nodes list, attempt to DNS resolve and @@ -483,18 +506,16 @@ namespace nodetool ++i; } - if (!full_addrs.size()) + // append the fallback nodes if we have too few seed nodes to start with + if (full_addrs.size() < MIN_WANTED_SEED_NODES) { - MINFO("DNS seed node lookup either timed out or failed, falling back to defaults"); - - full_addrs.insert("107.152.130.98:18080"); - full_addrs.insert("212.83.175.67:18080"); - full_addrs.insert("5.9.100.248:18080"); - full_addrs.insert("163.172.182.165:18080"); - full_addrs.insert("161.67.132.39:18080"); - full_addrs.insert("198.74.231.92:18080"); - full_addrs.insert("195.154.123.123:28080"); - full_addrs.insert("212.83.172.165:28080"); + if (full_addrs.empty()) + MINFO("DNS seed node lookup either timed out or failed, falling back to defaults"); + else + MINFO("Not enough DNS seed nodes found, using fallback defaults too"); + + for (const auto &peer: get_seed_nodes(false)) + full_addrs.insert(peer); } } @@ -505,14 +526,14 @@ namespace nodetool } MDEBUG("Number of seed nodes: " << m_seed_nodes.size()); - bool res = handle_command_line(vm, testnet); + bool res = handle_command_line(vm); CHECK_AND_ASSERT_MES(res, false, "Failed to handle command line"); - auto config_arg = testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; + auto config_arg = m_testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir; m_config_folder = command_line::get_arg(vm, config_arg); - if ((!testnet && m_port != std::to_string(::config::P2P_DEFAULT_PORT)) - || (testnet && m_port != std::to_string(::config::testnet::P2P_DEFAULT_PORT))) { + if ((!m_testnet && m_port != std::to_string(::config::P2P_DEFAULT_PORT)) + || (m_testnet && m_port != std::to_string(::config::testnet::P2P_DEFAULT_PORT))) { m_config_folder = m_config_folder + "/" + m_port; } @@ -1082,6 +1103,7 @@ namespace nodetool { size_t try_count = 0; size_t current_index = crypto::rand()%m_seed_nodes.size(); + bool fallback_nodes_added = false; while(true) { if(m_net_server.is_stop_signal_sent()) @@ -1091,8 +1113,22 @@ namespace nodetool break; if(++try_count > m_seed_nodes.size()) { - MWARNING("Failed to connect to any of seed peers, continuing without seeds"); - break; + if (!fallback_nodes_added) + { + MWARNING("Failed to connect to any of seed peers, trying fallback seeds"); + for (const auto &peer: get_seed_nodes(m_testnet)) + { + MDEBUG("Fallback seed node: " << peer); + append_net_address(m_seed_nodes, peer); + } + fallback_nodes_added = true; + // continue for another few cycles + } + else + { + MWARNING("Failed to connect to any of seed peers, continuing without seeds"); + break; + } } if(++current_index >= m_seed_nodes.size()) current_index = 0; @@ -1654,7 +1690,6 @@ namespace nodetool bool node_server::parse_peers_and_add_to_container(const boost::program_options::variables_map& vm, const command_line::arg_descriptor > & arg, Container& container) { std::vector perrs = command_line::get_arg(vm, arg); - bool testnet = command_line::get_arg(vm, command_line::arg_testnet_on); for(const std::string& pr_str: perrs) { @@ -1662,7 +1697,7 @@ namespace nodetool bool r = parse_peer_from_string(na, pr_str); CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str); if (na.port == 0) - na.port = testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT; + na.port = m_testnet ? ::config::testnet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT; container.push_back(na); }