Compare commits

..

69 Commits

Author SHA1 Message Date
xmrig
1080379350 Update README.md 2018-03-26 12:34:05 +07:00
XMRig
ffe5fa7af9 v2.5.2 2018-03-26 12:24:22 +07:00
XMRig
8036e3dfa9 Fixed totally broken reconnect. 2018-03-26 12:09:19 +07:00
xmrig
1b573ba99d Update README.md 2018-03-25 14:23:23 +07:00
XMRig
3b82aad213 #148 Fixed build without API. 2018-03-25 10:45:38 +07:00
XMRig
dc42d4b862 v2.5.0 release candidate 2018-03-24 14:24:48 +07:00
XMRig
b52c3effa1 Merge branch 'dev' 2018-03-24 14:19:05 +07:00
XMRig
f35e1fbbb8 Removed unused private field in FailoverStrategy class. 2018-03-24 14:03:33 +07:00
XMRig
a5672912e6 Merge branch 'dev' of github.com:xmrig/xmrig-proxy into dev 2018-03-24 13:47:45 +07:00
XMRig
48c72526a7 Removed unused private field in FailoverStrategy class. 2018-03-24 13:47:22 +07:00
xmrig
cde94e04c5 Update README.md 2018-03-23 23:45:52 +07:00
XMRig
2ad6ff8acf Fix DonateStrategy and disable donation for simple mode. 2018-03-23 23:33:43 +07:00
XMRig
35f4eff2db Print pools summary if pools changed. 2018-03-23 19:29:23 +07:00
XMRig
c0d3e2306d Information about upstreams extended in new API endpoint GET /1/summary. 2018-03-23 13:53:58 +07:00
XMRig
1ea7ce452f Added new example config.json. 2018-03-22 21:14:29 +07:00
xmrig
344f59d4a0 Update CHANGELOG.md 2018-03-22 18:11:57 +07:00
XMRig
da967ced1b Add IP address to accepted and rejected shares in proxy output. 2018-03-22 17:45:47 +07:00
XMRig
0263beb009 * Don't use dual stack for incoming connections and fix ip detection in IPv6 mode. 2018-03-22 12:51:13 +07:00
XMRig
79f580df4b Messages use pool now shown only in verbose mode. 2018-03-22 08:55:43 +07:00
xmrig
4fb3ea6e60 Update CHANGELOG.md 2018-03-22 08:25:49 +07:00
XMRig
9efeb4a9b0 Added alternative working mode. 2018-03-22 07:54:08 +07:00
XMRig
883ac25b03 Unify FailoverStrategy and SinglePoolStrategy with recent miner code. 2018-03-18 09:20:57 +07:00
XMRig
4b8b045d6c Merge branch 'dev' of github.com:xmrig/xmrig-proxy into dev 2018-03-14 23:19:11 +07:00
XMRig
2b190c30b9 #135 Added missing xmrig.h 2018-03-14 23:18:38 +07:00
xmrig
bb9bfd970f Update CHANGELOG.md 2018-03-13 20:40:46 +07:00
XMRig
2e392069c2 Add option variant to config JSON output. 2018-03-13 20:36:44 +07:00
XMRig
636800fdac Enable IPv6 by default, replace command line option --api-ipv6 to --api-no-ipv6. 2018-03-13 20:34:59 +07:00
XMRig
7738b54de5 Added option variant. 2018-03-13 20:17:34 +07:00
XMRig
d8333c0ce8 Added per pool specified coin option. 2018-03-08 22:41:48 +07:00
XMRig
84041c8ef5 Fix crash. 2018-03-07 22:59:08 +07:00
XMRig
f2c14e9425 Added nicehash extension. 2018-03-07 22:10:07 +07:00
xmrig
e5ba679fe2 Update CHANGELOG.md 2018-03-06 15:18:24 +07:00
XMRig
f04995f67c Safe delete suspended upstreams. 2018-03-06 14:55:49 +07:00
XMRig
47153da760 Fix build with old libmicrohttpd. 2018-03-05 14:14:14 +07:00
XMRig
1bad050ec1 Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy parsed incorrectly. 2018-03-05 14:07:21 +07:00
XMRig
c32f5ca12a #113 Fixed bug when handle expired shares after pool switch. 2018-03-05 01:58:13 +07:00
XMRig
880f777f4a Update CMakeLists.txt. 2018-03-04 11:49:06 +07:00
XMRig
747c6087be Added "PUT /1/config" API endpoint. 2018-03-04 11:45:47 +07:00
XMRig
385eef78ac Fix error in previous commit. 2018-03-01 23:49:30 +07:00
XMRig
f7907829ce IPv6 now fully supported for connections to upstream pools. 2018-03-01 20:44:48 +07:00
XMRig
2689016a45 Added IPv6 support for bind. 2018-03-01 17:10:03 +07:00
XMRig
2f937eada6 Added command line option --api-ipv6 and similar config option to enable IPv6 support for HTTP API. 2018-03-01 12:20:01 +07:00
XMRig
c1e3f72b5b Remove unused commented code. 2018-03-01 10:59:43 +07:00
XMRig
22071348de Merge branch 'dev' of github.com:xmrig/xmrig-proxy into dev 2018-02-28 23:31:34 +07:00
XMRig
a64cfb0d94 Use adaptive timer instead of idle handler for HTTP server. 2018-02-28 22:18:02 +07:00
xmrig
c9ae1b91bd Update CHANGELOG.md 2018-02-28 12:42:21 +07:00
XMRig
fd813fff4b Added dynamic config reload support, pools and some other settings now can changed without proxy restart. 2018-02-28 12:28:28 +07:00
XMRig
669d45e575 Fixed regression, since v2.4.0 not compatible miners wasn't force disconnected. 2018-02-26 12:49:35 +07:00
XMRig
e03005a85f Remove .travis.yml 2018-02-20 22:50:01 +07:00
XMRig
537d5ae28e Run internal http server in main loop to avoid requirement to thread synchronization. 2018-02-20 22:46:53 +07:00
XMRig
3c7077130d Merge branch 'master' into dev 2018-02-20 22:42:40 +07:00
XMRig
6dfb662d0a Merge branch 'master' of github.com:xmrig/xmrig-proxy 2018-02-19 04:35:20 +07:00
XMRig
8d5f4b63d2 v2.4.5 RC 2018-02-19 04:34:57 +07:00
xmrig
0d342aed29 Update README.md 2018-02-19 04:19:37 +07:00
XMRig
4bd95cad19 #109 Hashrate reports now more detailed for low speed workers. 2018-02-19 01:00:22 +07:00
XMRig
c8da934297 Fixed, in some cases proxy was doesn't write log to stdout. 2018-02-18 16:42:01 +07:00
xmrig
b26d8001a3 Update README.md 2018-02-18 05:52:25 +07:00
xmrig
ee59665c21 Merge pull request #104 from DeadManWalkingTO/master
Update README.md
2018-02-18 05:51:49 +07:00
xmrig
ca95a45773 Update README.md 2018-02-18 05:06:44 +07:00
DeadManWalking
dcca3fd7f6 Update README.md 2018-02-02 01:07:57 +02:00
XMRig
d681854964 Fixed 32bit build without SSE2. 2018-01-12 13:48:22 +07:00
xmrig
64628e41ac Update CHANGELOG.md 2018-01-12 13:33:04 +07:00
XMRig
437909e4e9 #70 Use kH/s instead of KH/s 2018-01-10 16:08:26 +07:00
XMRig
3e7f690387 Update year. 2018-01-10 15:50:28 +07:00
XMRig
81b08fbcc7 Sync changes with xmrig miner.
* Add libmicrohttpd version to --version output.
* Fix recent MSVC 2017 version detection.
* Remove extra semicolon.
* Add missing stdio header.
* Reduce cmake version requirement to 2.8.
2018-01-10 15:42:02 +07:00
XMRig
3fdc2f4af6 Fix wrong signal handle. 2018-01-04 13:14:27 +07:00
xmrig
63d5431d00 Update README.md 2018-01-02 19:07:32 +07:00
XMRig
23b8d9e6fa #37 Fixed ARM build. 2017-11-05 22:02:37 +03:00
XMRig
1ea65898e7 Add missing colors option to config.json. 2017-11-05 04:34:40 +03:00
94 changed files with 4674 additions and 1549 deletions

View File

@@ -1,70 +0,0 @@
dist: trusty
osx_image: xcode8.3
sudo: false
language: cpp
addons:
apt:
packages: &default_packages
- cmake
- libuv-dev
- uuid-dev
matrix:
include:
- os: linux
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- *default_packages
- gcc-5
- g++-5
env:
- CMAKE_CXX_COMPILER=g++-5
- CMAKE_C_COMPILER=gcc-5
- os: linux
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- *default_packages
- gcc-6
- g++-6
env:
- CMAKE_CXX_COMPILER=g++-6
- CMAKE_C_COMPILER=gcc-6
- os: linux
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- *default_packages
- gcc-7
- g++-7
env:
- CMAKE_CXX_COMPILER=g++-7
- CMAKE_C_COMPILER=gcc-7
- os: osx
compiler: gcc
script:
- if [ $TRAVIS_OS_NAME = osx ]; then
brew install libuv;
cmake .;
else
cmake -D CMAKE_C_COMPILER=${CMAKE_C_COMPILER} -D CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} .;
fi;
- make

View File

