Compare commits

..

23 Commits

Author SHA1 Message Date
xmrig
74c6c14dee Update README.md 2018-04-22 22:24:14 +07:00
XMRig
ca8ba5ec81 Fix msvc build. 2018-04-22 20:12:30 +07:00
XMRig
95e9962b34 v2.5.3 2018-04-22 20:01:05 +07:00
XMRig
987edca758 Fixed build with libmicrohttpd older than 0.9.39. 2018-04-22 13:27:46 +07:00
XMRig
9745130545 Added FreeBSD 10 support (patch sent via email). 2018-04-22 11:54:00 +07:00
XMRig
799a4f0c54 Merge branch 'dev' 2018-04-21 23:54:40 +07:00
XMRig
1523e2fe6f Update CHANGELOG.md. 2018-04-21 23:51:41 +07:00
xmrig
5100b60192 Update STRATUM_EXT.md 2018-04-20 23:53:13 +07:00
XMRig
ab74319afe Merge branch 'dev' of github.com:xmrig/xmrig-proxy into dev 2018-04-19 10:25:42 +07:00
XMRig
27831e4eb6 #178 Revert changes in Client::close to pre v2.5. 2018-04-19 10:25:25 +07:00
xmrig
7a89ff9e0a Update STRATUM_EXT.md 2018-04-12 12:53:58 +07:00
XMRig
15f104ac47 Add stratum protocol docs. 2018-04-12 07:08:12 +07:00
XMRig
08355390d1 More refactoring. 2018-04-12 03:28:19 +07:00
XMRig
0d7bd43b44 Sync changes with the miner. 2018-04-12 02:38:03 +07:00
XMRig
e06c44902d More code unification, used same CommonConfig with CPU miner. 2018-04-09 03:51:51 +07:00
XMRig
0092f741f2 Added configurable keepalive support, now possible override default timeout (60 seconds) via config file (only). 2018-03-29 14:27:08 +07:00
XMRig
0c6f414a74 Better handle client life cycle, prevent possible crashes. 2018-03-29 00:06:51 +07:00
XMRig
5992167dde Merge branch 'master' into dev 2018-03-28 20:26:06 +07:00
XMRig
694446bb72 #152 Fixed build with old gcc. 2018-03-27 11:31:27 +07:00
XMRig
75e4943cba Fix wrong miners count in 32bit build. 2018-03-26 21:36:56 +07:00
XMRig
53f28f99ed Merge branch 'master' into dev 2018-03-26 17:37:55 +07:00
XMRig
74dd286a38 #149 Fixed build with gcc 4.8. 2018-03-25 18:53:54 +07:00
XMRig
1fd8dfee98 Merge branch 'master' into dev 2018-03-25 14:43:15 +07:00
61 changed files with 2168 additions and 1184 deletions

View File

@@ -1,3 +1,8 @@
# v2.5.3
- Fixed critical bug, in some cases proxy was can't recovery connection and switch to failover pool, version 2.5.2 affected.
- Added configurable keepalive support, now possible override default timeout (60 seconds) via config file (only).
- Fixed wrong miners count in 32 bit builds.
# v2.5.2
- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect.

View File

@@ -13,13 +13,16 @@ set(HEADERS
src/3rdparty/align.h
src/App.h
src/Console.h
src/core/CommonConfig.h
src/core/Config.h
src/core/ConfigLoader.h
src/core/ConfigLoader_static.h
src/core/ConfigLoader_platform.h
src/core/ConfigWatcher.h
src/core/Controller.h
src/donate.h
src/interfaces/IClientListener.h
src/interfaces/IConfig.h
src/interfaces/IConfigCreator.h
src/interfaces/IConsoleListener.h
src/interfaces/IControllerListener.h
src/interfaces/IEvent.h
@@ -37,10 +40,11 @@ set(HEADERS
src/net/Client.h
src/net/Id.h
src/net/Job.h
src/net/Pool.h
src/net/Storage.h
src/net/strategies/DonateStrategy.h
src/net/strategies/FailoverStrategy.h
src/net/strategies/SinglePoolStrategy.h
src/net/Url.h
src/Platform.h
src/proxy/Addr.h
src/proxy/Counters.h
@@ -80,6 +84,7 @@ set(HEADERS
set(SOURCES
src/App.cpp
src/Console.cpp
src/core/CommonConfig.cpp
src/core/Config.cpp
src/core/ConfigLoader.cpp
src/core/ConfigWatcher.cpp
@@ -93,11 +98,11 @@ set(SOURCES
src/log/ShareLog.cpp
src/net/Client.cpp
src/net/Job.cpp
src/net/Pool.cpp
src/net/strategies/DonateStrategy.cpp
src/net/strategies/FailoverStrategy.cpp
src/net/strategies/SinglePoolStrategy.cpp
src/net/SubmitResult.cpp
src/net/Url.cpp
src/Platform.cpp
src/proxy/Counters.cpp
src/proxy/CustomDiff.cpp
@@ -152,7 +157,11 @@ else()
src/proxy/Uuid_unix.cpp
)
set(EXTRA_LIBS pthread uuid)
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
set(EXTRA_LIBS pthread)
else()
set(EXTRA_LIBS pthread uuid)
endif()
endif()
add_definitions(/DXMRIG_PROXY_PROJECT)

View File

@@ -72,8 +72,8 @@ Default donation fee is 2% can be reduced to 1% or disabled via `donate-level` o
## Release checksums
### SHA-256
```
005a90c13d0f1f37f5f1bafb41a5c20149df6e42e6a6991621335ccae9215c29 xmrig-proxy-2.5.2-win32/xmrig-proxy.exe
58d1a6f03485a4ba7b3ab048831ac4886de8adf2e4f2448dab0d28ac29251d4c xmrig-proxy-2.5.2-win64/xmrig-proxy.exe
f2ef4d088940634b5fd325c88a216a03b807c770cd2fbe9a7d9c7a51f81ac04e xmrig-proxy-2.5.3-win32/xmrig-proxy.exe
09a0e096a575aefd1d4bcd06642c4b620a1cc04360037686ed99e3affd73bc74 xmrig-proxy-2.5.3-win64/xmrig-proxy.exe
```
## Contacts

133
doc/STRATUM.md Normal file
View File

@@ -0,0 +1,133 @@
# Stratum mining protocol
## login
Miner send `login` request after connection successfully established for authorization on pool.
#### Example request:
```json
{
"id": 1,
"jsonrpc": "2.0",
"method": "login",
"params": {
"login": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD",
"pass": "x",
"agent": "XMRig/2.6.0-beta2 (Linux x86_64) libuv/1.8.0 gcc/5.4.0"
}
}
```
#### Example success reply:
```json
{
"id": 1,
"jsonrpc": "2.0",
"error": null,
"result": {
"id": "1be0b7b6-b15a-47be-a17d-46b2911cf7d0",
"job": {
"blob": "070780e6b9d60586ba419a0c224e3c6c3e134cc45c4fa04d8ee2d91c2595463c57eef0a4f0796c000000002fcc4d62fa6c77e76c30017c768be5c61d83ec9d3a085d524ba8053ecc3224660d",
"job_id": "q7PLUPL25UV0z5Ij14IyMk8htXbj",
"target": "b88d0600",
"id": "1be0b7b6-b15a-47be-a17d-46b2911cf7d0"
},
"status": "OK"
}
}
```
#### Example error reply:
```json
{
"id": 1,
"jsonrpc": "2.0",
"error": {
"code": -1,
"message": "Invalid payment address provided"
}
}
```
## job
Pool send new job to miner. Miner should switch to new job as fast as possible.
#### Example notification:
```json
{
"jsonrpc": "2.0",
"method": "job",
"params": {
"blob": "0707d5efb9d6057e95a35f868231780b3a8649c4e57f3c77eaf437329243eef0b9f4b6987d05b900000000cae7754cb85a0ad8eebf3e0bf55f3ec5e754a1d6b05d46e5c358f907dbcbb72b01",
"job_id": "4BiGm3/RgGQzgkTI/xV0smdA+EGZ",
"target": "b88d0600",
"id": "1be0b7b6-b15a-47be-a17d-46b2911cf7d0"
}
}
```
## submit
Miner send `submit` request after share was found.
#### Example request:
```json
{
"id": 2,
"jsonrpc": "2.0",
"method": "submit",
"params": {
"id": "1be0b7b6-b15a-47be-a17d-46b2911cf7d0",
"job_id": "4BiGm3/RgGQzgkTI/xV0smdA+EGZ",
"nonce": "d0030040",
"result": "e1364b8782719d7683e2ccd3d8f724bc59dfa780a9e960e7c0e0046acdb40100"
}
}
```
#### Example success reply:
```json
{
"id": 2,
"jsonrpc": "2.0",
"error": null,
"result": {
"status": "OK"
}
}
```
#### Example error reply:
```json
{
"id": 2,
"jsonrpc": "2.0",
"error": {
"code": -1,
"message": "Low difficulty share"
}
}
```
## keepalived
Non standard but widely supported protocol extension. Miner send `keepalived` to prevent connection timeout.
#### Example request:
```json
{
"id": 2,
"method": "keepalived",
"params": {
"id": "1be0b7b6-b15a-47be-a17d-46b2911cf7d0"
}
}
```
#### Example success reply:
```json
{
"id": 2,
"jsonrpc": "2.0",
"error": null,
"result": {
"status": "KEEPALIVED"
}
}
```

101
doc/STRATUM_EXT.md Normal file
View File

@@ -0,0 +1,101 @@
# Stratum protocol extensions
## Mining algorithm negotiation
Subset of protocol extensions, used to negotiate algorithm between miner and pool/proxy. All extensions is backward compatible with standart stratum protocol.
### Miner defined algorithms list
Miner should send list of algorithms supported. Multiple algorithms in list meant miner can switch algorithms in runtime.
```json
{
"id": 1, "jsonrpc": "2.0", "method": "login",
"params": {
"login": "...", "pass": "...", "agent": "...",
"algo": ["cn", "cn-lite", "cn-heavy"]
}
}
```
In case if miner not support dynamic algorithm change, miner should send list with one item, for example `"algo": ["cn-heavy"]`, pool/proxy should provide work for selected algorithm or send error.
### Extended job object
To each `job` object pool/proxy should add 2 additional fields `algo` and `variant`.
```json
{
"id": 1, "jsonrpc": "2.0", "error": null,
"result": {
"id": "...",
"job": {
"blob": "...", "job_id": "...", "target": "...", "id": "...",
"algo": "cn", "variant": 1
},
"status": "OK"
}
}
```
```json
{
"jsonrpc": "2.0", "method": "job",
"params": {
"blob": "...", "job_id": "...", "target": "b88d0600", "id": "...",
"algo": "cn", "variant": 1
}
}
```
Possible values for `variant`:
* `1` Force use variant 1 of algorithm.
* `0` Force use original cn/cn-lite algorithm.
* `-1` or missing field, leave miner autodetect algorithm by block version.
Note about `cn-heavy` this algorithm now support only one (original) variant, so only valid values `-1` or `0`. `1` is reserved for future use, current pool/proxy implementation should never send `"variant": 1` if `cn-heavy` algorithm used.
If miner not support algorithm connection should be closed by miner to initiate switch to backup pool.
### Algo extension
This extension is backward compatible with xmr-stak [extended mining statistics](#extended-mining-statistics).
First, pool should add `algo` to extensions list:
```json
{
"id": 1, "jsonrpc": "2.0", "error": null,
"result": {
"id": "...",
"job": {
"blob": "...", "job_id": "...", "target": "...", "id": "...",
"algo": "cn", "variant": 1
},
"extensions" : ["algo"],
"status": "OK"
}
}
```
Second, miner add fields `algo` and `variant` to submit request.
```json
{
"id": 2, "jsonrpc": "2.0", "method": "submit",
"params": {
"id": "...", "job_id": "...", "nonce": "...", "result": "...",
"algo": "cn", "variant": 1
}
}
```
Note about xmr-stak, this miner not send `variant` field and always use long algorithm names, also used 2 non standart algorithm names `cryptonight-monerov7` and `cryptonight-aeonv7`, pool side should support it as `cn` variant 1 and `cn-lite` variant 1.
### Algorithm names and variants
Both miner and pool should support short algorithm name aliases:
| Long name | Short name | Variants |
|-------------------|------------|------------|
| cryptonight | cn | `0` or `1` |
| cryptonight-lite | cn-lite | `0` or `1` |
| cryptonight-heavy | cn-heavy | only `0` |
| cryptonight-ipbc | cn-ipbc | only `1` |
Note about **cryptonight** and **cryptonight variant 1**, also known as **cryptonight v7**, all these variants use same algorithm name `cryptonight` or `cn`, miner should able to switch between variants in runtime.
## Rig identifier
User defined rig identifier. Optional field `rigid` in `login` request. More details: https://github.com/fireice-uk/xmr-stak/issues/849
## Extended mining statistics
More details: https://github.com/fireice-uk/xmr-stak/issues/66

View File

@@ -53,7 +53,7 @@ App::App(int argc, char **argv) :
return;
}
if (!m_controller->config()->background()) {
if (!m_controller->config()->isBackground()) {
m_console = new Console(this);
}
@@ -102,8 +102,8 @@ int App::exec()
m_httpd = new Httpd(
m_controller->config()->apiPort(),
m_controller->config()->apiToken(),
m_controller->config()->apiIPv6(),
m_controller->config()->apiRestricted()
m_controller->config()->isApiIPv6(),
m_controller->config()->isApiRestricted()
);
m_httpd->start();
@@ -133,7 +133,7 @@ void App::onConsoleCommand(char command)
case 'v':
case 'V':
m_controller->config()->toggleVerbose();
LOG_NOTICE("verbose: %d", m_controller->config()->verbose());
LOG_NOTICE("verbose: %d", m_controller->config()->isVerbose());
break;
case 'h':

View File

@@ -4,8 +4,8 @@
* 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 2016-2018 XMRig <support@xmrig.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>
*
* 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
@@ -38,7 +38,7 @@ void App::background()
{
signal(SIGPIPE, SIG_IGN);
if (!m_controller->config()->background()) {
if (!m_controller->config()->isBackground()) {
return;
}

View File

@@ -4,8 +4,8 @@
* 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 2016-2017 XMRig <support@xmrig.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>
*
* 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
@@ -33,7 +33,7 @@
void App::background()
{
if (!m_controller->config()->background()) {
if (!m_controller->config()->isBackground()) {
return;
}

View File

@@ -4,8 +4,8 @@
* 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 2016-2017 XMRig <support@xmrig.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>
*
* 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
@@ -117,6 +117,7 @@ void Platform::setThreadPriority(int priority)
setpriority(PRIO_PROCESS, 0, prio);
# ifdef SCHED_IDLE
if (priority == 0) {
sched_param param;
param.sched_priority = 0;
@@ -125,4 +126,5 @@ void Platform::setThreadPriority(int priority)
sched_setscheduler(0, SCHED_BATCH, &param);
}
}
# endif
}

View File

@@ -29,7 +29,7 @@
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "net/Url.h"
#include "net/Pool.h"
#include "proxy/Addr.h"
#include "Summary.h"
#include "version.h"
@@ -50,7 +50,7 @@ static void print_versions(xmrig::Controller *controller)
# endif
if (controller->config()->colors()) {
if (controller->config()->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mxmrig-proxy/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf);
} else {
Log::i()->text(" * VERSIONS: xmrig-proxy/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf);
@@ -60,22 +60,22 @@ static void print_versions(xmrig::Controller *controller)
static void print_mode(xmrig::Controller *controller)
{
Log::i()->text(controller->config()->colors() ? "\x1B[01;32m * \x1B[01;37mMODE:\x1B[0m \x1B[01;37m%s" : " * MODE: %s",
Log::i()->text(controller->config()->isColors() ? "\x1B[01;32m * \x1B[01;37mMODE:\x1B[0m \x1B[01;37m%s" : " * MODE: %s",
controller->config()->modeName());
}
static void print_bind(xmrig::Controller *controller)
{
const std::vector<Addr*> &addrs = controller->config()->addrs();
const std::vector<Addr> &addrs = controller->config()->addrs();
for (size_t i = 0; i < addrs.size(); ++i) {
Log::i()->text(controller->config()->colors() ? "\x1B[01;32m * \x1B[01;37mBIND #%d:\x1B[0m \x1B[36m%s%s%s:%d" : " * BIND #%d: %s%s%s:%d",
Log::i()->text(controller->config()->isColors() ? "\x1B[01;32m * \x1B[01;37mBIND #%d:\x1B[0m \x1B[36m%s%s%s:%d" : " * BIND #%d: %s%s%s:%d",
i + 1,
addrs[i]->isIPv6() ? "[" : "",
addrs[i]->ip(),
addrs[i]->isIPv6() ? "]" : "",
addrs[i]->port());
addrs[i].isIPv6() ? "[" : "",
addrs[i].ip(),
addrs[i].isIPv6() ? "]" : "",
addrs[i].port());
}
}
@@ -88,15 +88,15 @@ static void print_api(xmrig::Controller *controller)
return;
}
Log::i()->text(controller->config()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d",
controller->config()->apiIPv6() ? "[::]" : "0.0.0.0", port);
Log::i()->text(controller->config()->isColors() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d",
controller->config()->isApiIPv6() ? "[::]" : "0.0.0.0", port);
}
#endif
static void print_commands(xmrig::Controller *controller)
{
if (controller->config()->colors()) {
if (controller->config()->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mc\x1B[01;37monnections, \x1B[01;35mv\x1B[01;37merbose, \x1B[01;35mw\x1B[01;37morkers");
}
else {
@@ -122,18 +122,18 @@ void Summary::print(xmrig::Controller *controller)
void Summary::printPools(xmrig::Config *config)
{
const std::vector<Url*> &pools = config->pools();
const std::vector<Pool> &pools = config->pools();
for (size_t i = 0; i < pools.size(); ++i) {
Log::i()->text(config->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d:\x1B[0m \x1B[36m%s:%d" : " * POOL #%d: %s:%d",
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d:\x1B[0m \x1B[36m%s" : " * POOL #%d: %s",
i + 1,
pools[i]->host(),
pools[i]->port());
pools[i].url()
);
}
# ifdef APP_DEBUG
for (size_t i = 0; i < pools.size(); ++i) {
Log::i()->text("%s:%d, user: %s, pass: %s", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password());
Log::i()->text("%s:%d, user: %s, pass: %s", pools[i].host(), pools[i].port(), pools[i].user(), pools[i].password());
}
# endif
}

View File

@@ -7,7 +7,6 @@
* 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>
*
*
* 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
@@ -34,37 +33,6 @@
#include "log/Log.h"
class UploadCtx
{
public:
inline UploadCtx() :
m_pos(0)
{}
inline bool write(const char *data, size_t size)
{
if (size > (sizeof(m_data) - m_pos - 1)) {
return false;
}
memcpy(m_data + m_pos, data, size);
m_pos += size;
m_data[m_pos] = '\0';
return true;
}
inline const char *data() const { return m_data; }
private:
char m_data[32768];
size_t m_pos;
};
Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) :
m_idle(true),
m_IPv6(IPv6),
@@ -97,6 +65,7 @@ bool Httpd::start()
}
unsigned int flags = 0;
# if MHD_VERSION >= 0x00093500
if (m_IPv6 && MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
flags |= MHD_USE_DUAL_STACK;
}
@@ -104,6 +73,7 @@ bool Httpd::start()
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
flags |= MHD_USE_EPOLL_LINUX_ONLY;
}
# endif
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
if (!m_daemon) {
@@ -111,7 +81,12 @@ bool Httpd::start()
return false;
}
# if MHD_VERSION >= 0x00093900
uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval);
# else
uv_timer_start(&m_timer, Httpd::onTimer, kActiveInterval, kActiveInterval);
# endif
return true;
}
@@ -137,6 +112,7 @@ void Httpd::run()
{
MHD_run(m_daemon);
# if MHD_VERSION >= 0x00093900
const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
if (m_idle && info->num_connections) {
uv_timer_set_repeat(&m_timer, kActiveInterval);
@@ -146,6 +122,7 @@ void Httpd::run()
uv_timer_set_repeat(&m_timer, kIdleInterval);
m_idle = true;
}
# endif
}

View File

@@ -7,7 +7,6 @@
* 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>
*
*
* 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

View File

@@ -5,7 +5,7 @@
"port": 0,
"access-token": null,
"worker-id": null,
"ipv6": true,
"ipv6": false,
"restricted": true
},
"background": false,

332
src/core/CommonConfig.cpp Normal file
View File

@@ -0,0 +1,332 @@
/* 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 2016-2018 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>
#include "core/CommonConfig.h"
#include "donate.h"
#include "log/Log.h"
#include "net/Pool.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
#include "xmrig.h"
xmrig::CommonConfig::CommonConfig() :
m_algorithm(CRYPTONIGHT),
m_adjusted(false),
m_apiIPv6(false),
m_apiRestricted(true),
m_background(false),
m_colors(true),
m_syslog(false),
# ifdef XMRIG_PROXY_PROJECT
m_watch(true),
# else
m_watch(false), // TODO: enable config file watch by default when this feature propertly handled and tested.
# endif
m_apiPort(0),
m_donateLevel(kDefaultDonateLevel),
m_printTime(60),
m_retries(5),
m_retryPause(5)
{
m_pools.push_back(Pool());
# ifdef XMRIG_PROXY_PROJECT
m_retries = 2;
m_retryPause = 1;
# endif
}
xmrig::CommonConfig::~CommonConfig()
{
}
bool xmrig::CommonConfig::adjust()
{
if (m_adjusted) {
return false;
}
m_adjusted = true;
for (Pool &pool : m_pools) {
pool.adjust(algorithm());
}
return true;
}
bool xmrig::CommonConfig::isValid() const
{
return m_pools[0].isValid();
}
bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
{
switch (key) {
case BackgroundKey: /* --background */
m_background = enable;
break;
case SyslogKey: /* --syslog */
m_syslog = enable;
break;
case KeepAliveKey: /* --keepalive */
m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0);
break;
# ifndef XMRIG_PROXY_PROJECT
case NicehashKey: /* --nicehash */
m_pools.back().setNicehash(enable);
break;
# endif
case ColorKey: /* --no-color */
m_colors = enable;
break;
case WatchKey: /* watch */
m_watch = enable;
break;
case ApiIPv6Key: /* ipv6 */
m_apiIPv6 = enable;
case ApiRestrictedKey: /* restricted */
m_apiRestricted = enable;
default:
break;
}
return true;
}
bool xmrig::CommonConfig::parseString(int key, const char *arg)
{
switch (key) {
case AlgorithmKey: /* --algo */
setAlgo(arg);
break;
case UserpassKey: /* --userpass */
if (!m_pools.back().setUserpass(arg)) {
return false;
}
break;
case UrlKey: /* --url */
if (m_pools.size() > 1 || m_pools[0].isValid()) {
Pool pool(arg);
if (pool.isValid()) {
m_pools.push_back(std::move(pool));
}
}
else {
m_pools[0].parse(arg);
}
if (!m_pools.back().isValid()) {
return false;
}
break;
case UserKey: /* --user */
m_pools.back().setUser(arg);
break;
case PasswordKey: /* --pass */
m_pools.back().setPassword(arg);
break;
case LogFileKey: /* --log-file */
m_logFile = arg;
break;
case ApiAccessTokenKey: /* --api-access-token */
m_apiToken = arg;
break;
case ApiWorkerIdKey: /* --api-worker-id */
m_apiWorkerId = arg;
break;
case UserAgentKey: /* --user-agent */
m_userAgent = arg;
break;
case RetriesKey: /* --retries */
case RetryPauseKey: /* --retry-pause */
case VariantKey: /* --variant */
case ApiPort: /* --api-port */
case PrintTimeKey: /* --cpu-priority */
return parseUint64(key, strtol(arg, nullptr, 10));
case BackgroundKey: /* --background */
case SyslogKey: /* --syslog */
case KeepAliveKey: /* --keepalive */
case NicehashKey: /* --nicehash */
return parseBoolean(key, true);
case ColorKey: /* --no-color */
case WatchKey: /* --no-watch */
case ApiRestrictedKey: /* --api-no-restricted */
case ApiIPv6Key: /* --api-no-ipv6 */
return parseBoolean(key, false);
case DonateLevelKey: /* --donate-level */
# ifdef XMRIG_PROXY_PROJECT
if (strncmp(arg, "minemonero.pro", 14) == 0) {
m_donateLevel = 0;
return true;
}
# endif
return parseUint64(key, strtol(arg, nullptr, 10));
default:
break;
}
return true;
}
bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg)
{
return parseInt(key, static_cast<int>(arg));
}
bool xmrig::CommonConfig::save()
{
if (m_fileName.isNull()) {
return false;
}
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName.data(), O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr);
if (fd < 0) {
return false;
}
uv_fs_req_cleanup(&req);
rapidjson::Document doc;
getJSON(doc);
FILE *fp = fdopen(fd, "w");
char buf[4096];
rapidjson::FileWriteStream os(fp, buf, sizeof(buf));
rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
doc.Accept(writer);
fclose(fp);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
return true;
}
void xmrig::CommonConfig::setFileName(const char *fileName)
{
m_fileName = fileName;
}
bool xmrig::CommonConfig::parseInt(int key, int arg)
{
switch (key) {
case RetriesKey: /* --retries */
if (arg > 0 && arg <= 1000) {
m_retries = arg;
}
break;
case RetryPauseKey: /* --retry-pause */
if (arg > 0 && arg <= 3600) {
m_retryPause = arg;
}
break;
case KeepAliveKey: /* --keepalive */
m_pools.back().setKeepAlive(arg);
break;
case VariantKey: /* --variant */
m_pools.back().setVariant(arg);
break;
case DonateLevelKey: /* --donate-level */
if (arg >= kMinimumDonateLevel && arg <= 99) {
m_donateLevel = arg;
}
break;
case ApiPort: /* --api-port */
if (arg > 0 && arg <= 65536) {
m_apiPort = arg;
}
break;
case PrintTimeKey: /* --print-time */
if (arg >= 0 && arg <= 3600) {
m_printTime = arg;
}
break;
default:
break;
}
return true;
}
void xmrig::CommonConfig::setAlgo(const char *algo)
{
m_algorithm = Pool::algorithm(algo);
}

105
src/core/CommonConfig.h Normal file
View File

@@ -0,0 +1,105 @@
/* 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 2016-2018 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 __COMMONCONFIG_H__
#define __COMMONCONFIG_H__
#include <vector>
#include "core/utils/c_str.h"
#include "interfaces/IConfig.h"
#include "net/Pool.h"
#include "xmrig.h"
namespace xmrig {
class CommonConfig : public IConfig
{
public:
CommonConfig();
~CommonConfig();
inline Algo algorithm() const { return m_algorithm; }
inline bool isApiIPv6() const { return m_apiIPv6; }
inline bool isApiRestricted() const { return m_apiRestricted; }
inline bool isBackground() const { return m_background; }
inline bool isColors() const { return m_colors; }
inline bool isSyslog() const { return m_syslog; }
inline const char *algoName() const { return Pool::algoName(m_algorithm); }
inline const char *apiToken() const { return m_apiToken.data(); }
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
inline const char *logFile() const { return m_logFile.data(); }
inline const char *userAgent() const { return m_userAgent.data(); }
inline const std::vector<Pool> &pools() const { return m_pools; }
inline int apiPort() const { return m_apiPort; }
inline int donateLevel() const { return m_donateLevel; }
inline int printTime() const { return m_printTime; }
inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; }
inline void setColors(bool colors) { m_colors = colors; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const char *fileName() const override { return m_fileName.data(); }
protected:
bool adjust() override;
bool isValid() const override;
bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override;
bool save() override;
void setFileName(const char *fileName) override;
Algo m_algorithm;
bool m_adjusted;
bool m_apiIPv6;
bool m_apiRestricted;
bool m_background;
bool m_colors;
bool m_syslog;
bool m_watch;
int m_apiPort;
int m_donateLevel;
int m_printTime;
int m_retries;
int m_retryPause;
std::vector<Pool> m_pools;
xmrig::c_str m_apiToken;
xmrig::c_str m_apiWorkerId;
xmrig::c_str m_fileName;
xmrig::c_str m_logFile;
xmrig::c_str m_userAgent;
private:
bool parseInt(int key, int arg);
void setAlgo(const char *algo);
};
} /* namespace xmrig */
#endif /* __COMMONCONFIG_H__ */

View File

@@ -7,7 +7,6 @@
* 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>
*
*
* 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
@@ -22,25 +21,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <limits.h>
#include <string.h>
#include <uv.h>
#include "core/Config.h"
#include "core/ConfigCreator.h"
#include "core/ConfigLoader.h"
#include "donate.h"
#include "log/Log.h"
#include "net/Url.h"
#include "proxy/Addr.h"
#include "net/Pool.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
static const char *algoNames[] = {
"cryptonight",
"cryptonight-lite"
};
#include "xmrig.h"
static const char *modeNames[] = {
@@ -49,72 +44,20 @@ static const char *modeNames[] = {
};
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#ifdef _WIN32
#if defined(_WIN32) && !defined(strncasecmp)
# define strncasecmp _strnicmp
#endif
xmrig::Config::Config() :
m_adjusted(false),
m_apiIPv6(true),
m_apiRestricted(true),
m_background(false),
m_colors(true),
xmrig::Config::Config() : xmrig::CommonConfig(),
m_debug(false),
m_ready(false),
m_syslog(false),
m_verbose(false),
m_watch(true),
m_workers(true),
m_accessLog(nullptr),
m_apiToken(nullptr),
m_apiWorkerId(nullptr),
m_fileName(nullptr),
m_logFile(nullptr),
m_userAgent(nullptr),
m_algorithm(CRYPTONIGHT),
m_apiPort(0),
m_donateLevel(kDonateLevel),
m_mode(NICEHASH_MODE),
m_retries(2),
m_retryPause(1),
m_reuseTimeout(0),
m_diff(0)
{
m_pools.push_back(new Url());
}
xmrig::Config::~Config()
{
for (Addr *addr : m_addrs) {
delete addr;
}
for (Url *url : m_pools) {
delete url;
}
m_addrs.clear();
m_pools.clear();
free(m_fileName);
free(m_accessLog);
free(m_apiToken);
free(m_apiWorkerId);
free(m_logFile);
free(m_userAgent);
}
bool xmrig::Config::isValid() const
{
return m_pools[0]->isValid();
}
@@ -124,53 +67,13 @@ bool xmrig::Config::reload(const char *json)
}
bool xmrig::Config::save()
{
if (!m_fileName) {
return false;
}
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName, O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr);
if (fd < 0) {
return false;
}
uv_fs_req_cleanup(&req);
rapidjson::Document doc;
getJSON(doc);
FILE *fp = fdopen(fd, "w");
char buf[4096];
rapidjson::FileWriteStream os(fp, buf, sizeof(buf));
rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
doc.Accept(writer);
fclose(fp);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName);
return true;
}
const char *xmrig::Config::algoName() const
{
return algoNames[m_algorithm];
}
const char *xmrig::Config::modeName() const
{
return modeNames[m_mode];
}
void xmrig::Config::getJSON(rapidjson::Document &doc)
void xmrig::Config::getJSON(rapidjson::Document &doc) const
{
doc.SetObject();
@@ -183,19 +86,19 @@ void xmrig::Config::getJSON(rapidjson::Document &doc)
api.AddMember("port", apiPort(), allocator);
api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
api.AddMember("ipv6", apiIPv6(), allocator);
api.AddMember("restricted", apiRestricted(), allocator);
api.AddMember("ipv6", isApiIPv6(), allocator);
api.AddMember("restricted", isApiRestricted(), allocator);
doc.AddMember("api", api, allocator);
doc.AddMember("background", background(), allocator);
doc.AddMember("background", isBackground(), allocator);
rapidjson::Value bind(rapidjson::kArrayType);
for (const Addr *addr : m_addrs) {
bind.PushBack(rapidjson::StringRef(addr->addr()), allocator);
for (const Addr &addr : m_addrs) {
bind.PushBack(rapidjson::StringRef(addr.addr()), allocator);
}
doc.AddMember("bind", bind, allocator);
doc.AddMember("colors", colors(), allocator);
doc.AddMember("colors", isColors(), allocator);
doc.AddMember("custom-diff", diff(), allocator);
doc.AddMember("donate-level", donateLevel(), allocator);
doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
@@ -203,14 +106,21 @@ void xmrig::Config::getJSON(rapidjson::Document &doc)
rapidjson::Value pools(rapidjson::kArrayType);
for (const Url *url : m_pools) {
for (const Pool &pool : m_pools) {
rapidjson::Value obj(rapidjson::kObjectType);
obj.AddMember("url", rapidjson::StringRef(url->url()), allocator);
obj.AddMember("user", rapidjson::StringRef(url->user()), allocator);
obj.AddMember("pass", rapidjson::StringRef(url->password()), allocator);
obj.AddMember("coin", rapidjson::StringRef(url->coin()), allocator);
obj.AddMember("variant", url->variant(), allocator);
obj.AddMember("url", rapidjson::StringRef(pool.url()), allocator);
obj.AddMember("user", rapidjson::StringRef(pool.user()), allocator);
obj.AddMember("pass", rapidjson::StringRef(pool.password()), allocator);
if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) {
obj.AddMember("keepalive", pool.keepAlive() > 0, allocator);
}
else {
obj.AddMember("keepalive", pool.keepAlive(), allocator);
}
obj.AddMember("variant", pool.variant(), allocator);
pools.PushBack(obj, allocator);
}
@@ -223,48 +133,144 @@ void xmrig::Config::getJSON(rapidjson::Document &doc)
doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
# ifdef HAVE_SYSLOG_H
doc.AddMember("syslog", syslog(), allocator);
doc.AddMember("syslog", isSyslog(), allocator);
# endif
doc.AddMember("verbose", verbose(), allocator);
doc.AddMember("watch", m_watch, allocator);
doc.AddMember("workers", workers(), allocator);
doc.AddMember("verbose", isVerbose(), allocator);
doc.AddMember("watch", m_watch, allocator);
doc.AddMember("workers", isWorkers(), allocator);
}
xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *listener)
{
return xmrig::ConfigLoader::load(argc, argv, listener);
return static_cast<Config*>(ConfigLoader::load(argc, argv, new ConfigCreator(), listener));
}
void xmrig::Config::adjust()
bool xmrig::Config::adjust()
{
if (m_adjusted) {
return;
if (!CommonConfig::adjust()) {
return false;
}
m_adjusted = true;
for (Url *url : m_pools) {
url->adjust(algorithm());
if (m_addrs.empty()) {
m_addrs.push_back(Addr("0.0.0.0:3333"));
m_addrs.push_back(Addr("[::]:3333"));
}
return true;
}
void xmrig::Config::setAlgo(const char *algo)
bool xmrig::Config::parseBoolean(int key, bool enable)
{
const size_t size = sizeof(algoNames) / sizeof((algoNames)[0]);
if (!CommonConfig::parseBoolean(key, enable)) {
return false;
}
for (size_t i = 0; i < size; i++) {
if (algoNames[i] && !strcmp(algo, algoNames[i])) {
m_algorithm = (int) i;
break;
switch (key) {
case VerboseKey: /* --verbose */
m_verbose = enable;
break;
case DebugKey: /* --debug */
m_debug = enable;
break;
case WorkersKey: /* workers */
m_workers = enable;
break;
default:
break;
}
return true;
}
bool xmrig::Config::parseString(int key, const char *arg)
{
if (!CommonConfig::parseString(key, arg)) {
return false;
}
switch (key) {
case ModeKey: /* --mode */
setMode(arg);
break;
case BindKey: /* --bind */
{
Addr addr(arg);
if (addr.isValid()) {
m_addrs.push_back(std::move(addr));
}
}
break;
if (i == size - 1 && !strcmp(algo, "cryptonight-light")) {
m_algorithm = CRYPTONIGHT_LITE;
break;
case CoinKey: /* --coin */
// m_pools.back()->setCoin(arg);
break;
case AccessLogFileKey: /* --access-log-file **/
m_accessLog = arg;
break;
case VerboseKey: /* --verbose */
case DebugKey: /* --debug */
return parseBoolean(key, true);
case WorkersKey: /* --no-workers */
return parseBoolean(key, false);
case CustomDiffKey: /* --custom-diff */
return parseUint64(key, strtol(arg, nullptr, 10));
default:
break;
}
return true;
}
bool xmrig::Config::parseUint64(int key, uint64_t arg)
{
if (!CommonConfig::parseUint64(key, arg)) {
return false;
}
switch (key) {
case CustomDiffKey: /* --custom-diff */
if (arg >= 100 && arg < INT_MAX) {
m_diff = arg;
}
break;
case ReuseTimeoutKey: /* --reuse-timeout */
m_reuseTimeout = static_cast<int>(arg);
break;
default:
break;
}
return true;
}
void xmrig::Config::parseJSON(const rapidjson::Document &doc)
{
const rapidjson::Value &bind = doc["bind"];
if (bind.IsArray()) {
for (const rapidjson::Value &value : bind.GetArray()) {
if (!value.IsString()) {
continue;
}
parseString(BindKey, value.GetString());
}
}
}
@@ -278,13 +284,6 @@ void xmrig::Config::setCoin(const char *coin)
}
void xmrig::Config::setFileName(const char *fileName)
{
free(m_fileName);
m_fileName = fileName ? strdup(fileName) : nullptr;
}
void xmrig::Config::setMode(const char *mode)
{
const size_t size = sizeof(modeNames) / sizeof((modeNames)[0]);

View File

@@ -7,7 +7,6 @@
* 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>
*
*
* 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
@@ -30,6 +29,9 @@
#include <vector>
#include "core/CommonConfig.h"
#include "core/utils/c_str.h"
#include "proxy/Addr.h"
#include "rapidjson/fwd.h"
@@ -55,96 +57,58 @@ class IWatcherListener;
* api/worker-id
* pools/
*/
class Config
class Config : public CommonConfig
{
friend class ConfigLoader;
public:
enum Algorithm {
CRYPTONIGHT, /* CryptoNight (Monero) */
CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
};
enum Mode {
NICEHASH_MODE,
SIMPLE_MODE
};
Config();
~Config();
bool isValid() const;
bool reload(const char *json);
bool save();
const char *algoName() const;
const char *modeName() const;
void getJSON(rapidjson::Document &doc);
void getJSON(rapidjson::Document &doc) const override;
static Config *load(int argc, char **argv, IWatcherListener *listener);
inline bool apiIPv6() const { return m_apiIPv6; }
inline bool apiRestricted() const { return m_apiRestricted; }
inline bool background() const { return m_background; }
inline bool colors() const { return m_colors; }
inline bool isDebug() const { return m_debug; }
inline bool syslog() const { return m_syslog; }
inline bool verbose() const { return m_verbose; }
inline bool watch() const { return m_watch && m_fileName; }
inline bool workers() const { return m_workers; }
inline const char *accessLog() const { return m_accessLog; }
inline const char *apiToken() const { return m_apiToken; }
inline const char *apiWorkerId() const { return m_apiWorkerId; }
inline const char *fileName() const { return m_fileName; }
inline const char *logFile() const { return m_logFile; }
inline const char *userAgent() const { return m_userAgent; }
inline const std::vector<Addr*> &addrs() const { return m_addrs; }
inline const std::vector<Url*> &pools() const { return m_pools; }
inline int algorithm() const { return m_algorithm; }
inline int apiPort() const { return m_apiPort; }
inline int donateLevel() const { return m_donateLevel; }
inline bool isVerbose() const { return m_verbose; }
inline bool isWorkers() const { return m_workers; }
inline const char *accessLog() const { return m_accessLog.data(); }
inline const std::vector<Addr> &addrs() const { return m_addrs; }
inline int mode() const { return m_mode; }
inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; }
inline int reuseTimeout() const { return m_reuseTimeout; }
inline uint64_t diff() const { return m_diff; }
inline void setColors(bool colors) { m_colors = colors; }
inline void setVerbose(bool verbose) { m_verbose = verbose; }
inline void toggleVerbose() { m_verbose = !m_verbose; }
protected:
bool adjust() override;
bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override;
void parseJSON(const rapidjson::Document &doc) override;
private:
void adjust();
void setAlgo(const char *algo);
void setCoin(const char *coin);
void setFileName(const char *fileName);
void setMode(const char *mode);
bool m_adjusted;
bool m_apiIPv6;
bool m_apiRestricted;
bool m_background;
bool m_colors;
bool m_debug;
bool m_ready;
bool m_syslog;
bool m_verbose;
bool m_watch;
bool m_workers;
char *m_accessLog;
char *m_apiToken;
char *m_apiWorkerId;
char *m_fileName;
char *m_logFile;
char *m_userAgent;
int m_algorithm;
int m_apiPort;
int m_donateLevel;
int m_mode;
int m_retries;
int m_retryPause;
int m_reuseTimeout;
std::vector<Addr*> m_addrs;
std::vector<Url*> m_pools;
std::vector<Addr> m_addrs;
uint64_t m_diff;
xmrig::c_str m_accessLog;
};

50
src/core/ConfigCreator.h Normal file
View 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 2016-2018 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 __CONFIGCREATOR_H__
#define __CONFIGCREATOR_H__
#include "core/Config.h"
#include "interfaces/IConfigCreator.h"
namespace xmrig {
class IConfig;
class ConfigCreator : public IConfigCreator
{
public:
inline IConfig *create() const override
{
return new Config();
}
};
} /* namespace xmrig */
#endif // __CONFIGCREATOR_H__

View File

@@ -7,7 +7,6 @@
* 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>
*
*
* 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
@@ -33,24 +32,30 @@
#endif
#include "core/Config.h"
#include "core/ConfigCreator.h"
#include "core/ConfigLoader.h"
#include "core/ConfigLoader_static.h"
#include "core/ConfigLoader_platform.h"
#include "core/ConfigWatcher.h"
#include "interfaces/IConfig.h"
#include "interfaces/IWatcherListener.h"
#include "net/Url.h"
#include "net/Pool.h"
#include "Platform.h"
#include "proxy/Addr.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/filereadstream.h"
xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr;
xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr;
xmrig::IConfigCreator *xmrig::ConfigLoader::m_creator = nullptr;
xmrig::IWatcherListener *xmrig::ConfigLoader::m_listener = nullptr;
bool xmrig::ConfigLoader::loadFromFile(xmrig::Config *config, const char *fileName)
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
bool xmrig::ConfigLoader::loadFromFile(xmrig::IConfig *config, const char *fileName)
{
rapidjson::Document doc;
if (!getJSON(fileName, doc)) {
@@ -63,7 +68,7 @@ bool xmrig::ConfigLoader::loadFromFile(xmrig::Config *config, const char *fileNa
}
bool xmrig::ConfigLoader::loadFromJSON(xmrig::Config *config, const char *json)
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const char *json)
{
rapidjson::Document doc;
doc.Parse(json);
@@ -76,7 +81,7 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::Config *config, const char *json)
}
bool xmrig::ConfigLoader::loadFromJSON(xmrig::Config *config, const rapidjson::Document &doc)
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Document &doc)
{
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
parseJSON(config, &config_options[i], doc);
@@ -95,17 +100,6 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::Config *config, const rapidjson::D
}
}
const rapidjson::Value &bind = doc["bind"];
if (bind.IsArray()) {
for (const rapidjson::Value &value : bind.GetArray()) {
if (!value.IsString()) {
continue;
}
parseArg(config, 'b', value.GetString());
}
}
const rapidjson::Value &api = doc["api"];
if (api.IsObject()) {
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
@@ -113,14 +107,16 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::Config *config, const rapidjson::D
}
}
config->parseJSON(doc);
config->adjust();
return config->isValid();
}
bool xmrig::ConfigLoader::reload(xmrig::Config *oldConfig, const char *json)
bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const char *json)
{
xmrig::Config *config = new xmrig::Config();
xmrig::IConfig *config = m_creator->create();
if (!loadFromJSON(config, json)) {
delete config;
@@ -130,7 +126,7 @@ bool xmrig::ConfigLoader::reload(xmrig::Config *oldConfig, const char *json)
config->setFileName(oldConfig->fileName());
const bool saved = config->save();
if (config->watch() && m_watcher && saved) {
if (config->isWatch() && m_watcher && saved) {
delete config;
return true;
@@ -141,11 +137,12 @@ bool xmrig::ConfigLoader::reload(xmrig::Config *oldConfig, const char *json)
}
xmrig::Config *xmrig::ConfigLoader::load(int argc, char **argv, IWatcherListener *listener)
xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *listener)
{
m_creator = creator;
m_listener = listener;
xmrig::Config *config = new xmrig::Config();
xmrig::IConfig *config = m_creator->create();
int key;
while (1) {
@@ -176,13 +173,8 @@ xmrig::Config *xmrig::ConfigLoader::load(int argc, char **argv, IWatcherListener
return nullptr;
}
if (config->m_addrs.empty()) {
config->m_addrs.push_back(new Addr("0.0.0.0:3333"));
config->m_addrs.push_back(new Addr("[::]:3333"));
}
if (config->watch()) {
m_watcher = new xmrig::ConfigWatcher(config->fileName(), listener);
if (config->isWatch()) {
m_watcher = new xmrig::ConfigWatcher(config->fileName(), creator, listener);
}
config->adjust();
@@ -193,6 +185,10 @@ xmrig::Config *xmrig::ConfigLoader::load(int argc, char **argv, IWatcherListener
void xmrig::ConfigLoader::release()
{
delete m_watcher;
delete m_creator;
m_watcher = nullptr;
m_creator = nullptr;
}
@@ -225,254 +221,30 @@ bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc
}
bool xmrig::ConfigLoader::parseArg(xmrig::Config *config, int key, const char *arg)
bool xmrig::ConfigLoader::parseArg(xmrig::IConfig *config, int key, const char *arg)
{
switch (key) {
case 'a': /* --algo */
config->setAlgo(arg);
break;
case 'm': /* --mode */
config->setMode(arg);
break;
case 'b': /* --bind */
{
Addr *addr = new Addr(arg);
if (addr->isValid()) {
config->m_addrs.push_back(addr);
}
else {
delete addr;
}
}
break;
case 'O': /* --userpass */
if (!config->m_pools.back()->setUserpass(arg)) {
return false;
}
break;
case 'o': /* --url */
if (config->m_pools.size() > 1 || config->m_pools[0]->isValid()) {
Url *url = new Url(arg);
if (url->isValid()) {
config->m_pools.push_back(url);
}
else {
delete url;
}
}
else {
config->m_pools[0]->parse(arg);
}
if (!config->m_pools.back()->isValid()) {
return false;
}
break;
case 'u': /* --user */
config->m_pools.back()->setUser(arg);
break;
case 'p': /* --pass */
config->m_pools.back()->setPassword(arg);
break;
case 'C':
config->m_pools.back()->setCoin(arg);
break;
case 'l': /* --log-file */
free(config->m_logFile);
config->m_logFile = strdup(arg);
break;
case 'A': /* --access-log-file **/
free(config->m_accessLog);
config->m_accessLog = strdup(arg);
break;
case 4001: /* --access-token */
free(config->m_apiToken);
config->m_apiToken = strdup(arg);
break;
case 4002: /* --worker-id */
free(config->m_apiWorkerId);
config->m_apiWorkerId = strdup(arg);
break;
case 'r': /* --retries */
case 'R': /* --retry-pause */
case 1010: /* --variant */
case 1102: /* --custom-diff */
case 4000: /* --api-port */
return parseArg(config, key, strtol(arg, nullptr, 10));
case 'B': /* --background */
case 'S': /* --syslog */
case 1100: /* --verbose */
case 1101: /* --debug */
return parseBoolean(config, key, true);
case 1002: /* --no-color */
case 1103: /* --no-workers */
case 1105: /* --no-watch */
case 4004: /* ----api-no-restricted */
case 4003: /* --api-no-ipv6 */
return parseBoolean(config, key, false);
case 1003: /* --donate-level */
if (strncmp(arg, "minemonero.pro", 14) == 0) {
config->m_donateLevel = 0;
}
else {
parseArg(config, key, strtol(arg, nullptr, 10));
}
break;
case 1104: /* --coin */
config->setCoin(arg);
break;
case 'V': /* --version */
case xmrig::IConfig::VersionKey: /* --version */
showVersion();
return false;
case 'h': /* --help */
showUsage(0);
case xmrig::IConfig::HelpKey: /* --help */
showUsage();
return false;
case 'c': /* --config */
case xmrig::IConfig::ConfigKey: /* --config */
loadFromFile(config, arg);
break;
case 1008: /* --user-agent */
free(config->m_userAgent);
config->m_userAgent = strdup(arg);
break;
default:
showUsage(1);
return false;
return config->parseString(key, arg);;
}
return true;
}
bool xmrig::ConfigLoader::parseArg(xmrig::Config *config, int key, uint64_t arg)
{
switch (key) {
case 'r': /* --retries */
if (arg < 1 || arg > 1000) {
showUsage(1);
return false;
}
config->m_retries = (int) arg;
break;
case 'R': /* --retry-pause */
if (arg < 1 || arg > 3600) {
showUsage(1);
return false;
}
config->m_retryPause = (int) arg;
break;
case 1003: /* --donate-level */
if ((int) arg < 0 || arg > 99) {
return true;
}
config->m_donateLevel = (int) arg;
break;
case 1010: /* --variant */
config->m_pools.back()->setVariant((int) arg);
break;
case 4000: /* --api-port */
if (arg <= 65536) {
config->m_apiPort = (int) arg;
}
break;
case 1102: /* --custom-diff */
if (arg >= 100 && arg < INT_MAX) {
config->m_diff = arg;
}
break;
case 1106: /* --reuse-timeout */
config->m_reuseTimeout = (int) arg;
break;
default:
break;
}
return true;
}
bool xmrig::ConfigLoader::parseBoolean(xmrig::Config *config, int key, bool enable)
{
switch (key) {
case 'B': /* --background */
config->m_background = enable;
break;
case 'S': /* --syslog */
config->m_syslog = enable;
break;
case 1002: /* --no-color */
config->m_colors = enable;
break;
case 1100: /* --verbose */
config->m_verbose = enable;
break;
case 1101: /* --debug */
config->m_debug = enable;
break;
case 2000: /* colors */
config->m_colors = enable;
break;
case 1103: /* workers */
config->m_workers = enable;
break;
case 1105: /* watch */
config->m_watch = enable;
break;
case 4003: /* ipv6 */
config->m_apiIPv6 = enable;
case 4004: /* restricted */
config->m_apiRestricted = enable;
default:
break;
}
return true;
}
void xmrig::ConfigLoader::parseJSON(xmrig::Config *config, const struct option *option, const rapidjson::Value &object)
void xmrig::ConfigLoader::parseJSON(xmrig::IConfig *config, const struct option *option, const rapidjson::Value &object)
{
if (!option->name || !object.HasMember(option->name)) {
return;
@@ -480,26 +252,26 @@ void xmrig::ConfigLoader::parseJSON(xmrig::Config *config, const struct option *
const rapidjson::Value &value = object[option->name];
if (option->has_arg && value.IsString()) {
parseArg(config, option->val, value.GetString());
if (option->has_arg) {
if (value.IsString()) {
config->parseString(option->val, value.GetString());
}
else if (value.IsInt64()) {
config->parseUint64(option->val, value.GetUint64());
}
else if (value.IsBool()) {
config->parseBoolean(option->val, value.IsTrue());
}
}
else if (option->has_arg && value.IsInt64()) {
parseArg(config, option->val, value.GetUint64());
}
else if (!option->has_arg && value.IsBool()) {
parseBoolean(config, option->val, value.IsTrue());
else if (value.IsBool()) {
config->parseBoolean(option->val, value.IsTrue());
}
}
void xmrig::ConfigLoader::showUsage(int status)
void xmrig::ConfigLoader::showUsage()
{
if (status) {
fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n");
}
else {
printf(usage);
}
printf(usage);
}

View File

@@ -7,7 +7,6 @@
* 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>
*
*
* 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
@@ -38,31 +37,31 @@ struct option;
namespace xmrig {
class Config;
class ConfigWatcher;
class IConfigCreator;
class IWatcherListener;
class IConfig;
class ConfigLoader
{
public:
static bool loadFromFile(Config *config, const char *fileName);
static bool loadFromJSON(Config *config, const char *json);
static bool loadFromJSON(Config *config, const rapidjson::Document &doc);
static bool reload(Config *oldConfig, const char *json);
static Config *load(int argc, char **argv, IWatcherListener *listener);
static bool loadFromFile(IConfig *config, const char *fileName);
static bool loadFromJSON(IConfig *config, const char *json);
static bool loadFromJSON(IConfig *config, const rapidjson::Document &doc);
static bool reload(IConfig *oldConfig, const char *json);
static IConfig *load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *listener);
static void release();
private:
static bool getJSON(const char *fileName, rapidjson::Document &doc);
static bool parseArg(Config *config, int key, const char *arg);
static bool parseArg(Config *config, int key, uint64_t arg);
static bool parseBoolean(Config *config, int key, bool enable);
static void parseJSON(Config *config, const struct option *option, const rapidjson::Value &object);
static void showUsage(int status);
static bool parseArg(IConfig *config, int key, const char *arg);
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
static void showUsage();
static void showVersion();
static ConfigWatcher *m_watcher;
static IConfigCreator *m_creator;
static IWatcherListener *m_listener;
};

View File

@@ -0,0 +1,173 @@
/* 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 2016-2018 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 __CONFIGLOADER_PLATFORM_H__
#define __CONFIGLOADER_PLATFORM_H__
#ifdef _MSC_VER
# include "getopt/getopt.h"
#else
# include <getopt.h>
#endif
#include "version.h"
#include "interfaces/IConfig.h"
namespace xmrig {
static char const usage[] = "\
Usage: " APP_ID " [OPTIONS]\n\
Options:\n\
-b, --bind=ADDR bind to specified address, example \"0.0.0.0:3333\"\n\
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
-m, --mode=MODE proxy mode, nicehash (default) or simple\n\
-o, --url=URL URL of mining server\n\
-O, --userpass=U:P username:password pair for mining server\n\
-u, --user=USERNAME username for mining server\n\
-p, --pass=PASSWORD password for mining server\n\
-k, --keepalive prevent timeout (need pool support)\n\
-r, --retries=N number of times to retry before switch to backup server (default: 1)\n\
-R, --retry-pause=N time to pause between retries (default: 1 second)\n\
--custom-diff=N override pool diff\n\
--reuse-timeout=N timeout in seconds for reuse pool connections in simple mode\n\
--verbose verbose output\n\
--user-agent=AGENT set custom user-agent string for pool\n\
--no-color disable colored output\n\
--no-workers disable per worker statistics\n\
--variant algorithm PoW variant\n\
--donate-level=N donate level, default 2%%\n\
-B, --background run the miner in the background\n\
-c, --config=FILE load a JSON-format configuration file\n\
--no-watch disable configuration file watching\n\
-l, --log-file=FILE log all output to a file\n"
# ifdef HAVE_SYSLOG_H
"\
-S, --syslog use system log for output messages\n"
# endif
"\
-A --access-log-file=N log all workers access to a file\n\
--api-port=N port for the miner API\n\
--api-access-token=T use Bearer access token for API\n\
--api-worker-id=ID custom worker-id for API\n\
--api-no-ipv6 disable IPv6 support for API\n\
--api-no-restricted enable full remote access (only if API token set)\n\
-h, --help display this help and exit\n\
-V, --version output version information and exit\n\
";
static char const short_options[] = "c:khBp:Px:r:R:s:T:o:u:O:Vl:Sb:A:a:C:m:";
static struct option const options[] = {
{ "access-log-file", 1, nullptr, xmrig::IConfig::AccessLogFileKey },
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey },
{ "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
{ "api-no-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ "api-port", 1, nullptr, xmrig::IConfig::ApiPort },
{ "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
{ "bind", 1, nullptr, xmrig::IConfig::BindKey },
{ "coin", 1, nullptr, xmrig::IConfig::CoinKey },
{ "config", 1, nullptr, xmrig::IConfig::ConfigKey },
{ "custom-diff", 1, nullptr, xmrig::IConfig::CustomDiffKey },
{ "debug", 0, nullptr, xmrig::IConfig::DebugKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
{ "help", 0, nullptr, xmrig::IConfig::HelpKey },
{ "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
{ "no-color", 0, nullptr, xmrig::IConfig::ColorKey },
{ "no-watch", 0, nullptr, xmrig::IConfig::WatchKey },
{ "no-workers", 0, nullptr, xmrig::IConfig::WorkersKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
{ "pool-coin", 1, nullptr, xmrig::IConfig::PoolCoinKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
{ "url", 1, nullptr, xmrig::IConfig::UrlKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "verbose", 0, nullptr, xmrig::IConfig::VerboseKey },
{ "version", 0, nullptr, xmrig::IConfig::VersionKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ "reuse-timeout", 1, nullptr, xmrig::IConfig::ReuseTimeoutKey },
{ "mode", 1, nullptr, xmrig::IConfig::ModeKey },
{ 0, 0, 0, 0 }
};
static struct option const config_options[] = {
{ "access-log-file", 1, nullptr, xmrig::IConfig::AccessLogFileKey },
{ "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey },
{ "background", 0, nullptr, xmrig::IConfig::BackgroundKey },
{ "coin", 1, nullptr, xmrig::IConfig::CoinKey },
{ "colors", 0, nullptr, xmrig::IConfig::ColorKey },
{ "custom-diff", 1, nullptr, xmrig::IConfig::CustomDiffKey },
{ "debug", 0, nullptr, xmrig::IConfig::DebugKey },
{ "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey },
{ "log-file", 1, nullptr, xmrig::IConfig::LogFileKey },
{ "retries", 1, nullptr, xmrig::IConfig::RetriesKey },
{ "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey },
{ "syslog", 0, nullptr, xmrig::IConfig::SyslogKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "verbose", 0, nullptr, xmrig::IConfig::VerboseKey },
{ "watch", 0, nullptr, xmrig::IConfig::WatchKey },
{ "workers", 0, nullptr, xmrig::IConfig::WorkersKey },
{ "reuse-timeout", 1, nullptr, xmrig::IConfig::ReuseTimeoutKey },
{ "mode", 1, nullptr, xmrig::IConfig::ModeKey },
{ 0, 0, 0, 0 }
};
static struct option const pool_options[] = {
{ "url", 1, nullptr, xmrig::IConfig::UrlKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "coin", 1, nullptr, xmrig::IConfig::PoolCoinKey },
{ "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ 0, 0, 0, 0 }
};
static struct option const api_options[] = {
{ "port", 1, nullptr, xmrig::IConfig::ApiPort },
{ "access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
{ "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ 0, 0, 0, 0 }
};
} /* namespace xmrig */
#endif /* __CONFIGLOADER_PLATFORM_H__ */

View File

@@ -54,6 +54,7 @@ Options:\n\
-O, --userpass=U:P username:password pair for mining server\n\
-u, --user=USERNAME username for mining server\n\
-p, --pass=PASSWORD password for mining server\n\
-k, --keepalive prevent timeout (need pool support)\n\
-r, --retries=N number of times to retry before switch to backup server (default: 1)\n\
-R, --retry-pause=N time to pause between retries (default: 1 second)\n\
--custom-diff=N override pool diff\n\
@@ -155,6 +156,7 @@ static struct option const pool_options[] = {
{ "user", 1, nullptr, 'u' },
{ "userpass", 1, nullptr, 'O' },
{ "coin", 1, nullptr, 'C' },
{ "keepalive", 2, nullptr ,'k' },
{ "variant", 1, nullptr, 1010 },
{ 0, 0, 0, 0 }
};

View File

@@ -25,16 +25,17 @@
#include <stdio.h>
#include "core/Config.h"
#include "core/ConfigCreator.h"
#include "core/ConfigLoader.h"
#include "core/ConfigWatcher.h"
#include "interfaces/IWatcherListener.h"
#include "log/Log.h"
xmrig::ConfigWatcher::ConfigWatcher(const char *path, IWatcherListener *listener) :
m_path(strdup(path)),
m_listener(listener)
xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) :
m_creator(creator),
m_listener(listener),
m_path(path)
{
uv_fs_event_init(uv_default_loop(), &m_fsEvent);
uv_timer_init(uv_default_loop(), &m_timer);
@@ -49,8 +50,6 @@ xmrig::ConfigWatcher::~ConfigWatcher()
{
uv_timer_stop(&m_timer);
uv_fs_event_stop(&m_fsEvent);
free(m_path);
}
@@ -79,10 +78,10 @@ void xmrig::ConfigWatcher::queueUpdate()
void xmrig::ConfigWatcher::reload()
{
LOG_WARN("\"%s\" was changed, reloading configuration", m_path);
LOG_WARN("\"%s\" was changed, reloading configuration", m_path.data());
xmrig::Config *config = new xmrig::Config();
ConfigLoader::loadFromFile(config, m_path);
IConfig *config = m_creator->create();
ConfigLoader::loadFromFile(config, m_path.data());
if (!config->isValid()) {
LOG_ERR("reloading failed");
@@ -102,5 +101,5 @@ void xmrig::ConfigWatcher::reload()
void xmrig::ConfigWatcher::start()
{
uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path, 0);
uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path.data(), 0);
}

View File

@@ -28,6 +28,8 @@
#include <stdint.h>
#include <uv.h>
#include "core/utils/c_str.h"
#include "rapidjson/fwd.h"
@@ -37,14 +39,14 @@ struct option;
namespace xmrig {
class Config;
class IConfigCreator;
class IWatcherListener;
class ConfigWatcher
{
public:
ConfigWatcher(const char *path, IWatcherListener *listener);
ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener);
~ConfigWatcher();
private:
@@ -56,10 +58,11 @@ private:
void reload();
void start();
char *m_path;
IConfigCreator *m_creator;
IWatcherListener *m_listener;
uv_fs_event_t m_fsEvent;
uv_timer_t m_timer;
xmrig::c_str m_path;
};

View File

@@ -103,7 +103,7 @@ int xmrig::Controller::init(int argc, char **argv)
Log::init();
Platform::init(config()->userAgent());
if (!config()->background()) {
if (!config()->isBackground()) {
Log::add(new ConsoleLog(this));
}
@@ -112,7 +112,7 @@ int xmrig::Controller::init(int argc, char **argv)
}
# ifdef HAVE_SYSLOG_H
if (config()->syslog()) {
if (config()->isSyslog()) {
Log::add(new SysLog());
}
# endif
@@ -134,13 +134,13 @@ void xmrig::Controller::addListener(IControllerListener *listener)
}
void xmrig::Controller::onNewConfig(Config *config)
void xmrig::Controller::onNewConfig(IConfig *config)
{
xmrig::Config *previousConfig = d_ptr->config;
d_ptr->config = config;
Config *previousConfig = d_ptr->config;
d_ptr->config = static_cast<Config*>(config);
for (xmrig::IControllerListener *listener : d_ptr->listeners) {
listener->onConfigChanged(config, previousConfig);
listener->onConfigChanged(d_ptr->config, previousConfig);
}
delete previousConfig;

View File

@@ -55,7 +55,7 @@ public:
void addListener(IControllerListener *listener);
protected:
void onNewConfig(Config *config) override;
void onNewConfig(IConfig *config) override;
private:
ControllerPrivate *d_ptr;

96
src/core/utils/c_str.h Normal file
View 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 2016-2018 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 __C_STR_H__
#define __C_STR_H__
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
namespace xmrig {
/**
* @brief Simple C string wrapper.
*
* 1. I know about std:string.
* 2. For some reason I prefer don't use std:string in miner, eg because of file size of MSYS2 builds.
*/
class c_str
{
public:
inline c_str() : m_data(nullptr) {}
inline c_str(c_str &&other) { m_data = other.m_data; other.m_data = nullptr; }
inline c_str(const c_str &other) : m_data(nullptr) { set(other.data()); }
inline c_str(const char *str) : m_data(nullptr) { set(str); }
inline ~c_str() { free(m_data); }
inline void set(const char *str)
{
free(m_data);
m_data = str != nullptr ? strdup(str) : nullptr;
}
inline void set(char *str)
{
free(m_data);
m_data = str;
}
inline bool isEqual(const char *str) const
{
return (m_data != nullptr && str != nullptr && strcmp(m_data, str)) || (m_data == nullptr && m_data == nullptr);
}
inline bool isNull() const { return m_data == nullptr; }
inline const char *data() const { return m_data; }
inline size_t size() const { return m_data == nullptr ? 0 : strlen(m_data); }
inline bool operator!=(const c_str &str) const { return !isEqual(str.data()); }
inline bool operator!=(const char *str) const { return !isEqual(str); }
inline bool operator==(const c_str &str) const { return isEqual(str.data()); }
inline bool operator==(const char *str) const { return isEqual(str); }
inline c_str &operator=(char *str) { set(str); return *this; }
inline c_str &operator=(const c_str &str) { set(str.data()); return *this; }
inline c_str &operator=(const char *str) { set(str); return *this; }
private:
char *m_data;
};
} /* namespace xmrig */
#endif /* __C_STR_H__ */

View File

@@ -4,8 +4,8 @@
* 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 2016-2017 XMRig <support@xmrig.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>
*
* 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
@@ -41,7 +41,8 @@
* Choice next donation time, with overime compensation. In proxy no way to use precise donation time.
* You can check actual donation via API.
*/
constexpr const int kDonateLevel = 2;
constexpr const int kDefaultDonateLevel = 2;
constexpr const int kMinimumDonateLevel = 0;
#endif /* __DONATE_H__ */

109
src/interfaces/IConfig.h Normal file
View File

@@ -0,0 +1,109 @@
/* 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 2016-2018 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 __ICONFIG_H__
#define __ICONFIG_H__
#include "rapidjson/fwd.h"
namespace xmrig {
class IConfig
{
public:
enum Keys {
// common
AlgorithmKey = 'a',
ApiPort = 4000,
ApiAccessTokenKey = 4001,
ApiWorkerIdKey = 4002,
ApiIPv6Key = 4003,
ApiRestrictedKey = 4004,
BackgroundKey = 'B',
ConfigKey = 'c',
DonateLevelKey = 1003,
HelpKey = 'h',
KeepAliveKey = 'k',
LogFileKey = 'l',
ColorKey = 1002,
WatchKey = 1105,
PasswordKey = 'p',
RetriesKey = 'r',
RetryPauseKey = 'R',
SyslogKey = 'S',
UrlKey = 'o',
UserKey = 'u',
UserAgentKey = 1008,
UserpassKey = 'O',
VerboseKey = 1100,
VersionKey = 'V',
VariantKey = 1010,
// xmrig common
CPUPriorityKey = 1021,
NicehashKey = 1006,
PrintTimeKey = 1007,
// xmrig cpu
AVKey = 'v',
CPUAffinityKey = 1020,
DryRunKey = 5000,
HugePagesKey = 1009,
MaxCPUUsageKey = 1004,
SafeKey = 1005,
ThreadsKey = 't',
// xmrig-proxy
AccessLogFileKey = 'A',
BindKey = 'b',
CoinKey = 1104,
CustomDiffKey = 1102,
DebugKey = 1101,
ModeKey = 'm',
PoolCoinKey = 'C',
ReuseTimeoutKey = 1106,
WorkersKey = 1103,
};
virtual ~IConfig() {}
virtual bool adjust() = 0;
virtual bool isValid() const = 0;
virtual bool isWatch() const = 0;
virtual bool parseBoolean(int key, bool enable) = 0;
virtual bool parseString(int key, const char *arg) = 0;
virtual bool parseUint64(int key, uint64_t arg) = 0;
virtual bool save() = 0;
virtual const char *fileName() const = 0;
virtual void getJSON(rapidjson::Document &doc) const = 0;
virtual void parseJSON(const rapidjson::Document &doc) = 0;
virtual void setFileName(const char *fileName) = 0;
};
} /* namespace xmrig */
#endif // __ICONFIG_H__

View 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 2016-2018 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 __ICONFIGCREATOR_H__
#define __ICONFIGCREATOR_H__
namespace xmrig {
class IConfig;
class IConfigCreator
{
public:
virtual ~IConfigCreator() {}
virtual IConfig *create() const = 0;
};
} /* namespace xmrig */
#endif // __ICONFIGCREATOR_H__

View File

@@ -4,8 +4,8 @@
* 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 2016-2018 XMRig <support@xmrig.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>
*
* 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
@@ -28,7 +28,7 @@
namespace xmrig {
class Config;
class IConfig;
class IWatcherListener
@@ -36,7 +36,7 @@ class IWatcherListener
public:
virtual ~IWatcherListener() {}
virtual void onNewConfig(Config *config) = 0;
virtual void onNewConfig(IConfig *config) = 0;
};

View File

@@ -78,7 +78,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
# endif
const char* color = nullptr;
const bool colors = m_controller->config()->colors();
const bool colors = m_controller->config()->isColors();
if (colors) {
switch (level) {
@@ -122,7 +122,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
void ConsoleLog::text(const char* fmt, va_list args)
{
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->colors() ? Log::kCL_N : "");
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->isColors() ? Log::kCL_N : "");
print(args);
}

View File

@@ -77,13 +77,13 @@ void ShareLog::onRejectedEvent(IEvent *event)
bool ShareLog::isColors() const
{
return m_controller->config()->colors();
return m_controller->config()->isColors();
}
void ShareLog::accept(const AcceptEvent *event)
{
if (!m_controller->config()->verbose()) {
if (!m_controller->config()->isVerbose()) {
return;
}

View File

@@ -32,7 +32,6 @@
#include "interfaces/IClientListener.h"
#include "log/Log.h"
#include "net/Client.h"
#include "net/Url.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
@@ -52,6 +51,7 @@
int64_t Client::m_sequence = 1;
xmrig::Storage<Client> Client::m_storage;
Client::Client(int id, const char *agent, IClientListener *listener) :
@@ -67,13 +67,17 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_state(UnconnectedState),
m_expire(0),
m_jobs(0),
m_keepAlive(0),
m_key(0),
m_stream(nullptr),
m_socket(nullptr)
{
m_key = m_storage.add(this);
memset(m_ip, 0, sizeof(m_ip));
memset(&m_hints, 0, sizeof(m_hints));
m_resolver.data = this;
m_resolver.data = m_storage.ptr(m_key);
m_hints.ai_family = AF_UNSPEC;
m_hints.ai_socktype = SOCK_STREAM;
@@ -81,11 +85,6 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_recvBuf.base = m_buf;
m_recvBuf.len = sizeof(m_buf);
# ifndef XMRIG_PROXY_PROJECT
m_keepAliveTimer.data = this;
uv_timer_init(uv_default_loop(), &m_keepAliveTimer);
# endif
}
@@ -97,7 +96,7 @@ Client::~Client()
void Client::connect()
{
resolve(m_url.host());
resolve(m_pool.host());
}
@@ -106,10 +105,10 @@ void Client::connect()
*
* @param url
*/
void Client::connect(const Url *url)
void Client::connect(const Pool &url)
{
setUrl(url);
resolve(m_url.host());
setPool(url);
connect();
}
@@ -122,34 +121,34 @@ void Client::deleteLater()
m_listener = nullptr;
if (!disconnect()) {
delete this;
m_storage.remove(m_key);
}
}
void Client::setUrl(const Url *url)
void Client::setPool(const Pool &pool)
{
if (!url || !url->isValid()) {
if (!pool.isValid()) {
return;
}
m_url = url;
m_pool = pool;
}
void Client::tick(uint64_t now)
{
if (m_expire == 0 || now < m_expire) {
return;
}
if (m_state == ConnectedState) {
LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port());
close();
if (m_expire && now > m_expire) {
LOG_DEBUG_ERR("[%s] timeout", m_pool.url());
close();
}
else if (m_keepAlive && now > m_keepAlive) {
ping();
}
}
if (m_state == ConnectingState) {
if (m_expire && now > m_expire && m_state == ConnectingState) {
connect();
}
}
@@ -157,12 +156,9 @@ void Client::tick(uint64_t now)
bool Client::disconnect()
{
# ifndef XMRIG_PROXY_PROJECT
uv_timer_stop(&m_keepAliveTimer);
# endif
m_expire = 0;
m_failures = -1;
m_keepAlive = 0;
m_expire = 0;
m_failures = -1;
return close();
}
@@ -205,28 +201,7 @@ bool Client::close()
setState(ClosingState);
uv_stream_t *stream = reinterpret_cast<uv_stream_t*>(m_socket);
if (uv_is_readable(stream) == 1) {
uv_read_stop(stream);
}
if (uv_is_writable(stream) == 1) {
const int rc = uv_shutdown(new uv_shutdown_t, stream, [](uv_shutdown_t* req, int status) {
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(req->handle)) == 0) {
uv_close(reinterpret_cast<uv_handle_t*>(req->handle), Client::onClose);
}
delete req;
});
assert(rc == 0);
if (rc != 0) {
onClose();
}
}
else {
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
}
@@ -264,11 +239,10 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
}
# ifdef XMRIG_PROXY_PROJECT
Job job(m_id, m_url.variant());
Job job(m_id, m_pool.variant());
job.setClientId(m_rpcId);
job.setCoin(m_url.coin());
# else
Job job(m_id, m_nicehash, m_url.algo(), m_url.variant());
Job job(m_id, m_nicehash, m_pool.algo(), m_pool.variant());
# endif
if (!job.setId(params["job_id"].GetString())) {
@@ -305,7 +279,7 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
}
if (!m_quiet) {
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
LOG_WARN("[%s] duplicate job received, reconnect", m_pool.url());
}
close();
@@ -321,7 +295,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
}
# ifndef XMRIG_PROXY_PROJECT
m_nicehash = m_url.isNicehash();
m_nicehash = m_pool.isNicehash();
# endif
if (result.HasMember("extensions")) {
@@ -349,7 +323,7 @@ int Client::resolve(const char *host)
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints);
if (r) {
if (!m_quiet) {
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r));
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r));
}
return 1;
}
@@ -360,9 +334,9 @@ int Client::resolve(const char *host)
int64_t Client::send(size_t size)
{
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf);
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf);
if (state() != ConnectedState || !uv_is_writable(m_stream)) {
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state);
return -1;
}
@@ -400,14 +374,14 @@ void Client::connect(sockaddr *addr)
{
setState(ConnectingState);
reinterpret_cast<struct sockaddr_in*>(addr)->sin_port = htons(m_url.port());
reinterpret_cast<sockaddr_in*>(addr)->sin_port = htons(m_pool.port());
delete m_socket;
uv_connect_t *req = new uv_connect_t;
req->data = this;
req->data = m_storage.ptr(m_key);
m_socket = new uv_tcp_t;
m_socket->data = this;
m_socket->data = m_storage.ptr(m_key);
uv_tcp_init(uv_default_loop(), m_socket);
uv_tcp_nodelay(m_socket, 1);
@@ -434,9 +408,9 @@ void Client::login()
doc.AddMember("method", "login", allocator);
rapidjson::Value params(rapidjson::kObjectType);
params.AddMember("login", rapidjson::StringRef(m_url.user()), allocator);
params.AddMember("pass", rapidjson::StringRef(m_url.password()), allocator);
params.AddMember("agent", rapidjson::StringRef(m_agent), allocator);
params.AddMember("login", rapidjson::StringRef(m_pool.user()), allocator);
params.AddMember("pass", rapidjson::StringRef(m_pool.password()), allocator);
params.AddMember("agent", rapidjson::StringRef(m_agent), allocator);
doc.AddMember("params", params, allocator);
@@ -475,11 +449,11 @@ void Client::parse(char *line, size_t len)
line[len - 1] = '\0';
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
LOG_DEBUG("[%s] received (%d bytes): \"%s\"", m_pool.url(), len, line);
if (len < 32 || line[0] != '{') {
if (!m_quiet) {
LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
LOG_ERR("[%s] JSON decode failed", m_pool.url());
}
return;
@@ -488,7 +462,7 @@ void Client::parse(char *line, size_t len)
rapidjson::Document doc;
if (doc.ParseInsitu(line).HasParseError()) {
if (!m_quiet) {
LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), rapidjson::GetParseError_En(doc.GetParseError()));
LOG_ERR("[%s] JSON decode failed: \"%s\"", m_pool.url(), rapidjson::GetParseError_En(doc.GetParseError()));
}
return;
@@ -530,7 +504,7 @@ void Client::parseNotification(const char *method, const rapidjson::Value &param
{
if (error.IsObject()) {
if (!m_quiet) {
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), error["message"].GetString(), error["code"].GetInt());
LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), error["message"].GetString(), error["code"].GetInt());
}
return;
}
@@ -548,7 +522,7 @@ void Client::parseNotification(const char *method, const rapidjson::Value &param
return;
}
LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method);
LOG_WARN("[%s] unsupported method: \"%s\"", m_pool.url(), method);
}
@@ -564,10 +538,10 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
m_results.erase(it);
}
else if (!m_quiet) {
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt());
LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), message, error["code"].GetInt());
}
if (id == 1 || isCriticalError(message)) {
if (isCriticalError(message)) {
close();
}
@@ -582,7 +556,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
int code = -1;
if (!parseLogin(result, &code)) {
if (!m_quiet) {
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
LOG_ERR("[%s] login error code: %d", m_pool.url(), code);
}
close();
@@ -613,18 +587,13 @@ void Client::ping()
void Client::reconnect()
{
if (!m_listener) {
delete this;
m_storage.remove(m_key);
return;
}
setState(ConnectingState);
# ifndef XMRIG_PROXY_PROJECT
if (m_url.isKeepAlive()) {
uv_timer_stop(&m_keepAliveTimer);
}
# endif
m_keepAlive = 0;
if (m_failures == -1) {
return m_listener->onClose(this, -1);
@@ -639,7 +608,7 @@ void Client::reconnect()
void Client::setState(SocketState state)
{
LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state);
LOG_DEBUG("[%s] state: %d", m_pool.url(), state);
if (m_state == state) {
return;
@@ -653,13 +622,9 @@ void Client::startTimeout()
{
m_expire = 0;
# ifndef XMRIG_PROXY_PROJECT
if (!m_url.isKeepAlive()) {
return;
if (m_pool.keepAlive()) {
m_keepAlive = uv_now(uv_default_loop()) + (m_pool.keepAlive() * 1000);
}
uv_timer_start(&m_keepAliveTimer, [](uv_timer_t *handle) { getClient(handle->data)->ping(); }, kKeepAliveTimeout, 0);
# endif
}
@@ -690,12 +655,13 @@ void Client::onConnect(uv_connect_t *req, int status)
{
auto client = getClient(req->data);
if (!client) {
delete req;
return;
}
if (status < 0) {
if (!client->m_quiet) {
LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
LOG_ERR("[%s] connect error: \"%s\"", client->m_pool.url(), uv_strerror(status));
}
delete req;
@@ -723,7 +689,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
if (nread < 0) {
if (nread != UV_EOF && !client->m_quiet) {
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread));
LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread));
}
client->close();
@@ -735,6 +701,11 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
return;
}
assert(client->m_listener != nullptr);
if (!client->m_listener) {
return client->reconnect();
}
client->m_recvBufPos += nread;
char* end;
@@ -771,9 +742,14 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
return;
}
assert(client->m_listener != nullptr);
if (!client->m_listener) {
return client->reconnect();
}
if (status < 0) {
if (!client->m_quiet) {
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
LOG_ERR("[%s] DNS error: \"%s\"", client->m_pool.url(), uv_strerror(status));
}
return client->reconnect();
@@ -797,7 +773,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
if (ipv4.empty() && ipv6.empty()) {
if (!client->m_quiet) {
LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port());
LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_pool.url());
}
uv_freeaddrinfo(res);

View File

@@ -32,8 +32,9 @@
#include "net/Id.h"
#include "net/Job.h"
#include "net/Storage.h"
#include "net/SubmitResult.h"
#include "net/Url.h"
#include "net/Pool.h"
#include "rapidjson/fwd.h"
@@ -53,31 +54,29 @@ public:
};
constexpr static int kResponseTimeout = 20 * 1000;
constexpr static int kKeepAliveTimeout = 60 * 1000;
Client(int id, const char *agent, IClientListener *listener);
~Client();
bool disconnect();
int64_t submit(const JobResult &result);
void connect();
void connect(const Url *url);
void connect(const Pool &pool);
void deleteLater();
void setUrl(const Url *url);
void setPool(const Pool &pool);
void tick(uint64_t now);
inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; }
inline const char *host() const { return m_url.host(); }
inline const char *host() const { return m_pool.host(); }
inline const char *ip() const { return m_ip; }
inline const Job &job() const { return m_job; }
inline int id() const { return m_id; }
inline SocketState state() const { return m_state; }
inline uint16_t port() const { return m_url.port(); }
inline uint16_t port() const { return m_pool.port(); }
inline void setQuiet(bool quiet) { m_quiet = quiet; }
inline void setRetryPause(int ms) { m_retryPause = ms; }
private:
~Client();
bool close();
bool isCriticalError(const char *message);
bool parseJob(const rapidjson::Value &params, int *code);
@@ -103,7 +102,7 @@ private:
static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
static void onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res);
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
static inline Client *getClient(void *data) { return m_storage.get(data); }
addrinfo m_hints;
bool m_ipv6;
@@ -118,22 +117,22 @@ private:
int m_retryPause;
int64_t m_failures;
Job m_job;
Pool m_pool;
size_t m_recvBufPos;
SocketState m_state;
static int64_t m_sequence;
std::map<int64_t, SubmitResult> m_results;
uint64_t m_expire;
uint64_t m_jobs;
Url m_url;
uint64_t m_keepAlive;
uintptr_t m_key;
uv_buf_t m_recvBuf;
uv_getaddrinfo_t m_resolver;
uv_stream_t *m_stream;
uv_tcp_t *m_socket;
xmrig::Id m_rpcId;
# ifndef XMRIG_PROXY_PROJECT
uv_timer_t m_keepAliveTimer;
# endif
static int64_t m_sequence;
static xmrig::Storage<Client> m_storage;
};

