diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 0718b9abe..166b560db 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -240,8 +240,8 @@ t_command_server::t_command_server(
m_command_lookup.set_handler(
"unban"
, std::bind(&t_command_parser_executor::unban, &m_parser, p::_1)
- , "unban
"
- , "Unban a given ."
+ , "unban |all"
+ , "Unban a given , or all banned addresses."
);
m_command_lookup.set_handler(
"banned"
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 3ae8f0a24..ad49db3e2 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -281,6 +281,7 @@ namespace nodetool
virtual bool unblock_host(const epee::net_utils::network_address &address);
virtual bool block_subnet(const epee::net_utils::ipv4_network_subnet &subnet, time_t seconds = P2P_IP_BLOCKTIME);
virtual bool unblock_subnet(const epee::net_utils::ipv4_network_subnet &subnet);
+ virtual bool clear_bans();
virtual bool is_host_blocked(const epee::net_utils::network_address &address, time_t *seconds) { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return !is_remote_host_allowed(address, seconds); }
virtual std::map get_blocked_hosts() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_hosts; }
virtual std::map get_blocked_subnets() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_subnets; }
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index f989ef75b..4ddaee7db 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -520,6 +520,18 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template
+ bool node_server::clear_bans()
+ {
+ CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
+ const bool had_bans = !m_blocked_hosts.empty() || !m_blocked_subnets.empty();
+ m_blocked_hosts.clear();
+ m_blocked_subnets.clear();
+ if (had_bans)
+ MCLOG_CYAN(el::Level::Info, "global", "All bans cleared.");
+ return had_bans;
+ }
+ //-----------------------------------------------------------------------------------
+ template
bool node_server::add_host_fail(const epee::net_utils::network_address &address, unsigned int score)
{
if(!address.is_blockable())
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 935a4fa51..1c7f9bae5 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -2419,6 +2419,12 @@ namespace cryptonote
{
epee::net_utils::network_address na;
+ if (!i->ban && i->host == "all")
+ {
+ m_p2p.clear_bans();
+ continue;
+ }
+
// try subnet first
if (!i->host.empty())
{
diff --git a/tests/functional_tests/bans.py b/tests/functional_tests/bans.py
index 1f9a5bb9c..94e329306 100755
--- a/tests/functional_tests/bans.py
+++ b/tests/functional_tests/bans.py
@@ -112,6 +112,16 @@ class BanTest():
res = daemon.get_bans()
assert 'bans' not in res or len(res.bans) == 0
+ daemon.set_bans([
+ {'host': '1.2.3.4', 'ban': True, 'seconds': 100},
+ {'host': '5.6.7.0/24', 'ban': True, 'seconds': 100},
+ ])
+ res = daemon.get_bans()
+ assert len(res.bans) == 2
+ daemon.set_bans([{'host': 'all', 'ban': False}])
+ res = daemon.get_bans()
+ assert 'bans' not in res or len(res.bans) == 0
+
if __name__ == '__main__':
BanTest().run_test()
diff --git a/tests/unit_tests/node_server.cpp b/tests/unit_tests/node_server.cpp
index a464b837d..25906f8dc 100644
--- a/tests/unit_tests/node_server.cpp
+++ b/tests/unit_tests/node_server.cpp
@@ -491,6 +491,22 @@ TEST(ban, limit)
ASSERT_TRUE(is_blocked(server,MAKE_IPV4_ADDRESS(1,2,3,4)));
}
+TEST(ban, clear)
+{
+ test_core pr_core;
+ cryptonote::t_cryptonote_protocol_handler cprotocol(pr_core, NULL);
+ Server server(cprotocol);
+ cprotocol.set_p2p_endpoint(&server);
+
+ ASSERT_FALSE(server.clear_bans());
+ ASSERT_TRUE(server.block_host(MAKE_IPV4_ADDRESS(1,2,3,4)));
+ ASSERT_TRUE(server.block_subnet(MAKE_IPV4_SUBNET(5,6,7,0,24)));
+ ASSERT_TRUE(server.clear_bans());
+ ASSERT_TRUE(server.get_blocked_hosts().empty());
+ ASSERT_TRUE(server.get_blocked_subnets().empty());
+ ASSERT_FALSE(server.clear_bans());
+}
+
TEST(ban, subnet)
{
time_t seconds;