@@ -1,3 +1,42 @@
# v2.5.2
- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect.
# v2.5.0
- [#119](https://github.com/xmrig/xmrig-proxy/issues/119) Added graceful reload support, pools and some other settings now can changed without proxy restart.
- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/miner was parsed incorrectly.
- [#40](https://github.com/xmrig/xmrig-proxy/issues/40#issuecomment-370202169) Added API endpoint `PUT /1/config` to update current config.
- [#118](https://github.com/xmrig/xmrig-proxy/issues/118#issuecomment-375172833) Added alternative working mode, in that mode proxy support chaining and nicehash.com but lose ability to reduce connection count.
- Added API endpoint `GET /1/config` to get current active config.
- Messages `use pool` now shown only in verbose mode.
- Added IPv6 support:
- IPv6 now fully supported for connections to upstream pools.
- `bind` now accept IPv6 addresses, for example, use `[::]:3333` to bind on all IPv6 interfaces and port 3333.
- Internal HTTP server now support IPv6 for incoming connections.
- New command line options (with equivalent config file options):
- Added `--mode` to switch working mode.
- Added `--reuse-timeout` to set timeout in seconds for reuse pool connections in simple mode.
- Added `--no-watch` and config option `watch` to disable config file watching.
- Added `--variant` to override PoW settings on xmrig miners.
- Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API.
- Added `--algo` to specify algorithm cryptonight or cryptonight-lite.
- Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified.
- Deprecations:
- Option `coin` now deprecated, use `algo` instead.
- API endpoint `GET /` now deprecated, use `GET /1/summary` instead.
- API endpoint `GET /workers.json`, use `GET /1/workers` instead.
# v2.4.5
- [#109](https://github.com/xmrig/xmrig-proxy/issues/109) Hashrate reports now more detailed for low speed workers.
- [#200](https://github.com/xmrig/xmrig/issues/200) In some cases proxy was doesn't write log to stdout.
# v2.4.4
- Added libmicrohttpd version to --version output.
- Fixed bug in singal handler, in some cases proxy wasn't shutdown properly.
- Fixed recent MSVC 2017 version detection.
- Fixed in default `config.json` was missing option `colors`.
- [#37](https://github.com/xmrig/xmrig-proxy/issues/37) Fixed ARM build.
- [#70](https://github.com/xmrig/xmrig-proxy/issues/70) Now used kH/s instead of KH/s.
# v2.4.2
- [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com.

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 2.8)
project(xmrig-proxy)
@@ -11,31 +11,36 @@ include (CheckIncludeFile)
set(HEADERS
src/3rdparty/align.h
src/api/Api.h
src/api/ApiState.h
src/App.h
src/Console.h
src/core/Config.h
src/core/ConfigLoader.h
src/core/ConfigLoader_static.h
src/core/ConfigWatcher.h
src/core/Controller.h
src/donate.h
src/interfaces/IClientListener.h
src/interfaces/IConsoleListener.h
src/interfaces/IControllerListener.h
src/interfaces/IEvent.h
src/interfaces/IEventListener.h
src/interfaces/ILogBackend.h
src/interfaces/ISplitter.h
src/interfaces/IStrategy.h
src/interfaces/IStrategyListener.h
src/interfaces/IWatcherListener.h
src/log/AccessLog.h
src/log/ConsoleLog.h
src/log/FileLog.h
src/log/Log.h
src/log/ShareLog.h
src/net/Client.h
src/net/Id.h
src/net/Job.h
src/net/JobId.h
src/net/strategies/DonateStrategy.h
src/net/strategies/FailoverStrategy.h
src/net/strategies/SinglePoolStrategy.h
src/net/Url.h
src/Options.h
src/Platform.h
src/proxy/Addr.h
src/proxy/Counters.h
@@ -55,9 +60,12 @@ set(HEADERS
src/proxy/Proxy.h
src/proxy/ProxyDebug.h
src/proxy/Server.h
src/proxy/splitters/NonceMapper.h
src/proxy/splitters/NonceSplitter.h
src/proxy/splitters/NonceStorage.h
src/proxy/splitters/nicehash/NonceMapper.h
src/proxy/splitters/nicehash/NonceSplitter.h
src/proxy/splitters/nicehash/NonceStorage.h
src/proxy/splitters/simple/SimpleMapper.h
src/proxy/splitters/simple/SimpleSplitter.h
src/proxy/splitters/Splitter.h
src/proxy/Stats.h
src/proxy/StatsData.h
src/proxy/TickingCounter.h
@@ -66,13 +74,16 @@ set(HEADERS
src/proxy/workers/Workers.h
src/Summary.h
src/version.h
src/xmrig.h
)
set(SOURCES
src/api/Api.cpp
src/api/ApiState.cpp
src/App.cpp
src/Console.cpp
src/core/Config.cpp
src/core/ConfigLoader.cpp
src/core/ConfigWatcher.cpp
src/core/Controller.cpp
src/crypto/c_keccak.c
src/crypto/c_keccak.h
src/log/AccessLog.cpp
@@ -87,7 +98,6 @@ set(SOURCES
src/net/strategies/SinglePoolStrategy.cpp
src/net/SubmitResult.cpp
src/net/Url.cpp
src/Options.cpp
src/Platform.cpp
src/proxy/Counters.cpp
src/proxy/CustomDiff.cpp
@@ -95,6 +105,7 @@ set(SOURCES
src/proxy/Events.cpp
src/proxy/events/ConnectionEvent.h
src/proxy/events/Event.cpp
src/proxy/events/MinerEvent.cpp
src/proxy/JobResult.cpp
src/proxy/LoginRequest.cpp
src/proxy/Miner.cpp
@@ -102,9 +113,12 @@ set(SOURCES
src/proxy/Proxy.cpp
src/proxy/ProxyDebug.cpp
src/proxy/Server.cpp
src/proxy/splitters/NonceMapper.cpp
src/proxy/splitters/NonceSplitter.cpp
src/proxy/splitters/NonceStorage.cpp
src/proxy/splitters/nicehash/NonceMapper.cpp
src/proxy/splitters/nicehash/NonceSplitter.cpp
src/proxy/splitters/nicehash/NonceStorage.cpp
src/proxy/splitters/simple/SimpleMapper.cpp
src/proxy/splitters/simple/SimpleSplitter.cpp
src/proxy/splitters/Splitter.cpp
src/proxy/Stats.cpp
src/proxy/workers/Worker.cpp
src/proxy/workers/Workers.cpp
@@ -145,10 +159,13 @@ add_definitions(/DXMRIG_PROXY_PROJECT)
add_definitions(/DUNICODE)
add_definitions(/D__STDC_FORMAT_MACROS)
add_definitions(/DAPP_DEVEL)
add_definitions(/DRAPIDJSON_SSE2)
add_definitions(/DNDEBUG)
#add_definitions(/DAPP_DEBUG)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(/DRAPIDJSON_SSE2)
endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
find_package(UV REQUIRED)
@@ -215,7 +232,18 @@ if (WITH_HTTPD)
if (MHD_FOUND)
include_directories(${MHD_INCLUDE_DIRS})
set(HTTPD_SOURCES src/api/Httpd.h src/api/Httpd.cpp)
set(HTTPD_SOURCES
src/api/Api.h
src/api/ApiRouter.h
src/api/HttpBody.h
src/api/Httpd.h
src/api/HttpReply.h
src/api/HttpRequest.h
src/api/Api.cpp
src/api/ApiRouter.cpp
src/api/Httpd.cpp
src/api/HttpRequest.cpp
)
else()
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
endif()

View File

@@ -1,11 +1,17 @@
# XMRig Proxy
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig-proxy/total.svg)](https://github.com/xmrig/xmrig-proxy/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig-proxy/all.svg)](https://github.com/xmrig/xmrig-proxy/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date-pre/xmrig/xmrig-proxy.svg)](https://github.com/xmrig/xmrig-proxy/releases)
[![GitHub license](https://img.shields.io/github/license/xmrig/xmrig-proxy.svg)](https://github.com/xmrig/xmrig-proxy/blob/master/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig-proxy.svg)](https://github.com/xmrig/xmrig-proxy/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig-proxy.svg)](https://github.com/xmrig/xmrig-proxy/network)
Extremely high performance Monero (XMR) Stratum protocol proxy, can easily handle over 100K connections on cheap $5 (1024 MB) virtual machine. Reduce number of pool connections up to 256 times, 100K workers become just 391 worker on pool side. Written on C++/libuv same as [XMRig](https://github.com/xmrig/xmrig) miner.
## Compatibility
:warning: :warning: :warning: **Nicehash support must be enabled on miner side, it mandatory.** :warning: :warning: :warning:
* Compatible with any Monero and AEON pools, strongly recommended use pool with fixed diff feature.
* Compatible with any Monero, Electroneum, Sumokoin and AEON pools, except **nicehash.com**.
* Any miner with nicehash support, `--nicehash` option for [XMRig](https://github.com/xmrig/xmrig), `"nicehash_nonce": true,` for xmr-stak-cpu.
* [Comparison](https://github.com/xmrig/xmrig-proxy/wiki/Comparison) with other proxies.
@@ -19,52 +25,57 @@ This proxy designed and created for handle donation traffic from XMRig. No one o
## Usage
:boom: If you use Linux and want handle more than **1000 connections**, you need [increase limits of open files](https://github.com/xmrig/xmrig-proxy/wiki/Ubuntu-setup).
### Basic example
```
xmrig-proxy.exe -o pool.minemonero.pro:5555 -u YOUR_WALLET -p x --bind 0.0.0.0:3333 --bind 0.0.0.0:5555
```
### Failover
```
xmrig-proxy.exe -o pool.minemonero.pro:5555 -u YOUR_WALLET1 -o pool.supportxmr.com:5555 -u YOUR_WALLET2 -p x --bind 0.0.0.0:5555
```
For failover you can add multiple pools, maximum count not limited.
Use [config.xmrig.com](https://config.xmrig.com/proxy) to generate, edit or share configurations.
### Options
```
-b, --bind=ADDR bind to specified address, example "0.0.0.0:3333"
-a, --algo=ALGO cryptonight (default) or cryptonight-lite
-m, --mode=MODE proxy mode, nicehash (default) or simple
-o, --url=URL URL of mining server
-O, --userpass=U:P username:password pair for mining server
-u, --user=USERNAME username for mining server
-p, --pass=PASSWORD password for mining server
-r, --retries=N number of times to retry before switch to backup server (default: 5)
-R, --retry-pause=N time to pause between retries (default: 5)
-r, --retries=N number of times to retry before switch to backup server (default: 1)
-R, --retry-pause=N time to pause between retries (default: 1 second)
--custom-diff=N override pool diff
--reuse-timeout=N timeout in seconds for reuse pool connections in simple mode
--verbose verbose output
--user-agent=AGENT set custom user-agent string for pool
--coin=COIN xmr for all cryptonight coins or aeon
--no-color disable colored output
--no-workers disable per worker statistics
--variant algorithm PoW variant
--donate-level=N donate level, default 2%
-B, --background run the miner in the background
-c, --config=FILE load a JSON-format configuration file
--no-watch disable configuration file watching
-l, --log-file=FILE log all output to a file
-S, --syslog use system log for output messages
-A --access-log-file=N log all workers access to a file
--api-port=N port for the miner API
--api-access-token=T access token for API
--api-access-token=T use Bearer access token for API
--api-worker-id=ID custom worker-id for API
--api-no-ipv6 disable IPv6 support for API
--api-no-restricted enable full remote access (only if API token set)
-h, --help display this help and exit
-V, --version output version information and exit
```
## Donations
Default donation fee is 2% can be reduced to 1% via `donate-level` option. Donation fee applyed only for second and more pool connection. If you use only one pool connection (up to 256 workers) there is no fee.
Default donation fee is 2% can be reduced to 1% or disabled via `donate-level` option. Donation fee applies only if you use more than 256 miners.
* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
## Release checksums
### SHA-256
```
005a90c13d0f1f37f5f1bafb41a5c20149df6e42e6a6991621335ccae9215c29 xmrig-proxy-2.5.2-win32/xmrig-proxy.exe
58d1a6f03485a4ba7b3ab048831ac4886de8adf2e4f2448dab0d28ac29251d4c xmrig-proxy-2.5.2-win64/xmrig-proxy.exe
```
## Contacts
* support@xmrig.com
* [reddit](https://www.reddit.com/user/XMRig/)

View File

@@ -8,15 +8,25 @@
find_path(
MHD_INCLUDE_DIR
NAMES microhttpd.h
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "include"
DOC "microhttpd include dir"
NO_DEFAULT_PATH
)
find_path(MHD_INCLUDE_DIR NAMES microhttpd.h)
find_library(
MHD_LIBRARY
NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
NAMES libmicrohttpd.a microhttpd libmicrohttpd
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "lib"
DOC "microhttpd library"
NO_DEFAULT_PATH
)
find_library(MHD_LIBRARY NAMES microhttpd libmicrohttpd)
set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
set(MHD_LIBRARIES ${MHD_LIBRARY})
@@ -34,6 +44,6 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(mhd DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
find_package_handle_standard_args(MHD DEFAULT_MSG MHD_LIBRARY MHD_INCLUDE_DIR)
mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)

View File

@@ -1,5 +1,22 @@
find_path(
UV_INCLUDE_DIR
NAMES uv.h
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "include"
NO_DEFAULT_PATH
)
find_path(UV_INCLUDE_DIR NAMES uv.h)
find_library(UV_LIBRARY NAMES uv libuv)
find_library(
UV_LIBRARY
NAMES libuv.a uv libuv
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
find_library(UV_LIBRARY NAMES libuv.a uv libuv)
set(UV_LIBRARIES ${UV_LIBRARY})
set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -4,7 +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
@@ -30,61 +31,37 @@
#include "api/Api.h"
#include "App.h"
#include "Console.h"
#include "log/ConsoleLog.h"
#include "log/FileLog.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "Options.h"
#include "Platform.h"
#include "proxy/Proxy.h"
#include "Summary.h"
#include "version.h"
#ifdef HAVE_SYSLOG_H
# include "log/SysLog.h"
#endif
#ifndef XMRIG_NO_HTTPD
# include "api/Httpd.h"
#endif
App *App::m_self = nullptr;
App::App(int argc, char **argv) :
m_console(nullptr),
m_proxy(nullptr),
m_options(nullptr)
m_httpd(nullptr)
{
m_self = this;
m_options = Options::parse(argc, argv);
if (!m_options) {
m_controller = new xmrig::Controller();
if (m_controller->init(argc, argv) != 0) {
return;
}
Log::init();
if (!m_options->background()) {
Log::add(new ConsoleLog(m_options->colors()));
if (!m_controller->config()->background()) {
m_console = new Console(this);
}
if (m_options->logFile()) {
Log::add(new FileLog(m_options->logFile()));
}
uv_signal_init(uv_default_loop(), &m_sigHUP);
uv_signal_init(uv_default_loop(), &m_sigINT);
uv_signal_init(uv_default_loop(), &m_sigTERM);
# ifdef HAVE_SYSLOG_H
if (m_options->syslog()) {
Log::add(new SysLog());
}
# endif
Platform::init(m_options->userAgent());
m_proxy = new Proxy(m_options);
uv_signal_init(uv_default_loop(), &m_signal);
m_sigHUP.data = m_sigINT.data = m_sigTERM.data = this;
}
@@ -93,7 +70,7 @@ App::~App()
uv_tty_reset_mode();
delete m_console;
delete m_proxy;
delete m_controller;
# ifndef XMRIG_NO_HTTPD
delete m_httpd;
@@ -105,33 +82,38 @@ App::~App()
int App::exec()
{
if (!m_options) {
if (!m_controller->config()) {
return 0;
}
uv_signal_start(&m_signal, App::onSignal, SIGHUP);
uv_signal_start(&m_signal, App::onSignal, SIGTERM);
uv_signal_start(&m_signal, App::onSignal, SIGINT);
uv_signal_start(&m_sigHUP, App::onSignal, SIGHUP);
uv_signal_start(&m_sigINT, App::onSignal, SIGINT);
uv_signal_start(&m_sigTERM, App::onSignal, SIGTERM);
background();
Summary::print();
Summary::print(m_controller);
# ifndef XMRIG_NO_API
Api::start();
Api::start(m_controller);
# endif
# ifndef XMRIG_NO_HTTPD
m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken());
m_httpd = new Httpd(
m_controller->config()->apiPort(),
m_controller->config()->apiToken(),
m_controller->config()->apiIPv6(),
m_controller->config()->apiRestricted()
);
m_httpd->start();
# endif
m_proxy->connect();
m_controller->proxy()->connect();
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());
Options::release();
Platform::release();
return r;
@@ -144,34 +126,34 @@ void App::onConsoleCommand(char command)
# ifdef APP_DEVEL
case 's':
case 'S':
m_proxy->printState();
m_controller->proxy()->printState();
break;
# endif
case 'v':
case 'V':
Options::i()->toggleVerbose();
LOG_NOTICE("verbose: %d", Options::i()->verbose());
m_controller->config()->toggleVerbose();
LOG_NOTICE("verbose: %d", m_controller->config()->verbose());
break;
case 'h':
case 'H':
m_proxy->printHashrate();
m_controller->proxy()->printHashrate();
break;
case 'c':
case 'C':
m_proxy->printConnections();
m_controller->proxy()->printConnections();
break;
case 'd':
case 'D':
m_proxy->toggleDebug();
m_controller->proxy()->toggleDebug();
break;
case 'w':
case 'W':
m_proxy->printWorkers();
m_controller->proxy()->printWorkers();
break;
case 3:
@@ -212,5 +194,5 @@ void App::onSignal(uv_signal_t *handle, int signum)
return;
}
m_self->close();
static_cast<App*>(handle->data)->close();
}

View File

@@ -4,7 +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
@@ -37,6 +38,11 @@ class Proxy;
class Options;
namespace xmrig {
class Controller;
}
class App : public IConsoleListener
{
public:
@@ -54,13 +60,12 @@ private:
static void onSignal(uv_signal_t *handle, int signum);
static App *m_self;
Console *m_console;
Httpd *m_httpd;
Proxy *m_proxy;
Options *m_options;
uv_signal_t m_signal;
uv_signal_t m_sigHUP;
uv_signal_t m_sigINT;
uv_signal_t m_sigTERM;
xmrig::Controller *m_controller;
};

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -29,15 +29,16 @@
#include "App.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "Options.h"
void App::background()
{
signal(SIGPIPE, SIG_IGN);
if (!m_options->background()) {
if (!m_controller->config()->background()) {
return;
}

View File

@@ -27,12 +27,13 @@
#include "App.h"
#include "Options.h"
#include "core/Config.h"
#include "core/Controller.h"
void App::background()
{
if (!m_options->background()) {
if (!m_controller->config()->background()) {
return;
}

View File

@@ -1,616 +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 2016-2017 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 <limits.h>
#include <string.h>
#include <uv.h>
#ifdef _MSC_VER
# include "getopt/getopt.h"
#else
# include <getopt.h>
#endif
#include "donate.h"
#include "net/Url.h"
#include "Options.h"
#include "Platform.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/filereadstream.h"
#include "version.h"
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
Options *Options::m_self = nullptr;
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\
-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\
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
-R, --retry-pause=N time to pause between retries (default: 5)\n\
--custom-diff=N override pool diff\n\
--verbose verbose output\n\
--user-agent=AGENT set custom user-agent string for pool\n\
--coin=COIN xmr for all cryptonight coins or aeon\n\
--no-color disable colored output\n\
--no-workers disable per worker statistics\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\
-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 access token for API\n\
--api-worker-id=ID custom worker-id for API\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:";
static struct option const options[] = {
{ "access-log-file", 1, nullptr, 'A' },
{ "api-access-token", 1, nullptr, 4001 },
{ "api-port", 1, nullptr, 4000 },
{ "api-worker-id", 1, nullptr, 4002 },
{ "background", 0, nullptr, 'B' },
{ "bind", 1, nullptr, 'b' },
{ "coin", 1, nullptr, 1104 },
{ "config", 1, nullptr, 'c' },
{ "custom-diff", 1, nullptr, 1102 },
{ "debug", 0, nullptr, 1101 },
{ "donate-level", 1, nullptr, 1003 },
{ "help", 0, nullptr, 'h' },
{ "keepalive", 0, nullptr ,'k' },
{ "log-file", 1, nullptr, 'l' },
{ "no-color", 0, nullptr, 1002 },
{ "no-workers", 0, nullptr, 1103 },
{ "pass", 1, nullptr, 'p' },
{ "retries", 1, nullptr, 'r' },
{ "retry-pause", 1, nullptr, 'R' },
{ "syslog", 0, nullptr, 'S' },
{ "url", 1, nullptr, 'o' },
{ "user", 1, nullptr, 'u' },
{ "user-agent", 1, nullptr, 1008 },
{ "userpass", 1, nullptr, 'O' },
{ "verbose", 0, nullptr, 1100 },
{ "version", 0, nullptr, 'V' },
{ 0, 0, 0, 0 }
};
static struct option const config_options[] = {
{ "access-log-file", 1, nullptr, 'A' },
{ "background", 0, nullptr, 'B' },
{ "coin", 1, nullptr, 1104 },
{ "colors", 0, nullptr, 2000 },
{ "custom-diff", 1, nullptr, 1102 },
{ "debug", 0, nullptr, 1101 },
{ "donate-level", 1, nullptr, 1003 },
{ "log-file", 1, nullptr, 'l' },
{ "retries", 1, nullptr, 'r' },
{ "retry-pause", 1, nullptr, 'R' },
{ "syslog", 0, nullptr, 'S' },
{ "user-agent", 1, nullptr, 1008 },
{ "verbose", 0, nullptr, 1100 },
{ "workers", 0, nullptr, 1103 },
{ 0, 0, 0, 0 }
};
static struct option const pool_options[] = {
{ "url", 1, nullptr, 'o' },
{ "pass", 1, nullptr, 'p' },
{ "user", 1, nullptr, 'u' },
{ "userpass", 1, nullptr, 'O' },
{ "keepalive", 0, nullptr ,'k' },
{ 0, 0, 0, 0 }
};
static struct option const api_options[] = {
{ "port", 1, nullptr, 4000 },
{ "access-token", 1, nullptr, 4001 },
{ "worker-id", 1, nullptr, 4002 },
{ 0, 0, 0, 0 }
};
Options *Options::parse(int argc, char **argv)
{
Options *options = new Options(argc, argv);
if (options->isReady()) {
m_self = options;
return m_self;
}
delete options;
return nullptr;
}
Options::Options(int argc, char **argv) :
m_background(false),
m_colors(true),
m_debug(false),
m_ready(false),
m_syslog(false),
m_verbose(false),
m_workers(true),
m_accessLog(nullptr),
m_apiToken(nullptr),
m_apiWorkerId(nullptr),
m_coin(nullptr),
m_logFile(nullptr),
m_userAgent(nullptr),
m_apiPort(0),
m_donateLevel(kDonateLevel),
m_retries(5),
m_retryPause(5),
m_diff(0)
{
m_pools.push_back(new Url());
int key;
while (1) {
key = getopt_long(argc, argv, short_options, options, NULL);
if (key < 0) {
break;
}
if (!parseArg(key, optarg)) {
return;
}
}
if (optind < argc) {
fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]);
return;
}
if (!m_pools[0]->isValid()) {
parseConfig(Platform::defaultConfigName());
}
if (!m_pools[0]->isValid()) {
fprintf(stderr, "No pool URL supplied. Exiting.\n");
return;
}
if (m_addrs.empty()) {
m_addrs.push_back(new Addr("0.0.0.0:3333"));
}
m_ready = true;
}
Options::~Options()
{
for (Addr *addr : m_addrs) {
delete addr;
}
for (Url *url : m_pools) {
delete url;
}
m_addrs.clear();
m_pools.clear();
free(m_accessLog);
free(m_apiToken);
free(m_apiWorkerId);
free(m_coin);
free(m_logFile);
free(m_userAgent);
}
bool Options::getJSON(const char *fileName, rapidjson::Document &doc)
{
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
if (fd < 0) {
fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
return false;
}
uv_fs_req_cleanup(&req);
FILE *fp = fdopen(fd, "rb");
char buf[8192];
rapidjson::FileReadStream is(fp, buf, sizeof(buf));
doc.ParseStream(is);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
if (doc.HasParseError()) {
printf("%s:%d: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
return false;
}
return doc.IsObject();
}
bool Options::parseArg(int key, const char *arg)
{
switch (key) {
case 'b': /* --bind */
{
Addr *addr = new Addr(arg);
if (addr->isValid()) {
m_addrs.push_back(addr);
}
else {
delete addr;
}
}
break;
case 'O': /* --userpass */
if (!m_pools.back()->setUserpass(arg)) {
return false;
}
break;
case 'o': /* --url */
if (m_pools.size() > 1 || m_pools[0]->isValid()) {
Url *url = new Url(arg);
if (url->isValid()) {
m_pools.push_back(url);
}
else {
delete url;
}
}
else {
m_pools[0]->parse(arg);
}
if (!m_pools.back()->isValid()) {
return false;
}
break;
case 'u': /* --user */
m_pools.back()->setUser(arg);
break;
case 'p': /* --pass */
m_pools.back()->setPassword(arg);
break;
case 'l': /* --log-file */
free(m_logFile);
m_logFile = strdup(arg);
break;
case 'A': /* --access-log-file **/
free(m_accessLog);
m_accessLog = strdup(arg);
break;
case 4001: /* --access-token */
free(m_apiToken);
m_apiToken = strdup(arg);
break;
case 4002: /* --worker-id */
free(m_apiWorkerId);
m_apiWorkerId = strdup(arg);
break;
case 'r': /* --retries */
case 'R': /* --retry-pause */
case 1102: /* --custom-diff */
case 4000: /* --api-port */
return parseArg(key, strtol(arg, nullptr, 10));
case 'B': /* --background */
case 'k': /* --keepalive */
case 'S': /* --syslog */
case 1100: /* --verbose */
case 1101: /* --debug */
return parseBoolean(key, true);
case 1002: /* --no-color */
case 1103: /* --no-workers */
return parseBoolean(key, false);
case 1003: /* --donate-level */
if (strncmp(arg, "minemonero.pro", 14) == 0) {
m_donateLevel = 0;
}
else {
parseArg(key, strtol(arg, nullptr, 10));
}
break;
case 1104: /* --coin */
free(m_coin);
m_coin = strdup(arg);
break;
case 'V': /* --version */
showVersion();
return false;
case 'h': /* --help */
showUsage(0);
return false;
case 'c': /* --config */
parseConfig(arg);
break;
case 1008: /* --user-agent */
free(m_userAgent);
m_userAgent = strdup(arg);
break;
default:
showUsage(1);
return false;
}
return true;
}
bool Options::parseArg(int key, uint64_t arg)
{
switch (key) {
case 'r': /* --retries */
if (arg < 1 || arg > 1000) {
showUsage(1);
return false;
}
m_retries = (int) arg;
break;
case 'R': /* --retry-pause */
if (arg < 1 || arg > 3600) {
showUsage(1);
return false;
}
m_retryPause = (int) arg;
break;
case 1003: /* --donate-level */
if (arg < 1 || arg > 99) {
return true;
}
m_donateLevel = (int) arg;
break;
case 4000: /* --api-port */
if (arg <= 65536) {
m_apiPort = (int) arg;
}
break;
case 1102: /* --custom-diff */
if (arg >= 100 && arg < INT_MAX) {
m_diff = arg;
}
break;
default:
break;
}
return true;
}
bool Options::parseBoolean(int key, bool enable)
{
switch (key) {
case 'B': /* --background */
m_background = enable;
break;
case 'k': /* --keepalive */
m_pools.back()->setKeepAlive(enable);
break;
case 'S': /* --syslog */
m_syslog = enable;
break;
case 1002: /* --no-color */
m_colors = enable;
break;
case 1100: /* --verbose */
m_verbose = enable;
break;
case 1101: /* --debug */
m_debug = enable;
break;
case 2000: /* colors */
m_colors = enable;
break;
case 1103: /* workers */
m_workers = enable;
break;
default:
break;
}
return true;
}
Url *Options::parseUrl(const char *arg) const
{
auto url = new Url(arg);
if (!url->isValid()) {
delete url;
return nullptr;
}
return url;
}
void Options::parseConfig(const char *fileName)
{
rapidjson::Document doc;
if (!getJSON(fileName, doc)) {
return;
}
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
parseJSON(&config_options[i], doc);
}
const rapidjson::Value &pools = doc["pools"];
if (pools.IsArray()) {
for (const rapidjson::Value &value : pools.GetArray()) {
if (!value.IsObject()) {
continue;
}
for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) {
parseJSON(&pool_options[i], value);
}
}
}
const rapidjson::Value &bind = doc["bind"];
if (bind.IsArray()) {
for (const rapidjson::Value &value : bind.GetArray()) {
if (!value.IsString()) {
continue;
}
parseArg('b', value.GetString());
}
}
const rapidjson::Value &api = doc["api"];
if (api.IsObject()) {
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
parseJSON(&api_options[i], api);
}
}
}
void Options::parseJSON(const struct option *option, const rapidjson::Value &object)
{
if (!option->name || !object.HasMember(option->name)) {
return;
}
const rapidjson::Value &value = object[option->name];
if (option->has_arg && value.IsString()) {
parseArg(option->val, value.GetString());
}
else if (option->has_arg && value.IsUint64()) {
parseArg(option->val, value.GetUint64());
}
else if (!option->has_arg && value.IsBool()) {
parseBoolean(option->val, value.IsTrue());
}
}
void Options::showUsage(int status) const
{
if (status) {
fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n");
}
else {
printf(usage);
}
}
void Options::showVersion()
{
printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
# if defined(__clang__)
" with clang " __clang_version__);
# elif defined(__GNUC__)
" with GCC");
printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
" with MSVC");
printf(" %d", MSVC_VERSION);
# else
);
# endif
printf("\n features:"
# if defined(__i386__) || defined(_M_IX86)
" i386"
# elif defined(__x86_64__) || defined(_M_AMD64)
" x86_64"
# endif
# if defined(__AES__) || defined(_MSC_VER)
" AES-NI"
# endif
"\n");
printf("\nlibuv/%s\n", uv_version_string());
}

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -22,6 +22,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <uv.h>
@@ -41,11 +42,11 @@ static inline char *createUserAgent()
char *buf = new char[max];
# ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__, __clang_patchlevel__);
# else
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
# ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__, __clang_patchlevel__);
# else
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
# endif
return buf;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,14 +26,16 @@
#include <uv.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "net/Url.h"
#include "Options.h"
#include "proxy/Addr.h"
#include "Summary.h"
#include "version.h"
static void print_versions()
static void print_versions(xmrig::Controller *controller)
{
char buf[16];
@@ -48,7 +50,7 @@ static void print_versions()
# endif
if (Options::i()->colors()) {
if (controller->config()->colors()) {
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);
@@ -56,53 +58,45 @@ static void print_versions()
}
static void print_pools()
static void print_mode(xmrig::Controller *controller)
{
const std::vector<Url*> &pools = Options::i()->pools();
for (size_t i = 0; i < pools.size(); ++i) {
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d:\x1B[0m \x1B[36m%s:%d" : " * POOL #%d: %s:%d",
i + 1,
pools[i]->host(),
pools[i]->port());
}
# ifdef APP_DEBUG
for (size_t i = 0; i < pools.size(); ++i) {
Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash());
}
# endif
Log::i()->text(controller->config()->colors() ? "\x1B[01;32m * \x1B[01;37mMODE:\x1B[0m \x1B[01;37m%s" : " * MODE: %s",
controller->config()->modeName());
}
static void print_bind()
static void print_bind(xmrig::Controller *controller)
{
const std::vector<Addr*> &addrs = Options::i()->addrs();
const std::vector<Addr*> &addrs = controller->config()->addrs();
for (size_t i = 0; i < addrs.size(); ++i) {
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mBIND #%d:\x1B[0m \x1B[36m%s:%d" : " * BIND #%d: %s:%d",
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",
i + 1,
addrs[i]->host(),
addrs[i]->isIPv6() ? "[" : "",
addrs[i]->ip(),
addrs[i]->isIPv6() ? "]" : "",
addrs[i]->port());
}
}
#ifndef XMRIG_NO_API
static void print_api()
static void print_api(xmrig::Controller *controller)
{
if (Options::i()->apiPort() == 0) {
const int port = controller->config()->apiPort();
if (port == 0) {
return;
}
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" : " * API PORT: %d", Options::i()->apiPort());
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);
}
#endif
static void print_commands()
static void print_commands(xmrig::Controller *controller)
{
if (Options::i()->colors()) {
if (controller->config()->colors()) {
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 {
@@ -111,17 +105,37 @@ static void print_commands()
}
void Summary::print()
void Summary::print(xmrig::Controller *controller)
{
print_versions();
print_pools();
print_bind();
print_versions(controller);
print_mode(controller);
printPools(controller->config());
print_bind(controller);
# ifndef XMRIG_NO_API
print_api();
print_api(controller);
# endif
print_commands();
print_commands(controller);
}
void Summary::printPools(xmrig::Config *config)
{
const std::vector<Url*> &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",
i + 1,
pools[i]->host(),
pools[i]->port());
}
# 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());
}
# endif
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,10 +25,17 @@
#define __SUMMARY_H__
namespace xmrig {
class Config;
class Controller;
}
class Summary
{
public:
static void print();
static void print(xmrig::Controller *controller);
static void printPools(xmrig::Config *config);
};

View File

@@ -4,7 +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
@@ -25,17 +26,17 @@
#include "api/Api.h"
#include "api/ApiState.h"
#include "api/ApiRouter.h"
#include "api/HttpReply.h"
#include "api/HttpRequest.h"
ApiState *Api::m_state = nullptr;
uv_mutex_t Api::m_mutex;
ApiRouter *Api::m_router = nullptr;
bool Api::start()
bool Api::start(xmrig::Controller *controller)
{
uv_mutex_init(&m_mutex);
m_state = new ApiState();
m_router = new ApiRouter(controller);
return true;
}
@@ -43,43 +44,20 @@ bool Api::start()
void Api::release()
{
delete m_state;
delete m_router;
}
char *Api::get(const char *url, int *status)
void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
{
if (!m_state) {
return nullptr;
}
uv_mutex_lock(&m_mutex);
char *buf = m_state->get(url, status);
uv_mutex_unlock(&m_mutex);
return buf;
}
void Api::tick(const StatsData &data)
{
if (!m_state) {
if (!m_router) {
reply.status = 500;
return;
}
uv_mutex_lock(&m_mutex);
m_state->tick(data);
uv_mutex_unlock(&m_mutex);
}
void Api::tick(const std::vector<Worker> &workers)
{
if (!m_state) {
return;
if (req.method() == xmrig::HttpRequest::Get) {
return m_router->get(req, reply);
}
uv_mutex_lock(&m_mutex);
m_state->tick(workers);
uv_mutex_unlock(&m_mutex);
m_router->exec(req, reply);
}

View File

@@ -4,7 +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
@@ -25,31 +26,26 @@
#define __API_H__
#include <uv.h>
#include <vector>
class ApiRouter;
#include "proxy/workers/Worker.h"
class ApiState;
class Hashrate;
class StatsData;
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
}
class Api
{
public:
static bool start();
static bool start(xmrig::Controller *controller);
static void release();
static char *get(const char *url, int *status);
static void tick(const StatsData &data);
static void tick(const std::vector<Worker> &workers);
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
private:
static ApiState *m_state;
static uv_mutex_t m_mutex;
static ApiRouter *m_router;
};
#endif /* __API_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,13 +32,16 @@
#endif
#include "api/ApiState.h"
#include "api/ApiRouter.h"
#include "api/HttpReply.h"
#include "api/HttpRequest.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "net/Job.h"
#include "Options.h"
#include "Platform.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "version.h"
@@ -58,78 +61,90 @@ static inline double normalize(double d)
}
ApiState::ApiState()
ApiRouter::ApiRouter(xmrig::Controller *controller) :
m_controller(controller)
{
memset(m_workerId, 0, sizeof(m_workerId));
if (Options::i()->apiWorkerId()) {
strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
}
setWorkerId(controller->config()->apiWorkerId());
genId();
controller->addListener(this);
}
ApiState::~ApiState()
ApiRouter::~ApiRouter()
{
}
char *ApiState::get(const char *url, int *status) const
void ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
{
rapidjson::Document doc;
doc.SetObject();
if (strncmp(url, "/workers.json", 13) == 0) {
if (req.match("/1/workers") || req.match("/workers.json")) {
getHashrate(doc);
getWorkers(doc);
return finalize(doc);
return finalize(reply, doc);
}
if (strncmp(url, "/resources.json", 15) == 0) {
if (req.match("/1/config")) {
if (req.isRestricted()) {
reply.status = 403;
return;
}
m_controller->config()->getJSON(doc);
return finalize(reply, doc);
}
if (req.match("/1/resources") || req.match("/resources.json")) {
getResources(doc);
return finalize(doc);
return finalize(reply, doc);
}
getIdentify(doc);
getMiner(doc);
getHashrate(doc);
getMinersSummary(doc);
getMinersSummary(doc, req.match("/1/summary"));
getResults(doc);
return finalize(doc);
return finalize(reply, doc);
}
void ApiState::tick(const StatsData &data)
void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
{
m_stats = data;
if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) {
m_controller->config()->reload(req.body());
return;
}
reply.status = 404;
}
void ApiState::tick(const std::vector<Worker> &workers)
void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
m_workers = workers;
updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId());
}
char *ApiState::finalize(rapidjson::Document &doc) const
void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const
{
rapidjson::StringBuffer buffer(0, 4096);
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
writer.SetMaxDecimalPlaces(10);
doc.Accept(writer);
return strdup(buffer.GetString());
reply.status = 200;
reply.buf = strdup(buffer.GetString());
reply.size = buffer.GetSize();
}
void ApiState::genId()
void ApiRouter::genId()
{
memset(m_id, 0, sizeof(m_id));
@@ -162,15 +177,17 @@ void ApiState::genId()
}
void ApiState::getHashrate(rapidjson::Document &doc) const
void ApiRouter::getHashrate(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
rapidjson::Value hashrate(rapidjson::kObjectType);
rapidjson::Value total(rapidjson::kArrayType);
for (size_t i = 0; i < sizeof(m_stats.hashrate) / sizeof(m_stats.hashrate[0]); i++) {
total.PushBack(normalize(m_stats.hashrate[i]), allocator);
auto &stats = m_controller->statsData();
for (size_t i = 0; i < sizeof(stats.hashrate) / sizeof(stats.hashrate[0]); i++) {
total.PushBack(normalize(stats.hashrate[i]), allocator);
}
hashrate.AddMember("total", total, allocator);
@@ -178,25 +195,27 @@ void ApiState::getHashrate(rapidjson::Document &doc) const
}
void ApiState::getIdentify(rapidjson::Document &doc) const
void ApiRouter::getIdentify(rapidjson::Document &doc) const
{
doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator());
doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator());
}
void ApiState::getMiner(rapidjson::Document &doc) const
void ApiRouter::getMiner(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
auto &stats = m_controller->statsData();
doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator);
doc.AddMember("mode", rapidjson::StringRef(m_controller->config()->modeName()), allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
doc.AddMember("uptime", m_stats.uptime(), allocator);
doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
doc.AddMember("uptime", stats.uptime(), allocator);
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
if (m_stats.hashes && m_stats.donateHashes) {
doc.AddMember("donated", normalize((double) m_stats.donateHashes / m_stats.hashes * 100.0), allocator);
if (stats.hashes && stats.donateHashes) {
doc.AddMember("donated", normalize((double) stats.donateHashes / stats.hashes * 100.0), allocator);
}
else {
doc.AddMember("donated", 0.0, allocator);
@@ -204,22 +223,37 @@ void ApiState::getMiner(rapidjson::Document &doc) const
}
void ApiState::getMinersSummary(rapidjson::Document &doc) const
void ApiRouter::getMinersSummary(rapidjson::Document &doc, bool advanced) const
{
auto &allocator = doc.GetAllocator();
auto &stats = m_controller->statsData();
rapidjson::Value miners(rapidjson::kObjectType);
miners.AddMember("now", m_stats.miners, allocator);
miners.AddMember("max", m_stats.maxMiners, allocator);
miners.AddMember("now", stats.miners, allocator);
miners.AddMember("max", stats.maxMiners, allocator);
doc.AddMember("miners", miners, allocator);
doc.AddMember("upstreams", m_stats.upstreams, allocator);
doc.AddMember("miners", miners, allocator);
if (advanced) {
rapidjson::Value upstreams(rapidjson::kObjectType);
upstreams.AddMember("active", stats.upstreams.active, allocator);
upstreams.AddMember("sleep", stats.upstreams.sleep, allocator);
upstreams.AddMember("error", stats.upstreams.error, allocator);
upstreams.AddMember("total", stats.upstreams.total, allocator);
upstreams.AddMember("ratio", normalize(stats.upstreams.ratio), allocator);
doc.AddMember("upstreams", upstreams, allocator);
}
else {
doc.AddMember("upstreams", stats.upstreams.active, allocator);
}
}
void ApiState::getResources(rapidjson::Document &doc) const
void ApiRouter::getResources(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
size_t rss = 0;
@@ -230,24 +264,25 @@ void ApiState::getResources(rapidjson::Document &doc) const
}
void ApiState::getResults(rapidjson::Document &doc) const
void ApiRouter::getResults(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
auto &stats = m_controller->statsData();
rapidjson::Value results(rapidjson::kObjectType);
results.AddMember("accepted", m_stats.accepted, allocator);
results.AddMember("rejected", m_stats.rejected, allocator);
results.AddMember("invalid", m_stats.invalid, allocator);
results.AddMember("expired", m_stats.expired, allocator);
results.AddMember("avg_time", m_stats.avgTime(), allocator);
results.AddMember("latency", m_stats.avgLatency(), allocator);
results.AddMember("hashes_total", m_stats.hashes, allocator);
results.AddMember("hashes_donate", m_stats.donateHashes, allocator);
results.AddMember("accepted", stats.accepted, allocator);
results.AddMember("rejected", stats.rejected, allocator);
results.AddMember("invalid", stats.invalid, allocator);
results.AddMember("expired", stats.expired, allocator);
results.AddMember("avg_time", stats.avgTime(), allocator);
results.AddMember("latency", stats.avgLatency(), allocator);
results.AddMember("hashes_total", stats.hashes, allocator);
results.AddMember("hashes_donate", stats.donateHashes, allocator);
rapidjson::Value best(rapidjson::kArrayType);
for (size_t i = 0; i < m_stats.topDiff.size(); ++i) {
best.PushBack(m_stats.topDiff[i], allocator);
for (size_t i = 0; i < stats.topDiff.size(); ++i) {
best.PushBack(stats.topDiff[i], allocator);
}
results.AddMember("best", best, allocator);
@@ -256,12 +291,14 @@ void ApiState::getResults(rapidjson::Document &doc) const
}
void ApiState::getWorkers(rapidjson::Document &doc) const
void ApiRouter::getWorkers(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
auto &list = m_controller->workers();
rapidjson::Value workers(rapidjson::kArrayType);
for (const Worker &worker : m_workers) {
for (const Worker &worker : list) {
if (worker.connections() == 0 && worker.lastHash() == 0) {
continue;
}
@@ -286,3 +323,30 @@ void ApiState::getWorkers(rapidjson::Document &doc) const
doc.AddMember("workers", workers, allocator);
}
void ApiRouter::setWorkerId(const char *id)
{
memset(m_workerId, 0, sizeof(m_workerId));
if (id && strlen(id) > 0) {
strncpy(m_workerId, id, sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
}
}
void ApiRouter::updateWorkerId(const char *id, const char *previousId)
{
if (id == previousId) {
return;
}
if (id != nullptr && previousId != nullptr && strcmp(id, previousId) == 0) {
return;
}
setWorkerId(id);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,43 +21,53 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __APISTATE_H__
#define __APISTATE_H__
#ifndef __APIROUTER_H__
#define __APIROUTER_H__
#include "interfaces/IControllerListener.h"
#include "proxy/StatsData.h"
#include "proxy/workers/Worker.h"
#include "rapidjson/fwd.h"
class Hashrate;
class ApiState
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
}
class ApiRouter : public xmrig::IControllerListener
{
public:
ApiState();
~ApiState();
ApiRouter(xmrig::Controller *controller);
~ApiRouter();
char *get(const char *url, int *status) const;
void tick(const StatsData &data);
void tick(const std::vector<Worker> &workers);
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
protected:
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
private:
char *finalize(rapidjson::Document &doc) const;
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
void genId();
void getHashrate(rapidjson::Document &doc) const;
void getIdentify(rapidjson::Document &doc) const;
void getMiner(rapidjson::Document &doc) const;
void getMinersSummary(rapidjson::Document &doc) const;
void getMinersSummary(rapidjson::Document &doc, bool advanced) const;
void getResources(rapidjson::Document &doc) const;
void getResults(rapidjson::Document &doc) const;
void getWorkers(rapidjson::Document &doc) const;
void setWorkerId(const char *id);
void updateWorkerId(const char *id, const char *previousId);
char m_id[17];
char m_workerId[128];
StatsData m_stats;
std::vector<Worker> m_workers;
xmrig::Controller *m_controller;
};
#endif /* __APISTATE_H__ */
#endif /* __APIROUTER_H__ */

69
src/api/HttpBody.h Normal file
View File

@@ -0,0 +1,69 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 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 __HTTPBODY_H__
#define __HTTPBODY_H__
#include <string.h>
namespace xmrig {
class HttpBody
{
public:
inline HttpBody() :
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;
};
} /* namespace xmrig */
#endif /* __HTTPBODY_H__ */

53
src/api/HttpReply.h Normal file
View File

@@ -0,0 +1,53 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 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 __HTTPREPLY_H__
#define __HTTPREPLY_H__
#include <stdint.h>
namespace xmrig {
class HttpReply
{
public:
HttpReply() :
buf(nullptr),
status(200),
size(0)
{}
char *buf;
int status;
size_t size;
};
} /* namespace xmrig */
#endif /* __HTTPREPLY_H__ */

175
src/api/HttpRequest.cpp Normal file
View File

@@ -0,0 +1,175 @@
/* 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 <microhttpd.h>
#include <string.h>
#include "api/HttpBody.h"
#include "api/HttpRequest.h"
#include "api/HttpReply.h"
#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE
# define MHD_HTTP_PAYLOAD_TOO_LARGE 413
#endif
xmrig::HttpRequest::HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls) :
m_fulfilled(true),
m_restricted(true),
m_uploadData(uploadData),
m_url(url),
m_body(static_cast<HttpBody*>(*cls)),
m_method(Unsupported),
m_connection(connection),
m_uploadSize(uploadSize),
m_cls(cls)
{
if (strcmp(method, MHD_HTTP_METHOD_OPTIONS) == 0) {
m_method = Options;
}
else if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) {
m_method = Get;
}
else if (strcmp(method, MHD_HTTP_METHOD_PUT) == 0) {
m_method = Put;
}
}
xmrig::HttpRequest::~HttpRequest()
{
if (m_fulfilled) {
delete m_body;
}
}
bool xmrig::HttpRequest::match(const char *path) const
{
return strcmp(m_url, path) == 0;
}
bool xmrig::HttpRequest::process(const char *accessToken, bool restricted, xmrig::HttpReply &reply)
{
m_restricted = restricted || !accessToken;
if (m_body) {
if (*m_uploadSize != 0) {
if (!m_body->write(m_uploadData, *m_uploadSize)) {
*m_cls = nullptr;
m_fulfilled = true;
reply.status = MHD_HTTP_PAYLOAD_TOO_LARGE;
return false;
}
*m_uploadSize = 0;
m_fulfilled = false;
return true;
}
m_fulfilled = true;
return true;
}
reply.status = auth(accessToken);
if (reply.status != MHD_HTTP_OK) {
return false;
}
if (m_restricted && m_method != Get) {
reply.status = MHD_HTTP_FORBIDDEN;
return false;
}
if (m_method == Get) {
return true;
}
const char *contentType = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Content-Type");
if (!contentType || strcmp(contentType, "application/json") != 0) {
reply.status = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;
return false;
}
m_body = new xmrig::HttpBody();
m_fulfilled = false;
*m_cls = m_body;
return true;
}
const char *xmrig::HttpRequest::body() const
{
return m_body ? m_body->data() : nullptr;
}
int xmrig::HttpRequest::end(const HttpReply &reply)
{
if (reply.buf) {
return end(reply.status, MHD_create_response_from_buffer(reply.size ? reply.size : strlen(reply.buf), (void*) reply.buf, MHD_RESPMEM_MUST_FREE));
}
return end(reply.status, nullptr);
}
int xmrig::HttpRequest::end(int status, MHD_Response *rsp)
{
if (!rsp) {
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
}
MHD_add_response_header(rsp, "Content-Type", "application/json");
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT");
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
const int ret = MHD_queue_response(m_connection, status, rsp);
MHD_destroy_response(rsp);
return ret;
}
int xmrig::HttpRequest::auth(const char *accessToken)
{
if (!accessToken) {
return MHD_HTTP_OK;
}
const char *header = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Authorization");
if (accessToken && !header) {
return MHD_HTTP_UNAUTHORIZED;
}
const size_t size = strlen(header);
if (size < 8 || strlen(accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
return MHD_HTTP_FORBIDDEN;
}
return strncmp(accessToken, header + 7, strlen(accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
}

84
src/api/HttpRequest.h Normal file
View File

@@ -0,0 +1,84 @@
/* 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 __HTTPREQUEST_H__
#define __HTTPREQUEST_H__
#include <stdint.h>
struct MHD_Connection;
struct MHD_Response;
namespace xmrig {
class HttpBody;
class HttpReply;
class HttpRequest
{
public:
enum Method {
Unsupported,
Options,
Get,
Put
};
HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls);
~HttpRequest();
inline bool isFulfilled() const { return m_fulfilled; }
inline bool isRestricted() const { return m_restricted; }
inline Method method() const { return m_method; }
bool match(const char *path) const;
bool process(const char *accessToken, bool restricted, xmrig::HttpReply &reply);
const char *body() const;
int end(const HttpReply &reply);
int end(int status, MHD_Response *rsp);
private:
int auth(const char *accessToken);
bool m_fulfilled;
bool m_restricted;
const char *m_uploadData;
const char *m_url;
HttpBody *m_body;
Method m_method;
MHD_Connection *m_connection;
size_t *m_uploadSize;
void **m_cls;
};
} /* namespace xmrig */
#endif /* __HTTPREQUEST_H__ */

View File

@@ -4,7 +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
@@ -28,14 +29,64 @@
#include "api/Api.h"
#include "api/Httpd.h"
#include "api/HttpReply.h"
#include "api/HttpRequest.h"
#include "log/Log.h"
Httpd::Httpd(int port, const char *accessToken) :
m_accessToken(accessToken),
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),
m_restricted(restricted),
m_accessToken(accessToken ? strdup(accessToken) : nullptr),
m_port(port),
m_daemon(nullptr)
{
uv_timer_init(uv_default_loop(), &m_timer);
m_timer.data = this;
}
Httpd::~Httpd()
{
uv_timer_stop(&m_timer);
if (m_daemon) {
MHD_stop_daemon(m_daemon);
}
delete m_accessToken;
}
@@ -46,11 +97,12 @@ bool Httpd::start()
}
unsigned int flags = 0;
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
if (m_IPv6 && MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
flags |= MHD_USE_DUAL_STACK;
}
else {
flags = MHD_USE_SELECT_INTERNALLY;
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
flags |= MHD_USE_EPOLL_LINUX_ONLY;
}
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
@@ -59,66 +111,61 @@ bool Httpd::start()
return false;
}
uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval);
return true;
}
int Httpd::auth(const char *header)
int Httpd::process(xmrig::HttpRequest &req)
{
if (!m_accessToken) {
return MHD_HTTP_OK;
xmrig::HttpReply reply;
if (!req.process(m_accessToken, m_restricted, reply)) {
return req.end(reply);
}
if (m_accessToken && !header) {
return MHD_HTTP_UNAUTHORIZED;
if (!req.isFulfilled()) {
return MHD_YES;
}
const size_t size = strlen(header);
if (size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
return MHD_HTTP_FORBIDDEN;
}
Api::exec(req, reply);
return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
return req.end(reply);
}
int Httpd::done(MHD_Connection *connection, int status, MHD_Response *rsp)
void Httpd::run()
{
if (!rsp) {
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
MHD_run(m_daemon);
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);
m_idle = false;
}
else if (!m_idle && !info->num_connections) {
uv_timer_set_repeat(&m_timer, kIdleInterval);
m_idle = true;
}
MHD_add_response_header(rsp, "Content-Type", "application/json");
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET");
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
const int ret = MHD_queue_response(connection, status, rsp);
MHD_destroy_response(rsp);
return ret;
}
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls)
{
if (strcmp(method, "OPTIONS") == 0) {
return done(connection, MHD_HTTP_OK, nullptr);
xmrig::HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls);
if (req.method() == xmrig::HttpRequest::Options) {
return req.end(MHD_HTTP_OK, nullptr);
}
if (strcmp(method, "GET") != 0) {
return MHD_NO;
if (req.method() == xmrig::HttpRequest::Unsupported) {
return req.end(MHD_HTTP_METHOD_NOT_ALLOWED, nullptr);
}
int status = static_cast<Httpd*>(cls)->auth(MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization"));
if (status != MHD_HTTP_OK) {
return done(connection, status, nullptr);
}
char *buf = Api::get(url, &status);
if (buf == nullptr) {
return MHD_NO;
}
MHD_Response *rsp = MHD_create_response_from_buffer(strlen(buf), (void*) buf, MHD_RESPMEM_MUST_FREE);
return done(connection, status, rsp);
return static_cast<Httpd*>(cls)->process(req);
}
void Httpd::onTimer(uv_timer_t *handle)
{
static_cast<Httpd*>(handle->data)->run();
}

View File

@@ -4,7 +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
@@ -33,21 +34,38 @@ struct MHD_Daemon;
struct MHD_Response;
class UploadCtx;
namespace xmrig {
class HttpRequest;
}
class Httpd
{
public:
Httpd(int port, const char *accessToken);
Httpd(int port, const char *accessToken, bool IPv6, bool restricted);
~Httpd();
bool start();
private:
int auth(const char *header);
constexpr static const int kIdleInterval = 200;
constexpr static const int kActiveInterval = 25;
static int done(MHD_Connection *connection, int status, MHD_Response *rsp);
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls);
int process(xmrig::HttpRequest &req);
void run();
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls);
static void onTimer(uv_timer_t *handle);
bool m_idle;
bool m_IPv6;
bool m_restricted;
const char *m_accessToken;
const int m_port;
MHD_Daemon *m_daemon;
uv_timer_t m_timer;
};
#endif /* __HTTPD_H__ */

View File

@@ -1,28 +1,36 @@
{
"background": false,
"log-file": null,
"access-log-file": null,
"retries": 5,
"retry-pause": 5,
"donate-level": 2,
"coin": "xmr",
"custom-diff": 0,
"syslog": false,
"verbose": false,
"workers": true,
"pools": [
{
"url": "pool.minemonero.pro:5555",
"user": "",
"pass": "x"
}
],
"bind": [
"0.0.0.0:3333"
],
"algo": "cryptonight",
"api": {
"port": 0,
"access-token": null,
"worker-id": null
}
"worker-id": null,
"ipv6": true,
"restricted": true
},
"background": false,
"bind": [
"0.0.0.0:3333",
"[::]:3333"
],
"colors": true,
"custom-diff": 0,
"donate-level": 2,
"log-file": null,
"mode": "nicehash",
"pools": [
{
"url": "failover.xmrig.com:443",
"user": "YOUR_WALLET",
"pass": "x",
"variant": -1
}
],
"retries": 2,
"retry-pause": 1,
"reuse-timeout": 0,
"user-agent": null,
"verbose": false,
"watch": true,
"workers": true
}

298
src/core/Config.cpp Normal file
View File

@@ -0,0 +1,298 @@
/* 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 <string.h>
#include <uv.h>
#include "core/Config.h"
#include "core/ConfigLoader.h"
#include "donate.h"
#include "log/Log.h"
#include "net/Url.h"
#include "proxy/Addr.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
static const char *algoNames[] = {
"cryptonight",
"cryptonight-lite"
};
static const char *modeNames[] = {
"nicehash",
"simple"
};
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#ifdef _WIN32
# define strncasecmp _strnicmp
#endif
xmrig::Config::Config() :
m_adjusted(false),
m_apiIPv6(true),
m_apiRestricted(true),
m_background(false),
m_colors(true),
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();
}
bool xmrig::Config::reload(const char *json)
{
return xmrig::ConfigLoader::reload(this, 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)
{
doc.SetObject();
auto &allocator = doc.GetAllocator();
doc.AddMember("access-log-file", accessLog() ? rapidjson::Value(rapidjson::StringRef(accessLog())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator);
rapidjson::Value api(rapidjson::kObjectType);
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);
doc.AddMember("api", api, allocator);
doc.AddMember("background", background(), allocator);
rapidjson::Value bind(rapidjson::kArrayType);
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("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);
doc.AddMember("mode", rapidjson::StringRef(modeName()), allocator);
rapidjson::Value pools(rapidjson::kArrayType);
for (const Url *url : 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);
pools.PushBack(obj, allocator);
}
doc.AddMember("pools", pools, allocator);
doc.AddMember("retries", retries(), allocator);
doc.AddMember("retry-pause", retryPause(), allocator);
doc.AddMember("reuse-timeout", reuseTimeout(), allocator);
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);
# endif
doc.AddMember("verbose", verbose(), allocator);
doc.AddMember("watch", m_watch, allocator);
doc.AddMember("workers", workers(), allocator);
}
xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *listener)
{
return xmrig::ConfigLoader::load(argc, argv, listener);
}
void xmrig::Config::adjust()
{
if (m_adjusted) {
return;
}
m_adjusted = true;
for (Url *url : m_pools) {
url->adjust(algorithm());
}
}
void xmrig::Config::setAlgo(const char *algo)
{
const size_t size = sizeof(algoNames) / sizeof((algoNames)[0]);
for (size_t i = 0; i < size; i++) {
if (algoNames[i] && !strcmp(algo, algoNames[i])) {
m_algorithm = (int) i;
break;
}
if (i == size - 1 && !strcmp(algo, "cryptonight-light")) {
m_algorithm = CRYPTONIGHT_LITE;
break;
}
}
}
void xmrig::Config::setCoin(const char *coin)
{
if (strncasecmp(coin, "aeon", 4) == 0) {
m_algorithm = CRYPTONIGHT_LITE;
}
}
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]);
for (size_t i = 0; i < size; i++) {
if (modeNames[i] && !strcmp(mode, modeNames[i])) {
m_mode = (int) i;
break;
}
}
}

View File

@@ -4,7 +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
@@ -21,90 +22,132 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __OPTIONS_H__
#define __OPTIONS_H__
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <stdint.h>
#include <vector>
#include "proxy/Addr.h"
#include "rapidjson/fwd.h"
class Addr;
class Url;
struct option;
class Options
namespace xmrig {
class ConfigLoader;
class IWatcherListener;
/**
* @brief The Config class
*
* Options with dynamic reload:
* colors
* debug
* verbose
* custom-diff (only for new connections)
* api/worker-id
* pools/
*/
class Config
{
public:
static inline Options* i() { return m_self; }
static Options *parse(int argc, char **argv);
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);
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 *coin() const { return m_userAgent; }
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 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; }
inline static void release() { delete m_self; }
private:
Options(int argc, char **argv);
~Options();
inline bool isReady() const { return m_ready; }
static Options *m_self;
bool getJSON(const char *fileName, rapidjson::Document &doc);
bool parseArg(int key, const char *arg);
bool parseArg(int key, uint64_t arg);
bool parseBoolean(int key, bool enable);
Url *parseUrl(const char *arg) const;
void parseConfig(const char *fileName);
void parseJSON(const struct option *option, const rapidjson::Value &object);
void showUsage(int status) const;
void showVersion(void);
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_coin;
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;
uint64_t m_diff;
};
#endif /* __OPTIONS_H__ */
} /* namespace xmrig */
#endif /* __CONFIG_H__ */

539
src/core/ConfigLoader.cpp Normal file
View File

@@ -0,0 +1,539 @@
/* 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 <limits.h>
#include <stdio.h>
#include <uv.h>
#ifndef XMRIG_NO_HTTPD
# include <microhttpd.h>
#endif
#include "core/Config.h"
#include "core/ConfigLoader.h"
#include "core/ConfigLoader_static.h"
#include "core/ConfigWatcher.h"
#include "interfaces/IWatcherListener.h"
#include "net/Url.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::IWatcherListener *xmrig::ConfigLoader::m_listener = nullptr;
bool xmrig::ConfigLoader::loadFromFile(xmrig::Config *config, const char *fileName)
{
rapidjson::Document doc;
if (!getJSON(fileName, doc)) {
return false;
}
config->setFileName(fileName);
return loadFromJSON(config, doc);
}
bool xmrig::ConfigLoader::loadFromJSON(xmrig::Config *config, const char *json)
{
rapidjson::Document doc;
doc.Parse(json);
if (doc.HasParseError() || !doc.IsObject()) {
return false;
}
return loadFromJSON(config, doc);
}
bool xmrig::ConfigLoader::loadFromJSON(xmrig::Config *config, const rapidjson::Document &doc)
{
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
parseJSON(config, &config_options[i], doc);
}
const rapidjson::Value &pools = doc["pools"];
if (pools.IsArray()) {
for (const rapidjson::Value &value : pools.GetArray()) {
if (!value.IsObject()) {
continue;
}
for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) {
parseJSON(config, &pool_options[i], value);
}
}
}
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++) {
parseJSON(config, &api_options[i], api);
}
}
config->adjust();
return config->isValid();
}
bool xmrig::ConfigLoader::reload(xmrig::Config *oldConfig, const char *json)
{
xmrig::Config *config = new xmrig::Config();
if (!loadFromJSON(config, json)) {
delete config;
return false;
}
config->setFileName(oldConfig->fileName());
const bool saved = config->save();
if (config->watch() && m_watcher && saved) {
delete config;
return true;
}
m_listener->onNewConfig(config);
return true;
}
xmrig::Config *xmrig::ConfigLoader::load(int argc, char **argv, IWatcherListener *listener)
{
m_listener = listener;
xmrig::Config *config = new xmrig::Config();
int key;
while (1) {
key = getopt_long(argc, argv, short_options, options, NULL);
if (key < 0) {
break;
}
if (!parseArg(config, key, optarg)) {
delete config;
return nullptr;
}
}
if (optind < argc) {
fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]);
delete config;
return nullptr;
}
if (!config->isValid()) {
loadFromFile(config, Platform::defaultConfigName());
}
if (!config->isValid()) {
fprintf(stderr, "No pool URL supplied. Exiting.\n");
delete config;
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);
}
config->adjust();
return config;
}
void xmrig::ConfigLoader::release()
{
delete m_watcher;
}
bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc)
{
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
if (fd < 0) {
fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
return false;
}
uv_fs_req_cleanup(&req);
FILE *fp = fdopen(fd, "rb");
char buf[8192];
rapidjson::FileReadStream is(fp, buf, sizeof(buf));
doc.ParseStream(is);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
if (doc.HasParseError()) {
printf("%s<%d>: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
return false;
}
return doc.IsObject();
}
bool xmrig::ConfigLoader::parseArg(xmrig::Config *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 */
showVersion();
return false;
case 'h': /* --help */
showUsage(0);
return false;
case 'c': /* --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 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)
{
if (!option->name || !object.HasMember(option->name)) {
return;
}
const rapidjson::Value &value = object[option->name];
if (option->has_arg && value.IsString()) {
parseArg(config, option->val, value.GetString());
}
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());
}
}
void xmrig::ConfigLoader::showUsage(int status)
{
if (status) {
fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n");
}
else {
printf(usage);
}
}
void xmrig::ConfigLoader::showVersion()
{
printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
# if defined(__clang__)
" with clang " __clang_version__);
# elif defined(__GNUC__)
" with GCC");
printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
" with MSVC");
printf(" %d", MSVC_VERSION);
# else
);
# endif
printf("\n features:"
# if defined(__i386__) || defined(_M_IX86)
" i386"
# elif defined(__x86_64__) || defined(_M_AMD64)
" x86_64"
# endif
# if defined(__AES__) || defined(_MSC_VER)
" AES-NI"
# endif
"\n");
printf("\nlibuv/%s\n", uv_version_string());
# ifndef XMRIG_NO_HTTPD
printf("libmicrohttpd/%s\n", MHD_get_version());
# endif
}

72
src/core/ConfigLoader.h Normal file
View File

@@ -0,0 +1,72 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 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_H__
#define __CONFIGLOADER_H__
#include <stdint.h>
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class Config;
class ConfigWatcher;
class IWatcherListener;
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 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 void showVersion();
static ConfigWatcher *m_watcher;
static IWatcherListener *m_listener;
};
} /* namespace xmrig */
#endif /* __CONFIGLOADER_H__ */

View File

@@ -0,0 +1,175 @@
/* 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_STATIC_H__
#define __CONFIGLOADER_STATIC_H__
#ifdef _MSC_VER
# include "getopt/getopt.h"
#else
# include <getopt.h>
#endif
#include "version.h"
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
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\
-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, 'A' },
{ "algo", 1, nullptr, 'a' },
{ "api-access-token", 1, nullptr, 4001 },
{ "api-no-ipv6", 0, nullptr, 4003 },
{ "api-no-restricted", 0, nullptr, 4004 },
{ "api-port", 1, nullptr, 4000 },
{ "api-worker-id", 1, nullptr, 4002 },
{ "background", 0, nullptr, 'B' },
{ "bind", 1, nullptr, 'b' },
{ "coin", 1, nullptr, 1104 },
{ "config", 1, nullptr, 'c' },
{ "custom-diff", 1, nullptr, 1102 },
{ "debug", 0, nullptr, 1101 },
{ "donate-level", 1, nullptr, 1003 },
{ "help", 0, nullptr, 'h' },
{ "keepalive", 0, nullptr ,'k' },
{ "log-file", 1, nullptr, 'l' },
{ "no-color", 0, nullptr, 1002 },
{ "no-watch", 0, nullptr, 1105 },
{ "no-workers", 0, nullptr, 1103 },
{ "pass", 1, nullptr, 'p' },
{ "pool-coin", 1, nullptr, 'C' },
{ "retries", 1, nullptr, 'r' },
{ "retry-pause", 1, nullptr, 'R' },
{ "syslog", 0, nullptr, 'S' },
{ "url", 1, nullptr, 'o' },
{ "user", 1, nullptr, 'u' },
{ "user-agent", 1, nullptr, 1008 },
{ "userpass", 1, nullptr, 'O' },
{ "verbose", 0, nullptr, 1100 },
{ "version", 0, nullptr, 'V' },
{ "variant", 1, nullptr, 1010 },
{ "reuse-timeout", 1, nullptr, 1106 },
{ "mode", 1, nullptr, 'm' },
{ 0, 0, 0, 0 }
};
static struct option const config_options[] = {
{ "access-log-file", 1, nullptr, 'A' },
{ "algo", 1, nullptr, 'a' },
{ "background", 0, nullptr, 'B' },
{ "coin", 1, nullptr, 1104 },
{ "colors", 0, nullptr, 2000 },
{ "custom-diff", 1, nullptr, 1102 },
{ "debug", 0, nullptr, 1101 },
{ "donate-level", 1, nullptr, 1003 },
{ "log-file", 1, nullptr, 'l' },
{ "retries", 1, nullptr, 'r' },
{ "retry-pause", 1, nullptr, 'R' },
{ "syslog", 0, nullptr, 'S' },
{ "user-agent", 1, nullptr, 1008 },
{ "verbose", 0, nullptr, 1100 },
{ "watch", 0, nullptr, 1105 },
{ "workers", 0, nullptr, 1103 },
{ "reuse-timeout", 1, nullptr, 1106 },
{ "mode", 1, nullptr, 'm' },
{ 0, 0, 0, 0 }
};
static struct option const pool_options[] = {
{ "url", 1, nullptr, 'o' },
{ "pass", 1, nullptr, 'p' },
{ "user", 1, nullptr, 'u' },
{ "userpass", 1, nullptr, 'O' },
{ "coin", 1, nullptr, 'C' },
{ "variant", 1, nullptr, 1010 },
{ 0, 0, 0, 0 }
};
static struct option const api_options[] = {
{ "port", 1, nullptr, 4000 },
{ "access-token", 1, nullptr, 4001 },
{ "worker-id", 1, nullptr, 4002 },
{ "ipv6", 0, nullptr, 4003 },
{ "restricted", 0, nullptr, 4004 },
{ 0, 0, 0, 0 }
};
} /* namespace xmrig */
#endif /* __CONFIGLOADER_STATIC_H__ */

106
src/core/ConfigWatcher.cpp Normal file
View File

@@ -0,0 +1,106 @@
/* 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 <stdio.h>
#include "core/Config.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)
{
uv_fs_event_init(uv_default_loop(), &m_fsEvent);
uv_timer_init(uv_default_loop(), &m_timer);
m_fsEvent.data = m_timer.data = this;
start();
}
xmrig::ConfigWatcher::~ConfigWatcher()
{
uv_timer_stop(&m_timer);
uv_fs_event_stop(&m_fsEvent);
free(m_path);
}
void xmrig::ConfigWatcher::onTimer(uv_timer_t* handle)
{
static_cast<xmrig::ConfigWatcher *>(handle->data)->reload();
}
void xmrig::ConfigWatcher::onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status)
{
if (!filename) {
return;
}
static_cast<xmrig::ConfigWatcher *>(handle->data)->queueUpdate();
}
void xmrig::ConfigWatcher::queueUpdate()
{
uv_timer_stop(&m_timer);
uv_timer_start(&m_timer, xmrig::ConfigWatcher::onTimer, kDelay, 0);
}
void xmrig::ConfigWatcher::reload()
{
LOG_WARN("\"%s\" was changed, reloading configuration", m_path);
xmrig::Config *config = new xmrig::Config();
ConfigLoader::loadFromFile(config, m_path);
if (!config->isValid()) {
LOG_ERR("reloading failed");
delete config;
return;
}
m_listener->onNewConfig(config);
# ifndef _WIN32
uv_fs_event_stop(&m_fsEvent);
start();
# endif
}
void xmrig::ConfigWatcher::start()
{
uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path, 0);
}

68
src/core/ConfigWatcher.h Normal file
View File

@@ -0,0 +1,68 @@
/* 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 __CONFIGWATCHER_H__
#define __CONFIGWATCHER_H__
#include <stdint.h>
#include <uv.h>
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class Config;
class IWatcherListener;
class ConfigWatcher
{
public:
ConfigWatcher(const char *path, IWatcherListener *listener);
~ConfigWatcher();
private:
constexpr static int kDelay = 500;
static void onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status);
static void onTimer(uv_timer_t* handle);
void queueUpdate();
void reload();
void start();
char *m_path;
IWatcherListener *m_listener;
uv_fs_event_t m_fsEvent;
uv_timer_t m_timer;
};
} /* namespace xmrig */
#endif /* __CONFIGWATCHER_H__ */

147
src/core/Controller.cpp Normal file
View File

@@ -0,0 +1,147 @@
/* 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/>.
*/
#include "core/Config.h"
#include "core/ConfigLoader.h"
#include "core/Controller.h"
#include "log/ConsoleLog.h"
#include "log/FileLog.h"
#include "log/Log.h"
#include "Platform.h"
#include "proxy/Proxy.h"
#include "interfaces/IControllerListener.h"
#ifdef HAVE_SYSLOG_H
# include "log/SysLog.h"
#endif
class xmrig::ControllerPrivate
{
public:
inline ControllerPrivate() :
proxy(nullptr),
config(nullptr)
{}
inline ~ControllerPrivate()
{
delete proxy;
delete config;
}
Proxy *proxy;
xmrig::Config *config;
std::vector<xmrig::IControllerListener *> listeners;
};
xmrig::Controller::Controller()
: d_ptr(new ControllerPrivate())
{
}
xmrig::Controller::~Controller()
{
ConfigLoader::release();
delete d_ptr;
}
xmrig::Config *xmrig::Controller::config() const
{
return d_ptr->config;
}
const StatsData &xmrig::Controller::statsData() const
{
return proxy()->statsData();
}
const std::vector<Worker> &xmrig::Controller::workers() const
{
return proxy()->workers();
}
int xmrig::Controller::init(int argc, char **argv)
{
d_ptr->config = xmrig::Config::load(argc, argv, this);
if (!d_ptr->config) {
return 1;
}
Log::init();
Platform::init(config()->userAgent());
if (!config()->background()) {
Log::add(new ConsoleLog(this));
}
if (config()->logFile()) {
Log::add(new FileLog(config()->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (config()->syslog()) {
Log::add(new SysLog());
}
# endif
d_ptr->proxy = new Proxy(this);
return 0;
}
Proxy *xmrig::Controller::proxy() const
{
return d_ptr->proxy;
}
void xmrig::Controller::addListener(IControllerListener *listener)
{
d_ptr->listeners.push_back(listener);
}
void xmrig::Controller::onNewConfig(Config *config)
{
xmrig::Config *previousConfig = d_ptr->config;
d_ptr->config = config;
for (xmrig::IControllerListener *listener : d_ptr->listeners) {
listener->onConfigChanged(config, previousConfig);
}
delete previousConfig;
}

66
src/core/Controller.h Normal file
View File

@@ -0,0 +1,66 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 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 __CONTROLLER_H__
#define __CONTROLLER_H__
#include "interfaces/IWatcherListener.h"
#include "proxy/workers/Worker.h"
class Proxy;
class StatsData;
namespace xmrig {
class Config;
class ControllerPrivate;
class IControllerListener;
class Controller : public IWatcherListener
{
public:
Controller();
~Controller();
Config *config() const;
const StatsData &statsData() const;
const std::vector<Worker> &workers() const;
int init(int argc, char **argv);
Proxy *proxy() const;
void addListener(IControllerListener *listener);
protected:
void onNewConfig(Config *config) override;
private:
ControllerPrivate *d_ptr;
};
} /* namespace xmrig */
#endif /* __CONTROLLER_H__ */

View File

@@ -0,0 +1,46 @@
/* 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 __ICONTROLLERLISTENER_H__
#define __ICONTROLLERLISTENER_H__
namespace xmrig {
class Config;
class IControllerListener
{
public:
virtual ~IControllerListener() {}
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
};
} /* namespace xmrig */
#endif // __ICONTROLLERLISTENER_H__

View File

@@ -0,0 +1,71 @@
/* 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 __ISPLITTER_H__
#define __ISPLITTER_H__
#include <stdint.h>
class Upstreams
{
public:
inline Upstreams() : active(0), sleep(0), total(0), error(0), ratio(0.0) {}
inline Upstreams(uint64_t active, uint64_t sleep, uint64_t total, uint64_t miners) :
active(active),
sleep(sleep),
total(total),
error(total - active - sleep),
ratio(active > 0 ? ((double) miners / active) : 0.0)
{}
uint64_t active;
uint64_t sleep;
uint64_t total;
uint64_t error;
double ratio;
};
class ISplitter
{
public:
virtual ~ISplitter() {}
virtual Upstreams upstreams() const = 0;
virtual void connect() = 0;
virtual void gc() = 0;
virtual void printConnections() = 0;
virtual void tick(uint64_t ticks) = 0;
# ifdef APP_DEVEL
virtual void printState() = 0;
# endif
};
#endif // __ISPLITTER_H__

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,10 +39,10 @@ class IStrategyListener
public:
virtual ~IStrategyListener() {}
virtual void onActive(Client *client) = 0;
virtual void onJob(Client *client, const Job &job) = 0;
virtual void onPause(IStrategy *strategy) = 0;
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
virtual void onActive(IStrategy *strategy, Client *client) = 0;
virtual void onJob(IStrategy *strategy, Client *client, const Job &job) = 0;
virtual void onPause(IStrategy *strategy) = 0;
virtual void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) = 0;
};

View File

@@ -0,0 +1,46 @@
/* 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 __IWATCHERLISTENER_H__
#define __IWATCHERLISTENER_H__
namespace xmrig {
class Config;
class IWatcherListener
{
public:
virtual ~IWatcherListener() {}
virtual void onNewConfig(Config *config) = 0;
};
} /* namespace xmrig */
#endif // __IWATCHERLISTENER_H__

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -28,8 +28,9 @@
#include <time.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "log/AccessLog.h"
#include "Options.h"
#include "proxy/Counters.h"
#include "proxy/events/CloseEvent.h"
#include "proxy/events/LoginEvent.h"
@@ -38,15 +39,16 @@
#include "proxy/Stats.h"
AccessLog::AccessLog() :
AccessLog::AccessLog(xmrig::Controller *controller) :
m_file(-1)
{
if (!Options::i()->accessLog()) {
const char *fileName = controller->config()->accessLog();
if (!fileName) {
return;
}
uv_fs_t req;
m_file = uv_fs_open(uv_default_loop(), &req, Options::i()->accessLog(), O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
uv_fs_req_cleanup(&req);
}

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -34,10 +34,15 @@
class Stats;
namespace xmrig {
class Controller;
}
class AccessLog : public IEventListener
{
public:
AccessLog();
AccessLog(xmrig::Controller *controller);
~AccessLog();
protected:

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -34,15 +34,18 @@
#endif
#include "core/Config.h"
#include "core/Controller.h"
#include "log/ConsoleLog.h"
#include "log/Log.h"
ConsoleLog::ConsoleLog(bool colors) :
m_colors(colors),
m_stream(nullptr)
ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
m_stream(nullptr),
m_controller(controller)
{
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
controller->config()->setColors(false);
return;
}
@@ -65,10 +68,6 @@ ConsoleLog::ConsoleLog(bool colors) :
void ConsoleLog::message(int level, const char* fmt, va_list args)
{
if (!isWritable()) {
return;
}
time_t now = time(nullptr);
tm stime;
@@ -79,7 +78,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
# endif
const char* color = nullptr;
if (m_colors) {
const bool colors = m_controller->config()->colors();
if (colors) {
switch (level) {
case Log::ERR:
color = Log::kCL_RED;
@@ -110,9 +111,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
m_colors ? color : "",
colors ? color : "",
fmt,
m_colors ? Log::kCL_N : ""
colors ? Log::kCL_N : ""
);
print(args);
@@ -121,11 +122,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
void ConsoleLog::text(const char* fmt, va_list args)
{
if (!isWritable()) {
return;
}
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->colors() ? Log::kCL_N : "");
print(args);
}
@@ -149,5 +146,11 @@ void ConsoleLog::print(va_list args)
return;
}
uv_try_write(m_stream, &m_uvBuf, 1);
if (!isWritable()) {
fputs(m_buf, stdout);
fflush(stdout);
}
else {
uv_try_write(m_stream, &m_uvBuf, 1);
}
}

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -31,10 +31,15 @@
#include "interfaces/ILogBackend.h"
namespace xmrig {
class Controller;
}
class ConsoleLog : public ILogBackend
{
public:
ConsoleLog(bool colors);
ConsoleLog(xmrig::Controller *controller);
void message(int level, const char *fmt, va_list args) override;
void text(const char *fmt, va_list args) override;
@@ -43,12 +48,12 @@ private:
bool isWritable() const;
void print(va_list args);
bool m_colors;
char m_buf[512];
char m_fmt[256];
uv_buf_t m_uvBuf;
uv_stream_t *m_stream;
uv_tty_t m_tty;
xmrig::Controller *m_controller;
};
#endif /* __CONSOLELOG_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,16 +25,19 @@
#include <inttypes.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "log/ShareLog.h"
#include "net/SubmitResult.h"
#include "Options.h"
#include "proxy/events/AcceptEvent.h"
#include "proxy/Miner.h"
#include "proxy/Stats.h"
ShareLog::ShareLog(const Stats &stats) :
m_stats(stats)
ShareLog::ShareLog(xmrig::Controller *controller, const Stats &stats) :
m_stats(stats),
m_controller(controller)
{
}
@@ -72,15 +75,21 @@ void ShareLog::onRejectedEvent(IEvent *event)
}
bool ShareLog::isColors() const
{
return m_controller->config()->colors();
}
void ShareLog::accept(const AcceptEvent *event)
{
if (!Options::i()->verbose()) {
if (!m_controller->config()->verbose()) {
return;
}
LOG_INFO(Options::i()->colors() ? "#%03u \x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
: "#%03u accepted (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u (%" PRIu64 " ms)",
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->result.elapsed);
LOG_INFO(isColors() ? "#%03u \x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[01;30m(%" PRIu64 " ms)"
: "#%03u accepted (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u ip %s (%" PRIu64 " ms)",
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->ip(), event->result.elapsed);
}
@@ -90,7 +99,7 @@ void ShareLog::reject(const AcceptEvent *event)
return;
}
LOG_INFO(Options::i()->colors() ? "#%03u \x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRId64 " ms)"
: "#%03u rejected (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u \"%s\" (%" PRId64 " ms)",
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->error(), event->result.elapsed);
LOG_INFO(isColors() ? "#%03u \x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRId64 " ms)"
: "#%03u rejected (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u ip %s \"%s\" (%" PRId64 " ms)",
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->ip(), event->error(), event->result.elapsed);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,10 +32,15 @@ class AcceptEvent;
class Stats;
namespace xmrig {
class Controller;
}
class ShareLog : public IEventListener
{
public:
ShareLog(const Stats &stats);
ShareLog(xmrig::Controller *controller, const Stats &stats);
~ShareLog();
protected:
@@ -43,10 +48,12 @@ protected:
void onRejectedEvent(IEvent *event) override;
private:
bool isColors() const;
void accept(const AcceptEvent *event);
void reject(const AcceptEvent *event);
const Stats &m_stats;
xmrig::Controller *m_controller;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <inttypes.h>
#include <iterator>
#include <stdio.h>
@@ -54,6 +55,8 @@ int64_t Client::m_sequence = 1;
Client::Client(int id, const char *agent, IClientListener *listener) :
m_ipv6(false),
m_nicehash(false),
m_quiet(false),
m_agent(agent),
m_listener(listener),
@@ -63,6 +66,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_recvBufPos(0),
m_state(UnconnectedState),
m_expire(0),
m_jobs(0),
m_stream(nullptr),
m_socket(nullptr)
{
@@ -71,7 +75,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_resolver.data = this;
m_hints.ai_family = PF_INET;
m_hints.ai_family = AF_UNSPEC;
m_hints.ai_socktype = SOCK_STREAM;
m_hints.ai_protocol = IPPROTO_TCP;
@@ -109,16 +113,17 @@ void Client::connect(const Url *url)
}
void Client::disconnect()
void Client::deleteLater()
{
# ifndef XMRIG_PROXY_PROJECT
uv_timer_stop(&m_keepAliveTimer);
# endif
if (!m_listener) {
return;
}
m_expire = 0;
m_failures = -1;
m_listener = nullptr;
close();
if (!disconnect()) {
delete this;
}
}
@@ -150,6 +155,19 @@ 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;
return close();
}
int64_t Client::submit(const JobResult &result)
{
# ifdef XMRIG_PROXY_PROJECT
@@ -167,13 +185,55 @@ int64_t Client::submit(const JobResult &result)
# endif
const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
m_sequence, m_rpcId, result.jobId.data(), nonce, data);
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
# ifdef XMRIG_PROXY_PROJECT
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
# else
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
# endif
return send(size);
}
bool Client::close()
{
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
return false;
}
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 {
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
}
return true;
}
bool Client::isCriticalError(const char *message)
{
if (!message) {
@@ -203,7 +263,14 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
return false;
}
Job job(m_id, m_url.isNicehash());
# ifdef XMRIG_PROXY_PROJECT
Job job(m_id, m_url.variant());
job.setClientId(m_rpcId);
job.setCoin(m_url.coin());
# else
Job job(m_id, m_nicehash, m_url.algo(), m_url.variant());
# endif
if (!job.setId(params["job_id"].GetString())) {
*code = 3;
return false;
@@ -219,32 +286,52 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
return false;
}
if (m_job == job) {
if (!m_quiet) {
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
}
if (params.HasMember("coin")) {
job.setCoin(params["coin"].GetString());
}
close();
if (params.HasMember("variant")) {
job.setVariant(params["variant"].GetInt());
}
if (m_job != job) {
m_jobs++;
m_job = std::move(job);
return true;
}
if (m_jobs == 0) { // https://github.com/xmrig/xmrig/issues/459
return false;
}
m_job = std::move(job);
return true;
if (!m_quiet) {
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
}
close();
return false;
}
bool Client::parseLogin(const rapidjson::Value &result, int *code)
{
const char *id = result["id"].GetString();
if (!id || strlen(id) >= sizeof(m_rpcId)) {
if (!m_rpcId.setId(result["id"].GetString())) {
*code = 1;
return false;
}
memset(m_rpcId, 0, sizeof(m_rpcId));
memcpy(m_rpcId, id, strlen(id));
# ifndef XMRIG_PROXY_PROJECT
m_nicehash = m_url.isNicehash();
# endif
return parseJob(result["job"], code);
if (result.HasMember("extensions")) {
parseExtensions(result["extensions"]);
}
const bool rc = parseJob(result["job"], code);
m_jobs = 0;
return rc;
}
@@ -259,7 +346,7 @@ int Client::resolve(const char *host)
m_failures = 0;
}
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
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));
@@ -291,21 +378,25 @@ int64_t Client::send(size_t size)
}
void Client::close()
void Client::connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6)
{
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) {
return;
addrinfo *addr = nullptr;
m_ipv6 = ipv4.empty() && !ipv6.empty();
if (m_ipv6) {
addr = ipv6[ipv6.size() == 1 ? 0 : rand() % ipv6.size()];
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), m_ip, 45);
}
else {
addr = ipv4[ipv4.size() == 1 ? 0 : rand() % ipv4.size()];
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), m_ip, 16);
}
setState(ClosingState);
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
}
connect(addr->ai_addr);
}
void Client::connect(struct sockaddr *addr)
void Client::connect(sockaddr *addr)
{
setState(ConnectingState);
@@ -366,6 +457,18 @@ void Client::login()
}
void Client::onClose()
{
delete m_socket;
m_stream = nullptr;
m_socket = nullptr;
setState(UnconnectedState);
reconnect();
}
void Client::parse(char *line, size_t len)
{
startTimeout();
@@ -374,6 +477,14 @@ void Client::parse(char *line, size_t len)
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
if (len < 32 || line[0] != '{') {
if (!m_quiet) {
LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
}
return;
}
rapidjson::Document doc;
if (doc.ParseInsitu(line).HasParseError()) {
if (!m_quiet) {
@@ -397,6 +508,24 @@ void Client::parse(char *line, size_t len)
}
void Client::parseExtensions(const rapidjson::Value &value)
{
if (!value.IsArray()) {
return;
}
for (const rapidjson::Value &ext : value.GetArray()) {
if (!ext.IsString()) {
continue;
}
if (strcmp(ext.GetString(), "nicehash") == 0) {
m_nicehash = true;
}
}
}
void Client::parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error)
{
if (error.IsObject()) {
@@ -456,7 +585,8 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
}
return close();
close();
return;
}
m_failures = 0;
@@ -476,12 +606,18 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap
void Client::ping()
{
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId));
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId.data()));
}
void Client::reconnect()
{
if (!m_listener) {
delete this;
return;
}
setState(ConnectingState);
# ifndef XMRIG_PROXY_PROJECT
@@ -530,6 +666,9 @@ void Client::startTimeout()
void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
{
auto client = getClient(handle->data);
if (!client) {
return;
}
buf->base = &client->m_recvBuf.base[client->m_recvBufPos];
buf->len = client->m_recvBuf.len - client->m_recvBufPos;
@@ -539,20 +678,21 @@ void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
void Client::onClose(uv_handle_t *handle)
{
auto client = getClient(handle->data);
if (!client) {
return;
}
delete client->m_socket;
client->m_stream = nullptr;
client->m_socket = nullptr;
client->setState(UnconnectedState);
client->reconnect();
client->onClose();
}
void Client::onConnect(uv_connect_t *req, int status)
{
auto client = getClient(req->data);
if (!client) {
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));
@@ -577,22 +717,28 @@ void Client::onConnect(uv_connect_t *req, int status)
void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
auto client = getClient(stream->data);
if (!client) {
return;
}
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));
}
return client->close();;
client->close();
return;
}
if ((size_t) nread > (sizeof(m_buf) - 8 - client->m_recvBufPos)) {
return client->close();;
client->close();
return;
}
client->m_recvBufPos += nread;
char* end;
char* start = buf->base;
char* start = client->m_recvBuf.base;
size_t remaining = client->m_recvBufPos;
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
@@ -609,11 +755,11 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
return;
}
if (start == buf->base) {
if (start == client->m_recvBuf.base) {
return;
}
memcpy(buf->base, start, remaining);
memcpy(client->m_recvBuf.base, start, remaining);
client->m_recvBufPos = remaining;
}
@@ -621,31 +767,43 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
{
auto client = getClient(req->data);
if (!client) {
return;
}
if (status < 0) {
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
return client->reconnect();;
if (!client->m_quiet) {
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
}
return client->reconnect();
}
addrinfo *ptr = res;
std::vector<addrinfo*> ipv4;
std::vector<addrinfo*> ipv6;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
ipv4.push_back(ptr);
}
if (ptr->ai_family == AF_INET6) {
ipv6.push_back(ptr);
}
ptr = ptr->ai_next;
}
if (ipv4.empty()) {
LOG_ERR("[%s:%u] DNS error: \"No IPv4 records found\"", client->m_url.host(), client->m_url.port());
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());
}
uv_freeaddrinfo(res);
return client->reconnect();
}
ptr = ipv4[rand() % ipv4.size()];
uv_ip4_name(reinterpret_cast<sockaddr_in*>(ptr->ai_addr), client->m_ip, 16);
client->connect(ptr->ai_addr);
client->connect(ipv4, ipv6);
uv_freeaddrinfo(res);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,8 +27,10 @@
#include <map>
#include <uv.h>
#include <vector>
#include "net/Id.h"
#include "net/Job.h"
#include "net/SubmitResult.h"
#include "net/Url.h"
@@ -54,12 +56,12 @@ public:
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 disconnect();
void deleteLater();
void setUrl(const Url *url);
void tick(uint64_t now);
@@ -74,15 +76,20 @@ public:
inline void setRetryPause(int ms) { m_retryPause = ms; }
private:
~Client();
bool close();
bool isCriticalError(const char *message);
bool parseJob(const rapidjson::Value &params, int *code);
bool parseLogin(const rapidjson::Value &result, int *code);
int resolve(const char *host);
int64_t send(size_t size);
void close();
void connect(struct sockaddr *addr);
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
void connect(sockaddr *addr);
void login();
void onClose();
void parse(char *line, size_t len);
void parseExtensions(const rapidjson::Value &value);
void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error);
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
void ping();
@@ -99,10 +106,11 @@ private:
static inline Client *getClient(void *data) { return static_cast<Client*>(data); }
addrinfo m_hints;
bool m_ipv6;
bool m_nicehash;
bool m_quiet;
char m_buf[2048];
char m_ip[17];
char m_rpcId[64];
char m_ip[46];
char m_sendBuf[768];
const char *m_agent;
IClientListener *m_listener;
@@ -115,11 +123,13 @@ private:
static int64_t m_sequence;
std::map<int64_t, SubmitResult> m_results;
uint64_t m_expire;
uint64_t m_jobs;
Url m_url;
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;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,40 +21,51 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __JOBID_H__
#define __JOBID_H__
#ifndef __ID_H__
#define __ID_H__
#include <string.h>
class JobId
namespace xmrig {
class Id
{
public:
inline JobId()
inline Id()
{
memset(m_data, 0, sizeof(m_data));
}
inline JobId(const char *id, size_t sizeFix = 0)
inline Id(const char *id, size_t sizeFix = 0)
{
setId(id, sizeFix);
}
inline bool operator==(const JobId &other) const
inline bool operator==(const Id &other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) == 0;
}
inline bool operator!=(const JobId &other) const
inline bool operator!=(const Id &other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) != 0;
}
Id &operator=(const Id &other)
{
memcpy(m_data, other.m_data, sizeof(m_data));
return *this;
}
inline bool setId(const char *id, size_t sizeFix = 0)
{
memset(m_data, 0, sizeof(m_data));
@@ -80,4 +91,8 @@ private:
char m_data[64];
};
#endif /* __JOBID_H__ */
} /* namespace xmrig */
#endif /* __ID_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
#include "net/Job.h"
#include "xmrig.h"
static inline unsigned char hf_hex2bin(char c, bool &err)
@@ -55,14 +56,25 @@ static inline char hf_bin2hex(unsigned char c)
}
Job::Job(int poolId, bool nicehash) :
m_nicehash(nicehash),
m_poolId(poolId),
m_threadId(-1),
Job::Job() :
m_poolId(-2),
m_variant(xmrig::VARIANT_AUTO),
m_size(0),
m_diff(0),
m_target(0)
{
memset(m_coin, 0, sizeof(m_coin));
}
Job::Job(int poolId, int variant) :
m_poolId(poolId),
m_variant(variant),
m_size(0),
m_diff(0),
m_target(0)
{
memset(m_coin, 0, sizeof(m_coin));
}
@@ -91,10 +103,6 @@ bool Job::setBlob(const char *blob)
return false;
}
if (*nonce() != 0 && !m_nicehash) {
m_nicehash = true;
}
# ifdef XMRIG_PROXY_PROJECT
memset(m_rawBlob, 0, sizeof(m_rawBlob));
memcpy(m_rawBlob, blob, m_size * 2);
@@ -146,6 +154,16 @@ bool Job::setTarget(const char *target)
}
void Job::setCoin(const char *coin)
{
if (strlen(coin) > 4) {
return;
}
strncpy(m_coin, coin, sizeof(m_coin));
}
bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
{
bool error = false;
@@ -156,6 +174,7 @@ bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
return false;
}
}
return true;
}
@@ -173,3 +192,9 @@ bool Job::operator==(const Job &other) const
{
return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0;
}
bool Job::operator!=(const Job &other) const
{
return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0;
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,32 +30,36 @@
#include "align.h"
#include "net/JobId.h"
#include "net/Id.h"
class Job
{
public:
Job(int poolId = -2, bool nicehash = false);
Job();
Job(int poolId, int variant);
~Job();
bool setBlob(const char *blob);
bool setTarget(const char *target);
void setCoin(const char *coin);
inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
inline bool setId(const char *id) { return m_id.setId(id); }
inline const JobId &id() const { return m_id; }
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
inline const uint8_t *blob() const { return m_blob; }
inline int poolId() const { return m_poolId; }
inline int threadId() const { return m_threadId; }
inline size_t size() const { return m_size; }
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
inline uint32_t diff() const { return (uint32_t) m_diff; }
inline uint64_t target() const { return m_target; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
inline void setThreadId(int threadId) { m_threadId = threadId; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
inline bool setId(const char *id) { return m_id.setId(id); }
inline const char *coin() const { return m_coin; }
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
inline const uint8_t *blob() const { return m_blob; }
inline const xmrig::Id &clientId() const { return m_clientId; }
inline const xmrig::Id &id() const { return m_id; }
inline int poolId() const { return m_poolId; }
inline int variant() const { return m_variant; }
inline size_t size() const { return m_size; }
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
inline uint32_t diff() const { return (uint32_t) m_diff; }
inline uint64_t target() const { return m_target; }
inline void reset() { m_size = 0; m_diff = 0; }
inline void setClientId(const xmrig::Id &id) { m_clientId = id; }
inline void setVariant(int variant) { m_variant = variant; }
# ifdef XMRIG_PROXY_PROJECT
inline char *rawBlob() { return m_rawBlob; }
@@ -68,17 +72,19 @@ public:
static void toHex(const unsigned char* in, unsigned int len, char* out);
bool operator==(const Job &other) const;
bool operator!=(const Job &other) const;
private:
VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
bool m_nicehash;
char m_coin[5];
int m_poolId;
int m_threadId;
JobId m_id;
int m_variant;
size_t m_size;
uint64_t m_diff;
uint64_t m_target;
xmrig::Id m_clientId;
xmrig::Id m_id;
# ifdef XMRIG_PROXY_PROJECT
VAR_ALIGN(16, char m_rawBlob[169]);

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,7 +28,8 @@
#include "net/SubmitResult.h"
SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff) :
SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId) :
reqId(reqId),
seq(seq),
diff(diff),
actualDiff(actualDiff),

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,11 +31,12 @@
class SubmitResult
{
public:
inline SubmitResult() : seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {}
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff);
inline SubmitResult() : reqId(0), seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {}
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0);
void done();
int64_t reqId;
int64_t seq;
uint32_t diff;
uint64_t actualDiff;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,11 +22,15 @@
*/
#include <string.h>
#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
@@ -35,11 +39,12 @@
Url::Url() :
m_keepAlive(false),
m_nicehash(false),
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
m_coin(""),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(kDefaultPort)
{
}
@@ -57,22 +62,24 @@ Url::Url() :
* @param url
*/
Url::Url(const char *url) :
m_keepAlive(false),
m_nicehash(false),
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, bool keepAlive, bool nicehash) :
m_keepAlive(keepAlive),
m_nicehash(nicehash),
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);
@@ -84,12 +91,10 @@ Url::~Url()
free(m_host);
free(m_password);
free(m_user);
}
bool Url::isNicehash() const
{
return isValid() && (m_nicehash || strstr(m_host, ".nicehash.com"));
if (m_url) {
delete [] m_url;
}
}
@@ -110,6 +115,10 @@ bool Url::parse(const char *url)
return false;
}
if (base[0] == '[') {
return parseIPv6(base);
}
const char *port = strchr(base, ':');
if (!port) {
m_host = strdup(base);
@@ -117,9 +126,8 @@ bool Url::parse(const char *url)
}
const size_t size = port++ - base + 1;
m_host = static_cast<char*>(malloc(size));
m_host = new char[size]();
memcpy(m_host, base, size - 1);
m_host[size - 1] = '\0';
m_port = (uint16_t) strtol(port, nullptr, 10);
return true;
@@ -144,6 +152,52 @@ bool Url::setUserpass(const char *userpass)
}
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) {
@@ -166,11 +220,39 @@ void Url::setUser(const char *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_keepAlive = other->m_keepAlive;
m_nicehash = other->m_nicehash;
m_port = other->m_port;
m_port = other->m_port;
m_variant = other->m_variant;
free(m_host);
m_host = strdup(other->m_host);
@@ -178,5 +260,34 @@ Url &Url::operator=(const Url *other)
setPassword(other->m_password);
setUser(other->m_user);
memcpy(m_coin, other->coin(), sizeof(m_coin));
if (m_url) {
delete [] m_url;
m_url = nullptr;
}
return *this;
}
bool Url::parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return false;
}
const char *port = strchr(end, ':');
if (!port) {
return false;
}
const size_t size = end - addr;
m_host = new char[size]();
memcpy(m_host, addr + 1, size - 1);
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
return true;
}

View File

@@ -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
@@ -37,32 +37,38 @@ public:
Url();
Url(const char *url);
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false );
Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr);
~Url();
inline bool isKeepAlive() const { return m_keepAlive; }
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; }
inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
bool isNicehash() const;
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 m_keepAlive;
bool m_nicehash;
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;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,10 +22,13 @@
*/
#include "core/Config.h"
#include "core/Controller.h"
#include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/strategies/DonateStrategy.h"
#include "Options.h"
#include "Platform.h"
#include "proxy/StatsData.h"
extern "C"
@@ -39,26 +42,28 @@ static inline int random(int min, int max){
}
DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
DonateStrategy::DonateStrategy(size_t id, xmrig::Controller *controller, IStrategyListener *listener) :
m_active(false),
m_suspended(false),
m_listener(listener),
m_id(id),
m_donateTicks(0),
m_target(0),
m_ticks(0)
m_ticks(0),
m_controller(controller)
{
uint8_t hash[200];
char userId[65] = { 0 };
const char *user = Options::i()->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", Options::i()->coin() && strncmp(Options::i()->coin(), "aeon", 4) ? 3333 : 443, userId, nullptr, false, true);
Url *url = new Url("proxy.fee.xmrig.com", controller->config()->algorithm() == xmrig::Config::CRYPTONIGHT_LITE ? 7777 : 4444, userId, nullptr);
m_client = new Client(-1, agent, this);
m_client = new Client(-1, Platform::userAgent(), this);
m_client->setUrl(url);
m_client->setRetryPause(Options::i()->retryPause() * 1000);
m_client->setRetryPause(1000);
delete url;
@@ -66,9 +71,15 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
}
DonateStrategy::~DonateStrategy()
{
m_client->deleteLater();
}
bool DonateStrategy::reschedule()
{
const uint64_t level = Options::i()->donateLevel() * 60;
const uint64_t level = m_controller->config()->donateLevel() * 60;
if (m_donateTicks < level) {
return false;
}
@@ -112,6 +123,11 @@ void DonateStrategy::tick(uint64_t now)
m_ticks++;
if (m_ticks == m_target) {
if (m_id == 0 && m_controller->statsData().upstreams.active == 1) {
m_target += 600;
return;
}
m_client->connect();
}
@@ -136,10 +152,10 @@ void DonateStrategy::onJobReceived(Client *client, const Job &job)
{
if (!isActive()) {
m_active = true;
m_listener->onActive(client);
m_listener->onActive(this, client);
}
m_listener->onJob(client, job);
m_listener->onJob(this, client, job);
}
@@ -150,5 +166,5 @@ void DonateStrategy::onLoginSuccess(Client *client)
void DonateStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(client, result, error);
m_listener->onResultAccepted(this, client, result, error);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,10 +34,17 @@ class IStrategyListener;
class Url;
namespace xmrig {
class Controller;
}
class DonateStrategy : public IStrategy, public IClientListener
{
public:
DonateStrategy(const char *agent, IStrategyListener *listener);
DonateStrategy(size_t id, xmrig::Controller *controller, IStrategyListener *listener);
~DonateStrategy();
bool reschedule();
inline bool isActive() const override { return m_active; }
@@ -59,9 +66,11 @@ private:
bool m_suspended;
Client *m_client;
IStrategyListener *m_listener;
size_t m_id;
uint64_t m_donateTicks;
uint64_t m_target;
uint64_t m_ticks;
xmrig::Controller *m_controller;
};
#endif /* __SINGLEPOOLSTRATEGY_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,22 +25,37 @@
#include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/strategies/FailoverStrategy.h"
#include "Options.h"
#include "Platform.h"
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener) :
FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
m_quiet(quiet),
m_retries(retries),
m_retryPause(retryPause),
m_active(-1),
m_index(0),
m_listener(listener)
{
for (const Url *url : urls) {
add(url, agent);
add(url);
}
}
FailoverStrategy::~FailoverStrategy()
{
for (Client *client : m_pools) {
client->deleteLater();
}
}
int64_t FailoverStrategy::submit(const JobResult &result)
{
if (m_active == -1) {
return -1;
}
return m_pools[m_active]->submit(result);
}
@@ -57,7 +72,7 @@ void FailoverStrategy::resume()
return;
}
m_listener->onJob( m_pools[m_active], m_pools[m_active]->job());
m_listener->onJob(this, m_pools[m_active], m_pools[m_active]->job());
}
@@ -93,7 +108,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
m_listener->onPause(this);
}
if (m_index == 0 && failures < Options::i()->retries()) {
if (m_index == 0 && failures < m_retries) {
return;
}
@@ -106,7 +121,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
void FailoverStrategy::onJobReceived(Client *client, const Job &job)
{
if (m_active == client->id()) {
m_listener->onJob(client, job);
m_listener->onJob(this, client, job);
}
}
@@ -127,22 +142,23 @@ void FailoverStrategy::onLoginSuccess(Client *client)
if (active >= 0 && active != m_active) {
m_index = m_active = active;
m_listener->onActive(client);
m_listener->onActive(this, client);
}
}
void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(client, result, error);
m_listener->onResultAccepted(this, client, result, error);
}
void FailoverStrategy::add(const Url *url, const char *agent)
void FailoverStrategy::add(const Url *url)
{
Client *client = new Client((int) m_pools.size(), agent, this);
Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this);
client->setUrl(url);
client->setRetryPause(Options::i()->retryPause() * 1000);
client->setRetryPause(m_retryPause * 1000);
client->setQuiet(m_quiet);
m_pools.push_back(client);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,7 +40,8 @@ class Url;
class FailoverStrategy : public IStrategy, public IClientListener
{
public:
FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener);
FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
~FailoverStrategy();
public:
inline bool isActive() const override { return m_active >= 0; }
@@ -58,8 +59,11 @@ protected:
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
private:
void add(const Url *url, const char *agent);
void add(const Url *url);
const bool m_quiet;
const int m_retries;
const int m_retryPause;
int m_active;
int m_index;
IStrategyListener *m_listener;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,16 +25,23 @@
#include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/strategies/SinglePoolStrategy.h"
#include "Options.h"
#include "Platform.h"
SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) :
SinglePoolStrategy::SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet) :
m_active(false),
m_listener(listener)
{
m_client = new Client(0, agent, this);
m_client = new Client(0, Platform::userAgent(), this);
m_client->setUrl(url);
m_client->setRetryPause(Options::i()->retryPause() * 1000);
m_client->setRetryPause(retryPause * 1000);
m_client->setQuiet(quiet);
}
SinglePoolStrategy::~SinglePoolStrategy()
{
m_client->deleteLater();
}
@@ -56,7 +63,7 @@ void SinglePoolStrategy::resume()
return;
}
m_listener->onJob(m_client, m_client->job());
m_listener->onJob(this, m_client, m_client->job());
}
@@ -85,18 +92,18 @@ void SinglePoolStrategy::onClose(Client *client, int failures)
void SinglePoolStrategy::onJobReceived(Client *client, const Job &job)
{
m_listener->onJob(client, job);
m_listener->onJob(this, client, job);
}
void SinglePoolStrategy::onLoginSuccess(Client *client)
{
m_active = true;
m_listener->onActive(client);
m_listener->onActive(this, client);
}
void SinglePoolStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
{
m_listener->onResultAccepted(client, result, error);
m_listener->onResultAccepted(this, client, result, error);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,7 +37,8 @@ class Url;
class SinglePoolStrategy : public IStrategy, public IClientListener
{
public:
SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener);
SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet = false);
~SinglePoolStrategy();
public:
inline bool isActive() const override { return m_active; }

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,46 +37,86 @@ public:
inline Addr() :
m_host(nullptr),
m_port(kDefaultPort)
m_addr(nullptr),
m_ip(nullptr),
m_version(0),
m_port(0)
{}
inline Addr(const char *addr) :
m_host(nullptr),
m_port(kDefaultPort)
m_addr(strdup(addr)),
m_ip(nullptr),
m_version(0),
m_port(0)
{
if (!addr) {
if (!addr || strlen(addr) < 5) {
return;
}
const char *port = strchr(addr, ':');
if (!port) {
m_host = strdup(addr);
if (addr[0] == '[') {
parseIPv6(addr);
return;
}
const size_t size = port++ - addr + 1;
m_host = static_cast<char*>(malloc(size));
memcpy(m_host, addr, size - 1);
m_host[size - 1] = '\0';
m_port = (uint16_t) strtol(port, nullptr, 10);
parseIPv4(addr);
}
inline ~Addr()
{
free(m_host);
delete [] m_addr;
delete [] m_ip;
}
inline bool isValid() const { return m_host && m_port > 0; }
inline const char *host() const { return m_host; }
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 uint16_t port() const { return m_port; }
private:
char *m_host;
void parseIPv4(const char *addr)
{
const char *port = strchr(addr, ':');
if (!port) {
return;
}
m_version = 4;
const size_t size = port++ - addr + 1;
m_ip = new char[size]();
memcpy(m_ip, addr, size - 1);
m_port = (uint16_t) strtol(port, nullptr, 10);
}
void parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return;
}
const char *port = strchr(end, ':');
if (!port) {
return;
}
m_version = 6;
const size_t size = end - addr;
m_ip = new char[size]();
memcpy(m_ip, addr + 1, size - 1);
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
}
char *m_addr;
char *m_ip;
int m_version;
uint16_t m_port;
};

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -27,14 +27,16 @@
#include <string.h>
#include "Options.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "proxy/CustomDiff.h"
#include "proxy/events/LoginEvent.h"
#include "proxy/LoginRequest.h"
#include "proxy/Miner.h"
CustomDiff::CustomDiff()
CustomDiff::CustomDiff(xmrig::Controller *controller) :
m_controller(controller)
{
}
@@ -61,7 +63,7 @@ void CustomDiff::onEvent(IEvent *event)
void CustomDiff::login(LoginEvent *event)
{
event->miner()->setCustomDiff(Options::i()->diff());
event->miner()->setCustomDiff(m_controller->config()->diff());
if (!event->request.login()) {
return;

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -31,10 +31,15 @@
class LoginEvent;
namespace xmrig {
class Controller;
}
class CustomDiff : public IEventListener
{
public:
CustomDiff();
CustomDiff(xmrig::Controller *controller);
~CustomDiff();
protected:
@@ -43,6 +48,8 @@ protected:
private:
void login(LoginEvent *event);
xmrig::Controller *m_controller;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,8 +33,8 @@ JobResult::JobResult(int64_t id, const char *jobId, const char *nonce, const cha
nonce(nonce),
result(result),
id(id),
jobId(jobId, 3),
diff(0),
jobId(jobId, 3),
m_actualDiff(0)
{
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
#include <string.h>
#include "net/JobId.h"
#include "net/Id.h"
class JobResult
@@ -52,8 +52,8 @@ public:
const char *nonce;
const char *result;
const int64_t id;
JobId jobId;
uint32_t diff;
xmrig::Id jobId;
private:
mutable uint64_t m_actualDiff;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,7 +45,9 @@
static int64_t nextId = 0;
Miner::Miner() :
Miner::Miner(bool nicehash, bool ipv6) :
m_ipv6(ipv6),
m_nicehash(nicehash),
m_id(++nextId),
m_loginId(0),
m_recvBufPos(0),
@@ -92,7 +94,12 @@ bool Miner::accept(uv_stream_t *server)
int size = sizeof(addr);
uv_tcp_getpeername(&m_socket, reinterpret_cast<sockaddr*>(&addr), &size);
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), m_ip, 16);
if (m_ipv6) {
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(&addr), m_ip, 45);
} else {
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), m_ip, 16);
}
uv_read_start(reinterpret_cast<uv_stream_t*>(&m_socket), Miner::onAllocBuffer, Miner::onRead);
@@ -108,9 +115,10 @@ void Miner::replyWithError(int64_t id, const char *message)
void Miner::setJob(Job &job)
{
snprintf(m_sendBuf, 4, "%02hhx", m_fixedByte);
memcpy(job.rawBlob() + 84, m_sendBuf, 2);
if (m_nicehash) {
snprintf(m_sendBuf, 4, "%02hhx", m_fixedByte);
memcpy(job.rawBlob() + 84, m_sendBuf, 2);
}
m_diff = job.diff();
bool customDiff = false;
@@ -126,12 +134,14 @@ void Miner::setJob(Job &job)
int size = 0;
if (m_state == WaitReadyState) {
setState(ReadyState);
size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"result\":{\"id\":\"%s\",\"job\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\"},\"status\":\"OK\"}}\n",
m_loginId, m_rpcId, job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget());
size = snprintf(m_sendBuf, sizeof(m_sendBuf),
"{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"result\":{\"id\":\"%s\",\"job\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\",\"coin\":\"%s\",\"variant\":%d}%s,\"status\":\"OK\"}}\n",
m_loginId, m_rpcId, job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget(), job.coin(), job.variant(), m_nicehash ? ",\"extensions\":[\"nicehash\"]" : "");
}
else {
size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"jsonrpc\":\"2.0\",\"method\":\"job\",\"params\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\"}}\n",
job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget());
size = snprintf(m_sendBuf, sizeof(m_sendBuf),
"{\"jsonrpc\":\"2.0\",\"method\":\"job\",\"params\":{\"blob\":\"%s\",\"job_id\":\"%s%02hhx0\",\"target\":\"%s\",\"coin\":\"%s\",\"variant\":%d}}\n",
job.rawBlob(), job.id().data(), m_fixedByte, customDiff ? target : job.rawTarget(), job.coin(), job.variant());
}
send(size);
@@ -180,11 +190,11 @@ bool Miner::parseRequest(int64_t id, const char *method, const rapidjson::Value
if (!event->request.isValid() || event->request.actualDiff() < diff()) {
event->reject(Error::LowDifficulty);
}
else if (!event->request.isCompatible(m_fixedByte)) {
else if (m_nicehash && !event->request.isCompatible(m_fixedByte)) {
event->reject(Error::InvalidNonce);
}
if (m_customDiff && event->request.actualDiff() < m_diff) {
if (event->error() == Error::NoError && m_customDiff && event->request.actualDiff() < m_diff) {
success(id, "OK");
return true;
}
@@ -193,7 +203,7 @@ bool Miner::parseRequest(int64_t id, const char *method, const rapidjson::Value
replyWithError(id, event->message());
}
return true;
return event->error() != Error::InvalidNonce;
}
if (strcmp(method, "keepalived") == 0) {
@@ -296,8 +306,13 @@ void Miner::shutdown(bool had_error)
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(req->handle)) == 0) {
uv_close(reinterpret_cast<uv_handle_t*>(req->handle), [](uv_handle_t *handle) {
CloseEvent::start(getMiner(handle->data));
delete static_cast<Miner*>(handle->data);
Miner *miner = getMiner(handle->data);
if (!miner) {
return;
}
CloseEvent::start(miner);
delete miner;
});
}
@@ -309,6 +324,9 @@ void Miner::shutdown(bool had_error)
void Miner::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
{
auto miner = getMiner(handle->data);
if (!miner) {
return;
}
buf->base = &miner->m_recvBuf.base[miner->m_recvBufPos];
buf->len = miner->m_recvBuf.len - miner->m_recvBufPos;
@@ -318,6 +336,10 @@ void Miner::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *
void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
auto miner = getMiner(stream->data);
if (!miner) {
return;
}
if (nread < 0 || (size_t) nread > (sizeof(m_buf) - 8 - miner->m_recvBufPos)) {
return miner->shutdown(nread != UV_EOF);;
}
@@ -326,7 +348,7 @@ void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
miner->m_recvBufPos += nread;
char* end;
char* start = buf->base;
char* start = miner->m_recvBuf.base;
size_t remaining = miner->m_recvBufPos;
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) {
@@ -343,11 +365,11 @@ void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
return;
}
if (start == buf->base) {
if (start == miner->m_recvBuf.base) {
return;
}
memcpy(buf->base, start, remaining);
memcpy(miner->m_recvBuf.base, start, remaining);
miner->m_recvBufPos = remaining;
}
@@ -355,6 +377,10 @@ void Miner::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
void Miner::onTimeout(uv_timer_t *handle)
{
auto miner = getMiner(handle->data);
if (!miner) {
return;
}
miner->m_recvBuf.base[sizeof(m_buf) - 1] = '\0';
miner->shutdown(true);

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,7 +32,6 @@
#include "rapidjson/fwd.h"
class IMinerListener;
class Job;
class RejectEvent;
@@ -47,7 +46,7 @@ public:
ClosingState
};
Miner();
Miner(bool nicehash, bool ipv6);
~Miner();
bool accept(uv_stream_t *server);
void replyWithError(int64_t id, const char *message);
@@ -88,8 +87,10 @@ private:
static inline Miner *getMiner(void *data) { return static_cast<Miner*>(data); }
bool m_ipv6;
bool m_nicehash;
char m_buf[2048];
char m_ip[17];
char m_ip[46];
char m_rpcId[37];
char m_sendBuf[768];
int64_t m_id;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,12 +30,14 @@
#include <time.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "Counters.h"
#include "log/AccessLog.h"
#include "log/Log.h"
#include "log/ShareLog.h"
#include "Options.h"
#include "Platform.h"
#include "proxy/Addr.h"
#include "proxy/Events.h"
#include "proxy/events/ConnectionEvent.h"
#include "proxy/Miner.h"
@@ -43,21 +45,34 @@
#include "proxy/Proxy.h"
#include "proxy/ProxyDebug.h"
#include "proxy/Server.h"
#include "proxy/splitters/NonceSplitter.h"
#include "proxy/splitters/nicehash/NonceSplitter.h"
#include "proxy/splitters/simple/SimpleSplitter.h"
#include "proxy/Stats.h"
#include "proxy/workers/Workers.h"
Proxy::Proxy(const Options *options) :
m_ticks(0)
Proxy::Proxy(xmrig::Controller *controller) :
m_customDiff(controller),
m_ticks(0),
m_controller(controller)
{
srand(time(0) ^ (uintptr_t) this);
m_miners = new Miners();
m_splitter = new NonceSplitter();
m_shareLog = new ShareLog(m_stats);
m_accessLog = new AccessLog();
m_workers = new Workers();
m_miners = new Miners();
Splitter *splitter = nullptr;
if (controller->config()->mode() == xmrig::Config::NICEHASH_MODE) {
splitter = new NonceSplitter(controller);
}
else {
splitter = new SimpleSplitter(controller);
}
m_splitter = splitter;
m_shareLog = new ShareLog(controller, m_stats);
m_accessLog = new AccessLog(controller);
m_workers = new Workers(controller);
m_timer.data = this;
uv_timer_init(uv_default_loop(), &m_timer);
@@ -66,18 +81,18 @@ Proxy::Proxy(const Options *options) :
Events::subscribe(IEvent::ConnectionType, &m_stats);
Events::subscribe(IEvent::CloseType, m_miners);
Events::subscribe(IEvent::CloseType, m_splitter);
Events::subscribe(IEvent::CloseType, splitter);
Events::subscribe(IEvent::CloseType, &m_stats);
Events::subscribe(IEvent::CloseType, m_accessLog);
Events::subscribe(IEvent::CloseType, m_workers);
Events::subscribe(IEvent::LoginType, &m_customDiff);
Events::subscribe(IEvent::LoginType, m_splitter);
Events::subscribe(IEvent::LoginType, splitter);
Events::subscribe(IEvent::LoginType, &m_stats);
Events::subscribe(IEvent::LoginType, m_accessLog);
Events::subscribe(IEvent::LoginType, m_workers);
Events::subscribe(IEvent::SubmitType, m_splitter);
Events::subscribe(IEvent::SubmitType, splitter);
Events::subscribe(IEvent::SubmitType, &m_stats);
Events::subscribe(IEvent::SubmitType, m_workers);
@@ -85,7 +100,9 @@ Proxy::Proxy(const Options *options) :
Events::subscribe(IEvent::AcceptType, m_shareLog);
Events::subscribe(IEvent::AcceptType, m_workers);
m_debug = new ProxyDebug(options->isDebug());
m_debug = new ProxyDebug(controller->config()->isDebug());
controller->addListener(this);
}
@@ -106,9 +123,9 @@ void Proxy::connect()
{
m_splitter->connect();
const std::vector<Addr*> &addrs = Options::i()->addrs();
const std::vector<Addr*> &addrs = m_controller->config()->addrs();
for (const Addr *addr : addrs) {
bind(addr->host(), addr->port());
bind(addr);
}
uv_timer_start(&m_timer, Proxy::onTick, 1000, 1000);
@@ -123,8 +140,8 @@ void Proxy::printConnections()
void Proxy::printHashrate()
{
LOG_INFO(Options::i()->colors() ? "\x1B[01;32m* \x1B[01;37mspeed\x1B[0m \x1B[01;30m(1m) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(10m) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(1h) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(12h) \x1B[01;36m%03.1f\x1B[0m, \x1B[01;30m(24h) \x1B[01;36m%03.1f KH/s"
: "* speed (1m) %03.1f, (10m) %03.1f, (1h) %03.1f, (12h) %03.1f, (24h) %03.1f KH/s",
LOG_INFO(isColors() ? "\x1B[01;32m* \x1B[01;37mspeed\x1B[0m \x1B[01;30m(1m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(10m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(1h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(12h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(24h) \x1B[01;36m%03.2f kH/s"
: "* speed (1m) %03.2f, (10m) %03.2f, (1h) %03.2f, (12h) %03.2f, (24h) %03.2f kH/s",
m_stats.hashrate(60), m_stats.hashrate(600), m_stats.hashrate(3600), m_stats.hashrate(3600 * 12), m_stats.hashrate(3600 * 24));
}
@@ -141,6 +158,18 @@ void Proxy::toggleDebug()
}
const StatsData &Proxy::statsData() const
{
return m_stats.data();
}
const std::vector<Worker> &Proxy::workers() const
{
return m_workers->workers();
}
#ifdef APP_DEVEL
void Proxy::printState()
{
@@ -153,9 +182,21 @@ void Proxy::printState()
#endif
void Proxy::bind(const char *ip, uint16_t port)
void Proxy::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
auto server = new Server(ip, port);
m_debug->setEnabled(config->isDebug());
}
bool Proxy::isColors() const
{
return m_controller->config()->colors();
}
void Proxy::bind(const Addr *addr)
{
auto server = new Server(addr, m_controller->config()->mode() == xmrig::Config::NICEHASH_MODE);
if (server->bind()) {
m_servers.push_back(server);
@@ -174,10 +215,10 @@ void Proxy::gc()
void Proxy::print()
{
LOG_INFO(Options::i()->colors() ? "\x1B[01;36m%03.1f 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.1f KH/s, shares: %" PRIu64 "/%s%" PRIu64 " +%" PRIu64 ", upstreams: %u, miners: %" PRIu64 " (max %" PRIu64 " +%u/-%u",
m_stats.hashrate(60), m_stats.data().accepted, Options::i()->colors() ? (m_stats.data().rejected ? "\x1B[31m" : "\x1B[01;37m") : "", m_stats.data().rejected,
Counters::accepted, m_splitter->activeUpstreams(), Counters::miners(), Counters::maxMiners(), Counters::added(), Counters::removed());
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",
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());
Counters::reset();
}
@@ -185,7 +226,7 @@ void Proxy::print()
void Proxy::tick()
{
m_stats.tick(m_ticks, *m_splitter);
m_stats.tick(m_ticks, m_splitter);
m_ticks++;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,13 +29,16 @@
#include <uv.h>
#include "interfaces/IControllerListener.h"
#include "proxy/CustomDiff.h"
#include "proxy/Stats.h"
#include "proxy/workers/Worker.h"
class AccessLog;
class Addr;
class Miners;
class NonceSplitter;
class ISplitter;
class Options;
class ProxyDebug;
class Server;
@@ -44,10 +47,15 @@ class Url;
class Workers;
class Proxy
namespace xmrig {
class Controller;
}
class Proxy : public xmrig::IControllerListener
{
public:
Proxy(const Options *options);
Proxy(xmrig::Controller *controller);
~Proxy();
void connect();
@@ -56,15 +64,23 @@ public:
void printWorkers();
void toggleDebug();
const StatsData &statsData() const;
const std::vector<Worker> &workers() const;
# ifdef APP_DEVEL
void printState();
# endif
protected:
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
private:
constexpr static int kPrintInterval = 60;
constexpr static int kGCInterval = 60;
void bind(const char *ip, uint16_t port);
bool isColors() const;
void bind(const Addr *addr);
void bind(const char *ip, uint16_t port, bool ipv6);
void gc();
void print();
void tick();
@@ -74,8 +90,8 @@ private:
AccessLog *m_accessLog;
CustomDiff m_customDiff;
ISplitter *m_splitter;
Miners *m_miners;
NonceSplitter *m_splitter;
ProxyDebug *m_debug;
ShareLog *m_shareLog;
Stats m_stats;
@@ -83,6 +99,7 @@ private:
uint64_t m_ticks;
uv_timer_t m_timer;
Workers *m_workers;
xmrig::Controller *m_controller;
};

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -34,7 +34,8 @@ public:
ProxyDebug(bool enabled);
~ProxyDebug();
inline void toggle() { m_enabled = !m_enabled; }
inline void setEnabled(bool enabled) { m_enabled = enabled; }
inline void toggle() { m_enabled = !m_enabled; }
protected:
void onEvent(IEvent *event) override;

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,26 +23,48 @@
#include "log/Log.h"
#include "proxy/Addr.h"
#include "proxy/events/ConnectionEvent.h"
#include "proxy/Miner.h"
#include "proxy/Server.h"
Server::Server(const char *ip, uint16_t port) :
m_ip(ip),
m_port(port)
Server::Server(const Addr *addr, bool nicehash) :
m_nicehash(nicehash),
m_ip(strdup(addr->ip())),
m_version(0),
m_port(addr->port())
{
uv_tcp_init(uv_default_loop(), &m_server);
m_server.data = this;
uv_ip4_addr(ip, port, &m_addr);
uv_tcp_nodelay(&m_server, 1);
if (addr->isIPv6() && uv_ip6_addr(m_ip, m_port, &m_addr6) == 0) {
m_version = 6;
return;
}
if (uv_ip4_addr(m_ip, m_port, &m_addr) == 0) {
m_version = 4;
}
}
Server::~Server()
{
free(m_ip);
}
bool Server::bind()
{
uv_tcp_bind(&m_server, reinterpret_cast<const sockaddr*>(&m_addr), 0);
if (!m_version) {
return false;
}
const sockaddr *addr = m_version == 6 ? reinterpret_cast<const sockaddr*>(&m_addr6) : reinterpret_cast<const sockaddr*>(&m_addr);
uv_tcp_bind(&m_server, addr, m_version == 6 ? UV_TCP_IPV6ONLY : 0);
const int r = uv_listen(reinterpret_cast<uv_stream_t*>(&m_server), 511, Server::onConnection);
if (r) {
@@ -54,18 +76,15 @@ bool Server::bind()
}
void Server::onConnection(uv_stream_t *server, int status)
void Server::create(uv_stream_t *server, int status)
{
auto instance = static_cast<Server*>(server->data);
if (status < 0) {
LOG_ERR("[%s:%u] new connection error: \"%s\"", instance->m_ip, instance->m_port, uv_strerror(status));
LOG_ERR("[%s:%u] new connection error: \"%s\"", m_ip, m_port, uv_strerror(status));
return;
}
Miner *miner = new Miner();
Miner *miner = new Miner(m_nicehash, m_version == 6);
if (!miner) {
LOG_ERR("NEW FAILED");
return;
}
@@ -74,5 +93,11 @@ void Server::onConnection(uv_stream_t *server, int status)
return;
}
ConnectionEvent::start(miner, instance->m_port);
ConnectionEvent::start(miner, m_port);
}
void Server::onConnection(uv_stream_t *server, int status)
{
static_cast<Server*>(server->data)->create(server, status);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,17 +28,26 @@
#include <uv.h>
class Addr;
class Server
{
public:
Server(const char *ip, uint16_t port);
Server(const Addr *addr, bool nicehash);
~Server();
bool bind();
private:
void create(uv_stream_t *server, int status);
static void onConnection(uv_stream_t *server, int status);
const char *m_ip;
struct sockaddr_in m_addr;
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;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,9 +24,9 @@
#include "api/Api.h"
#include "Counters.h"
#include "interfaces/ISplitter.h"
#include "net/SubmitResult.h"
#include "proxy/events/AcceptEvent.h"
#include "proxy/splitters/NonceSplitter.h"
#include "proxy/Stats.h"
@@ -42,7 +42,7 @@ Stats::~Stats()
}
void Stats::tick(uint64_t ticks, const NonceSplitter &splitter)
void Stats::tick(uint64_t ticks, const ISplitter *splitter)
{
ticks++;
@@ -55,12 +55,12 @@ void Stats::tick(uint64_t ticks, const NonceSplitter &splitter)
m_data.hashrate[2] = hashrate(3600);
m_data.hashrate[3] = hashrate(3600 * 12);
m_data.hashrate[4] = hashrate(3600 * 24);
m_data.hashrate[5] = hashrate(m_data.uptime());
m_data.upstreams = splitter.activeUpstreams();
m_data.upstreams = splitter->upstreams();
m_data.miners = Counters::miners();
m_data.maxMiners = Counters::maxMiners();
m_data.expired = Counters::expired;
Api::tick(m_data);
# endif
}
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
class AcceptEvent;
class NonceSplitter;
class ISplitter;
class Stats : public IEventListener
@@ -43,7 +43,7 @@ public:
Stats();
~Stats();
void tick(uint64_t ticks, const NonceSplitter &splitter);
void tick(uint64_t ticks, const ISplitter *splitter);
inline const StatsData &data() const { return m_data; }
inline double hashrate(int seconds) const { return m_hashrate.calc(seconds); }

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +31,9 @@
#include <vector>
#include "interfaces/ISplitter.h"
class StatsData
{
public:
@@ -44,8 +47,7 @@ public:
maxMiners(0),
miners(0),
rejected(0),
startTime(0),
upstreams(0)
startTime(0)
{
}
@@ -84,7 +86,7 @@ public:
}
double hashrate[5] { 0.0 };
double hashrate[6] { 0.0 };
std::array<uint64_t, 10> topDiff { { } };
std::vector<uint16_t> latency;
uint64_t accepted;
@@ -97,7 +99,7 @@ public:
uint64_t miners;
uint64_t rejected;
uint64_t startTime;
uint64_t upstreams;
Upstreams upstreams;
};

View File

@@ -0,0 +1,35 @@
/* 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 "proxy/events/MinerEvent.h"
#include "proxy/Miner.h"
static const char *kDefaultIP = "0.0.0.0";
const char *MinerEvent::ip() const
{
return m_miner ? m_miner->ip() : kDefaultIP;
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,6 +34,9 @@ class Miner;
class MinerEvent : public Event
{
public:
const char *ip() const;
inline Miner *miner() const { return m_miner; }

View File

@@ -0,0 +1,33 @@
/* 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 "core/Controller.h"
#include "proxy/splitters/Splitter.h"
Splitter::Splitter(xmrig::Controller *controller) :
m_controller(controller)
{
controller->addListener(this);
}

View File

@@ -0,0 +1,48 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 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 __SPLITTER_H__
#define __SPLITTER_H__
#include "interfaces/IControllerListener.h"
#include "interfaces/IEventListener.h"
#include "interfaces/ISplitter.h"
namespace xmrig {
class Controller;
}
class Splitter : public IEventListener, public ISplitter, public xmrig::IControllerListener
{
public:
Splitter(xmrig::Controller *controller);
protected:
xmrig::Controller *m_controller;
};
#endif /* __SPLITTER_H__ */

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,48 +27,43 @@
#include <string.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "net/Client.h"
#include "net/strategies/DonateStrategy.h"
#include "net/strategies/FailoverStrategy.h"
#include "net/strategies/SinglePoolStrategy.h"
#include "net/Url.h"
#include "Options.h"
#include "proxy/Counters.h"
#include "proxy/Error.h"
#include "proxy/events/AcceptEvent.h"
#include "proxy/events/SubmitEvent.h"
#include "proxy/JobResult.h"
#include "proxy/Miner.h"
#include "proxy/splitters/NonceMapper.h"
#include "proxy/splitters/NonceStorage.h"
#include "proxy/splitters/nicehash/NonceMapper.h"
#include "proxy/splitters/nicehash/NonceStorage.h"
NonceMapper::NonceMapper(size_t id, const Options *options, const char *agent) :
m_suspended(false),
m_agent(agent),
m_options(options),
NonceMapper::NonceMapper(size_t id, xmrig::Controller *controller) :
m_donate(nullptr),
m_id(id)
m_suspended(0),
m_pending(nullptr),
m_id(id),
m_controller(controller)
{
m_storage = new NonceStorage();
const std::vector<Url*> &pools = options->pools();
m_storage = new NonceStorage();
m_strategy = createStrategy(controller->config()->pools());
if (pools.size() > 1) {
m_strategy = new FailoverStrategy(pools, m_agent, this);
}
else {
m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this);
}
if (id != 0 && m_options->donateLevel() > 0) {
m_donate = new DonateStrategy(m_agent, this);
if (controller->config()->donateLevel() > 0) {
m_donate = new DonateStrategy(id, controller, this);
}
}
NonceMapper::~NonceMapper()
{
delete m_pending;
delete m_strategy;
delete m_storage;
delete m_donate;
@@ -81,7 +76,7 @@ bool NonceMapper::add(Miner *miner, const LoginRequest &request)
return false;
}
if (m_suspended) {
if (isSuspended()) {
connect();
}
@@ -92,13 +87,18 @@ bool NonceMapper::add(Miner *miner, const LoginRequest &request)
bool NonceMapper::isActive() const
{
return m_storage->isActive() && !m_suspended;
return m_storage->isActive() && !isSuspended();
}
void NonceMapper::gc()
{
if (m_suspended || m_id == 0 || m_storage->isUsed()) {
if (isSuspended()) {
m_suspended++;
return;
}
if (m_id == 0 || m_storage->isUsed()) {
return;
}
@@ -106,6 +106,15 @@ void NonceMapper::gc()
}
void NonceMapper::reload(const std::vector<Url*> &pools)
{
delete m_pending;
m_pending = createStrategy(pools);
m_pending->connect();
}
void NonceMapper::remove(const Miner *miner)
{
m_storage->remove(miner);
@@ -150,7 +159,7 @@ void NonceMapper::tick(uint64_t ticks, uint64_t now)
#ifdef APP_DEVEL
void NonceMapper::printState()
{
if (m_suspended) {
if (isSuspended()) {
return;
}
@@ -159,7 +168,7 @@ void NonceMapper::printState()
#endif
void NonceMapper::onActive(Client *client)
void NonceMapper::onActive(IStrategy *strategy, Client *client)
{
m_storage->setActive(true);
@@ -167,15 +176,24 @@ void NonceMapper::onActive(Client *client)
return;
}
LOG_INFO(m_options->colors() ? "#%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());
if (m_pending && strategy == m_pending) {
delete m_strategy;
m_strategy = strategy;
m_pending = nullptr;
}
if (m_controller->config()->verbose()) {
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());
}
}
void NonceMapper::onJob(Client *client, const Job &job)
void NonceMapper::onJob(IStrategy *strategy, Client *client, const Job &job)
{
if (m_options->verbose()) {
LOG_INFO(m_options->colors() ? "#%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",
if (m_controller->config()->verbose()) {
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());
}
@@ -191,13 +209,13 @@ void NonceMapper::onPause(IStrategy *strategy)
{
m_storage->setActive(false);
if (!m_suspended) {
if (!isSuspended()) {
LOG_ERR("#%03u no active pools, stop", m_id);
}
}
void NonceMapper::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
void NonceMapper::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
{
const SubmitCtx ctx = submitCtx(result.seq);
@@ -216,6 +234,22 @@ void NonceMapper::onResultAccepted(Client *client, const SubmitResult &result, c
}
bool NonceMapper::isColors() const
{
return m_controller->config()->colors();
}
IStrategy *NonceMapper::createStrategy(const std::vector<Url*> &pools)
{
if (pools.size() > 1) {
return new FailoverStrategy(pools, m_controller->config()->retryPause(), m_controller->config()->retries(), this);
}
return new SinglePoolStrategy(pools.front(), m_controller->config()->retryPause(), this);
}
SubmitCtx NonceMapper::submitCtx(int64_t seq)
{
if (!m_results.count(seq)) {
@@ -236,7 +270,7 @@ SubmitCtx NonceMapper::submitCtx(int64_t seq)
void NonceMapper::connect()
{
m_suspended = false;
m_suspended = 0;
m_strategy->connect();
if (m_donate) {
@@ -247,7 +281,7 @@ void NonceMapper::connect()
void NonceMapper::suspend()
{
m_suspended = true;
m_suspended = 1;
m_storage->setActive(false);
m_storage->reset();
m_strategy->stop();

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,6 +45,11 @@ class SubmitEvent;
class Url;
namespace xmrig {
class Controller;
}
class SubmitCtx
{
public:
@@ -60,42 +65,46 @@ public:
class NonceMapper : public IStrategyListener
{
public:
NonceMapper(size_t id, const Options *options, const char *agent);
NonceMapper(size_t id, xmrig::Controller *controller);
~NonceMapper();
bool add(Miner *miner, const LoginRequest &request);
bool isActive() const;
void gc();
void reload(const std::vector<Url*> &pools);
void remove(const Miner *miner);
void start();
void submit(SubmitEvent *event);
void tick(uint64_t ticks, uint64_t now);
inline bool isSuspended() const { return m_suspended; }
inline bool isSuspended() const { return m_suspended > 0; }
inline int suspended() const { return m_suspended; }
# ifdef APP_DEVEL
void printState();
# endif
protected:
void onActive(Client *client) override;
void onJob(Client *client, const Job &job) override;
void onActive(IStrategy *strategy, Client *client) override;
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
void onPause(IStrategy *strategy) override;
void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
private:
bool isColors() const;
IStrategy *createStrategy(const std::vector<Url*> &pools);
SubmitCtx submitCtx(int64_t seq);
void connect();
void suspend();
bool m_suspended;
const char *m_agent;
const Options *m_options;
DonateStrategy *m_donate;
int m_suspended;
IStrategy *m_pending;
IStrategy *m_strategy;
NonceStorage *m_storage;
size_t m_id;
std::map<int64_t, SubmitCtx> m_results;
xmrig::Controller *m_controller;
};

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,27 +21,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <inttypes.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "Options.h"
#include "Platform.h"
#include "net/Url.h"
#include "proxy/Counters.h"
#include "proxy/events/CloseEvent.h"
#include "proxy/events/LoginEvent.h"
#include "proxy/events/SubmitEvent.h"
#include "proxy/Miner.h"
#include "proxy/splitters/NonceMapper.h"
#include "proxy/splitters/NonceSplitter.h"
#include "proxy/Stats.h"
#include "proxy/splitters/nicehash/NonceMapper.h"
#include "proxy/splitters/nicehash/NonceSplitter.h"
#include "Summary.h"
#define LABEL(x) " \x1B[01;30m" x ":\x1B[0m "
NonceSplitter::NonceSplitter()
static bool compare(Url *i, Url *j) {
return *i == *j;
}
NonceSplitter::NonceSplitter(xmrig::Controller *controller) : Splitter(controller)
{
}
@@ -51,23 +56,30 @@ NonceSplitter::~NonceSplitter()
}
uint32_t NonceSplitter::activeUpstreams() const
Upstreams NonceSplitter::upstreams() const
{
uint32_t active = 0;
uint64_t active = 0;
uint64_t sleep = 0;
for (const NonceMapper *mapper : m_upstreams) {
if (mapper->isActive()) {
active++;
continue;
}
if (mapper->isSuspended()) {
sleep++;
continue;
}
}
return active;
return Upstreams(active, sleep, m_upstreams.size(), Counters::miners());
}
void NonceSplitter::connect()
{
auto upstream = new NonceMapper(m_upstreams.size(), Options::i(), Platform::userAgent());
auto upstream = new NonceMapper(m_upstreams.size(), m_controller);
m_upstreams.push_back(upstream);
upstream->start();
@@ -79,42 +91,32 @@ void NonceSplitter::gc()
for (NonceMapper *mapper : m_upstreams) {
mapper->gc();
}
while (m_upstreams.back()->suspended() >= 2) {
delete m_upstreams.back();
m_upstreams.pop_back();
}
}
void NonceSplitter::printConnections()
{
int active = 0;
int suspended = 0;
const Upstreams info = upstreams();
for (const NonceMapper *mapper : m_upstreams) {
if (mapper->isActive()) {
active++;
continue;
}
if (mapper->isSuspended()) {
suspended++;
continue;
}
}
const int error = (int) m_upstreams.size() - active - suspended;
const double ratio = active > 0 ? ((double) Counters::miners() / active) : 0;
if (Options::i()->colors()) {
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%d\x1B[0m" LABEL("sleep") "\x1B[01;37m%d\x1B[0m" LABEL("error") "%s%d\x1B[0m" LABEL("total") "\x1B[01;37m%d",
active ? "\x1B[01;32m" : "\x1B[01;31m", active, suspended, error ? "\x1B[01;31m" : "\x1B[01;37m", error, m_upstreams.size());
if (m_controller->config()->colors()) {
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);
LOG_INFO("\x1B[01;32m* \x1B[01;37mminers \x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("max") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("ratio") "%s1:%3.1f",
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners(), (ratio > 200 ? "\x1B[01;32m" : "\x1B[01;33m"), ratio);
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners(), (info.ratio > 200 ? "\x1B[01;32m" : "\x1B[01;33m"), info.ratio);
}
else {
LOG_INFO("* upstreams: active %d sleep %d error %d total %d",
active, suspended, error, m_upstreams.size());
LOG_INFO("* upstreams: active %" PRIu64 " sleep %" PRIu64 " error %" PRIu64 " total %" PRIu64,
info.active, info.sleep, info.error, info.total);
LOG_INFO("* miners: active %" PRIu64 " max %" PRIu64 " ratio 1:%3.1f",
Counters::miners(), Counters::maxMiners(), ratio);
Counters::miners(), Counters::maxMiners(), info.ratio);
}
}
@@ -139,6 +141,21 @@ void NonceSplitter::printState()
#endif
void NonceSplitter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
const std::vector<Url*> &pools = config->pools();
const std::vector<Url*> &previousPools = previousConfig->pools();
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin(), compare)) {
Summary::printPools(config);
for (NonceMapper *mapper : m_upstreams) {
mapper->reload(pools);
}
}
}
void NonceSplitter::onEvent(IEvent *event)
{
switch (event->type())
@@ -194,7 +211,5 @@ void NonceSplitter::remove(Miner *miner)
void NonceSplitter::submit(SubmitEvent *event)
{
assert(event->miner()->mapperId() >= 0);
m_upstreams[event->miner()->mapperId()]->submit(event);
}

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
#include <vector>
#include "interfaces/IEventListener.h"
#include "proxy/splitters/Splitter.h"
class LoginEvent;
@@ -40,25 +40,31 @@ class Stats;
class SubmitEvent;
class NonceSplitter : public IEventListener
namespace xmrig {
class Controller;
}
class NonceSplitter : public Splitter
{
public:
NonceSplitter();
NonceSplitter(xmrig::Controller *controller);
~NonceSplitter();
uint32_t activeUpstreams() const;
void connect();
void gc();
void printConnections();
void tick(uint64_t ticks);
protected:
Upstreams upstreams() const override;
void connect() override;
void gc() override;
void printConnections() override;
void tick(uint64_t ticks) override;
# ifdef APP_DEVEL
void printState();
void printState() override;
# endif
protected:
void onEvent(IEvent *event) override;
inline void onRejectedEvent(IEvent *event) override {}
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
void onEvent(IEvent *event) override;
private:
void login(LoginEvent *event);

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
#include "proxy/Counters.h"
#include "proxy/LoginRequest.h"
#include "proxy/Miner.h"
#include "proxy/splitters/NonceStorage.h"
#include "proxy/splitters/nicehash/NonceStorage.h"
NonceStorage::NonceStorage() :
@@ -77,7 +77,7 @@ bool NonceStorage::isUsed() const
}
bool NonceStorage::isValidJobId(const JobId &id)
bool NonceStorage::isValidJobId(const xmrig::Id &id) const
{
if (m_job.id() == id) {
return true;
@@ -127,8 +127,14 @@ void NonceStorage::setJob(const Job &job)
}
}
m_prevJob = m_job;
m_job = job;
if (m_job.clientId() == job.clientId()) {
m_prevJob = m_job;
}
else {
m_prevJob.reset();
}
m_job = job;
for (size_t i = 0; i < 256; ++i) {
const int64_t index = m_used[i];

View File

@@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@ public:
bool add(Miner *miner, const LoginRequest &request);
bool isUsed() const;
bool isValidJobId(const JobId &id);
bool isValidJobId(const xmrig::Id &id) const;
Miner *miner(int64_t id);
void remove(const Miner *miner);
void reset();

View File

@@ -0,0 +1,258 @@
/* 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 <inttypes.h>
#include <memory>
#include <string.h>
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "net/Client.h"
#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"
#include "proxy/events/SubmitEvent.h"
#include "proxy/JobResult.h"
#include "proxy/Miner.h"
#include "proxy/splitters/simple/SimpleMapper.h"
SimpleMapper::SimpleMapper(uint64_t id, xmrig::Controller *controller) :
m_active(false),
m_donate(nullptr),
m_pending(nullptr),
m_miner(nullptr),
m_id(id),
m_idleTime(0),
m_controller(controller)
{
m_strategy = createStrategy(controller->config()->pools());
// if (controller->config()->donateLevel() > 0) {
// m_donate = new DonateStrategy(id, controller, this);
// }
}
SimpleMapper::~SimpleMapper()
{
delete m_pending;
delete m_strategy;
delete m_donate;
}
void SimpleMapper::add(Miner *miner, const LoginRequest &request)
{
m_miner = miner;
m_miner->setMapperId(m_id);
connect();
}
void SimpleMapper::reload(const std::vector<Url*> &pools)
{
delete m_pending;
m_pending = createStrategy(pools);
m_pending->connect();
}
void SimpleMapper::remove(const Miner *miner)
{
m_miner = nullptr;
m_dirty = true;
}
void SimpleMapper::reuse(Miner *miner, const LoginRequest &request)
{
m_idleTime = 0;
m_miner = miner;
m_miner->setMapperId(m_id);
}
void SimpleMapper::submit(SubmitEvent *event)
{
if (!isActive()) {
return event->reject(Error::BadGateway);
}
if (!isValidJobId(event->request.jobId)) {
return event->reject(Error::InvalidJobId);
}
JobResult req = event->request;
req.diff = m_job.diff();
IStrategy *strategy = m_donate && m_donate->isActive() ? m_donate : m_strategy;
if (strategy) {
strategy->submit(req);
}
}
void SimpleMapper::tick(uint64_t ticks, uint64_t now)
{
m_strategy->tick(now);
if (!m_miner) {
m_idleTime++;
}
if (m_donate) {
m_donate->tick(now);
}
}
void SimpleMapper::onActive(IStrategy *strategy, Client *client)
{
m_active = true;
if (client->id() == -1) {
return;
}
if (m_pending && strategy == m_pending) {
delete m_strategy;
m_strategy = strategy;
m_pending = nullptr;
}
if (m_controller->config()->verbose()) {
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());
}
}
void SimpleMapper::onJob(IStrategy *strategy, Client *client, const Job &job)
{
if (m_controller->config()->verbose()) {
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());
}
if (m_donate && m_donate->isActive() && client->id() != -1 && !m_donate->reschedule()) {
return;
}
setJob(job);
}
void SimpleMapper::onPause(IStrategy *strategy)
{
if (m_strategy == strategy) {
m_active = false;
}
}
void SimpleMapper::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
{
AcceptEvent::start(m_id, m_miner, result, client->id() == -1, error);
if (!m_miner) {
return;
}
if (error) {
m_miner->replyWithError(result.reqId, error);
}
else {
m_miner->success(result.reqId, "OK");
}
}
bool SimpleMapper::isColors() const
{
return m_controller->config()->colors();
}
bool SimpleMapper::isValidJobId(const xmrig::Id &id) const
{
if (m_job.id() == id) {
return true;
}
if (m_prevJob.isValid() && m_prevJob.id() == id) {
Counters::expired++;
return true;
}
return false;
}
IStrategy *SimpleMapper::createStrategy(const std::vector<Url*> &pools)
{
if (pools.size() > 1) {
return new FailoverStrategy(pools, m_controller->config()->retryPause(), m_controller->config()->retries(), this);
}
return new SinglePoolStrategy(pools.front(), m_controller->config()->retryPause(), this);
}
void SimpleMapper::connect()
{
m_strategy->connect();
if (m_donate) {
m_donate->connect();
}
}
void SimpleMapper::setJob(const Job &job)
{
if (m_job.clientId() == job.clientId()) {
m_prevJob = m_job;
}
else {
m_prevJob.reset();
}
m_job = job;
m_dirty = false;
if (m_miner) {
m_miner->setJob(m_job);
}
}

View File

@@ -0,0 +1,98 @@
/* 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 __SIMPLEMAPPER_H__
#define __SIMPLEMAPPER_H__
#include <map>
#include <uv.h>
#include <vector>
#include "interfaces/IStrategyListener.h"
#include "net/Job.h"
class DonateStrategy;
class IStrategy;
class JobResult;
class LoginRequest;
class Miner;
class NonceStorage;
class Options;
class SubmitEvent;
class Url;
namespace xmrig {
class Controller;
}
class SimpleMapper : public IStrategyListener
{
public:
SimpleMapper(uint64_t id, xmrig::Controller *controller);
~SimpleMapper();
void add(Miner *miner, const LoginRequest &request);
void reload(const std::vector<Url*> &pools);
void remove(const Miner *miner);
void reuse(Miner *miner, const LoginRequest &request);
void submit(SubmitEvent *event);
void tick(uint64_t ticks, uint64_t now);
inline bool isActive() const { return m_active && m_miner; }
inline bool isReusable() const { return m_active && !m_miner && !m_dirty; }
inline uint64_t id() const { return m_id; }
inline uint64_t idleTime() const { return m_idleTime; }
protected:
void onActive(IStrategy *strategy, Client *client) override;
void onJob(IStrategy *strategy, Client *client, const Job &job) override;
void onPause(IStrategy *strategy) override;
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
private:
bool isColors() const;
bool isValidJobId(const xmrig::Id &id) const;
IStrategy *createStrategy(const std::vector<Url*> &pools);
void connect();
void setJob(const Job &job);
bool m_active;
bool m_dirty;
DonateStrategy *m_donate;
IStrategy *m_pending;
IStrategy *m_strategy;
Job m_job;
Job m_prevJob;
Miner *m_miner;
uint64_t m_id;
uint64_t m_idleTime;
xmrig::Controller *m_controller;
};
#endif /* __SIMPLEMAPPER_H__ */

View File

@@ -0,0 +1,246 @@
/* 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 <inttypes.h>
#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"
#include "proxy/events/LoginEvent.h"
#include "proxy/events/SubmitEvent.h"
#include "proxy/Miner.h"
#include "proxy/splitters/simple/SimpleMapper.h"
#include "proxy/splitters/simple/SimpleSplitter.h"
#include "Summary.h"
#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)
{
}
SimpleSplitter::~SimpleSplitter()
{
}
Upstreams SimpleSplitter::upstreams() const
{
uint64_t active = 0;
for (auto const &kv : m_upstreams) {
if (kv.second->isActive()) {
active++;
}
}
return Upstreams(active, m_idles.size(), m_upstreams.size(), Counters::miners());
}
void SimpleSplitter::connect()
{
}
void SimpleSplitter::gc()
{
}
void SimpleSplitter::printConnections()
{
const Upstreams info = upstreams();
if (m_controller->config()->colors()) {
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());
LOG_INFO("\x1B[01;32m* \x1B[01;37mminers \x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("max") "\x1B[01;37m%" PRIu64 "\x1B[0m",
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners());
}
else {
LOG_INFO("* upstreams: active %" PRIu64 " sleep %" PRIu64 " error %" PRIu64 " total %" PRIu64,
info.active, info.sleep, info.error, m_upstreams.size());
LOG_INFO("* miners: active %" PRIu64 " max %" PRIu64,
Counters::miners(), Counters::maxMiners());
}
}
void SimpleSplitter::tick(uint64_t ticks)
{
const uint64_t now = uv_now(uv_default_loop());
std::vector<SimpleMapper *> released;
for (auto const &kv : m_upstreams) {
if (kv.second->idleTime() > m_reuseTimeout) {
released.push_back(kv.second);
continue;
}
kv.second->tick(ticks, now);
}
if (released.empty()) {
return;
}
for (SimpleMapper *mapper : released) {
removeIdle(mapper->id());
removeUpstream(mapper->id());
delete mapper;
}
}
#ifdef APP_DEVEL
void SimpleSplitter::printState()
{
}
#endif
void SimpleSplitter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
m_reuseTimeout = config->reuseTimeout();
const std::vector<Url*> &pools = config->pools();
const std::vector<Url*> &previousPools = previousConfig->pools();
if (pools.size() != previousPools.size() || !std::equal(pools.begin(), pools.end(), previousPools.begin(), compare)) {
Summary::printPools(config);
for (auto const &kv : m_upstreams) {
kv.second->reload(pools);
}
}
}
void SimpleSplitter::onEvent(IEvent *event)
{
switch (event->type())
{
case IEvent::CloseType:
remove(static_cast<CloseEvent*>(event)->miner());
break;
case IEvent::LoginType:
login(static_cast<LoginEvent*>(event));
break;
case IEvent::SubmitType:
submit(static_cast<SubmitEvent*>(event));
break;
default:
break;
}
}
void SimpleSplitter::login(LoginEvent *event)
{
if (!m_idles.empty()) {
for (auto const &kv : m_idles) {
if (kv.second->isReusable()) {
removeIdle(kv.first);
kv.second->reuse(event->miner(), event->request);
return;
}
}
}
SimpleMapper *mapper = new SimpleMapper(m_sequence++, m_controller);
m_upstreams[mapper->id()] = mapper;
mapper->add(event->miner(), event->request);
}
void SimpleSplitter::remove(Miner *miner)
{
const ssize_t id = miner->mapperId();
if (id < 0 || m_upstreams.count(id) == 0) {
return;
}
SimpleMapper *mapper = m_upstreams[id];
mapper->remove(miner);
if (m_reuseTimeout == 0) {
removeUpstream(id);
delete mapper;
}
else {
m_idles[id] = mapper;
}
}
void SimpleSplitter::removeIdle(uint64_t id)
{
auto it = m_idles.find(id);
if (it != m_idles.end()) {
m_idles.erase(it);
}
}
void SimpleSplitter::removeUpstream(uint64_t id)
{
auto it = m_upstreams.find(id);
if (it != m_upstreams.end()) {
m_upstreams.erase(it);
}
}
void SimpleSplitter::submit(SubmitEvent *event)
{
SimpleMapper *mapper = m_upstreams[event->miner()->mapperId()];
if (mapper) {
mapper->submit(event);
}
}

View File

@@ -0,0 +1,83 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 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 __SIMPLESPLITTER_H__
#define __SIMPLESPLITTER_H__
#include <stdint.h>
#include <map>
#include "proxy/splitters/Splitter.h"
class LoginEvent;
class Miner;
class Options;
class SimpleMapper;
class Stats;
class SubmitEvent;
namespace xmrig {
class Controller;
}
class SimpleSplitter : public Splitter
{
public:
SimpleSplitter(xmrig::Controller *controller);
~SimpleSplitter();
protected:
Upstreams upstreams() const override;
void connect() override;
void gc() override;
void printConnections() override;
void tick(uint64_t ticks) override;
# ifdef APP_DEVEL
void printState() override;
# endif
inline void onRejectedEvent(IEvent *event) override {}
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
void onEvent(IEvent *event) override;
private:
void login(LoginEvent *event);
void remove(Miner *miner);
void removeIdle(uint64_t id);
void removeUpstream(uint64_t id);
void submit(SubmitEvent *event);
std::map<uint64_t, SimpleMapper *> m_idles;
std::map<uint64_t, SimpleMapper *> m_upstreams;
uint64_t m_reuseTimeout;
uint64_t m_sequence;
};
#endif /* __SIMPLESPLITTER_H__ */

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -25,9 +25,9 @@
#include <inttypes.h>
#include "api/Api.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "log/Log.h"
#include "Options.h"
#include "proxy/events/AcceptEvent.h"
#include "proxy/events/CloseEvent.h"
#include "proxy/events/LoginEvent.h"
@@ -37,8 +37,9 @@
#include "proxy/workers/Workers.h"
Workers::Workers() :
m_enabled(Options::i()->workers())
Workers::Workers(xmrig::Controller *controller) :
m_enabled(controller->config()->workers()),
m_controller(controller)
{
}
@@ -59,8 +60,8 @@ void Workers::printWorkers()
char workerName[24];
size_t size = 0;
Log::i()->text(Options::i()->colors() ? "\x1B[01;37m%-23s | %-15s | %-5s | %-8s | %-3s | %10s |" : "%-23s | %-15s | %-5s | %-8s | %-3s | %10s |",
"WORKER NAME", "LAST IP", "COUNT", "ACCEPTED", "REJ", "10 MIN");
Log::i()->text(m_controller->config()->colors() ? "\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) {
const char *name = worker.name();
@@ -76,8 +77,8 @@ void Workers::printWorkers()
strncpy(workerName, name, sizeof(workerName) - 1);
}
Log::i()->text("%-23s | %-15s | %5" PRIu64 " | %8" PRIu64 " | %3" PRIu64 " | %5.1f KH/s |",
workerName, worker.ip(), worker.connections(), worker.accepted(), worker.rejected(), worker.hashrate(600));
Log::i()->text("%-23s | %-15s | %5" PRIu64 " | %8" PRIu64 " | %3" PRIu64 " | %6.2f kH/s | %6.2f kH/s |",
workerName, worker.ip(), worker.connections(), worker.accepted(), worker.rejected(), worker.hashrate(600), worker.hashrate(86400));
}
}
@@ -91,8 +92,6 @@ void Workers::tick(uint64_t ticks)
for (Worker &worker : m_workers) {
worker.tick(ticks);
}
Api::tick(m_workers);
}

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -41,15 +41,22 @@ class Miner;
class SubmitEvent;
namespace xmrig {
class Controller;
}
class Workers : public IEventListener
{
public:
Workers();
Workers(xmrig::Controller *controller);
~Workers();
void printWorkers();
void tick(uint64_t ticks);
inline const std::vector<Worker> &workers() const { return m_workers; }
protected:
void onEvent(IEvent *event) override;
void onRejectedEvent(IEvent *event) override;
@@ -65,6 +72,7 @@ private:
std::map<int64_t, size_t> m_miners;
std::map<std::string, size_t> m_map;
std::vector<Worker> m_workers;
xmrig::Controller *m_controller;
};

View File

@@ -4,7 +4,7 @@
* 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 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
@@ -27,19 +27,19 @@
#define APP_ID "xmrig-proxy"
#define APP_NAME "xmrig-proxy"
#define APP_DESC "XMRig Stratum proxy"
#define APP_VERSION "2.4.2"
#define APP_VERSION "2.5.2"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com"
#define APP_KIND "proxy"
#define APP_VER_MAJOR 2
#define APP_VER_MINOR 4
#define APP_VER_MINOR 5
#define APP_VER_BUILD 2
#define APP_VER_REV 0
#ifdef _MSC_VER
# if (_MSC_VER == 1910 || _MSC_VER == 1911)
# if (_MSC_VER >= 1910)
# define MSVC_VERSION 2017
# elif _MSC_VER == 1900
# define MSVC_VERSION 2015

47
src/xmrig.h Normal file
View File

@@ -0,0 +1,47 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 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 __XMRIG_H__
#define __XMRIG_H__
namespace xmrig
{
enum Algo {
ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */
ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
};
enum Variant {
VARIANT_AUTO = -1,
VARIANT_NONE = 0,
VARIANT_V1 = 1
};
} /* xmrig */
#endif /* __XMRIG_H__ */