diff --git a/index.html b/index.html
index 7bf56f41..7ae349e9 100644
--- a/index.html
+++ b/index.html
@@ -12,6 +12,8 @@
.right{text-align:right;}
.center{text-align:center;}
.toolbar { float: right; padding-left: 10pt;}
+ .online { color: green}
+ .offline { color: red}
@@ -26,10 +28,7 @@ $.fn.dataTable.ext.search.push(
var hide = document.getElementById("hideOffline").checked;
var lastStatus = settings.aoData[dataIndex]._aData.client_status.last_status_update * 1000;
- var threshold = new Date().getTime() - 10*60*1000;
-
- console.log("lastStatus: " + new Date(lastStatus));
- console.log("threshold: " + new Date(threshold));
+ var threshold = new Date().getTime() - 60 * 1000;
if (lastStatus > threshold || !hide) {
return true;
@@ -50,7 +49,7 @@ $(document).ready(function() {
dataSrc : 'client_status_list'
},
columns: [
- { data: "client_status.client_id"},
+ { data: "client_status.client_id", render: clientInfo},
{ data: "client_status.current_pool"},
{ data: "client_status.current_status"},
{ data: "client_status.current_algo_name"},
@@ -138,14 +137,14 @@ $(document).ready(function() {
}, 0 );
// Update footer
- $( api.column(4).footer()).html(sumHashrateShort);
- $( api.column(5).footer()).html(sumHashrateMedium);
- $( api.column(6).footer()).html(sumHashrateLong);
- $( api.column(7).footer()).html(sumHashrateHighest);
- $( api.column(8).footer()).html(sumHashesTotal);
- $( api.column(9).footer()).html(avgTimeTotal);
- $( api.column(10).footer()).html(sumSharesGood);
- $( api.column(11).footer()).html(sumSharedTotal);
+ $(api.column(4).footer()).html(sumHashrateShort);
+ $(api.column(5).footer()).html(sumHashrateMedium);
+ $(api.column(6).footer()).html(sumHashrateLong);
+ $(api.column(7).footer()).html(sumHashrateHighest);
+ $(api.column(8).footer()).html(sumHashesTotal);
+ $(api.column(9).footer()).html(avgTimeTotal);
+ $(api.column(10).footer()).html(sumSharesGood);
+ $(api.column(11).footer()).html(sumSharedTotal);
}
});
@@ -179,7 +178,7 @@ $(document).ready(function() {
var htmlContent = "
" +
""+
"" +
"
";
@@ -187,7 +186,7 @@ $(document).ready(function() {
$('#editConfig').modal('show');
},
error: function (data) {
- alert("Unable to fetch " + clientId + "_config.json or default_config.json, please check your configuration!");
+ alert("Unable to fetch " + clientId + "_config.json or default_config.json, please check your Server configuration and the the config files are located on the Server!");
}
});
}
@@ -223,9 +222,40 @@ $(document).ready(function() {
function laststatus( data, type, row ) {
var date = new Date(data*1000);
+
return '' + jQuery.timeago(date) + '';
}
+function clientInfo( data, type, row ) {
+ var tooltip = "CPU: " + row.client_status.cpu_brand;
+ tooltip += '\n';
+ tooltip += "CPU Flags: " + (row.client_status.cpu_has_aes ? "AES-NI " : "");
+ tooltip += (row.client_status.cpu_is_x64 ? "x64" : "");
+ tooltip += '\n';
+ tooltip += "CPU Cache L2/L3: " + (row.client_status.cpu_l2 / 1024) + " MB/"+ (row.client_status.cpu_l3 / 1024) + " MB";
+ tooltip += '\n';
+ tooltip += "Huge Pages: " + (row.client_status.hugepages_available ? " available, " : " unavailable, ");
+ tooltip += (row.client_status.hugepages_enabled ? "enabled" : "disabled");
+ tooltip += '\n';
+ tooltip += "Threads: " + row.client_status.current_threads;
+ tooltip += (row.client_status.double_hash_mode ? " [double hash mode]" :"");
+ tooltip += '\n';
+ tooltip += "Client IP: " + row.client_status.external_ip;
+ tooltip += '\n';
+ tooltip += "Status: ";
+
+ var lastStatus = row.client_status.last_status_update * 1000;
+ var threshold = new Date().getTime() - 60 * 1000;
+ if (lastStatus > threshold) {
+ tooltip += "Online";
+ return '' + data + '
';
+ }
+ else {
+ tooltip += "Offline";
+ return '' + data + '
';
+ }
+}
+
function round( data, type, row ) {
return Math.round(data * 100) / 100;
}
diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp
index 471690ef..69d4b672 100644
--- a/src/cc/CCClient.cpp
+++ b/src/cc/CCClient.cpp
@@ -25,10 +25,12 @@
#include
#include <3rdparty/rapidjson/stringbuffer.h>
#include <3rdparty/rapidjson/prettywriter.h>
-#include
#include "CCClient.h"
#include "App.h"
+#include "Platform.h"
+#include "Cpu.h"
+#include "Mem.h"
#include "ControlCommand.h"
#include "api/NetworkState.h"
@@ -69,6 +71,19 @@ CCClient::CCClient(const Options *options)
m_clientStatus.setCurrentAlgoName(m_options->algoName());
}
+ m_clientStatus.setHugepagesEnabled(Mem::isHugepagesEnabled());
+ m_clientStatus.setHugepages(Mem::isHugepagesAvailable());
+ m_clientStatus.setDoubleHashMode(Mem::isDoubleHash());
+
+ m_clientStatus.setCpuBrand(Cpu::brand());
+ m_clientStatus.setCpuAES(Cpu::hasAES());
+ m_clientStatus.setCpuCores(Cpu::cores());
+ m_clientStatus.setCpuX64(Cpu::isX64());
+
+ m_clientStatus.setCpuL2(Cpu::l2());
+ m_clientStatus.setCpuL3(Cpu::l3());
+ m_clientStatus.setCurrentThreads(Cpu::threads());
+
if (m_options->ccToken() != nullptr) {
m_authorization = std::string("Bearer ") + m_self->m_options->ccToken();
}
diff --git a/src/cc/ClientStatus.cpp b/src/cc/ClientStatus.cpp
index ad9ca03b..3382e558 100644
--- a/src/cc/ClientStatus.cpp
+++ b/src/cc/ClientStatus.cpp
@@ -43,6 +43,16 @@ ClientStatus::ClientStatus()
}
+ClientStatus::Status ClientStatus::getCurrentStatus() const
+{
+ return m_currentStatus;
+}
+
+void ClientStatus::setCurrentStatus(Status currentStatus)
+{
+ m_currentStatus = currentStatus;
+}
+
std::string ClientStatus::getClientId() const
{
return m_clientId;
@@ -73,14 +83,74 @@ std::string ClientStatus::getCurrentAlgoName() const
return m_currentAlgoName;
}
-ClientStatus::Status ClientStatus::getCurrentStatus() const
+std::string ClientStatus::getCpuBrand() const
{
- return m_currentStatus;
+ return m_cpuBrand;
}
-void ClientStatus::setCurrentStatus(Status currentStatus)
+void ClientStatus::setCpuBrand(const std::string& cpuBrand)
{
- m_currentStatus = currentStatus;
+ m_cpuBrand = cpuBrand;
+}
+
+std::string ClientStatus::getExternalIp() const
+{
+ return m_externalIp;
+}
+
+void ClientStatus::setExternalIp(const std::string& externalIp)
+{
+ m_externalIp = externalIp;
+}
+
+bool ClientStatus::hasHugepages() const
+{
+ return m_hasHugepages;
+}
+
+void ClientStatus::setHugepages(bool hasHugepages)
+{
+ m_hasHugepages = hasHugepages;
+}
+
+bool ClientStatus::isHugepagesEnabled() const
+{
+ return m_isHugepagesEnabled;
+}
+
+void ClientStatus::setHugepagesEnabled(bool hugepagesEnabled)
+{
+ m_isHugepagesEnabled = hugepagesEnabled;
+}
+
+bool ClientStatus::isDoubleHashMode() const
+{
+ return m_isDoubleHashMode;
+}
+
+void ClientStatus::setDoubleHashMode(bool isDoubleHashMode)
+{
+ m_isDoubleHashMode = isDoubleHashMode;
+}
+
+bool ClientStatus::isCpuX64() const
+{
+ return m_isCpuX64;
+}
+
+void ClientStatus::setCpuX64(bool isCpuX64)
+{
+ m_isCpuX64 = isCpuX64;
+}
+
+bool ClientStatus::hasCpuAES() const
+{
+ return m_hasCpuAES;
+}
+
+void ClientStatus::setCpuAES(bool hasCpuAES)
+{
+ m_hasCpuAES = hasCpuAES;
}
double ClientStatus::getHashrateShort() const
@@ -113,6 +183,56 @@ void ClientStatus::setHashrateLong(double hashrateLong)
m_hashrateLong = hashrateLong;
}
+void ClientStatus::setHashrateHighest(double hashrateHighest)
+{
+ m_hashrateHighest = hashrateHighest;
+}
+
+double ClientStatus::getHashrateHighest() const
+{
+ return m_hashrateHighest;
+}
+
+int ClientStatus::getCurrentThreads() const
+{
+ return m_currentThreads;
+}
+
+void ClientStatus::setCurrentThreads(int currentThreads)
+{
+ m_currentThreads = currentThreads;
+}
+
+int ClientStatus::getCpuCores() const
+{
+ return m_cpuCores;
+}
+
+void ClientStatus::setCpuCores(int cpuCores)
+{
+ m_cpuCores = cpuCores;
+}
+
+int ClientStatus::getCpuL2() const
+{
+ return m_cpuL2;
+}
+
+void ClientStatus::setCpuL2(int cpuL2)
+{
+ m_cpuL2 = cpuL2;
+}
+
+int ClientStatus::getCpuL3() const
+{
+ return m_cpuL3;
+}
+
+void ClientStatus::setCpuL3(int cpuL3)
+{
+ m_cpuL3 = cpuL3;
+}
+
uint64_t ClientStatus::getSharesGood() const
{
return m_sharesGood;
@@ -142,17 +262,6 @@ void ClientStatus::setHashesTotal(uint64_t hashesTotal)
{
m_hashesTotal = hashesTotal;
}
-
-void ClientStatus::setHashrateHighest(double hashrateHighest)
-{
- m_hashrateHighest = hashrateHighest;
-}
-
-double ClientStatus::getHashrateHighest() const
-{
- return m_hashrateHighest;
-}
-
void ClientStatus::setAvgTime(uint32_t avgTime)
{
m_avgTime = avgTime;
@@ -176,6 +285,10 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
{
rapidjson::Value::ConstObject clientStatus = document["client_status"].GetObject();
+ if (clientStatus.HasMember("current_status")) {
+ m_currentStatus = toStatus(clientStatus["current_status"].GetString());
+ }
+
if (clientStatus.HasMember("client_id")) {
m_clientId = clientStatus["client_id"].GetString();
}
@@ -184,14 +297,38 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
m_currentPool = clientStatus["current_pool"].GetString();
}
- if (clientStatus.HasMember("current_status")) {
- m_currentStatus = toStatus(clientStatus["current_status"].GetString());
- }
-
if (clientStatus.HasMember("current_algo_name")) {
m_currentAlgoName = clientStatus["current_algo_name"].GetString();
}
+ if (clientStatus.HasMember("cpu_brand")) {
+ m_cpuBrand = clientStatus["cpu_brand"].GetString();
+ }
+
+ if (clientStatus.HasMember("external_ip")) {
+ m_externalIp = clientStatus["external_ip"].GetString();
+ }
+
+ if (clientStatus.HasMember("hugepages_available")) {
+ m_hasHugepages = clientStatus["hugepages_available"].GetBool();
+ }
+
+ if (clientStatus.HasMember("hugepages_enabled")) {
+ m_isHugepagesEnabled = clientStatus["hugepages_enabled"].GetBool();
+ }
+
+ if (clientStatus.HasMember("double_hash_mode")) {
+ m_isDoubleHashMode = clientStatus["double_hash_mode"].GetBool();
+ }
+
+ if (clientStatus.HasMember("cpu_is_x64")) {
+ m_isCpuX64 = clientStatus["cpu_is_x64"].GetBool();
+ }
+
+ if (clientStatus.HasMember("cpu_has_aes")) {
+ m_hasCpuAES = clientStatus["cpu_has_aes"].GetBool();
+ }
+
if (clientStatus.HasMember("hashrate_short")) {
m_hashrateShort = clientStatus["hashrate_short"].GetDouble();
}
@@ -208,8 +345,20 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
m_hashrateHighest = clientStatus["hashrate_highest"].GetDouble();
}
- if (clientStatus.HasMember("avg_time")) {
- m_avgTime = clientStatus["avg_time"].GetUint();
+ if (clientStatus.HasMember("current_threads")) {
+ m_currentThreads = clientStatus["current_threads"].GetInt();
+ }
+
+ if (clientStatus.HasMember("cpu_cores")) {
+ m_cpuCores = clientStatus["cpu_cores"].GetInt();
+ }
+
+ if (clientStatus.HasMember("cpu_l2")) {
+ m_cpuL2 = clientStatus["cpu_l2"].GetInt();
+ }
+
+ if (clientStatus.HasMember("cpu_l3")) {
+ m_cpuL3 = clientStatus["cpu_l3"].GetInt();
}
if (clientStatus.HasMember("shares_good")) {
@@ -224,6 +373,10 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
m_hashesTotal = clientStatus["hashes_total"].GetUint64();
}
+ if (clientStatus.HasMember("avg_time")) {
+ m_avgTime = clientStatus["avg_time"].GetUint();
+ }
+
auto time_point = std::chrono::system_clock::now();
m_lastStatusUpdate = std::chrono::system_clock::to_time_t(time_point);
@@ -239,21 +392,36 @@ rapidjson::Value ClientStatus::toJson(rapidjson::MemoryPoolAllocator
#include
-#include "rapidjson/document.h"
+#include
class ClientStatus
{
@@ -58,6 +58,9 @@ public:
return Status::RUNNING;
}
+ Status getCurrentStatus() const;
+ void setCurrentStatus(Status currentStatus);
+
std::string getClientId() const;
void setClientId(const std::string& clientId);
@@ -67,8 +70,26 @@ public:
std::string getCurrentAlgoName() const;
void setCurrentAlgoName(const std::string &algoName);
- Status getCurrentStatus() const;
- void setCurrentStatus(Status currentStatus);
+ std::string getCpuBrand() const;
+ void setCpuBrand(const std::string &cpuBrand);
+
+ std::string getExternalIp() const;
+ void setExternalIp(const std::string &externalIp);
+
+ bool hasHugepages() const;
+ void setHugepages(bool hasHugepages);
+
+ bool isHugepagesEnabled() const;
+ void setHugepagesEnabled(bool hugepagesEnabled);
+
+ bool isDoubleHashMode() const;
+ void setDoubleHashMode(bool isDoubleHashMode);
+
+ bool isCpuX64() const;
+ void setCpuX64(bool isCpuX64);
+
+ bool hasCpuAES() const;
+ void setCpuAES(bool hasCpuAES);
double getHashrateShort() const;
void setHashrateShort(double hashrateShort);
@@ -79,6 +100,21 @@ public:
double getHashrateLong() const;
void setHashrateLong(double hashrateLong);
+ void setHashrateHighest(double hashrateHighest);
+ double getHashrateHighest() const;
+
+ int getCurrentThreads() const;
+ void setCurrentThreads(int currentThreads);
+
+ int getCpuCores() const;
+ void setCpuCores(int cpuCores);
+
+ int getCpuL2() const;
+ void setCpuL2(int cpuL2);
+
+ int getCpuL3() const;
+ void setCpuL3(int cpuL3);
+
uint64_t getSharesGood() const;
void setSharesGood(uint64_t sharesGood);
@@ -88,9 +124,6 @@ public:
uint64_t getHashesTotal() const;
void setHashesTotal(uint64_t hashesTotal);
- void setHashrateHighest(double hashrateHighest);
- double getHashrateHighest() const;
-
void setAvgTime(uint32_t avgTime);
uint32_t getAvgTime() const;
@@ -113,12 +146,25 @@ private:
std::string m_clientId;
std::string m_currentPool;
std::string m_currentAlgoName;
+ std::string m_cpuBrand;
+ std::string m_externalIp;
+
+ bool m_hasHugepages;
+ bool m_isHugepagesEnabled;
+ bool m_isDoubleHashMode;
+ bool m_isCpuX64;
+ bool m_hasCpuAES;
double m_hashrateShort;
double m_hashrateMedium;
double m_hashrateLong;
double m_hashrateHighest;
+ int m_currentThreads;
+ int m_cpuCores;
+ int m_cpuL2;
+ int m_cpuL3;
+
uint64_t m_sharesGood;
uint64_t m_sharesTotal;
uint64_t m_hashesTotal;
diff --git a/src/cc/Httpd.cpp b/src/cc/Httpd.cpp
index 6b0a95a1..ecee7e3f 100644
--- a/src/cc/Httpd.cpp
+++ b/src/cc/Httpd.cpp
@@ -212,15 +212,26 @@ int Httpd::handlePOST(const Httpd* httpd, struct MHD_Connection* connection, con
} else {
std::string resp;
std::string url(urlPtr);
+ std::string clientIp;
std::string clientId;
+ const MHD_ConnectionInfo *info = MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
+ if (info) {
+ char clientHost[NI_MAXHOST];
+ int ec = getnameinfo(info->client_addr, sizeof(*info->client_addr), clientHost, sizeof(clientHost),
+ 0, 0, NI_NUMERICHOST|NI_NUMERICSERV);
+
+ if (ec == 0) {
+ clientIp = std::string(clientHost);
+ }
+ }
+
const char* clientIdPtr = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "clientId");
- if (clientIdPtr)
- {
+ if (clientIdPtr) {
clientId = std::string(clientIdPtr);
}
- unsigned status = Service::handlePOST(httpd->m_options, url, clientId, cc->data.str(), resp);
+ unsigned status = Service::handlePOST(httpd->m_options, url, clientIp, clientId, cc->data.str(), resp);
MHD_Response* rsp = nullptr;
if (!resp.empty()) {
diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp
index f8a2ca7e..ed8a6bd3 100644
--- a/src/cc/Service.cpp
+++ b/src/cc/Service.cpp
@@ -86,16 +86,18 @@ unsigned Service::handleGET(const Options* options, const std::string& url, cons
return resultCode;
}
-unsigned Service::handlePOST(const Options* options, const std::string& url, const std::string& clientId, const std::string& data, std::string& resp)
+unsigned Service::handlePOST(const Options* options, const std::string& url, const std::string& clientIp,
+ const std::string& clientId, const std::string& data, std::string& resp)
{
uv_mutex_lock(&m_mutex);
unsigned resultCode = MHD_HTTP_NOT_FOUND;
- LOG_INFO("POST(url='%s', clientId='%s', dataLen='%d')", url.c_str(), clientId.c_str(), data.length());
+ LOG_INFO("POST(url='%s', clientIp='%s', clientId='%s', dataLen='%d')",
+ url.c_str(), clientId.c_str(), clientIp.c_str(), data.length());
if (url.rfind("/client/setClientStatus", 0) == 0) {
- resultCode = setClientStatus(clientId, data, resp);
+ resultCode = setClientStatus(clientIp, clientId, data, resp);
} else if (url.rfind("/admin/setClientConfig", 0) == 0) {
resultCode = setClientConfig(options, clientId, data, resp);
} else if (url.rfind("/admin/setClientCommand", 0) == 0) {
@@ -204,7 +206,7 @@ unsigned Service::getClientStatusList(std::string& resp)
return MHD_HTTP_OK;
}
-unsigned Service::setClientStatus(const std::string& clientId, const std::string& data, std::string& resp)
+unsigned Service::setClientStatus(const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp)
{
int resultCode = MHD_HTTP_BAD_REQUEST;
@@ -214,6 +216,7 @@ unsigned Service::setClientStatus(const std::string& clientId, const std::string
ClientStatus clientStatus;
clientStatus.parseFromJson(document);
+ clientStatus.setExternalIp(clientIp);
m_clientStatus[clientId] = clientStatus;
diff --git a/src/cc/Service.h b/src/cc/Service.h
index a80c9387..28767d43 100644
--- a/src/cc/Service.h
+++ b/src/cc/Service.h
@@ -43,7 +43,7 @@ public:
static void release();
static unsigned handleGET(const Options* options, const std::string& url, const std::string& clientId, std::string& resp);
- static unsigned handlePOST(const Options* options, const std::string& url, const std::string& clientId, const std::string& data, std::string& resp);
+ static unsigned handlePOST(const Options* options, const std::string& url, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
private:
static unsigned getClientConfig(const Options* options, const std::string& clientId, std::string& resp);
@@ -51,7 +51,7 @@ private:
static unsigned getClientStatusList(std::string& resp);
static unsigned getAdminPage(const Options* options, std::string& resp);
- static unsigned setClientStatus(const std::string& clientId, const std::string& data, std::string& resp);
+ static unsigned setClientStatus(const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp);
static unsigned setClientCommand(const std::string& clientId, const std::string& data, std::string& resp);
static unsigned setClientConfig(const Options* options, const std::string &clientId, const std::string &data, std::string &resp);
diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp
index d14a4738..3f795190 100644
--- a/src/net/strategies/DonateStrategy.cpp
+++ b/src/net/strategies/DonateStrategy.cpp
@@ -49,7 +49,7 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
keccak(reinterpret_cast(user), static_cast(strlen(user)), hash, sizeof(hash));
Job::toHex(hash, 32, userId);
- Url *url = new Url("donate.graef.in", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 4444, userId, nullptr, false, true);
+ Url *url = new Url("donate.graef.in", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 80 : 443, userId, nullptr, false, true);
m_client = new Client(-1, agent, this);
m_client->setUrl(url);
diff --git a/src/version.h b/src/version.h
index 1ede7cc3..3a779dee 100644
--- a/src/version.h
+++ b/src/version.h
@@ -29,22 +29,21 @@
#define APP_ID "xmrigCC"
#define APP_NAME "XMRigCC"
#define APP_DESC "XMRigCC Command'n'Control Server"
-#define APP_VERSION "1.0.9"
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
# else
#define APP_ID "xmrigCC"
#define APP_NAME "XMRigCC"
#define APP_DESC "XMRigCC CPU miner"
-#define APP_VERSION "2.4.2"
#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id"
#endif
+#define APP_VERSION "1.0.9 (based on XMRig 2.4.2)"
#define APP_DOMAIN ""
#define APP_SITE "https://github.com/Bendr0id/xmrigCC"
#define APP_KIND "cpu"
-#define APP_VER_MAJOR 2
-#define APP_VER_MINOR 4
-#define APP_VER_BUILD 2
+#define APP_VER_MAJOR 1
+#define APP_VER_MINOR 0
+#define APP_VER_BUILD 9
#define APP_VER_REV 0
#ifdef _MSC_VER