261
src/net/Pool.cpp Normal file
View File

@@ -0,0 +1,261 @@
/* 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 2016-2018 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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "net/Pool.h"
#ifdef _MSC_VER
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
#endif
static const char *algoNames[] = {
"cryptonight",
"cryptonight-lite",
"cryptonight-heavy"
};
static const char *algoNamesShort[] = {
"cn",
"cn-lite",
"cn-heavy"
};
Pool::Pool() :
m_nicehash(false),
m_keepAlive(0),
m_port(kDefaultPort),
m_algo(xmrig::CRYPTONIGHT),
m_variant(xmrig::VARIANT_AUTO)
{
}
/**
* @brief Parse url.
*
* Valid urls:
* example.com
* example.com:3333
* stratum+tcp://example.com
* stratum+tcp://example.com:3333
*
* @param url
*/
Pool::Pool(const char *url) :
m_nicehash(false),
m_keepAlive(0),
m_port(kDefaultPort),
m_algo(xmrig::CRYPTONIGHT),
m_variant(xmrig::VARIANT_AUTO)
{
parse(url);
}
Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, xmrig::Variant variant) :
m_nicehash(nicehash),
m_keepAlive(keepAlive),
m_port(port),
m_algo(xmrig::CRYPTONIGHT),
m_host(host),
m_password(password),
m_user(user),
m_variant(variant)
{
const size_t size = m_host.size() + 8;
assert(size > 8);
char *url = new char[size]();
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
m_url = url;
}
const char *Pool::algoName(xmrig::Algo algorithm)
{
return algoNames[algorithm];
}
xmrig::Algo Pool::algorithm(const char *algo)
{
if (strcasecmp(algo, "cryptonight-light") == 0) {
fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n");
return xmrig::CRYPTONIGHT_LITE;
}
const size_t size = sizeof(algoNames) / sizeof(algoNames[0]);
assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0])));
for (size_t i = 0; i < size; i++) {
if (strcasecmp(algo, algoNames[i]) == 0 || strcasecmp(algo, algoNamesShort[i]) == 0) {
return static_cast<xmrig::Algo>(i);
}
}
return xmrig::CRYPTONIGHT;
}
bool Pool::parse(const char *url)
{
assert(url != nullptr);
const char *p = strstr(url, "://");
const char *base = url;
if (p) {
if (strncasecmp(url, "stratum+tcp://", 14)) {
return false;
}
base = url + 14;
}
if (!strlen(base) || *base == '/') {
return false;
}
m_url = url;
if (base[0] == '[') {
return parseIPv6(base);
}
const char *port = strchr(base, ':');
if (!port) {
m_host = base;
return true;
}
const size_t size = port++ - base + 1;
char *host = new char[size]();
memcpy(host, base, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port, nullptr, 10));
return true;
}
bool Pool::setUserpass(const char *userpass)
{
const char *p = strchr(userpass, ':');
if (!p) {
return false;
}
char *user = new char[p - userpass + 1]();
strncpy(user, userpass, p - userpass);
m_user = user;
m_password = p + 1;
return true;
}
void Pool::adjust(xmrig::Algo algo)
{
if (!isValid()) {
return;
}
m_algo = algo;
if (strstr(m_host.data(), ".nicehash.com")) {
m_keepAlive = false;
m_nicehash = true;
}
if (strstr(m_host.data(), ".minergate.com")) {
m_keepAlive = false;
}
}
void Pool::setVariant(int variant)
{
switch (variant) {
case xmrig::VARIANT_AUTO:
case xmrig::VARIANT_NONE:
case xmrig::VARIANT_V1:
m_variant = static_cast<xmrig::Variant>(variant);
break;
default:
assert(false);
break;
}
}
bool Pool::isEqual(const Pool &other) const
{
return (m_nicehash == other.m_nicehash
&& m_keepAlive == other.m_keepAlive
&& m_port == other.m_port
&& m_algo == other.m_algo
&& m_host == other.m_host
&& m_password == other.m_password
&& m_url == other.m_url
&& m_user == other.m_user
&& m_variant == other.m_variant);
}
bool Pool::parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return false;
}
const char *port = strchr(end, ':');
if (!port) {
return false;
}
const size_t size = end - addr;
char *host = new char[size]();
memcpy(host, addr + 1, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port + 1, nullptr, 10));
return true;
}

96
src/net/Pool.h Normal file
View 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 2016-2018 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 __POOL_H__
#define __POOL_H__
#include <stdint.h>
#include "core/utils/c_str.h"
#include "xmrig.h"
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;
Pool();
Pool(const char *url);
Pool(const char *host,
uint16_t port,
const char *user = nullptr,
const char *password = nullptr,
int keepAlive = 0,
bool nicehash = false,
xmrig::Variant variant = xmrig::VARIANT_AUTO
);
static const char *algoName(xmrig::Algo algorithm);
static xmrig::Algo algorithm(const char *algo);
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
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 *url() const { return m_url.data(); }
inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; }
inline int keepAlive() const { return m_keepAlive; }
inline uint16_t port() const { return m_port; }
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
inline void setPassword(const char *password) { m_password = password; }
inline void setUser(const char *user) { m_user = user; }
inline xmrig::Algo algo() const { return m_algo; }
inline xmrig::Variant variant() const { return m_variant; }
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
inline bool operator==(const Pool &other) const { return isEqual(other); }
bool parse(const char *url);
bool setUserpass(const char *userpass);
void adjust(xmrig::Algo algo);
void setVariant(int variant);
bool isEqual(const Pool &other) const;
private:
bool parseIPv6(const char *addr);
bool m_nicehash;
int m_keepAlive;
uint16_t m_port;
xmrig::Algo m_algo;
xmrig::c_str m_host;
xmrig::c_str m_password;
xmrig::c_str m_url;
xmrig::c_str m_user;
xmrig::Variant m_variant;
};
#endif /* __POOL_H__ */

