Added miner uptime to dashboard
WIP SSL/TLS for CC communication and Dashboard
This commit is contained in:
parent
e6f05b3648
commit
1b7b48f6e3
13 changed files with 146 additions and 10 deletions
|
@ -10,6 +10,7 @@ option(WITH_AEON "CryptoNight-Lite support" ON)
|
|||
option(WITH_HTTPD "HTTP REST API" OFF)
|
||||
option(WITH_CC_CLIENT "CC Client" ON)
|
||||
option(WITH_CC_SERVER "CC Server" ON)
|
||||
option(WITH_SSL_TLS "SSL/TLS support" ON)
|
||||
|
||||
include (CheckIncludeFile)
|
||||
include (cmake/cpu.cmake)
|
||||
|
@ -54,6 +55,7 @@ set(SOURCES_COMMON
|
|||
src/log/Log.cpp
|
||||
src/Platform.cpp
|
||||
src/Cpu.cpp
|
||||
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
|
@ -106,6 +108,26 @@ find_package(UV REQUIRED)
|
|||
|
||||
include(cmake/flags.cmake)
|
||||
|
||||
if (WITH_SSL_TLS)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
add_definitions(/DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
include_directories(src/3rdparty/evt-tls)
|
||||
include_directories(src/3rdparty/evt-tls/api)
|
||||
set(SOURCES_SSL_TLS
|
||||
src/3rdparty/evt-tls/src/uv_tls.c
|
||||
src/3rdparty/evt-tls/src/evt_tls.c)
|
||||
else()
|
||||
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_SSL_TLS=OFF` to build without SSL/TLS support")
|
||||
endif()
|
||||
else()
|
||||
add_definitions(/DXMRIG_NO_SSL_TLS)
|
||||
endif()
|
||||
|
||||
if (WITH_LIBCPUID)
|
||||
add_subdirectory(src/3rdparty/libcpuid)
|
||||
|
||||
|
@ -189,10 +211,10 @@ if (WITH_CC_SERVER OR WITH_CC_CLIENT)
|
|||
add_library(xmrig_cc_common STATIC ${SOURCES_CC_COMMON})
|
||||
endif (WITH_CC_SERVER OR WITH_CC_CLIENT)
|
||||
|
||||
add_executable(xmrigMiner ${SOURCES} ${SOURCES_CRYPTO} ${HTTPD_SOURCES} ${SOURCES_CC_CLIENT} res/app.rc)
|
||||
add_executable(xmrigMiner ${SOURCES} ${SOURCES_CRYPTO} ${HTTPD_SOURCES} ${SOURCES_CC_CLIENT} ${SOURCES_SSL_TLS} res/app.rc)
|
||||
|
||||
target_link_libraries(xmrigMiner xmrig_common xmrig_os_dependencies xmrig_cpuid
|
||||
${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
|
||||
${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB} ${OPENSSL_LIBRARIES})
|
||||
|
||||
if (WITH_CC_CLIENT)
|
||||
target_link_libraries(xmrigMiner xmrig_cc_common)
|
||||
|
|
10
index.html
10
index.html
|
@ -46,6 +46,7 @@
|
|||
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.0/js/buttons.bootstrap.min.js"></script>
|
||||
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/select/1.2.4/js/dataTables.select.min.js"></script>
|
||||
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.6.1/jquery.timeago.min.js"></script>
|
||||
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/2.2.1/moment-duration-format.min.js"></script>
|
||||
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
<script src="https://use.fontawesome.com/6b3cdfc597.js"></script>
|
||||
|
@ -112,6 +113,7 @@
|
|||
{data: "client_status.avg_time", className: "right"},
|
||||
{data: "client_status.shares_good", className: "right"},
|
||||
{data: "client_status.shares_total", className: "right"},
|
||||
{data: "client_status.uptime", render: uptime},
|
||||
{data: "client_status.last_status_update", render: laststatus},
|
||||
{
|
||||
data: null,
|
||||
|
@ -450,6 +452,14 @@
|
|||
});
|
||||
}
|
||||
|
||||
function uptime( data, type, row ) {
|
||||
if (type !== 'sort') {
|
||||
return moment.duration(data, "milliseconds");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function laststatus( data, type, row ) {
|
||||
if (type !== 'sort') {
|
||||
var date = new Date(data*1000 - clockDrift);
|
||||
|
|
|
@ -40,7 +40,7 @@ struct cryptonight_ctx;
|
|||
class Mem
|
||||
{
|
||||
public:
|
||||
typedef std::bitset<64> ThreadBitSet;
|
||||
typedef std::bitset<128> ThreadBitSet;
|
||||
enum Flags {
|
||||
HugepagesAvailable = 1,
|
||||
HugepagesEnabled = 2,
|
||||
|
|
|
@ -269,6 +269,8 @@ Options::Options(int argc, char **argv) :
|
|||
m_safe(false),
|
||||
m_syslog(false),
|
||||
m_daemonized(false),
|
||||
m_useTls(true),
|
||||
m_ccUseTls(true),
|
||||
m_configFile(Platform::defaultConfigName()),
|
||||
m_apiToken(nullptr),
|
||||
m_apiWorkerId(nullptr),
|
||||
|
@ -281,6 +283,8 @@ Options::Options(int argc, char **argv) :
|
|||
m_ccAdminPass(nullptr),
|
||||
m_ccClientConfigFolder(nullptr),
|
||||
m_ccCustomDashboard(nullptr),
|
||||
m_ccKeyFile(nullptr),
|
||||
m_ccCertFile(nullptr),
|
||||
m_algo(ALGO_CRYPTONIGHT),
|
||||
m_algoVariant(AV0_AUTO),
|
||||
m_aesni(AESNI_AUTO),
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
inline bool hugePages() const { return m_hugePages; }
|
||||
inline bool syslog() const { return m_syslog; }
|
||||
inline bool daemonized() const { return m_daemonized; }
|
||||
inline bool useTls() const { return m_useTls; }
|
||||
inline bool ccUseTls() const { return m_ccUseTls; }
|
||||
inline const char *configFile() const { return m_configFile; }
|
||||
inline const char *apiToken() const { return m_apiToken; }
|
||||
inline const char *apiWorkerId() const { return m_apiWorkerId; }
|
||||
|
@ -81,6 +83,8 @@ public:
|
|||
inline const char *ccAdminPass() const { return m_ccAdminPass; }
|
||||
inline const char *ccClientConfigFolder() const { return m_ccClientConfigFolder; }
|
||||
inline const char *ccCustomDashboard() const { return m_ccCustomDashboard == nullptr ? "index.html" : m_ccCustomDashboard; }
|
||||
inline const char *ccKeyFile() const { return m_ccKeyFile == nullptr ? "server.key" : m_ccKeyFile; }
|
||||
inline const char *ccCertFile() const { return m_ccCertFile == nullptr ? "server.pem" : m_ccCertFile; }
|
||||
inline const std::vector<Url*> &pools() const { return m_pools; }
|
||||
inline Algo algo() const { return m_algo; }
|
||||
inline bool aesni() const { return m_aesni == AESNI_ON; }
|
||||
|
@ -134,6 +138,8 @@ private:
|
|||
bool m_safe;
|
||||
bool m_syslog;
|
||||
bool m_daemonized;
|
||||
bool m_useTls;
|
||||
bool m_ccUseTls;
|
||||
const char* m_configFile;
|
||||
char *m_apiToken;
|
||||
char *m_apiWorkerId;
|
||||
|
@ -146,6 +152,8 @@ private:
|
|||
char *m_ccAdminPass;
|
||||
char *m_ccClientConfigFolder;
|
||||
char *m_ccCustomDashboard;
|
||||
char *m_ccKeyFile;
|
||||
char *m_ccCertFile;
|
||||
Algo m_algo;
|
||||
AlgoVariant m_algoVariant;
|
||||
AesNi m_aesni;
|
||||
|
|
|
@ -92,6 +92,8 @@ CCClient::CCClient(Options* options, uv_async_t* async)
|
|||
m_clientStatus.setCpuL3(Cpu::l3());
|
||||
m_clientStatus.setCurrentThreads(m_options->threads());
|
||||
|
||||
m_startTime = std::chrono::system_clock::now();
|
||||
|
||||
if (m_options->ccToken() != nullptr) {
|
||||
m_authorization = std::string("Bearer ") + m_self->m_options->ccToken();
|
||||
}
|
||||
|
@ -138,6 +140,8 @@ void CCClient::updateNetworkState(const NetworkState& network)
|
|||
|
||||
void CCClient::publishClientStatusReport()
|
||||
{
|
||||
refreshUptime();
|
||||
|
||||
std::string requestUrl = "/client/setClientStatus?clientId=" + m_self->m_clientStatus.getClientId();
|
||||
std::string requestBuffer = m_self->m_clientStatus.toJsonString();
|
||||
|
||||
|
@ -256,7 +260,17 @@ std::shared_ptr<httplib::Response> CCClient::performRequest(const std::string& r
|
|||
const std::string& requestBuffer,
|
||||
const std::string& operation)
|
||||
{
|
||||
httplib::Client cli(m_self->m_options->ccHost(), m_self->m_options->ccPort());
|
||||
std::shared_ptr<httplib::Client> cli;
|
||||
|
||||
# ifndef XMRIG_NO_SSL_TLS
|
||||
if (m_self->m_options->ccUseTls()) {
|
||||
cli = std::make_shared<httplib::SSLClient>(m_self->m_options->ccHost(), m_self->m_options->ccPort());
|
||||
}
|
||||
# endif
|
||||
|
||||
if (!cli) {
|
||||
cli = std::make_shared<httplib::Client>(m_self->m_options->ccHost(), m_self->m_options->ccPort());
|
||||
}
|
||||
|
||||
httplib::Request req;
|
||||
req.method = operation;
|
||||
|
@ -277,7 +291,15 @@ std::shared_ptr<httplib::Response> CCClient::performRequest(const std::string& r
|
|||
|
||||
auto res = std::make_shared<httplib::Response>();
|
||||
|
||||
return cli.send(req, *res) ? res : nullptr;
|
||||
return cli->send(req, *res) ? res : nullptr;
|
||||
}
|
||||
|
||||
void CCClient::refreshUptime()
|
||||
{
|
||||
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
|
||||
auto uptime = std::chrono::duration_cast<std::chrono::milliseconds>(m_self->m_startTime - now);
|
||||
|
||||
m_self->m_clientStatus.setUptime(static_cast<uint64_t>(uptime.count()));
|
||||
}
|
||||
|
||||
void CCClient::onThreadStarted(void* handle)
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#ifndef XMRIG_NO_CC
|
||||
|
||||
#include <uv.h>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <3rdparty/cpp-httplib/httplib.h>
|
||||
#include "Options.h"
|
||||
#include "ClientStatus.h"
|
||||
|
@ -65,11 +67,14 @@ private:
|
|||
|
||||
std::string m_authorization;
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> m_startTime;
|
||||
|
||||
uv_async_t* m_async;
|
||||
uv_timer_t m_timer;
|
||||
uv_loop_t m_client_loop;
|
||||
uv_thread_t m_thread;
|
||||
|
||||
static void refreshUptime();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -90,7 +90,7 @@ CCServer::~CCServer()
|
|||
int CCServer::start()
|
||||
{
|
||||
if (!m_options) {
|
||||
return 0;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
uv_signal_start(&m_signal, CCServer::onSignal, SIGHUP);
|
||||
|
@ -106,7 +106,9 @@ int CCServer::start()
|
|||
Service::start();
|
||||
|
||||
m_httpd = new Httpd(m_options);
|
||||
m_httpd->start();
|
||||
if (!m_httpd->start()) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
uv_loop_close(uv_default_loop());
|
||||
|
|
|
@ -51,6 +51,7 @@ ClientStatus::ClientStatus()
|
|||
m_sharesGood(0),
|
||||
m_sharesTotal(0),
|
||||
m_hashesTotal(0),
|
||||
m_uptime(0),
|
||||
m_avgTime(0),
|
||||
m_lastStatusUpdate(0)
|
||||
{
|
||||
|
@ -321,6 +322,16 @@ std::time_t ClientStatus::getLastStatusUpdate() const
|
|||
return m_lastStatusUpdate;
|
||||
}
|
||||
|
||||
uint64_t ClientStatus::getUptime() const
|
||||
{
|
||||
return m_uptime;
|
||||
}
|
||||
|
||||
void ClientStatus::setUptime(uint64_t uptime)
|
||||
{
|
||||
m_uptime = uptime;
|
||||
}
|
||||
|
||||
bool ClientStatus::parseFromJson(const rapidjson::Document& document)
|
||||
{
|
||||
bool result = false;
|
||||
|
@ -433,6 +444,10 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
|
|||
m_avgTime = clientStatus["avg_time"].GetUint();
|
||||
}
|
||||
|
||||
if (clientStatus.HasMember("uptime")) {
|
||||
m_uptime = clientStatus["uptime"].GetUint64();
|
||||
}
|
||||
|
||||
auto time_point = std::chrono::system_clock::now();
|
||||
m_lastStatusUpdate = std::chrono::system_clock::to_time_t(time_point);
|
||||
|
||||
|
@ -481,6 +496,8 @@ rapidjson::Value ClientStatus::toJson(rapidjson::MemoryPoolAllocator<rapidjson::
|
|||
|
||||
clientStatus.AddMember("avg_time", m_avgTime, allocator);
|
||||
|
||||
clientStatus.AddMember("uptime", m_uptime, allocator);
|
||||
|
||||
clientStatus.AddMember("last_status_update", static_cast<uint64_t >(m_lastStatusUpdate), allocator);
|
||||
|
||||
return clientStatus;
|
||||
|
|
|
@ -137,6 +137,9 @@ public:
|
|||
|
||||
std::time_t getLastStatusUpdate() const;
|
||||
|
||||
void setUptime(uint64_t uptime);
|
||||
uint64_t getUptime() const;
|
||||
|
||||
std::string toJsonString();
|
||||
rapidjson::Value toJson(rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>& allocator);
|
||||
bool parseFromJson(const rapidjson::Document& document);
|
||||
|
@ -179,6 +182,7 @@ private:
|
|||
uint64_t m_sharesGood;
|
||||
uint64_t m_sharesTotal;
|
||||
uint64_t m_hashesTotal;
|
||||
uint64_t m_uptime;
|
||||
|
||||
uint32_t m_avgTime;
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <microhttpd.h>
|
||||
#include <memory>
|
||||
|
||||
|
@ -43,8 +45,30 @@ bool Httpd::start()
|
|||
return false;
|
||||
}
|
||||
|
||||
m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, static_cast<uint16_t>(m_options->ccPort()), nullptr, nullptr, &Httpd::handler,
|
||||
this, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 10, MHD_OPTION_END);
|
||||
# ifndef XMRIG_NO_SSL_TLS
|
||||
if (m_options->ccUseTls()) {
|
||||
|
||||
m_keyPem = readFile(m_options->ccKeyFile());
|
||||
m_certPem = readFile(m_options->ccCertFile());
|
||||
|
||||
if (m_keyPem.length() == 0 || m_certPem.length() == 0) {
|
||||
LOG_ERR("HTTPS Daemon failed to start. Unable to load Key/Cert.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL,
|
||||
static_cast<uint16_t>(m_options->ccPort()), nullptr, nullptr, &Httpd::handler,
|
||||
this, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 10,
|
||||
MHD_OPTION_HTTPS_MEM_KEY, m_keyPem,
|
||||
MHD_OPTION_HTTPS_MEM_CERT, m_certPem,
|
||||
MHD_OPTION_END);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (!m_daemon) {
|
||||
m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, static_cast<uint16_t>(m_options->ccPort()), nullptr, nullptr, &Httpd::handler,
|
||||
this, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 10, MHD_OPTION_END);
|
||||
}
|
||||
|
||||
if (!m_daemon) {
|
||||
LOG_ERR("HTTP Daemon failed to start.");
|
||||
|
@ -56,6 +80,18 @@ bool Httpd::start()
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string Httpd::readFile(const std::string &fileName)
|
||||
{
|
||||
std::stringstream data;
|
||||
std::ifstream file(fileName);
|
||||
if (file) {
|
||||
data << file.rdbuf();
|
||||
file.close();
|
||||
}
|
||||
|
||||
return data.str();
|
||||
}
|
||||
|
||||
unsigned Httpd::tokenAuth(struct MHD_Connection* connection)
|
||||
{
|
||||
if (!m_options->ccToken()) {
|
||||
|
|
|
@ -58,9 +58,13 @@ private:
|
|||
static int handleGET(const Httpd* httpd, MHD_Connection* connection, const char* url);
|
||||
static int handlePOST(const Httpd* httpd, MHD_Connection* connection, const char* url, const char* upload_data, size_t* upload_data_size, void** con_cls);
|
||||
|
||||
const Options* m_options;
|
||||
static std::string readFile(const std::string &fileName);
|
||||
|
||||
const Options* m_options;
|
||||
MHD_Daemon* m_daemon;
|
||||
|
||||
std::string m_keyPem;
|
||||
std::string m_certPem;
|
||||
};
|
||||
|
||||
#endif /* __HTTPD_H__ */
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <uv.h>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#include "net/Job.h"
|
||||
|
@ -124,6 +125,7 @@ private:
|
|||
# ifndef XMRIG_PROXY_PROJECT
|
||||
uv_timer_t m_keepAliveTimer;
|
||||
# endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue