diff --git a/src/api/Api.cpp b/src/api/Api.cpp index d1bac212e..a11325f32 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -38,6 +38,7 @@ #include "api/v1/ApiRouter.h" #include "base/kernel/Base.h" #include "base/tools/Buffer.h" +#include "base/tools/Chrono.h" #include "common/crypto/keccak.h" #include "core/config/Config.h" #include "core/Controller.h" @@ -53,7 +54,8 @@ xmrig::Api::Api(Base *base) : m_base(base), m_id(), m_workerId(), - m_httpd(nullptr) + m_httpd(nullptr), + m_timestamp(Chrono::steadyMSecs()) { base->addListener(this); @@ -118,9 +120,12 @@ void xmrig::Api::exec(IApiRequest &request) using namespace rapidjson; if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) { + auto &allocator = request.doc().GetAllocator(); + request.accept(); - request.reply().AddMember("id", StringRef(m_id), request.doc().GetAllocator()); - request.reply().AddMember("worker_id", StringRef(m_workerId), request.doc().GetAllocator());; + request.reply().AddMember("id", StringRef(m_id), allocator); + request.reply().AddMember("worker_id", StringRef(m_workerId), allocator); + request.reply().AddMember("uptime", (Chrono::steadyMSecs() - m_timestamp) / 1000, allocator); } for (IApiListener *listener : m_listeners) { diff --git a/src/api/Api.h b/src/api/Api.h index 0c7fac524..eef57c3a4 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -27,6 +27,7 @@ #include +#include #include "base/kernel/interfaces/IBaseListener.h" @@ -72,6 +73,7 @@ private: char m_workerId[128]; Httpd *m_httpd; std::vector m_listeners; + uint64_t m_timestamp; }; diff --git a/src/base/tools/String.h b/src/base/tools/String.h index eb0a18207..2c47d8501 100644 --- a/src/base/tools/String.h +++ b/src/base/tools/String.h @@ -80,6 +80,7 @@ public: inline String &operator=(char *str) { move(str); return *this; } inline String &operator=(const char *str) { copy(str); return *this; } inline String &operator=(const String &str) { copy(str); return *this; } + inline String &operator=(std::nullptr_t) { delete [] m_data; m_data = nullptr; m_size = 0; return *this; } inline String &operator=(String &&other) { move(std::move(other)); return *this; } rapidjson::Value toJSON() const; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 32cad6a6e..1ab422368 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -100,7 +100,7 @@ void xmrig::Network::onActive(IStrategy *strategy, IClient *client) return; } - m_state.setPool(client->pool().host(), client->pool().port(), client->ip()); + m_state.onActive(client); const char *tlsVersion = client->tlsVersion(); LOG_INFO(WHITE_BOLD("use %s ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " " BLACK_BOLD("%s"), @@ -235,11 +235,14 @@ void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document reply.AddMember("algo", StringRef((algo.isValid() ? algo : m_controller->config()->algorithm()).shortName()), allocator); Value connection(kObjectType); - connection.AddMember("pool", StringRef(m_state.pool), allocator); - connection.AddMember("uptime", m_state.connectionTime(), allocator); - connection.AddMember("ping", m_state.latency(), allocator); - connection.AddMember("failures", m_state.failures, allocator); - connection.AddMember("error_log", Value(kArrayType), allocator); + connection.AddMember("pool", StringRef(m_state.pool), allocator); + connection.AddMember("ip", m_state.ip().toJSON(), allocator); + connection.AddMember("uptime", m_state.connectionTime(), allocator); + connection.AddMember("ping", m_state.latency(), allocator); + connection.AddMember("failures", m_state.failures, allocator); + connection.AddMember("tls", m_state.tls().toJSON(), allocator); + connection.AddMember("tls-fingerprint", m_state.fingerprint().toJSON(), allocator); + connection.AddMember("error_log", Value(kArrayType), allocator); reply.AddMember("connection", connection, allocator); } diff --git a/src/net/NetworkState.cpp b/src/net/NetworkState.cpp index e495773a8..6868f57e2 100644 --- a/src/net/NetworkState.cpp +++ b/src/net/NetworkState.cpp @@ -29,6 +29,8 @@ #include +#include "base/kernel/interfaces/IClient.h" +#include "base/net/stratum/Pool.h" #include "base/net/stratum/SubmitResult.h" #include "base/tools/Chrono.h" #include "net/NetworkState.h" @@ -96,19 +98,25 @@ void xmrig::NetworkState::add(const SubmitResult &result, const char *error) } -void xmrig::NetworkState::setPool(const char *host, int port, const char *ip) +void xmrig::NetworkState::onActive(IClient *client) { - snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port); + snprintf(pool, sizeof(pool) - 1, "%s:%d", client->pool().host().data(), client->pool().port()); - m_active = true; + m_ip = client->ip(); + m_tls = client->tlsVersion(); + m_fingerprint = client->tlsFingerprint(); + m_active = true; m_connectionTime = Chrono::steadyMSecs(); } void xmrig::NetworkState::stop() { - m_active = false; - diff = 0; + m_active = false; + diff = 0; + m_ip = nullptr; + m_tls = nullptr; + m_fingerprint = nullptr; failures++; m_latency.clear(); diff --git a/src/net/NetworkState.h b/src/net/NetworkState.h index cf9a649a0..ce56ec725 100644 --- a/src/net/NetworkState.h +++ b/src/net/NetworkState.h @@ -30,9 +30,13 @@ #include +#include "base/tools/String.h" + + namespace xmrig { +class IClient; class SubmitResult; @@ -41,11 +45,15 @@ class NetworkState public: NetworkState(); + inline const String &fingerprint() const { return m_fingerprint; } + inline const String &ip() const { return m_ip; } + inline const String &tls() const { return m_tls; } + uint32_t avgTime() const; uint32_t latency() const; uint64_t connectionTime() const; void add(const SubmitResult &result, const char *error); - void setPool(const char *host, int port, const char *ip); + void onActive(IClient *client); void stop(); char pool[256]; @@ -59,6 +67,9 @@ public: private: bool m_active; std::vector m_latency; + String m_fingerprint; + String m_ip; + String m_tls; uint64_t m_connectionTime; };