97
src/net/Storage.h Normal file
View 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 2016-2018 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 __STORAGE_H__
#define __STORAGE_H__
#include <assert.h>
#include <map>
#include "log/Log.h"
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(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(void *id) { remove(reinterpret_cast<uintptr_t>(id)); }
inline void remove(uintptr_t id)
{
TYPE *obj = get(id);
if (obj == nullptr) {
return;
}
auto it = m_data.find(id);
if (it != m_data.end()) {
m_data.erase(it);
}
delete obj;
}
private:
std::map<uintptr_t, TYPE *> m_data;
uint64_t m_counter;
};
} /* namespace xmrig */
#endif /* __STORAGE_H__ */

View File

@@ -1,293 +0,0 @@
/* 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 2016-2018 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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "core/Config.h"
#include "net/Url.h"
#include "xmrig.h"
#ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
Url::Url() :
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
m_coin(""),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(kDefaultPort)
{
}
/**
* @brief Parse url.
*
* Valid urls:
* example.com
* example.com:3333
* stratum+tcp://example.com
* stratum+tcp://example.com:3333
*
* @param url
*/
Url::Url(const char *url) :
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
m_coin(""),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(kDefaultPort)
{
parse(url);
}
Url::Url(const char *host, uint16_t port, const char *user, const char *password) :
m_password(password ? strdup(password) : nullptr),
m_user(user ? strdup(user) : nullptr),
m_coin(""),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(port)
{
m_host = strdup(host);
}
Url::~Url()
{
free(m_host);
free(m_password);
free(m_user);
if (m_url) {
delete [] m_url;
}
}
bool Url::parse(const char *url)
{
const char *p = strstr(url, "://");
const char *base = url;
if (p) {
if (strncasecmp(url, "stratum+tcp://", 14)) {
return false;
}
base = url + 14;
}
if (!strlen(base) || *base == '/') {
return false;
}
if (base[0] == '[') {
return parseIPv6(base);
}
const char *port = strchr(base, ':');
if (!port) {
m_host = strdup(base);
return false;
}
const size_t size = port++ - base + 1;
m_host = new char[size]();
memcpy(m_host, base, size - 1);
m_port = (uint16_t) strtol(port, nullptr, 10);
return true;
}
bool Url::setUserpass(const char *userpass)
{
const char *p = strchr(userpass, ':');
if (!p) {
return false;
}
free(m_user);
free(m_password);
m_user = static_cast<char*>(calloc(p - userpass + 1, 1));
strncpy(m_user, userpass, p - userpass);
m_password = strdup(p + 1);
return true;
}
const char *Url::url() const
{
if (!m_url) {
const size_t size = strlen(m_host) + 8;
m_url = new char[size];
snprintf(m_url, size - 1, "%s:%d", m_host, m_port);
}
return m_url;
}
void Url::adjust(int algorithm)
{
if (!isValid()) {
return;
}
if (strlen(m_coin) == 0) {
if (algorithm == xmrig::Config::CRYPTONIGHT) {
memcpy(m_coin, "XMR", 4);
}
else {
memcpy(m_coin, "AEON", 5);
}
}
}
void Url::setCoin(const char *coin)
{
if (!coin || strlen(coin) > 4) {
return;
}
strncpy(m_coin, coin, sizeof(m_coin));
char *s = m_coin;
while (*s) {
*s = toupper((unsigned char) *s);
s++;
}
}
void Url::setPassword(const char *password)
{
if (!password) {
return;
}
free(m_password);
m_password = strdup(password);
}
void Url::setUser(const char *user)
{
if (!user) {
return;
}
free(m_user);
m_user = strdup(user);
}
void Url::setVariant(int variant)
{
switch (variant) {
case xmrig::VARIANT_AUTO:
case xmrig::VARIANT_NONE:
case xmrig::VARIANT_V1:
m_variant = variant;
break;
default:
break;
}
}
bool Url::operator==(const Url &other) const
{
if (m_port != other.m_port || m_variant != other.m_variant) {
return false;
}
if (strcmp(host(), other.host()) != 0 || strcmp(user(), other.user()) != 0 || strcmp(password(), other.password()) != 0 || strcmp(coin(), other.coin()) != 0) {
return false;
}
return true;
}
Url &Url::operator=(const Url *other)
{
m_port = other->m_port;
m_variant = other->m_variant;
free(m_host);
m_host = strdup(other->m_host);
setPassword(other->m_password);
setUser(other->m_user);
memcpy(m_coin, other->coin(), sizeof(m_coin));
if (m_url) {
delete [] m_url;
m_url = nullptr;
}
return *this;
}
bool Url::parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return false;
}
const char *port = strchr(end, ':');
if (!port) {
return false;
}
const size_t size = end - addr;
m_host = new char[size]();
memcpy(m_host, addr + 1, size - 1);
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
return true;
}

