aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h78
-rw-r--r--src/daemon/command_parser_executor.cpp17
-rw-r--r--src/daemon/command_parser_executor.h4
-rw-r--r--src/daemon/command_server.cpp6
-rw-r--r--src/daemon/rpc_command_executor.cpp32
-rw-r--r--src/daemon/rpc_command_executor.h4
-rw-r--r--src/p2p/net_node.cpp1
-rw-r--r--src/p2p/net_node.h6
-rw-r--r--src/p2p/net_node.inl57
-rw-r--r--src/p2p/p2p_protocol_defs.h2
-rw-r--r--src/rpc/core_rpc_server.cpp12
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h24
13 files changed, 205 insertions, 40 deletions
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index ee64da5d8..de270bfd0 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -77,6 +77,8 @@ class async_protocol_handler_config
levin_commands_handler<t_connection_context>* m_pcommands_handler;
void (*m_pcommands_handler_destroy)(levin_commands_handler<t_connection_context>*);
+ void delete_connections (size_t count, bool incoming);
+
public:
typedef t_connection_context connection_context;
uint64_t m_max_packet_size;
@@ -101,6 +103,7 @@ public:
{}
~async_protocol_handler_config() { set_handler(NULL, NULL); }
void del_out_connections(size_t count);
+ void del_in_connections(size_t count);
};
@@ -731,41 +734,50 @@ void async_protocol_handler_config<t_connection_context>::del_connection(async_p
}
//------------------------------------------------------------------------------------------
template<class t_connection_context>
+void async_protocol_handler_config<t_connection_context>::delete_connections(size_t count, bool incoming)
+{
+ std::vector <boost::uuids::uuid> connections;
+ CRITICAL_REGION_BEGIN(m_connects_lock);
+ for (auto& c: m_connects)
+ {
+ if (c.second->m_connection_context.m_is_income == incoming)
+ connections.push_back(c.first);
+ }
+
+ // close random connections from the provided set
+ // TODO or better just keep removing random elements (performance)
+ unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
+ shuffle(connections.begin(), connections.end(), std::default_random_engine(seed));
+ while (count > 0 && connections.size() > 0)
+ {
+ try
+ {
+ auto i = connections.end() - 1;
+ async_protocol_handler<t_connection_context> *conn = m_connects.at(*i);
+ del_connection(conn);
+ close(*i);
+ connections.erase(i);
+ }
+ catch (const std::out_of_range &e)
+ {
+ MWARNING("Connection not found in m_connects, continuing");
+ }
+ --count;
+ }
+
+ CRITICAL_REGION_END();
+}
+//------------------------------------------------------------------------------------------
+template<class t_connection_context>
void async_protocol_handler_config<t_connection_context>::del_out_connections(size_t count)
{
- std::vector <boost::uuids::uuid> out_connections;
- CRITICAL_REGION_BEGIN(m_connects_lock);
- for (auto& c: m_connects)
- {
- if (!c.second->m_connection_context.m_is_income)
- out_connections.push_back(c.first);
- }
-
- if (out_connections.size() == 0)
- return;
-
- // close random out connections
- // TODO or better just keep removing random elements (performance)
- unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- shuffle(out_connections.begin(), out_connections.end(), std::default_random_engine(seed));
- while (count > 0 && out_connections.size() > 0)
- {
- try
- {
- auto i = out_connections.end() - 1;
- async_protocol_handler<t_connection_context> *conn = m_connects.at(*i);
- del_connection(conn);
- close(*i);
- out_connections.erase(i);
- }
- catch (const std::out_of_range &e)
- {
- MWARNING("Connection not found in m_connects, continuing");
- }
- --count;
- }
-
- CRITICAL_REGION_END();
+ delete_connections(count, false);
+}
+//------------------------------------------------------------------------------------------
+template<class t_connection_context>
+void async_protocol_handler_config<t_connection_context>::del_in_connections(size_t count)
+{
+ delete_connections(count, true);
}
//------------------------------------------------------------------------------------------
template<class t_connection_context>
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index 3ec74ff79..09e425dd1 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -428,6 +428,23 @@ bool t_command_parser_executor::out_peers(const std::vector<std::string>& args)
return m_executor.out_peers(limit);
}
+bool t_command_parser_executor::in_peers(const std::vector<std::string>& args)
+{
+ if (args.empty()) return false;
+
+ unsigned int limit;
+ try {
+ limit = std::stoi(args[0]);
+ }
+
+ catch(const std::exception& ex) {
+ _erro("stoi exception");
+ return false;
+ }
+
+ return m_executor.in_peers(limit);
+}
+
bool t_command_parser_executor::start_save_graph(const std::vector<std::string>& args)
{
if (!args.empty()) return false;
diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h
index 37e900b8f..2c09a4748 100644
--- a/src/daemon/command_parser_executor.h
+++ b/src/daemon/command_parser_executor.h
@@ -108,7 +108,9 @@ public:
bool set_limit_down(const std::vector<std::string>& args);
bool out_peers(const std::vector<std::string>& args);
-
+
+ bool in_peers(const std::vector<std::string>& args);
+
bool start_save_graph(const std::vector<std::string>& args);
bool stop_save_graph(const std::vector<std::string>& args);
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 1f8981fa2..a50dbea69 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -197,6 +197,12 @@ t_command_server::t_command_server(
, "Set the <max_number> of out peers."
);
m_command_lookup.set_handler(
+ "in_peers"
+ , std::bind(&t_command_parser_executor::in_peers, &m_parser, p::_1)
+ , "in_peers <max_number>"
+ , "Set the <max_number> of in peers."
+ );
+ m_command_lookup.set_handler(
"start_save_graph"
, std::bind(&t_command_parser_executor::start_save_graph, &m_parser, p::_1)
, "Start saving data for dr monero."
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 2da4f3e6e..af9c05bc7 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -1281,6 +1281,38 @@ bool t_rpc_command_executor::out_peers(uint64_t limit)
return true;
}
+bool t_rpc_command_executor::in_peers(uint64_t limit)
+{
+ cryptonote::COMMAND_RPC_IN_PEERS::request req;
+ cryptonote::COMMAND_RPC_IN_PEERS::response res;
+
+ epee::json_rpc::error error_resp;
+
+ req.in_peers = limit;
+
+ std::string fail_message = "Unsuccessful";
+
+ if (m_is_rpc)
+ {
+ if (!m_rpc_client->json_rpc_request(req, res, "in_peers", fail_message.c_str()))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (!m_rpc_server->on_in_peers(req, res) || res.status != CORE_RPC_STATUS_OK)
+ {
+ tools::fail_msg_writer() << make_error(fail_message, res.status);
+ return true;
+ }
+ }
+
+ std::cout << "Max number of in peers set to " << limit << std::endl;
+
+ return true;
+}
+
bool t_rpc_command_executor::start_save_graph()
{
cryptonote::COMMAND_RPC_START_SAVE_GRAPH::request req;
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index f0781180a..fa83d8988 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -122,7 +122,9 @@ public:
bool set_limit(int64_t limit_down, int64_t limit_up);
bool out_peers(uint64_t limit);
-
+
+ bool in_peers(uint64_t limit);
+
bool start_save_graph();
bool stop_save_graph();
diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index 121e72392..994941168 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -55,6 +55,7 @@ namespace nodetool
const command_line::arg_descriptor<bool> arg_no_igd = {"no-igd", "Disable UPnP port mapping"};
const command_line::arg_descriptor<int64_t> arg_out_peers = {"out-peers", "set max number of out peers", -1};
+ const command_line::arg_descriptor<int64_t> arg_in_peers = {"in-peers", "set max number of in peers", -1};
const command_line::arg_descriptor<int> arg_tos_flag = {"tos-flag", "set TOS flag", -1};
const command_line::arg_descriptor<int64_t> arg_limit_rate_up = {"limit-rate-up", "set limit-rate-up [kB/s]", -1};
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 2f26695a2..568c650cc 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -81,6 +81,7 @@ namespace nodetool
node_server(t_payload_net_handler& payload_handler)
:m_payload_handler(payload_handler),
m_current_number_of_out_peers(0),
+ m_current_number_of_in_peers(0),
m_allow_local_ip(false),
m_hide_my_port(false),
m_no_igd(false),
@@ -117,8 +118,10 @@ 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;}
void delete_out_connections(size_t count);
+ void delete_in_connections(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 std::map<std::string, time_t> get_blocked_hosts() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_hosts; }
@@ -230,6 +233,7 @@ namespace nodetool
bool parse_peers_and_add_to_container(const boost::program_options::variables_map& vm, const command_line::arg_descriptor<std::vector<std::string> > & arg, Container& container);
bool set_max_out_peers(const boost::program_options::variables_map& vm, int64_t max);
+ bool set_max_in_peers(const boost::program_options::variables_map& vm, int64_t max);
bool set_tos_flag(const boost::program_options::variables_map& vm, int limit);
bool set_rate_up_limit(const boost::program_options::variables_map& vm, int64_t limit);
@@ -271,6 +275,7 @@ namespace nodetool
public:
config m_config; // TODO was private, add getters?
std::atomic<unsigned int> m_current_number_of_out_peers;
+ std::atomic<unsigned int> m_current_number_of_in_peers;
void set_save_graph(bool save_graph)
{
@@ -345,6 +350,7 @@ namespace nodetool
extern const command_line::arg_descriptor<bool> arg_no_igd;
extern const command_line::arg_descriptor<bool> arg_offline;
extern const command_line::arg_descriptor<int64_t> arg_out_peers;
+ extern const command_line::arg_descriptor<int64_t> arg_in_peers;
extern const command_line::arg_descriptor<int> arg_tos_flag;
extern const command_line::arg_descriptor<int64_t> arg_limit_rate_up;
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 5f00e97f0..3445674f6 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -85,6 +85,7 @@ namespace nodetool
command_line::add_arg(desc, arg_p2p_hide_my_port);
command_line::add_arg(desc, arg_no_igd);
command_line::add_arg(desc, arg_out_peers);
+ command_line::add_arg(desc, arg_in_peers);
command_line::add_arg(desc, arg_tos_flag);
command_line::add_arg(desc, arg_limit_rate_up);
command_line::add_arg(desc, arg_limit_rate_down);
@@ -315,6 +316,9 @@ namespace nodetool
if ( !set_max_out_peers(vm, command_line::get_arg(vm, arg_out_peers) ) )
return false;
+ if ( !set_max_in_peers(vm, command_line::get_arg(vm, arg_in_peers) ) )
+ return false;
+
if ( !set_tos_flag(vm, command_line::get_arg(vm, arg_tos_flag) ) )
return false;
@@ -565,14 +569,23 @@ namespace nodetool
while (!is_closing && !m_net_server.is_stop_signal_sent())
{ // main loop of thread
//number_of_peers = m_net_server.get_config_object().get_connections_count();
- unsigned int number_of_peers = 0;
+ unsigned int number_of_in_peers = 0;
+ unsigned int number_of_out_peers = 0;
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
- if (!cntxt.m_is_income) ++number_of_peers;
+ if (cntxt.m_is_income)
+ {
+ ++number_of_in_peers;
+ }
+ else
+ {
+ ++number_of_out_peers;
+ }
return true;
}); // lambda
- m_current_number_of_out_peers = number_of_peers;
+ m_current_number_of_in_peers = number_of_in_peers;
+ m_current_number_of_out_peers = number_of_out_peers;
boost::this_thread::sleep_for(boost::chrono::seconds(1));
} // main loop of thread
@@ -1253,6 +1266,20 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
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;
+ }
+ //-----------------------------------------------------------------------------------
+ template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::idle_worker()
{
m_peer_handshake_idle_maker_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::peer_sync_idle_maker, this));
@@ -1618,6 +1645,13 @@ namespace nodetool
return 1;
}
+ if (m_current_number_of_in_peers >= m_config.m_net_config.max_in_connection_count) // in peers limit
+ {
+ LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came, but already have max incoming connections, so dropping this one.");
+ drop_connection(context);
+ return 1;
+ }
+
if(!m_payload_handler.process_payload_sync_data(arg.payload_data, context, true))
{
LOG_WARNING_CC(context, "COMMAND_HANDSHAKE came, but process_payload_sync_data returned false, dropping connection.");
@@ -1787,12 +1821,29 @@ namespace nodetool
}
template<class t_payload_net_handler>
+ bool node_server<t_payload_net_handler>::set_max_in_peers(const boost::program_options::variables_map& vm, int64_t max)
+ {
+ if(max == -1) {
+ m_config.m_net_config.max_in_connection_count = -1;
+ return true;
+ }
+ m_config.m_net_config.max_in_connection_count = max;
+ return true;
+ }
+
+ template<class t_payload_net_handler>
void node_server<t_payload_net_handler>::delete_out_connections(size_t count)
{
m_net_server.get_config_object().del_out_connections(count);
}
template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::delete_in_connections(size_t count)
+ {
+ m_net_server.get_config_object().del_in_connections(count);
+ }
+
+ template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::set_tos_flag(const boost::program_options::variables_map& vm, int flag)
{
if(flag==-1){
diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h
index 3fa71713d..e793e19b6 100644
--- a/src/p2p/p2p_protocol_defs.h
+++ b/src/p2p/p2p_protocol_defs.h
@@ -132,12 +132,14 @@ namespace nodetool
{
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(max_out_connection_count)
+ KV_SERIALIZE(max_in_connection_count)
KV_SERIALIZE(handshake_interval)
KV_SERIALIZE(packet_max_size)
KV_SERIALIZE(config_id)
END_KV_SERIALIZE_MAP()
uint32_t max_out_connection_count;
+ uint32_t max_in_connection_count;
uint32_t connection_timeout;
uint32_t ping_connection_timeout;
uint32_t handshake_interval;
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 2bae6352e..80d9823d4 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1603,6 +1603,18 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool core_rpc_server::on_in_peers(const COMMAND_RPC_IN_PEERS::request& req, COMMAND_RPC_IN_PEERS::response& res)
+ {
+ PERF_TIMER(on_in_peers);
+ size_t n_connections = m_p2p.get_incoming_connections_count();
+ size_t n_delete = (n_connections > req.in_peers) ? n_connections - req.in_peers : 0;
+ m_p2p.m_config.m_net_config.max_in_connection_count = req.in_peers;
+ if (n_delete)
+ m_p2p.delete_in_connections(n_delete);
+ res.status = CORE_RPC_STATUS_OK;
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res)
{
PERF_TIMER(on_start_save_graph);
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index 0c7028719..2b0d54bef 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -114,6 +114,7 @@ namespace cryptonote
MAP_URI_AUTO_JON2("/get_limit", on_get_limit, COMMAND_RPC_GET_LIMIT)
MAP_URI_AUTO_JON2_IF("/set_limit", on_set_limit, COMMAND_RPC_SET_LIMIT, !m_restricted)
MAP_URI_AUTO_JON2_IF("/out_peers", on_out_peers, COMMAND_RPC_OUT_PEERS, !m_restricted)
+ MAP_URI_AUTO_JON2_IF("/in_peers", on_in_peers, COMMAND_RPC_IN_PEERS, !m_restricted)
MAP_URI_AUTO_JON2_IF("/start_save_graph", on_start_save_graph, COMMAND_RPC_START_SAVE_GRAPH, !m_restricted)
MAP_URI_AUTO_JON2_IF("/stop_save_graph", on_stop_save_graph, COMMAND_RPC_STOP_SAVE_GRAPH, !m_restricted)
MAP_URI_AUTO_JON2("/get_outs", on_get_outs, COMMAND_RPC_GET_OUTPUTS)
@@ -183,6 +184,7 @@ namespace cryptonote
bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res);
bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res);
bool on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res);
+ bool on_in_peers(const COMMAND_RPC_IN_PEERS::request& req, COMMAND_RPC_IN_PEERS::response& res);
bool on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res);
bool on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res);
bool on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res);
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 9b9a8f949..3a878c4cc 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -1678,8 +1678,28 @@ namespace cryptonote
struct response
{
- std::string status;
-
+ std::string status;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(status)
+ END_KV_SERIALIZE_MAP()
+ };
+ };
+
+ struct COMMAND_RPC_IN_PEERS
+ {
+ struct request
+ {
+ uint64_t in_peers;
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(in_peers)
+ END_KV_SERIALIZE_MAP()
+ };
+
+ struct response
+ {
+ std::string status;
+
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()