From 9f88b7ce6bc9845e097a6d67f3d3c97110b819c1 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Fri, 18 Jul 2014 19:33:03 -0400 Subject: [PATCH] Added get_connections RPC call to daemon --- .../cryptonote_protocol_defs.h | 35 ++++++++++++++++ .../cryptonote_protocol_handler.h | 3 ++ .../cryptonote_protocol_handler.inl | 41 +++++++++++++++++++ src/rpc/core_rpc_server.cpp | 16 ++++++++ src/rpc/core_rpc_server.h | 2 + src/rpc/core_rpc_server_commands_defs.h | 19 +++++++++ 6 files changed, 116 insertions(+) diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index d646a7f6f..eddb3b67b 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -14,6 +14,41 @@ namespace cryptonote #define BC_COMMANDS_POOL_BASE 2000 + /************************************************************************/ + /* P2P connection info, serializable to json */ + /************************************************************************/ + struct connection_info + { + bool incoming; + + std::string ip; + std::string port; + + std::string peer_id; + + uint64_t recv_count; + time_t recv_idle_time; + + uint64_t send_count; + time_t send_idle_time; + + std::string state; + + time_t live_time; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(incoming) + KV_SERIALIZE(ip) + KV_SERIALIZE(port) + KV_SERIALIZE(peer_id) + KV_SERIALIZE(recv_count) + KV_SERIALIZE(recv_idle_time) + KV_SERIALIZE(send_count) + KV_SERIALIZE(send_idle_time) + KV_SERIALIZE(state) + KV_SERIALIZE(live_time) + END_KV_SERIALIZE_MAP() + }; /************************************************************************/ /* */ diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 80538677c..187e7b922 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include #include "storages/levin_abstract_invoke2.h" #include "warnings.h" @@ -53,6 +55,7 @@ namespace cryptonote t_core& get_core(){return m_core;} bool is_synchronized(){return m_synchronized;} void log_connections(); + std::list get_connections(); private: //----------------- commands handlers ---------------------------------------------- int handle_notify_new_block(int command, NOTIFY_NEW_BLOCK::request& arg, cryptonote_connection_context& context); diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index a2f0bb3ad..3358860d1 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -3,6 +3,8 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include + #include "cryptonote_core/cryptonote_format_utils.h" #include "profile_tools.h" namespace cryptonote @@ -90,6 +92,45 @@ namespace cryptonote }); LOG_PRINT_L0("Connections: " << ENDL << ss.str()); } + //------------------------------------------------------------------------------------------------------------------------ + // Returns a list of connection_info objects describing each open p2p connection + //------------------------------------------------------------------------------------------------------------------------ + template + std::list t_cryptonote_protocol_handler::get_connections() + { + std::list connections; + + m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id) + { + connection_info cnx; + auto timestamp = time(NULL); + + cnx.incoming = cntxt.m_is_income ? true : false; + + cnx.ip = epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip); + cnx.port = std::to_string(cntxt.m_remote_port); + + std::stringstream peer_id_str; + peer_id_str << std::hex << peer_id; + peer_id_str >> cnx.peer_id; + + cnx.recv_count = cntxt.m_recv_cnt; + cnx.recv_idle_time = timestamp - cntxt.m_last_recv; + + cnx.send_count = cntxt.m_send_cnt; + cnx.send_idle_time = timestamp; + + cnx.state = get_protocol_state_string(cntxt.m_state); + + cnx.live_time = timestamp - cntxt.m_started; + + connections.push_back(cnx); + + return true; + }); + + return connections; + } //------------------------------------------------------------------------------------------------------------------------ template bool t_cryptonote_protocol_handler::process_payload_sync_data(const CORE_SYNC_DATA& hshd, cryptonote_connection_context& context, bool is_inital) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index c3f98563d..1334b5137 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -604,4 +604,20 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx) + { + if(!check_core_busy()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy."; + return false; + } + + res.connections = m_p2p.get_payload_object().get_connections(); + + res.status = CORE_RPC_STATUS_OK; + + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ } diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index abd9e3de7..399a0214f 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -51,6 +51,7 @@ namespace cryptonote MAP_JON_RPC_WE("getlastblockheader", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER) MAP_JON_RPC_WE("getblockheaderbyhash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH) MAP_JON_RPC_WE("getblockheaderbyheight", on_get_block_header_by_height, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT) + MAP_JON_RPC_WE("get_connections", on_get_connections, COMMAND_RPC_GET_CONNECTIONS) END_JSON_RPC_MAP() END_URI_MAP2() @@ -74,6 +75,7 @@ namespace cryptonote bool on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); bool on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); bool on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); + bool on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); //----------------------- bool handle_command_line(const boost::program_options::variables_map& vm); bool check_core_busy(); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 20f73c9d8..39acadb04 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -481,5 +481,24 @@ namespace cryptonote }; + struct COMMAND_RPC_GET_CONNECTIONS + { + struct request + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + std::list connections; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(connections) + END_KV_SERIALIZE_MAP() + }; + + }; }