diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index f0aef384f..0c89c8f4b 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -176,8 +176,15 @@ namespace nodetool if(!addr.is_blockable()) return false; + const time_t now = time(nullptr); + CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); - m_blocked_hosts[addr.host_str()] = time(nullptr) + seconds; + time_t limit; + if (now > std::numeric_limits::max() - seconds) + limit = std::numeric_limits::max(); + else + limit = now + seconds; + m_blocked_hosts[addr.host_str()] = limit; // drop any connection to that address. This should only have to look into // the zone related to the connection, but really make sure everything is diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp index eb1ee8932..c8ce19ba4 100644 --- a/tests/unit_tests/ban.cpp +++ b/tests/unit_tests/ban.cpp @@ -93,18 +93,7 @@ typedef nodetool::node_server hosts = server.get_blocked_hosts(); - for (auto rec: hosts) - { - if (rec.first == host) - { - if (t) - *t = rec.second; - return true; - } - } - return false; + return server.is_host_blocked(address.host_str(), t); } TEST(ban, add) @@ -192,5 +181,21 @@ TEST(ban, add) ASSERT_TRUE(t >= 4); } +TEST(ban, limit) +{ + test_core pr_core; + cryptonote::t_cryptonote_protocol_handler cprotocol(pr_core, NULL); + Server server(cprotocol); + cprotocol.set_p2p_endpoint(&server); + + // starts empty + ASSERT_TRUE(server.get_blocked_hosts().empty()); + ASSERT_FALSE(is_blocked(server,MAKE_IPV4_ADDRESS(1,2,3,4))); + ASSERT_TRUE(server.block_host(MAKE_IPV4_ADDRESS(1,2,3,4), std::numeric_limits::max() - 1)); + ASSERT_TRUE(is_blocked(server,MAKE_IPV4_ADDRESS(1,2,3,4))); + ASSERT_TRUE(server.block_host(MAKE_IPV4_ADDRESS(1,2,3,4), 1)); + ASSERT_TRUE(is_blocked(server,MAKE_IPV4_ADDRESS(1,2,3,4))); +} + namespace nodetool { template class node_server>; } namespace cryptonote { template class t_cryptonote_protocol_handler; }