View File

@@ -1,75 +0,0 @@
/* 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 2016-2018 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 __URL_H__
#define __URL_H__
#include <stdint.h>
class Url
{
public:
constexpr static const char *kDefaultPassword = "x";
constexpr static const char *kDefaultUser = "x";
constexpr static uint16_t kDefaultPort = 3333;
Url();
Url(const char *url);
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr);
~Url();
inline bool isValid() const { return m_host && m_port > 0; }
inline const char *coin() const { return m_coin; }
inline const char *host() const { return m_host; }
inline const char *password() const { return m_password ? m_password : kDefaultPassword; }
inline const char *user() const { return m_user ? m_user : kDefaultUser; }
inline int variant() const { return m_variant; }
inline uint16_t port() const { return m_port; }
bool parse(const char *url);
bool setUserpass(const char *userpass);
const char *url() const;
void adjust(int algorithm);
void setCoin(const char *coin);
void setPassword(const char *password);
void setUser(const char *user);
void setVariant(int variant);
bool operator==(const Url &other) const;
Url &operator=(const Url *other);
private:
bool parseIPv6(const char *addr);
char *m_host;
char *m_password;
char *m_user;
char m_coin[5];
int m_variant;
mutable char *m_url;
uint16_t m_port;
};
#endif /* __URL_H__ */

