From ee7a1e54f7b79257f0e28537992fe5f4cbf8b0d4 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Wed, 8 Sep 2021 20:25:39 +0200 Subject: [PATCH] DNS name resolution for command line parameters --- src/json_rpc_request.cpp | 14 +++++++++++--- src/p2p_server.cpp | 11 ++++++----- src/p2pool.cpp | 18 ++++++++++++------ src/params.cpp | 2 +- src/params.h | 2 +- src/util.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/util.h | 2 ++ 7 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/json_rpc_request.cpp b/src/json_rpc_request.cpp index faed2db..773b725 100644 --- a/src/json_rpc_request.cpp +++ b/src/json_rpc_request.cpp @@ -39,8 +39,13 @@ JSONRPCRequest::JSONRPCRequest(const char* address, int port, const char* req, C uv_tcp_init(uv_default_loop_checked(), &m_socket); uv_tcp_nodelay(&m_socket, 1); - sockaddr_in dest; - uv_ip4_addr(address, port, &dest); + sockaddr_storage addr; + if (uv_ip4_addr(address, port, reinterpret_cast(&addr)) != 0) { + const int err = uv_ip6_addr(address, port, reinterpret_cast(&addr)); + if (err) { + LOGERR(1, "invalid IP address " << address << " or port " << port); + } + } m_socket.data = this; m_connect.data = this; @@ -59,7 +64,10 @@ JSONRPCRequest::JSONRPCRequest(const char* address, int port, const char* req, C m_response.reserve(sizeof(m_readBuf)); - uv_tcp_connect(&m_connect, &m_socket, reinterpret_cast(&dest), on_connect); + const int err = uv_tcp_connect(&m_connect, &m_socket, reinterpret_cast(&addr), on_connect); + if (err) { + LOGERR(1, "failed to initiate tcp connection to " << address << ", error " << uv_err_name(err)); + } } void JSONRPCRequest::on_connect(uv_connect_t* req, int status) diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index ae4d38f..969c8cd 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -135,9 +135,11 @@ void P2PServer::store_in_cache(const PoolBlock& block) void P2PServer::connect_to_peers(const std::string& peer_list) { parse_address_list(peer_list, - [this](bool is_v6, const std::string& /*address*/, const std::string& ip, int port) + [this](bool is_v6, const std::string& /*address*/, std::string ip, int port) { - connect_to_peer(is_v6, ip.c_str(), port); + if (resolve_host(ip, is_v6)) { + connect_to_peer(is_v6, ip.c_str(), port); + } }); } @@ -313,10 +315,9 @@ void P2PServer::save_peer_list() void P2PServer::load_peer_list() { - // First take peers from the command line - std::string saved_list = m_pool->params().m_p2pPeerList; + std::string saved_list; - // Then load peers from seed nodes if we're on the default sidechain + // Load peers from seed nodes if we're on the default sidechain if (m_pool->side_chain().is_default()) { for (size_t i = 0; i < array_size(seed_nodes); ++i) { LOGINFO(4, "loading peers from " << seed_nodes[i]); diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 519d634..612ef92 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -55,6 +55,12 @@ p2pool::p2pool(int argc, char* argv[]) panic(); } + bool is_v6; + if (!resolve_host(m_params->m_host, is_v6)) { + LOGERR(1, "resolve_host failed for " << m_params->m_host); + panic(); + } + hash pub, sec, eph_public_key; generate_keys(pub, sec); @@ -384,7 +390,7 @@ void p2pool::submit_block() const const uint32_t nonce = submit_data.nonce; const uint32_t extra_nonce = submit_data.extra_nonce; - JSONRPCRequest::call(m_params->m_host, m_params->m_rpcPort, request.c_str(), + JSONRPCRequest::call(m_params->m_host.c_str(), m_params->m_rpcPort, request.c_str(), [height, diff, template_id, nonce, extra_nonce](const char* data, size_t size) { rapidjson::Document doc; @@ -465,7 +471,7 @@ void p2pool::download_block_headers(uint64_t current_height) s.m_pos = 0; s << "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_block_header_by_height\",\"params\":{\"height\":" << height << "}}\0"; - JSONRPCRequest::call(m_params->m_host, m_params->m_rpcPort, buf, + JSONRPCRequest::call(m_params->m_host.c_str(), m_params->m_rpcPort, buf, [this, prev_seed_height, height](const char* data, size_t size) { ChainMain block; @@ -485,7 +491,7 @@ void p2pool::download_block_headers(uint64_t current_height) s.m_pos = 0; s << "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_block_headers_range\",\"params\":{\"start_height\":" << current_height - BLOCK_HEADERS_REQUIRED << ",\"end_height\":" << current_height - 1 << "}}\0"; - JSONRPCRequest::call(m_params->m_host, m_params->m_rpcPort, buf, + JSONRPCRequest::call(m_params->m_host.c_str(), m_params->m_rpcPort, buf, [this, current_height](const char* data, size_t size) { if (parse_block_headers_range(data, size) == BLOCK_HEADERS_REQUIRED) { @@ -572,7 +578,7 @@ void p2pool::stratum_on_block() void p2pool::get_info() { - JSONRPCRequest::call(m_params->m_host, m_params->m_rpcPort, "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_info\"}", + JSONRPCRequest::call(m_params->m_host.c_str(), m_params->m_rpcPort, "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_info\"}", [this](const char* data, size_t size) { parse_get_info_rpc(data, size); @@ -658,7 +664,7 @@ void p2pool::parse_get_info_rpc(const char* data, size_t size) void p2pool::get_miner_data() { - JSONRPCRequest::call(m_params->m_host, m_params->m_rpcPort, "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_miner_data\"}", + JSONRPCRequest::call(m_params->m_host.c_str(), m_params->m_rpcPort, "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_miner_data\"}", [this](const char* data, size_t size) { parse_get_miner_data_rpc(data, size); @@ -1076,7 +1082,7 @@ int p2pool::run() } try { - ZMQReader z(m_params->m_host, m_params->m_zmqPort, this); + ZMQReader z(m_params->m_host.c_str(), m_params->m_zmqPort, this); get_info(); const int rc = uv_run(uv_default_loop_checked(), UV_RUN_DEFAULT); LOGINFO(1, "uv_run exited, result = " << rc); diff --git a/src/params.cpp b/src/params.cpp index 290208d..14cbf51 100644 --- a/src/params.cpp +++ b/src/params.cpp @@ -72,7 +72,7 @@ Params::Params(int argc, char* argv[]) bool Params::ok() const { - return m_host && m_rpcPort && m_zmqPort && m_wallet.valid(); + return !m_host.empty() && m_rpcPort && m_zmqPort && m_wallet.valid(); } } // namespace p2pool diff --git a/src/params.h b/src/params.h index 9f1afe5..4f2c5a2 100644 --- a/src/params.h +++ b/src/params.h @@ -27,7 +27,7 @@ struct Params bool ok() const; - const char* m_host = "127.0.0.1"; + std::string m_host = "127.0.0.1"; uint32_t m_rpcPort = 18081; uint32_t m_zmqPort = 18083; bool m_lightMode = false; diff --git a/src/util.cpp b/src/util.cpp index fb65741..b1105c0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -325,4 +325,42 @@ void BackgroundJobTracker::print_status() BackgroundJobTracker bkg_jobs_tracker; thread_local bool is_main_thread = false; +bool resolve_host(std::string& host, bool& is_v6) +{ + addrinfo hints{}; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; + + addrinfo* r = nullptr; + const int err = getaddrinfo(host.c_str(), nullptr, &hints, &r); + if ((err == 0) && r) { + const char* addr_str = nullptr; + char addr_str_buf[64]; + + void* addr; + if (r->ai_family == AF_INET6) { + addr = &reinterpret_cast(r->ai_addr)->sin6_addr; + is_v6 = true; + } + else { + addr = &reinterpret_cast(r->ai_addr)->sin_addr; + is_v6 = false; + } + + addr_str = inet_ntop(r->ai_family, addr, addr_str_buf, sizeof(addr_str_buf)); + if (addr_str) { + LOGINFO(5, log::LightCyan() << host << log::NoColor() << " resolved to " << log::Gray() << addr_str); + host = addr_str; + } + freeaddrinfo(r); + } + else { + LOGWARN(4, "getaddrinfo failed for " << host << ": " << gai_strerror(err)); + return false; + } + + return true; +} + } // namespace p2pool diff --git a/src/util.h b/src/util.h index a894d7f..d60e1ce 100644 --- a/src/util.h +++ b/src/util.h @@ -117,6 +117,8 @@ private: extern BackgroundJobTracker bkg_jobs_tracker; extern thread_local bool is_main_thread; +bool resolve_host(std::string& host, bool& is_v6); + } // namespace p2pool template<>