Merge branch 'release' into develop
# Conflicts: # src/version.h.in
This commit is contained in:
commit
1b8cfa0194
10 changed files with 204 additions and 27 deletions
|
|
@ -54,7 +54,7 @@ namespace epee {
|
|||
namespace net_utils {
|
||||
|
||||
struct i_connection_filter {
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress) = 0;
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress, bool is_incoming) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~i_connection_filter()
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ bool connection<t_protocol_handler>::start(bool is_income, bool is_multithreaded
|
|||
|
||||
LOG_PRINT_L3("[sock " << socket_.native_handle() << "] new connection, remote end_point: " << print_connection_context_short(context) << " local end_point: " << local_ep.address().to_string() << ':' << local_ep.port() << ", total sockets objects " << m_ref_sockets_count);
|
||||
|
||||
if(is_income && m_pfilter && !m_pfilter->is_remote_ip_allowed(context.m_remote_ip)) {
|
||||
if(is_income && m_pfilter && !m_pfilter->is_remote_ip_allowed(context.m_remote_ip, is_income)) {
|
||||
LOG_PRINT_L0("[sock " << socket_.native_handle() << "] ip denied " << string_tools::get_ip_string_from_int32(context.m_remote_ip) << ", shutdowning connection");
|
||||
close();
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@
|
|||
|
||||
|
||||
#define P2P_NET_DATA_FILENAME "p2pstate.bin"
|
||||
#define P2P_MANUAL_CONFIG_FILENAME "p2p_manual_config.json"
|
||||
#define MINER_CONFIG_FILENAME "miner_conf.json"
|
||||
#define GUI_SECURE_CONFIG_FILENAME "gui_secure_conf.bin"
|
||||
#define GUI_CONFIG_FILENAME "gui_settings.json"
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ namespace currency
|
|||
for(auto it = conn_map.rbegin(); it != conn_map.rend(); ++it)
|
||||
ss << it->second;
|
||||
|
||||
LOG_PRINT_L0("Connections (" << incoming_count << " in, " << outgoing_count << " out, " << incoming_count + outgoing_count << " total):" << ENDL << ss.str());
|
||||
LOG_PRINT_L0("Connections:" << ENDL << ss.str() << ENDL << "(" << incoming_count << " in, " << outgoing_count << " out, " << incoming_count + outgoing_count << " total)");
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ public:
|
|||
m_cmd_binder.set_handler("debug_remote_node_mode", boost::bind(&daemon_commands_handler::debug_remote_node_mode, this, ph::_1), "<ip-address> - If node got connected put node into 'debug mode' i.e. no sync process of other communication except ping responses, maintenance secrete key will be requested");
|
||||
m_cmd_binder.set_handler("full_db_cache_warmup", boost::bind(&daemon_commands_handler::full_db_cache_warmup, this, ph::_1), "(Experimental) Perform full DB loading to RAM cache(make sense only with big numbers passed to --db-cache-l2 option)");
|
||||
m_cmd_binder.set_handler("print_cache_state", boost::bind(&daemon_commands_handler::print_cache_state, this, ph::_1), "Print db l2 cache state");
|
||||
m_cmd_binder.set_handler("reload_p2p_manual_config", boost::bind(&daemon_commands_handler::reload_p2p_manual_config, this, ph::_1), "Reload manual p2p config from '" P2P_MANUAL_CONFIG_FILENAME "'");
|
||||
#ifdef _DEBUG
|
||||
m_cmd_binder.set_handler("debug_set_time_adj", boost::bind(&daemon_commands_handler::debug_set_time_adj, this, ph::_1), "DEBUG: set core time adjustment");
|
||||
#endif
|
||||
|
|
@ -226,10 +227,10 @@ private:
|
|||
std::map<uint32_t, time_t> blocklist;
|
||||
m_srv.get_ip_block_list(blocklist);
|
||||
std::stringstream ss;
|
||||
ss << "BLOCKED IPS:" << ENDL;
|
||||
ss << "AUTO BLOCKED IPs:" << ENDL << "ip block time" << ENDL;
|
||||
for (const auto& e : blocklist)
|
||||
{
|
||||
ss << string_tools::get_ip_string_from_int32(e.first) << ", time: " << std::put_time(std::localtime(&e.second), "%Y-%m-%d %H:%M:%S") << ENDL;
|
||||
ss << std::left << std::setw(15) << string_tools::get_ip_string_from_int32(e.first) << " " << std::put_time(std::localtime(&e.second), "%Y-%m-%d %H:%M:%S") << ENDL;
|
||||
}
|
||||
LOG_PRINT_L0(ss.str());
|
||||
return true;
|
||||
|
|
@ -901,6 +902,13 @@ private:
|
|||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool reload_p2p_manual_config(const std::vector<std::string>& args)
|
||||
{
|
||||
m_srv.reload_p2p_manual_config(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool print_pool(const std::vector<std::string>& args)
|
||||
{
|
||||
LOG_PRINT_L0("Pool state: " << ENDL << m_srv.get_payload_object().get_core().print_pool(false));
|
||||
|
|
|
|||
|
|
@ -121,10 +121,12 @@ namespace nodetool
|
|||
bool log_connections();
|
||||
virtual uint64_t get_connections_count();
|
||||
size_t get_outgoing_connections_count();
|
||||
size_t get_incoming_connections_count();
|
||||
peerlist_manager& get_peerlist_manager(){return m_peerlist;}
|
||||
bool handle_maintainers_entry(const maintainers_entry& me);
|
||||
bool get_maintainers_info(maintainers_info_external& me);
|
||||
void get_ip_block_list(std::map<uint32_t, time_t>& blocklist);
|
||||
bool reload_p2p_manual_config(bool silent = true);
|
||||
typedef COMMAND_REQUEST_STAT_INFO_T<typename t_payload_net_handler::stat_info> COMMAND_REQUEST_STAT_INFO;
|
||||
private:
|
||||
|
||||
|
|
@ -182,9 +184,10 @@ namespace nodetool
|
|||
virtual bool add_ip_fail(uint32_t address);
|
||||
virtual bool is_stop_signal_sent();
|
||||
//----------------- i_connection_filter --------------------------------------------------------
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress);
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress, bool is_incoming);
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
|
||||
bool parse_peerlist(const std::vector<std::string>& perrs_str, std::list<nodetool::net_address>& peers);
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool idle_worker();
|
||||
bool handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const net_utils::connection_context_base& context);
|
||||
|
|
@ -219,7 +222,7 @@ namespace nodetool
|
|||
bool critical_alert_worker();
|
||||
bool remove_dead_connections();
|
||||
bool is_ip_good_for_adding_to_peerlist(uint32_t adress);
|
||||
bool is_ip_in_blacklist(uint32_t adress);
|
||||
bool is_ip_in_blacklist(uint32_t adress, bool ignore_auto_blocked_list = false);
|
||||
|
||||
|
||||
//debug functions
|
||||
|
|
@ -296,9 +299,16 @@ namespace nodetool
|
|||
critical_section m_blocked_ips_lock;
|
||||
std::map<uint32_t, time_t> m_blocked_ips;
|
||||
|
||||
//critical_section m_permanently_blocked_ips_lock;
|
||||
std::set<uint32_t> m_permanently_blocked_ips;
|
||||
|
||||
|
||||
critical_section m_ip_fails_score_lock;
|
||||
std::map<uint32_t, uint64_t> m_ip_fails_score;
|
||||
|
||||
critical_section m_p2p_manual_config_lock;
|
||||
p2p_config_data m_p2p_manual_config;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace nodetool
|
|||
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port ("hide-my-port", "Do not announce yourself as peerlist candidate");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_offline_mode ( "offline-mode", "Don't connect to any node and reject any connections");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_disable_debug_reqs ( "disable-debug-p2p-requests", "Disable p2p debug requests");
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_ip_auto_blocking ( "p2p-ip-auto-blocking", "Enable (1) or disable (0) peers auto-blocking by IP <0|1>. Default: 0", 1);
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_ip_auto_blocking ( "p2p-ip-auto-blocking", "Enable (1) or disable (0) peers auto-blocking by IP <0|1>. Default: 1", 1);
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_server_threads ( "p2p-server-threads", "Specify number of p2p server threads. Default: 10", P2P_SERVER_DEFAULT_THREADS_NUM);
|
||||
}
|
||||
|
||||
|
|
@ -106,15 +106,22 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_remote_ip_allowed(uint32_t addr)
|
||||
bool node_server<t_payload_net_handler>::is_remote_ip_allowed(uint32_t addr, bool is_incoming)
|
||||
{
|
||||
if (m_offline_mode)
|
||||
return false;
|
||||
|
||||
if (!m_ip_auto_blocking_enabled)
|
||||
return true;
|
||||
|
||||
return !is_ip_in_blacklist(addr);
|
||||
if (is_incoming)
|
||||
{
|
||||
if (m_p2p_manual_config.incoming_connections_limit && *m_p2p_manual_config.incoming_connections_limit >= get_incoming_connections_count())
|
||||
return false;
|
||||
|
||||
if (m_use_only_priority_peers)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ignore_auto_blocked_list = !m_ip_auto_blocking_enabled;
|
||||
return !is_ip_in_blacklist(addr, ignore_auto_blocked_list);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
|
|
@ -129,9 +136,18 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_ip_in_blacklist(uint32_t addr)
|
||||
bool node_server<t_payload_net_handler>::is_ip_in_blacklist(uint32_t addr, bool ignore_auto_blocked_list /* = false */)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||
|
||||
//first check permanently blocked ip
|
||||
if (m_permanently_blocked_ips.find(addr) != m_permanently_blocked_ips.end())
|
||||
return true;
|
||||
|
||||
if (ignore_auto_blocked_list)
|
||||
return false;
|
||||
|
||||
//check temporary blocked
|
||||
auto it = m_blocked_ips.find(addr);
|
||||
if (it == m_blocked_ips.end())
|
||||
return false;
|
||||
|
|
@ -147,6 +163,77 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::reload_p2p_manual_config(bool silent)
|
||||
{
|
||||
std::set<uint32_t> new_block_list;
|
||||
std::list<net_address> new_priority_peers;
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_p2p_manual_config_lock);
|
||||
p2p_config_data config = AUTO_VAL_INIT(config);
|
||||
std::string p2p_config_file_path = m_config_folder + "/" + P2P_MANUAL_CONFIG_FILENAME;
|
||||
bool r = epee::serialization::load_t_from_json_file(config, p2p_config_file_path);
|
||||
if (!r)
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
LOG_PRINT_L0("P2P network config file is missing or not loaded");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//loaded json, let's try to load blacklist
|
||||
for (const std::string& ip_str_entry : config.ip_black_list)
|
||||
{
|
||||
uint32_t ip = 0;
|
||||
if (!string_tools::get_ip_int32_from_string(ip, ip_str_entry))
|
||||
{
|
||||
LOG_ERROR("P2P network config file loading error: failed to convert '" << ip_str_entry << "' to ip address");
|
||||
return false;
|
||||
}
|
||||
new_block_list.insert(ip);
|
||||
}
|
||||
|
||||
if (config.priority_peers_list.size())
|
||||
{
|
||||
bool r = parse_peerlist(config.priority_peers_list, new_priority_peers);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse priority peers");
|
||||
}
|
||||
|
||||
m_p2p_manual_config = config;
|
||||
|
||||
|
||||
//override some of the settings
|
||||
if (m_p2p_manual_config.use_only_priority_peers)
|
||||
{
|
||||
m_use_only_priority_peers = *m_p2p_manual_config.use_only_priority_peers;
|
||||
}
|
||||
|
||||
m_priority_peers = new_priority_peers;
|
||||
|
||||
|
||||
if (m_p2p_manual_config.incoming_connections_limit && *m_p2p_manual_config.incoming_connections_limit == 0)
|
||||
{
|
||||
m_hide_my_port = true;
|
||||
}
|
||||
|
||||
if (m_p2p_manual_config.outgoing_connections_limit && *m_p2p_manual_config.outgoing_connections_limit == 0)
|
||||
{
|
||||
//TODO: consider if need to do this
|
||||
//m_offline_mode = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//TODO: this command when passed to running daemon via command line option might be multi-thread-unsafe, subject for refactoring
|
||||
//CRITICAL_REGION_LOCAL(m_permanently_blocked_ips_lock);
|
||||
m_permanently_blocked_ips.clear();
|
||||
m_permanently_blocked_ips = new_block_list;
|
||||
|
||||
LOG_PRINT_L0("P2P network manual config file loaded(some of the p2p cpommand line options might be overridden by '" << P2P_MANUAL_CONFIG_FILENAME << "').");
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::block_ip(uint32_t addr)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||
|
|
@ -188,6 +275,19 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::parse_peerlist(const std::vector<std::string>& perrs_str, std::list<net_address>& peers)
|
||||
{
|
||||
for (const std::string& pr_str : perrs_str)
|
||||
{
|
||||
nodetool::net_address na = AUTO_VAL_INIT(na);
|
||||
bool r = parse_peer_from_string(na, pr_str);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
|
||||
peers.push_back(na);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
{
|
||||
m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip);
|
||||
|
|
@ -236,13 +336,8 @@ namespace nodetool
|
|||
if (command_line::has_arg(vm, arg_p2p_add_priority_node))
|
||||
{
|
||||
std::vector<std::string> perrs = command_line::get_arg(vm, arg_p2p_add_priority_node);
|
||||
for(const std::string& pr_str: perrs)
|
||||
{
|
||||
nodetool::net_address na = AUTO_VAL_INIT(na);
|
||||
bool r = parse_peer_from_string(na, pr_str);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
|
||||
m_priority_peers.push_back(na);
|
||||
}
|
||||
bool r = parse_peerlist(perrs, m_priority_peers);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse priority peers");
|
||||
}
|
||||
if(command_line::has_arg(vm, arg_p2p_use_only_priority_nodes))
|
||||
m_use_only_priority_peers = true;
|
||||
|
|
@ -383,6 +478,10 @@ namespace nodetool
|
|||
LOG_PRINT_GREEN("Net service binded on " << m_bind_ip << ":" << m_listenning_port, LOG_LEVEL_0);
|
||||
if(m_external_port)
|
||||
LOG_PRINT_L0("External port defined as " << m_external_port);
|
||||
|
||||
|
||||
reload_p2p_manual_config(true);
|
||||
|
||||
return res;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
@ -842,7 +941,7 @@ namespace nodetool
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!is_remote_ip_allowed(pe.adr.ip))
|
||||
if (!is_remote_ip_allowed(pe.adr.ip, false))
|
||||
{
|
||||
++peer_index;
|
||||
continue;
|
||||
|
|
@ -912,10 +1011,22 @@ namespace nodetool
|
|||
|
||||
size_t expected_white_connections = (m_config.m_net_config.connections_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
|
||||
|
||||
size_t conn_count = get_outgoing_connections_count();
|
||||
if(conn_count < m_config.m_net_config.connections_count)
|
||||
size_t out_conn_count = get_outgoing_connections_count();
|
||||
bool need_more_connections = false;
|
||||
if (m_p2p_manual_config.outgoing_connections_limit)
|
||||
{
|
||||
if(conn_count < expected_white_connections)
|
||||
// m_p2p_manual_config always override default settings from m_config.m_net_config
|
||||
need_more_connections = out_conn_count < *m_p2p_manual_config.outgoing_connections_limit;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use default policy
|
||||
need_more_connections = out_conn_count < m_config.m_net_config.connections_count;
|
||||
}
|
||||
|
||||
if(need_more_connections)
|
||||
{
|
||||
if(out_conn_count < expected_white_connections)
|
||||
{
|
||||
//start from white list
|
||||
if(!make_expected_connections_count(true, expected_white_connections))
|
||||
|
|
@ -966,6 +1077,20 @@ namespace nodetool
|
|||
return true;
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
size_t node_server<t_payload_net_handler>::get_incoming_connections_count()
|
||||
{
|
||||
size_t count = 0;
|
||||
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
|
||||
{
|
||||
if (cntxt.m_is_income)
|
||||
++count;
|
||||
return true;
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -289,6 +289,29 @@ namespace nodetool
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct p2p_config_data
|
||||
{
|
||||
std::optional<uint64_t> incoming_connections_limit;
|
||||
std::optional<uint64_t> outgoing_connections_limit;
|
||||
std::vector<std::string> ip_black_list;
|
||||
std::optional<bool> use_only_priority_peers = false; //allow to make outgoing connections only to the peers listed in ip_priority_list
|
||||
std::vector<std::string> priority_peers_list;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(incoming_connections_limit)
|
||||
KV_SERIALIZE(outgoing_connections_limit)
|
||||
KV_SERIALIZE(ip_black_list)
|
||||
KV_SERIALIZE(use_only_priority_peers)
|
||||
KV_SERIALIZE(priority_peers_list)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef ALLOW_DEBUG_COMMANDS
|
||||
//These commands are considered as insecure, and made in debug purposes for a limited lifetime.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
|
||||
#define SANITY_CHECK_MAX_RESERVATION_RAM 10000000
|
||||
|
||||
|
||||
//#include "serialization.h"
|
||||
template <template <bool> class Archive, class T>
|
||||
bool do_serialize(Archive<false> &ar, std::vector<T> &v);
|
||||
|
|
@ -49,7 +53,13 @@ bool do_serialize(Archive<false> &ar, std::vector<T> &v)
|
|||
return false;
|
||||
}
|
||||
|
||||
v.reserve(cnt);
|
||||
if (sizeof(T) * cnt < SANITY_CHECK_MAX_RESERVATION_RAM)
|
||||
{
|
||||
v.reserve(cnt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (size_t i = 0; i < cnt; i++) {
|
||||
if (i > 0)
|
||||
ar.delimit_array();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "8"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 419
|
||||
#define PROJECT_VERSION_BUILD_NO 421
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue