mirror of
https://github.com/xmrig/xmrig-proxy.git
synced 2026-02-18 07:22:26 +08:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74c6c14dee | ||
|
|
ca8ba5ec81 | ||
|
|
95e9962b34 | ||
|
|
987edca758 | ||
|
|
9745130545 | ||
|
|
799a4f0c54 | ||
|
|
1523e2fe6f | ||
|
|
5100b60192 | ||
|
|
ab74319afe | ||
|
|
27831e4eb6 | ||
|
|
7a89ff9e0a | ||
|
|
15f104ac47 | ||
|
|
08355390d1 | ||
|
|
0d7bd43b44 | ||
|
|
e06c44902d | ||
|
|
0092f741f2 | ||
|
|
0c6f414a74 | ||
|
|
5992167dde | ||
|
|
694446bb72 | ||
|
|
75e4943cba | ||
|
|
53f28f99ed | ||
|
|
74dd286a38 | ||
|
|
1fd8dfee98 |
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
133
doc/STRATUM.md
Normal 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
101
doc/STRATUM_EXT.md
Normal 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
|
||||
@@ -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':
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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, ¶m);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
332
src/core/CommonConfig.cpp
Normal 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
105
src/core/CommonConfig.h
Normal 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__ */
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
50
src/core/ConfigCreator.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 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__
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
173
src/core/ConfigLoader_platform.h
Normal file
173
src/core/ConfigLoader_platform.h
Normal 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__ */
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
96
src/core/utils/c_str.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 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__ */
|
||||
@@ -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
109
src/interfaces/IConfig.h
Normal 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__
|
||||
45
src/interfaces/IConfigCreator.h
Normal file
45
src/interfaces/IConfigCreator.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 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__
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ¶ms, 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 ¶ms, 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 ¶m
|
||||
{
|
||||
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 ¶m
|
||||
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);
|
||||
|
||||
@@ -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 ¶ms, 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
261
src/net/Pool.cpp
Normal 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
96
src/net/Pool.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 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
97
src/net/Storage.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 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__ */
|
||||
293
src/net/Url.cpp
293
src/net/Url.cpp
@@ -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;
|
||||
}
|
||||
@@ -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__ */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
34
src/xmrig.h
34
src/xmrig.h
@@ -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__ */
|
||||
|
||||
Reference in New Issue
Block a user