diff options
author | luigi1111 <luigi1111w@gmail.com> | 2020-11-06 17:15:11 -0600 |
---|---|---|
committer | luigi1111 <luigi1111w@gmail.com> | 2020-11-06 17:15:11 -0600 |
commit | 4191dc8981d5e5546bc9d1b141839f76f5c5ccad (patch) | |
tree | 6a129e239ccf52a105598888e8706a0efe23a020 | |
parent | Merge pull request #6985 (diff) | |
parent | Add support for i2p and tor seed nodes (diff) | |
download | monero-4191dc8981d5e5546bc9d1b141839f76f5c5ccad.tar.xz |
Merge pull request #6990
263579b Add support for i2p and tor seed nodes (vtnerd)
-rw-r--r-- | src/p2p/net_node.h | 23 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 114 |
2 files changed, 83 insertions, 54 deletions
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 7204ce66b..87fec9994 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -164,6 +164,7 @@ namespace nodetool network_zone() : m_connect(nullptr), m_net_server(epee::net_utils::e_connection_type_P2P), + m_seed_nodes(), m_bind_ip(), m_bind_ipv6_address(), m_port(), @@ -175,7 +176,9 @@ namespace nodetool m_proxy_address(), m_current_number_of_out_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(); } @@ -183,6 +186,7 @@ namespace nodetool network_zone(boost::asio::io_service& public_service) : m_connect(nullptr), m_net_server(public_service, epee::net_utils::e_connection_type_P2P), + m_seed_nodes(), m_bind_ip(), m_bind_ipv6_address(), m_port(), @@ -194,13 +198,16 @@ namespace nodetool m_proxy_address(), m_current_number_of_out_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(); } connect_func* m_connect; net_server m_net_server; + std::vector<epee::net_utils::network_address> m_seed_nodes; std::string m_bind_ip; std::string m_bind_ipv6_address; std::string m_port; @@ -212,7 +219,9 @@ namespace nodetool 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_in_peers; + boost::shared_mutex m_seed_nodes_lock; bool m_can_pingback; + bool m_seed_nodes_initialized; private: void set_config_defaults() noexcept @@ -383,9 +392,10 @@ namespace nodetool 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_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_seed_nodes(); - bool connect_to_seed(); + std::set<std::string> get_ip_seed_nodes() const; + std::set<std::string> get_dns_seed_nodes(); + std::set<std::string> get_seed_nodes(epee::net_utils::zone); + bool connect_to_seed(epee::net_utils::zone); template <class Container> bool connect_to_peerlist(const Container& peers); @@ -467,9 +477,6 @@ namespace nodetool 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_seed_nodes; - bool m_seed_nodes_initialized = false; - boost::shared_mutex m_seed_nodes_lock; std::atomic_flag m_fallback_seed_nodes_added; std::vector<nodetool::peerlist_entry> m_command_line_peers; uint64_t m_peer_livetime; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index bb57ef410..1eb32a087 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -451,9 +451,9 @@ namespace nodetool 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; } @@ -644,21 +644,21 @@ namespace nodetool //----------------------------------------------------------------------------------- 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; - if (nettype == cryptonote::TESTNET) + if (m_nettype == cryptonote::TESTNET) { full_addrs.insert("212.83.175.67:28080"); full_addrs.insert("212.83.172.165: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("192.110.160.146:38080"); } - else if (nettype == cryptonote::FAKECHAIN) + else if (m_nettype == cryptonote::FAKECHAIN) { } else @@ -680,7 +680,7 @@ namespace nodetool } //----------------------------------------------------------------------------------- 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) { @@ -688,11 +688,11 @@ namespace nodetool } if (m_nettype == cryptonote::TESTNET) { - return get_seed_nodes(cryptonote::TESTNET); + return get_ip_seed_nodes(); } if (m_nettype == cryptonote::STAGENET) { - return get_seed_nodes(cryptonote::STAGENET); + return get_ip_seed_nodes(); } std::set<std::string> full_addrs; @@ -780,7 +780,7 @@ namespace nodetool else 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); m_fallback_seed_nodes_added.test_and_set(); } @@ -789,6 +789,23 @@ namespace nodetool } //----------------------------------------------------------------------------------- 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) { const auto zone_ = m_network_zones.lower_bound(zone); @@ -1640,56 +1657,59 @@ namespace nodetool } //----------------------------------------------------------------------------------- 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); - m_seed_nodes_initialized = true; - for (const auto& full_addr : get_seed_nodes()) + server.m_seed_nodes_initialized = true; + for (const auto& full_addr : get_seed_nodes(zone)) { + // seeds should have hostname converted to IP already 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; size_t try_count = 0; bool is_connected_to_at_least_one_seed_node = false; - size_t current_index = crypto::rand_idx(m_seed_nodes.size()); - const net_server& server = m_network_zones.at(epee::net_utils::zone::public_).m_net_server; + size_t current_index = crypto::rand_idx(server.m_seed_nodes.size()); while(true) { - if(server.is_stop_signal_sent()) + if(server.m_net_server.is_stop_signal_sent()) return false; 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)) 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; - 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"); - 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); - for (const auto &peer: get_seed_nodes(m_nettype)) + for (const auto &peer: get_ip_seed_nodes()) { 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"); break; @@ -1703,7 +1723,7 @@ namespace nodetool break; } } - if(++current_index >= m_seed_nodes.size()) + if(++current_index >= server.m_seed_nodes.size()) current_index = 0; } return true; @@ -1719,20 +1739,21 @@ namespace nodetool if (!m_exclusive_peers.empty()) return true; - // Only have seeds in the public zone right now. - - size_t start_conn_count = get_public_outgoing_connections_count(); - if(!get_public_white_peers_count() && !connect_to_seed()) + bool one_succeeded = false; + for(auto& zone : m_network_zones) { - return false; - } + 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 (!connect_to_peerlist(m_priority_peers)) return false; + if (zone.first == zone_type::public_ && !connect_to_peerlist(m_priority_peers)) continue; - for(auto& zone : m_network_zones) - { 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); while(conn_count < zone.second.m_config.m_net_config.max_out_connection_count) { @@ -1769,16 +1790,17 @@ namespace nodetool } 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) - { - MINFO("Failed to connect to any, trying seeds"); - if (!connect_to_seed()) - return false; + 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"); + if (!connect_to_seed(zone.first)) + continue; + } + one_succeeded = true; } - return true; + return one_succeeded; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> |