mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-17 03:22:48 -05:00
Draft merge
This commit is contained in:
137
src/base/base.cmake
Normal file
137
src/base/base.cmake
Normal file
@@ -0,0 +1,137 @@
|
||||
set(HEADERS_BASE
|
||||
src/base/io/Console.h
|
||||
src/base/io/json/Json.h
|
||||
src/base/io/json/JsonChain.h
|
||||
src/base/io/json/JsonRequest.h
|
||||
src/base/io/log/backends/ConsoleLog.h
|
||||
src/base/io/log/backends/FileLog.h
|
||||
src/base/io/log/Log.h
|
||||
src/base/io/Watcher.h
|
||||
src/base/kernel/Base.h
|
||||
src/base/kernel/config/BaseConfig.h
|
||||
src/base/kernel/config/BaseTransform.h
|
||||
src/base/kernel/Entry.h
|
||||
src/base/kernel/interfaces/IBaseListener.h
|
||||
src/base/kernel/interfaces/IClient.h
|
||||
src/base/kernel/interfaces/IClientListener.h
|
||||
src/base/kernel/interfaces/IConfig.h
|
||||
src/base/kernel/interfaces/IConfigListener.h
|
||||
src/base/kernel/interfaces/IConfigTransform.h
|
||||
src/base/kernel/interfaces/IConsoleListener.h
|
||||
src/base/kernel/interfaces/IDnsListener.h
|
||||
src/base/kernel/interfaces/ILineListener.h
|
||||
src/base/kernel/interfaces/ILogBackend.h
|
||||
src/base/kernel/interfaces/ISignalListener.h
|
||||
src/base/kernel/interfaces/IStrategy.h
|
||||
src/base/kernel/interfaces/IStrategyListener.h
|
||||
src/base/kernel/interfaces/ITimerListener.h
|
||||
src/base/kernel/interfaces/IWatcherListener.h
|
||||
src/base/kernel/Process.h
|
||||
src/base/kernel/Signals.h
|
||||
src/base/net/dns/Dns.h
|
||||
src/base/net/dns/DnsRecord.h
|
||||
src/base/net/http/Http.h
|
||||
src/base/net/stratum/BaseClient.h
|
||||
src/base/net/stratum/Client.h
|
||||
src/base/net/stratum/Job.h
|
||||
src/base/net/stratum/Pool.h
|
||||
src/base/net/stratum/Pools.h
|
||||
src/base/net/stratum/strategies/FailoverStrategy.h
|
||||
src/base/net/stratum/strategies/SinglePoolStrategy.h
|
||||
src/base/net/stratum/SubmitResult.h
|
||||
src/base/net/tools/RecvBuf.h
|
||||
src/base/net/tools/Storage.h
|
||||
src/base/tools/Arguments.h
|
||||
src/base/tools/Baton.h
|
||||
src/base/tools/Buffer.h
|
||||
src/base/tools/Chrono.h
|
||||
src/base/tools/Handle.h
|
||||
src/base/tools/String.h
|
||||
src/base/tools/Timer.h
|
||||
)
|
||||
|
||||
set(SOURCES_BASE
|
||||
src/base/io/Console.cpp
|
||||
src/base/io/json/Json.cpp
|
||||
src/base/io/json/JsonChain.cpp
|
||||
src/base/io/json/JsonRequest.cpp
|
||||
src/base/io/log/backends/ConsoleLog.cpp
|
||||
src/base/io/log/backends/FileLog.cpp
|
||||
src/base/io/log/Log.cpp
|
||||
src/base/io/Watcher.cpp
|
||||
src/base/kernel/Base.cpp
|
||||
src/base/kernel/config/BaseConfig.cpp
|
||||
src/base/kernel/config/BaseTransform.cpp
|
||||
src/base/kernel/Entry.cpp
|
||||
src/base/kernel/Process.cpp
|
||||
src/base/kernel/Signals.cpp
|
||||
src/base/net/dns/Dns.cpp
|
||||
src/base/net/dns/DnsRecord.cpp
|
||||
src/base/net/http/Http.cpp
|
||||
src/base/net/stratum/BaseClient.cpp
|
||||
src/base/net/stratum/Client.cpp
|
||||
src/base/net/stratum/Job.cpp
|
||||
src/base/net/stratum/Pool.cpp
|
||||
src/base/net/stratum/Pools.cpp
|
||||
src/base/net/stratum/strategies/FailoverStrategy.cpp
|
||||
src/base/net/stratum/strategies/SinglePoolStrategy.cpp
|
||||
src/base/tools/Arguments.cpp
|
||||
src/base/tools/Buffer.cpp
|
||||
src/base/tools/String.cpp
|
||||
src/base/tools/Timer.cpp
|
||||
)
|
||||
|
||||
|
||||
if (WIN32)
|
||||
set(SOURCES_OS src/base/io/json/Json_win.cpp)
|
||||
else()
|
||||
set(SOURCES_OS src/base/io/json/Json_unix.cpp)
|
||||
endif()
|
||||
|
||||
|
||||
if (NOT WIN32)
|
||||
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
|
||||
if (HAVE_SYSLOG_H)
|
||||
add_definitions(/DHAVE_SYSLOG_H)
|
||||
set(SOURCES_SYSLOG src/base/io/log/backends/SysLog.h src/base/io/log/backends/SysLog.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if (WITH_HTTP)
|
||||
set(HEADERS_BASE_HTTP
|
||||
src/3rdparty/http-parser/http_parser.h
|
||||
src/base/kernel/interfaces/IHttpListener.h
|
||||
src/base/kernel/interfaces/IJsonReader.h
|
||||
src/base/kernel/interfaces/ITcpServerListener.h
|
||||
src/base/net/http/HttpApiResponse.h
|
||||
src/base/net/http/HttpClient.h
|
||||
src/base/net/http/HttpContext.h
|
||||
src/base/net/http/HttpData.h
|
||||
src/base/net/http/HttpResponse.h
|
||||
src/base/net/http/HttpServer.h
|
||||
src/base/net/stratum/DaemonClient.h
|
||||
src/base/net/tools/TcpServer.h
|
||||
)
|
||||
|
||||
set(SOURCES_BASE_HTTP
|
||||
src/3rdparty/http-parser/http_parser.c
|
||||
src/base/net/http/HttpApiResponse.cpp
|
||||
src/base/net/http/HttpClient.cpp
|
||||
src/base/net/http/HttpContext.cpp
|
||||
src/base/net/http/HttpResponse.cpp
|
||||
src/base/net/http/HttpServer.cpp
|
||||
src/base/net/stratum/DaemonClient.cpp
|
||||
src/base/net/tools/TcpServer.cpp
|
||||
)
|
||||
|
||||
add_definitions(/DXMRIG_FEATURE_HTTP)
|
||||
add_definitions(/DXMRIG_FEATURE_API)
|
||||
else()
|
||||
set(HEADERS_BASE_HTTP "")
|
||||
set(SOURCES_BASE_HTTP "")
|
||||
remove_definitions(/DXMRIG_FEATURE_HTTP)
|
||||
remove_definitions(/DXMRIG_FEATURE_API)
|
||||
endif()
|
||||
|
||||
add_definitions(/DXMRIG_DEPRECATED)
|
||||
80
src/base/io/Console.cpp
Normal file
80
src/base/io/Console.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/Console.h"
|
||||
#include "base/kernel/interfaces/IConsoleListener.h"
|
||||
#include "base/tools/Handle.h"
|
||||
|
||||
|
||||
xmrig::Console::Console(IConsoleListener *listener)
|
||||
: m_listener(listener)
|
||||
{
|
||||
m_tty = new uv_tty_t;
|
||||
|
||||
m_tty->data = this;
|
||||
uv_tty_init(uv_default_loop(), m_tty, 0, 1);
|
||||
|
||||
if (!uv_is_readable(reinterpret_cast<uv_stream_t*>(m_tty))) {
|
||||
return;
|
||||
}
|
||||
|
||||
uv_tty_set_mode(m_tty, UV_TTY_MODE_RAW);
|
||||
uv_read_start(reinterpret_cast<uv_stream_t*>(m_tty), Console::onAllocBuffer, Console::onRead);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Console::~Console()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Console::stop()
|
||||
{
|
||||
uv_tty_reset_mode();
|
||||
|
||||
Handle::close(m_tty);
|
||||
m_tty = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Console::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
|
||||
{
|
||||
auto console = static_cast<Console*>(handle->data);
|
||||
buf->len = 1;
|
||||
buf->base = console->m_buf;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
if (nread < 0) {
|
||||
return uv_close(reinterpret_cast<uv_handle_t*>(stream), nullptr);
|
||||
}
|
||||
|
||||
if (nread == 1) {
|
||||
static_cast<Console*>(stream->data)->m_listener->onConsoleCommand(buf->base[0]);
|
||||
}
|
||||
}
|
||||
60
src/base/io/Console.h
Normal file
60
src/base/io/Console.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CONSOLE_H
|
||||
#define XMRIG_CONSOLE_H
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConsoleListener;
|
||||
|
||||
|
||||
class Console
|
||||
{
|
||||
public:
|
||||
Console(IConsoleListener *listener);
|
||||
~Console();
|
||||
|
||||
void stop();
|
||||
|
||||
private:
|
||||
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||
|
||||
char m_buf[1];
|
||||
IConsoleListener *m_listener;
|
||||
uv_tty_t *m_tty;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CONSOLE_H */
|
||||
@@ -29,37 +29,31 @@
|
||||
#include "base/kernel/interfaces/IWatcherListener.h"
|
||||
#include "base/io/Watcher.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "base/tools/Timer.h"
|
||||
|
||||
|
||||
xmrig::Watcher::Watcher(const String &path, IWatcherListener *listener) :
|
||||
m_listener(listener),
|
||||
m_path(path)
|
||||
{
|
||||
m_timer = new Timer(this);
|
||||
|
||||
m_fsEvent = new uv_fs_event_t;
|
||||
m_fsEvent->data = this;
|
||||
uv_fs_event_init(uv_default_loop(), m_fsEvent);
|
||||
|
||||
m_timer = new uv_timer_t;
|
||||
uv_timer_init(uv_default_loop(), m_timer);
|
||||
|
||||
m_fsEvent->data = m_timer->data = this;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
xmrig::Watcher::~Watcher()
|
||||
{
|
||||
Handle::close(m_timer);
|
||||
delete m_timer;
|
||||
|
||||
Handle::close(m_fsEvent);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Watcher::onTimer(uv_timer_t *handle)
|
||||
{
|
||||
static_cast<Watcher *>(handle->data)->reload();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int, int)
|
||||
{
|
||||
if (!filename) {
|
||||
@@ -72,8 +66,8 @@ void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int,
|
||||
|
||||
void xmrig::Watcher::queueUpdate()
|
||||
{
|
||||
uv_timer_stop(m_timer);
|
||||
uv_timer_start(m_timer, xmrig::Watcher::onTimer, kDelay, 0);
|
||||
m_timer->stop();
|
||||
m_timer->start(kDelay, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,30 +26,33 @@
|
||||
#define XMRIG_WATCHER_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ITimerListener.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
typedef struct uv_fs_event_s uv_fs_event_t;
|
||||
typedef struct uv_timer_s uv_timer_t;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IWatcherListener;
|
||||
class Timer;
|
||||
|
||||
|
||||
class Watcher
|
||||
class Watcher : public ITimerListener
|
||||
{
|
||||
public:
|
||||
Watcher(const String &path, IWatcherListener *listener);
|
||||
~Watcher();
|
||||
~Watcher() override;
|
||||
|
||||
protected:
|
||||
inline void onTimer(const Timer *) override { reload(); }
|
||||
|
||||
private:
|
||||
constexpr static int kDelay = 500;
|
||||
|
||||
static void onFsEvent(uv_fs_event_t *handle, const char *filename, int events, int status);
|
||||
static void onTimer(uv_timer_t *handle);
|
||||
|
||||
void queueUpdate();
|
||||
void reload();
|
||||
@@ -57,11 +60,12 @@ private:
|
||||
|
||||
IWatcherListener *m_listener;
|
||||
String m_path;
|
||||
Timer *m_timer;
|
||||
uv_fs_event_t *m_fsEvent;
|
||||
uv_timer_t *m_timer;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_WATCHER_H */
|
||||
|
||||
@@ -23,10 +23,17 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const rapidjson::Value kNullValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
@@ -49,6 +56,39 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
if (i != obj.MemberEnd() && i->value.IsArray()) {
|
||||
return i->value;
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
if (i != obj.MemberEnd() && i->value.IsObject()) {
|
||||
return i->value;
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
if (i != obj.MemberEnd()) {
|
||||
return i->value;
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
|
||||
{
|
||||
auto i = obj.FindMember(key);
|
||||
@@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonReader::isEmpty() const
|
||||
{
|
||||
return !m_obj.IsObject() || m_obj.ObjectEmpty();
|
||||
}
|
||||
79
src/base/io/json/Json.h
Normal file
79
src/base/io/json/Json.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_JSON_H
|
||||
#define XMRIG_JSON_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IJsonReader.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Json
|
||||
{
|
||||
public:
|
||||
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
|
||||
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
|
||||
static const rapidjson::Value &getArray(const rapidjson::Value &obj, const char *key);
|
||||
static const rapidjson::Value &getObject(const rapidjson::Value &obj, const char *key);
|
||||
static const rapidjson::Value &getValue(const rapidjson::Value &obj, const char *key);
|
||||
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
|
||||
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
|
||||
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
|
||||
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
|
||||
|
||||
static bool get(const char *fileName, rapidjson::Document &doc);
|
||||
static bool save(const char *fileName, const rapidjson::Document &doc);
|
||||
};
|
||||
|
||||
|
||||
class JsonReader : public IJsonReader
|
||||
{
|
||||
public:
|
||||
inline JsonReader(const rapidjson::Value &obj) : m_obj(obj) {}
|
||||
|
||||
inline bool getBool(const char *key, bool defaultValue = false) const override { return Json::getBool(m_obj, key, defaultValue); }
|
||||
inline const char *getString(const char *key, const char *defaultValue = nullptr) const override { return Json::getString(m_obj, key, defaultValue); }
|
||||
inline const rapidjson::Value &getArray(const char *key) const override { return Json::getArray(m_obj, key); }
|
||||
inline const rapidjson::Value &getObject(const char *key) const override { return Json::getObject(m_obj, key); }
|
||||
inline const rapidjson::Value &getValue(const char *key) const override { return Json::getValue(m_obj, key); }
|
||||
inline int getInt(const char *key, int defaultValue = 0) const override { return Json::getInt(m_obj, key, defaultValue); }
|
||||
inline int64_t getInt64(const char *key, int64_t defaultValue = 0) const override { return Json::getInt64(m_obj, key, defaultValue); }
|
||||
inline uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override { return Json::getUint64(m_obj, key, defaultValue); }
|
||||
inline unsigned getUint(const char *key, unsigned defaultValue = 0) const override { return Json::getUint(m_obj, key, defaultValue); }
|
||||
|
||||
bool isEmpty() const override;
|
||||
|
||||
private:
|
||||
const rapidjson::Value &m_obj;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JSON_H */
|
||||
213
src/base/io/json/JsonChain.cpp
Normal file
213
src/base/io/json/JsonChain.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/json/JsonChain.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const rapidjson::Value kNullValue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::JsonChain::JsonChain()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::add(rapidjson::Document &&doc)
|
||||
{
|
||||
if (doc.HasParseError() || !doc.IsObject() || doc.ObjectEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_chain.push_back(std::move(doc));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::addFile(const char *fileName)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
if (Json::get(fileName, doc)) {
|
||||
m_fileName = fileName;
|
||||
|
||||
return add(std::move(doc));
|
||||
}
|
||||
|
||||
if (doc.HasParseError()) {
|
||||
LOG_ERR("%s<offset:%zu>: \"%s\"", fileName, doc.GetErrorOffset(), GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
else {
|
||||
LOG_ERR("unable to open \"%s\".", fileName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::addRaw(const char *json)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
Document doc;
|
||||
doc.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(json);
|
||||
|
||||
return add(std::move(doc));
|
||||
}
|
||||
|
||||
|
||||
void xmrig::JsonChain::dump(const char *fileName)
|
||||
{
|
||||
rapidjson::Document doc(rapidjson::kArrayType);
|
||||
|
||||
for (rapidjson::Document &value : m_chain) {
|
||||
doc.PushBack(value, doc.GetAllocator());
|
||||
}
|
||||
|
||||
Json::save(fileName, doc);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::JsonChain::getBool(const char *key, bool defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsBool()) {
|
||||
return i->value.GetBool();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::JsonChain::getString(const char *key, const char *defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsString()) {
|
||||
return i->value.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::JsonChain::getArray(const char *key) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsArray()) {
|
||||
return i->value;
|
||||
}
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::JsonChain::getObject(const char *key) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsObject()) {
|
||||
return i->value;
|
||||
}
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd()) {
|
||||
return i->value;
|
||||
}
|
||||
}
|
||||
|
||||
return kNullValue;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::JsonChain::getInt(const char *key, int defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsInt()) {
|
||||
return i->value.GetInt();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::JsonChain::getInt64(const char *key, int64_t defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsInt64()) {
|
||||
return i->value.GetInt64();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
uint64_t xmrig::JsonChain::getUint64(const char *key, uint64_t defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsUint64()) {
|
||||
return i->value.GetUint64();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
unsigned xmrig::JsonChain::getUint(const char *key, unsigned defaultValue) const
|
||||
{
|
||||
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||
auto i = it->FindMember(key);
|
||||
if (i != it->MemberEnd() && i->value.IsUint()) {
|
||||
return i->value.GetUint();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
76
src/base/io/json/JsonChain.h
Normal file
76
src/base/io/json/JsonChain.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_JSONCHAIN_H
|
||||
#define XMRIG_JSONCHAIN_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IJsonReader.h"
|
||||
#include "base/tools/String.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class JsonChain : public IJsonReader
|
||||
{
|
||||
public:
|
||||
JsonChain();
|
||||
|
||||
bool add(rapidjson::Document &&doc);
|
||||
bool addFile(const char *fileName);
|
||||
bool addRaw(const char *json);
|
||||
|
||||
void dump(const char *fileName);
|
||||
|
||||
inline const String &fileName() const { return m_fileName; }
|
||||
inline size_t size() const { return m_chain.size(); }
|
||||
|
||||
protected:
|
||||
inline bool isEmpty() const override { return m_chain.empty(); }
|
||||
|
||||
bool getBool(const char *key, bool defaultValue = false) const override;
|
||||
const char *getString(const char *key, const char *defaultValue = nullptr) const override;
|
||||
const rapidjson::Value &getArray(const char *key) const override;
|
||||
const rapidjson::Value &getObject(const char *key) const override;
|
||||
const rapidjson::Value &getValue(const char *key) const override;
|
||||
int getInt(const char *key, int defaultValue = 0) const override;
|
||||
int64_t getInt64(const char *key, int64_t defaultValue = 0) const override;
|
||||
uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override;
|
||||
unsigned getUint(const char *key, unsigned defaultValue = 0) const override;
|
||||
|
||||
private:
|
||||
std::vector<rapidjson::Document> m_chain;
|
||||
String m_fileName;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JSONCHAIN_H */
|
||||
38
src/base/io/json/JsonRequest.cpp
Normal file
38
src/base/io/json/JsonRequest.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/json/JsonRequest.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value ¶ms)
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
doc.AddMember("id", id, allocator);
|
||||
doc.AddMember("jsonrpc", "2.0", allocator);
|
||||
doc.AddMember("method", rapidjson::StringRef(method), allocator);
|
||||
doc.AddMember("params", params, allocator);
|
||||
}
|
||||
45
src/base/io/json/JsonRequest.h
Normal file
45
src/base/io/json/JsonRequest.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_JSONREQUEST_H
|
||||
#define XMRIG_JSONREQUEST_H
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class JsonRequest
|
||||
{
|
||||
public:
|
||||
static void create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value ¶ms);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JSONREQUEST_H */
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/istreamwrapper.h"
|
||||
#include "rapidjson/ostreamwrapper.h"
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/istreamwrapper.h"
|
||||
#include "rapidjson/ostreamwrapper.h"
|
||||
@@ -102,7 +102,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
|
||||
return false;
|
||||
}
|
||||
# elif defined(__GNUC__)
|
||||
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_TRUNC);
|
||||
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC);
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
250
src/base/io/log/Log.cpp
Normal file
250
src/base/io/log/Log.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/ILogBackend.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *colors_map[] = {
|
||||
RED_BOLD_S, // EMERG
|
||||
RED_BOLD_S, // ALERT
|
||||
RED_BOLD_S, // CRIT
|
||||
RED_S, // ERR
|
||||
YELLOW_S, // WARNING
|
||||
WHITE_BOLD_S, // NOTICE
|
||||
nullptr, // INFO
|
||||
# ifdef WIN32
|
||||
BLACK_BOLD_S // DEBUG
|
||||
# else
|
||||
BRIGHT_BLACK_S // DEBUG
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LogPrivate
|
||||
{
|
||||
public:
|
||||
inline LogPrivate() :
|
||||
m_buf()
|
||||
{
|
||||
uv_mutex_init(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
inline ~LogPrivate()
|
||||
{
|
||||
uv_mutex_destroy(&m_mutex);
|
||||
|
||||
for (ILogBackend *backend : m_backends) {
|
||||
delete backend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void add(ILogBackend *backend) { m_backends.push_back(backend); }
|
||||
|
||||
|
||||
void print(Log::Level level, const char *fmt, va_list args)
|
||||
{
|
||||
size_t size = 0;
|
||||
size_t offset = 0;
|
||||
|
||||
lock();
|
||||
timestamp(level, size, offset);
|
||||
color(level, size);
|
||||
|
||||
const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args);
|
||||
if (rc < 0) {
|
||||
return unlock();
|
||||
}
|
||||
|
||||
size += std::min(static_cast<size_t>(rc), sizeof (m_buf) - offset - 32);
|
||||
endl(size);
|
||||
|
||||
std::string txt(m_buf);
|
||||
size_t i;
|
||||
while ((i = txt.find(CSI)) != std::string::npos) {
|
||||
txt.erase(i, txt.find('m', i) - i + 1);
|
||||
}
|
||||
|
||||
if (!m_backends.empty()) {
|
||||
for (ILogBackend *backend : m_backends) {
|
||||
backend->print(level, m_buf, offset, size, true);
|
||||
backend->print(level, txt.c_str(), offset, txt.size(), false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fputs(txt.c_str(), stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
inline void lock() { uv_mutex_lock(&m_mutex); }
|
||||
inline void unlock() { uv_mutex_unlock(&m_mutex); }
|
||||
|
||||
|
||||
inline void timestamp(Log::Level level, size_t &size, size_t &offset)
|
||||
{
|
||||
if (level == Log::NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t ms = Chrono::currentMSecsSinceEpoch();
|
||||
time_t now = ms / 1000;
|
||||
tm stime;
|
||||
|
||||
# ifdef _WIN32
|
||||
localtime_s(&stime, &now);
|
||||
# else
|
||||
localtime_r(&now, &stime);
|
||||
# endif
|
||||
|
||||
const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ",
|
||||
stime.tm_year + 1900,
|
||||
stime.tm_mon + 1,
|
||||
stime.tm_mday,
|
||||
stime.tm_hour,
|
||||
stime.tm_min,
|
||||
stime.tm_sec,
|
||||
static_cast<int>(ms % 1000)
|
||||
);
|
||||
|
||||
if (rc > 0) {
|
||||
size = offset = static_cast<size_t>(rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void color(Log::Level level, size_t &size)
|
||||
{
|
||||
if (level == Log::NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *color = colors_map[level];
|
||||
if (color == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t s = strlen(color);
|
||||
memcpy(m_buf + size, color, s);
|
||||
|
||||
size += s;
|
||||
}
|
||||
|
||||
|
||||
inline void endl(size_t &size)
|
||||
{
|
||||
# ifdef _WIN32
|
||||
memcpy(m_buf + size, CLEAR "\r\n", 7);
|
||||
size += 6;
|
||||
# else
|
||||
memcpy(m_buf + size, CLEAR "\n", 6);
|
||||
size += 5;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
char m_buf[4096];
|
||||
std::vector<ILogBackend*> m_backends;
|
||||
uv_mutex_t m_mutex;
|
||||
};
|
||||
|
||||
|
||||
bool Log::colors = true;
|
||||
LogPrivate *Log::d = new LogPrivate();
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
|
||||
void xmrig::Log::add(ILogBackend *backend)
|
||||
{
|
||||
if (d) {
|
||||
d->add(backend);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Log::destroy()
|
||||
{
|
||||
delete d;
|
||||
d = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Log::print(const char *fmt, ...)
|
||||
{
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
d->print(NONE, fmt, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Log::print(Level level, const char *fmt, ...)
|
||||
{
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
d->print(level, fmt, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
129
src/base/io/log/Log.h
Normal file
129
src/base/io/log/Log.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_LOG_H
|
||||
#define XMRIG_LOG_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ILogBackend;
|
||||
class LogPrivate;
|
||||
|
||||
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
enum Level : int {
|
||||
NONE = -1,
|
||||
EMERG, // system is unusable
|
||||
ALERT, // action must be taken immediately
|
||||
CRIT, // critical conditions
|
||||
ERR, // error conditions
|
||||
WARNING, // warning conditions
|
||||
NOTICE, // normal but significant condition
|
||||
INFO, // informational
|
||||
DEBUG, // debug-level messages
|
||||
};
|
||||
|
||||
static void add(ILogBackend *backend);
|
||||
static void destroy();
|
||||
static void print(const char *fmt, ...);
|
||||
static void print(Level level, const char *fmt, ...);
|
||||
|
||||
static bool colors;
|
||||
|
||||
private:
|
||||
static LogPrivate *d;
|
||||
};
|
||||
|
||||
|
||||
#define CSI "\x1B[" // Control Sequence Introducer (ANSI spec name)
|
||||
#define CLEAR CSI "0m" // all attributes off
|
||||
#define BRIGHT_BLACK_S CSI "0;90m" // somewhat MD.GRAY
|
||||
#define BLACK_S CSI "0;30m"
|
||||
#define BLACK_BOLD_S CSI "1;30m" // another name for GRAY
|
||||
#define RED_S CSI "0;31m"
|
||||
#define RED_BOLD_S CSI "1;31m"
|
||||
#define GREEN_S CSI "0;32m"
|
||||
#define GREEN_BOLD_S CSI "1;32m"
|
||||
#define YELLOW_S CSI "0;33m"
|
||||
#define YELLOW_BOLD_S CSI "1;33m"
|
||||
#define BLUE_S CSI "0;34m"
|
||||
#define BLUE_BOLD_S CSI "1;34m"
|
||||
#define MAGENTA_S CSI "0;35m"
|
||||
#define MAGENTA_BOLD_S CSI "1;35m"
|
||||
#define CYAN_S CSI "0;36m"
|
||||
#define CYAN_BOLD_S CSI "1;36m"
|
||||
#define WHITE_S CSI "0;37m" // another name for LT.GRAY
|
||||
#define WHITE_BOLD_S CSI "1;37m" // actually white
|
||||
|
||||
//color wrappings
|
||||
#define BLACK(x) BLACK_S x CLEAR
|
||||
#define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR
|
||||
#define RED(x) RED_S x CLEAR
|
||||
#define RED_BOLD(x) RED_BOLD_S x CLEAR
|
||||
#define GREEN(x) GREEN_S x CLEAR
|
||||
#define GREEN_BOLD(x) GREEN_BOLD_S x CLEAR
|
||||
#define YELLOW(x) YELLOW_S x CLEAR
|
||||
#define YELLOW_BOLD(x) YELLOW_BOLD_S x CLEAR
|
||||
#define BLUE(x) BLUE_S x CLEAR
|
||||
#define BLUE_BOLD(x) BLUE_BOLD_S x CLEAR
|
||||
#define MAGENTA(x) MAGENTA_S x CLEAR
|
||||
#define MAGENTA_BOLD(x) MAGENTA_BOLD_S x CLEAR
|
||||
#define CYAN(x) CYAN_S x CLEAR
|
||||
#define CYAN_BOLD(x) CYAN_BOLD_S x CLEAR
|
||||
#define WHITE(x) WHITE_S x CLEAR
|
||||
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
|
||||
|
||||
|
||||
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
|
||||
#define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__)
|
||||
#define LOG_CRIT(x, ...) xmrig::Log::print(xmrig::Log::CRIT, x, ##__VA_ARGS__)
|
||||
#define LOG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
|
||||
#define LOG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
|
||||
#define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__)
|
||||
#define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__)
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
# define LOG_DEBUG(x, ...) xmrig::Log::print(xmrig::Log::DEBUG, x, ##__VA_ARGS__)
|
||||
#else
|
||||
# define LOG_DEBUG(x, ...)
|
||||
#endif
|
||||
|
||||
#if defined(APP_DEBUG) || defined(APP_DEVEL)
|
||||
# define LOG_DEBUG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
|
||||
# define LOG_DEBUG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
|
||||
#else
|
||||
# define LOG_DEBUG_ERR(x, ...)
|
||||
# define LOG_DEBUG_WARN(x, ...)
|
||||
#endif
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_LOG_H */
|
||||
97
src/base/io/log/backends/ConsoleLog.cpp
Normal file
97
src/base/io/log/backends/ConsoleLog.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "base/tools/Handle.h"
|
||||
#include "base/io/log/backends/ConsoleLog.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
xmrig::ConsoleLog::ConsoleLog() :
|
||||
m_stream(nullptr)
|
||||
{
|
||||
m_tty = new uv_tty_t;
|
||||
|
||||
if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) {
|
||||
Log::colors = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
|
||||
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
|
||||
|
||||
# ifdef WIN32
|
||||
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
DWORD mode = 0;
|
||||
if (GetConsoleMode(handle, &mode)) {
|
||||
mode &= ~ENABLE_QUICK_EDIT_MODE;
|
||||
SetConsoleMode(handle, mode | ENABLE_EXTENDED_FLAGS);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
xmrig::ConsoleLog::~ConsoleLog()
|
||||
{
|
||||
Handle::close(m_tty);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors)
|
||||
{
|
||||
if (Log::colors != colors) {
|
||||
return;
|
||||
}
|
||||
|
||||
# ifdef _WIN32
|
||||
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), static_cast<unsigned int>(size));
|
||||
# else
|
||||
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), size);
|
||||
# endif
|
||||
|
||||
if (!isWritable()) {
|
||||
fputs(line, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
else {
|
||||
uv_try_write(m_stream, &buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConsoleLog::isWritable() const
|
||||
{
|
||||
if (!m_stream || uv_is_writable(m_stream) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uv_handle_type type = uv_guess_handle(1);
|
||||
return type == UV_TTY || type == UV_NAMED_PIPE;
|
||||
}
|
||||
60
src/base/io/log/backends/ConsoleLog.h
Normal file
60
src/base/io/log/backends/ConsoleLog.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CONSOLELOG_H
|
||||
#define XMRIG_CONSOLELOG_H
|
||||
|
||||
|
||||
typedef struct uv_stream_s uv_stream_t;
|
||||
typedef struct uv_tty_s uv_tty_t;
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ILogBackend.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ConsoleLog : public ILogBackend
|
||||
{
|
||||
public:
|
||||
ConsoleLog();
|
||||
~ConsoleLog() override;
|
||||
|
||||
protected:
|
||||
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
|
||||
|
||||
private:
|
||||
bool isWritable() const;
|
||||
|
||||
uv_stream_t *m_stream;
|
||||
uv_tty_t *m_tty;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CONSOLELOG_H */
|
||||
67
src/base/io/log/backends/FileLog.cpp
Normal file
67
src/base/io/log/backends/FileLog.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/io/log/backends/FileLog.h"
|
||||
|
||||
|
||||
xmrig::FileLog::FileLog(const char *fileName)
|
||||
{
|
||||
uv_fs_t req;
|
||||
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
|
||||
uv_fs_req_cleanup(&req);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FileLog::print(int, const char *line, size_t, size_t size, bool colors)
|
||||
{
|
||||
if (m_file < 0 || colors) {
|
||||
return;
|
||||
}
|
||||
|
||||
# ifdef _WIN32
|
||||
uv_buf_t buf = uv_buf_init(strdup(line), static_cast<unsigned int>(size));
|
||||
# else
|
||||
uv_buf_t buf = uv_buf_init(strdup(line), size);
|
||||
# endif
|
||||
|
||||
uv_fs_t *req = new uv_fs_t;
|
||||
req->data = buf.base;
|
||||
|
||||
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, FileLog::onWrite);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FileLog::onWrite(uv_fs_t *req)
|
||||
{
|
||||
delete [] static_cast<char *>(req->data);
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
delete req;
|
||||
}
|
||||
58
src/base/io/log/backends/FileLog.h
Normal file
58
src/base/io/log/backends/FileLog.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_FILELOG_H
|
||||
#define XMRIG_FILELOG_H
|
||||
|
||||
|
||||
typedef struct uv_fs_s uv_fs_t;
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ILogBackend.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class FileLog : public ILogBackend
|
||||
{
|
||||
public:
|
||||
FileLog(const char *fileName);
|
||||
|
||||
|
||||
protected:
|
||||
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
|
||||
|
||||
private:
|
||||
static void onWrite(uv_fs_t *req);
|
||||
|
||||
int m_file;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_FILELOG_H */
|
||||
53
src/base/io/log/backends/SysLog.cpp
Normal file
53
src/base/io/log/backends/SysLog.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
#include "base/io/log/backends/SysLog.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
xmrig::SysLog::SysLog()
|
||||
{
|
||||
openlog(APP_ID, LOG_PID, LOG_USER);
|
||||
}
|
||||
|
||||
|
||||
xmrig::SysLog::~SysLog()
|
||||
{
|
||||
closelog();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SysLog::print(int level, const char *line, size_t offset, size_t, bool colors)
|
||||
{
|
||||
if (colors) {
|
||||
return;
|
||||
}
|
||||
|
||||
syslog(level == -1 ? LOG_INFO : level, "%s", line + offset);
|
||||
}
|
||||
50
src/base/io/log/backends/SysLog.h
Normal file
50
src/base/io/log/backends/SysLog.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_SYSLOG_H
|
||||
#define XMRIG_SYSLOG_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ILogBackend.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class SysLog : public ILogBackend
|
||||
{
|
||||
public:
|
||||
SysLog();
|
||||
~SysLog();
|
||||
|
||||
protected:
|
||||
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_SYSLOG_H */
|
||||
291
src/base/kernel/Base.cpp
Normal file
291
src/base/kernel/Base.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/json/JsonChain.h"
|
||||
#include "base/io/log/backends/ConsoleLog.h"
|
||||
#include "base/io/log/backends/FileLog.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/Watcher.h"
|
||||
#include "base/kernel/Base.h"
|
||||
#include "base/kernel/interfaces/IBaseListener.h"
|
||||
#include "base/kernel/Process.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/config/ConfigTransform.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include "base/io/log/backends/SysLog.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
# include "api/Api.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||
# include "core/config/Config_default.h"
|
||||
#endif
|
||||
|
||||
|
||||
class xmrig::BasePrivate
|
||||
{
|
||||
public:
|
||||
inline BasePrivate(Process *process) :
|
||||
api(nullptr),
|
||||
config(nullptr),
|
||||
process(process),
|
||||
watcher(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
inline ~BasePrivate()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
delete api;
|
||||
# endif
|
||||
|
||||
delete config;
|
||||
delete watcher;
|
||||
}
|
||||
|
||||
|
||||
inline bool read(const JsonChain &chain, std::unique_ptr<Config> &config)
|
||||
{
|
||||
config = std::unique_ptr<Config>(new Config());
|
||||
|
||||
return config->read(chain, chain.fileName());
|
||||
}
|
||||
|
||||
|
||||
inline Config *load()
|
||||
{
|
||||
JsonChain chain;
|
||||
ConfigTransform transform;
|
||||
std::unique_ptr<Config> config;
|
||||
|
||||
transform.load(chain, process, transform);
|
||||
|
||||
if (read(chain, config)) {
|
||||
return config.release();
|
||||
}
|
||||
|
||||
chain.addFile(process->location(Process::ExeLocation, "config.json"));
|
||||
|
||||
if (read(chain, config)) {
|
||||
return config.release();
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||
chain.addRaw(default_config);
|
||||
|
||||
if (read(chain, config)) {
|
||||
return config.release();
|
||||
}
|
||||
# endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
inline void replace(Config *newConfig)
|
||||
{
|
||||
Config *previousConfig = config;
|
||||
config = newConfig;
|
||||
|
||||
for (IBaseListener *listener : listeners) {
|
||||
listener->onConfigChanged(config, previousConfig);
|
||||
}
|
||||
|
||||
delete previousConfig;
|
||||
}
|
||||
|
||||
|
||||
Api *api;
|
||||
Config *config;
|
||||
Process *process;
|
||||
std::vector<IBaseListener *> listeners;
|
||||
Watcher *watcher;
|
||||
};
|
||||
|
||||
|
||||
xmrig::Base::Base(Process *process)
|
||||
: d_ptr(new BasePrivate(process))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::Base::~Base()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Base::isReady() const
|
||||
{
|
||||
return d_ptr->config != nullptr;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Base::init()
|
||||
{
|
||||
d_ptr->config = d_ptr->load();
|
||||
|
||||
if (!d_ptr->config) {
|
||||
LOG_EMERG("No valid configuration found. Exiting.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
d_ptr->api = new Api(this);
|
||||
# endif
|
||||
|
||||
Platform::init(config()->userAgent());
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
Platform::setProcessPriority(config()->priority());
|
||||
# endif
|
||||
|
||||
if (!config()->isBackground()) {
|
||||
Log::add(new ConsoleLog());
|
||||
}
|
||||
|
||||
if (config()->logFile()) {
|
||||
Log::add(new FileLog(config()->logFile()));
|
||||
}
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
if (config()->isSyslog()) {
|
||||
Log::add(new SysLog());
|
||||
}
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::start()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
api()->start();
|
||||
# endif
|
||||
|
||||
if (config()->isShouldSave()) {
|
||||
config()->save();
|
||||
}
|
||||
|
||||
if (config()->isWatch()) {
|
||||
d_ptr->watcher = new Watcher(config()->fileName(), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::stop()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
api()->stop();
|
||||
# endif
|
||||
|
||||
delete d_ptr->watcher;
|
||||
d_ptr->watcher = nullptr;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Api *xmrig::Base::api() const
|
||||
{
|
||||
assert(d_ptr->api != nullptr);
|
||||
|
||||
return d_ptr->api;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Base::reload(const rapidjson::Value &json)
|
||||
{
|
||||
JsonReader reader(json);
|
||||
if (reader.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Config *config = new Config();
|
||||
if (!config->read(reader, d_ptr->config->fileName())) {
|
||||
delete config;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool saved = config->save();
|
||||
|
||||
if (config->isWatch() && d_ptr->watcher && saved) {
|
||||
delete config;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
d_ptr->replace(config);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::Base::config() const
|
||||
{
|
||||
assert(d_ptr->config != nullptr);
|
||||
|
||||
return d_ptr->config;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::addListener(IBaseListener *listener)
|
||||
{
|
||||
d_ptr->listeners.push_back(listener);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Base::onFileChanged(const String &fileName)
|
||||
{
|
||||
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
|
||||
|
||||
JsonChain chain;
|
||||
chain.addFile(fileName);
|
||||
|
||||
Config *config = new Config();
|
||||
|
||||
if (!config->read(chain, chain.fileName())) {
|
||||
LOG_ERR("reloading failed");
|
||||
|
||||
delete config;
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->replace(config);
|
||||
pconfig = config;
|
||||
}
|
||||
@@ -22,32 +22,50 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_JSON_H
|
||||
#define XMRIG_JSON_H
|
||||
#ifndef XMRIG_BASE_H
|
||||
#define XMRIG_BASE_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IConfigListener.h"
|
||||
#include "base/kernel/interfaces/IWatcherListener.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Json
|
||||
class Api;
|
||||
class Config;
|
||||
class BasePrivate;
|
||||
class IBaseListener;
|
||||
class Process;
|
||||
|
||||
|
||||
class Base : public IWatcherListener
|
||||
{
|
||||
public:
|
||||
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
|
||||
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
|
||||
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
|
||||
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
|
||||
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
|
||||
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
|
||||
Base(Process *process);
|
||||
~Base() override;
|
||||
|
||||
static bool get(const char *fileName, rapidjson::Document &doc);
|
||||
static bool save(const char *fileName, const rapidjson::Document &doc);
|
||||
virtual bool isReady() const;
|
||||
virtual int init();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
|
||||
Api *api() const;
|
||||
bool reload(const rapidjson::Value &json);
|
||||
Config *config() const;
|
||||
void addListener(IBaseListener *listener);
|
||||
|
||||
protected:
|
||||
void onFileChanged(const String &fileName) override;
|
||||
|
||||
private:
|
||||
BasePrivate *d_ptr;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JSON_H */
|
||||
#endif /* XMRIG_BASE_H */
|
||||
@@ -27,19 +27,14 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include <microhttpd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/kernel/Entry.h"
|
||||
#include "base/kernel/Process.h"
|
||||
#include "core/usage.h"
|
||||
#include "core/config/usage.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
@@ -73,11 +68,7 @@ static int showVersion()
|
||||
|
||||
printf("\nlibuv/%s\n", uv_version_string());
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
printf("microhttpd/%s\n", MHD_get_version());
|
||||
# endif
|
||||
|
||||
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
{
|
||||
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
||||
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
|
||||
#include "base/kernel/Process.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
|
||||
|
||||
static size_t location(xmrig::Process::Location location, char *buf, size_t max)
|
||||
@@ -50,7 +51,7 @@ static size_t location(xmrig::Process::Location location, char *buf, size_t max)
|
||||
xmrig::Process::Process(int argc, char **argv) :
|
||||
m_arguments(argc, argv)
|
||||
{
|
||||
srand(static_cast<unsigned int>(static_cast<uintptr_t>(time(nullptr)) ^ reinterpret_cast<uintptr_t>(this)));
|
||||
srand(static_cast<unsigned int>(Chrono::currentMSecsSinceEpoch() ^ reinterpret_cast<uintptr_t>(this)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -44,20 +44,31 @@ xmrig::Signals::Signals(ISignalListener *listener)
|
||||
m_signals[i] = signal;
|
||||
|
||||
uv_signal_init(uv_default_loop(), signal);
|
||||
uv_signal_start(signal, xmrig::Signals::onSignal, signums[i]);
|
||||
uv_signal_start(signal, Signals::onSignal, signums[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::Signals::~Signals()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Signals::stop()
|
||||
{
|
||||
if (!m_signals[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < kSignalsCount; ++i) {
|
||||
Handle::close(m_signals[i]);
|
||||
m_signals[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Signals::onSignal(uv_signal_t *handle, int signum)
|
||||
{
|
||||
static_cast<xmrig::Signals *>(handle->data)->m_listener->onSignal(signum);
|
||||
static_cast<Signals *>(handle->data)->m_listener->onSignal(signum);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ public:
|
||||
Signals(ISignalListener *listener);
|
||||
~Signals();
|
||||
|
||||
void stop();
|
||||
|
||||
private:
|
||||
void close(int signum);
|
||||
|
||||
|
||||
196
src/base/kernel/config/BaseConfig.cpp
Normal file
196
src/base/kernel/config/BaseConfig.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_AMD_PROJECT
|
||||
# if defined(__APPLE__)
|
||||
# include <OpenCL/cl.h>
|
||||
# else
|
||||
# include "3rdparty/CL/cl.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_NVIDIA_PROJECT
|
||||
# include "nvidia/cryptonight.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/config/BaseConfig.h"
|
||||
#include "base/kernel/interfaces/IJsonReader.h"
|
||||
#include "donate.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
xmrig::BaseConfig::BaseConfig() :
|
||||
m_algorithm(CRYPTONIGHT, VARIANT_AUTO),
|
||||
m_autoSave(true),
|
||||
m_background(false),
|
||||
m_dryRun(false),
|
||||
m_syslog(false),
|
||||
m_upgrade(false),
|
||||
m_watch(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseConfig::printVersions()
|
||||
{
|
||||
char buf[256] = { 0 };
|
||||
|
||||
# if defined(__clang__)
|
||||
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||
# elif defined(__GNUC__)
|
||||
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
|
||||
# elif defined(_MSC_VER)
|
||||
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
|
||||
# endif
|
||||
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf);
|
||||
|
||||
# if defined(XMRIG_AMD_PROJECT)
|
||||
# if CL_VERSION_2_0
|
||||
const char *ocl = "2.0";
|
||||
# elif CL_VERSION_1_2
|
||||
const char *ocl = "1.2";
|
||||
# elif CL_VERSION_1_1
|
||||
const char *ocl = "1.1";
|
||||
# elif CL_VERSION_1_0
|
||||
const char *ocl = "1.0";
|
||||
# else
|
||||
const char *ocl = "0.0";
|
||||
# endif
|
||||
int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl);
|
||||
# elif defined(XMRIG_NVIDIA_PROJECT)
|
||||
const int cudaVersion = cuda_get_runtime_version();
|
||||
int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100);
|
||||
# else
|
||||
memset(buf, 0, 16);
|
||||
|
||||
# if defined(XMRIG_FEATURE_HTTP) || defined(XMRIG_FEATURE_TLS)
|
||||
int length = 0;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
{
|
||||
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
||||
length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
|
||||
}
|
||||
# endif
|
||||
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), buf);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
|
||||
{
|
||||
m_fileName = fileName;
|
||||
|
||||
if (reader.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_autoSave = reader.getBool("autosave", m_autoSave);
|
||||
m_background = reader.getBool("background", m_background);
|
||||
m_dryRun = reader.getBool("dry-run", m_dryRun);
|
||||
m_syslog = reader.getBool("syslog", m_syslog);
|
||||
m_watch = reader.getBool("watch", m_watch);
|
||||
Log::colors = reader.getBool("colors", Log::colors);
|
||||
m_logFile = reader.getString("log-file");
|
||||
m_userAgent = reader.getString("user-agent");
|
||||
|
||||
setPrintTime(reader.getUint("print-time", 60));
|
||||
|
||||
const rapidjson::Value &api = reader.getObject("api");
|
||||
if (api.IsObject()) {
|
||||
m_apiId = Json::getString(api, "id");
|
||||
m_apiWorkerId = Json::getString(api, "worker-id");
|
||||
}
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
if (api.IsObject() && api.HasMember("port")) {
|
||||
m_upgrade = true;
|
||||
m_http.load(api);
|
||||
m_http.setEnabled(Json::getUint(api, "port") > 0);
|
||||
m_http.setHost("0.0.0.0");
|
||||
}
|
||||
else {
|
||||
m_http.load(reader.getObject("http"));
|
||||
}
|
||||
# else
|
||||
m_http.load(chain.getObject("http"));
|
||||
# endif
|
||||
|
||||
m_algorithm.parseAlgorithm(reader.getString("algo", "cn"));
|
||||
|
||||
m_pools.load(reader.getArray("pools"));
|
||||
m_pools.setDonateLevel(reader.getInt("donate-level", kDefaultDonateLevel));
|
||||
m_pools.setProxyDonate(reader.getInt("donate-over-proxy", Pools::PROXY_DONATE_AUTO));
|
||||
m_pools.setRetries(reader.getInt("retries"));
|
||||
m_pools.setRetryPause(reader.getInt("retry-pause"));
|
||||
|
||||
if (!m_algorithm.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pools.adjust(m_algorithm);
|
||||
|
||||
return m_pools.active() > 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::BaseConfig::save()
|
||||
{
|
||||
if (m_fileName.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rapidjson::Document doc;
|
||||
getJSON(doc);
|
||||
|
||||
if (Json::save(m_fileName, doc)) {
|
||||
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
101
src/base/kernel/config/BaseConfig.h
Normal file
101
src/base/kernel/config/BaseConfig.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_BASECONFIG_H
|
||||
#define XMRIG_BASECONFIG_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IConfig.h"
|
||||
#include "base/net/http/Http.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
#include "common/xmrig.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IJsonReader;
|
||||
|
||||
|
||||
class BaseConfig : public IConfig
|
||||
{
|
||||
public:
|
||||
BaseConfig();
|
||||
|
||||
inline bool isAutoSave() const { return m_autoSave; }
|
||||
inline bool isBackground() const { return m_background; }
|
||||
inline bool isDryRun() const { return m_dryRun; }
|
||||
inline bool isCalibrateAlgo() const { return m_calibrateAlgo; }
|
||||
inline int calibrateAlgoTime() const { return m_calibrateAlgoTime; }
|
||||
inline bool isSyslog() const { return m_syslog; }
|
||||
inline const char *logFile() const { return m_logFile.data(); }
|
||||
inline const char *userAgent() const { return m_userAgent.data(); }
|
||||
inline const Http &http() const { return m_http; }
|
||||
inline const Pools &pools() const { return m_pools; }
|
||||
inline const String &apiId() const { return m_apiId; }
|
||||
inline const String &apiWorkerId() const { return m_apiWorkerId; }
|
||||
inline uint32_t printTime() const { return m_printTime; }
|
||||
|
||||
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
|
||||
inline const Algorithm &algorithm() const override { return m_algorithm; }
|
||||
inline const String &fileName() const override { return m_fileName; }
|
||||
inline void setFileName(const char *fileName) override { m_fileName = fileName; }
|
||||
|
||||
bool read(const IJsonReader &reader, const char *fileName) override;
|
||||
bool save() override;
|
||||
|
||||
void printVersions();
|
||||
|
||||
protected:
|
||||
Algorithm m_algorithm;
|
||||
bool m_autoSave;
|
||||
bool m_background;
|
||||
bool m_dryRun;
|
||||
bool m_calibrateAlgo;
|
||||
int m_calibrateAlgoTime;
|
||||
bool m_syslog;
|
||||
bool m_upgrade;
|
||||
bool m_watch;
|
||||
Http m_http;
|
||||
Pools m_pools;
|
||||
String m_apiId;
|
||||
String m_apiWorkerId;
|
||||
String m_fileName;
|
||||
String m_logFile;
|
||||
String m_userAgent;
|
||||
uint32_t m_printTime;
|
||||
|
||||
private:
|
||||
inline void setPrintTime(uint32_t printTime) { if (printTime <= 3600) { m_printTime = printTime; } }
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_BASECONFIG_H */
|
||||
279
src/base/kernel/config/BaseTransform.cpp
Normal file
279
src/base/kernel/config/BaseTransform.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include "getopt/getopt.h"
|
||||
#else
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/kernel/config/BaseTransform.h"
|
||||
#include "base/kernel/Process.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/IConfig.h"
|
||||
#include "base/io/json/JsonChain.h"
|
||||
#include "core/config/Config_platform.h"
|
||||
|
||||
|
||||
namespace xmrig
|
||||
{
|
||||
|
||||
static const char *kApi = "api";
|
||||
static const char *kHttp = "http";
|
||||
static const char *kPools = "pools";
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::BaseTransform::BaseTransform()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
int key;
|
||||
int argc = process->arguments().argc();
|
||||
char **argv = process->arguments().argv();
|
||||
|
||||
Document doc(kObjectType);
|
||||
|
||||
while (1) {
|
||||
key = getopt_long(argc, argv, short_options, options, nullptr);
|
||||
if (key < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (key == IConfig::ConfigKey) {
|
||||
chain.add(std::move(doc));
|
||||
chain.addFile(optarg);
|
||||
|
||||
doc = Document(kObjectType);
|
||||
}
|
||||
else {
|
||||
transform.transform(doc, key, optarg);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
LOG_WARN("%s: unsupported non-option argument '%s'", argv[0], argv[optind]);
|
||||
}
|
||||
|
||||
chain.add(std::move(doc));
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const char *arg)
|
||||
{
|
||||
switch (key) {
|
||||
case IConfig::AlgorithmKey: /* --algo */
|
||||
return set(doc, "algo", arg);
|
||||
|
||||
case IConfig::UserpassKey: /* --userpass */
|
||||
{
|
||||
const char *p = strrchr(arg, ':');
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *user = new char[p - arg + 1]();
|
||||
strncpy(user, arg, static_cast<size_t>(p - arg));
|
||||
|
||||
add<const char *>(doc, kPools, "user", user);
|
||||
add(doc, kPools, "pass", p + 1);
|
||||
delete [] user;
|
||||
}
|
||||
break;
|
||||
|
||||
case IConfig::UrlKey: /* --url */
|
||||
return add(doc, kPools, "url", arg, true);
|
||||
|
||||
case IConfig::UserKey: /* --user */
|
||||
return add(doc, kPools, "user", arg);
|
||||
|
||||
case IConfig::PasswordKey: /* --pass */
|
||||
return add(doc, kPools, "pass", arg);
|
||||
|
||||
case IConfig::RigIdKey: /* --rig-id */
|
||||
return add(doc, kPools, "rig-id", arg);
|
||||
|
||||
case IConfig::FingerprintKey: /* --tls-fingerprint */
|
||||
return add(doc, kPools, "tls-fingerprint", arg);
|
||||
|
||||
case IConfig::VariantKey: /* --variant */
|
||||
return add(doc, kPools, "variant", arg);
|
||||
|
||||
case IConfig::LogFileKey: /* --log-file */
|
||||
return set(doc, "log-file", arg);
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case IConfig::ApiAccessTokenKey: /* --api-access-token */
|
||||
fputs("option \"--api-access-token\" deprecated, use \"--http-access-token\" instead.\n", stderr);
|
||||
fflush(stdout);
|
||||
return set(doc, kHttp, "access-token", arg);
|
||||
# endif
|
||||
|
||||
case IConfig::HttpAccessTokenKey: /* --http-access-token */
|
||||
return set(doc, kHttp, "access-token", arg);
|
||||
|
||||
case IConfig::HttpHostKey: /* --http-host */
|
||||
return set(doc, kHttp, "host", arg);
|
||||
|
||||
case IConfig::ApiWorkerIdKey: /* --api-worker-id */
|
||||
return set(doc, kApi, "worker-id", arg);
|
||||
|
||||
case IConfig::ApiIdKey: /* --api-id */
|
||||
return set(doc, kApi, "id", arg);
|
||||
|
||||
case IConfig::UserAgentKey: /* --user-agent */
|
||||
return set(doc, "user-agent", arg);
|
||||
|
||||
case IConfig::RetriesKey: /* --retries */
|
||||
case IConfig::RetryPauseKey: /* --retry-pause */
|
||||
case IConfig::PrintTimeKey: /* --print-time */
|
||||
case IConfig::HttpPort: /* --http-port */
|
||||
case IConfig::DonateLevelKey: /* --donate-level */
|
||||
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case IConfig::ApiPort: /* --api-port */
|
||||
# endif
|
||||
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
|
||||
case IConfig::BackgroundKey: /* --background */
|
||||
case IConfig::SyslogKey: /* --syslog */
|
||||
case IConfig::KeepAliveKey: /* --keepalive */
|
||||
case IConfig::NicehashKey: /* --nicehash */
|
||||
case IConfig::TlsKey: /* --tls */
|
||||
case IConfig::DryRunKey: /* --dry-run */
|
||||
case IConfig::HttpEnabledKey: /* --http-enabled */
|
||||
case IConfig::DaemonKey: /* --daemon */
|
||||
return transformBoolean(doc, key, true);
|
||||
|
||||
case IConfig::ColorKey: /* --no-color */
|
||||
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case IConfig::ApiRestrictedKey: /* --api-no-restricted */
|
||||
case IConfig::ApiIPv6Key: /* --api-ipv6 */
|
||||
# endif
|
||||
return transformBoolean(doc, key, false);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable)
|
||||
{
|
||||
switch (key) {
|
||||
case IConfig::BackgroundKey: /* --background */
|
||||
return set(doc, "background", enable);
|
||||
|
||||
case IConfig::SyslogKey: /* --syslog */
|
||||
return set(doc, "syslog", enable);
|
||||
|
||||
case IConfig::KeepAliveKey: /* --keepalive */
|
||||
return add(doc, kPools, "keepalive", enable);
|
||||
|
||||
case IConfig::TlsKey: /* --tls */
|
||||
return add(doc, kPools, "tls", enable);
|
||||
|
||||
case IConfig::DaemonKey: /* --daemon */
|
||||
return add(doc, kPools, "daemon", enable);
|
||||
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
case IConfig::NicehashKey: /* --nicehash */
|
||||
return add<bool>(doc, kPools, "nicehash", enable);
|
||||
# endif
|
||||
|
||||
case IConfig::ColorKey: /* --no-color */
|
||||
return set(doc, "colors", enable);
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case IConfig::ApiIPv6Key: /* --api-ipv6 */
|
||||
break;
|
||||
|
||||
case IConfig::ApiRestrictedKey: /* --api-no-restricted */
|
||||
fputs("option \"--api-no-restricted\" deprecated, use \"--http-no-restricted\" instead.\n", stderr);
|
||||
fflush(stdout);
|
||||
return set(doc, kHttp, "restricted", enable);
|
||||
# endif
|
||||
|
||||
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
|
||||
return set(doc, kHttp, "restricted", enable);
|
||||
|
||||
case IConfig::HttpEnabledKey: /* --http-enabled */
|
||||
return set(doc, kHttp, "enabled", enable);
|
||||
|
||||
case IConfig::DryRunKey: /* --dry-run */
|
||||
return set(doc, "dry-run", enable);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg)
|
||||
{
|
||||
switch (key) {
|
||||
case IConfig::RetriesKey: /* --retries */
|
||||
return set(doc, "retries", arg);
|
||||
|
||||
case IConfig::RetryPauseKey: /* --retry-pause */
|
||||
return set(doc, "retry-pause", arg);
|
||||
|
||||
case IConfig::DonateLevelKey: /* --donate-level */
|
||||
return set(doc, "donate-level", arg);
|
||||
|
||||
case IConfig::ProxyDonateKey: /* --donate-over-proxy */
|
||||
return set(doc, "donate-over-proxy", arg);
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case IConfig::ApiPort: /* --api-port */
|
||||
fputs("option \"--api-port\" deprecated, use \"--http-port\" instead.\n", stderr);
|
||||
fflush(stdout);
|
||||
return set(doc, kHttp, "port", arg);
|
||||
# endif
|
||||
|
||||
case IConfig::HttpPort: /* --http-port */
|
||||
return set(doc, kHttp, "port", arg);
|
||||
|
||||
case IConfig::PrintTimeKey: /* --print-time */
|
||||
return set(doc, "print-time", arg);
|
||||
|
||||
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
|
||||
return add(doc, kPools, "daemon-poll-interval", arg);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
123
src/base/kernel/config/BaseTransform.h
Normal file
123
src/base/kernel/config/BaseTransform.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_BASETRANSFORM_H
|
||||
#define XMRIG_BASETRANSFORM_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IConfigTransform.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
struct option;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfigTransform;
|
||||
class JsonChain;
|
||||
class Process;
|
||||
|
||||
|
||||
class BaseTransform : public IConfigTransform
|
||||
{
|
||||
public:
|
||||
BaseTransform();
|
||||
|
||||
static void load(JsonChain &chain, Process *process, IConfigTransform &transform);
|
||||
|
||||
protected:
|
||||
void transform(rapidjson::Document &doc, int key, const char *arg) override;
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void set(rapidjson::Document &doc, const char *key, T value) { set<T>(doc, doc, key, value); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void set(rapidjson::Document &doc, const char *objKey, const char *key, T value)
|
||||
{
|
||||
if (!doc.HasMember(objKey)) {
|
||||
doc.AddMember(rapidjson::StringRef(objKey), rapidjson::kObjectType, doc.GetAllocator());
|
||||
}
|
||||
|
||||
set<T>(doc, doc[objKey], key, value);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void add(rapidjson::Document &doc, const char *arrayKey, const char *key, T value, bool force = false)
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
if (!doc.HasMember(arrayKey)) {
|
||||
doc.AddMember(rapidjson::StringRef(arrayKey), rapidjson::kArrayType, allocator);
|
||||
}
|
||||
|
||||
rapidjson::Value &array = doc[arrayKey];
|
||||
if (force || array.Size() == 0) {
|
||||
array.PushBack(rapidjson::kObjectType, allocator);
|
||||
}
|
||||
|
||||
set<T>(doc, array[array.Size() - 1], key, value);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, T value)
|
||||
{
|
||||
if (obj.HasMember(key)) {
|
||||
obj[key] = value;
|
||||
}
|
||||
else {
|
||||
obj.AddMember(rapidjson::StringRef(key), value, doc.GetAllocator());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void transformBoolean(rapidjson::Document &doc, int key, bool enable);
|
||||
void transformUint64(rapidjson::Document &doc, int key, uint64_t arg);
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
inline void BaseTransform::set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, const char *value)
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
if (obj.HasMember(key)) {
|
||||
obj[key] = rapidjson::Value(value, allocator);
|
||||
}
|
||||
else {
|
||||
obj.AddMember(rapidjson::StringRef(key), rapidjson::Value(value, allocator), allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_BASETRANSFORM_H */
|
||||
47
src/base/kernel/interfaces/IBaseListener.h
Normal file
47
src/base/kernel/interfaces/IBaseListener.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_IBASELISTENER_H
|
||||
#define XMRIG_IBASELISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Config;
|
||||
|
||||
|
||||
class IBaseListener
|
||||
{
|
||||
public:
|
||||
virtual ~IBaseListener() = default;
|
||||
|
||||
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_IBASELISTENER_H
|
||||
85
src/base/kernel/interfaces/IClient.h
Normal file
85
src/base/kernel/interfaces/IClient.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ICLIENT_H
|
||||
#define XMRIG_ICLIENT_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Algorithm;
|
||||
class Job;
|
||||
class JobResult;
|
||||
class Pool;
|
||||
class String;
|
||||
|
||||
|
||||
class IClient
|
||||
{
|
||||
public:
|
||||
enum Extension {
|
||||
EXT_ALGO,
|
||||
EXT_NICEHASH,
|
||||
EXT_CONNECT,
|
||||
EXT_TLS,
|
||||
EXT_KEEPALIVE,
|
||||
EXT_MAX
|
||||
};
|
||||
|
||||
virtual ~IClient() = default;
|
||||
|
||||
virtual bool disconnect() = 0;
|
||||
virtual bool hasExtension(Extension extension) const noexcept = 0;
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual bool isTLS() const = 0;
|
||||
virtual const char *mode() const = 0;
|
||||
virtual const char *tlsFingerprint() const = 0;
|
||||
virtual const char *tlsVersion() const = 0;
|
||||
virtual const Job &job() const = 0;
|
||||
virtual const Pool &pool() const = 0;
|
||||
virtual const String &ip() const = 0;
|
||||
virtual int id() const = 0;
|
||||
virtual int64_t submit(const JobResult &result) = 0;
|
||||
virtual void connect() = 0;
|
||||
virtual void connect(const Pool &pool) = 0;
|
||||
virtual void deleteLater() = 0;
|
||||
virtual void setAlgo(const Algorithm &algo) = 0;
|
||||
virtual void setEnabled(bool enabled) = 0;
|
||||
virtual void setPool(const Pool &pool) = 0;
|
||||
virtual void setQuiet(bool quiet) = 0;
|
||||
virtual void setRetries(int retries) = 0;
|
||||
virtual void setRetryPause(uint64_t ms) = 0;
|
||||
virtual void tick(uint64_t now) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ICLIENT_H
|
||||
59
src/base/kernel/interfaces/IClientListener.h
Normal file
59
src/base/kernel/interfaces/IClientListener.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ICLIENTLISTENER_H
|
||||
#define XMRIG_ICLIENTLISTENER_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IClient;
|
||||
class Job;
|
||||
class SubmitResult;
|
||||
|
||||
|
||||
class IClientListener
|
||||
{
|
||||
public:
|
||||
virtual ~IClientListener() = default;
|
||||
|
||||
virtual void onClose(IClient *client, int failures) = 0;
|
||||
virtual void onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms) = 0;
|
||||
virtual void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0;
|
||||
virtual void onLoginSuccess(IClient *client) = 0;
|
||||
virtual void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ICLIENTLISTENER_H
|
||||
157
src/base/kernel/interfaces/IConfig.h
Normal file
157
src/base/kernel/interfaces/IConfig.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ICONFIG_H
|
||||
#define XMRIG_ICONFIG_H
|
||||
|
||||
|
||||
#include "common/crypto/Algorithm.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IJsonReader;
|
||||
class String;
|
||||
|
||||
|
||||
class IConfig
|
||||
{
|
||||
public:
|
||||
enum Keys {
|
||||
// common
|
||||
AlgorithmKey = 'a',
|
||||
ApiWorkerIdKey = 4002,
|
||||
ApiIdKey = 4005,
|
||||
HttpPort = 4100,
|
||||
HttpAccessTokenKey = 4101,
|
||||
HttpRestrictedKey = 4104,
|
||||
HttpEnabledKey = 4106,
|
||||
HttpHostKey = 4107,
|
||||
BackgroundKey = 'B',
|
||||
ColorKey = 1002,
|
||||
ConfigKey = 'c',
|
||||
DonateLevelKey = 1003,
|
||||
KeepAliveKey = 'k',
|
||||
LogFileKey = 'l',
|
||||
PasswordKey = 'p',
|
||||
RetriesKey = 'r',
|
||||
RetryPauseKey = 'R',
|
||||
RigIdKey = 1012,
|
||||
SyslogKey = 'S',
|
||||
UrlKey = 'o',
|
||||
UserAgentKey = 1008,
|
||||
UserKey = 'u',
|
||||
UserpassKey = 'O',
|
||||
VariantKey = 1010,
|
||||
VerboseKey = 1100,
|
||||
TlsKey = 1013,
|
||||
FingerprintKey = 1014,
|
||||
ProxyDonateKey = 1017,
|
||||
DaemonKey = 1018,
|
||||
DaemonPollKey = 1019,
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
ApiPort = 4000,
|
||||
ApiAccessTokenKey = 4001,
|
||||
ApiIPv6Key = 4003,
|
||||
ApiRestrictedKey = 4004,
|
||||
# endif
|
||||
|
||||
// xmrig common
|
||||
CPUPriorityKey = 1021,
|
||||
NicehashKey = 1006,
|
||||
PrintTimeKey = 1007,
|
||||
|
||||
// xmrig cpu
|
||||
AVKey = 'v',
|
||||
CPUAffinityKey = 1020,
|
||||
DryRunKey = 5000,
|
||||
HugePagesKey = 1009,
|
||||
MaxCPUUsageKey = 1004,
|
||||
SafeKey = 1005,
|
||||
ThreadsKey = 't',
|
||||
// HardwareAESKey = 1011,
|
||||
AssemblyKey = 1015,
|
||||
|
||||
// xmrig amd
|
||||
OclPlatformKey = 1400,
|
||||
OclAffinityKey = 1401,
|
||||
OclDevicesKey = 1402,
|
||||
OclLaunchKey = 1403,
|
||||
OclCacheKey = 1404,
|
||||
OclPrintKey = 1405,
|
||||
OclLoaderKey = 1406,
|
||||
OclSridedIndexKey = 1407,
|
||||
OclMemChunkKey = 1408,
|
||||
OclUnrollKey = 1409,
|
||||
OclCompModeKey = 1410,
|
||||
|
||||
// xmrig-proxy
|
||||
AccessLogFileKey = 'A',
|
||||
BindKey = 'b',
|
||||
CustomDiffKey = 1102,
|
||||
DebugKey = 1101,
|
||||
ModeKey = 'm',
|
||||
PoolCoinKey = 'C',
|
||||
ReuseTimeoutKey = 1106,
|
||||
WorkersKey = 1103,
|
||||
WorkersAdvKey = 1107,
|
||||
TlsBindKey = 1108,
|
||||
TlsCertKey = 1109,
|
||||
TlsCertKeyKey = 1110,
|
||||
TlsDHparamKey = 1111,
|
||||
TlsCiphersKey = 1112,
|
||||
TlsCipherSuitesKey = 1113,
|
||||
TlsProtocolsKey = 1114,
|
||||
AlgoExtKey = 1115,
|
||||
ProxyPasswordKey = 1116,
|
||||
|
||||
// xmrig nvidia
|
||||
CudaMaxThreadsKey = 1200,
|
||||
CudaBFactorKey = 1201,
|
||||
CudaBSleepKey = 1202,
|
||||
CudaDevicesKey = 1203,
|
||||
CudaLaunchKey = 1204,
|
||||
CudaAffinityKey = 1205,
|
||||
CudaMaxUsageKey = 1206,
|
||||
};
|
||||
|
||||
virtual ~IConfig() = default;
|
||||
|
||||
virtual bool isWatch() const = 0;
|
||||
virtual bool read(const IJsonReader &reader, const char *fileName) = 0;
|
||||
virtual bool save() = 0;
|
||||
virtual const Algorithm &algorithm() const = 0;
|
||||
virtual const String &fileName() const = 0;
|
||||
virtual void getJSON(rapidjson::Document &doc) const = 0;
|
||||
virtual void setFileName(const char *fileName) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ICONFIG_H
|
||||
@@ -22,58 +22,31 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
#ifndef XMRIG_ICONFIGTRANSFORM_H
|
||||
#define XMRIG_ICONFIGTRANSFORM_H
|
||||
|
||||
|
||||
#include "base/tools/Handle.h"
|
||||
#include "common/crypto/Algorithm.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
void xmrig::Handle::close(uv_fs_event_t *handle)
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IJsonReader;
|
||||
class String;
|
||||
|
||||
|
||||
class IConfigTransform
|
||||
{
|
||||
if (handle) {
|
||||
uv_fs_event_stop(handle);
|
||||
close(reinterpret_cast<uv_handle_t *>(handle));
|
||||
}
|
||||
}
|
||||
public:
|
||||
virtual ~IConfigTransform() = default;
|
||||
|
||||
virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0;
|
||||
};
|
||||
|
||||
|
||||
void xmrig::Handle::close(uv_getaddrinfo_t *handle)
|
||||
{
|
||||
if (handle) {
|
||||
uv_cancel(reinterpret_cast<uv_req_t *>(handle));
|
||||
close(reinterpret_cast<uv_handle_t *>(handle));
|
||||
}
|
||||
}
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
void xmrig::Handle::close(uv_handle_t *handle)
|
||||
{
|
||||
uv_close(handle, [](uv_handle_t *handle) { delete handle; });
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Handle::close(uv_signal_t *handle)
|
||||
{
|
||||
if (handle) {
|
||||
uv_signal_stop(handle);
|
||||
close(reinterpret_cast<uv_handle_t *>(handle));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Handle::close(uv_tcp_t *handle)
|
||||
{
|
||||
if (handle) {
|
||||
close(reinterpret_cast<uv_handle_t *>(handle));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Handle::close(uv_timer_s *handle)
|
||||
{
|
||||
if (handle) {
|
||||
uv_timer_stop(handle);
|
||||
close(reinterpret_cast<uv_handle_t *>(handle));
|
||||
}
|
||||
}
|
||||
#endif // XMRIG_ICONFIGTRANSFORM_H
|
||||
44
src/base/kernel/interfaces/IConsoleListener.h
Normal file
44
src/base/kernel/interfaces/IConsoleListener.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ICONSOLELISTENER_H
|
||||
#define XMRIG_ICONSOLELISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConsoleListener
|
||||
{
|
||||
public:
|
||||
virtual ~IConsoleListener() = default;
|
||||
|
||||
virtual void onConsoleCommand(char command) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ICONSOLELISTENER_H
|
||||
47
src/base/kernel/interfaces/IDnsListener.h
Normal file
47
src/base/kernel/interfaces/IDnsListener.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_IDNSLISTENER_H
|
||||
#define XMRIG_IDNSLISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Dns;
|
||||
|
||||
|
||||
class IDnsListener
|
||||
{
|
||||
public:
|
||||
virtual ~IDnsListener() = default;
|
||||
|
||||
virtual void onResolved(const Dns &dns, int status) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_IDNSLISTENER_H
|
||||
48
src/base/kernel/interfaces/IHttpListener.h
Normal file
48
src/base/kernel/interfaces/IHttpListener.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_IHTTPLISTENER_H
|
||||
#define XMRIG_IHTTPLISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpData;
|
||||
class HttpResponse;
|
||||
|
||||
|
||||
class IHttpListener
|
||||
{
|
||||
public:
|
||||
virtual ~IHttpListener() = default;
|
||||
|
||||
virtual void onHttpData(const HttpData &data) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_IHTTPLISTENER_H
|
||||
56
src/base/kernel/interfaces/IJsonReader.h
Normal file
56
src/base/kernel/interfaces/IJsonReader.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_IJSONREADER_H
|
||||
#define XMRIG_IJSONREADER_H
|
||||
|
||||
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IJsonReader
|
||||
{
|
||||
public:
|
||||
virtual ~IJsonReader() = default;
|
||||
|
||||
virtual bool getBool(const char *key, bool defaultValue = false) const = 0;
|
||||
virtual bool isEmpty() const = 0;
|
||||
virtual const char *getString(const char *key, const char *defaultValue = nullptr) const = 0;
|
||||
virtual const rapidjson::Value &getArray(const char *key) const = 0;
|
||||
virtual const rapidjson::Value &getObject(const char *key) const = 0;
|
||||
virtual const rapidjson::Value &getValue(const char *key) const = 0;
|
||||
virtual int getInt(const char *key, int defaultValue = 0) const = 0;
|
||||
virtual int64_t getInt64(const char *key, int64_t defaultValue = 0) const = 0;
|
||||
virtual uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const = 0;
|
||||
virtual unsigned getUint(const char *key, unsigned defaultValue = 0) const = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_IJSONREADER_H
|
||||
50
src/base/kernel/interfaces/ILineListener.h
Normal file
50
src/base/kernel/interfaces/ILineListener.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ILINELISTENER_H
|
||||
#define XMRIG_ILINELISTENER_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class String;
|
||||
|
||||
|
||||
class ILineListener
|
||||
{
|
||||
public:
|
||||
virtual ~ILineListener() = default;
|
||||
|
||||
virtual void onLine(char *line, size_t size) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ILINELISTENER_H
|
||||
49
src/base/kernel/interfaces/ILogBackend.h
Normal file
49
src/base/kernel/interfaces/ILogBackend.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ILOGBACKEND_H
|
||||
#define XMRIG_ILOGBACKEND_H
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ILogBackend
|
||||
{
|
||||
public:
|
||||
virtual ~ILogBackend() = default;
|
||||
|
||||
virtual void print(int level, const char *line, size_t offset, size_t size, bool colors) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ILOGBACKEND_H
|
||||
59
src/base/kernel/interfaces/IStrategy.h
Normal file
59
src/base/kernel/interfaces/IStrategy.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ISTRATEGY_H
|
||||
#define XMRIG_ISTRATEGY_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Algorithm;
|
||||
class IClient;
|
||||
class JobResult;
|
||||
|
||||
|
||||
class IStrategy
|
||||
{
|
||||
public:
|
||||
virtual ~IStrategy() = default;
|
||||
|
||||
virtual bool isActive() const = 0;
|
||||
virtual IClient *client() const = 0;
|
||||
virtual int64_t submit(const JobResult &result) = 0;
|
||||
virtual void connect() = 0;
|
||||
virtual void resume() = 0;
|
||||
virtual void setAlgo(const Algorithm &algo) = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void tick(uint64_t now) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ISTRATEGY_H
|
||||
56
src/base/kernel/interfaces/IStrategyListener.h
Normal file
56
src/base/kernel/interfaces/IStrategyListener.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ISTRATEGYLISTENER_H
|
||||
#define XMRIG_ISTRATEGYLISTENER_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IClient;
|
||||
class IStrategy;
|
||||
class Job;
|
||||
class SubmitResult;
|
||||
|
||||
|
||||
class IStrategyListener
|
||||
{
|
||||
public:
|
||||
virtual ~IStrategyListener() = default;
|
||||
|
||||
virtual void onActive(IStrategy *strategy, IClient *client) = 0;
|
||||
virtual void onJob(IStrategy *strategy, IClient *client, const Job &job) = 0;
|
||||
virtual void onPause(IStrategy *strategy) = 0;
|
||||
virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ISTRATEGYLISTENER_H
|
||||
53
src/base/kernel/interfaces/ITcpServerListener.h
Normal file
53
src/base/kernel/interfaces/ITcpServerListener.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ITCPSERVERLISTENER_H
|
||||
#define XMRIG_ITCPSERVERLISTENER_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct uv_stream_s uv_stream_t;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class String;
|
||||
|
||||
|
||||
class ITcpServerListener
|
||||
{
|
||||
public:
|
||||
virtual ~ITcpServerListener() = default;
|
||||
|
||||
virtual void onConnection(uv_stream_t *stream, uint16_t port) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ITCPSERVERLISTENER_H
|
||||
47
src/base/kernel/interfaces/ITimerListener.h
Normal file
47
src/base/kernel/interfaces/ITimerListener.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ITIMERLISTENER_H
|
||||
#define XMRIG_ITIMERLISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Timer;
|
||||
|
||||
|
||||
class ITimerListener
|
||||
{
|
||||
public:
|
||||
virtual ~ITimerListener() = default;
|
||||
|
||||
virtual void onTimer(const Timer *timer) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ITIMERLISTENER_H
|
||||
163
src/base/net/dns/Dns.cpp
Normal file
163
src/base/net/dns/Dns.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IDnsListener.h"
|
||||
#include "base/net/dns/Dns.h"
|
||||
#include "base/tools/Handle.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
Storage<Dns> Dns::m_storage;
|
||||
static const DnsRecord defaultRecord;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Dns::Dns(IDnsListener *listener) :
|
||||
m_hints(),
|
||||
m_listener(listener),
|
||||
m_status(0),
|
||||
m_resolver(nullptr)
|
||||
{
|
||||
m_key = m_storage.add(this);
|
||||
|
||||
m_resolver = new uv_getaddrinfo_t;
|
||||
m_resolver->data = m_storage.ptr(m_key);
|
||||
|
||||
m_hints.ai_family = AF_UNSPEC;
|
||||
m_hints.ai_socktype = SOCK_STREAM;
|
||||
m_hints.ai_protocol = IPPROTO_TCP;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Dns::~Dns()
|
||||
{
|
||||
m_storage.release(m_key);
|
||||
|
||||
delete m_resolver;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Dns::resolve(const String &host)
|
||||
{
|
||||
if (m_host != host) {
|
||||
m_host = host;
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
m_status = uv_getaddrinfo(uv_default_loop(), m_resolver, Dns::onResolved, m_host.data(), nullptr, &m_hints);
|
||||
|
||||
return m_status == 0;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Dns::error() const
|
||||
{
|
||||
return uv_strerror(m_status);
|
||||
}
|
||||
|
||||
|
||||
const xmrig::DnsRecord &xmrig::Dns::get(DnsRecord::Type prefered) const
|
||||
{
|
||||
if (count() == 0) {
|
||||
return defaultRecord;
|
||||
}
|
||||
|
||||
const size_t ipv4 = m_ipv4.size();
|
||||
const size_t ipv6 = m_ipv6.size();
|
||||
|
||||
if (ipv6 && (prefered == DnsRecord::AAAA || !ipv4)) {
|
||||
return m_ipv6[ipv6 == 1 ? 0 : static_cast<size_t>(rand()) % ipv6];
|
||||
}
|
||||
|
||||
if (ipv4) {
|
||||
return m_ipv4[ipv4 == 1 ? 0 : static_cast<size_t>(rand()) % ipv4];
|
||||
}
|
||||
|
||||
return defaultRecord;
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::Dns::count(DnsRecord::Type type) const
|
||||
{
|
||||
if (type == DnsRecord::A) {
|
||||
return m_ipv4.size();
|
||||
}
|
||||
|
||||
if (type == DnsRecord::AAAA) {
|
||||
return m_ipv6.size();
|
||||
}
|
||||
|
||||
return m_ipv4.size() + m_ipv6.size();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Dns::clear()
|
||||
{
|
||||
m_ipv4.clear();
|
||||
m_ipv6.clear();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Dns::onResolved(int status, addrinfo *res)
|
||||
{
|
||||
m_status = status;
|
||||
|
||||
if (m_status < 0) {
|
||||
return m_listener->onResolved(*this, status);
|
||||
}
|
||||
|
||||
clear();
|
||||
|
||||
addrinfo *ptr = res;
|
||||
while (ptr != nullptr) {
|
||||
if (ptr->ai_family == AF_INET) {
|
||||
m_ipv4.push_back(ptr);
|
||||
}
|
||||
|
||||
if (ptr->ai_family == AF_INET6) {
|
||||
m_ipv6.push_back(ptr);
|
||||
}
|
||||
|
||||
ptr = ptr->ai_next;
|
||||
}
|
||||
|
||||
if (isEmpty()) {
|
||||
m_status = UV_EAI_NONAME;
|
||||
}
|
||||
|
||||
m_listener->onResolved(*this, m_status);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Dns::onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res)
|
||||
{
|
||||
Dns *dns = m_storage.get(req->data);
|
||||
if (dns) {
|
||||
dns->onResolved(status, res);
|
||||
}
|
||||
|
||||
uv_freeaddrinfo(res);
|
||||
}
|
||||
81
src/base/net/dns/Dns.h
Normal file
81
src/base/net/dns/Dns.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_DNS_H
|
||||
#define XMRIG_DNS_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/net/dns/DnsRecord.h"
|
||||
#include "base/net/tools/Storage.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IDnsListener;
|
||||
|
||||
|
||||
class Dns
|
||||
{
|
||||
public:
|
||||
Dns(IDnsListener *listener);
|
||||
~Dns();
|
||||
|
||||
inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); }
|
||||
inline const String &host() const { return m_host; }
|
||||
inline int status() const { return m_status; }
|
||||
|
||||
bool resolve(const String &host);
|
||||
const char *error() const;
|
||||
const DnsRecord &get(DnsRecord::Type prefered = DnsRecord::A) const;
|
||||
size_t count(DnsRecord::Type type = DnsRecord::Unknown) const;
|
||||
|
||||
private:
|
||||
void clear();
|
||||
void onResolved(int status, addrinfo *res);
|
||||
|
||||
static void onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res);
|
||||
|
||||
addrinfo m_hints;
|
||||
IDnsListener *m_listener;
|
||||
int m_status;
|
||||
std::vector<DnsRecord> m_ipv4;
|
||||
std::vector<DnsRecord> m_ipv6;
|
||||
String m_host;
|
||||
uintptr_t m_key;
|
||||
uv_getaddrinfo_t *m_resolver;
|
||||
|
||||
static Storage<Dns> m_storage;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_DNS_H */
|
||||
66
src/base/net/dns/DnsRecord.cpp
Normal file
66
src/base/net/dns/DnsRecord.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/net/dns/DnsRecord.h"
|
||||
|
||||
|
||||
xmrig::DnsRecord::DnsRecord(const addrinfo *addr) :
|
||||
m_type(addr->ai_family == AF_INET6 ? AAAA : A)
|
||||
{
|
||||
char *buf = nullptr;
|
||||
|
||||
if (m_type == AAAA) {
|
||||
buf = new char[45]();
|
||||
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), buf, 45);
|
||||
}
|
||||
else {
|
||||
buf = new char[16]();
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), buf, 16);
|
||||
}
|
||||
|
||||
m_ip = buf;
|
||||
}
|
||||
|
||||
|
||||
sockaddr *xmrig::DnsRecord::addr(uint16_t port) const
|
||||
{
|
||||
if (m_type == A) {
|
||||
sockaddr_in *addr = new sockaddr_in();
|
||||
uv_ip4_addr(m_ip.data(), port, addr);
|
||||
|
||||
return reinterpret_cast<sockaddr *>(addr);
|
||||
}
|
||||
else if (m_type == AAAA) {
|
||||
sockaddr_in6 *addr = new sockaddr_in6();
|
||||
uv_ip6_addr(m_ip.data(), port, addr);
|
||||
|
||||
return reinterpret_cast<sockaddr *>(addr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
66
src/base/net/dns/DnsRecord.h
Normal file
66
src/base/net/dns/DnsRecord.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_DNSRECORD_H
|
||||
#define XMRIG_DNSRECORD_H
|
||||
|
||||
|
||||
struct addrinfo;
|
||||
struct sockaddr;
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class DnsRecord
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
Unknown,
|
||||
A,
|
||||
AAAA
|
||||
};
|
||||
|
||||
inline DnsRecord() : m_type(Unknown) {}
|
||||
DnsRecord(const addrinfo *addr);
|
||||
|
||||
sockaddr *addr(uint16_t port = 0) const;
|
||||
|
||||
inline bool isValid() const { return m_type != Unknown; }
|
||||
inline const String &ip() const { return m_ip; }
|
||||
inline Type type() const { return m_type; }
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
String m_ip;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_DNSRECORD_H */
|
||||
99
src/base/net/http/Http.cpp
Normal file
99
src/base/net/http/Http.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/net/http/Http.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kEnabled = "enabled";
|
||||
static const char *kHost = "host";
|
||||
static const char *kLocalhost = "127.0.0.1";
|
||||
static const char *kPort = "port";
|
||||
static const char *kRestricted = "restricted";
|
||||
static const char *kToken = "access-token";
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::Http::Http() :
|
||||
m_enabled(false),
|
||||
m_restricted(true),
|
||||
m_host(kLocalhost),
|
||||
m_port(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Http::isEqual(const Http &other) const
|
||||
{
|
||||
return other.m_enabled == m_enabled &&
|
||||
other.m_restricted == m_restricted &&
|
||||
other.m_host == m_host &&
|
||||
other.m_token == m_token &&
|
||||
other.m_port == m_port;
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value xmrig::Http::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value obj(kObjectType);
|
||||
|
||||
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
||||
obj.AddMember(StringRef(kHost), m_host.toJSON(), allocator);
|
||||
obj.AddMember(StringRef(kPort), m_port, allocator);
|
||||
obj.AddMember(StringRef(kToken), m_token.toJSON(), allocator);
|
||||
obj.AddMember(StringRef(kRestricted), m_restricted, allocator);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Http::load(const rapidjson::Value &http)
|
||||
{
|
||||
if (!http.IsObject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_enabled = Json::getBool(http, kEnabled);
|
||||
m_restricted = Json::getBool(http, kRestricted, true);
|
||||
m_host = Json::getString(http, kHost, kLocalhost);
|
||||
m_token = Json::getString(http, kToken);
|
||||
|
||||
setPort(Json::getInt(http, kPort));
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Http::setPort(int port)
|
||||
{
|
||||
if (port >= 0 && port <= 65536) {
|
||||
m_port = static_cast<uint16_t>(port);
|
||||
}
|
||||
}
|
||||
73
src/base/net/http/Http.h
Normal file
73
src/base/net/http/Http.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTP_H
|
||||
#define XMRIG_HTTP_H
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Http
|
||||
{
|
||||
public:
|
||||
Http();
|
||||
|
||||
inline bool isAuthRequired() const { return m_restricted == false || !m_token.isNull(); }
|
||||
inline bool isEnabled() const { return m_enabled; }
|
||||
inline bool isRestricted() const { return m_restricted; }
|
||||
inline const String &host() const { return m_host; }
|
||||
inline const String &token() const { return m_token; }
|
||||
inline uint16_t port() const { return m_port; }
|
||||
inline void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||
inline void setHost(const char *host) { m_host = host; }
|
||||
inline void setRestricted(bool restricted) { m_restricted = restricted; }
|
||||
inline void setToken(const char *token) { m_token = token; }
|
||||
|
||||
inline bool operator!=(const Http &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const Http &other) const { return isEqual(other); }
|
||||
|
||||
bool isEqual(const Http &other) const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
void load(const rapidjson::Value &http);
|
||||
void setPort(int port);
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
bool m_restricted;
|
||||
String m_host;
|
||||
String m_token;
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTP_H
|
||||
|
||||
86
src/base/net/http/HttpApiResponse.cpp
Normal file
86
src/base/net/http/HttpApiResponse.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "base/net/http/HttpApiResponse.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kError = "error";
|
||||
static const char *kStatus = "status";
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpApiResponse::HttpApiResponse(uint64_t id) :
|
||||
HttpResponse(id),
|
||||
m_doc(rapidjson::kObjectType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpApiResponse::HttpApiResponse(uint64_t id, int status) :
|
||||
HttpResponse(id),
|
||||
m_doc(rapidjson::kObjectType)
|
||||
{
|
||||
setStatus(status);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpApiResponse::end()
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
setHeader("Access-Control-Allow-Origin", "*");
|
||||
setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
|
||||
setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
|
||||
|
||||
if (statusCode() >= 400) {
|
||||
if (!m_doc.HasMember(kStatus)) {
|
||||
m_doc.AddMember(StringRef(kStatus), statusCode(), m_doc.GetAllocator());
|
||||
}
|
||||
|
||||
if (!m_doc.HasMember(kError)) {
|
||||
m_doc.AddMember(StringRef(kError), StringRef(http_status_str(static_cast<http_status>(statusCode()))), m_doc.GetAllocator());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_doc.MemberCount()) {
|
||||
return HttpResponse::end();
|
||||
}
|
||||
|
||||
setHeader("Content-Type", "application/json");
|
||||
|
||||
StringBuffer buffer(nullptr, 4096);
|
||||
PrettyWriter<StringBuffer> writer(buffer);
|
||||
writer.SetMaxDecimalPlaces(10);
|
||||
m_doc.Accept(writer);
|
||||
|
||||
HttpResponse::end(buffer.GetString(), buffer.GetSize());
|
||||
}
|
||||
57
src/base/net/http/HttpApiResponse.h
Normal file
57
src/base/net/http/HttpApiResponse.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPAPIRESPONSE_H
|
||||
#define XMRIG_HTTPAPIRESPONSE_H
|
||||
|
||||
|
||||
#include "base/net/http/HttpResponse.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpApiResponse : public HttpResponse
|
||||
{
|
||||
public:
|
||||
HttpApiResponse(uint64_t id);
|
||||
HttpApiResponse(uint64_t id, int status);
|
||||
|
||||
inline rapidjson::Document &doc() { return m_doc; }
|
||||
|
||||
void end();
|
||||
|
||||
private:
|
||||
rapidjson::Document m_doc;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPAPIRESPONSE_H
|
||||
|
||||
224
src/base/net/http/HttpClient.cpp
Normal file
224
src/base/net/http/HttpClient.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/dns/Dns.h"
|
||||
#include "base/net/http/HttpClient.h"
|
||||
#include "base/tools/Baton.h"
|
||||
#include "common/Platform.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kCRLF = "\r\n";
|
||||
|
||||
|
||||
class ClientWriteBaton : public Baton<uv_write_t>
|
||||
{
|
||||
public:
|
||||
inline ClientWriteBaton(const std::string &header, std::string &&body) :
|
||||
m_body(std::move(body)),
|
||||
m_header(header)
|
||||
{
|
||||
bufs[0].len = m_header.size();
|
||||
bufs[0].base = const_cast<char *>(m_header.c_str());
|
||||
|
||||
if (!m_body.empty()) {
|
||||
bufs[1].len = m_body.size();
|
||||
bufs[1].base = const_cast<char *>(m_body.c_str());
|
||||
}
|
||||
else {
|
||||
bufs[1].base = nullptr;
|
||||
bufs[1].len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
|
||||
inline size_t size() const { return bufs[0].len + bufs[1].len; }
|
||||
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<ClientWriteBaton *>(req->data); }
|
||||
|
||||
|
||||
uv_buf_t bufs[2];
|
||||
|
||||
private:
|
||||
std::string m_body;
|
||||
std::string m_header;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
|
||||
HttpContext(HTTP_RESPONSE, listener),
|
||||
m_quiet(false),
|
||||
m_port(0)
|
||||
{
|
||||
this->method = method;
|
||||
this->url = url;
|
||||
|
||||
if (data) {
|
||||
body = size ? std::string(data, size) : data;
|
||||
}
|
||||
|
||||
m_dns = new Dns(this);
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpClient::~HttpClient()
|
||||
{
|
||||
delete m_dns;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpClient::connect(const String &host, uint16_t port)
|
||||
{
|
||||
m_port = port;
|
||||
|
||||
return m_dns->resolve(host);
|
||||
}
|
||||
|
||||
|
||||
const xmrig::String &xmrig::HttpClient::host() const
|
||||
{
|
||||
return m_dns->host();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::onResolved(const Dns &dns, int status)
|
||||
{
|
||||
this->status = status;
|
||||
|
||||
if (status < 0 && dns.isEmpty()) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), m_port, uv_strerror(status));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sockaddr *addr = dns.get().addr(m_port);
|
||||
|
||||
uv_connect_t *req = new uv_connect_t;
|
||||
req->data = this;
|
||||
|
||||
uv_tcp_connect(req, m_tcp, addr, onConnect);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::handshake()
|
||||
{
|
||||
headers.insert({ "Host", m_dns->host().data() });
|
||||
headers.insert({ "Connection", "close" });
|
||||
headers.insert({ "User-Agent", Platform::userAgent() });
|
||||
|
||||
if (body.size()) {
|
||||
headers.insert({ "Content-Length", std::to_string(body.size()) });
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << http_method_str(static_cast<http_method>(method)) << " " << url << " HTTP/1.1" << kCRLF;
|
||||
|
||||
for (auto &header : headers) {
|
||||
ss << header.first << ": " << header.second << kCRLF;
|
||||
}
|
||||
|
||||
ss << kCRLF;
|
||||
|
||||
headers.clear();
|
||||
|
||||
write(ss.str());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::read(const char *data, size_t size)
|
||||
{
|
||||
if (parse(data, size) < size) {
|
||||
close(UV_EPROTO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::write(const std::string &header)
|
||||
{
|
||||
ClientWriteBaton *baton = new ClientWriteBaton(header, std::move(body));
|
||||
uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
|
||||
{
|
||||
HttpClient *client = static_cast<HttpClient *>(req->data);
|
||||
if (!client) {
|
||||
delete req;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
if (!client->m_quiet) {
|
||||
LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(status));
|
||||
}
|
||||
|
||||
delete req;
|
||||
client->close(status);
|
||||
return;
|
||||
}
|
||||
|
||||
uv_read_start(client->stream(),
|
||||
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
|
||||
{
|
||||
buf->base = new char[suggested_size];
|
||||
|
||||
# ifdef _WIN32
|
||||
buf->len = static_cast<unsigned int>(suggested_size);
|
||||
# else
|
||||
buf->len = suggested_size;
|
||||
# endif
|
||||
},
|
||||
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
HttpClient *client = static_cast<HttpClient*>(tcp->data);
|
||||
|
||||
if (nread >= 0) {
|
||||
client->read(buf->base, static_cast<size_t>(nread));
|
||||
} else {
|
||||
if (!client->m_quiet && nread != UV_EOF) {
|
||||
LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(static_cast<int>(nread)));
|
||||
}
|
||||
|
||||
client->close(static_cast<int>(nread));
|
||||
}
|
||||
|
||||
delete [] buf->base;
|
||||
});
|
||||
|
||||
client->handshake();
|
||||
}
|
||||
74
src/base/net/http/HttpClient.h
Normal file
74
src/base/net/http/HttpClient.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPCLIENT_H
|
||||
#define XMRIG_HTTPCLIENT_H
|
||||
|
||||
|
||||
#include "base/net/http/HttpContext.h"
|
||||
#include "base/kernel/interfaces/IDnsListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class String;
|
||||
|
||||
|
||||
class HttpClient : public HttpContext, public IDnsListener
|
||||
{
|
||||
public:
|
||||
HttpClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0);
|
||||
~HttpClient() override;
|
||||
|
||||
inline uint16_t port() const { return m_port; }
|
||||
inline void setQuiet(bool quiet) { m_quiet = quiet; }
|
||||
|
||||
bool connect(const String &host, uint16_t port);
|
||||
const String &host() const;
|
||||
|
||||
protected:
|
||||
void onResolved(const Dns &dns, int status) override;
|
||||
|
||||
virtual void handshake();
|
||||
virtual void read(const char *data, size_t size);
|
||||
virtual void write(const std::string &header);
|
||||
|
||||
bool m_quiet;
|
||||
|
||||
private:
|
||||
static void onConnect(uv_connect_t *req, int status);
|
||||
|
||||
Dns *m_dns;
|
||||
uint16_t m_port;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPCLIENT_H
|
||||
|
||||
228
src/base/net/http/HttpContext.cpp
Normal file
228
src/base/net/http/HttpContext.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "base/kernel/interfaces/IHttpListener.h"
|
||||
#include "base/net/http/HttpContext.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static http_parser_settings http_settings;
|
||||
static std::map<uint64_t, HttpContext *> storage;
|
||||
static uint64_t SEQUENCE = 0;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpContext::HttpContext(int parser_type, IHttpListener *listener) :
|
||||
HttpData(SEQUENCE++),
|
||||
m_wasHeaderValue(false),
|
||||
m_listener(listener)
|
||||
{
|
||||
storage[id()] = this;
|
||||
|
||||
m_parser = new http_parser;
|
||||
m_tcp = new uv_tcp_t;
|
||||
|
||||
uv_tcp_init(uv_default_loop(), m_tcp);
|
||||
uv_tcp_nodelay(m_tcp, 1);
|
||||
|
||||
http_parser_init(m_parser, static_cast<http_parser_type>(parser_type));
|
||||
|
||||
m_parser->data = m_tcp->data = this;
|
||||
|
||||
if (http_settings.on_message_complete == nullptr) {
|
||||
attach(&http_settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpContext::~HttpContext()
|
||||
{
|
||||
delete m_tcp;
|
||||
delete m_parser;
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::HttpContext::parse(const char *data, size_t size)
|
||||
{
|
||||
return http_parser_execute(m_parser, &http_settings, data, size);
|
||||
}
|
||||
|
||||
|
||||
std::string xmrig::HttpContext::ip() const
|
||||
{
|
||||
char ip[46] = {};
|
||||
sockaddr_storage addr = {};
|
||||
int size = sizeof(addr);
|
||||
|
||||
uv_tcp_getpeername(m_tcp, reinterpret_cast<sockaddr*>(&addr), &size);
|
||||
if (reinterpret_cast<sockaddr_in *>(&addr)->sin_family == AF_INET6) {
|
||||
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(&addr), ip, 45);
|
||||
}
|
||||
else {
|
||||
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), ip, 16);
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::close(int status)
|
||||
{
|
||||
if (status < 0 && m_listener) {
|
||||
this->status = status;
|
||||
m_listener->onHttpData(*this);
|
||||
}
|
||||
|
||||
auto it = storage.find(id());
|
||||
if (it != storage.end()) {
|
||||
storage.erase(it);
|
||||
}
|
||||
|
||||
if (!uv_is_closing(handle())) {
|
||||
uv_close(handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpContext *xmrig::HttpContext::get(uint64_t id)
|
||||
{
|
||||
if (storage.count(id) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return storage[id];
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::closeAll()
|
||||
{
|
||||
for (auto kv : storage) {
|
||||
if (!uv_is_closing(kv.second->handle())) {
|
||||
uv_close(kv.second->handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_t length)
|
||||
{
|
||||
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||
|
||||
if (ctx->m_wasHeaderValue) {
|
||||
if (!ctx->m_lastHeaderField.empty()) {
|
||||
ctx->setHeader();
|
||||
}
|
||||
|
||||
ctx->m_lastHeaderField = std::string(at, length);
|
||||
ctx->m_wasHeaderValue = false;
|
||||
} else {
|
||||
ctx->m_lastHeaderField += std::string(at, length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_t length)
|
||||
{
|
||||
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||
|
||||
if (!ctx->m_wasHeaderValue) {
|
||||
ctx->m_lastHeaderValue = std::string(at, length);
|
||||
ctx->m_wasHeaderValue = true;
|
||||
} else {
|
||||
ctx->m_lastHeaderValue += std::string(at, length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::attach(http_parser_settings *settings)
|
||||
{
|
||||
settings->on_message_begin = nullptr;
|
||||
settings->on_status = nullptr;
|
||||
settings->on_chunk_header = nullptr;
|
||||
settings->on_chunk_complete = nullptr;
|
||||
|
||||
settings->on_url = [](http_parser *parser, const char *at, size_t length) -> int
|
||||
{
|
||||
static_cast<HttpContext*>(parser->data)->url = std::string(at, length);
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_header_field = onHeaderField;
|
||||
settings->on_header_value = onHeaderValue;
|
||||
|
||||
settings->on_headers_complete = [](http_parser* parser) -> int {
|
||||
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||
ctx->status = parser->status_code;
|
||||
|
||||
if (parser->type == HTTP_REQUEST) {
|
||||
ctx->method = parser->method;
|
||||
}
|
||||
|
||||
if (!ctx->m_lastHeaderField.empty()) {
|
||||
ctx->setHeader();
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_body = [](http_parser *parser, const char *at, size_t len) -> int
|
||||
{
|
||||
static_cast<HttpContext*>(parser->data)->body += std::string(at, len);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
settings->on_message_complete = [](http_parser *parser) -> int
|
||||
{
|
||||
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||
ctx->m_listener->onHttpData(*ctx);
|
||||
ctx->m_listener = nullptr;
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::setHeader()
|
||||
{
|
||||
std::transform(m_lastHeaderField.begin(), m_lastHeaderField.end(), m_lastHeaderField.begin(), ::tolower);
|
||||
headers.insert({ m_lastHeaderField, m_lastHeaderValue });
|
||||
|
||||
m_lastHeaderField.clear();
|
||||
m_lastHeaderValue.clear();
|
||||
}
|
||||
|
||||
86
src/base/net/http/HttpContext.h
Normal file
86
src/base/net/http/HttpContext.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPCONTEXT_H
|
||||
#define XMRIG_HTTPCONTEXT_H
|
||||
|
||||
|
||||
typedef struct http_parser http_parser;
|
||||
typedef struct http_parser_settings http_parser_settings;
|
||||
typedef struct uv_connect_s uv_connect_t;
|
||||
typedef struct uv_handle_s uv_handle_t;
|
||||
typedef struct uv_stream_s uv_stream_t;
|
||||
typedef struct uv_tcp_s uv_tcp_t;
|
||||
|
||||
|
||||
#include "base/net/http/HttpData.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IHttpListener;
|
||||
|
||||
|
||||
class HttpContext : public HttpData
|
||||
{
|
||||
public:
|
||||
HttpContext(int parser_type, IHttpListener *listener);
|
||||
virtual ~HttpContext();
|
||||
|
||||
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_tcp); }
|
||||
inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(m_tcp); }
|
||||
|
||||
size_t parse(const char *data, size_t size);
|
||||
std::string ip() const;
|
||||
void close(int status = 0);
|
||||
|
||||
static HttpContext *get(uint64_t id);
|
||||
static void closeAll();
|
||||
|
||||
protected:
|
||||
uv_tcp_t *m_tcp;
|
||||
|
||||
private:
|
||||
static int onHeaderField(http_parser *parser, const char *at, size_t length);
|
||||
static int onHeaderValue(http_parser *parser, const char *at, size_t length);
|
||||
static void attach(http_parser_settings *settings);
|
||||
|
||||
void setHeader();
|
||||
|
||||
bool m_wasHeaderValue;
|
||||
http_parser *m_parser;
|
||||
IHttpListener *m_listener;
|
||||
std::string m_lastHeaderField;
|
||||
std::string m_lastHeaderValue;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPCONTEXT_H
|
||||
|
||||
60
src/base/net/http/HttpData.h
Normal file
60
src/base/net/http/HttpData.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPDATA_H
|
||||
#define XMRIG_HTTPDATA_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpData
|
||||
{
|
||||
public:
|
||||
inline HttpData(uint64_t id) : method(0), status(0), m_id(id) {}
|
||||
|
||||
inline uint64_t id() const { return m_id; }
|
||||
|
||||
int method;
|
||||
int status;
|
||||
std::map<const std::string, const std::string> headers;
|
||||
std::string body;
|
||||
std::string url;
|
||||
|
||||
private:
|
||||
const uint64_t m_id;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPDATA_H
|
||||
|
||||
153
src/base/net/http/HttpResponse.cpp
Normal file
153
src/base/net/http/HttpResponse.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/http/HttpContext.h"
|
||||
#include "base/net/http/HttpResponse.h"
|
||||
#include "base/tools/Baton.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kCRLF = "\r\n";
|
||||
static const char *kUserAgent = "user-agent";
|
||||
|
||||
|
||||
class WriteBaton : public Baton<uv_write_t>
|
||||
{
|
||||
public:
|
||||
inline WriteBaton(const std::stringstream &ss, const char *data, size_t size, HttpContext *ctx) :
|
||||
m_ctx(ctx),
|
||||
m_header(ss.str())
|
||||
{
|
||||
bufs[0].len = m_header.size();
|
||||
bufs[0].base = const_cast<char *>(m_header.c_str());
|
||||
|
||||
if (data) {
|
||||
bufs[1].len = size;
|
||||
bufs[1].base = new char[size];
|
||||
memcpy(bufs[1].base, data, size);
|
||||
}
|
||||
else {
|
||||
bufs[1].base = nullptr;
|
||||
bufs[1].len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline ~WriteBaton()
|
||||
{
|
||||
if (count() == 2) {
|
||||
delete [] bufs[1].base;
|
||||
}
|
||||
|
||||
m_ctx->close();
|
||||
}
|
||||
|
||||
|
||||
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
|
||||
inline size_t size() const { return bufs[0].len + bufs[1].len; }
|
||||
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<WriteBaton *>(req->data); }
|
||||
|
||||
|
||||
uv_buf_t bufs[2];
|
||||
|
||||
private:
|
||||
HttpContext *m_ctx;
|
||||
std::string m_header;
|
||||
};
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpResponse::HttpResponse(uint64_t id, int statusCode) :
|
||||
m_id(id),
|
||||
m_statusCode(statusCode)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpResponse::isAlive() const
|
||||
{
|
||||
HttpContext *ctx = HttpContext::get(m_id);
|
||||
|
||||
return ctx && uv_is_writable(ctx->stream());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpResponse::end(const char *data, size_t size)
|
||||
{
|
||||
if (!isAlive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data && !size) {
|
||||
size = strlen(data);
|
||||
}
|
||||
|
||||
if (size) {
|
||||
setHeader("Content-Length", std::to_string(size));
|
||||
}
|
||||
|
||||
setHeader("Connection", "close");
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "HTTP/1.1 " << statusCode() << " " << http_status_str(static_cast<http_status>(statusCode())) << kCRLF;
|
||||
|
||||
for (auto &header : m_headers) {
|
||||
ss << header.first << ": " << header.second << kCRLF;
|
||||
}
|
||||
|
||||
ss << kCRLF;
|
||||
|
||||
HttpContext *ctx = HttpContext::get(m_id);
|
||||
WriteBaton *baton = new WriteBaton(ss, data, size, ctx);
|
||||
|
||||
# ifndef APP_DEBUG
|
||||
if (statusCode() >= 400)
|
||||
# endif
|
||||
{
|
||||
const bool err = statusCode() >= 400;
|
||||
|
||||
Log::print(err ? Log::ERR : Log::INFO, CYAN("%s ") CLEAR MAGENTA_BOLD("%s") WHITE_BOLD(" %s ") CSI "1;%dm%d " CLEAR WHITE_BOLD("%zu ") BLACK_BOLD("\"%s\""),
|
||||
ctx->ip().c_str(),
|
||||
http_method_str(static_cast<http_method>(ctx->method)),
|
||||
ctx->url.c_str(),
|
||||
err ? 31 : 32,
|
||||
statusCode(),
|
||||
baton->size(),
|
||||
ctx->headers.count(kUserAgent) ? ctx->headers.at(kUserAgent).c_str() : nullptr
|
||||
);
|
||||
}
|
||||
|
||||
uv_write(&baton->req, ctx->stream(), baton->bufs, baton->count(), WriteBaton::onWrite);
|
||||
}
|
||||
61
src/base/net/http/HttpResponse.h
Normal file
61
src/base/net/http/HttpResponse.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPRESPONSE_H
|
||||
#define XMRIG_HTTPRESPONSE_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpResponse
|
||||
{
|
||||
public:
|
||||
HttpResponse(uint64_t id, int statusCode = 200);
|
||||
|
||||
inline int statusCode() const { return m_statusCode; }
|
||||
inline void setHeader(const std::string &key, const std::string &value) { m_headers.insert({ key, value }); }
|
||||
inline void setStatus(int code) { m_statusCode = code; }
|
||||
|
||||
bool isAlive() const;
|
||||
void end(const char *data = nullptr, size_t size = 0);
|
||||
|
||||
private:
|
||||
const uint64_t m_id;
|
||||
int m_statusCode;
|
||||
std::map<const std::string, const std::string> m_headers;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPRESPONSE_H
|
||||
|
||||
83
src/base/net/http/HttpServer.cpp
Normal file
83
src/base/net/http/HttpServer.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "base/kernel/interfaces/IHttpListener.h"
|
||||
#include "base/net/http/HttpContext.h"
|
||||
#include "base/net/http/HttpResponse.h"
|
||||
#include "base/net/http/HttpServer.h"
|
||||
|
||||
|
||||
xmrig::HttpServer::HttpServer(IHttpListener *listener) :
|
||||
m_listener(listener)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpServer::~HttpServer()
|
||||
{
|
||||
HttpContext::closeAll();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpServer::onConnection(uv_stream_t *stream, uint16_t)
|
||||
{
|
||||
HttpContext *ctx = new HttpContext(HTTP_REQUEST, m_listener);
|
||||
uv_accept(stream, ctx->stream());
|
||||
|
||||
uv_read_start(ctx->stream(),
|
||||
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
|
||||
{
|
||||
buf->base = new char[suggested_size];
|
||||
|
||||
# ifdef _WIN32
|
||||
buf->len = static_cast<unsigned int>(suggested_size);
|
||||
# else
|
||||
buf->len = suggested_size;
|
||||
# endif
|
||||
},
|
||||
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
HttpContext *ctx = static_cast<HttpContext*>(tcp->data);
|
||||
|
||||
if (nread >= 0) {
|
||||
const size_t size = static_cast<size_t>(nread);
|
||||
const size_t parsed = ctx->parse(buf->base, size);
|
||||
|
||||
if (parsed < size) {
|
||||
ctx->close();
|
||||
}
|
||||
} else {
|
||||
ctx->close();
|
||||
}
|
||||
|
||||
delete [] buf->base;
|
||||
});
|
||||
}
|
||||
62
src/base/net/http/HttpServer.h
Normal file
62
src/base/net/http/HttpServer.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPSERVER_H
|
||||
#define XMRIG_HTTPSERVER_H
|
||||
|
||||
|
||||
typedef struct http_parser http_parser;
|
||||
typedef struct http_parser_settings http_parser_settings;
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ITcpServerListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IHttpListener;
|
||||
|
||||
|
||||
class HttpServer : public ITcpServerListener
|
||||
{
|
||||
public:
|
||||
HttpServer(IHttpListener *listener);
|
||||
~HttpServer() override;
|
||||
|
||||
protected:
|
||||
void onConnection(uv_stream_t *stream, uint16_t port) override;
|
||||
|
||||
private:
|
||||
IHttpListener *m_listener;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPSERVER_H
|
||||
|
||||
208
src/base/net/http/HttpsClient.cpp
Normal file
208
src/base/net/http/HttpsClient.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/http/HttpsClient.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint) :
|
||||
HttpClient(method, url, listener, data, size),
|
||||
m_ready(false),
|
||||
m_buf(),
|
||||
m_ssl(nullptr),
|
||||
m_fp(fingerprint)
|
||||
{
|
||||
m_ctx = SSL_CTX_new(SSLv23_method());
|
||||
assert(m_ctx != nullptr);
|
||||
|
||||
if (!m_ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_writeBio = BIO_new(BIO_s_mem());
|
||||
m_readBio = BIO_new(BIO_s_mem());
|
||||
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpsClient::~HttpsClient()
|
||||
{
|
||||
if (m_ctx) {
|
||||
SSL_CTX_free(m_ctx);
|
||||
}
|
||||
|
||||
if (m_ssl) {
|
||||
SSL_free(m_ssl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::HttpsClient::fingerprint() const
|
||||
{
|
||||
return m_ready ? m_fingerprint : nullptr;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::HttpsClient::version() const
|
||||
{
|
||||
return m_ready ? SSL_get_version(m_ssl) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::handshake()
|
||||
{
|
||||
m_ssl = SSL_new(m_ctx);
|
||||
assert(m_ssl != nullptr);
|
||||
|
||||
if (!m_ssl) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSL_set_connect_state(m_ssl);
|
||||
SSL_set_bio(m_ssl, m_readBio, m_writeBio);
|
||||
SSL_set_tlsext_host_name(m_ssl, host().data());
|
||||
|
||||
SSL_do_handshake(m_ssl);
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::read(const char *data, size_t size)
|
||||
{
|
||||
BIO_write(m_readBio, data, size);
|
||||
|
||||
if (!SSL_is_init_finished(m_ssl)) {
|
||||
const int rc = SSL_connect(m_ssl);
|
||||
|
||||
if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
|
||||
flush();
|
||||
} else if (rc == 1) {
|
||||
X509 *cert = SSL_get_peer_certificate(m_ssl);
|
||||
if (!verify(cert)) {
|
||||
X509_free(cert);
|
||||
return close(UV_EPROTO);
|
||||
}
|
||||
|
||||
X509_free(cert);
|
||||
m_ready = true;
|
||||
|
||||
HttpClient::handshake();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int bytes_read = 0;
|
||||
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
|
||||
HttpClient::read(m_buf, static_cast<size_t>(bytes_read));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::write(const std::string &header)
|
||||
{
|
||||
SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
|
||||
body.clear();
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpsClient::verify(X509 *cert)
|
||||
{
|
||||
if (cert == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!verifyFingerprint(cert)) {
|
||||
if (!m_quiet) {
|
||||
LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port());
|
||||
|
||||
if (strlen(m_fingerprint) == 64 && !m_fp.isNull()) {
|
||||
LOG_ERR("\"%s\" was given", m_fingerprint);
|
||||
LOG_ERR("\"%s\" was configured", m_fp.data());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
|
||||
{
|
||||
const EVP_MD *digest = EVP_get_digestbyname("sha256");
|
||||
if (digest == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int dlen;
|
||||
|
||||
if (X509_digest(cert, digest, md, &dlen) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Buffer::toHex(md, 32, m_fingerprint);
|
||||
|
||||
return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpsClient::flush()
|
||||
{
|
||||
uv_buf_t buf;
|
||||
buf.len = BIO_get_mem_data(m_writeBio, &buf.base);
|
||||
|
||||
if (buf.len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
if (uv_is_writable(stream())) {
|
||||
result = uv_try_write(stream(), &buf, 1) == static_cast<int>(buf.len);
|
||||
|
||||
if (!result) {
|
||||
close(UV_EIO);
|
||||
}
|
||||
}
|
||||
|
||||
(void) BIO_reset(m_writeBio);
|
||||
}
|
||||
77
src/base/net/http/HttpsClient.h
Normal file
77
src/base/net/http/HttpsClient.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_HTTPSCLIENT_H
|
||||
#define XMRIG_HTTPSCLIENT_H
|
||||
|
||||
|
||||
typedef struct bio_st BIO;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct x509_st X509;
|
||||
|
||||
|
||||
#include "base/net/http/HttpClient.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpsClient : public HttpClient
|
||||
{
|
||||
public:
|
||||
HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint);
|
||||
~HttpsClient() override;
|
||||
|
||||
const char *fingerprint() const;
|
||||
const char *version() const;
|
||||
|
||||
protected:
|
||||
void handshake() override;
|
||||
void read(const char *data, size_t size) override;
|
||||
void write(const std::string &header) override;
|
||||
|
||||
private:
|
||||
bool verify(X509 *cert);
|
||||
bool verifyFingerprint(X509 *cert);
|
||||
void flush();
|
||||
|
||||
BIO *m_readBio;
|
||||
BIO *m_writeBio;
|
||||
bool m_ready;
|
||||
char m_buf[1024 * 2];
|
||||
char m_fingerprint[32 * 2 + 8];
|
||||
SSL *m_ssl;
|
||||
SSL_CTX *m_ctx;
|
||||
String m_fp;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPSCLIENT_H
|
||||
62
src/base/net/stratum/BaseClient.cpp
Normal file
62
src/base/net/stratum/BaseClient.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "base/net/stratum/BaseClient.h"
|
||||
#include "base/net/stratum/SubmitResult.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
int64_t BaseClient::m_sequence = 1;
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
xmrig::BaseClient::BaseClient(int id, IClientListener *listener) :
|
||||
m_quiet(false),
|
||||
m_listener(listener),
|
||||
m_id(id),
|
||||
m_retries(5),
|
||||
m_failures(0),
|
||||
m_state(UnconnectedState),
|
||||
m_retryPause(5000)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::BaseClient::handleSubmitResponse(int64_t id, const char *error)
|
||||
{
|
||||
auto it = m_results.find(id);
|
||||
if (it != m_results.end()) {
|
||||
it->second.done();
|
||||
m_listener->onResultAccepted(this, it->second, error);
|
||||
m_results.erase(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
96
src/base/net/stratum/BaseClient.h
Normal file
96
src/base/net/stratum/BaseClient.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_BASECLIENT_H
|
||||
#define XMRIG_BASECLIENT_H
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IClient.h"
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IClientListener;
|
||||
class SubmitResult;
|
||||
|
||||
|
||||
class BaseClient : public IClient
|
||||
{
|
||||
public:
|
||||
BaseClient(int id, IClientListener *listener);
|
||||
|
||||
inline bool isEnabled() const override { return m_enabled; }
|
||||
inline const Job &job() const override { return m_job; }
|
||||
inline const Pool &pool() const override { return m_pool; }
|
||||
inline const String &ip() const override { return m_ip; }
|
||||
inline int id() const override { return m_id; }
|
||||
inline void setAlgo(const Algorithm &algo) override { m_pool.setAlgo(algo); }
|
||||
inline void setEnabled(bool enabled) override { m_enabled = enabled; }
|
||||
inline void setPool(const Pool &pool) override { if (pool.isValid()) { m_pool = pool; } }
|
||||
inline void setQuiet(bool quiet) override { m_quiet = quiet; }
|
||||
inline void setRetries(int retries) override { m_retries = retries; }
|
||||
inline void setRetryPause(uint64_t ms) override { m_retryPause = ms; }
|
||||
|
||||
protected:
|
||||
enum SocketState {
|
||||
UnconnectedState,
|
||||
HostLookupState,
|
||||
ConnectingState,
|
||||
ConnectedState,
|
||||
ClosingState
|
||||
};
|
||||
|
||||
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
|
||||
|
||||
bool handleSubmitResponse(int64_t id, const char *error = nullptr);
|
||||
|
||||
bool m_quiet;
|
||||
IClientListener *m_listener;
|
||||
int m_id;
|
||||
int m_retries;
|
||||
int64_t m_failures;
|
||||
Job m_job;
|
||||
Pool m_pool;
|
||||
SocketState m_state;
|
||||
std::map<int64_t, SubmitResult> m_results;
|
||||
String m_ip;
|
||||
uint64_t m_retryPause;
|
||||
|
||||
static int64_t m_sequence;
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_BASECLIENT_H */
|
||||
956
src/base/net/stratum/Client.cpp
Normal file
956
src/base/net/stratum/Client.cpp
Normal file
@@ -0,0 +1,956 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <iterator>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
# include "base/net/stratum/Tls.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/io/json/JsonRequest.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "base/net/dns/Dns.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "core/Config.h" // for pconfig to access pconfig->get_algo_perf
|
||||
#include "workers/Workers.h" // to do Workers::switch_algo
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/writer.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
Storage<Client> Client::m_storage;
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
static const char *states[] = {
|
||||
"unconnected",
|
||||
"host-lookup",
|
||||
"connecting",
|
||||
"connected",
|
||||
"closing"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||
BaseClient(id, listener),
|
||||
m_agent(agent),
|
||||
m_tls(nullptr),
|
||||
m_expire(0),
|
||||
m_jobs(0),
|
||||
m_keepAlive(0),
|
||||
m_key(0),
|
||||
m_stream(nullptr),
|
||||
m_socket(nullptr)
|
||||
{
|
||||
m_key = m_storage.add(this);
|
||||
m_dns = new Dns(this);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Client::~Client()
|
||||
{
|
||||
delete m_dns;
|
||||
delete m_socket;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::disconnect()
|
||||
{
|
||||
m_keepAlive = 0;
|
||||
m_expire = 0;
|
||||
m_failures = -1;
|
||||
|
||||
return close();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::isTLS() const
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
return m_pool.isTLS() && m_tls;
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Client::tlsFingerprint() const
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS() && m_pool.fingerprint() == nullptr) {
|
||||
return m_tls->fingerprint();
|
||||
}
|
||||
# endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Client::tlsVersion() const
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
return m_tls->version();
|
||||
}
|
||||
# endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::Client::submit(const JobResult &result)
|
||||
{
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
if (result.clientId != m_rpcId) {
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
const char *nonce = result.nonce;
|
||||
const char *data = result.result;
|
||||
# else
|
||||
char *nonce = m_sendBuf;
|
||||
char *data = m_sendBuf + 16;
|
||||
|
||||
Buffer::toHex(reinterpret_cast<const char*>(&result.nonce), 4, nonce);
|
||||
nonce[8] = '\0';
|
||||
|
||||
Buffer::toHex(result.result, 32, data);
|
||||
data[64] = '\0';
|
||||
# endif
|
||||
|
||||
Document doc(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value params(kObjectType);
|
||||
params.AddMember("id", StringRef(m_rpcId.data()), allocator);
|
||||
params.AddMember("job_id", StringRef(result.jobId.data()), allocator);
|
||||
params.AddMember("nonce", StringRef(nonce), allocator);
|
||||
params.AddMember("result", StringRef(data), allocator);
|
||||
|
||||
if (has<EXT_ALGO>() && result.algorithm.isValid()) {
|
||||
params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator);
|
||||
}
|
||||
|
||||
JsonRequest::create(doc, m_sequence, "submit", params);
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
|
||||
# else
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||
# endif
|
||||
|
||||
return send(doc);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::connect()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_pool.isTLS()) {
|
||||
m_tls = new Tls(this);
|
||||
}
|
||||
# endif
|
||||
|
||||
resolve(m_pool.host());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::connect(const Pool &pool)
|
||||
{
|
||||
setPool(pool);
|
||||
connect();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::deleteLater()
|
||||
{
|
||||
if (!m_listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener = nullptr;
|
||||
|
||||
if (!disconnect()) {
|
||||
m_storage.remove(m_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::tick(uint64_t now)
|
||||
{
|
||||
if (m_state == ConnectedState) {
|
||||
if (m_expire && now > m_expire) {
|
||||
LOG_DEBUG_ERR("[%s] timeout", url());
|
||||
close();
|
||||
}
|
||||
else if (m_keepAlive && now > m_keepAlive) {
|
||||
ping();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_expire && now > m_expire && m_state == ConnectingState) {
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::onResolved(const Dns &dns, int status)
|
||||
{
|
||||
assert(m_listener != nullptr);
|
||||
if (!m_listener) {
|
||||
return reconnect();
|
||||
}
|
||||
|
||||
if (status < 0 && dns.isEmpty()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] DNS error: \"%s\"", url(), uv_strerror(status));
|
||||
}
|
||||
|
||||
return reconnect();
|
||||
}
|
||||
|
||||
const DnsRecord &record = dns.get();
|
||||
m_ip = record.ip();
|
||||
|
||||
connect(record.addr(m_pool.port()));
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::close()
|
||||
{
|
||||
if (m_state == ClosingState) {
|
||||
return m_socket != nullptr;
|
||||
}
|
||||
|
||||
if (m_state == UnconnectedState || m_socket == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setState(ClosingState);
|
||||
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::isCriticalError(const char *message)
|
||||
{
|
||||
if (!message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncasecmp(message, "Unauthenticated", 15) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strncasecmp(message, "your IP is banned", 17) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strncasecmp(message, "IP Address currently banned", 27) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||
{
|
||||
if (!params.IsObject()) {
|
||||
*code = 2;
|
||||
return false;
|
||||
}
|
||||
|
||||
Job job(m_id, has<EXT_NICEHASH>(), m_pool.algorithm(), m_rpcId);
|
||||
|
||||
if (!job.setId(params["job_id"].GetString())) {
|
||||
*code = 3;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!job.setBlob(params["blob"].GetString())) {
|
||||
*code = 4;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!job.setTarget(params["target"].GetString())) {
|
||||
*code = 5;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (params.HasMember("algo")) {
|
||||
job.setAlgorithm(params["algo"].GetString());
|
||||
}
|
||||
else if (params.HasMember("variant")) {
|
||||
const rapidjson::Value &variant = params["variant"];
|
||||
|
||||
if (variant.IsInt()) {
|
||||
job.setVariant(variant.GetInt());
|
||||
}
|
||||
else if (variant.IsString()){
|
||||
job.setVariant(variant.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
if (params.HasMember("seed_hash")) {
|
||||
const rapidjson::Value &variant = params["seed_hash"];
|
||||
|
||||
if (variant.IsString()) {
|
||||
job.setSeedHash(variant.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
if (params.HasMember("height")) {
|
||||
const rapidjson::Value &variant = params["height"];
|
||||
|
||||
if (variant.IsUint64()) {
|
||||
job.setHeight(variant.GetUint64());
|
||||
}
|
||||
}
|
||||
|
||||
if (!verifyAlgorithm(job.algorithm())) {
|
||||
*code = 6;
|
||||
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// retarget workers for possible new Algo profile (same algo profile is not reapplied)
|
||||
Workers::switch_algo(job.algorithm());
|
||||
|
||||
m_job.setClientId(m_rpcId);
|
||||
|
||||
if (m_job != job) {
|
||||
m_jobs++;
|
||||
m_job = std::move(job);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_jobs == 0) { // https://github.com/xmrig/xmrig/issues/459
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isQuiet()) {
|
||||
LOG_WARN("[%s] duplicate job received, reconnect", url());
|
||||
}
|
||||
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||
{
|
||||
m_rpcId = result["id"].GetString();
|
||||
if (m_rpcId.isNull()) {
|
||||
*code = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
parseExtensions(result);
|
||||
|
||||
const bool rc = parseJob(result["job"], code);
|
||||
m_jobs = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::send(BIO *bio)
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
uv_buf_t buf;
|
||||
buf.len = BIO_get_mem_data(bio, &buf.base);
|
||||
|
||||
if (buf.len == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s] TLS send (%d bytes)", url(), static_cast<int>(buf.len));
|
||||
|
||||
bool result = false;
|
||||
if (state() == ConnectedState && uv_is_writable(m_stream)) {
|
||||
result = uv_try_write(m_stream, &buf, 1) > 0;
|
||||
|
||||
if (!result) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", url(), m_state);
|
||||
}
|
||||
|
||||
(void) BIO_reset(bio);
|
||||
|
||||
return result;
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm) const
|
||||
{
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
if (m_pool.algorithm().variant() == VARIANT_AUTO || m_id == -1) {
|
||||
return true;
|
||||
}
|
||||
# endif
|
||||
|
||||
if (m_pool.isCompatible(algorithm)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isQuiet()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (algorithm.isValid()) {
|
||||
LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name());
|
||||
}
|
||||
else {
|
||||
LOG_ERR("Unknown/unsupported algorithm detected, reconnect");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Client::resolve(const String &host)
|
||||
{
|
||||
setState(HostLookupState);
|
||||
|
||||
m_expire = 0;
|
||||
m_recvBuf.reset();
|
||||
|
||||
if (m_failures == -1) {
|
||||
m_failures = 0;
|
||||
}
|
||||
|
||||
if (!m_dns->resolve(host)) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host.data(), m_pool.port(), uv_strerror(m_dns->status()));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::Client::send(const rapidjson::Document &doc)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
StringBuffer buffer(nullptr, 512);
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
doc.Accept(writer);
|
||||
|
||||
const size_t size = buffer.GetSize();
|
||||
if (size > (sizeof(m_sendBuf) - 2)) {
|
||||
LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", url(), size, (sizeof(m_sendBuf) - 2));
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(m_sendBuf, buffer.GetString(), size);
|
||||
m_sendBuf[size] = '\n';
|
||||
m_sendBuf[size + 1] = '\0';
|
||||
|
||||
return send(size + 1);
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::Client::send(size_t size)
|
||||
{
|
||||
LOG_DEBUG("[%s] send (%d bytes): \"%.*s\"", url(), size, static_cast<int>(size) - 1, m_sendBuf);
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
if (!m_tls->send(m_sendBuf, size)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
if (state() != ConnectedState || !uv_is_writable(m_stream)) {
|
||||
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", url(), m_state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
|
||||
|
||||
if (uv_try_write(m_stream, &buf, 1) < 0) {
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
m_expire = Chrono::steadyMSecs() + kResponseTimeout;
|
||||
return m_sequence++;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::connect(sockaddr *addr)
|
||||
{
|
||||
setState(ConnectingState);
|
||||
|
||||
uv_connect_t *req = new uv_connect_t;
|
||||
req->data = m_storage.ptr(m_key);
|
||||
|
||||
m_socket = new uv_tcp_t;
|
||||
m_socket->data = m_storage.ptr(m_key);
|
||||
|
||||
uv_tcp_init(uv_default_loop(), m_socket);
|
||||
uv_tcp_nodelay(m_socket, 1);
|
||||
|
||||
# ifndef WIN32
|
||||
uv_tcp_keepalive(m_socket, 1, 60);
|
||||
# endif
|
||||
|
||||
uv_tcp_connect(req, m_socket, addr, onConnect);
|
||||
|
||||
delete addr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::handshake()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
m_expire = Chrono::steadyMSecs() + kResponseTimeout;
|
||||
|
||||
m_tls->handshake();
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
login();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::login()
|
||||
{
|
||||
using namespace rapidjson;
|
||||
m_results.clear();
|
||||
|
||||
Document doc(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value params(kObjectType);
|
||||
params.AddMember("login", m_pool.user().toJSON(), allocator);
|
||||
params.AddMember("pass", m_pool.password().toJSON(), allocator);
|
||||
params.AddMember("agent", StringRef(m_agent), allocator);
|
||||
|
||||
if (!m_pool.rigId().isNull()) {
|
||||
params.AddMember("rigid", m_pool.rigId().toJSON(), allocator);
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
if (m_pool.algorithm().variant() != xmrig::VARIANT_AUTO)
|
||||
# endif
|
||||
{
|
||||
Value algo(kArrayType);
|
||||
|
||||
for (const auto &a : m_pool.algorithms()) {
|
||||
algo.PushBack(StringRef(a.shortName()), allocator);
|
||||
}
|
||||
|
||||
params.AddMember("algo", algo, allocator);
|
||||
|
||||
// addding algo-perf based on pconfig->get_algo_perf
|
||||
Value algo_perf(kObjectType);
|
||||
for (int a = 0; a != xmrig::PerfAlgo::PA_MAX; ++ a) {
|
||||
const xmrig::PerfAlgo pa = static_cast<xmrig::PerfAlgo>(a);
|
||||
Value key(xmrig::Algorithm::perfAlgoName(pa), allocator);
|
||||
algo_perf.AddMember(key, Value(xmrig::pconfig->get_algo_perf(pa)), allocator);
|
||||
}
|
||||
|
||||
params.AddMember("algo-perf", algo_perf, allocator);
|
||||
}
|
||||
|
||||
m_listener->onLogin(this, doc, params);
|
||||
|
||||
JsonRequest::create(doc, 1, "login", params);
|
||||
|
||||
send(doc);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::onClose()
|
||||
{
|
||||
delete m_socket;
|
||||
|
||||
m_stream = nullptr;
|
||||
m_socket = nullptr;
|
||||
setState(UnconnectedState);
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_tls) {
|
||||
delete m_tls;
|
||||
m_tls = nullptr;
|
||||
}
|
||||
# endif
|
||||
|
||||
reconnect();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::parse(char *line, size_t len)
|
||||
{
|
||||
startTimeout();
|
||||
|
||||
LOG_DEBUG("[%s] received (%d bytes): \"%.*s\"", url(), len, static_cast<int>(len), line);
|
||||
|
||||
if (len < 32 || line[0] != '{') {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] JSON decode failed", url());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rapidjson::Document doc;
|
||||
if (doc.ParseInsitu(line).HasParseError()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] JSON decode failed: \"%s\"", url(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!doc.IsObject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rapidjson::Value &id = doc["id"];
|
||||
if (id.IsInt64()) {
|
||||
parseResponse(id.GetInt64(), doc["result"], doc["error"]);
|
||||
}
|
||||
else {
|
||||
parseNotification(doc["method"].GetString(), doc["params"], doc["error"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::parseExtensions(const rapidjson::Value &result)
|
||||
{
|
||||
m_extensions.reset();
|
||||
|
||||
if (!result.HasMember("extensions")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rapidjson::Value &extensions = result["extensions"];
|
||||
if (!extensions.IsArray()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const rapidjson::Value &ext : extensions.GetArray()) {
|
||||
if (!ext.IsString()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *name = ext.GetString();
|
||||
|
||||
if (strcmp(name, "algo") == 0) {
|
||||
setExtension(EXT_ALGO, true);
|
||||
}
|
||||
else if (strcmp(name, "nicehash") == 0) {
|
||||
setExtension(EXT_NICEHASH, true);
|
||||
}
|
||||
else if (strcmp(name, "connect") == 0) {
|
||||
setExtension(EXT_CONNECT, true);
|
||||
}
|
||||
else if (strcmp(name, "keepalive") == 0) {
|
||||
setExtension(EXT_KEEPALIVE, true);
|
||||
}
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
else if (strcmp(name, "tls") == 0) {
|
||||
setExtension(EXT_TLS, true);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error)
|
||||
{
|
||||
if (error.IsObject()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] error: \"%s\", code: %d", url(), error["message"].GetString(), error["code"].GetInt());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!method) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(method, "job") == 0) {
|
||||
int code = -1;
|
||||
if (parseJob(params, &code)) {
|
||||
m_listener->onJobReceived(this, m_job, params);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_WARN("[%s] unsupported method: \"%s\"", url(), method);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
|
||||
{
|
||||
if (error.IsObject()) {
|
||||
const char *message = error["message"].GetString();
|
||||
|
||||
if (!handleSubmitResponse(id, message) && !isQuiet()) {
|
||||
LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", url(), message, error["code"].GetInt());
|
||||
}
|
||||
|
||||
if (isCriticalError(message)) {
|
||||
close();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result.IsObject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == 1) {
|
||||
int code = -1;
|
||||
if (!parseLogin(result, &code)) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] login error code: %d", url(), code);
|
||||
}
|
||||
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
m_failures = 0;
|
||||
m_listener->onLoginSuccess(this);
|
||||
m_listener->onJobReceived(this, m_job, result["job"]);
|
||||
return;
|
||||
}
|
||||
|
||||
handleSubmitResponse(id);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::ping()
|
||||
{
|
||||
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId.data()));
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::read(ssize_t nread)
|
||||
{
|
||||
const size_t size = static_cast<size_t>(nread);
|
||||
|
||||
if (nread > 0 && size > m_recvBuf.available()) {
|
||||
nread = UV_ENOBUFS;
|
||||
}
|
||||
|
||||
if (nread < 0) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] read error: \"%s\"", url(), uv_strerror(static_cast<int>(nread)));
|
||||
}
|
||||
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_listener != nullptr);
|
||||
if (!m_listener) {
|
||||
return reconnect();
|
||||
}
|
||||
|
||||
m_recvBuf.nread(size);
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
LOG_DEBUG("[%s] TLS received (%d bytes)", url(), static_cast<int>(nread));
|
||||
|
||||
m_tls->read(m_recvBuf.base(), m_recvBuf.pos());
|
||||
m_recvBuf.reset();
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
m_recvBuf.getline(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::reconnect()
|
||||
{
|
||||
if (!m_listener) {
|
||||
m_storage.remove(m_key);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_keepAlive = 0;
|
||||
|
||||
if (m_failures == -1) {
|
||||
return m_listener->onClose(this, -1);
|
||||
}
|
||||
|
||||
setState(ConnectingState);
|
||||
|
||||
m_failures++;
|
||||
m_listener->onClose(this, static_cast<int>(m_failures));
|
||||
|
||||
m_expire = Chrono::steadyMSecs() + m_retryPause;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::setState(SocketState state)
|
||||
{
|
||||
LOG_DEBUG("[%s] state: \"%s\"", url(), states[state]);
|
||||
|
||||
if (m_state == state) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::startTimeout()
|
||||
{
|
||||
m_expire = 0;
|
||||
|
||||
if (has<EXT_KEEPALIVE>()) {
|
||||
const uint64_t ms = static_cast<uint64_t>(m_pool.keepAlive() > 0 ? m_pool.keepAlive() : Pool::kKeepAliveTimeout) * 1000;
|
||||
|
||||
m_keepAlive = Chrono::steadyMSecs() + ms;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
|
||||
{
|
||||
auto client = getClient(handle->data);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf->base = client->m_recvBuf.current();
|
||||
|
||||
# ifdef _WIN32
|
||||
buf->len = static_cast<ULONG>(client->m_recvBuf.available());
|
||||
# else
|
||||
buf->len = client->m_recvBuf.available();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::onClose(uv_handle_t *handle)
|
||||
{
|
||||
auto client = getClient(handle->data);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
client->onClose();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::onConnect(uv_connect_t *req, int status)
|
||||
{
|
||||
auto client = getClient(req->data);
|
||||
if (!client) {
|
||||
delete req;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
if (!client->isQuiet()) {
|
||||
LOG_ERR("[%s] connect error: \"%s\"", client->url(), uv_strerror(status));
|
||||
}
|
||||
|
||||
delete req;
|
||||
client->close();
|
||||
return;
|
||||
}
|
||||
|
||||
client->m_stream = static_cast<uv_stream_t*>(req->handle);
|
||||
client->m_stream->data = req->data;
|
||||
client->setState(ConnectedState);
|
||||
|
||||
uv_read_start(client->m_stream, onAllocBuffer, onRead);
|
||||
delete req;
|
||||
|
||||
client->handshake();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *)
|
||||
{
|
||||
auto client = getClient(stream->data);
|
||||
if (client) {
|
||||
client->read(nread);
|
||||
}
|
||||
}
|
||||
151
src/base/net/stratum/Client.h
Normal file
151
src/base/net/stratum/Client.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CLIENT_H
|
||||
#define XMRIG_CLIENT_H
|
||||
|
||||
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IDnsListener.h"
|
||||
#include "base/kernel/interfaces/ILineListener.h"
|
||||
#include "base/net/stratum/BaseClient.h"
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
#include "base/net/stratum/SubmitResult.h"
|
||||
#include "base/net/tools/RecvBuf.h"
|
||||
#include "base/net/tools/Storage.h"
|
||||
#include "common/crypto/Algorithm.h"
|
||||
|
||||
|
||||
typedef struct bio_st BIO;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IClientListener;
|
||||
class JobResult;
|
||||
|
||||
|
||||
class Client : public BaseClient, public IDnsListener, public ILineListener
|
||||
{
|
||||
public:
|
||||
constexpr static int kResponseTimeout = 20 * 1000;
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
constexpr static int kInputBufferSize = 1024 * 16;
|
||||
# else
|
||||
constexpr static int kInputBufferSize = 1024 * 2;
|
||||
# endif
|
||||
|
||||
Client(int id, const char *agent, IClientListener *listener);
|
||||
~Client() override;
|
||||
|
||||
protected:
|
||||
bool disconnect() override;
|
||||
bool isTLS() const override;
|
||||
const char *tlsFingerprint() const override;
|
||||
const char *tlsVersion() const override;
|
||||
int64_t submit(const JobResult &result) override;
|
||||
void connect() override;
|
||||
void connect(const Pool &pool) override;
|
||||
void deleteLater() override;
|
||||
void tick(uint64_t now) override;
|
||||
|
||||
void onResolved(const Dns &dns, int status) override;
|
||||
|
||||
inline bool hasExtension(Extension extension) const noexcept override { return m_extensions.test(extension); }
|
||||
inline const char *mode() const override { return "pool"; }
|
||||
inline void onLine(char *line, size_t size) override { parse(line, size); }
|
||||
|
||||
private:
|
||||
class Tls;
|
||||
|
||||
bool close();
|
||||
bool isCriticalError(const char *message);
|
||||
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
||||
bool parseLogin(const rapidjson::Value &result, int *code);
|
||||
bool send(BIO *bio);
|
||||
bool verifyAlgorithm(const Algorithm &algorithm) const;
|
||||
int resolve(const String &host);
|
||||
int64_t send(const rapidjson::Document &doc);
|
||||
int64_t send(size_t size);
|
||||
void connect(sockaddr *addr);
|
||||
void handshake();
|
||||
void login();
|
||||
void onClose();
|
||||
void parse(char *line, size_t len);
|
||||
void parseExtensions(const rapidjson::Value &result);
|
||||
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error);
|
||||
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||
void ping();
|
||||
void read(ssize_t nread);
|
||||
void reconnect();
|
||||
void setState(SocketState state);
|
||||
void startTimeout();
|
||||
|
||||
inline const char *url() const { return m_pool.url(); }
|
||||
inline SocketState state() const { return m_state; }
|
||||
inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
|
||||
template<Extension ext> inline bool has() const noexcept { return m_extensions.test(ext); }
|
||||
|
||||
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||
static void onClose(uv_handle_t *handle);
|
||||
static void onConnect(uv_connect_t *req, int status);
|
||||
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
|
||||
|
||||
static inline Client *getClient(void *data) { return m_storage.get(data); }
|
||||
|
||||
char m_sendBuf[2048];
|
||||
const char *m_agent;
|
||||
Dns *m_dns;
|
||||
RecvBuf<kInputBufferSize> m_recvBuf;
|
||||
std::bitset<EXT_MAX> m_extensions;
|
||||
String m_rpcId;
|
||||
Tls *m_tls;
|
||||
uint64_t m_expire;
|
||||
uint64_t m_jobs;
|
||||
uint64_t m_keepAlive;
|
||||
uintptr_t m_key;
|
||||
uv_stream_t *m_stream;
|
||||
uv_tcp_t *m_socket;
|
||||
|
||||
static Storage<Client> m_storage;
|
||||
};
|
||||
|
||||
|
||||
template<> inline bool Client::has<Client::EXT_NICEHASH>() const noexcept { return m_extensions.test(EXT_NICEHASH) || m_pool.isNicehash(); }
|
||||
template<> inline bool Client::has<Client::EXT_KEEPALIVE>() const noexcept { return m_extensions.test(EXT_KEEPALIVE) || m_pool.keepAlive() > 0; }
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CLIENT_H */
|
||||
380
src/base/net/stratum/DaemonClient.cpp
Normal file
380
src/base/net/stratum/DaemonClient.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/json/JsonRequest.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "base/net/http/HttpClient.h"
|
||||
#include "base/net/stratum/DaemonClient.h"
|
||||
#include "base/net/stratum/SubmitResult.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "base/tools/Timer.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/writer.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include "base/net/http/HttpsClient.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kBlocktemplateBlob = "blocktemplate_blob";
|
||||
static const char *kGetHeight = "/getheight";
|
||||
static const char *kGetInfo = "/getinfo";
|
||||
static const char *kHash = "hash";
|
||||
static const char *kHeight = "height";
|
||||
static const char *kJsonRPC = "/json_rpc";
|
||||
|
||||
}
|
||||
|
||||
|
||||
xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) :
|
||||
BaseClient(id, listener),
|
||||
m_monero(true)
|
||||
{
|
||||
m_timer = new Timer(this);
|
||||
}
|
||||
|
||||
|
||||
xmrig::DaemonClient::~DaemonClient()
|
||||
{
|
||||
delete m_timer;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::disconnect()
|
||||
{
|
||||
if (m_state != UnconnectedState) {
|
||||
setState(UnconnectedState);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::isTLS() const
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
return m_pool.isTLS();
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::DaemonClient::submit(const JobResult &result)
|
||||
{
|
||||
if (result.jobId != (m_blocktemplate.data() + m_blocktemplate.size() - 32)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
memcpy(m_blocktemplate.data() + 78, result.nonce, 8);
|
||||
# else
|
||||
Buffer::toHex(reinterpret_cast<const uint8_t *>(&result.nonce), 4, m_blocktemplate.data() + 78);
|
||||
# endif
|
||||
|
||||
using namespace rapidjson;
|
||||
Document doc(kObjectType);
|
||||
|
||||
Value params(kArrayType);
|
||||
params.PushBack(m_blocktemplate.toJSON(), doc.GetAllocator());
|
||||
|
||||
JsonRequest::create(doc, m_sequence, "submitblock", params);
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
|
||||
# else
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||
# endif
|
||||
|
||||
send(HTTP_POST, kJsonRPC, doc);
|
||||
|
||||
return m_sequence++;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::connect()
|
||||
{
|
||||
setState(ConnectingState);
|
||||
getBlockTemplate();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::connect(const Pool &pool)
|
||||
{
|
||||
setPool(pool);
|
||||
connect();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::onHttpData(const HttpData &data)
|
||||
{
|
||||
if (data.status != HTTP_STATUS_OK) {
|
||||
return retry();
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s:%d] received (%d bytes): \"%.*s\"", m_pool.host().data(), m_pool.port(), static_cast<int>(data.body.size()), static_cast<int>(data.body.size()), data.body.c_str());
|
||||
|
||||
m_ip = static_cast<const HttpContext &>(data).ip().c_str();
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
m_tlsVersion = static_cast<const HttpsClient &>(data).version();
|
||||
m_tlsFingerprint = static_cast<const HttpsClient &>(data).fingerprint();
|
||||
}
|
||||
# endif
|
||||
|
||||
rapidjson::Document doc;
|
||||
if (doc.Parse(data.body.c_str()).HasParseError()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s:%d] JSON decode failed: \"%s\"", m_pool.host().data(), m_pool.port(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
|
||||
return retry();
|
||||
}
|
||||
|
||||
if (data.method == HTTP_GET) {
|
||||
if (data.url == kGetHeight) {
|
||||
if (!doc.HasMember(kHash)) {
|
||||
m_monero = false;
|
||||
|
||||
return send(HTTP_GET, kGetInfo);
|
||||
}
|
||||
|
||||
if (isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, kHash))) {
|
||||
getBlockTemplate();
|
||||
}
|
||||
}
|
||||
else if (data.url == kGetInfo && isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, "top_block_hash"))) {
|
||||
getBlockTemplate();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!parseResponse(Json::getInt64(doc, "id", -1), Json::getObject(doc, "result"), Json::getObject(doc, "error"))) {
|
||||
retry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::onTimer(const Timer *)
|
||||
{
|
||||
if (m_state == ConnectingState) {
|
||||
getBlockTemplate();
|
||||
}
|
||||
else if (m_state == ConnectedState) {
|
||||
send(HTTP_GET, m_monero ? kGetHeight : kGetInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::isOutdated(uint64_t height, const char *hash) const
|
||||
{
|
||||
return m_job.height() != height || m_prevHash != hash;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||
{
|
||||
Job job(m_id, false, m_pool.algorithm(), String());
|
||||
|
||||
String blocktemplate = Json::getString(params, kBlocktemplateBlob);
|
||||
if (blocktemplate.isNull() || !job.setBlob(Json::getString(params, "blockhashing_blob"))) {
|
||||
*code = 4;
|
||||
return false;
|
||||
}
|
||||
|
||||
job.setSeedHash(Json::getString(params, "seed_hash"));
|
||||
|
||||
job.setHeight(Json::getUint64(params, kHeight));
|
||||
job.setDiff(Json::getUint64(params, "difficulty"));
|
||||
job.setId(blocktemplate.data() + blocktemplate.size() - 32);
|
||||
|
||||
m_job = std::move(job);
|
||||
m_blocktemplate = std::move(blocktemplate);
|
||||
m_prevHash = Json::getString(params, "prev_hash");
|
||||
|
||||
if (m_state == ConnectingState) {
|
||||
setState(ConnectedState);
|
||||
}
|
||||
|
||||
m_listener->onJobReceived(this, m_job, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
|
||||
{
|
||||
if (id == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error.IsObject()) {
|
||||
const char *message = error["message"].GetString();
|
||||
|
||||
if (!handleSubmitResponse(id, message) && !isQuiet()) {
|
||||
LOG_ERR("[%s:%d] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", m_pool.host().data(), m_pool.port(), message, error["code"].GetInt());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!result.IsObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int code = -1;
|
||||
if (result.HasMember(kBlocktemplateBlob) && parseJob(result, &code)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (handleSubmitResponse(id)) {
|
||||
getBlockTemplate();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::DaemonClient::getBlockTemplate()
|
||||
{
|
||||
using namespace rapidjson;
|
||||
Document doc(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value params(kObjectType);
|
||||
params.AddMember("wallet_address", m_pool.user().toJSON(), allocator);
|
||||
params.AddMember("reserve_size", 8, allocator);
|
||||
|
||||
JsonRequest::create(doc, m_sequence, "getblocktemplate", params);
|
||||
|
||||
send(HTTP_POST, kJsonRPC, doc);
|
||||
|
||||
return m_sequence++;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::retry()
|
||||
{
|
||||
m_failures++;
|
||||
m_listener->onClose(this, static_cast<int>(m_failures));
|
||||
|
||||
if (m_failures == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_state == ConnectedState) {
|
||||
setState(ConnectingState);
|
||||
}
|
||||
|
||||
m_timer->stop();
|
||||
m_timer->start(m_retryPause, 0);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::send(int method, const char *url, const char *data, size_t size)
|
||||
{
|
||||
LOG_DEBUG("[%s:%d] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"",
|
||||
m_pool.host().data(),
|
||||
m_pool.port(),
|
||||
http_method_str(static_cast<http_method>(method)),
|
||||
url,
|
||||
size,
|
||||
static_cast<int>(size),
|
||||
data);
|
||||
|
||||
HttpClient *client;
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_pool.isTLS()) {
|
||||
client = new HttpsClient(method, url, this, data, size, m_pool.fingerprint());
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
client = new HttpClient(method, url, this, data, size);
|
||||
}
|
||||
|
||||
client->setQuiet(isQuiet());
|
||||
client->connect(m_pool.host(), m_pool.port());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::send(int method, const char *url, const rapidjson::Document &doc)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
StringBuffer buffer(nullptr, 512);
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
doc.Accept(writer);
|
||||
|
||||
send(method, url, buffer.GetString(), buffer.GetSize());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::setState(SocketState state)
|
||||
{
|
||||
assert(m_state != state);
|
||||
if (m_state == state) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
|
||||
switch (state) {
|
||||
case ConnectedState:
|
||||
{
|
||||
m_failures = 0;
|
||||
m_listener->onLoginSuccess(this);
|
||||
|
||||
const uint64_t interval = std::max<uint64_t>(20, m_pool.pollInterval());
|
||||
m_timer->start(interval, interval);
|
||||
}
|
||||
break;
|
||||
|
||||
case UnconnectedState:
|
||||
m_failures = -1;
|
||||
m_timer->stop();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
83
src/base/net/stratum/DaemonClient.h
Normal file
83
src/base/net/stratum/DaemonClient.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_DAEMONCLIENT_H
|
||||
#define XMRIG_DAEMONCLIENT_H
|
||||
|
||||
|
||||
#include "base/net/stratum/BaseClient.h"
|
||||
#include "base/kernel/interfaces/ITimerListener.h"
|
||||
#include "base/kernel/interfaces/IHttpListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class DaemonClient : public BaseClient, public ITimerListener, public IHttpListener
|
||||
{
|
||||
public:
|
||||
DaemonClient(int id, IClientListener *listener);
|
||||
~DaemonClient() override;
|
||||
|
||||
protected:
|
||||
bool disconnect() override;
|
||||
bool isTLS() const override;
|
||||
int64_t submit(const JobResult &result) override;
|
||||
void connect() override;
|
||||
void connect(const Pool &pool) override;
|
||||
|
||||
void onHttpData(const HttpData &data) override;
|
||||
void onTimer(const Timer *timer) override;
|
||||
|
||||
inline bool hasExtension(Extension) const noexcept override { return false; }
|
||||
inline const char *mode() const override { return "daemon"; }
|
||||
inline const char *tlsFingerprint() const override { return m_tlsFingerprint; }
|
||||
inline const char *tlsVersion() const override { return m_tlsVersion; }
|
||||
inline void deleteLater() override { delete this; }
|
||||
inline void tick(uint64_t) override {}
|
||||
|
||||
private:
|
||||
bool isOutdated(uint64_t height, const char *hash) const;
|
||||
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
||||
bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||
int64_t getBlockTemplate();
|
||||
void retry();
|
||||
void send(int method, const char *url, const char *data = nullptr, size_t size = 0);
|
||||
void send(int method, const char *url, const rapidjson::Document &doc);
|
||||
void setState(SocketState state);
|
||||
|
||||
bool m_monero;
|
||||
String m_blocktemplate;
|
||||
String m_prevHash;
|
||||
String m_tlsFingerprint;
|
||||
String m_tlsVersion;
|
||||
Timer *m_timer;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_DAEMONCLIENT_H */
|
||||
213
src/base/net/stratum/Job.cpp
Normal file
213
src/base/net/stratum/Job.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
|
||||
|
||||
xmrig::Job::Job() :
|
||||
m_autoVariant(false),
|
||||
m_nicehash(false),
|
||||
m_poolId(-2),
|
||||
m_threadId(-1),
|
||||
m_size(0),
|
||||
m_diff(0),
|
||||
m_height(0),
|
||||
m_target(0),
|
||||
m_seedHash(),
|
||||
m_blob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::Job::Job(int poolId, bool nicehash, const Algorithm &algorithm, const String &clientId) :
|
||||
m_algorithm(algorithm),
|
||||
m_autoVariant(algorithm.variant() == VARIANT_AUTO),
|
||||
m_nicehash(nicehash),
|
||||
m_poolId(poolId),
|
||||
m_threadId(-1),
|
||||
m_size(0),
|
||||
m_clientId(clientId),
|
||||
m_diff(0),
|
||||
m_height(0),
|
||||
m_target(0),
|
||||
m_seedHash(),
|
||||
m_blob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::Job::~Job()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Job::isEqual(const Job &other) const
|
||||
{
|
||||
return m_id == other.m_id && m_clientId == other.m_clientId && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Job::setBlob(const char *blob)
|
||||
{
|
||||
if (!blob) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_size = strlen(blob);
|
||||
if (m_size % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_size /= 2;
|
||||
if (m_size < 76 || m_size >= sizeof(m_blob)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Buffer::fromHex(blob, m_size * 2, m_blob)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*nonce() != 0 && !m_nicehash) {
|
||||
m_nicehash = true;
|
||||
}
|
||||
|
||||
if (m_autoVariant) {
|
||||
m_algorithm.setVariant(variant());
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
memset(m_rawBlob, 0, sizeof(m_rawBlob));
|
||||
memcpy(m_rawBlob, blob, m_size * 2);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// for algo benchmarking
|
||||
void xmrig::Job::setRawBlob(const uint8_t *blob, const size_t size)
|
||||
{
|
||||
memcpy(m_blob, blob, m_size = size);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Job::setTarget(const char *target)
|
||||
{
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t len = strlen(target);
|
||||
|
||||
if (len <= 8) {
|
||||
uint32_t tmp = 0;
|
||||
char str[8];
|
||||
memcpy(str, target, len);
|
||||
|
||||
if (!Buffer::fromHex(str, 8, reinterpret_cast<uint8_t *>(&tmp)) || tmp == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_target = 0xFFFFFFFFFFFFFFFFULL / (0xFFFFFFFFULL / static_cast<uint64_t>(tmp));
|
||||
}
|
||||
else if (len <= 16) {
|
||||
m_target = 0;
|
||||
char str[16];
|
||||
memcpy(str, target, len);
|
||||
|
||||
if (!Buffer::fromHex(str, 16, reinterpret_cast<uint8_t *>(&m_target)) || m_target == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
memset(m_rawTarget, 0, sizeof(m_rawTarget));
|
||||
memcpy(m_rawTarget, target, len);
|
||||
# endif
|
||||
|
||||
m_diff = toDiff(m_target);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Job::setAlgorithm(const char *algo)
|
||||
{
|
||||
m_algorithm.parseAlgorithm(algo);
|
||||
|
||||
if (m_algorithm.variant() == xmrig::VARIANT_AUTO) {
|
||||
m_algorithm.setVariant(variant());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Job::setDiff(uint64_t diff)
|
||||
{
|
||||
m_diff = diff;
|
||||
m_target = toDiff(diff);
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
Buffer::toHex(reinterpret_cast<uint8_t *>(&m_target), 8, m_rawTarget);
|
||||
m_rawTarget[16] = '\0';
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Job::setSeedHash(const char *hash)
|
||||
{
|
||||
if (!hash || (strlen(hash) != sizeof(m_seedHash) * 2))
|
||||
return false;
|
||||
|
||||
return Buffer::fromHex(hash, sizeof(m_seedHash) * 2, m_seedHash);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Variant xmrig::Job::variant() const
|
||||
{
|
||||
switch (m_algorithm.algo()) {
|
||||
case CRYPTONIGHT:
|
||||
return (m_blob[0] >= 10) ? VARIANT_4 : ((m_blob[0] >= 8) ? VARIANT_2 : VARIANT_1);
|
||||
|
||||
case CRYPTONIGHT_LITE:
|
||||
return VARIANT_1;
|
||||
|
||||
case CRYPTONIGHT_HEAVY:
|
||||
return VARIANT_0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return m_algorithm.variant();
|
||||
}
|
||||
128
src/base/net/stratum/Job.h
Normal file
128
src/base/net/stratum/Job.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_JOB_H
|
||||
#define XMRIG_JOB_H
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
#include "common/crypto/Algorithm.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Job
|
||||
{
|
||||
public:
|
||||
// Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
|
||||
// SECOR increase requirements for blob size: https://github.com/xmrig/xmrig/issues/913
|
||||
static constexpr const size_t kMaxBlobSize = 128;
|
||||
|
||||
Job();
|
||||
Job(int poolId, bool nicehash, const Algorithm &algorithm, const String &clientId);
|
||||
~Job();
|
||||
|
||||
bool isEqual(const Job &other) const;
|
||||
bool setBlob(const char *blob);
|
||||
void setRawBlob(const uint8_t *blob, const size_t size); // for algo benchmarking
|
||||
bool setTarget(const char *target);
|
||||
// for algo benchmarking to set PoW variant
|
||||
void setAlgorithm(const xmrig::Algorithm& algorithm) { m_algorithm = algorithm; }
|
||||
void setAlgorithm(const char *algo);
|
||||
void setDiff(uint64_t diff);
|
||||
bool setSeedHash(const char *hash);
|
||||
|
||||
inline bool isNicehash() const { return m_nicehash; }
|
||||
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
||||
inline bool setId(const char *id) { return m_id = id; }
|
||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const String &clientId() const { return m_clientId; }
|
||||
inline const String &id() const { return m_id; }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
|
||||
inline const uint8_t *blob() const { return m_blob; }
|
||||
inline const uint8_t *seed_hash() const { return m_seedHash; }
|
||||
inline int poolId() const { return m_poolId; }
|
||||
inline int threadId() const { return m_threadId; }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
||||
inline uint64_t diff() const { return m_diff; }
|
||||
inline uint64_t height() const { return m_height; }
|
||||
inline uint64_t target() const { return m_target; }
|
||||
inline uint8_t fixedByte() const { return *(m_blob + 42); }
|
||||
inline void reset() { m_size = 0; m_diff = 0; }
|
||||
inline void setClientId(const String &id) { m_clientId = id; }
|
||||
inline void setHeight(uint64_t height) { m_height = height; }
|
||||
inline void setPoolId(int poolId) { m_poolId = poolId; }
|
||||
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
||||
inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); }
|
||||
inline void setVariant(int variant) { m_algorithm.parseVariant(variant); }
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
inline char *rawBlob() { return m_rawBlob; }
|
||||
inline const char *rawBlob() const { return m_rawBlob; }
|
||||
inline const char *rawTarget() const { return m_rawTarget; }
|
||||
# endif
|
||||
|
||||
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
|
||||
static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; }
|
||||
|
||||
inline bool operator==(const Job &other) const { return isEqual(other); }
|
||||
inline bool operator!=(const Job &other) const { return !isEqual(other); }
|
||||
|
||||
private:
|
||||
Variant variant() const;
|
||||
|
||||
Algorithm m_algorithm;
|
||||
bool m_autoVariant;
|
||||
bool m_nicehash;
|
||||
int m_poolId;
|
||||
int m_threadId;
|
||||
size_t m_size;
|
||||
String m_clientId;
|
||||
String m_id;
|
||||
uint64_t m_diff;
|
||||
uint64_t m_height;
|
||||
uint64_t m_target;
|
||||
uint8_t m_seedHash[32];
|
||||
uint8_t m_blob[kMaxBlobSize];
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
char m_rawBlob[kMaxBlobSize * 2 + 8];
|
||||
char m_rawTarget[24];
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_JOB_H */
|
||||
@@ -6,6 +6,7 @@
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
@@ -30,34 +31,46 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/net/Pool.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
# include "common/log/Log.h"
|
||||
# include "base/io/log/Log.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp _strnicmp
|
||||
# define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kEnabled = "enabled";
|
||||
static const char *kFingerprint = "tls-fingerprint";
|
||||
static const char *kKeepalive = "keepalive";
|
||||
static const char *kNicehash = "nicehash";
|
||||
static const char *kPass = "pass";
|
||||
static const char *kRigId = "rig-id";
|
||||
static const char *kTls = "tls";
|
||||
static const char *kUrl = "url";
|
||||
static const char *kUser = "user";
|
||||
static const char *kVariant = "variant";
|
||||
static const char *kDaemon = "daemon";
|
||||
static const char *kDaemonPollInterval = "daemon-poll-interval";
|
||||
static const char *kEnabled = "enabled";
|
||||
static const char *kFingerprint = "tls-fingerprint";
|
||||
static const char *kKeepalive = "keepalive";
|
||||
static const char *kNicehash = "nicehash";
|
||||
static const char *kPass = "pass";
|
||||
static const char *kRigId = "rig-id";
|
||||
static const char *kTls = "tls";
|
||||
static const char *kUrl = "url";
|
||||
static const char *kUser = "user";
|
||||
static const char *kVariant = "variant";
|
||||
|
||||
const String Pool::kDefaultPassword = "x";
|
||||
const String Pool::kDefaultUser = "x";
|
||||
|
||||
static const char kStratumTcp[] = "stratum+tcp://";
|
||||
static const char kStratumSsl[] = "stratum+ssl://";
|
||||
|
||||
#ifdef XMRIG_FEATURE_HTTP
|
||||
static const char kDaemonHttp[] = "daemon+http://";
|
||||
static const char kDaemonHttps[] = "daemon+https://";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -79,6 +92,7 @@ xmrig::Algorithms all_algorithms() {
|
||||
algorithms.push_back(xmrig::Algorithm(xmrig::CRYPTONIGHT, xmrig::VARIANT_RWZ));
|
||||
algorithms.push_back(xmrig::Algorithm(xmrig::CRYPTONIGHT, xmrig::VARIANT_ZLS));
|
||||
algorithms.push_back(xmrig::Algorithm(xmrig::CRYPTONIGHT, xmrig::VARIANT_DOUBLE));
|
||||
algorithms.push_back(xmrig::Algorithm(xmrig::CRYPTONIGHT, xmrig::VARIANT_RX_WOW));
|
||||
|
||||
algorithms.push_back(xmrig::Algorithm(xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1));
|
||||
algorithms.push_back(xmrig::Algorithm(xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0));
|
||||
@@ -95,11 +109,10 @@ xmrig::Algorithms all_algorithms() {
|
||||
|
||||
xmrig::Pool::Pool() :
|
||||
m_algorithms(all_algorithms()),
|
||||
m_enabled(true),
|
||||
m_nicehash(false),
|
||||
m_tls(false),
|
||||
m_keepAlive(0),
|
||||
m_port(kDefaultPort)
|
||||
m_flags(0),
|
||||
m_port(kDefaultPort),
|
||||
m_pollInterval(kDefaultPollInterval)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -117,11 +130,10 @@ xmrig::Pool::Pool() :
|
||||
*/
|
||||
xmrig::Pool::Pool(const char *url) :
|
||||
m_algorithms(all_algorithms()),
|
||||
m_enabled(true),
|
||||
m_nicehash(false),
|
||||
m_tls(false),
|
||||
m_keepAlive(0),
|
||||
m_port(kDefaultPort)
|
||||
m_flags(1),
|
||||
m_port(kDefaultPort),
|
||||
m_pollInterval(kDefaultPollInterval)
|
||||
{
|
||||
parse(url);
|
||||
}
|
||||
@@ -129,22 +141,27 @@ xmrig::Pool::Pool(const char *url) :
|
||||
|
||||
xmrig::Pool::Pool(const rapidjson::Value &object) :
|
||||
m_algorithms(all_algorithms()),
|
||||
m_enabled(true),
|
||||
m_nicehash(false),
|
||||
m_tls(false),
|
||||
m_keepAlive(0),
|
||||
m_port(kDefaultPort)
|
||||
m_flags(1),
|
||||
m_port(kDefaultPort),
|
||||
m_pollInterval(kDefaultPollInterval)
|
||||
{
|
||||
if (!parse(Json::getString(object, kUrl))) {
|
||||
return;
|
||||
}
|
||||
|
||||
setUser(Json::getString(object, kUser));
|
||||
setPassword(Json::getString(object, kPass));
|
||||
setRigId(Json::getString(object, kRigId));
|
||||
setNicehash(Json::getBool(object, kNicehash));
|
||||
m_user = Json::getString(object, kUser);
|
||||
m_password = Json::getString(object, kPass);
|
||||
m_rigId = Json::getString(object, kRigId);
|
||||
m_fingerprint = Json::getString(object, kFingerprint);
|
||||
m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval);
|
||||
|
||||
const rapidjson::Value &keepalive = object[kKeepalive];
|
||||
m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true));
|
||||
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash));
|
||||
m_flags.set(FLAG_TLS, Json::getBool(object, kTls, m_flags.test(FLAG_TLS)));
|
||||
m_flags.set(FLAG_DAEMON, Json::getBool(object, kDaemon, m_flags.test(FLAG_DAEMON)));
|
||||
|
||||
const rapidjson::Value &keepalive = Json::getValue(object, kKeepalive);
|
||||
if (keepalive.IsInt()) {
|
||||
setKeepAlive(keepalive.GetInt());
|
||||
}
|
||||
@@ -152,7 +169,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
|
||||
setKeepAlive(keepalive.GetBool());
|
||||
}
|
||||
|
||||
const rapidjson::Value &variant = object[kVariant];
|
||||
const rapidjson::Value &variant = Json::getValue(object, kVariant);
|
||||
if (variant.IsString()) {
|
||||
algorithm().parseVariant(variant.GetString());
|
||||
}
|
||||
@@ -160,22 +177,18 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
|
||||
algorithm().parseVariant(variant.GetInt());
|
||||
}
|
||||
|
||||
m_enabled = Json::getBool(object, kEnabled, true);
|
||||
m_tls = Json::getBool(object, kTls);
|
||||
m_fingerprint = Json::getString(object, kFingerprint);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) :
|
||||
m_algorithms(all_algorithms()),
|
||||
m_enabled(true),
|
||||
m_nicehash(nicehash),
|
||||
m_tls(tls),
|
||||
m_keepAlive(keepAlive),
|
||||
m_flags(1),
|
||||
m_host(host),
|
||||
m_password(password),
|
||||
m_user(user),
|
||||
m_port(port)
|
||||
m_port(port),
|
||||
m_pollInterval(kDefaultPollInterval)
|
||||
{
|
||||
const size_t size = m_host.size() + 8;
|
||||
assert(size > 8);
|
||||
@@ -184,6 +197,9 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char
|
||||
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
|
||||
|
||||
m_url = url;
|
||||
|
||||
m_flags.set(FLAG_NICEHASH, nicehash);
|
||||
m_flags.set(FLAG_TLS, tls);
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +217,7 @@ bool xmrig::Pool::isCompatible(const Algorithm &algorithm) const
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
if (m_algorithm.algo() == xmrig::CRYPTONIGHT && algorithm.algo() == xmrig::CRYPTONIGHT) {
|
||||
return m_algorithm.variant() == xmrig::VARIANT_XTL || m_algorithm.variant() == xmrig::VARIANT_MSR;
|
||||
return m_algorithm.variant() == xmrig::VARIANT_RWZ || m_algorithm.variant() == xmrig::VARIANT_ZLS;
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -211,30 +227,35 @@ bool xmrig::Pool::isCompatible(const Algorithm &algorithm) const
|
||||
|
||||
bool xmrig::Pool::isEnabled() const
|
||||
{
|
||||
# ifdef XMRIG_NO_TLS
|
||||
# ifndef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
return m_enabled && isValid() && algorithm().isValid();
|
||||
# ifndef XMRIG_FEATURE_HTTP
|
||||
if (isDaemon()) {
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
return m_flags.test(FLAG_ENABLED) && isValid() && algorithm().isValid();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Pool::isEqual(const Pool &other) const
|
||||
{
|
||||
return (m_nicehash == other.m_nicehash
|
||||
&& m_enabled == other.m_enabled
|
||||
&& m_tls == other.m_tls
|
||||
&& m_keepAlive == other.m_keepAlive
|
||||
&& m_port == other.m_port
|
||||
&& m_algorithm == other.m_algorithm
|
||||
&& m_fingerprint == other.m_fingerprint
|
||||
&& m_host == other.m_host
|
||||
&& m_password == other.m_password
|
||||
&& m_rigId == other.m_rigId
|
||||
&& m_url == other.m_url
|
||||
&& m_user == other.m_user);
|
||||
return (m_flags == other.m_flags
|
||||
&& m_keepAlive == other.m_keepAlive
|
||||
&& m_port == other.m_port
|
||||
&& m_algorithm == other.m_algorithm
|
||||
&& m_fingerprint == other.m_fingerprint
|
||||
&& m_host == other.m_host
|
||||
&& m_password == other.m_password
|
||||
&& m_rigId == other.m_rigId
|
||||
&& m_url == other.m_url
|
||||
&& m_user == other.m_user
|
||||
&& m_pollInterval == other.m_pollInterval);
|
||||
}
|
||||
|
||||
|
||||
@@ -242,21 +263,33 @@ bool xmrig::Pool::parse(const char *url)
|
||||
{
|
||||
assert(url != nullptr);
|
||||
|
||||
const char *p = strstr(url, "://");
|
||||
const char *p = strstr(url, "://");
|
||||
const char *base = url;
|
||||
|
||||
if (p) {
|
||||
if (strncasecmp(url, "stratum+tcp://", 14) == 0) {
|
||||
m_tls = false;
|
||||
if (strncasecmp(url, kStratumTcp, sizeof(kStratumTcp) - 1) == 0) {
|
||||
m_flags.set(FLAG_DAEMON, false);
|
||||
m_flags.set(FLAG_TLS, false);
|
||||
}
|
||||
else if (strncasecmp(url, "stratum+ssl://", 14) == 0) {
|
||||
m_tls = true;
|
||||
else if (strncasecmp(url, kStratumSsl, sizeof(kStratumSsl) - 1) == 0) {
|
||||
m_flags.set(FLAG_DAEMON, false);
|
||||
m_flags.set(FLAG_TLS, true);
|
||||
}
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
else if (strncasecmp(url, kDaemonHttps, sizeof(kDaemonHttps) - 1) == 0) {
|
||||
m_flags.set(FLAG_DAEMON, true);
|
||||
m_flags.set(FLAG_TLS, true);
|
||||
}
|
||||
else if (strncasecmp(url, kDaemonHttp, sizeof(kDaemonHttp) - 1) == 0) {
|
||||
m_flags.set(FLAG_DAEMON, true);
|
||||
m_flags.set(FLAG_TLS, false);
|
||||
}
|
||||
# endif
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
base = url + 14;
|
||||
base = p + 3;
|
||||
}
|
||||
|
||||
if (!strlen(base) || *base == '/') {
|
||||
@@ -286,23 +319,6 @@ bool xmrig::Pool::parse(const char *url)
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Pool::setUserpass(const char *userpass)
|
||||
{
|
||||
const char *p = strchr(userpass, ':');
|
||||
if (!p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char *user = new char[p - userpass + 1]();
|
||||
strncpy(user, userpass, static_cast<size_t>(p - userpass));
|
||||
|
||||
m_user = user;
|
||||
m_password = p + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
@@ -343,9 +359,11 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
|
||||
break;
|
||||
}
|
||||
|
||||
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
||||
obj.AddMember(StringRef(kTls), isTLS(), allocator);
|
||||
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
|
||||
obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator);
|
||||
obj.AddMember(StringRef(kTls), isTLS(), allocator);
|
||||
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
|
||||
obj.AddMember(StringRef(kDaemon), m_flags.test(FLAG_DAEMON), allocator);
|
||||
obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@@ -380,7 +398,7 @@ void xmrig::Pool::print() const
|
||||
LOG_DEBUG ("pass: %s", m_password.data());
|
||||
LOG_DEBUG ("rig-id %s", m_rigId.data());
|
||||
LOG_DEBUG ("algo: %s", m_algorithm.name());
|
||||
LOG_DEBUG ("nicehash: %d", static_cast<int>(m_nicehash));
|
||||
LOG_DEBUG ("nicehash: %d", static_cast<int>(m_flags.test(FLAG_NICEHASH)));
|
||||
LOG_DEBUG ("keepAlive: %d", m_keepAlive);
|
||||
}
|
||||
#endif
|
||||
@@ -416,8 +434,8 @@ void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint)
|
||||
using namespace xmrig;
|
||||
|
||||
if (m_host.contains(".nicehash.com")) {
|
||||
m_flags.set(FLAG_NICEHASH, true);
|
||||
m_keepAlive = false;
|
||||
m_nicehash = true;
|
||||
bool valid = true;
|
||||
|
||||
switch (m_port) {
|
||||
@@ -452,7 +470,7 @@ void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint)
|
||||
m_algorithm.setAlgo(INVALID_ALGO);
|
||||
}
|
||||
|
||||
m_tls = m_port > 33000;
|
||||
m_flags.set(FLAG_TLS, m_port > 33000);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
@@ -27,6 +28,7 @@
|
||||
#define XMRIG_POOL_H
|
||||
|
||||
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -41,10 +43,20 @@ namespace xmrig {
|
||||
class Pool
|
||||
{
|
||||
public:
|
||||
constexpr static const char *kDefaultPassword = "x";
|
||||
constexpr static const char *kDefaultUser = "x";
|
||||
constexpr static uint16_t kDefaultPort = 3333;
|
||||
constexpr static int kKeepAliveTimeout = 60;
|
||||
enum Flags {
|
||||
FLAG_ENABLED,
|
||||
FLAG_NICEHASH,
|
||||
FLAG_TLS,
|
||||
FLAG_DAEMON,
|
||||
FLAG_MAX
|
||||
};
|
||||
|
||||
static const String kDefaultPassword;
|
||||
static const String kDefaultUser;
|
||||
|
||||
constexpr static int kKeepAliveTimeout = 60;
|
||||
constexpr static uint16_t kDefaultPort = 3333;
|
||||
constexpr static uint64_t kDefaultPollInterval = 1000;
|
||||
|
||||
Pool();
|
||||
Pool(const char *url);
|
||||
@@ -58,37 +70,33 @@ public:
|
||||
bool tls = false
|
||||
);
|
||||
|
||||
inline bool isNicehash() const { return m_nicehash; }
|
||||
inline bool isTLS() const { return m_tls; }
|
||||
inline Algorithm &algorithm() { return m_algorithm; }
|
||||
inline bool isDaemon() const { return m_flags.test(FLAG_DAEMON); }
|
||||
inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); }
|
||||
inline bool isTLS() const { return m_flags.test(FLAG_TLS); }
|
||||
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
|
||||
inline const char *fingerprint() const { return m_fingerprint.data(); }
|
||||
inline const char *host() const { return m_host.data(); }
|
||||
inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; }
|
||||
inline const char *rigId() const { return m_rigId.data(); }
|
||||
inline const char *url() const { return m_url.data(); }
|
||||
inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; }
|
||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const Algorithms &algorithms() const { return m_algorithms; }
|
||||
inline const String &fingerprint() const { return m_fingerprint; }
|
||||
inline const String &host() const { return m_host; }
|
||||
inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; }
|
||||
inline const String &rigId() const { return m_rigId; }
|
||||
inline const String &url() const { return m_url; }
|
||||
inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; }
|
||||
inline int keepAlive() const { return m_keepAlive; }
|
||||
inline uint16_t port() const { return m_port; }
|
||||
inline void setFingerprint(const char *fingerprint) { m_fingerprint = fingerprint; }
|
||||
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
|
||||
inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); }
|
||||
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
||||
inline void setPassword(const char *password) { m_password = password; }
|
||||
inline void setRigId(const char *rigId) { m_rigId = rigId; }
|
||||
inline void setTLS(bool tls) { m_tls = tls; }
|
||||
inline void setUser(const char *user) { m_user = user; }
|
||||
inline Algorithm &algorithm() { return m_algorithm; }
|
||||
inline uint64_t pollInterval() const { return m_pollInterval; }
|
||||
inline void setPassword(const String &password) { m_password = password; }
|
||||
inline void setRigId(const String &rigId) { m_rigId = rigId; }
|
||||
inline void setUser(const String &user) { m_user = user; }
|
||||
|
||||
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const Pool &other) const { return isEqual(other); }
|
||||
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const Pool &other) const { return isEqual(other); }
|
||||
|
||||
bool isCompatible(const Algorithm &algorithm) const;
|
||||
bool isEnabled() const;
|
||||
bool isEqual(const Pool &other) const;
|
||||
bool parse(const char *url);
|
||||
bool setUserpass(const char *userpass);
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
void adjust(const Algorithm &algorithm);
|
||||
void setAlgo(const Algorithm &algorithm);
|
||||
@@ -98,15 +106,16 @@ public:
|
||||
# endif
|
||||
|
||||
private:
|
||||
inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); }
|
||||
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
|
||||
|
||||
bool parseIPv6(const char *addr);
|
||||
void adjustVariant(const Variant variantHint);
|
||||
|
||||
Algorithm m_algorithm;
|
||||
Algorithms m_algorithms;
|
||||
bool m_enabled;
|
||||
bool m_nicehash;
|
||||
bool m_tls;
|
||||
int m_keepAlive;
|
||||
std::bitset<FLAG_MAX> m_flags;
|
||||
String m_fingerprint;
|
||||
String m_host;
|
||||
String m_password;
|
||||
@@ -114,6 +123,7 @@ private:
|
||||
String m_url;
|
||||
String m_user;
|
||||
uint16_t m_port;
|
||||
uint64_t m_pollInterval;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,16 +23,19 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "base/net/Pools.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/net/strategies/FailoverStrategy.h"
|
||||
#include "common/net/strategies/SinglePoolStrategy.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
#include "base/net/stratum/strategies/FailoverStrategy.h"
|
||||
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
|
||||
#include "donate.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
xmrig::Pools::Pools() :
|
||||
m_donateLevel(kDefaultDonateLevel),
|
||||
m_retries(5),
|
||||
m_retryPause(5)
|
||||
m_retryPause(5),
|
||||
m_proxyDonate(PROXY_DONATE_AUTO)
|
||||
{
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_retries = 2;
|
||||
@@ -41,16 +44,6 @@ xmrig::Pools::Pools() :
|
||||
}
|
||||
|
||||
|
||||
xmrig::Pool &xmrig::Pools::current()
|
||||
{
|
||||
if (m_data.empty()) {
|
||||
m_data.push_back(Pool());
|
||||
}
|
||||
|
||||
return m_data.back();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Pools::isEqual(const Pools &other) const
|
||||
{
|
||||
if (m_data.size() != other.m_data.size() || m_retries != other.m_retries || m_retryPause != other.m_retryPause) {
|
||||
@@ -61,25 +54,6 @@ bool xmrig::Pools::isEqual(const Pools &other) const
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Pools::setUrl(const char *url)
|
||||
{
|
||||
if (m_data.empty() || m_data.back().isValid()) {
|
||||
Pool pool(url);
|
||||
|
||||
if (pool.isValid()) {
|
||||
m_data.push_back(std::move(pool));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
current().parse(url);
|
||||
|
||||
return m_data.back().isValid();
|
||||
}
|
||||
|
||||
|
||||
xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) const
|
||||
{
|
||||
if (active() == 1) {
|
||||
@@ -141,6 +115,10 @@ void xmrig::Pools::load(const rapidjson::Value &pools)
|
||||
{
|
||||
m_data.clear();
|
||||
|
||||
if (!pools.IsArray()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const rapidjson::Value &value : pools.GetArray()) {
|
||||
if (!value.IsObject()) {
|
||||
continue;
|
||||
@@ -158,25 +136,12 @@ void xmrig::Pools::print() const
|
||||
{
|
||||
size_t i = 1;
|
||||
for (const Pool &pool : m_data) {
|
||||
if (Log::colors) {
|
||||
const int color = pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31;
|
||||
|
||||
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "\x1B[1;%dm%s\x1B[0m variant " WHITE_BOLD("%s"),
|
||||
i,
|
||||
color,
|
||||
pool.url(),
|
||||
pool.algorithm().variantName()
|
||||
);
|
||||
}
|
||||
else {
|
||||
Log::i()->text(" * POOL #%-7zu%s%s variant=%s %s",
|
||||
i,
|
||||
pool.isEnabled() ? "" : "-",
|
||||
pool.url(),
|
||||
pool.algorithm().variantName(),
|
||||
pool.isTLS() ? "TLS" : ""
|
||||
);
|
||||
}
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " variant " WHITE_BOLD("%s"),
|
||||
i,
|
||||
(pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31),
|
||||
pool.url().data(),
|
||||
pool.algorithm().variantName()
|
||||
);
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -191,6 +156,25 @@ void xmrig::Pools::print() const
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Pools::setDonateLevel(int level)
|
||||
{
|
||||
if (level >= kMinimumDonateLevel && level <= 99) {
|
||||
m_donateLevel = level;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Pools::setProxyDonate(int value)
|
||||
{
|
||||
switch (value) {
|
||||
case PROXY_DONATE_NONE:
|
||||
case PROXY_DONATE_AUTO:
|
||||
case PROXY_DONATE_ALWAYS:
|
||||
m_proxyDonate = static_cast<ProxyDonate>(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Pools::setRetries(int retries)
|
||||
{
|
||||
if (retries > 0 && retries <= 1000) {
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/net/Pool.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -42,42 +42,41 @@ class IStrategyListener;
|
||||
class Pools
|
||||
{
|
||||
public:
|
||||
enum ProxyDonate {
|
||||
PROXY_DONATE_NONE,
|
||||
PROXY_DONATE_AUTO,
|
||||
PROXY_DONATE_ALWAYS
|
||||
};
|
||||
|
||||
Pools();
|
||||
|
||||
inline bool setUserpass(const char *userpass) { return current().setUserpass(userpass); }
|
||||
inline const std::vector<Pool> &data() const { return m_data; }
|
||||
inline int donateLevel() const { return m_donateLevel; }
|
||||
inline void setDonateLevel(const int donate) { m_donateLevel = donate; }
|
||||
inline int retries() const { return m_retries; }
|
||||
inline int retryPause() const { return m_retryPause; }
|
||||
inline void setFingerprint(const char *fingerprint) { current().setFingerprint(fingerprint); }
|
||||
inline void setKeepAlive(bool enable) { current().setKeepAlive(enable); }
|
||||
inline void setKeepAlive(int keepAlive) { current().setKeepAlive(keepAlive); }
|
||||
inline void setNicehash(bool enable) { current().setNicehash(enable); }
|
||||
inline void setPassword(const char *password) { current().setPassword(password); }
|
||||
inline void setRigId(const char *rigId) { current().setRigId(rigId); }
|
||||
inline void setTLS(bool enable) { current().setTLS(enable); }
|
||||
inline void setUser(const char *user) { current().setUser(user); }
|
||||
inline void setVariant(const char *variant) { current().algorithm().parseVariant(variant); }
|
||||
inline void setVariant(int variant) { current().algorithm().parseVariant(variant); }
|
||||
inline ProxyDonate proxyDonate() const { return m_proxyDonate; }
|
||||
|
||||
inline bool operator!=(const Pools &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const Pools &other) const { return isEqual(other); }
|
||||
|
||||
bool isEqual(const Pools &other) const;
|
||||
bool setUrl(const char *url);
|
||||
IStrategy *createStrategy(IStrategyListener *listener) const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
size_t active() const;
|
||||
void adjust(const Algorithm &algorithm);
|
||||
void load(const rapidjson::Value &pools);
|
||||
void print() const;
|
||||
void setDonateLevel(int level);
|
||||
void setProxyDonate(int value);
|
||||
void setRetries(int retries);
|
||||
void setRetryPause(int retryPause);
|
||||
|
||||
private:
|
||||
Pool ¤t();
|
||||
|
||||
int m_donateLevel;
|
||||
int m_retries;
|
||||
int m_retryPause;
|
||||
ProxyDonate m_proxyDonate;
|
||||
std::vector<Pool> m_data;
|
||||
};
|
||||
|
||||
72
src/base/net/stratum/SubmitResult.h
Normal file
72
src/base/net/stratum/SubmitResult.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_SUBMITRESULT_H
|
||||
#define XMRIG_SUBMITRESULT_H
|
||||
|
||||
|
||||
#include "base/tools/Chrono.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class SubmitResult
|
||||
{
|
||||
public:
|
||||
inline SubmitResult() :
|
||||
reqId(0),
|
||||
seq(0),
|
||||
actualDiff(0),
|
||||
diff(0),
|
||||
elapsed(0),
|
||||
m_start(0)
|
||||
{}
|
||||
|
||||
inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId = 0) :
|
||||
reqId(reqId),
|
||||
seq(seq),
|
||||
actualDiff(actualDiff),
|
||||
diff(diff),
|
||||
elapsed(0),
|
||||
m_start(Chrono::steadyMSecs())
|
||||
{}
|
||||
|
||||
inline void done() { elapsed = Chrono::steadyMSecs() - m_start; }
|
||||
|
||||
int64_t reqId;
|
||||
int64_t seq;
|
||||
uint64_t actualDiff;
|
||||
uint64_t diff;
|
||||
uint64_t elapsed;
|
||||
|
||||
private:
|
||||
uint64_t m_start;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_SUBMITRESULT_H */
|
||||
192
src/base/net/stratum/Tls.cpp
Normal file
192
src/base/net/stratum/Tls.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
#include "base/net/stratum/Tls.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::Client::Tls::Tls(Client *client) :
|
||||
m_ready(false),
|
||||
m_buf(),
|
||||
m_fingerprint(),
|
||||
m_client(client),
|
||||
m_ssl(nullptr)
|
||||
{
|
||||
m_ctx = SSL_CTX_new(SSLv23_method());
|
||||
assert(m_ctx != nullptr);
|
||||
|
||||
if (!m_ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_writeBio = BIO_new(BIO_s_mem());
|
||||
m_readBio = BIO_new(BIO_s_mem());
|
||||
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Client::Tls::~Tls()
|
||||
{
|
||||
if (m_ctx) {
|
||||
SSL_CTX_free(m_ctx);
|
||||
}
|
||||
|
||||
if (m_ssl) {
|
||||
SSL_free(m_ssl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::Tls::handshake()
|
||||
{
|
||||
m_ssl = SSL_new(m_ctx);
|
||||
assert(m_ssl != nullptr);
|
||||
|
||||
if (!m_ssl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_set_connect_state(m_ssl);
|
||||
SSL_set_bio(m_ssl, m_readBio, m_writeBio);
|
||||
SSL_do_handshake(m_ssl);
|
||||
|
||||
return send();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::Tls::send(const char *data, size_t size)
|
||||
{
|
||||
SSL_write(m_ssl, data, size);
|
||||
|
||||
return send();
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Client::Tls::fingerprint() const
|
||||
{
|
||||
return m_ready ? m_fingerprint : nullptr;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Client::Tls::version() const
|
||||
{
|
||||
return m_ready ? SSL_get_version(m_ssl) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::Tls::read(const char *data, size_t size)
|
||||
{
|
||||
BIO_write(m_readBio, data, size);
|
||||
|
||||
if (!SSL_is_init_finished(m_ssl)) {
|
||||
const int rc = SSL_connect(m_ssl);
|
||||
|
||||
if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
|
||||
send();
|
||||
} else if (rc == 1) {
|
||||
X509 *cert = SSL_get_peer_certificate(m_ssl);
|
||||
if (!verify(cert)) {
|
||||
X509_free(cert);
|
||||
m_client->close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
X509_free(cert);
|
||||
m_ready = true;
|
||||
m_client->login();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int bytes_read = 0;
|
||||
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
|
||||
m_buf[bytes_read - 1] = '\0';
|
||||
m_client->parse(m_buf, static_cast<size_t>(bytes_read));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::Tls::send()
|
||||
{
|
||||
return m_client->send(m_writeBio);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::Tls::verify(X509 *cert)
|
||||
{
|
||||
if (cert == nullptr) {
|
||||
LOG_ERR("[%s] Failed to get server certificate", m_client->url());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!verifyFingerprint(cert)) {
|
||||
LOG_ERR("[%s] Failed to verify server certificate fingerprint", m_client->url());
|
||||
|
||||
const char *fingerprint = m_client->m_pool.fingerprint();
|
||||
if (strlen(m_fingerprint) == 64 && fingerprint != nullptr) {
|
||||
LOG_ERR("\"%s\" was given", m_fingerprint);
|
||||
LOG_ERR("\"%s\" was configured", fingerprint);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::Tls::verifyFingerprint(X509 *cert)
|
||||
{
|
||||
const EVP_MD *digest = EVP_get_digestbyname("sha256");
|
||||
if (digest == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int dlen;
|
||||
|
||||
if (X509_digest(cert, digest, md, &dlen) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Buffer::toHex(md, 32, m_fingerprint);
|
||||
const char *fingerprint = m_client->m_pool.fingerprint();
|
||||
|
||||
return fingerprint == nullptr || strncasecmp(m_fingerprint, fingerprint, 64) == 0;
|
||||
}
|
||||
69
src/base/net/stratum/Tls.h
Normal file
69
src/base/net/stratum/Tls.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CLIENT_TLS_H
|
||||
#define XMRIG_CLIENT_TLS_H
|
||||
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
|
||||
#include "base/net/stratum/Client.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Client::Tls
|
||||
{
|
||||
public:
|
||||
Tls(Client *client);
|
||||
~Tls();
|
||||
|
||||
bool handshake();
|
||||
bool send(const char *data, size_t size);
|
||||
const char *fingerprint() const;
|
||||
const char *version() const;
|
||||
void read(const char *data, size_t size);
|
||||
|
||||
private:
|
||||
bool send();
|
||||
bool verify(X509 *cert);
|
||||
bool verifyFingerprint(X509 *cert);
|
||||
|
||||
BIO *m_readBio;
|
||||
BIO *m_writeBio;
|
||||
bool m_ready;
|
||||
char m_buf[1024 * 2];
|
||||
char m_fingerprint[32 * 2 + 8];
|
||||
Client *m_client;
|
||||
SSL *m_ssl;
|
||||
SSL_CTX *m_ctx;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CLIENT_TLS_H */
|
||||
198
src/base/net/stratum/strategies/FailoverStrategy.cpp
Normal file
198
src/base/net/stratum/strategies/FailoverStrategy.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IStrategyListener.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
#include "base/net/stratum/strategies/FailoverStrategy.h"
|
||||
#include "common/Platform.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_HTTP
|
||||
# include "base/net/stratum/DaemonClient.h"
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::FailoverStrategy::FailoverStrategy(const std::vector<Pool> &pools, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
m_quiet(quiet),
|
||||
m_retries(retries),
|
||||
m_retryPause(retryPause),
|
||||
m_active(-1),
|
||||
m_listener(listener),
|
||||
m_index(0)
|
||||
{
|
||||
for (const Pool &pool : pools) {
|
||||
add(pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::FailoverStrategy::FailoverStrategy(int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
m_quiet(quiet),
|
||||
m_retries(retries),
|
||||
m_retryPause(retryPause),
|
||||
m_active(-1),
|
||||
m_listener(listener),
|
||||
m_index(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::FailoverStrategy::~FailoverStrategy()
|
||||
{
|
||||
for (IClient *client : m_pools) {
|
||||
client->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::add(const Pool &pool)
|
||||
{
|
||||
const int id = static_cast<int>(m_pools.size());
|
||||
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
IClient *client = !pool.isDaemon() ? static_cast<IClient *>(new Client(id, Platform::userAgent(), this))
|
||||
: static_cast<IClient *>(new DaemonClient(id, this));
|
||||
# else
|
||||
IClient *client = new Client(id, Platform::userAgent(), this);
|
||||
# endif
|
||||
|
||||
client->setPool(pool);
|
||||
client->setRetries(m_retries);
|
||||
client->setRetryPause(m_retryPause * 1000);
|
||||
client->setQuiet(m_quiet);
|
||||
|
||||
m_pools.push_back(client);
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::FailoverStrategy::submit(const JobResult &result)
|
||||
{
|
||||
if (!isActive()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return active()->submit(result);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::connect()
|
||||
{
|
||||
m_pools[m_index]->connect();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::resume()
|
||||
{
|
||||
if (!isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener->onJob(this, active(), active()->job());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::setAlgo(const xmrig::Algorithm &algo)
|
||||
{
|
||||
for (IClient *client : m_pools) {
|
||||
client->setAlgo(algo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::stop()
|
||||
{
|
||||
for (size_t i = 0; i < m_pools.size(); ++i) {
|
||||
m_pools[i]->disconnect();
|
||||
}
|
||||
|
||||
m_index = 0;
|
||||
m_active = -1;
|
||||
|
||||
m_listener->onPause(this);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::tick(uint64_t now)
|
||||
{
|
||||
for (IClient *client : m_pools) {
|
||||
client->tick(now);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::onClose(IClient *client, int failures)
|
||||
{
|
||||
if (failures == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_active == client->id()) {
|
||||
m_active = -1;
|
||||
m_listener->onPause(this);
|
||||
}
|
||||
|
||||
if (m_index == 0 && failures < m_retries) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_index == static_cast<size_t>(client->id()) && (m_pools.size() - m_index) > 1) {
|
||||
m_pools[++m_index]->connect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &)
|
||||
{
|
||||
if (m_active == client->id()) {
|
||||
m_listener->onJob(this, client, job);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::onLoginSuccess(IClient *client)
|
||||
{
|
||||
int active = m_active;
|
||||
|
||||
if (client->id() == 0 || !isActive()) {
|
||||
active = client->id();
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < m_pools.size(); ++i) {
|
||||
if (active != static_cast<int>(i)) {
|
||||
m_pools[i]->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
if (active >= 0 && active != m_active) {
|
||||
m_index = m_active = active;
|
||||
m_listener->onActive(this, client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::onResultAccepted(IClient *client, const SubmitResult &result, const char *error)
|
||||
{
|
||||
m_listener->onResultAccepted(this, client, result, error);
|
||||
}
|
||||
85
src/base/net/stratum/strategies/FailoverStrategy.h
Normal file
85
src/base/net/stratum/strategies/FailoverStrategy.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_FAILOVERSTRATEGY_H
|
||||
#define XMRIG_FAILOVERSTRATEGY_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "base/kernel/interfaces/IStrategy.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Client;
|
||||
class IStrategyListener;
|
||||
|
||||
|
||||
class FailoverStrategy : public IStrategy, public IClientListener
|
||||
{
|
||||
public:
|
||||
FailoverStrategy(const std::vector<Pool> &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
|
||||
FailoverStrategy(int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
|
||||
~FailoverStrategy() override;
|
||||
|
||||
void add(const Pool &pool);
|
||||
|
||||
protected:
|
||||
inline bool isActive() const override { return m_active >= 0; }
|
||||
inline IClient *client() const override { return isActive() ? active() : m_pools[m_index]; }
|
||||
inline void onLogin(IClient *, rapidjson::Document &, rapidjson::Value &) override {}
|
||||
|
||||
int64_t submit(const JobResult &result) override;
|
||||
void connect() override;
|
||||
void resume() override;
|
||||
void setAlgo(const Algorithm &algo) override;
|
||||
void stop() override;
|
||||
void tick(uint64_t now) override;
|
||||
|
||||
void onClose(IClient *client, int failures) override;
|
||||
void onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms) override;
|
||||
void onLoginSuccess(IClient *client) override;
|
||||
void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
private:
|
||||
inline IClient *active() const { return m_pools[static_cast<size_t>(m_active)]; }
|
||||
|
||||
const bool m_quiet;
|
||||
const int m_retries;
|
||||
const int m_retryPause;
|
||||
int m_active;
|
||||
IStrategyListener *m_listener;
|
||||
size_t m_index;
|
||||
std::vector<IClient*> m_pools;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* XMRIG_FAILOVERSTRATEGY_H */
|
||||
132
src/base/net/stratum/strategies/SinglePoolStrategy.cpp
Normal file
132
src/base/net/stratum/strategies/SinglePoolStrategy.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IStrategyListener.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
|
||||
#include "common/Platform.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_HTTP
|
||||
# include "base/net/stratum/DaemonClient.h"
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||
m_active(false),
|
||||
m_listener(listener)
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
if (!pool.isDaemon()) {
|
||||
m_client = new Client(0, Platform::userAgent(), this);
|
||||
}
|
||||
else {
|
||||
m_client = new DaemonClient(0, this);
|
||||
}
|
||||
# else
|
||||
m_client = new Client(0, Platform::userAgent(), this);
|
||||
# endif
|
||||
|
||||
m_client->setPool(pool);
|
||||
m_client->setRetries(retries);
|
||||
m_client->setRetryPause(retryPause * 1000);
|
||||
m_client->setQuiet(quiet);
|
||||
}
|
||||
|
||||
|
||||
xmrig::SinglePoolStrategy::~SinglePoolStrategy()
|
||||
{
|
||||
m_client->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::SinglePoolStrategy::submit(const JobResult &result)
|
||||
{
|
||||
return m_client->submit(result);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::connect()
|
||||
{
|
||||
m_client->connect();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::resume()
|
||||
{
|
||||
if (!isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener->onJob(this, m_client, m_client->job());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::setAlgo(const xmrig::Algorithm &algo)
|
||||
{
|
||||
m_client->setAlgo(algo);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::stop()
|
||||
{
|
||||
m_client->disconnect();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::tick(uint64_t now)
|
||||
{
|
||||
m_client->tick(now);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::onClose(IClient *, int)
|
||||
{
|
||||
if (!isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_active = false;
|
||||
m_listener->onPause(this);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &)
|
||||
{
|
||||
m_listener->onJob(this, client, job);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::onLoginSuccess(IClient *client)
|
||||
{
|
||||
m_active = true;
|
||||
m_listener->onActive(this, client);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::onResultAccepted(IClient *client, const SubmitResult &result, const char *error)
|
||||
{
|
||||
m_listener->onResultAccepted(this, client, result, error);
|
||||
}
|
||||
74
src/base/net/stratum/strategies/SinglePoolStrategy.h
Normal file
74
src/base/net/stratum/strategies/SinglePoolStrategy.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_SINGLEPOOLSTRATEGY_H
|
||||
#define XMRIG_SINGLEPOOLSTRATEGY_H
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "base/kernel/interfaces/IStrategy.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Client;
|
||||
class IStrategyListener;
|
||||
class Pool;
|
||||
|
||||
|
||||
class SinglePoolStrategy : public IStrategy, public IClientListener
|
||||
{
|
||||
public:
|
||||
SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
|
||||
~SinglePoolStrategy() override;
|
||||
|
||||
protected:
|
||||
inline bool isActive() const override { return m_active; }
|
||||
inline IClient *client() const override { return m_client; }
|
||||
inline void onLogin(IClient *, rapidjson::Document &, rapidjson::Value &) override {}
|
||||
|
||||
int64_t submit(const JobResult &result) override;
|
||||
void connect() override;
|
||||
void resume() override;
|
||||
void setAlgo(const Algorithm &algo) override;
|
||||
void stop() override;
|
||||
void tick(uint64_t now) override;
|
||||
|
||||
void onClose(IClient *client, int failures) override;
|
||||
void onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms) override;
|
||||
void onLoginSuccess(IClient *client) override;
|
||||
void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
private:
|
||||
bool m_active;
|
||||
IClient *m_client;
|
||||
IStrategyListener *m_listener;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_SINGLEPOOLSTRATEGY_H */
|
||||
99
src/base/net/tools/RecvBuf.h
Normal file
99
src/base/net/tools/RecvBuf.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_RECVBUF_H
|
||||
#define XMRIG_RECVBUF_H
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ILineListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
template<size_t N>
|
||||
class RecvBuf
|
||||
{
|
||||
public:
|
||||
inline RecvBuf() :
|
||||
m_buf(),
|
||||
m_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline char *base() { return m_buf; }
|
||||
inline char *current() { return m_buf + m_pos; }
|
||||
inline const char *base() const { return m_buf; }
|
||||
inline const char *current() const { return m_buf + m_pos; }
|
||||
inline size_t available() const { return N - m_pos; }
|
||||
inline size_t pos() const { return m_pos; }
|
||||
inline void nread(size_t size) { m_pos += size; }
|
||||
inline void reset() { m_pos = 0; }
|
||||
|
||||
constexpr inline size_t size() const { return N; }
|
||||
|
||||
inline void getline(ILineListener *listener)
|
||||
{
|
||||
char *end;
|
||||
char *start = m_buf;
|
||||
size_t remaining = m_pos;
|
||||
|
||||
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
|
||||
*end = '\0';
|
||||
|
||||
end++;
|
||||
const size_t len = static_cast<size_t>(end - start);
|
||||
|
||||
listener->onLine(start, len - 1);
|
||||
|
||||
remaining -= len;
|
||||
start = end;
|
||||
}
|
||||
|
||||
if (remaining == 0) {
|
||||
m_pos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (start == m_buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(m_buf, start, remaining);
|
||||
m_pos = remaining;
|
||||
}
|
||||
|
||||
private:
|
||||
char m_buf[N];
|
||||
size_t m_pos;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_RECVBUF_H */
|
||||
97
src/base/net/tools/Storage.h
Normal file
97
src/base/net/tools/Storage.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_STORAGE_H
|
||||
#define XMRIG_STORAGE_H
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
template <class TYPE>
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
inline Storage() :
|
||||
m_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline uintptr_t add(TYPE *ptr)
|
||||
{
|
||||
m_data[m_counter] = ptr;
|
||||
|
||||
return m_counter++;
|
||||
}
|
||||
|
||||
|
||||
inline static void *ptr(uintptr_t id) { return reinterpret_cast<void *>(id); }
|
||||
|
||||
|
||||
inline TYPE *get(const void *id) const { return get(reinterpret_cast<uintptr_t>(id)); }
|
||||
inline TYPE *get(uintptr_t id) const
|
||||
{
|
||||
assert(m_data.count(id) > 0);
|
||||
if (m_data.count(id) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_data.at(id);
|
||||
}
|
||||
|
||||
|
||||
inline void remove(const void *id) { delete release(reinterpret_cast<uintptr_t>(id)); }
|
||||
inline void remove(uintptr_t id) { delete release(id); }
|
||||
|
||||
|
||||
inline TYPE *release(const void *id) { release(reinterpret_cast<uintptr_t>(id)); }
|
||||
inline TYPE *release(uintptr_t id)
|
||||
{
|
||||
TYPE *obj = get(id);
|
||||
if (obj != nullptr) {
|
||||
auto it = m_data.find(id);
|
||||
if (it != m_data.end()) {
|
||||
m_data.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::map<uintptr_t, TYPE *> m_data;
|
||||
uint64_t m_counter;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_STORAGE_H */
|
||||
102
src/base/net/tools/TcpServer.cpp
Normal file
102
src/base/net/tools/TcpServer.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ITcpServerListener.h"
|
||||
#include "base/net/tools/TcpServer.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
static const xmrig::String kLocalHost("127.0.0.1");
|
||||
|
||||
|
||||
xmrig::TcpServer::TcpServer(const String &host, uint16_t port, ITcpServerListener *listener) :
|
||||
m_host(host.isNull() ? kLocalHost : host),
|
||||
m_version(0),
|
||||
m_listener(listener),
|
||||
m_addr(),
|
||||
m_port(port)
|
||||
{
|
||||
m_tcp = new uv_tcp_t;
|
||||
uv_tcp_init(uv_default_loop(), m_tcp);
|
||||
m_tcp->data = this;
|
||||
|
||||
uv_tcp_nodelay(m_tcp, 1);
|
||||
|
||||
if (m_host.contains(":") && uv_ip6_addr(m_host.data(), m_port, reinterpret_cast<sockaddr_in6 *>(&m_addr)) == 0) {
|
||||
m_version = 6;
|
||||
}
|
||||
else if (uv_ip4_addr(m_host.data(), m_port, reinterpret_cast<sockaddr_in *>(&m_addr)) == 0) {
|
||||
m_version = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::TcpServer::~TcpServer()
|
||||
{
|
||||
Handle::close(m_tcp);
|
||||
}
|
||||
|
||||
|
||||
int xmrig::TcpServer::bind()
|
||||
{
|
||||
if (!m_version) {
|
||||
return UV_EAI_ADDRFAMILY;
|
||||
}
|
||||
|
||||
uv_tcp_bind(m_tcp, reinterpret_cast<const sockaddr*>(&m_addr), 0);
|
||||
|
||||
const int rc = uv_listen(reinterpret_cast<uv_stream_t*>(m_tcp), 511, TcpServer::onConnection);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!m_port) {
|
||||
sockaddr_storage storage = {};
|
||||
int size = sizeof(storage);
|
||||
|
||||
uv_tcp_getsockname(m_tcp, reinterpret_cast<sockaddr*>(&storage), &size);
|
||||
|
||||
m_port = ntohs(reinterpret_cast<sockaddr_in *>(&storage)->sin_port);
|
||||
}
|
||||
|
||||
return m_port;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::TcpServer::create(uv_stream_t *stream, int status)
|
||||
{
|
||||
if (status < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener->onConnection(stream, m_port);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::TcpServer::onConnection(uv_stream_t *stream, int status)
|
||||
{
|
||||
static_cast<TcpServer *>(stream->data)->create(stream, status);
|
||||
}
|
||||
64
src/base/net/tools/TcpServer.h
Normal file
64
src/base/net/tools/TcpServer.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_TCPSERVER_H
|
||||
#define XMRIG_TCPSERVER_H
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ITcpServerListener;
|
||||
class String;
|
||||
|
||||
|
||||
class TcpServer
|
||||
{
|
||||
public:
|
||||
TcpServer(const String &host, uint16_t port, ITcpServerListener *listener);
|
||||
~TcpServer();
|
||||
|
||||
int bind();
|
||||
|
||||
private:
|
||||
void create(uv_stream_t *stream, int status);
|
||||
|
||||
static void onConnection(uv_stream_t *stream, int status);
|
||||
|
||||
const String &m_host;
|
||||
int m_version;
|
||||
ITcpServerListener *m_listener;
|
||||
sockaddr_storage m_addr;
|
||||
uint16_t m_port;
|
||||
uv_tcp_t *m_tcp;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_TCPSERVER_H */
|
||||
45
src/base/tools/Baton.h
Normal file
45
src/base/tools/Baton.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_BATON_H
|
||||
#define XMRIG_BATON_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
template<typename REQ>
|
||||
class Baton
|
||||
{
|
||||
public:
|
||||
inline Baton() { req.data = this; }
|
||||
|
||||
REQ req;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_BATON_H */
|
||||
201
src/base/tools/Buffer.cpp
Normal file
201
src/base/tools/Buffer.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/tools/Buffer.h"
|
||||
|
||||
|
||||
static inline uint8_t hf_hex2bin(uint8_t c, bool &err)
|
||||
{
|
||||
if (c >= '0' && c <= '9') {
|
||||
return c - '0';
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f') {
|
||||
return c - 'a' + 0xA;
|
||||
}
|
||||
else if (c >= 'A' && c <= 'F') {
|
||||
return c - 'A' + 0xA;
|
||||
}
|
||||
|
||||
err = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline uint8_t hf_bin2hex(uint8_t c)
|
||||
{
|
||||
if (c <= 0x9) {
|
||||
return '0' + c;
|
||||
}
|
||||
|
||||
return 'a' - 0xA + c;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer::Buffer() :
|
||||
m_data(nullptr),
|
||||
m_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer::Buffer(Buffer &&other) :
|
||||
m_data(other.m_data),
|
||||
m_size(other.m_size)
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
other.m_size = 0;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer::Buffer(const Buffer &other)
|
||||
{
|
||||
copy(other.data(), other.size());
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer::Buffer(const char *data, size_t size)
|
||||
{
|
||||
copy(data, size);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer::Buffer(size_t size) :
|
||||
m_size(size)
|
||||
{
|
||||
m_data = new char[size]();
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer::~Buffer()
|
||||
{
|
||||
delete [] m_data;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Buffer::from(const char *data, size_t size)
|
||||
{
|
||||
if (m_size > 0) {
|
||||
if (m_size == size) {
|
||||
memcpy(m_data, data, m_size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] m_data;
|
||||
}
|
||||
|
||||
copy(data, size);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer xmrig::Buffer::allocUnsafe(size_t size)
|
||||
{
|
||||
Buffer buf;
|
||||
buf.m_size = size;
|
||||
buf.m_data = new char[size];
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Buffer::fromHex(const uint8_t *in, size_t size, uint8_t *out)
|
||||
{
|
||||
bool error = false;
|
||||
for (size_t i = 0; i < size; i += 2) {
|
||||
out[i / 2] = static_cast<uint8_t>((hf_hex2bin(in[i], error) << 4) | hf_hex2bin(in[i + 1], error));
|
||||
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Buffer xmrig::Buffer::fromHex(const char *data, size_t size)
|
||||
{
|
||||
if (data == nullptr || size % 2 != 0) {
|
||||
return Buffer();
|
||||
}
|
||||
|
||||
Buffer buf(size / 2);
|
||||
fromHex(data, size, buf.data());
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Buffer::toHex(const uint8_t *in, size_t size, uint8_t *out)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
out[i * 2] = hf_bin2hex((in[i] & 0xF0) >> 4);
|
||||
out[i * 2 + 1] = hf_bin2hex(in[i] & 0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::String xmrig::Buffer::toHex(const uint8_t *in, size_t size)
|
||||
{
|
||||
return Buffer(reinterpret_cast<const char *>(in), size).toHex();
|
||||
}
|
||||
|
||||
|
||||
xmrig::String xmrig::Buffer::toHex() const
|
||||
{
|
||||
if (m_size == 0) {
|
||||
return String();
|
||||
}
|
||||
|
||||
char *buf = new char[m_size * 2 + 1];
|
||||
buf[m_size * 2] = '\0';
|
||||
|
||||
toHex(m_data, m_size, buf);
|
||||
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Buffer::copy(const char *data, size_t size)
|
||||
{
|
||||
m_data = new char[size];
|
||||
m_size = size;
|
||||
|
||||
memcpy(m_data, data, m_size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Buffer::move(Buffer &&other)
|
||||
{
|
||||
if (m_size > 0) {
|
||||
delete [] m_data;
|
||||
}
|
||||
|
||||
m_data = other.m_data;
|
||||
m_size = other.m_size;
|
||||
|
||||
other.m_data = nullptr;
|
||||
other.m_size = 0;
|
||||
}
|
||||
88
src/base/tools/Buffer.h
Normal file
88
src/base/tools/Buffer.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_BUFFER_H
|
||||
#define XMRIG_BUFFER_H
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
Buffer();
|
||||
Buffer(Buffer &&other);
|
||||
Buffer(const Buffer &other);
|
||||
Buffer(const char *data, size_t size);
|
||||
Buffer(size_t size);
|
||||
~Buffer();
|
||||
|
||||
|
||||
inline char *data() { return m_data; }
|
||||
inline const char *data() const { return m_data; }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline void from(const Buffer &other) { from(other.data(), other.size()); }
|
||||
|
||||
|
||||
void from(const char *data, size_t size);
|
||||
|
||||
|
||||
inline Buffer &operator=(const Buffer &other) { from(other); return *this; }
|
||||
inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; }
|
||||
|
||||
|
||||
static Buffer allocUnsafe(size_t size);
|
||||
static inline Buffer alloc(size_t size) { return Buffer(size); }
|
||||
|
||||
|
||||
inline static bool fromHex(const char *in, size_t size, char *out) { return fromHex(reinterpret_cast<const uint8_t *>(in), size, reinterpret_cast<uint8_t *>(out)); }
|
||||
inline static bool fromHex(const char *in, size_t size, uint8_t *out) { return fromHex(reinterpret_cast<const uint8_t *>(in), size, out); }
|
||||
inline static Buffer fromHex(const char *data) { return fromHex(data, strlen(data)); }
|
||||
inline static Buffer fromHex(const String &str) { return fromHex(str.data(), str.size()); }
|
||||
inline static void toHex(const char *in, size_t size, char *out) { return toHex(reinterpret_cast<const uint8_t *>(in), size, reinterpret_cast<uint8_t *>(out)); }
|
||||
inline static void toHex(const uint8_t *in, size_t size, char *out) { return toHex(in, size, reinterpret_cast<uint8_t *>(out)); }
|
||||
|
||||
static bool fromHex(const uint8_t *in, size_t size, uint8_t *out);
|
||||
static Buffer fromHex(const char *data, size_t size);
|
||||
static String toHex(const uint8_t *in, size_t size);
|
||||
static void toHex(const uint8_t *in, size_t size, uint8_t *out);
|
||||
String toHex() const;
|
||||
|
||||
private:
|
||||
void copy(const char *data, size_t size);
|
||||
void move(Buffer &&other);
|
||||
|
||||
char *m_data;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_BUFFER_H */
|
||||
60
src/base/tools/Chrono.h
Normal file
60
src/base/tools/Chrono.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CHRONO_H
|
||||
#define XMRIG_CHRONO_H
|
||||
|
||||
|
||||
#include <chrono>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Chrono
|
||||
{
|
||||
public:
|
||||
static inline uint64_t steadyMSecs()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
if (high_resolution_clock::is_steady) {
|
||||
return static_cast<uint64_t>(time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count());
|
||||
}
|
||||
|
||||
return static_cast<uint64_t>(time_point_cast<milliseconds>(steady_clock::now()).time_since_epoch().count());
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t currentMSecsSinceEpoch()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
return static_cast<uint64_t>(time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* XMRIG_CHRONO_H */
|
||||
@@ -26,12 +26,7 @@
|
||||
#define XMRIG_HANDLE_H
|
||||
|
||||
|
||||
typedef struct uv_fs_event_s uv_fs_event_t;
|
||||
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
|
||||
typedef struct uv_handle_s uv_handle_t;
|
||||
typedef struct uv_signal_s uv_signal_t;
|
||||
typedef struct uv_tcp_s uv_tcp_t;
|
||||
typedef struct uv_timer_s uv_timer_t;
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -40,15 +35,57 @@ namespace xmrig {
|
||||
class Handle
|
||||
{
|
||||
public:
|
||||
static void close(uv_fs_event_t *handle);
|
||||
static void close(uv_getaddrinfo_t *handle);
|
||||
static void close(uv_handle_t *handle);
|
||||
static void close(uv_signal_t *handle);
|
||||
static void close(uv_tcp_t *handle);
|
||||
static void close(uv_timer_t *handle);
|
||||
template<typename T>
|
||||
static inline void close(T handle)
|
||||
{
|
||||
if (handle) {
|
||||
deleteLater(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static inline void deleteLater(T handle)
|
||||
{
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t *>(handle))) {
|
||||
return;
|
||||
}
|
||||
|
||||
uv_close(reinterpret_cast<uv_handle_t *>(handle), [](uv_handle_t *handle) { delete handle; });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
inline void Handle::close(uv_timer_t *handle)
|
||||
{
|
||||
if (handle) {
|
||||
uv_timer_stop(handle);
|
||||
deleteLater(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline void Handle::close(uv_signal_t *handle)
|
||||
{
|
||||
if (handle) {
|
||||
uv_signal_stop(handle);
|
||||
deleteLater(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline void Handle::close(uv_fs_event_t *handle)
|
||||
{
|
||||
if (handle) {
|
||||
uv_fs_event_stop(handle);
|
||||
deleteLater(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
@@ -22,6 +23,9 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
@@ -128,6 +132,20 @@ std::vector<xmrig::String> xmrig::String::split(char sep) const
|
||||
}
|
||||
|
||||
|
||||
xmrig::String &xmrig::String::toLower()
|
||||
{
|
||||
if (isNull() || isEmpty()) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size(); ++i) {
|
||||
m_data[i] = static_cast<char>(tolower(m_data[i]));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
xmrig::String xmrig::String::join(const std::vector<xmrig::String> &vec, char sep)
|
||||
{
|
||||
if (vec.empty()) {
|
||||
@@ -178,14 +196,10 @@ void xmrig::String::copy(const char *str)
|
||||
|
||||
void xmrig::String::copy(const String &other)
|
||||
{
|
||||
if (m_size > 0) {
|
||||
if (m_size == other.m_size) {
|
||||
memcpy(m_data, other.m_data, m_size + 1);
|
||||
if (m_size > 0 && m_size == other.m_size) {
|
||||
memcpy(m_data, other.m_data, m_size + 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] m_data;
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] m_data;
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -79,11 +80,13 @@ 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;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
std::vector<xmrig::String> split(char sep) const;
|
||||
String &toLower();
|
||||
|
||||
static String join(const std::vector<xmrig::String> &vec, char sep);
|
||||
|
||||
|
||||
91
src/base/tools/Timer.cpp
Normal file
91
src/base/tools/Timer.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/ITimerListener.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "base/tools/Timer.h"
|
||||
|
||||
|
||||
xmrig::Timer::Timer(ITimerListener *listener) :
|
||||
m_listener(listener),
|
||||
m_timer(nullptr)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
xmrig::Timer::Timer(ITimerListener *listener, uint64_t timeout, uint64_t repeat) :
|
||||
m_listener(listener),
|
||||
m_timer(nullptr)
|
||||
{
|
||||
init();
|
||||
start(timeout, repeat);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Timer::~Timer()
|
||||
{
|
||||
Handle::close(m_timer);
|
||||
}
|
||||
|
||||
|
||||
uint64_t xmrig::Timer::repeat() const
|
||||
{
|
||||
return uv_timer_get_repeat(m_timer);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Timer::setRepeat(uint64_t repeat)
|
||||
{
|
||||
uv_timer_set_repeat(m_timer, repeat);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Timer::start(uint64_t timeout, uint64_t repeat)
|
||||
{
|
||||
uv_timer_start(m_timer, onTimer, timeout, repeat);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Timer::stop()
|
||||
{
|
||||
uv_timer_stop(m_timer);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Timer::init()
|
||||
{
|
||||
m_timer = new uv_timer_t;
|
||||
m_timer->data = this;
|
||||
uv_timer_init(uv_default_loop(), m_timer);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Timer::onTimer(uv_timer_t *handle)
|
||||
{
|
||||
const Timer *timer = static_cast<Timer *>(handle->data);
|
||||
|
||||
timer->m_listener->onTimer(timer);
|
||||
}
|
||||
66
src/base/tools/Timer.h
Normal file
66
src/base/tools/Timer.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_TIMER_H
|
||||
#define XMRIG_TIMER_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct uv_timer_s uv_timer_t;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ITimerListener;
|
||||
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer(ITimerListener *listener);
|
||||
Timer(ITimerListener *listener, uint64_t timeout, uint64_t repeat);
|
||||
~Timer();
|
||||
|
||||
uint64_t repeat() const;
|
||||
void setRepeat(uint64_t repeat);
|
||||
void start(uint64_t timeout, uint64_t repeat);
|
||||
void stop();
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
static void onTimer(uv_timer_t *handle);
|
||||
|
||||
ITimerListener *m_listener;
|
||||
uv_timer_t *m_timer;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_TIMER_H */
|
||||
Reference in New Issue
Block a user