|
|
@ -155,20 +155,56 @@ namespace nodetool
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
template<class t_payload_net_handler>
|
|
|
|
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);
|
|
|
|
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
|
|
|
|
auto it = m_blocked_hosts.find(address.host_str());
|
|
|
|
|
|
|
|
if(it == m_blocked_hosts.end())
|
|
|
|
const time_t now = time(nullptr);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if(time(nullptr) >= it->second)
|
|
|
|
// look in the hosts list
|
|
|
|
|
|
|
|
auto it = m_blocked_hosts.find(address);
|
|
|
|
|
|
|
|
if (it != m_blocked_hosts.end())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (now >= it->second)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_blocked_hosts.erase(it);
|
|
|
|
m_blocked_hosts.erase(it);
|
|
|
|
MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
|
|
|
|
MCLOG_CYAN(el::Level::Info, "global", "Host " << address.host_str() << " unblocked.");
|
|
|
|
return true;
|
|
|
|
it = m_blocked_hosts.end();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (t)
|
|
|
|
|
|
|
|
*t = it->second - now;
|
|
|
|
|
|
|
|
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;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++it;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// not found in hosts or subnets, allowed
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
template<class t_payload_net_handler>
|
|
|
|
template<class t_payload_net_handler>
|
|
|
|
bool node_server<t_payload_net_handler>::block_host(const epee::net_utils::network_address &addr, time_t seconds)
|
|
|
|
bool node_server<t_payload_net_handler>::block_host(const epee::net_utils::network_address &addr, time_t seconds)
|
|
|
@ -184,7 +220,7 @@ namespace nodetool
|
|
|
|
limit = std::numeric_limits<time_t>::max();
|
|
|
|
limit = std::numeric_limits<time_t>::max();
|
|
|
|
else
|
|
|
|
else
|
|
|
|
limit = now + seconds;
|
|
|
|
limit = now + seconds;
|
|
|
|
m_blocked_hosts[addr.host_str()] = limit;
|
|
|
|
m_blocked_hosts[addr] = limit;
|
|
|
|
|
|
|
|
|
|
|
|
// drop any connection to that address. This should only have to look into
|
|
|
|
// 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
|
|
|
|
// the zone related to the connection, but really make sure everything is
|
|
|
@ -214,7 +250,7 @@ namespace nodetool
|
|
|
|
bool node_server<t_payload_net_handler>::unblock_host(const epee::net_utils::network_address &address)
|
|
|
|
bool node_server<t_payload_net_handler>::unblock_host(const epee::net_utils::network_address &address)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
|
|
|
|
CRITICAL_REGION_LOCAL(m_blocked_hosts_lock);
|
|
|
|
auto i = m_blocked_hosts.find(address.host_str());
|
|
|
|
auto i = m_blocked_hosts.find(address);
|
|
|
|
if (i == m_blocked_hosts.end())
|
|
|
|
if (i == m_blocked_hosts.end())
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
m_blocked_hosts.erase(i);
|
|
|
|
m_blocked_hosts.erase(i);
|
|
|
@ -223,6 +259,58 @@ namespace nodetool
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
template<class t_payload_net_handler>
|
|
|
|
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)
|
|
|
|
bool node_server<t_payload_net_handler>::add_host_fail(const epee::net_utils::network_address &address)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(!address.is_blockable())
|
|
|
|
if(!address.is_blockable())
|
|
|
|