diff options
author | Erik de Castro Lopo <erikd@mega-nerd.com> | 2018-01-21 08:44:23 +1100 |
---|---|---|
committer | Erik de Castro Lopo <erikd@mega-nerd.com> | 2018-01-29 11:14:02 +1100 |
commit | 32c0f908cd753f9319909e2f43d2b4657ebaf664 (patch) | |
tree | 85af316f61c3e28b995ff8b97be8424be4992d3f /src | |
parent | Rename delete_connections to delete_out_connections (diff) | |
download | monero-32c0f908cd753f9319909e2f43d2b4657ebaf664.tar.xz |
Allow the number of incoming connections to be limited
It was already possible to limit outgoing connections. One might want
to do this on home network connections with high bandwidth but low
usage caps.
Diffstat (limited to 'src')
-rw-r--r-- | src/daemon/command_parser_executor.cpp | 17 | ||||
-rw-r--r-- | src/daemon/command_parser_executor.h | 4 | ||||
-rw-r--r-- | src/daemon/command_server.cpp | 6 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.cpp | 32 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.h | 4 | ||||
-rw-r--r-- | src/p2p/net_node.cpp | 1 | ||||
-rw-r--r-- | src/p2p/net_node.h | 6 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 57 | ||||
-rw-r--r-- | src/p2p/p2p_protocol_defs.h | 2 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 12 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.h | 2 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 24 |
12 files changed, 160 insertions, 7 deletions
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() |