View File

@@ -29,6 +29,7 @@
#include "net/strategies/DonateStrategy.h"
#include "Platform.h"
#include "proxy/StatsData.h"
#include "xmrig.h"
extern "C"
@@ -54,19 +55,28 @@ DonateStrategy::DonateStrategy(size_t id, xmrig::Controller *controller, IStrate
{
uint8_t hash[200];
char userId[65] = { 0 };
const char *user = controller->config()->pools().front()->user();
const char *user = controller->config()->pools().front().user();
keccak(reinterpret_cast<const uint8_t *>(user), static_cast<int>(strlen(user)), hash, sizeof(hash));
Job::toHex(hash, 32, userId);
Url *url = new Url("proxy.fee.xmrig.com", controller->config()->algorithm() == xmrig::Config::CRYPTONIGHT_LITE ? 7777 : 4444, userId, nullptr);
uint16_t port = 4444;
switch (controller->config()->algorithm()) {
case xmrig::CRYPTONIGHT_LITE:
port = 7777;
break;
case xmrig::CRYPTONIGHT_HEAVY:
port = 8887;
default:
break;
}
m_client = new Client(-1, Platform::userAgent(), this);
m_client->setUrl(url);
m_client->setPool(Pool("proxy.fee.xmrig.com", port, userId, nullptr));
m_client->setRetryPause(1000);
delete url;
m_target = random(3000, 9000);
}

View File

@@ -28,7 +28,7 @@
#include "Platform.h"
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
FailoverStrategy::FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
m_quiet(quiet),
m_retries(retries),
m_retryPause(retryPause),
@@ -36,7 +36,7 @@ FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause
m_index(0),
m_listener(listener)
{
for (const Url *url : urls) {
for (const Pool &url : urls) {
add(url);
}
}
@@ -153,10 +153,10 @@ void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &resu
}
void FailoverStrategy::add(const Url *url)
void FailoverStrategy::add(const Pool &pool)
{
Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this);
client->setUrl(url);
client->setPool(pool);
client->setRetryPause(m_retryPause * 1000);
client->setQuiet(m_quiet);

View File

@@ -30,6 +30,7 @@
#include "interfaces/IClientListener.h"
#include "interfaces/IStrategy.h"
#include "net/Pool.h"
class Client;
@@ -40,7 +41,7 @@ class Url;
class FailoverStrategy : public IStrategy, public IClientListener
{
public:
FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
~FailoverStrategy();
public:
@@ -59,7 +60,7 @@ protected:
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
private:
void add(const Url *url);
void add(const Pool &pool);
const bool m_quiet;
const int m_retries;

View File

@@ -28,12 +28,12 @@
#include "Platform.h"
SinglePoolStrategy::SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet) :
SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) :
m_active(false),
m_listener(listener)
{
m_client = new Client(0, Platform::userAgent(), this);
m_client->setUrl(url);
m_client->setPool(pool);
m_client->setRetryPause(retryPause * 1000);
m_client->setQuiet(quiet);
}

View File

@@ -37,7 +37,7 @@ class Url;
class SinglePoolStrategy : public IStrategy, public IClientListener
{
public:
SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet = false);
SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet = false);
~SinglePoolStrategy();
public:

View File

@@ -30,6 +30,9 @@
#include <stdlib.h>
#include "core/utils/c_str.h"
class Addr
{
public:
@@ -37,18 +40,15 @@ public:
inline Addr() :
m_addr(nullptr),
m_ip(nullptr),
m_version(0),
m_port(0)
{}
inline Addr(const char *addr) :
m_addr(strdup(addr)),
m_ip(nullptr),
m_version(0),
m_port(0)
m_port(0),
m_addr(addr)
{
if (!addr || strlen(addr) < 5) {
return;
@@ -63,17 +63,10 @@ public:
}
inline ~Addr()
{
delete [] m_addr;
delete [] m_ip;
}
inline bool isIPv6() const { return m_version == 6; }
inline bool isValid() const { return m_version && m_ip && m_port > 0; }
inline const char *addr() const { return m_addr; }
inline const char *ip() const { return m_ip; }
inline bool isValid() const { return m_version && !m_ip.isNull() && m_port > 0; }
inline const char *addr() const { return m_addr.data(); }
inline const char *ip() const { return m_ip.data(); }
inline uint16_t port() const { return m_port; }
private:
@@ -86,10 +79,11 @@ private:
m_version = 4;
const size_t size = port++ - addr + 1;
m_ip = new char[size]();
memcpy(m_ip, addr, size - 1);
char *ip = new char[size]();
memcpy(ip, addr, size - 1);
m_port = (uint16_t) strtol(port, nullptr, 10);
m_ip = ip;
m_port = static_cast<uint16_t>(strtol(port, nullptr, 10));
}
@@ -107,17 +101,18 @@ private:
m_version = 6;
const size_t size = end - addr;
m_ip = new char[size]();
memcpy(m_ip, addr + 1, size - 1);
char *ip = new char[size]();
memcpy(ip, addr + 1, size - 1);
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
m_ip = ip;
m_port = static_cast<uint16_t>(strtol(port + 1, nullptr, 10));
}
char *m_addr;
char *m_ip;
int m_version;
uint16_t m_port;
xmrig::c_str m_addr;
xmrig::c_str m_ip;
};
#endif /* __ADDR_H__ */

View File

