aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_config.h2
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl37
-rw-r--r--src/p2p/net_node.cpp1
-rw-r--r--src/p2p/net_node.h7
-rw-r--r--src/p2p/net_node.inl60
-rw-r--r--src/p2p/net_node_common.h4
6 files changed, 87 insertions, 24 deletions
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index 21f2bf81e..97706f745 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -197,6 +197,8 @@
#define RPC_CREDITS_PER_HASH_SCALE ((float)(1<<24))
+#define DNS_BLOCKLIST_LIFETIME (86400 * 8)
+
// New constants are intended to go here
namespace config
{
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 2e0f67486..15734cf29 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -2298,30 +2298,16 @@ skip:
return true;
}
- // if we're still around, we might be at a point where the peer is pruned, so we could either
- // drop it to make space for other peers, or ask for a span further down the line
- const uint32_t next_stripe = get_next_needed_pruning_stripe().first;
- const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
- const uint32_t local_stripe = tools::get_pruning_stripe(m_core.get_blockchain_pruning_seed());
- if (!(m_sync_pruned_blocks && peer_stripe == local_stripe) && next_stripe && peer_stripe && next_stripe != peer_stripe)
+ // we can do nothing, so drop this peer to make room for others unless we think we've downloaded all we need
+ const uint64_t blockchain_height = m_core.get_current_blockchain_height();
+ if (std::max(blockchain_height, m_block_queue.get_next_needed_height(blockchain_height)) >= m_core.get_target_blockchain_height())
{
- // at this point, we have to either close the connection, or start getting blocks past the
- // current point, or become dormant
- MDEBUG(context << "this peer is pruned at seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) <<
- ", next stripe needed is " << next_stripe);
- if (!context.m_is_income)
- {
- if (should_drop_connection(context, next_stripe))
- {
- m_p2p->add_used_stripe_peer(context);
- return false; // drop outgoing connections
- }
- }
- // we'll get back stuck waiting for the go ahead
context.m_state = cryptonote_connection_context::state_normal;
MLOG_PEER_STATE("Nothing to do for now, switching to normal state");
return true;
}
+ MLOG_PEER_STATE("We can download nothing from this peer, dropping");
+ return false;
}
skip:
@@ -2562,6 +2548,8 @@ skip:
}
std::unordered_set<crypto::hash> hashes;
+ uint64_t height = arg.start_height;
+ const uint64_t blockchain_height = m_core.get_current_blockchain_height();
for (const auto &h: arg.m_block_ids)
{
if (!hashes.insert(h).second)
@@ -2570,6 +2558,17 @@ skip:
drop_connection(context, true, false);
return 1;
}
+ if (height < blockchain_height)
+ {
+ const crypto::hash block_in_chain = m_core.get_block_id_by_height(height);
+ if ((height < context.m_expect_height - 1 && block_in_chain == h) || (height == context.m_expect_height - 1 && block_in_chain != h))
+ {
+ LOG_ERROR_CCONTEXT("sent existing block " << h << " at height " << height << ", expected height was " << context.m_expect_height << ", dropping connection");
+ drop_connection(context, true, false);
+ return 1;
+ }
+ }
+ ++height;
}
uint64_t n_use_blocks = m_core.prevalidate_block_hashes(arg.start_height, arg.m_block_ids, arg.m_block_weights);
diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index aee1fa593..8dd551d1e 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -149,6 +149,7 @@ namespace nodetool
const command_line::arg_descriptor<std::string> arg_ban_list = {"ban-list", "Specify ban list file, one IP address per line"};
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
const command_line::arg_descriptor<bool> arg_no_sync = {"no-sync", "Don't synchronize the blockchain with other peers", false};
+ const command_line::arg_descriptor<bool> arg_enable_dns_blocklist = {"enable-dns-blocklist", "Apply realtime blocklist from DNS", false};
const command_line::arg_descriptor<bool> arg_no_igd = {"no-igd", "Disable UPnP port mapping"};
const command_line::arg_descriptor<std::string> arg_igd = {"igd", "UPnP port mapping (disabled, enabled, delayed)", "delayed"};
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index f13b36a82..9fba5d636 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -287,7 +287,7 @@ namespace nodetool
uint32_t get_max_out_public_peers() const;
void change_max_in_public_peers(size_t count);
uint32_t get_max_in_public_peers() const;
- virtual bool block_host(epee::net_utils::network_address address, time_t seconds = P2P_IP_BLOCKTIME);
+ virtual bool block_host(epee::net_utils::network_address address, time_t seconds = P2P_IP_BLOCKTIME, bool add_only = false);
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);
@@ -369,6 +369,7 @@ namespace nodetool
bool peer_sync_idle_maker();
bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false);
bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id);
+ bool update_dns_blocklist();
bool make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist);
bool make_new_connection_from_peerlist(network_zone& zone, bool use_white_list);
@@ -474,6 +475,7 @@ namespace nodetool
epee::math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval;
epee::math_helper::once_a_time_seconds<60> m_gray_peerlist_housekeeping_interval;
epee::math_helper::once_a_time_seconds<3600, false> m_incoming_connections_interval;
+ epee::math_helper::once_a_time_seconds<7000> m_dns_blocklist_interval;
std::list<epee::net_utils::network_address> m_priority_peers;
std::vector<epee::net_utils::network_address> m_exclusive_peers;
@@ -512,6 +514,8 @@ namespace nodetool
cryptonote::network_type m_nettype;
epee::net_utils::ssl_support_t m_ssl_support;
+
+ bool m_enable_dns_blocklist;
};
const int64_t default_limit_up = P2P_DEFAULT_LIMIT_RATE_UP; // kB/s
@@ -533,6 +537,7 @@ namespace nodetool
extern const command_line::arg_descriptor<std::string> arg_ban_list;
extern const command_line::arg_descriptor<bool> arg_p2p_hide_my_port;
extern const command_line::arg_descriptor<bool> arg_no_sync;
+ extern const command_line::arg_descriptor<bool> arg_enable_dns_blocklist;
extern const command_line::arg_descriptor<bool> arg_no_igd;
extern const command_line::arg_descriptor<std::string> arg_igd;
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 128d17155..03ab04b21 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -37,6 +37,7 @@
#include <boost/optional/optional.hpp>
#include <boost/thread/thread.hpp>
#include <boost/uuid/uuid_io.hpp>
+#include <boost/algorithm/string.hpp>
#include <atomic>
#include <functional>
#include <limits>
@@ -120,6 +121,7 @@ namespace nodetool
command_line::add_arg(desc, arg_ban_list);
command_line::add_arg(desc, arg_p2p_hide_my_port);
command_line::add_arg(desc, arg_no_sync);
+ command_line::add_arg(desc, arg_enable_dns_blocklist);
command_line::add_arg(desc, arg_no_igd);
command_line::add_arg(desc, arg_igd);
command_line::add_arg(desc, arg_out_peers);
@@ -226,7 +228,7 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
- bool node_server<t_payload_net_handler>::block_host(epee::net_utils::network_address addr, time_t seconds)
+ bool node_server<t_payload_net_handler>::block_host(epee::net_utils::network_address addr, time_t seconds, bool add_only)
{
if(!addr.is_blockable())
return false;
@@ -240,7 +242,11 @@ namespace nodetool
else
limit = now + seconds;
const std::string host_str = addr.host_str();
- m_blocked_hosts[host_str] = limit;
+ auto it = m_blocked_hosts.find(host_str);
+ if (it == m_blocked_hosts.end())
+ m_blocked_hosts[host_str] = limit;
+ else if (it->second < limit || !add_only)
+ it->second = 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
@@ -260,6 +266,8 @@ namespace nodetool
peerlist_entry pe{};
pe.adr = addr;
zone.second.m_peerlist.remove_from_peer_white(pe);
+ zone.second.m_peerlist.remove_from_peer_gray(pe);
+ zone.second.m_peerlist.remove_from_peer_anchor(addr);
for (const auto &c: conns)
zone.second.m_net_server.get_config_object().close(c);
@@ -497,6 +505,8 @@ namespace nodetool
if (command_line::has_arg(vm, arg_no_sync))
m_payload_handler.set_no_sync(true);
+ m_enable_dns_blocklist = command_line::get_arg(vm, arg_enable_dns_blocklist);
+
if ( !set_max_out_peers(public_zone, command_line::get_arg(vm, arg_out_peers) ) )
return false;
else
@@ -1971,6 +1981,52 @@ namespace nodetool
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));
m_incoming_connections_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::check_incoming_connections, this));
+ m_dns_blocklist_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::update_dns_blocklist, this));
+ return true;
+ }
+ //-----------------------------------------------------------------------------------
+ template<class t_payload_net_handler>
+ bool node_server<t_payload_net_handler>::update_dns_blocklist()
+ {
+ if (!m_enable_dns_blocklist)
+ return true;
+ if (m_nettype != cryptonote::MAINNET)
+ return true;
+
+ static const std::vector<std::string> dns_urls = {
+ "blocklist.moneropulse.se"
+ , "blocklist.moneropulse.org"
+ , "blocklist.moneropulse.net"
+ , "blocklist.moneropulse.no"
+ , "blocklist.moneropulse.fr"
+ , "blocklist.moneropulse.de"
+ , "blocklist.moneropulse.ch"
+ };
+
+ std::vector<std::string> records;
+ if (!tools::dns_utils::load_txt_records_from_dns(records, dns_urls))
+ return true;
+
+ unsigned good = 0, bad = 0;
+ for (const auto& record : records)
+ {
+ std::vector<std::string> ips;
+ boost::split(ips, record, boost::is_any_of(";"));
+ for (const auto &ip: ips)
+ {
+ const expect<epee::net_utils::network_address> parsed_addr = net::get_network_address(ip, 0);
+ if (!parsed_addr)
+ {
+ MWARNING("Invalid IP address from DNS blocklist: " << ip << " - " << parsed_addr.error());
+ ++bad;
+ continue;
+ }
+ block_host(*parsed_addr, DNS_BLOCKLIST_LIFETIME, true);
+ ++good;
+ }
+ }
+ if (good > 0)
+ MINFO(good << " addresses added to the blocklist");
return true;
}
//-----------------------------------------------------------------------------------
diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h
index f1490a0db..0da758ad4 100644
--- a/src/p2p/net_node_common.h
+++ b/src/p2p/net_node_common.h
@@ -58,7 +58,7 @@ namespace nodetool
virtual uint64_t get_public_connections_count()=0;
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
- virtual bool block_host(epee::net_utils::network_address address, time_t seconds = 0)=0;
+ virtual bool block_host(epee::net_utils::network_address address, time_t seconds = 0, bool add_only = false)=0;
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()=0;
@@ -108,7 +108,7 @@ namespace nodetool
{
return false;
}
- virtual bool block_host(epee::net_utils::network_address address, time_t seconds)
+ virtual bool block_host(epee::net_utils::network_address address, time_t seconds, bool add_only)
{
return true;
}