mirror of
https://github.com/monero-project/monero.git
synced 2025-11-27 20:10:25 -05:00
allow blocking whole subnets
This commit is contained in:
parent
515ac2951d
commit
65c4004963
19 changed files with 413 additions and 34 deletions
|
|
@ -248,7 +248,11 @@ namespace nodetool
|
|||
void change_max_in_public_peers(size_t count);
|
||||
virtual bool block_host(const epee::net_utils::network_address &adress, time_t seconds = P2P_IP_BLOCKTIME);
|
||||
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 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<epee::net_utils::network_address, time_t> get_blocked_hosts() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_hosts; }
|
||||
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_subnets; }
|
||||
|
||||
virtual void add_used_stripe_peer(const typename t_payload_net_handler::connection_context &context);
|
||||
virtual void remove_used_stripe_peer(const typename t_payload_net_handler::connection_context &context);
|
||||
|
|
@ -319,7 +323,7 @@ namespace nodetool
|
|||
virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f);
|
||||
virtual bool add_host_fail(const epee::net_utils::network_address &address);
|
||||
//----------------- i_connection_filter --------------------------------------------------------
|
||||
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address);
|
||||
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address, time_t *t = NULL);
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool parse_peer_from_string(epee::net_utils::network_address& pe, const std::string& node_addr, uint16_t default_port = 0);
|
||||
bool handle_command_line(
|
||||
|
|
@ -461,8 +465,9 @@ namespace nodetool
|
|||
std::map<epee::net_utils::network_address, time_t> m_conn_fails_cache;
|
||||
epee::critical_section m_conn_fails_cache_lock;
|
||||
|
||||
epee::critical_section m_blocked_hosts_lock;
|
||||
epee::critical_section m_blocked_hosts_lock; // for both hosts and subnets
|
||||
std::map<epee::net_utils::network_address, time_t> m_blocked_hosts;
|
||||
std::map<epee::net_utils::ipv4_network_subnet, time_t> m_blocked_subnets;
|
||||
|
||||
epee::critical_section m_host_fails_score_lock;
|
||||
std::map<std::string, uint64_t> m_host_fails_score;
|
||||
|
|
|
|||
|
|
@ -155,19 +155,55 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_remote_host_allowed(const epee::net_utils::network_address &address)
|
||||
bool node_server<t_payload_net_handler>::is_remote_host_allowed(const epee::net_utils::network_address &address, time_t *t)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
|
||||
|
||||
const time_t now = time(nullptr);
|
||||
|
||||
// look in the hosts list
|
||||
auto it = m_blocked_hosts.find(address);
|
||||
if(it == m_blocked_hosts.end())
|
||||
return true;
|
||||
if(time(nullptr) >= it->second)
|
||||
if (it != m_blocked_hosts.end())
|
||||
{
|
||||
m_blocked_hosts.erase(it);
|
||||
MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
|
||||
return true;
|
||||
if (now >= it->second)
|
||||
{
|
||||
m_blocked_hosts.erase(it);
|
||||
MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
|
||||
it = m_blocked_hosts.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t)
|
||||
*t = it->second - now;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
// manually loop in subnets
|
||||
if (address.get_type_id() == epee::net_utils::address_type::ipv4)
|
||||
{
|
||||
auto ipv4_address = address.template as<epee::net_utils::ipv4_network_address>();
|
||||
std::map<epee::net_utils::ipv4_network_subnet, time_t>::iterator it;
|
||||
for (it = m_blocked_subnets.begin(); it != m_blocked_subnets.end(); )
|
||||
{
|
||||
if (now >= it->second)
|
||||
{
|
||||
it = m_blocked_subnets.erase(it);
|
||||
MCLOG_CYAN(el::Level::Info, "global", "Subnet " << it->first.host_str() << " unblocked.");
|
||||
continue;
|
||||
}
|
||||
if (it->first.matches(ipv4_address))
|
||||
{
|
||||
if (t)
|
||||
*t = it->second - now;
|
||||
return false;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// not found in hosts or subnets, allowed
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
|
|
@ -223,6 +259,58 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::block_subnet(const epee::net_utils::ipv4_network_subnet &subnet, time_t seconds)
|
||||
{
|
||||
const time_t now = time(nullptr);
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
|
||||
time_t limit;
|
||||
if (now > std::numeric_limits<time_t>::max() - seconds)
|
||||
limit = std::numeric_limits<time_t>::max();
|
||||
else
|
||||
limit = now + seconds;
|
||||
m_blocked_subnets[subnet] = limit;
|
||||
|
||||
// drop any connection to that subnet. This should only have to look into
|
||||
// the zone related to the connection, but really make sure everything is
|
||||
// swept ...
|
||||
std::vector<boost::uuids::uuid> conns;
|
||||
for(auto& zone : m_network_zones)
|
||||
{
|
||||
zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
|
||||
{
|
||||
if (cntxt.m_remote_address.get_type_id() != epee::net_utils::ipv4_network_address::get_type_id())
|
||||
return true;
|
||||
auto ipv4_address = cntxt.m_remote_address.template as<epee::net_utils::ipv4_network_address>();
|
||||
if (subnet.matches(ipv4_address))
|
||||
{
|
||||
conns.push_back(cntxt.m_connection_id);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
for (const auto &c: conns)
|
||||
zone.second.m_net_server.get_config_object().close(c);
|
||||
|
||||
conns.clear();
|
||||
}
|
||||
|
||||
MCLOG_CYAN(el::Level::Info, "global", "Subnet " << subnet.host_str() << " blocked.");
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::unblock_subnet(const epee::net_utils::ipv4_network_subnet &subnet)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
|
||||
auto i = m_blocked_subnets.find(subnet);
|
||||
if (i == m_blocked_subnets.end())
|
||||
return false;
|
||||
m_blocked_subnets.erase(i);
|
||||
MCLOG_CYAN(el::Level::Info, "global", "Subnet " << subnet.host_str() << " unblocked.");
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::add_host_fail(const epee::net_utils::network_address &address)
|
||||
{
|
||||
if(!address.is_blockable())
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ namespace nodetool
|
|||
virtual bool block_host(const epee::net_utils::network_address &address, time_t seconds = 0)=0;
|
||||
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
|
||||
virtual std::map<epee::net_utils::network_address, time_t> get_blocked_hosts()=0;
|
||||
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()=0;
|
||||
virtual bool add_host_fail(const epee::net_utils::network_address &address)=0;
|
||||
virtual void add_used_stripe_peer(const t_connection_context &context)=0;
|
||||
virtual void remove_used_stripe_peer(const t_connection_context &context)=0;
|
||||
|
|
@ -116,6 +117,10 @@ namespace nodetool
|
|||
{
|
||||
return std::map<epee::net_utils::network_address, time_t>();
|
||||
}
|
||||
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()
|
||||
{
|
||||
return std::map<epee::net_utils::ipv4_network_subnet, time_t>();
|
||||
}
|
||||
virtual bool add_host_fail(const epee::net_utils::network_address &address)
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue