diff options
Diffstat (limited to 'src/p2p/net_node.inl')
-rw-r--r-- | src/p2p/net_node.inl | 107 |
1 files changed, 104 insertions, 3 deletions
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index c68dae446..0e43d9579 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -208,7 +208,7 @@ namespace nodetool if(time(nullptr) >= it->second) { m_blocked_ips.erase(it); - MLOG_CYAN(el::Level::Info, "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); + MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); return true; } return false; @@ -246,7 +246,7 @@ namespace nodetool for (const auto &c: conns) m_net_server.get_config_object().close(c); - MLOG_CYAN(el::Level::Info, "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " blocked."); + MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " blocked."); return true; } //----------------------------------------------------------------------------------- @@ -258,7 +258,7 @@ namespace nodetool if (i == m_blocked_ips.end()) return false; m_blocked_ips.erase(i); - MLOG_CYAN(el::Level::Info, "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); + MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); return true; } //----------------------------------------------------------------------------------- @@ -935,6 +935,50 @@ namespace nodetool return true; } + template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::check_connection_and_handshake_with_peer(const net_address& na, uint64_t last_seen_stamp) + { + LOG_PRINT_L1("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":" + << epee::string_tools::num_to_string_fast(na.port) << "(last_seen: " + << (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never") + << ")..."); + + typename net_server::t_connection_context con = AUTO_VAL_INIT(con); + bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(na.ip), + epee::string_tools::num_to_string_fast(na.port), + m_config.m_net_config.connection_timeout, + con); + + if (!res) { + bool is_priority = is_priority_node(na); + + LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to " + << epee::string_tools::get_ip_string_from_int32(na.ip) + << ":" << epee::string_tools::num_to_string_fast(na.port)); + + return false; + } + + peerid_type pi = AUTO_VAL_INIT(pi); + res = do_handshake_with_peer(pi, con, true); + + if (!res) { + bool is_priority = is_priority_node(na); + + LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer " + << epee::string_tools::get_ip_string_from_int32(na.ip) + << ":" << epee::string_tools::num_to_string_fast(na.port)); + + return false; + } + + m_net_server.get_config_object().close(con.m_connection_id); + + LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK AND CLOSED."); + + return true; + } + #undef LOG_PRINT_CC_PRIORITY_NODE //----------------------------------------------------------------------------------- @@ -1106,6 +1150,7 @@ namespace nodetool { m_peer_handshake_idle_maker_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::peer_sync_idle_maker, this)); m_connections_maker_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::connections_maker, this)); + m_gray_peerlist_housekeeping_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::gray_peerlist_housekeeping, this)); m_peerlist_store_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::store_config, this)); return true; } @@ -1465,6 +1510,14 @@ namespace nodetool drop_connection(context); return 1; } + + if(has_too_many_connections(context.m_remote_ip)) + { + LOG_PRINT_CCONTEXT_L1("CONNECTION FROM " << epee::string_tools::get_ip_string_from_int32(context.m_remote_ip) << " REFUSED, too many connections from the same address"); + drop_connection(context); + return 1; + } + //associate peer_id with this connection context.peer_id = arg.node_data.peer_id; @@ -1683,4 +1736,52 @@ namespace nodetool return true; } + + template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::has_too_many_connections(const uint32_t ip) + { + const uint8_t max_connections = 1; + uint8_t count = 0; + + m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + { + if (cntxt.m_is_income && cntxt.m_remote_ip == ip) { + count++; + + if (count > max_connections) { + return false; + } + } + + return true; + }); + + return count > max_connections; + } + + template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::gray_peerlist_housekeeping() + { + peerlist_entry pe = AUTO_VAL_INIT(pe); + + if (!m_peerlist.get_random_gray_peer(pe)) { + return false; + } + + bool success = check_connection_and_handshake_with_peer(pe.adr, pe.last_seen); + + if (!success) { + m_peerlist.remove_from_peer_gray(pe); + + LOG_PRINT_L2("PEER EVICTED FROM GRAY PEER LIST IP address: " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << " Peer ID: " << std::hex << pe.id); + + return true; + } + + m_peerlist.set_peer_just_seen(pe.id, pe.adr); + + LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << " Peer ID: " << std::hex << pe.id); + + return true; + } } |