@@ -123,8 +123,8 @@ void Proxy::connect()
{
m_splitter->connect();
const std::vector<Addr*> &addrs = m_controller->config()->addrs();
for (const Addr *addr : addrs) {
const std::vector<Addr> &addrs = m_controller->config()->addrs();
for (const Addr &addr : addrs) {
bind(addr);
}
@@ -190,11 +190,11 @@ void Proxy::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig
bool Proxy::isColors() const
{
return m_controller->config()->colors();
return m_controller->config()->isColors();
}
void Proxy::bind(const Addr *addr)
void Proxy::bind(const Addr &addr)
{
auto server = new Server(addr, m_controller->config()->mode() == xmrig::Config::NICEHASH_MODE);
@@ -215,8 +215,8 @@ void Proxy::gc()
void Proxy::print()
{
LOG_INFO(isColors() ? "\x1B[01;36m%03.2f kH/s\x1B[0m, shares: \x1B[01;37m%" PRIu64 "\x1B[0m/%s%" PRIu64 "\x1B[0m +%" PRIu64 ", upstreams: \x1B[01;37m%u\x1B[0m, miners: \x1B[01;37m%" PRIu64 "\x1B[0m (max \x1B[01;37m%" PRIu64 "\x1B[0m) +%u/-%u"
: "%03.2f kH/s, shares: %" PRIu64 "/%s%" PRIu64 " +%" PRIu64 ", upstreams: %u, miners: %" PRIu64 " (max %" PRIu64 " +%u/-%u",
LOG_INFO(isColors() ? "\x1B[01;36m%03.2f kH/s\x1B[0m, shares: \x1B[01;37m%" PRIu64 "\x1B[0m/%s%" PRIu64 "\x1B[0m +%" PRIu64 ", upstreams: \x1B[01;37m%" PRIu64 "\x1B[0m, miners: \x1B[01;37m%" PRIu64 "\x1B[0m (max \x1B[01;37m%" PRIu64 "\x1B[0m) +%u/-%u"
: "%03.2f kH/s, shares: %" PRIu64 "/%s%" PRIu64 " +%" PRIu64 ", upstreams: %" PRIu64 ", miners: %" PRIu64 " (max %" PRIu64 " +%u/-%u",
m_stats.hashrate(60), m_stats.data().accepted, isColors() ? (m_stats.data().rejected ? "\x1B[31m" : "\x1B[01;37m") : "", m_stats.data().rejected,
Counters::accepted, m_splitter->upstreams().active, Counters::miners(), Counters::maxMiners(), Counters::added(), Counters::removed());

View File

@@ -79,8 +79,7 @@ private:
constexpr static int kGCInterval = 60;
bool isColors() const;
void bind(const Addr *addr);
void bind(const char *ip, uint16_t port, bool ipv6);
void bind(const Addr &addr);
void gc();
void print();
void tick();

View File

@@ -29,34 +29,28 @@
#include "proxy/Server.h"
Server::Server(const Addr *addr, bool nicehash) :
Server::Server(const Addr &addr, bool nicehash) :
m_nicehash(nicehash),
m_ip(strdup(addr->ip())),
m_version(0),
m_port(addr->port())
m_port(addr.port()),
m_ip(addr.ip())
{
uv_tcp_init(uv_default_loop(), &m_server);
m_server.data = this;
uv_tcp_nodelay(&m_server, 1);
if (addr->isIPv6() && uv_ip6_addr(m_ip, m_port, &m_addr6) == 0) {
if (addr.isIPv6() && uv_ip6_addr(m_ip.data(), m_port, &m_addr6) == 0) {
m_version = 6;
return;
}
if (uv_ip4_addr(m_ip, m_port, &m_addr) == 0) {
if (uv_ip4_addr(m_ip.data(), m_port, &m_addr) == 0) {
m_version = 4;
}
}
Server::~Server()
{
free(m_ip);
}
bool Server::bind()
{
if (!m_version) {
@@ -68,7 +62,7 @@ bool Server::bind()
const int r = uv_listen(reinterpret_cast<uv_stream_t*>(&m_server), 511, Server::onConnection);
if (r) {
LOG_ERR("[%s:%u] listen error: \"%s\"", m_ip, m_port, uv_strerror(r));
LOG_ERR("[%s:%u] listen error: \"%s\"", m_ip.data(), m_port, uv_strerror(r));
return false;
}
@@ -79,7 +73,7 @@ bool Server::bind()
void Server::create(uv_stream_t *server, int status)
{
if (status < 0) {
LOG_ERR("[%s:%u] new connection error: \"%s\"", m_ip, m_port, uv_strerror(status));
LOG_ERR("[%s:%u] new connection error: \"%s\"", m_ip.data(), m_port, uv_strerror(status));
return;
}

View File

@@ -28,14 +28,16 @@
#include <uv.h>
#include "core/utils/c_str.h"
class Addr;
class Server
{
public:
Server(const Addr *addr, bool nicehash);
~Server();
Server(const Addr &addr, bool nicehash);
bool bind();
private:
@@ -44,12 +46,12 @@ private:
static void onConnection(uv_stream_t *server, int status);
bool m_nicehash;
char *m_ip;
int m_version;
sockaddr_in m_addr;
sockaddr_in6 m_addr6;
uint16_t m_port;
uv_tcp_t m_server;
xmrig::c_str m_ip;
};
#endif /* __SERVER_H__ */

View File

@@ -4,8 +4,8 @@
* 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 2016-2017 XMRig <support@xmrig.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>
*
* 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
@@ -21,8 +21,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <uuid/uuid.h>
#ifdef __FreeBSD__
# include <uuid.h>
#else
# include <uuid/uuid.h>
#endif
#include "proxy/Uuid.h"
@@ -30,6 +33,12 @@
void Uuid::create(char *out, size_t size)
{
uuid_t id;
# ifdef __FreeBSD__
uuid_create(&id, nullptr);
uuid_to_string(&id, &out, nullptr);
# else
uuid_generate(id);
uuid_unparse_lower(id, out);
# endif
}

View File

@@ -34,7 +34,6 @@
#include "net/strategies/DonateStrategy.h"
#include "net/strategies/FailoverStrategy.h"
#include "net/strategies/SinglePoolStrategy.h"
#include "net/Url.h"
#include "proxy/Counters.h"
#include "proxy/Error.h"
#include "proxy/events/AcceptEvent.h"
@@ -106,7 +105,7 @@ void NonceMapper::gc()
}
void NonceMapper::reload(const std::vector<Url*> &pools)
void NonceMapper::reload(const std::vector<Pool> &pools)
{
delete m_pending;
@@ -183,7 +182,7 @@ void NonceMapper::onActive(IStrategy *strategy, Client *client)
m_pending = nullptr;
}
if (m_controller->config()->verbose()) {
if (m_controller->config()->isVerbose()) {
LOG_INFO(isColors() ? "#%03u \x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "#%03u use pool %s:%d %s",
m_id, client->host(), client->port(), client->ip());
}
@@ -192,7 +191,7 @@ void NonceMapper::onActive(IStrategy *strategy, Client *client)
void NonceMapper::onJob(IStrategy *strategy, Client *client, const Job &job)
{
if (m_controller->config()->verbose()) {
if (m_controller->config()->isVerbose()) {
LOG_INFO(isColors() ? "#%03u \x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d" : "#%03u new job from %s:%d diff %d",
m_id, client->host(), client->port(), job.diff());
}
@@ -236,11 +235,11 @@ void NonceMapper::onResultAccepted(IStrategy *strategy, Client *client, const Su
bool NonceMapper::isColors() const
{
return m_controller->config()->colors();
return m_controller->config()->isColors();
}
IStrategy *NonceMapper::createStrategy(const std::vector<Url*> &pools)
IStrategy *NonceMapper::createStrategy(const std::vector<Pool> &pools)
{
if (pools.size() > 1) {
return new FailoverStrategy(pools, m_controller->config()->retryPause(), m_controller->config()->retries(), this);

View File

@@ -32,6 +32,7 @@
#include "interfaces/IStrategyListener.h"
#include "net/Job.h"
#include "net/Pool.h"
class DonateStrategy;
@@ -71,7 +72,7 @@ public:
bool add(Miner *miner, const LoginRequest &request);
bool isActive() const;
void gc();
void reload(const std::vector<Url*> &pools);
void reload(const std::vector<Pool> &pools);
void remove(const Miner *miner);
void start();
void submit(SubmitEvent *event);
@@ -92,7 +93,7 @@ protected:
private:
bool isColors() const;
IStrategy *createStrategy(const std::vector<Url*> &pools);
IStrategy *createStrategy(const std::vector<Pool> &pools);
SubmitCtx submitCtx(int64_t seq);
void connect();
void suspend();

View File

@@ -27,7 +27,6 @@
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "net/Url.h"
#include "proxy/Counters.h"
#include "proxy/events/CloseEvent.h"
#include "proxy/events/LoginEvent.h"
@@ -41,11 +40,6 @@
#define LABEL(x) " \x1B[01;30m" x ":\x1B[0m "
static bool compare(Url *i, Url *j) {
return *i == *j;
}
NonceSplitter::NonceSplitter(xmrig::Controller *controller) : Splitter(controller)
{
}
@@ -104,7 +98,7 @@ void NonceSplitter::printConnections()
{
const Upstreams info = upstreams();
if (m_controller->config()->colors()) {
if (m_controller->config()->isColors()) {
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("sleep") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("error") "%s%" PRIu64 "\x1B[0m" LABEL("total") "\x1B[01;37m%" PRIu64,
info.active ? "\x1B[01;32m" : "\x1B[01;31m", info.active, info.sleep, info.error ? "\x1B[01;31m" : "\x1B[01;37m", info.error, info.total);
@@ -143,10 +137,10 @@ void NonceSplitter::printState()
void NonceSplitter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
const std::vector<Url*> &pools = config->pools();
const std::vector<Url*> &previousPools = previousConfig->pools();
const std::vector<Pool> &pools = config->pools();
const std::vector<Pool> &previousPools = previousConfig->pools();
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin(), compare)) {
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin())) {
Summary::printPools(config);
for (NonceMapper *mapper : m_upstreams) {

View File

@@ -34,7 +34,6 @@
#include "net/strategies/DonateStrategy.h"
#include "net/strategies/FailoverStrategy.h"
#include "net/strategies/SinglePoolStrategy.h"
#include "net/Url.h"
#include "proxy/Counters.h"
#include "proxy/Error.h"
#include "proxy/events/AcceptEvent.h"
@@ -78,7 +77,7 @@ void SimpleMapper::add(Miner *miner, const LoginRequest &request)
}
void SimpleMapper::reload(const std::vector<Url*> &pools)
void SimpleMapper::reload(const std::vector<Pool> &pools)
{
delete m_pending;
@@ -102,6 +101,20 @@ void SimpleMapper::reuse(Miner *miner, const LoginRequest &request)
}
void SimpleMapper::stop()
{
m_strategy->stop();
if (m_pending) {
m_pending->stop();
}
if (m_donate) {
m_donate->stop();
}
}
void SimpleMapper::submit(SubmitEvent *event)
{
if (!isActive()) {
@@ -152,7 +165,7 @@ void SimpleMapper::onActive(IStrategy *strategy, Client *client)
m_pending = nullptr;
}
if (m_controller->config()->verbose()) {
if (m_controller->config()->isVerbose()) {
LOG_INFO(isColors() ? "#%03u \x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "#%03u use pool %s:%d %s",
m_id, client->host(), client->port(), client->ip());
}
@@ -161,7 +174,7 @@ void SimpleMapper::onActive(IStrategy *strategy, Client *client)
void SimpleMapper::onJob(IStrategy *strategy, Client *client, const Job &job)
{
if (m_controller->config()->verbose()) {
if (m_controller->config()->isVerbose()) {
LOG_INFO(isColors() ? "#%03u \x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d" : "#%03u new job from %s:%d diff %d",
m_id, client->host(), client->port(), job.diff());
}
@@ -201,7 +214,7 @@ void SimpleMapper::onResultAccepted(IStrategy *strategy, Client *client, const S
bool SimpleMapper::isColors() const
{
return m_controller->config()->colors();
return m_controller->config()->isColors();
}
@@ -220,7 +233,7 @@ bool SimpleMapper::isValidJobId(const xmrig::Id &id) const
}
IStrategy *SimpleMapper::createStrategy(const std::vector<Url*> &pools)
IStrategy *SimpleMapper::createStrategy(const std::vector<Pool> &pools)
{
if (pools.size() > 1) {
return new FailoverStrategy(pools, m_controller->config()->retryPause(), m_controller->config()->retries(), this);

View File

@@ -32,6 +32,7 @@
#include "interfaces/IStrategyListener.h"
#include "net/Job.h"
#include "net/Pool.h"
class DonateStrategy;
@@ -57,9 +58,10 @@ public:
~SimpleMapper();
void add(Miner *miner, const LoginRequest &request);
void reload(const std::vector<Url*> &pools);
void reload(const std::vector<Pool> &pools);
void remove(const Miner *miner);
void reuse(Miner *miner, const LoginRequest &request);
void stop();
void submit(SubmitEvent *event);
void tick(uint64_t ticks, uint64_t now);
@@ -77,7 +79,7 @@ protected:
private:
bool isColors() const;
bool isValidJobId(const xmrig::Id &id) const;
IStrategy *createStrategy(const std::vector<Url*> &pools);
IStrategy *createStrategy(const std::vector<Pool> &pools);
void connect();
void setJob(const Job &job);

View File

@@ -27,7 +27,6 @@
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "net/Url.h"
#include "Platform.h"
#include "proxy/Counters.h"
#include "proxy/events/CloseEvent.h"
@@ -42,11 +41,6 @@
#define LABEL(x) " \x1B[01;30m" x ":\x1B[0m "
static bool compare(Url *i, Url *j) {
return *i == *j;
}
SimpleSplitter::SimpleSplitter(xmrig::Controller *controller) : Splitter(controller),
m_reuseTimeout(controller->config()->reuseTimeout()),
m_sequence(0)
@@ -87,7 +81,7 @@ void SimpleSplitter::printConnections()
{
const Upstreams info = upstreams();
if (m_controller->config()->colors()) {
if (m_controller->config()->isColors()) {
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("sleep") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("error") "%s%" PRIu64 "\x1B[0m" LABEL("total") "\x1B[01;37m%" PRIu64,
info.active ? "\x1B[01;32m" : "\x1B[01;31m", info.active, info.sleep, info.error ? "\x1B[01;31m" : "\x1B[01;37m", info.error, m_upstreams.size());
@@ -107,26 +101,27 @@ void SimpleSplitter::printConnections()
void SimpleSplitter::tick(uint64_t ticks)
{
const uint64_t now = uv_now(uv_default_loop());
std::vector<SimpleMapper *> released;
for (SimpleMapper *mapper : m_released) {
delete mapper;
}
m_released.clear();
for (auto const &kv : m_upstreams) {
if (kv.second->idleTime() > m_reuseTimeout) {
released.push_back(kv.second);
m_released.push_back(kv.second);
continue;
}
kv.second->tick(ticks, now);
}
if (released.empty()) {
if (m_released.empty()) {
return;
}
for (SimpleMapper *mapper : released) {
removeIdle(mapper->id());
removeUpstream(mapper->id());
delete mapper;
for (SimpleMapper *mapper : m_released) {
stop(mapper);
}
}
@@ -142,10 +137,10 @@ void SimpleSplitter::onConfigChanged(xmrig::Config *config, xmrig::Config *previ
{
m_reuseTimeout = config->reuseTimeout();
const std::vector<Url*> &pools = config->pools();
const std::vector<Url*> &previousPools = previousConfig->pools();
const std::vector<Pool> &pools = config->pools();
const std::vector<Pool> &previousPools = previousConfig->pools();
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin(), compare)) {
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin())) {
Summary::printPools(config);
for (auto const &kv : m_upstreams) {
@@ -197,6 +192,15 @@ void SimpleSplitter::login(LoginEvent *event)
}
void SimpleSplitter::stop(SimpleMapper *mapper)
{
removeIdle(mapper->id());
removeUpstream(mapper->id());
mapper->stop();
}
void SimpleSplitter::remove(Miner *miner)
{
const ssize_t id = miner->mapperId();
@@ -209,9 +213,9 @@ void SimpleSplitter::remove(Miner *miner)
mapper->remove(miner);
if (m_reuseTimeout == 0) {
removeUpstream(id);
stop(mapper);
delete mapper;
m_released.push_back(mapper);
}
else {
m_idles[id] = mapper;

View File

@@ -25,8 +25,9 @@
#define __SIMPLESPLITTER_H__
#include <stdint.h>
#include <map>
#include <stdint.h>
#include <vector>
#include "proxy/splitters/Splitter.h"
@@ -71,10 +72,12 @@ private:
void remove(Miner *miner);
void removeIdle(uint64_t id);
void removeUpstream(uint64_t id);
void stop(SimpleMapper *mapper);
void submit(SubmitEvent *event);
std::map<uint64_t, SimpleMapper *> m_idles;
std::map<uint64_t, SimpleMapper *> m_upstreams;
std::vector<SimpleMapper *> m_released;
uint64_t m_reuseTimeout;
uint64_t m_sequence;
};

View File

@@ -38,7 +38,7 @@
Workers::Workers(xmrig::Controller *controller) :
m_enabled(controller->config()->workers()),
m_enabled(controller->config()->isWorkers()),
m_controller(controller)
{
}
@@ -60,7 +60,7 @@ void Workers::printWorkers()
char workerName[24];
size_t size = 0;
Log::i()->text(m_controller->config()->colors() ? "\x1B[01;37m%-23s | %-15s | %-5s | %-8s | %-3s | %11s | %11s |" : "%-23s | %-15s | %-5s | %-8s | %-3s | %11s | %11s |",
Log::i()->text(m_controller->config()->isColors() ? "\x1B[01;37m%-23s | %-15s | %-5s | %-8s | %-3s | %11s | %11s |" : "%-23s | %-15s | %-5s | %-8s | %-3s | %11s | %11s |",
"WORKER NAME", "LAST IP", "COUNT", "ACCEPTED", "REJ", "10 MINUTES", "24 HOURS");
for (const Worker &worker : m_workers) {

View File

@@ -27,7 +27,7 @@
#define APP_ID "xmrig-proxy"
#define APP_NAME "xmrig-proxy"
#define APP_DESC "XMRig Stratum proxy"
#define APP_VERSION "2.5.2"
#define APP_VERSION "2.5.3"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com"
@@ -35,7 +35,7 @@
#define APP_VER_MAJOR 2
#define APP_VER_MINOR 5
#define APP_VER_BUILD 2
#define APP_VER_BUILD 3
#define APP_VER_REV 0
#ifdef _MSC_VER

View File

@@ -30,18 +30,40 @@ namespace xmrig
enum Algo {
ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */
ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
CRYPTONIGHT, /* CryptoNight (Monero) */
CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */
};
//--av=1 For CPUs with hardware AES.
//--av=2 Lower power mode (double hash) of 1.
//--av=3 Software AES implementation.
//--av=4 Lower power mode (double hash) of 3.
enum AlgoVariant {
AV_AUTO, // --av=0 Automatic mode.
AV_SINGLE, // --av=1 Single hash mode
AV_DOUBLE, // --av=2 Double hash mode
AV_SINGLE_SOFT, // --av=3 Single hash mode (Software AES)
AV_DOUBLE_SOFT, // --av=4 Double hash mode (Software AES)
AV_TRIPLE, // --av=5 Triple hash mode
AV_QUAD, // --av=6 Quard hash mode
AV_PENTA, // --av=7 Penta hash mode
AV_TRIPLE_SOFT, // --av=8 Triple hash mode (Software AES)
AV_QUAD_SOFT, // --av=9 Quard hash mode (Software AES)
AV_PENTA_SOFT, // --av=10 Penta hash mode (Software AES)
AV_MAX
};
enum Variant {
VARIANT_AUTO = -1,
VARIANT_NONE = 0,
VARIANT_V1 = 1
VARIANT_AUTO = -1, // Autodetect
VARIANT_NONE = 0, // Original CryptoNight
VARIANT_V1 = 1 // Monero v7 PoW
};
} /* xmrig */
} /* namespace xmrig */
#endif /* __XMRIG_H__ */