Compare commits

..

97 Commits

Author SHA1 Message Date
XMRig
6e839d2c92 Use fake algorithm for test. 2019-08-09 15:08:39 +07:00
XMRig
57ebee8ea7 v2.99.1-beta 2019-08-09 14:21:02 +07:00
XMRig
13a44dda16 Sync changes with miner. 2019-08-09 14:01:43 +07:00
XMRig
e661835b83 v2.99.0-beta 2019-08-04 18:22:30 +07:00
XMRig
704ffd4b26 Merge branch 'evo' into beta 2019-08-04 18:19:08 +07:00
xmrig
8564da0b18 Update CHANGELOG.md 2019-08-04 15:53:51 +07:00
XMRig
216c33a633 v2.99.0-evo 2019-08-03 23:34:53 +07:00
XMRig
90261ac1d2 Merge branch 'v2_99' into evo 2019-08-03 23:21:40 +07:00
XMRig
5bda61755f Updated default config.json. 2019-08-03 12:53:52 +07:00
XMRig
cf48ac311c Restored old donate method. 2019-08-03 12:38:07 +07:00
XMRig
a76e56a30d Sync changes. 2019-08-02 21:36:38 +07:00
XMRig
e796b84198 Move files. 2019-07-29 11:30:42 +07:00
XMRig
971e905ccb Removed unused source files. 2019-07-29 08:17:42 +07:00
XMRig
22605fdb29 Sync changes. 2019-07-28 21:24:06 +07:00
XMRig
9fc2b8b2d2 Merge branch 'beta' into evo 2019-07-28 18:16:32 +07:00
XMRig
ed820e9eae v2.16.1-beta 2019-07-21 23:47:55 +07:00
XMRig
bfc2c27bb1 Merge branch 'evo' into beta 2019-07-21 23:44:44 +07:00
xmrig
c6e0d4ef09 Update CHANGELOG.md 2019-07-21 03:05:39 +07:00
xmrig
3c80356961 Update CHANGELOG.md 2019-07-21 03:05:13 +07:00
XMRig
d51dcd6315 Added "rx/loki" algorithm. 2019-07-20 00:41:01 +07:00
XMRig
be09f9ef3c v2.16.1-evo 2019-06-26 11:09:29 +07:00
XMRig
4f1ad0aea3 Merge branch 'beta' into evo 2019-06-26 11:08:45 +07:00
xmrig
9c1fba5a25 Update CHANGELOG.md 2019-06-26 11:03:56 +07:00
xmrig
eabbfc1ec4 Update CHANGELOG.md 2019-06-25 14:49:45 +07:00
XMRig
be8fdaf6f0 v2.16.0-beta 2019-06-25 14:14:42 +07:00
XMRig
fe002102c6 Merge branch 'evo' into beta 2019-06-25 14:13:50 +07:00
XMRig
98e04e24cf Fix. 2019-06-25 10:52:59 +07:00
XMRig
d7faffc0a0 Added RandomWOW support. 2019-06-25 10:22:34 +07:00
XMRig
816489d110 Sync changes. 2019-06-01 13:13:06 +07:00
XMRig
96e2a36d41 Merge branch 'dev' into evo 2019-06-01 12:40:50 +07:00
XMRig
e3a62ab274 v2.14.5-dev 2019-05-31 23:06:10 +07:00
XMRig
3549bc687e Merge branch 'master' into dev 2019-05-31 22:55:02 +07:00
XMRig
157ba8ec42 v2.14.4 2019-05-30 12:03:32 +07:00
XMRig
cd848f27f9 Merge branch 'dev' 2019-05-30 12:03:03 +07:00
xmrig
64117d6bc7 Update CHANGELOG.md 2019-05-29 17:25:50 +07:00
XMRig
6634b61dab Merge branch 'master' into dev 2019-05-29 17:08:09 +07:00
XMRig
d2fb04ead8 v2.14.4-dev 2019-05-29 17:03:55 +07:00
XMRig
79d5be209f Removed obsolete automatic variants. 2019-05-26 19:02:16 +07:00
XMRig
354dd60f7f v2.15.4-beta 2019-04-18 21:01:29 +07:00
XMRig
20998e2c77 Merge branch 'beta' into evo 2019-04-18 21:00:27 +07:00
XMRig
02efd26a50 Fixed regression, default value for algo option was not applied. 2019-04-18 15:27:26 +07:00
XMRig
234b96bc16 v2.15.2-beta 2019-04-18 00:26:45 +07:00
XMRig
8e0507d865 Merge branch 'evo' into beta 2019-04-18 00:26:16 +07:00
xmrig
8d5802b77e Update CHANGELOG.md 2019-04-18 00:02:40 +07:00
XMRig
9620faf35c Updated default config. 2019-04-17 19:06:05 +07:00
XMRig
f234fd71a9 Fixed Linux build. 2019-04-14 03:40:04 +07:00
XMRig
6aba4bd787 Sync changes. 2019-04-14 03:36:21 +07:00
XMRig
aa7a64ae04 Added daemon support. 2019-04-13 19:06:33 +07:00
XMRig
a11aceb69a Fix build on FreeBSD. 2019-04-06 21:19:25 +07:00
XMRig
513db3012e Merge branch 'feature-json-centric-config' into evo 2019-04-06 18:31:35 +07:00
XMRig
26815f93eb New config subsystem. 2019-04-06 17:48:31 +07:00
XMRig
fc4ffc0a1b Fixed, big HTTP responses was truncated. 2019-04-02 17:47:37 +07:00
XMRig
0f3a0afc13 v2.15.2-evo 2019-04-02 00:00:54 +07:00
XMRig
8caed995de Merge branch 'beta' into evo 2019-04-01 23:42:11 +07:00
XMRig
7ddbcb0c21 v2.15.1-beta 2019-04-01 19:06:32 +07:00
XMRig
beeaf14784 Merge branch 'evo' into beta 2019-04-01 19:06:03 +07:00
xmrig
b1ef6268aa Update CHANGELOG.md 2019-04-01 19:02:23 +07:00
XMRig
0bfee737cb Fixed wrong status code for "GET /1/config" and updated app.rc. 2019-04-01 17:37:03 +07:00
XMRig
1158294789 Sync changes. 2019-04-01 12:31:49 +07:00
XMRig
b49a51e569 Better compatibility with previous configs. 2019-04-01 00:28:09 +07:00
XMRig
f7f8e54498 Fixed malformed HTTP response on Linux. 2019-04-01 00:20:11 +07:00
XMRig
916eb43349 Fix compile issue. 2019-04-01 00:01:10 +07:00
XMRig
294dd9f2e1 Merge branch 'feature-httpd' into evo 2019-03-31 23:38:35 +07:00
XMRig
ce0a5ac20b Fixed Linux build. 2019-03-31 23:21:51 +07:00
XMRig
76e47c864f Restored API. 2019-03-31 20:33:43 +07:00
XMRig
2822d65150 Replace XMRIG_NO_TLS to XMRIG_FEATURE_TLS 2019-03-31 04:10:00 +07:00
XMRig
7fd1ac53ee Sync changes. 2019-03-31 04:01:08 +07:00
xmrig
d10846fde6 Update CHANGELOG.md 2019-03-27 21:20:00 +07:00
XMRig
a32de74384 Remove unused field. 2019-03-27 20:06:49 +07:00
XMRig
9cdaad7c74 Sync changes. 2019-03-27 18:02:18 +07:00
XMRig
f890145a6d Fix Linux build. 2019-03-27 03:30:49 +07:00
XMRig
8879b0119e Use new log. 2019-03-27 03:16:17 +07:00
XMRig
518923879a Merge branch 'beta' into evo 2019-03-27 02:00:49 +07:00
XMRig
73456ec126 v2.15.0-beta 2019-03-24 02:31:41 +07:00
xmrig
441822eb0b Update CHANGELOG.md 2019-03-24 02:26:45 +07:00
XMRig
7d5b9d0154 Merge branch 'master' into beta 2019-03-24 02:18:55 +07:00
xmrig
398646b7f4 Update CHANGELOG.md 2019-03-23 16:11:59 +07:00
XMRig
14e80ef4d3 v2.15.0-evo 2019-03-20 11:51:59 +07:00
XMRig
acfb73bf98 Merge branch 'feature-donate-over-proxy' into evo 2019-03-20 11:43:56 +07:00
XMRig
4d6b7c78a9 Add url checking. 2019-03-20 10:17:33 +07:00
XMRig
2024200df1 Fix uv_tty_reset_mode on Linux. 2019-03-19 22:09:07 +07:00
XMRig
e6c7805f6e Sync changes. 2019-03-19 21:49:07 +07:00
XMRig
d011694905 Fix nicehash mode and remove process title. 2019-03-17 14:55:15 +07:00
XMRig
1e5b592fbd Added graceful exit. 2019-03-17 03:23:16 +07:00
XMRig
d2ffa7302a Sync changes. 2019-03-16 02:53:38 +07:00
XMRig
bde3eff542 Add process title. 2019-03-14 23:03:03 +07:00
XMRig
f6171f406f Remove timestamp.h. 2019-03-14 19:09:49 +07:00
XMRig
868b3cec4d Fix statistics. 2019-03-14 18:03:35 +07:00
XMRig
2b2dae6bcb Implemented donate over proxy feature. 2019-03-14 01:42:40 +07:00
XMRig
1f2790781f Added option "access-password". 2019-03-11 22:15:19 +07:00
XMRig
4685a5cb8f Added option "algo-ext". 2019-03-11 01:03:27 +07:00
XMRig
3d6be9ef77 v2.14.1 2019-03-10 11:39:38 +07:00
XMRig
aae906e5d3 Merge branch 'dev' 2019-03-10 11:39:04 +07:00
XMRig
b272148c72 Prepare for donation over proxy feature. 2019-03-09 21:57:47 +07:00
XMRig
46d4799c43 #306 Fix build on FreeBSD. 2019-03-07 23:21:22 +07:00
XMRig
8166b3bac4 v2.14.2-dev 2019-03-07 17:59:56 +07:00
XMRig
ec77f1a52f Merge branch 'master' into dev 2019-03-07 17:59:29 +07:00
233 changed files with 14415 additions and 7115 deletions

View File

@@ -1,3 +1,47 @@
# v2.99.1-beta
- [#1066](https://github.com/xmrig/xmrig/issues/1066#issuecomment-518080529) Added error message if pool not ready for RandomX.
- Name for reference RandomX configuration changed to `rx/text` to avoid potential conflicts in future.
# v2.99.0-beta
* [#335](https://github.com/xmrig/xmrig-proxy/issues/335) Added support for unlimited algorithm switching.
* Config files from previous versions NOT compatible, `variant` option replaced to `algo`, global option `algo` removed.
* Command line options also not compatible, `--variant` option replaced to `--algo`.
* Algorithm `cn/msr` renamed to `cn/fast`.
* Algorithm `cn/xtl` removed.
# v2.16.1-beta
- Added RandomXL algorithm for [Loki](https://loki.network/).
- Algorithm name used by proxy is `randomx/loki` or `rx/loki`.
# v2.16.0-beta
- [#1036](https://github.com/xmrig/xmrig/pull/1036) Added RandomWOW (RandomX with different preferences) algorithm support for [Wownero](http://wownero.org/).
- Algorithm name used by proxy is `randomx/wow` or `rx/wow`.
- Currently runtime algorithm switching NOT supported with other algorithms.
# v2.15.3-beta
- [#1014](https://github.com/xmrig/xmrig/issues/1014) Fixed regression, default value for `algo` option was not applied.
# v2.15.2-beta
- [#1010](https://github.com/xmrig/xmrig/pull/1010#issuecomment-482632107) Added daemon support (solo mining).
- Config subsystem was rewritten, internally JSON is primary format now.
- Fixed regression, big HTTP responses was truncated.
# v2.15.1-beta
- [#1007](https://github.com/xmrig/xmrig/issues/1007) Old HTTP API backend based on libmicrohttpd, replaced to custom HTTP server (libuv + http_parser).
- [#257](https://github.com/xmrig/xmrig-nvidia/pull/257) New logging subsystem, file and syslog now always without colors.
# v2.15.0-beta
- [#314](https://github.com/xmrig/xmrig-proxy/issues/314) Added donate over proxy feature and changed donation model.
- Added new options `algo-ext` and `access-password`.
- Added real graceful exit.
# v2.14.4
- Fixed MSVC 2019 version detection.
- Removed obsolete automatic variants.
# v2.14.1
- [#306](https://github.com/xmrig/xmrig-proxy/issues/306) [#310](https://github.com/xmrig/xmrig-proxy/issues/310) Fixed compile issues and random crashing if verbose mode or access log was enabled.
# v2.14.0
- **[#969](https://github.com/xmrig/xmrig/pull/969) Added new algorithm `cryptonight/rwz`, short alias `cn/rwz` (also known as CryptoNight ReverseWaltz), for upcoming [Graft](https://www.graft.network/) fork.**
- **[#931](https://github.com/xmrig/xmrig/issues/931) Added new algorithm `cryptonight/zls`, short alias `cn/zls` for [Zelerius Network](https://zelerius.org) fork.**

View File

@@ -4,65 +4,27 @@ project(xmrig-proxy)
option(WITH_GOOGLE_BREAKPAD "Use Google Breakpad" OFF)
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
option(WITH_HTTPD "HTTP REST API" ON)
option(WITH_HTTP "HTTP protocol support (client/server)" ON)
option(WITH_TLS "Enable OpenSSL support" ON)
include (CheckIncludeFile)
include (src/base/base.cmake)
set(HEADERS
src/3rdparty/align.h
"${HEADERS_BASE}"
"${HEADERS_BASE_HTTP}"
src/App.h
src/base/io/Json.h
src/base/io/Watcher.h
src/base/kernel/Entry.h
src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/ISignalListener.h
src/base/kernel/interfaces/IWatcherListener.h
src/base/kernel/Process.h
src/base/kernel/Signals.h
src/base/net/Pool.h
src/base/net/Pools.h
src/base/tools/Arguments.h
src/base/tools/Handle.h
src/base/tools/String.h
src/common/config/CommonConfig.h
src/common/config/ConfigLoader.h
src/common/config/ConfigWatcher.h
src/common/Console.h
src/common/crypto/Algorithm.h
src/common/crypto/keccak.h
src/common/interfaces/IClientListener.h
src/common/interfaces/IConfig.h
src/common/interfaces/IConfigCreator.h
src/common/interfaces/IConsoleListener.h
src/common/interfaces/IControllerListener.h
src/common/interfaces/ILogBackend.h
src/common/interfaces/IStrategy.h
src/common/interfaces/IStrategyListener.h
src/common/log/BasicLog.h
src/common/log/ConsoleLog.h
src/common/log/FileLog.h
src/common/log/Log.h
src/common/net/Client.h
src/common/net/Id.h
src/common/net/Job.h
src/common/net/Storage.h
src/common/net/strategies/FailoverStrategy.h
src/common/net/strategies/SinglePoolStrategy.h
src/common/Platform.h
src/common/xmrig.h
src/core/Config.h
src/core/ConfigLoader_platform.h
src/core/config/Config_platform.h
src/core/config/Config.h
src/core/config/ConfigTransform.h
src/core/config/usage.h
src/core/Controller.h
src/core/usage.h
src/crypto/cn/CnAlgo.h
src/crypto/common/Algorithm.h
src/crypto/common/keccak.h
src/donate.h
src/interfaces/IEvent.h
src/interfaces/IEventListener.h
src/interfaces/ISplitter.h
src/log/AccessLog.h
src/log/ShareLog.h
src/net/JobResult.h
src/net/strategies/DonateStrategy.h
src/proxy/BindHost.h
@@ -77,12 +39,19 @@ set(HEADERS
src/proxy/events/LoginEvent.h
src/proxy/events/MinerEvent.h
src/proxy/events/SubmitEvent.h
src/proxy/interfaces/IEvent.h
src/proxy/interfaces/IEventListener.h
src/proxy/interfaces/ISplitter.h
src/proxy/log/AccessLog.h
src/proxy/log/ShareLog.h
src/proxy/Login.h
src/proxy/Miner.h
src/proxy/Miners.h
src/proxy/Proxy.h
src/proxy/ProxyDebug.h
src/proxy/Server.h
src/proxy/splitters/donate/DonateMapper.h
src/proxy/splitters/donate/DonateSplitter.h
src/proxy/splitters/nicehash/NonceMapper.h
src/proxy/splitters/nicehash/NonceSplitter.h
src/proxy/splitters/nicehash/NonceStorage.h
@@ -100,37 +69,14 @@ set(HEADERS
)
set(SOURCES
"${SOURCES_BASE}"
"${SOURCES_BASE_HTTP}"
src/App.cpp
src/base/io/Json.cpp
src/base/io/Watcher.cpp
src/base/kernel/Entry.cpp
src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp
src/base/net/Pool.cpp
src/base/net/Pools.cpp
src/base/tools/Arguments.cpp
src/base/tools/Handle.cpp
src/base/tools/String.cpp
src/common/config/CommonConfig.cpp
src/common/config/ConfigLoader.cpp
src/common/config/ConfigWatcher.cpp
src/common/Console.cpp
src/common/crypto/Algorithm.cpp
src/common/crypto/keccak.cpp
src/common/log/BasicLog.cpp
src/common/log/ConsoleLog.cpp
src/common/log/FileLog.cpp
src/common/log/Log.cpp
src/common/net/Client.cpp
src/common/net/Job.cpp
src/common/net/strategies/FailoverStrategy.cpp
src/common/net/strategies/SinglePoolStrategy.cpp
src/common/net/SubmitResult.cpp
src/common/Platform.cpp
src/core/Config.cpp
src/core/config/Config.cpp
src/core/config/ConfigTransform.cpp
src/core/Controller.cpp
src/log/AccessLog.cpp
src/log/ShareLog.cpp
src/crypto/common/Algorithm.cpp
src/crypto/common/keccak.cpp
src/net/JobResult.cpp
src/net/strategies/DonateStrategy.cpp
src/proxy/BindHost.cpp
@@ -141,12 +87,16 @@ set(SOURCES
src/proxy/events/ConnectionEvent.h
src/proxy/events/Event.cpp
src/proxy/events/MinerEvent.cpp
src/proxy/log/AccessLog.cpp
src/proxy/log/ShareLog.cpp
src/proxy/Login.cpp
src/proxy/Miner.cpp
src/proxy/Miners.cpp
src/proxy/Proxy.cpp
src/proxy/ProxyDebug.cpp
src/proxy/Server.cpp
src/proxy/splitters/donate/DonateMapper.cpp
src/proxy/splitters/donate/DonateSplitter.cpp
src/proxy/splitters/nicehash/NonceMapper.cpp
src/proxy/splitters/nicehash/NonceSplitter.cpp
src/proxy/splitters/nicehash/NonceStorage.cpp
@@ -162,10 +112,9 @@ set(SOURCES
if (WIN32)
set(SOURCES_OS
"${SOURCES_OS}"
res/app.rc
src/App_win.cpp
src/base/io/Json_win.cpp
src/common/Platform_win.cpp
src/proxy/Uuid_win.cpp
)
@@ -173,9 +122,8 @@ if (WIN32)
set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv)
elseif (APPLE)
set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_mac.cpp
src/proxy/Uuid_mac.cpp
)
@@ -183,9 +131,8 @@ elseif (APPLE)
set(EXTRA_LIBS ${CFLIB})
else()
set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_unix.cpp
src/proxy/Uuid_unix.cpp
)
@@ -202,6 +149,12 @@ add_definitions(/D__STDC_FORMAT_MACROS)
add_definitions(/DAPP_DEVEL)
add_definitions(/DXMRIG_NO_ASM)
add_definitions(/DXMRIG_ALGO_RANDOMX)
add_definitions(/DXMRIG_ALGO_CN_LITE)
add_definitions(/DXMRIG_ALGO_CN_HEAVY)
add_definitions(/DXMRIG_ALGO_CN_PICO)
add_definitions(/DXMRIG_ALGO_CN_GPU)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(/DRAPIDJSON_SSE2)
endif()
@@ -260,12 +213,6 @@ endif()
include(cmake/OpenSSL.cmake)
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_SYSLOG_H)
set(SOURCES_SYSLOG src/common/log/SysLog.h src/common/log/SysLog.cpp)
endif()
if (WITH_GOOGLE_BREAKPAD)
include_directories(/usr/local/include/breakpad)
set(GOOGLE_BREAKPAD_LIBS breakpad_client)
@@ -273,31 +220,22 @@ else()
add_definitions(/DXMRIG_NO_GOOGLE_BREAKPAD)
endif()
if (WITH_HTTPD)
find_package(MHD)
if (MHD_FOUND)
include_directories(${MHD_INCLUDE_DIRS})
set(HTTPD_SOURCES
src/api/Api.h
src/api/ApiRouter.h
src/common/api/HttpBody.h
src/common/api/Httpd.h
src/common/api/HttpReply.h
src/common/api/HttpRequest.h
src/api/Api.cpp
src/api/ApiRouter.cpp
src/common/api/Httpd.cpp
src/common/api/HttpRequest.cpp
)
else()
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
endif()
if (WITH_HTTP)
set(HTTP_SOURCES
src/api/Api.cpp
src/api/Api.h
src/api/Httpd.cpp
src/api/Httpd.h
src/api/interfaces/IApiRequest.h
src/api/requests/ApiRequest.cpp
src/api/requests/ApiRequest.h
src/api/requests/HttpApiRequest.cpp
src/api/requests/HttpApiRequest.h
src/api/v1/ApiRouter.cpp
src/api/v1/ApiRouter.h
)
else()
set(HTTPD_SOURCES "")
set(MHD_LIBRARY "")
add_definitions(/DXMRIG_NO_HTTPD)
add_definitions(/DXMRIG_NO_API)
set(HTTP_SOURCES "")
endif()
if (WITH_DEBUG_LOG)
@@ -308,5 +246,5 @@ include_directories(src)
include_directories(src/3rdparty)
include_directories(${UV_INCLUDE_DIR})
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${GOOGLE_BREAKPAD_LIBS})
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_SYSLOG} ${HTTP_SOURCES} ${TLS_SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${GOOGLE_BREAKPAD_LIBS})

View File

@@ -12,8 +12,8 @@ if (WITH_TLS)
if (OPENSSL_FOUND)
set(TLS_SOURCES
src/common/net/Tls.cpp
src/common/net/Tls.h
src/base/net/stratum/Tls.cpp
src/base/net/stratum/Tls.h
src/proxy/tls/Tls.cpp
src/proxy/tls/Tls.h
src/proxy/tls/TlsConfig.cpp
@@ -21,14 +21,21 @@ if (WITH_TLS)
src/proxy/tls/TlsContext.cpp
src/proxy/tls/TlsContext.h
)
include_directories(${OPENSSL_INCLUDE_DIR})
if (WITH_HTTP)
set(TLS_SOURCES ${TLS_SOURCES} src/base/net/http/HttpsClient.h src/base/net/http/HttpsClient.cpp)
endif()
else()
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
endif()
add_definitions(/DXMRIG_FEATURE_TLS)
else()
set(TLS_SOURCES "")
set(OPENSSL_LIBRARIES "")
add_definitions(/DXMRIG_NO_TLS)
remove_definitions(/DXMRIG_FEATURE_TLS)
set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
endif()

View File

@@ -1,7 +1,7 @@
#include <windows.h>
#include "../src/version.h"
IDI_ICON1 ICON DISCARDABLE "app.ico"
101 ICON "app.ico"
VS_VERSION_INFO VERSIONINFO
FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0

33
src/3rdparty/align.h vendored
View File

@@ -1,33 +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/>.
*/
#ifndef __ALIGN_H__
#define __ALIGN_H__
#ifdef _MSC_VER
# define VAR_ALIGN(x, decl) __declspec(align(x)) decl
#else
# define VAR_ALIGN(x, decl) decl __attribute__ ((aligned(x)))
#endif
#endif /* __ALIGN_H__ */

68
src/3rdparty/http-parser/AUTHORS vendored Normal file
View File

@@ -0,0 +1,68 @@
# Authors ordered by first contribution.
Ryan Dahl <ry@tinyclouds.org>
Jeremy Hinegardner <jeremy@hinegardner.org>
Sergey Shepelev <temotor@gmail.com>
Joe Damato <ice799@gmail.com>
tomika <tomika_nospam@freemail.hu>
Phoenix Sol <phoenix@burninglabs.com>
Cliff Frey <cliff@meraki.com>
Ewen Cheslack-Postava <ewencp@cs.stanford.edu>
Santiago Gala <sgala@apache.org>
Tim Becker <tim.becker@syngenio.de>
Jeff Terrace <jterrace@gmail.com>
Ben Noordhuis <info@bnoordhuis.nl>
Nathan Rajlich <nathan@tootallnate.net>
Mark Nottingham <mnot@mnot.net>
Aman Gupta <aman@tmm1.net>
Tim Becker <tim.becker@kuriositaet.de>
Sean Cunningham <sean.cunningham@mandiant.com>
Peter Griess <pg@std.in>
Salman Haq <salman.haq@asti-usa.com>
Cliff Frey <clifffrey@gmail.com>
Jon Kolb <jon@b0g.us>
Fouad Mardini <f.mardini@gmail.com>
Paul Querna <pquerna@apache.org>
Felix Geisendörfer <felix@debuggable.com>
koichik <koichik@improvement.jp>
Andre Caron <andre.l.caron@gmail.com>
Ivo Raisr <ivosh@ivosh.net>
James McLaughlin <jamie@lacewing-project.org>
David Gwynne <loki@animata.net>
Thomas LE ROUX <thomas@november-eleven.fr>
Randy Rizun <rrizun@ortivawireless.com>
Andre Louis Caron <andre.louis.caron@usherbrooke.ca>
Simon Zimmermann <simonz05@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com>
Martell Malone <martellmalone@gmail.com>
Bertrand Paquet <bpaquet@octo.com>
BogDan Vatra <bogdan@kde.org>
Peter Faiman <peter@thepicard.org>
Corey Richardson <corey@octayn.net>
Tóth Tamás <tomika_nospam@freemail.hu>
Cam Swords <cam.swords@gmail.com>
Chris Dickinson <christopher.s.dickinson@gmail.com>
Uli Köhler <ukoehler@btronik.de>
Charlie Somerville <charlie@charliesomerville.com>
Patrik Stutz <patrik.stutz@gmail.com>
Fedor Indutny <fedor.indutny@gmail.com>
runner <runner.mei@gmail.com>
Alexis Campailla <alexis@janeasystems.com>
David Wragg <david@wragg.org>
Vinnie Falco <vinnie.falco@gmail.com>
Alex Butum <alexbutum@linux.com>
Rex Feng <rexfeng@gmail.com>
Alex Kocharin <alex@kocharin.ru>
Mark Koopman <markmontymark@yahoo.com>
Helge Heß <me@helgehess.eu>
Alexis La Goutte <alexis.lagoutte@gmail.com>
George Miroshnykov <george.miroshnykov@gmail.com>
Maciej Małecki <me@mmalecki.com>
Marc O'Morain <github.com@marcomorain.com>
Jeff Pinner <jpinner@twitter.com>
Timothy J Fontaine <tjfontaine@gmail.com>
Akagi201 <akagi201@gmail.com>
Romain Giraud <giraud.romain@gmail.com>
Jay Satiro <raysatiro@yahoo.com>
Arne Steen <Arne.Steen@gmx.de>
Kjell Schubert <kjell.schubert@gmail.com>
Olivier Mengué <dolmen@cpan.org>

19
src/3rdparty/http-parser/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

246
src/3rdparty/http-parser/README.md vendored Normal file
View File

@@ -0,0 +1,246 @@
HTTP Parser
===========
[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser)
This is a parser for HTTP messages written in C. It parses both requests and
responses. The parser is designed to be used in performance HTTP
applications. It does not make any syscalls nor allocations, it does not
buffer data, it can be interrupted at anytime. Depending on your
architecture, it only requires about 40 bytes of data per message
stream (in a web server that is per connection).
Features:
* No dependencies
* Handles persistent streams (keep-alive).
* Decodes chunked encoding.
* Upgrade support
* Defends against buffer overflow attacks.
The parser extracts the following information from HTTP messages:
* Header fields and values
* Content-Length
* Request method
* Response status code
* Transfer-Encoding
* HTTP version
* Request URL
* Message body
Usage
-----
One `http_parser` object is used per TCP connection. Initialize the struct
using `http_parser_init()` and set the callbacks. That might look something
like this for a request parser:
```c
http_parser_settings settings;
settings.on_url = my_url_callback;
settings.on_header_field = my_header_field_callback;
/* ... */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST);
parser->data = my_socket;
```
When data is received on the socket execute the parser and check for errors.
```c
size_t len = 80*1024, nparsed;
char buf[len];
ssize_t recved;
recved = recv(fd, buf, len, 0);
if (recved < 0) {
/* Handle error. */
}
/* Start up / continue the parser.
* Note we pass recved==0 to signal that EOF has been received.
*/
nparsed = http_parser_execute(parser, &settings, buf, recved);
if (parser->upgrade) {
/* handle new protocol */
} else if (nparsed != recved) {
/* Handle error. Usually just close the connection. */
}
```
`http_parser` needs to know where the end of the stream is. For example, sometimes
servers send responses without Content-Length and expect the client to
consume input (for the body) until EOF. To tell `http_parser` about EOF, give
`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors
can still be encountered during an EOF, so one must still be prepared
to receive them.
Scalar valued message information such as `status_code`, `method`, and the
HTTP version are stored in the parser structure. This data is only
temporally stored in `http_parser` and gets reset on each new message. If
this information is needed later, copy it out of the structure during the
`headers_complete` callback.
The parser decodes the transfer-encoding for both requests and responses
transparently. That is, a chunked encoding is decoded before being sent to
the on_body callback.
The Special Problem of Upgrade
------------------------------
`http_parser` supports upgrading the connection to a different protocol. An
increasingly common example of this is the WebSocket protocol which sends
a request like
GET /demo HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
WebSocket-Protocol: sample
followed by non-HTTP data.
(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the
WebSocket protocol.)
To support this, the parser will treat this as a normal HTTP message without a
body, issuing both on_headers_complete and on_message_complete callbacks. However
http_parser_execute() will stop parsing at the end of the headers and return.
The user is expected to check if `parser->upgrade` has been set to 1 after
`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied
offset by the return value of `http_parser_execute()`.
Callbacks
---------
During the `http_parser_execute()` call, the callbacks set in
`http_parser_settings` will be executed. The parser maintains state and
never looks behind, so buffering the data is not necessary. If you need to
save certain data for later usage, you can do that from the callbacks.
There are two types of callbacks:
* notification `typedef int (*http_cb) (http_parser*);`
Callbacks: on_message_begin, on_headers_complete, on_message_complete.
* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);`
Callbacks: (requests only) on_url,
(common) on_header_field, on_header_value, on_body;
Callbacks must return 0 on success. Returning a non-zero value indicates
error to the parser, making it exit immediately.
For cases where it is necessary to pass local information to/from a callback,
the `http_parser` object's `data` field can be used.
An example of such a case is when using threads to handle a socket connection,
parse a request, and then give a response over that socket. By instantiation
of a thread-local struct containing relevant data (e.g. accepted socket,
allocated memory for callbacks to write into, etc), a parser's callbacks are
able to communicate data between the scope of the thread and the scope of the
callback in a threadsafe manner. This allows `http_parser` to be used in
multi-threaded contexts.
Example:
```c
typedef struct {
socket_t sock;
void* buffer;
int buf_len;
} custom_data_t;
int my_url_callback(http_parser* parser, const char *at, size_t length) {
/* access to thread local custom_data_t struct.
Use this access save parsed data for later use into thread local
buffer, or communicate over socket
*/
parser->data;
...
return 0;
}
...
void http_parser_thread(socket_t sock) {
int nparsed = 0;
/* allocate memory for user data */
custom_data_t *my_data = malloc(sizeof(custom_data_t));
/* some information for use by callbacks.
* achieves thread -> callback information flow */
my_data->sock = sock;
/* instantiate a thread-local parser */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST); /* initialise parser */
/* this custom data reference is accessible through the reference to the
parser supplied to callback functions */
parser->data = my_data;
http_parser_settings settings; /* set up callbacks */
settings.on_url = my_url_callback;
/* execute parser */
nparsed = http_parser_execute(parser, &settings, buf, recved);
...
/* parsed information copied from callback.
can now perform action on data copied into thread-local memory from callbacks.
achieves callback -> thread information flow */
my_data->buffer;
...
}
```
In case you parse HTTP message in chunks (i.e. `read()` request line
from socket, parse, read half headers, parse, etc) your data callbacks
may be called more than once. `http_parser` guarantees that data pointer is only
valid for the lifetime of callback. You can also `read()` into a heap allocated
buffer to avoid copying memory around if this fits your application.
Reading headers may be a tricky task if you read/parse headers partially.
Basically, you need to remember whether last header callback was field or value
and apply the following logic:
(on_header_field and on_header_value shortened to on_h_*)
------------------------ ------------ --------------------------------------------
| State (prev. callback) | Callback | Description/action |
------------------------ ------------ --------------------------------------------
| nothing (first call) | on_h_field | Allocate new buffer and copy callback data |
| | | into it |
------------------------ ------------ --------------------------------------------
| value | on_h_field | New header started. |
| | | Copy current name,value buffers to headers |
| | | list and allocate new buffer for new name |
------------------------ ------------ --------------------------------------------
| field | on_h_field | Previous name continues. Reallocate name |
| | | buffer and append callback data to it |
------------------------ ------------ --------------------------------------------
| field | on_h_value | Value for current header started. Allocate |
| | | new buffer and copy callback data to it |
------------------------ ------------ --------------------------------------------
| value | on_h_value | Value continues. Reallocate value buffer |
| | | and append callback data to it |
------------------------ ------------ --------------------------------------------
Parsing URLs
------------
A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`.
Users of this library may wish to use it to parse URLs constructed from
consecutive `on_url` callbacks.
See examples of reading in headers:
* [partial example](http://gist.github.com/155877) in C
* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C
* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript

2501
src/3rdparty/http-parser/http_parser.c vendored Normal file

File diff suppressed because it is too large Load Diff

439
src/3rdparty/http-parser/http_parser.h vendored Normal file
View File

@@ -0,0 +1,439 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef http_parser_h
#define http_parser_h
#ifdef __cplusplus
extern "C" {
#endif
/* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9
#define HTTP_PARSER_VERSION_PATCH 0
#include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \
(!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
#include <BaseTsd.h>
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
* faster
*/
#ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1
#endif
/* Maximium header size allowed. If the macro is not defined
* before including this header then the default is used. To
* change the maximum header size, define the macro in the build
* environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
* the effective limit on the size of the header, define the macro
* to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
*/
#ifndef HTTP_MAX_HEADER_SIZE
# define HTTP_MAX_HEADER_SIZE (80*1024)
#endif
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
/* Callbacks should return non-zero to indicate an error. The parser will
* then halt execution.
*
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
* returning '1' from on_headers_complete will tell the parser that it
* should not expect a body. This is used when receiving a response to a
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body.
*
* Returning `2` from on_headers_complete will tell parser that it should not
* expect neither a body nor any futher responses on this connection. This is
* useful for handling responses to a CONNECT request which may not contain
* `Upgrade` or `Connection: upgrade` headers.
*
* http_data_cb does not return data chunks. It will be called arbitrarily
* many times for each string. E.G. you might get 10 callbacks for "on_url"
* each providing just a few characters more data.
*/
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
/* Status Codes */
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \
XX(200, OK, OK) \
XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi-Status) \
XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
XX(302, FOUND, Found) \
XX(303, SEE_OTHER, See Other) \
XX(304, NOT_MODIFIED, Not Modified) \
XX(305, USE_PROXY, Use Proxy) \
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
XX(400, BAD_REQUEST, Bad Request) \
XX(401, UNAUTHORIZED, Unauthorized) \
XX(402, PAYMENT_REQUIRED, Payment Required) \
XX(403, FORBIDDEN, Forbidden) \
XX(404, NOT_FOUND, Not Found) \
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
XX(408, REQUEST_TIMEOUT, Request Timeout) \
XX(409, CONFLICT, Conflict) \
XX(410, GONE, Gone) \
XX(411, LENGTH_REQUIRED, Length Required) \
XX(412, PRECONDITION_FAILED, Precondition Failed) \
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
XX(414, URI_TOO_LONG, URI Too Long) \
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
XX(417, EXPECTATION_FAILED, Expectation Failed) \
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
XX(423, LOCKED, Locked) \
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
XX(501, NOT_IMPLEMENTED, Not Implemented) \
XX(502, BAD_GATEWAY, Bad Gateway) \
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
enum http_status
{
#define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX)
#undef XX
};
/* Request Methods */
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
/* pathological */ \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
/* WebDAV */ \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
/* subversion */ \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
/* upnp */ \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
/* RFC-5789 */ \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
XX(33, SOURCE, SOURCE) \
enum http_method
{
#define XX(num, name, string) HTTP_##name = num,
HTTP_METHOD_MAP(XX)
#undef XX
};
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
/* Flag values for http_parser.flags field */
enum flags
{ F_CHUNKED = 1 << 0
, F_CONNECTION_KEEP_ALIVE = 1 << 1
, F_CONNECTION_CLOSE = 1 << 2
, F_CONNECTION_UPGRADE = 1 << 3
, F_TRAILING = 1 << 4
, F_UPGRADE = 1 << 5
, F_SKIPBODY = 1 << 6
, F_CONTENTLENGTH = 1 << 7
};
/* Map for errno-related constants
*
* The provided argument should be a macro that takes 2 arguments.
*/
#define HTTP_ERRNO_MAP(XX) \
/* No error */ \
XX(OK, "success") \
\
/* Callback-related errors */ \
XX(CB_message_begin, "the on_message_begin callback failed") \
XX(CB_url, "the on_url callback failed") \
XX(CB_header_field, "the on_header_field callback failed") \
XX(CB_header_value, "the on_header_value callback failed") \
XX(CB_headers_complete, "the on_headers_complete callback failed") \
XX(CB_body, "the on_body callback failed") \
XX(CB_message_complete, "the on_message_complete callback failed") \
XX(CB_status, "the on_status callback failed") \
XX(CB_chunk_header, "the on_chunk_header callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
\
/* Parsing-related errors */ \
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
XX(HEADER_OVERFLOW, \
"too many header bytes seen; overflow detected") \
XX(CLOSED_CONNECTION, \
"data received after completed connection: close message") \
XX(INVALID_VERSION, "invalid HTTP version") \
XX(INVALID_STATUS, "invalid HTTP status code") \
XX(INVALID_METHOD, "invalid HTTP method") \
XX(INVALID_URL, "invalid URL") \
XX(INVALID_HOST, "invalid host") \
XX(INVALID_PORT, "invalid port") \
XX(INVALID_PATH, "invalid path") \
XX(INVALID_QUERY_STRING, "invalid query string") \
XX(INVALID_FRAGMENT, "invalid fragment") \
XX(LF_EXPECTED, "LF character expected") \
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(INVALID_CONTENT_LENGTH, \
"invalid character in content-length header") \
XX(UNEXPECTED_CONTENT_LENGTH, \
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \
XX(UNKNOWN, "an unknown error occurred")
/* Define HPE_* values for each errno value above */
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno {
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN
/* Get an http_errno value from an http_parser */
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
struct http_parser {
/** PRIVATE **/
unsigned int type : 2; /* enum http_parser_type */
unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
unsigned int state : 7; /* enum state from http_parser.c */
unsigned int header_state : 7; /* enum header_state from http_parser.c */
unsigned int index : 7; /* index into current matcher */
unsigned int lenient_http_headers : 1;
uint32_t nread; /* # bytes read in various scenarios */
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
/** READ-ONLY **/
unsigned short http_major;
unsigned short http_minor;
unsigned int status_code : 16; /* responses only */
unsigned int method : 8; /* requests only */
unsigned int http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to
* error checking.
*/
unsigned int upgrade : 1;
/** PUBLIC **/
void *data; /* A pointer to get hook to the "connection" or "socket" object */
};
struct http_parser_settings {
http_cb on_message_begin;
http_data_cb on_url;
http_data_cb on_status;
http_data_cb on_header_field;
http_data_cb on_header_value;
http_cb on_headers_complete;
http_data_cb on_body;
http_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
*/
http_cb on_chunk_header;
http_cb on_chunk_complete;
};
enum http_parser_url_fields
{ UF_SCHEMA = 0
, UF_HOST = 1
, UF_PORT = 2
, UF_PATH = 3
, UF_QUERY = 4
, UF_FRAGMENT = 5
, UF_USERINFO = 6
, UF_MAX = 7
};
/* Result structure for http_parser_parse_url().
*
* Callers should index into field_data[] with UF_* values iff field_set
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
* because we probably have padding left over), we convert any port to
* a uint16_t.
*/
struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
struct {
uint16_t off; /* Offset into buffer in which field starts */
uint16_t len; /* Length of run in buffer */
} field_data[UF_MAX];
};
/* Returns the library version. Bits 16-23 contain the major version number,
* bits 8-15 the minor version number and bits 0-7 the patch level.
* Usage example:
*
* unsigned long version = http_parser_version();
* unsigned major = (version >> 16) & 255;
* unsigned minor = (version >> 8) & 255;
* unsigned patch = version & 255;
* printf("http_parser v%u.%u.%u\n", major, minor, patch);
*/
unsigned long http_parser_version(void);
void http_parser_init(http_parser *parser, enum http_parser_type type);
/* Initialize http_parser_settings members to 0
*/
void http_parser_settings_init(http_parser_settings *settings);
/* Executes the parser. Returns number of parsed bytes. Sets
* `parser->http_errno` on error. */
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings,
const char *data,
size_t len);
/* If http_should_keep_alive() in the on_headers_complete or
* on_message_complete callback returns 0, then this should be
* the last message on the connection.
* If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection.
*/
int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
const char *http_method_str(enum http_method m);
/* Returns a string version of the HTTP status code. */
const char *http_status_str(enum http_status s);
/* Return a string name of the given error */
const char *http_errno_name(enum http_errno err);
/* Return a string description of the given error */
const char *http_errno_description(enum http_errno err);
/* Initialize all http_parser_url members to 0 */
void http_parser_url_init(struct http_parser_url *u);
/* Parse a URL; return nonzero on failure */
int http_parser_parse_url(const char *buf, size_t buflen,
int is_connect,
struct http_parser_url *u);
/* Pause or un-pause the parser; a nonzero value pauses */
void http_parser_pause(http_parser *parser, int paused);
/* Checks if this is the final chunk of the body. */
int http_body_is_final(const http_parser *parser);
/* Change the maximum header size provided at compile time. */
void http_parser_set_max_header_size(uint32_t size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -29,24 +29,18 @@
#include "api/Api.h"
#include "App.h"
#include "base/io/Console.h"
#include "base/io/log/Log.h"
#include "base/kernel/Signals.h"
#include "common/Console.h"
#include "common/log/Log.h"
#include "common/Platform.h"
#include "core/Config.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "proxy/Proxy.h"
#include "Summary.h"
#include "version.h"
#ifndef XMRIG_NO_HTTPD
# include "common/api/Httpd.h"
#endif
xmrig::App::App(Process *process) :
m_console(nullptr),
m_httpd(nullptr),
m_signals(nullptr)
{
m_controller = new Controller(process);
@@ -62,17 +56,9 @@ xmrig::App::App(Process *process) :
xmrig::App::~App()
{
uv_tty_reset_mode();
delete m_signals;
delete m_console;
delete m_controller;
# ifndef XMRIG_NO_HTTPD
delete m_httpd;
# endif
Log::release();
}
@@ -88,28 +74,12 @@ int xmrig::App::exec()
Summary::print(m_controller);
# ifndef XMRIG_NO_API
Api::start(m_controller);
# endif
m_controller->start();
# ifndef XMRIG_NO_HTTPD
m_httpd = new Httpd(
m_controller->config()->apiPort(),
m_controller->config()->apiToken(),
m_controller->config()->isApiIPv6(),
m_controller->config()->isApiRestricted()
);
m_httpd->start();
# endif
m_controller->watch();
m_controller->proxy()->connect();
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
const int rc = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());
return r;
return rc;
}
@@ -186,5 +156,9 @@ void xmrig::App::onSignal(int signum)
void xmrig::App::close()
{
uv_stop(uv_default_loop());
m_signals->stop();
m_console->stop();
m_controller->stop();
Log::destroy();
}

View File

@@ -26,18 +26,17 @@
#define XMRIG_APP_H
#include "base/kernel/interfaces/IConsoleListener.h"
#include "base/kernel/interfaces/ISignalListener.h"
#include "common/interfaces/IConsoleListener.h"
class Console;
class Httpd;
class Proxy;
namespace xmrig {
class Console;
class Controller;
class Process;
class Signals;
@@ -61,7 +60,6 @@ private:
Console *m_console;
Controller *m_controller;
Httpd *m_httpd;
Signals *m_signals;
};

View File

@@ -29,8 +29,8 @@
#include "App.h"
#include "common/log/Log.h"
#include "core/Config.h"
#include "base/io/log/Log.h"
#include "core/config/Config.h"
#include "core/Controller.h"

View File

@@ -28,7 +28,7 @@
#include "App.h"
#include "core/Config.h"
#include "core/config/Config.h"
#include "core/Controller.h"

View File

@@ -27,8 +27,8 @@
#include <uv.h>
#include "common/log/Log.h"
#include "core/Config.h"
#include "base/io/log/Log.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "proxy/BindHost.h"
#include "Summary.h"
@@ -37,17 +37,7 @@
static void print_mode(xmrig::Controller *controller)
{
Log::i()->text(controller->config()->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") MAGENTA_BOLD("%s")
: " * %-13s%s",
"MODE", controller->config()->modeName());
}
static void print_algo(xmrig::Controller *controller)
{
Log::i()->text(controller->config()->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") MAGENTA_BOLD("%s")
: " * %-13s%s",
"ALGO", controller->config()->algorithm().name());
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") MAGENTA_BOLD("%s"), "MODE", controller->config()->modeName());
}
@@ -55,41 +45,28 @@ static void print_bind(xmrig::Controller *controller)
{
const xmrig::BindHosts &bind = controller->config()->bind();
if (controller->config()->isColors()) {
for (size_t i = 0; i < bind.size(); ++i) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("BIND #%-7zu") CYAN("%s%s%s:") "\x1B[1;%dm%d\x1B[0m",
i + 1,
bind[i].isIPv6() ? "[" : "",
bind[i].host(),
bind[i].isIPv6() ? "]" : "",
bind[i].isTLS() ? 32 : 36,
bind[i].port());
}
}
else {
for (size_t i = 0; i < bind.size(); ++i) {
Log::i()->text(" * BIND #%-7zu%s%s%s:%d TLS=%d",
i + 1,
bind[i].isIPv6() ? "[" : "",
bind[i].host(),
bind[i].isIPv6() ? "]" : "",
bind[i].port(),
static_cast<int>(bind[i].isTLS()));
}
for (size_t i = 0; i < bind.size(); ++i) {
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("BIND #%-7zu") CYAN("%s%s%s:") "\x1B[1;%dm%d\x1B[0m",
i + 1,
bind[i].isIPv6() ? "[" : "",
bind[i].host(),
bind[i].isIPv6() ? "]" : "",
bind[i].isTLS() ? 32 : 36,
bind[i].port());
}
}
static void print_commands(xmrig::Controller *controller)
static void print_commands(xmrig::Controller *)
{
if (controller->config()->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
MAGENTA_BOLD("c") WHITE_BOLD("onnections, ")
MAGENTA_BOLD("v") WHITE_BOLD("erbose, ")
MAGENTA_BOLD("w") WHITE_BOLD("orkers"));
if (xmrig::Log::colors) {
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
MAGENTA_BOLD("c") WHITE_BOLD("onnections, ")
MAGENTA_BOLD("v") WHITE_BOLD("erbose, ")
MAGENTA_BOLD("w") WHITE_BOLD("orkers"));
}
else {
Log::i()->text(" * COMMANDS 'h' hashrate, 'c' connections, 'v' verbose, 'w' workers");
xmrig::Log::print(" * COMMANDS 'h' hashrate, 'c' connections, 'v' verbose, 'w' workers");
}
}
@@ -98,9 +75,7 @@ void Summary::print(xmrig::Controller *controller)
{
controller->config()->printVersions();
print_mode(controller);
print_algo(controller);
controller->config()->printPools();
controller->config()->pools().print();
print_bind(controller);
controller->config()->printAPI();
print_commands(controller);
}

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,42 +22,192 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <uv.h>
#ifndef _WIN32
# include <unistd.h>
#endif
#include "3rdparty/http-parser/http_parser.h"
#include "api/Api.h"
#include "api/ApiRouter.h"
#include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h"
#include "api/interfaces/IApiListener.h"
#include "api/requests/HttpApiRequest.h"
#include "api/v1/ApiRouter.h"
#include "base/kernel/Base.h"
#include "base/tools/Buffer.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "crypto/common/keccak.h"
#include "version.h"
ApiRouter *Api::m_router = nullptr;
#ifdef XMRIG_FEATURE_HTTP
# include "api/Httpd.h"
#endif
bool Api::start(xmrig::Controller *controller)
xmrig::Api::Api(Base *base) :
m_base(base),
m_id(),
m_workerId(),
m_timestamp(Chrono::currentMSecsSinceEpoch()),
m_httpd(nullptr)
{
m_router = new ApiRouter(controller);
base->addListener(this);
return true;
genId(base->config()->apiId());
m_v1 = new ApiRouter(base);
addListener(m_v1);
}
void Api::release()
xmrig::Api::~Api()
{
delete m_router;
delete m_v1;
# ifdef XMRIG_FEATURE_HTTP
delete m_httpd;
# endif
}
void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
void xmrig::Api::request(const HttpData &req)
{
if (!m_router) {
reply.status = 500;
HttpApiRequest request(req, m_base->config()->http().isRestricted());
exec(request);
}
void xmrig::Api::start()
{
genWorkerId(m_base->config()->apiWorkerId());
# ifdef XMRIG_FEATURE_HTTP
m_httpd = new Httpd(m_base);
m_httpd->start();
# endif
}
void xmrig::Api::stop()
{
# ifdef XMRIG_FEATURE_HTTP
m_httpd->stop();
# endif
}
void xmrig::Api::onConfigChanged(Config *config, Config *previousConfig)
{
if (config->apiId() != previousConfig->apiId()) {
genId(config->apiId());
}
if (config->apiWorkerId() != previousConfig->apiWorkerId()) {
genWorkerId(config->apiWorkerId());
}
}
void xmrig::Api::exec(IApiRequest &request)
{
using namespace rapidjson;
if (request.type() == IApiRequest::REQ_SUMMARY) {
auto &allocator = request.doc().GetAllocator();
request.accept();
request.reply().AddMember("id", StringRef(m_id), allocator);
request.reply().AddMember("worker_id", StringRef(m_workerId), allocator);
request.reply().AddMember("uptime", (Chrono::currentMSecsSinceEpoch() - m_timestamp) / 1000, allocator);
Value features(kArrayType);
# ifdef XMRIG_FEATURE_API
features.PushBack("api", allocator);
# endif
# ifdef XMRIG_FEATURE_ASM
features.PushBack("asm", allocator);
# endif
# ifdef XMRIG_FEATURE_HTTP
features.PushBack("http", allocator);
# endif
# ifdef XMRIG_FEATURE_LIBCPUID
features.PushBack("cpuid", allocator);
# endif
# ifdef XMRIG_FEATURE_HWLOC
features.PushBack("hwloc", allocator);
# endif
# ifdef XMRIG_FEATURE_TLS
features.PushBack("tls", allocator);
# endif
request.reply().AddMember("features", features, allocator);
}
for (IApiListener *listener : m_listeners) {
listener->onRequest(request);
if (request.isDone()) {
return;
}
}
request.done(request.isNew() ? HTTP_STATUS_NOT_FOUND : HTTP_STATUS_OK);
}
void xmrig::Api::genId(const String &id)
{
memset(m_id, 0, sizeof(m_id));
if (id.size() > 0) {
strncpy(m_id, id.data(), sizeof(m_id) - 1);
return;
}
if (req.method() == xmrig::HttpRequest::Get) {
return m_router->get(req, reply);
uv_interface_address_t *interfaces;
int count = 0;
if (uv_interface_addresses(&interfaces, &count) < 0) {
return;
}
m_router->exec(req, reply);
for (int i = 0; i < count; i++) {
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr);
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
const uint16_t port = static_cast<uint16_t>(m_base->config()->http().port());
uint8_t *input = new uint8_t[inSize]();
memcpy(input, &port, sizeof(uint16_t));
memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize);
memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
keccak(input, inSize, hash);
Buffer::toHex(hash, 8, m_id);
delete [] input;
break;
}
}
uv_free_interface_addresses(interfaces, count);
}
void xmrig::Api::genWorkerId(const String &id)
{
memset(m_workerId, 0, sizeof(m_workerId));
if (id.size() > 0) {
strncpy(m_workerId, id.data(), sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
}
}

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,30 +22,62 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __API_H__
#define __API_H__
#ifndef XMRIG_API_H
#define XMRIG_API_H
class ApiRouter;
#include <vector>
#include <stdint.h>
#include "base/kernel/interfaces/IBaseListener.h"
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
}
class Api
class ApiRouter;
class Base;
class Httpd;
class HttpData;
class IApiListener;
class IApiRequest;
class String;
class Api : public IBaseListener
{
public:
static bool start(xmrig::Controller *controller);
static void release();
Api(Base *base);
~Api() override;
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
inline const char *id() const { return m_id; }
inline const char *workerId() const { return m_workerId; }
inline void addListener(IApiListener *listener) { m_listeners.push_back(listener); }
void request(const HttpData &req);
void start();
void stop();
protected:
void onConfigChanged(Config *config, Config *previousConfig) override;
private:
static ApiRouter *m_router;
void exec(IApiRequest &request);
void genId(const String &id);
void genWorkerId(const String &id);
ApiRouter *m_v1;
Base *m_base;
char m_id[32];
char m_workerId[128];
const uint64_t m_timestamp;
Httpd *m_httpd;
std::vector<IApiListener *> m_listeners;
};
#endif /* __API_H__ */
} // namespace xmrig
#endif /* XMRIG_API_H */

View File

@@ -1,439 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cmath>
#include <string.h>
#include <uv.h>
#include <thread>
#if _WIN32
# include "winsock2.h"
#else
# include "unistd.h"
#endif
#include "api/ApiRouter.h"
#include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h"
#include "common/crypto/keccak.h"
#include "common/net/Job.h"
#include "common/Platform.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "proxy/Miner.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "version.h"
static inline double normalize(double d)
{
if (!std::isnormal(d)) {
return 0.0;
}
return std::floor(d * 100.0) / 100.0;
}
ApiRouter::ApiRouter(xmrig::Controller *controller) :
m_controller(controller)
{
setWorkerId(controller->config()->apiWorkerId());
genId(controller->config()->apiId());
controller->addListener(this);
}
ApiRouter::~ApiRouter()
{
}
void ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
{
rapidjson::Document doc;
doc.SetObject();
if (req.match("/1/workers") || req.match("/workers.json")) {
getHashrate(doc);
getWorkers(doc);
return finalize(reply, doc);
}
if (req.match("/1/miners")) {
getMiners(doc);
return finalize(reply, doc);
}
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(reply, doc);
}
getIdentify(doc);
getMiner(doc);
getHashrate(doc);
getResourcesSummary(doc);
getMinersSummary(doc, req.match("/1/summary"));
getResults(doc);
return finalize(reply, doc);
}
void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
{
if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) {
m_controller->config()->reload(req.body());
return;
}
reply.status = 404;
}
void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId());
}
void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const
{
rapidjson::StringBuffer buffer(nullptr, 4096);
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
writer.SetMaxDecimalPlaces(10);
doc.Accept(writer);
reply.status = 200;
reply.buf = strdup(buffer.GetString());
reply.size = buffer.GetSize();
}
void ApiRouter::genId(const char *id)
{
memset(m_id, 0, sizeof(m_id));
if (id && strlen(id) > 0) {
strncpy(m_id, id, sizeof(m_id) - 1);
return;
}
uv_interface_address_t *interfaces;
int count = 0;
if (uv_interface_addresses(&interfaces, &count) < 0) {
return;
}
for (int i = 0; i < count; i++) {
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr);
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
const uint16_t port = static_cast<uint16_t>(m_controller->config()->apiPort());
uint8_t *input = new uint8_t[inSize]();
memcpy(input, &port, sizeof(uint16_t));
memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize);
memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
xmrig::keccak(input, inSize, hash);
xmrig::Job::toHex(hash, 8, m_id);
delete [] input;
break;
}
}
uv_free_interface_addresses(interfaces, count);
}
void ApiRouter::getHashrate(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
rapidjson::Value hashrate(rapidjson::kObjectType);
rapidjson::Value total(rapidjson::kArrayType);
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);
doc.AddMember("hashrate", hashrate, allocator);
}
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 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("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator);
doc.AddMember("mode", rapidjson::StringRef(m_controller->config()->modeName()), allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
doc.AddMember("uptime", stats.uptime(), allocator);
doc.AddMember("donate_level", m_controller->config()->donateLevel(), 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);
}
}
void ApiRouter::getMiners(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
auto list = m_controller->miners();
Value miners(kArrayType);
for (const xmrig::Miner *miner : list) {
if (miner->mapperId() == -1) {
continue;
}
Value value(kArrayType);
value.PushBack(miner->id(), allocator);
value.PushBack(StringRef(miner->ip()), allocator);
value.PushBack(miner->tx(), allocator);
value.PushBack(miner->rx(), allocator);
value.PushBack(miner->state(), allocator);
value.PushBack(miner->diff(), allocator);
value.PushBack(miner->user().toJSON(), allocator);
value.PushBack(miner->password().toJSON(), allocator);
value.PushBack(miner->rigId().toJSON(), allocator);
value.PushBack(miner->agent().toJSON(), allocator);
miners.PushBack(value, allocator);
}
Value format(kArrayType);
format.PushBack("id", allocator);
format.PushBack("ip", allocator);
format.PushBack("tx", allocator);
format.PushBack("rx", allocator);
format.PushBack("state", allocator);
format.PushBack("diff", allocator);
format.PushBack("user", allocator);
format.PushBack("password", allocator);
format.PushBack("rig_id", allocator);
format.PushBack("agent", allocator);
doc.AddMember("format", format, allocator);
doc.AddMember("miners", miners, allocator);
}
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", stats.miners, allocator);
miners.AddMember("max", stats.maxMiners, allocator);
doc.AddMember("miners", miners, allocator);
doc.AddMember("workers", static_cast<uint64_t>(m_controller->workers().size()), 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 ApiRouter::getResourcesSummary(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
size_t rss = 0;
uv_resident_set_memory(&rss);
Value resources(kObjectType);
Value memory(kObjectType);
Value load_average(kArrayType);
memory.AddMember("total", uv_get_total_memory(), allocator);
memory.AddMember("resident_set_memory", static_cast<uint64_t>(rss), allocator);
double loadavg[3] = { 1.0 };
uv_loadavg(loadavg);
load_average.PushBack(loadavg[0], allocator);
load_average.PushBack(loadavg[1], allocator);
load_average.PushBack(loadavg[2], allocator);
resources.AddMember("memory", memory, allocator);
resources.AddMember("load_average", load_average, allocator);
resources.AddMember("hardware_concurrency", std::thread::hardware_concurrency(), allocator);
doc.AddMember("resources", resources, allocator);
}
void ApiRouter::getResources(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
size_t rss = 0;
uv_resident_set_memory(&rss);
doc.AddMember("total_memory", uv_get_total_memory(), allocator);
doc.AddMember("resident_set_memory", static_cast<uint64_t>(rss), allocator);
}
void ApiRouter::getResults(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
auto &stats = m_controller->statsData();
rapidjson::Value results(rapidjson::kObjectType);
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 < stats.topDiff.size(); ++i) {
best.PushBack(stats.topDiff[i], allocator);
}
results.AddMember("best", best, allocator);
doc.AddMember("results", results, allocator);
}
void ApiRouter::getWorkers(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
auto &list = m_controller->workers();
Value workers(kArrayType);
for (const xmrig::Worker &worker : list) {
Value array(kArrayType);
array.PushBack(StringRef(worker.name()), allocator);
array.PushBack(StringRef(worker.ip()), allocator);
array.PushBack(worker.connections(), allocator);
array.PushBack(worker.accepted(), allocator);
array.PushBack(worker.rejected(), allocator);
array.PushBack(worker.invalid(), allocator);
array.PushBack(worker.hashes(), allocator);
array.PushBack(worker.lastHash(), allocator);
array.PushBack(normalize(worker.hashrate(60)), allocator);
array.PushBack(normalize(worker.hashrate(600)), allocator);
array.PushBack(normalize(worker.hashrate(3600)), allocator);
array.PushBack(normalize(worker.hashrate(3600 * 12)), allocator);
array.PushBack(normalize(worker.hashrate(3600 * 24)), allocator);
workers.PushBack(array, allocator);
}
doc.AddMember("mode", StringRef(xmrig::Workers::modeName(m_controller->config()->workersMode())), allocator);
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

@@ -1,75 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_APIROUTER_H
#define XMRIG_APIROUTER_H
#include "common/interfaces/IControllerListener.h"
#include "proxy/StatsData.h"
#include "rapidjson/fwd.h"
class Hashrate;
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
}
class ApiRouter : public xmrig::IControllerListener
{
public:
ApiRouter(xmrig::Controller *controller);
~ApiRouter();
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:
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
void genId(const char *id);
void getHashrate(rapidjson::Document &doc) const;
void getIdentify(rapidjson::Document &doc) const;
void getMiner(rapidjson::Document &doc) const;
void getMiners(rapidjson::Document &doc) const;
void getMinersSummary(rapidjson::Document &doc, bool advanced) const;
void getResourcesSummary(rapidjson::Document &doc) 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[32];
char m_workerId[128];
xmrig::Controller *m_controller;
};
#endif /* XMRIG_APIROUTER_H */

193
src/api/Httpd.cpp Normal file
View File

@@ -0,0 +1,193 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "3rdparty/http-parser/http_parser.h"
#include "api/Api.h"
#include "api/Httpd.h"
#include "base/io/log/Log.h"
#include "base/net/http/HttpApiResponse.h"
#include "base/net/http/HttpData.h"
#include "base/net/http/HttpServer.h"
#include "base/net/tools/TcpServer.h"
#include "core/config/Config.h"
#include "core/Controller.h"
namespace xmrig {
static const char *kAuthorization = "authorization";
static const char *kContentType = "content-type";
#ifdef _WIN32
static const char *favicon = nullptr;
static size_t faviconSize = 0;
#endif
} // namespace xmrig
xmrig::Httpd::Httpd(Base *base) :
m_base(base),
m_http(nullptr),
m_server(nullptr),
m_port(0)
{
base->addListener(this);
}
xmrig::Httpd::~Httpd()
{
}
bool xmrig::Httpd::start()
{
const Http &config = m_base->config()->http();
if (!config.isEnabled()) {
return true;
}
m_http = new HttpServer(this);
m_server = new TcpServer(config.host(), config.port(), m_http);
const int rc = m_server->bind();
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") BLUE_BOLD("%s:%d") " " RED_BOLD("%s"),
"HTTP API",
config.host().data(),
rc < 0 ? config.port() : rc,
rc < 0 ? uv_strerror(rc) : ""
);
if (rc < 0) {
stop();
return false;
}
m_port = static_cast<uint16_t>(rc);
# ifdef _WIN32
HRSRC src = FindResource(nullptr, MAKEINTRESOURCE(1), RT_ICON);
if (src != nullptr) {
HGLOBAL res = LoadResource(nullptr, src);
if (res != nullptr) {
favicon = static_cast<const char *>(LockResource(res));
faviconSize = SizeofResource(nullptr, src);
}
}
# endif
return true;
}
void xmrig::Httpd::stop()
{
delete m_server;
delete m_http;
m_server = nullptr;
m_http = nullptr;
m_port = 0;
}
void xmrig::Httpd::onConfigChanged(Config *config, Config *previousConfig)
{
if (config->http() == previousConfig->http()) {
return;
}
stop();
start();
}
void xmrig::Httpd::onHttpData(const HttpData &data)
{
if (data.method == HTTP_OPTIONS) {
return HttpApiResponse(data.id()).end();
}
if (data.method == HTTP_GET && data.url == "/favicon.ico") {
# ifdef _WIN32
if (favicon != nullptr) {
HttpResponse response(data.id());
response.setHeader("Content-Type", "image/x-icon");
return response.end(favicon, faviconSize);
}
# endif
return HttpResponse(data.id(), 404).end();
}
if (data.method > 4) {
return HttpApiResponse(data.id(), HTTP_STATUS_METHOD_NOT_ALLOWED).end();
}
const int status = auth(data);
if (status != HTTP_STATUS_OK) {
return HttpApiResponse(data.id(), status).end();
}
if (data.method != HTTP_GET) {
if (m_base->config()->http().isRestricted()) {
return HttpApiResponse(data.id(), HTTP_STATUS_FORBIDDEN).end();
}
if (!data.headers.count(kContentType) || data.headers.at(kContentType) != "application/json") {
return HttpApiResponse(data.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end();
}
}
m_base->api()->request(data);
}
int xmrig::Httpd::auth(const HttpData &req) const
{
const Http &config = m_base->config()->http();
if (!req.headers.count(kAuthorization)) {
return config.isAuthRequired() ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_OK;
}
if (config.token().isNull()) {
return HTTP_STATUS_UNAUTHORIZED;
}
const std::string &token = req.headers.at(kAuthorization);
const size_t size = token.size();
if (token.size() < 8 || config.token().size() != size - 7 || memcmp("Bearer ", token.c_str(), 7) != 0) {
return HTTP_STATUS_FORBIDDEN;
}
return strncmp(config.token().data(), token.c_str() + 7, config.token().size()) == 0 ? HTTP_STATUS_OK : HTTP_STATUS_FORBIDDEN;
}

70
src/api/Httpd.h Normal file
View File

@@ -0,0 +1,70 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPD_H
#define XMRIG_HTTPD_H
#include <stdint.h>
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/kernel/interfaces/IHttpListener.h"
namespace xmrig {
class Base;
class HttpServer;
class TcpServer;
class Httpd : public IBaseListener, public IHttpListener
{
public:
Httpd(Base *base);
~Httpd() override;
bool start();
void stop();
protected:
void onConfigChanged(Config *config, Config *previousConfig) override;
void onHttpData(const HttpData &data) override;
private:
int auth(const HttpData &req) const;
Base *m_base;
HttpServer *m_http;
TcpServer *m_server;
uint16_t m_port;
};
} /* namespace xmrig */
#endif /* XMRIG_HTTPD_H */

View File

@@ -20,31 +20,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIGCREATOR_H__
#define __CONFIGCREATOR_H__
#include "common/interfaces/IConfigCreator.h"
#include "core/Config.h"
#ifndef XMRIG_IAPILISTENER_H
#define XMRIG_IAPILISTENER_H
namespace xmrig {
class IConfig;
class IApiRequest;
class ConfigCreator : public IConfigCreator
class IApiListener
{
public:
inline IConfig *create() const override
{
return new Config();
}
virtual ~IApiListener() = default;
# ifdef XMRIG_FEATURE_API
virtual void onRequest(IApiRequest &request) = 0;
# endif
};
} /* namespace xmrig */
#endif // __CONFIGCREATOR_H__
#endif // XMRIG_IAPILISTENER_H

View File

@@ -0,0 +1,82 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IAPIREQUEST_H
#define XMRIG_IAPIREQUEST_H
#include "rapidjson/fwd.h"
namespace xmrig {
class String;
class IApiRequest
{
public:
enum Method {
METHOD_DELETE,
METHOD_GET,
METHOD_HEAD,
METHOD_POST,
METHOD_PUT
};
enum Source {
SOURCE_HTTP
};
enum RequestType {
REQ_UNKNOWN,
REQ_SUMMARY
};
virtual ~IApiRequest() = default;
virtual bool isDone() const = 0;
virtual bool isNew() const = 0;
virtual bool isRestricted() const = 0;
virtual const rapidjson::Value &json() const = 0;
virtual const String &url() const = 0;
virtual int version() const = 0;
virtual Method method() const = 0;
virtual rapidjson::Document &doc() = 0;
virtual rapidjson::Value &reply() = 0;
virtual RequestType type() const = 0;
virtual Source source() const = 0;
virtual void accept() = 0;
virtual void done(int status) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_IAPIREQUEST_H

View File

@@ -23,24 +23,16 @@
*/
#include <uv.h>
#include "api/requests/ApiRequest.h"
#include "common/net/SubmitResult.h"
xmrig::SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId) :
reqId(reqId),
seq(seq),
diff(diff),
actualDiff(actualDiff),
elapsed(0)
xmrig::ApiRequest::ApiRequest(Source source, bool restricted) :
m_restricted(restricted),
m_source(source)
{
start = uv_hrtime();
}
void xmrig::SubmitResult::done()
xmrig::ApiRequest::~ApiRequest()
{
elapsed = (uv_hrtime() - start) / 1000000;
}

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 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_APIREQUEST_H
#define XMRIG_APIREQUEST_H
#include "api/interfaces/IApiRequest.h"
namespace xmrig {
class ApiRequest : public IApiRequest
{
public:
ApiRequest(Source source, bool restricted);
~ApiRequest() override;
protected:
inline bool isDone() const override { return m_state == STATE_DONE; }
inline bool isNew() const override { return m_state == STATE_NEW; }
inline bool isRestricted() const override { return m_restricted; }
inline int version() const override { return m_version; }
inline RequestType type() const override { return m_type; }
inline Source source() const override { return m_source; }
inline void accept() override { m_state = STATE_ACCEPTED; }
inline void done(int) override { m_state = STATE_DONE; }
int m_version = 1;
RequestType m_type = REQ_UNKNOWN;
private:
enum State {
STATE_NEW,
STATE_ACCEPTED,
STATE_DONE
};
bool m_restricted;
Source m_source;
State m_state = STATE_NEW;
};
} // namespace xmrig
#endif // XMRIG_APIREQUEST_H

View File

@@ -0,0 +1,87 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "api/requests/HttpApiRequest.h"
#include "base/net/http/HttpData.h"
#include "rapidjson/error/en.h"
xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) :
ApiRequest(SOURCE_HTTP, restricted),
m_parsed(false),
m_req(req),
m_res(req.id()),
m_url(req.url.c_str())
{
if (method() == METHOD_GET) {
if (url() == "/1/summary" || url() == "/2/summary" || url() == "/api.json") {
m_type = REQ_SUMMARY;
}
}
if (url().size() > 4) {
if (memcmp(url().data(), "/2/", 3) == 0) {
m_version = 2;
}
}
}
const rapidjson::Value &xmrig::HttpApiRequest::json() const
{
return m_body;
}
xmrig::IApiRequest::Method xmrig::HttpApiRequest::method() const
{
return static_cast<IApiRequest::Method>(m_req.method);
}
void xmrig::HttpApiRequest::accept()
{
using namespace rapidjson;
ApiRequest::accept();
if (!m_parsed && !m_req.body.empty()) {
m_parsed = true;
m_body.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(m_req.body.c_str());
if (m_body.HasParseError()) {
reply().AddMember("error", StringRef(GetParseError_En(m_body.GetParseError())), doc().GetAllocator());;
}
}
}
void xmrig::HttpApiRequest::done(int status)
{
ApiRequest::done(status);
m_res.setStatus(status);
m_res.end();
}

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 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPAPIREQUEST_H
#define XMRIG_HTTPAPIREQUEST_H
#include "api/requests/ApiRequest.h"
#include "base/net/http/HttpApiResponse.h"
#include "base/tools/String.h"
namespace xmrig {
class HttpData;
class HttpApiRequest : public ApiRequest
{
public:
HttpApiRequest(const HttpData &req, bool restricted);
protected:
inline rapidjson::Document &doc() override { return m_res.doc(); }
inline rapidjson::Value &reply() override { return m_res.doc(); }
inline const String &url() const override { return m_url; }
const rapidjson::Value &json() const override;
Method method() const override;
void accept() override;
void done(int status) override;
private:
bool m_parsed;
const HttpData &m_req;
HttpApiResponse m_res;
rapidjson::Document m_body;
String m_url;
};
} // namespace xmrig
#endif // XMRIG_HTTPAPIREQUEST_H

286
src/api/v1/ApiRouter.cpp Normal file
View File

@@ -0,0 +1,286 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cmath>
#include <string.h>
#include <uv.h>
#include <thread>
#include "api/interfaces/IApiRequest.h"
#include "api/v1/ApiRouter.h"
#include "base/kernel/Platform.h"
#include "base/tools/Buffer.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "proxy/Miner.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "version.h"
static inline double normalize(double d)
{
if (!std::isnormal(d)) {
return 0.0;
}
return std::floor(d * 100.0) / 100.0;
}
xmrig::ApiRouter::ApiRouter(Base *base) :
m_base(base)
{
}
xmrig::ApiRouter::~ApiRouter()
{
}
void xmrig::ApiRouter::onRequest(IApiRequest &request)
{
if (request.method() == IApiRequest::METHOD_GET) {
if (request.type() == IApiRequest::REQ_SUMMARY) {
request.accept();
getMiner(request.reply(), request.doc());
getHashrate(request.reply(), request.doc());
getResourcesSummary(request.reply(), request.doc());
getMinersSummary(request.reply(), request.doc());
getResults(request.reply(), request.doc());
}
else if (request.url() == "/1/workers") {
request.accept();
getHashrate(request.reply(), request.doc());
getWorkers(request.reply(), request.doc());
}
else if (request.url() == "/1/miners") {
request.accept();
getMiners(request.reply(), request.doc());
}
}
}
void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
rapidjson::Value hashrate(rapidjson::kObjectType);
rapidjson::Value total(rapidjson::kArrayType);
auto &stats = static_cast<Controller *>(m_base)->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);
reply.AddMember("hashrate", hashrate, allocator);
}
void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
auto &stats = static_cast<Controller *>(m_base)->statsData();
reply.AddMember("version", APP_VERSION, allocator);
reply.AddMember("kind", APP_KIND, allocator);
reply.AddMember("algo", "invalid", allocator);
reply.AddMember("mode", rapidjson::StringRef(m_base->config()->modeName()), allocator);
reply.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator);
if (stats.hashes && stats.donateHashes) {
reply.AddMember("donated", normalize((double) stats.donateHashes / stats.hashes * 100.0), allocator);
}
else {
reply.AddMember("donated", 0.0, allocator);
}
}
void xmrig::ApiRouter::getMiners(rapidjson::Value &reply, rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
auto list = static_cast<Controller *>(m_base)->miners();
Value miners(kArrayType);
for (const xmrig::Miner *miner : list) {
if (miner->mapperId() == -1) {
continue;
}
Value value(kArrayType);
value.PushBack(miner->id(), allocator);
value.PushBack(StringRef(miner->ip()), allocator);
value.PushBack(miner->tx(), allocator);
value.PushBack(miner->rx(), allocator);
value.PushBack(miner->state(), allocator);
value.PushBack(miner->diff(), allocator);
value.PushBack(miner->user().toJSON(), allocator);
value.PushBack(miner->password().toJSON(), allocator);
value.PushBack(miner->rigId().toJSON(), allocator);
value.PushBack(miner->agent().toJSON(), allocator);
miners.PushBack(value, allocator);
}
Value format(kArrayType);
format.PushBack("id", allocator);
format.PushBack("ip", allocator);
format.PushBack("tx", allocator);
format.PushBack("rx", allocator);
format.PushBack("state", allocator);
format.PushBack("diff", allocator);
format.PushBack("user", allocator);
format.PushBack("password", allocator);
format.PushBack("rig_id", allocator);
format.PushBack("agent", allocator);
reply.AddMember("format", format, allocator);
reply.AddMember("miners", miners, allocator);
}
void xmrig::ApiRouter::getMinersSummary(rapidjson::Value &reply, rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
auto &stats = static_cast<Controller *>(m_base)->statsData();
rapidjson::Value miners(rapidjson::kObjectType);
miners.AddMember("now", stats.miners, allocator);
miners.AddMember("max", stats.maxMiners, allocator);
reply.AddMember("miners", miners, allocator);
reply.AddMember("workers", static_cast<uint64_t>(static_cast<Controller *>(m_base)->workers().size()), allocator);
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);
reply.AddMember("upstreams", upstreams, allocator);
}
void xmrig::ApiRouter::getResourcesSummary(rapidjson::Value &reply, rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
size_t rss = 0;
uv_resident_set_memory(&rss);
Value resources(kObjectType);
Value memory(kObjectType);
Value load_average(kArrayType);
memory.AddMember("total", uv_get_total_memory(), allocator);
memory.AddMember("resident_set_memory", static_cast<uint64_t>(rss), allocator);
double loadavg[3] = { 1.0 };
uv_loadavg(loadavg);
load_average.PushBack(loadavg[0], allocator);
load_average.PushBack(loadavg[1], allocator);
load_average.PushBack(loadavg[2], allocator);
resources.AddMember("memory", memory, allocator);
resources.AddMember("load_average", load_average, allocator);
resources.AddMember("hardware_concurrency", std::thread::hardware_concurrency(), allocator);
reply.AddMember("resources", resources, allocator);
}
void xmrig::ApiRouter::getResults(rapidjson::Value &reply, rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
auto &stats = static_cast<Controller *>(m_base)->statsData();
rapidjson::Value results(rapidjson::kObjectType);
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 < stats.topDiff.size(); ++i) {
best.PushBack(stats.topDiff[i], allocator);
}
results.AddMember("best", best, allocator);
reply.AddMember("results", results, allocator);
}
void xmrig::ApiRouter::getWorkers(rapidjson::Value &reply, rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
auto &list = static_cast<Controller *>(m_base)->workers();
Value workers(kArrayType);
for (const Worker &worker : list) {
Value array(kArrayType);
array.PushBack(StringRef(worker.name()), allocator);
array.PushBack(StringRef(worker.ip()), allocator);
array.PushBack(worker.connections(), allocator);
array.PushBack(worker.accepted(), allocator);
array.PushBack(worker.rejected(), allocator);
array.PushBack(worker.invalid(), allocator);
array.PushBack(worker.hashes(), allocator);
array.PushBack(worker.lastHash(), allocator);
array.PushBack(normalize(worker.hashrate(60)), allocator);
array.PushBack(normalize(worker.hashrate(600)), allocator);
array.PushBack(normalize(worker.hashrate(3600)), allocator);
array.PushBack(normalize(worker.hashrate(3600 * 12)), allocator);
array.PushBack(normalize(worker.hashrate(3600 * 24)), allocator);
workers.PushBack(array, allocator);
}
reply.AddMember("mode", StringRef(Workers::modeName(static_cast<Controller *>(m_base)->config()->workersMode())), allocator);
reply.AddMember("workers", workers, allocator);
}

View File

@@ -22,51 +22,45 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CONFIGLOADER_H
#define XMRIG_CONFIGLOADER_H
#include <stdint.h>
#ifndef XMRIG_APIROUTER_H
#define XMRIG_APIROUTER_H
#include "api/interfaces/IApiListener.h"
#include "proxy/StatsData.h"
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class ConfigWatcher;
class IConfigCreator;
class IConfigListener;
class IConfig;
class Process;
class Base;
class ConfigLoader
class ApiRouter : public xmrig::IApiListener
{
public:
static bool loadFromFile(IConfig *config, const char *fileName);
static bool loadFromJSON(IConfig *config, const char *json);
static bool loadFromJSON(IConfig *config, const rapidjson::Document &doc);
static bool reload(IConfig *oldConfig, const char *json);
static bool watch(IConfig *config);
static IConfig *load(Process *process, IConfigCreator *creator, IConfigListener *listener);
static void release();
ApiRouter(Base *base);
~ApiRouter() override;
protected:
void onRequest(IApiRequest &request) override;
private:
static bool getJSON(const char *fileName, rapidjson::Document &doc);
static bool parseArg(IConfig *config, int key, const char *arg);
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getIdentify(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getMiners(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getMinersSummary(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getResourcesSummary(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getResults(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getWorkers(rapidjson::Value &reply, rapidjson::Document &doc) const;
static ConfigWatcher *m_watcher;
static IConfigCreator *m_creator;
static IConfigListener *m_listener;
Base *m_base;
};
} /* namespace xmrig */
} // namespace xmrig
#endif /* XMRIG_CONFIGLOADER_H */
#endif /* XMRIG_APIROUTER_H */

148
src/base/base.cmake Normal file
View File

@@ -0,0 +1,148 @@
set(HEADERS_BASE
src/base/io/Console.h
src/base/io/json/Json.h
src/base/io/json/JsonChain.h
src/base/io/json/JsonRequest.h
src/base/io/log/backends/ConsoleLog.h
src/base/io/log/backends/FileLog.h
src/base/io/log/Log.h
src/base/io/Watcher.h
src/base/kernel/Base.h
src/base/kernel/config/BaseConfig.h
src/base/kernel/config/BaseTransform.h
src/base/kernel/Entry.h
src/base/kernel/interfaces/IBaseListener.h
src/base/kernel/interfaces/IClient.h
src/base/kernel/interfaces/IClientListener.h
src/base/kernel/interfaces/IConfig.h
src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/IConfigTransform.h
src/base/kernel/interfaces/IConsoleListener.h
src/base/kernel/interfaces/IDnsListener.h
src/base/kernel/interfaces/ILineListener.h
src/base/kernel/interfaces/ILogBackend.h
src/base/kernel/interfaces/ISignalListener.h
src/base/kernel/interfaces/IStrategy.h
src/base/kernel/interfaces/IStrategyListener.h
src/base/kernel/interfaces/ITimerListener.h
src/base/kernel/interfaces/IWatcherListener.h
src/base/kernel/Platform.h
src/base/kernel/Process.h
src/base/kernel/Signals.h
src/base/net/dns/Dns.h
src/base/net/dns/DnsRecord.h
src/base/net/http/Http.h
src/base/net/stratum/BaseClient.h
src/base/net/stratum/Client.h
src/base/net/stratum/Job.h
src/base/net/stratum/Pool.h
src/base/net/stratum/Pools.h
src/base/net/stratum/strategies/FailoverStrategy.h
src/base/net/stratum/strategies/SinglePoolStrategy.h
src/base/net/stratum/SubmitResult.h
src/base/net/tools/RecvBuf.h
src/base/net/tools/Storage.h
src/base/tools/Arguments.h
src/base/tools/Baton.h
src/base/tools/Buffer.h
src/base/tools/Chrono.h
src/base/tools/Handle.h
src/base/tools/String.h
src/base/tools/Timer.h
)
set(SOURCES_BASE
src/base/io/Console.cpp
src/base/io/json/Json.cpp
src/base/io/json/JsonChain.cpp
src/base/io/json/JsonRequest.cpp
src/base/io/log/backends/ConsoleLog.cpp
src/base/io/log/backends/FileLog.cpp
src/base/io/log/Log.cpp
src/base/io/Watcher.cpp
src/base/kernel/Base.cpp
src/base/kernel/config/BaseConfig.cpp
src/base/kernel/config/BaseTransform.cpp
src/base/kernel/Entry.cpp
src/base/kernel/Platform.cpp
src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp
src/base/net/dns/Dns.cpp
src/base/net/dns/DnsRecord.cpp
src/base/net/http/Http.cpp
src/base/net/stratum/BaseClient.cpp
src/base/net/stratum/Client.cpp
src/base/net/stratum/Job.cpp
src/base/net/stratum/Pool.cpp
src/base/net/stratum/Pools.cpp
src/base/net/stratum/strategies/FailoverStrategy.cpp
src/base/net/stratum/strategies/SinglePoolStrategy.cpp
src/base/tools/Arguments.cpp
src/base/tools/Buffer.cpp
src/base/tools/String.cpp
src/base/tools/Timer.cpp
)
if (WIN32)
set(SOURCES_OS
src/base/io/json/Json_win.cpp
src/base/kernel/Platform_win.cpp
)
elseif (APPLE)
set(SOURCES_OS
src/base/io/json/Json_unix.cpp
src/base/kernel/Platform_mac.cpp
)
else()
set(SOURCES_OS
src/base/io/json/Json_unix.cpp
src/base/kernel//Platform_unix.cpp
)
endif()
if (NOT WIN32)
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_SYSLOG_H)
set(SOURCES_SYSLOG src/base/io/log/backends/SysLog.h src/base/io/log/backends/SysLog.cpp)
endif()
endif()
if (WITH_HTTP)
set(HEADERS_BASE_HTTP
src/3rdparty/http-parser/http_parser.h
src/base/kernel/interfaces/IHttpListener.h
src/base/kernel/interfaces/IJsonReader.h
src/base/kernel/interfaces/ITcpServerListener.h
src/base/net/http/HttpApiResponse.h
src/base/net/http/HttpClient.h
src/base/net/http/HttpContext.h
src/base/net/http/HttpData.h
src/base/net/http/HttpResponse.h
src/base/net/http/HttpServer.h
src/base/net/stratum/DaemonClient.h
src/base/net/tools/TcpServer.h
)
set(SOURCES_BASE_HTTP
src/3rdparty/http-parser/http_parser.c
src/base/net/http/HttpApiResponse.cpp
src/base/net/http/HttpClient.cpp
src/base/net/http/HttpContext.cpp
src/base/net/http/HttpResponse.cpp
src/base/net/http/HttpServer.cpp
src/base/net/stratum/DaemonClient.cpp
src/base/net/tools/TcpServer.cpp
)
add_definitions(/DXMRIG_FEATURE_HTTP)
add_definitions(/DXMRIG_FEATURE_API)
else()
set(HEADERS_BASE_HTTP "")
set(SOURCES_BASE_HTTP "")
remove_definitions(/DXMRIG_FEATURE_HTTP)
remove_definitions(/DXMRIG_FEATURE_API)
endif()

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,26 +23,44 @@
*/
#include "common/Console.h"
#include "interfaces/IConsoleListener.h"
#include "base/io/Console.h"
#include "base/kernel/interfaces/IConsoleListener.h"
#include "base/tools/Handle.h"
Console::Console(IConsoleListener *listener)
xmrig::Console::Console(IConsoleListener *listener)
: m_listener(listener)
{
m_tty.data = this;
uv_tty_init(uv_default_loop(), &m_tty, 0, 1);
m_tty = new uv_tty_t;
if (!uv_is_readable(reinterpret_cast<uv_stream_t*>(&m_tty))) {
m_tty->data = this;
uv_tty_init(uv_default_loop(), m_tty, 0, 1);
if (!uv_is_readable(reinterpret_cast<uv_stream_t*>(m_tty))) {
return;
}
uv_tty_set_mode(&m_tty, UV_TTY_MODE_RAW);
uv_read_start(reinterpret_cast<uv_stream_t*>(&m_tty), Console::onAllocBuffer, Console::onRead);
uv_tty_set_mode(m_tty, UV_TTY_MODE_RAW);
uv_read_start(reinterpret_cast<uv_stream_t*>(m_tty), Console::onAllocBuffer, Console::onRead);
}
void Console::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
xmrig::Console::~Console()
{
stop();
}
void xmrig::Console::stop()
{
uv_tty_reset_mode();
Handle::close(m_tty);
m_tty = nullptr;
}
void xmrig::Console::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
{
auto console = static_cast<Console*>(handle->data);
buf->len = 1;
@@ -49,7 +68,7 @@ void Console::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
}
void Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
void xmrig::Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
if (nread < 0) {
return uv_close(reinterpret_cast<uv_handle_t*>(stream), nullptr);

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,13 +22,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONSOLE_H__
#define __CONSOLE_H__
#ifndef XMRIG_CONSOLE_H
#define XMRIG_CONSOLE_H
#include <uv.h>
namespace xmrig {
class IConsoleListener;
@@ -35,6 +40,9 @@ class Console
{
public:
Console(IConsoleListener *listener);
~Console();
void stop();
private:
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
@@ -42,8 +50,11 @@ private:
char m_buf[1];
IConsoleListener *m_listener;
uv_tty_t m_tty;
uv_tty_t *m_tty;
};
#endif /* __CONSOLE_H__ */
} /* namespace xmrig */
#endif /* XMRIG_CONSOLE_H */

View File

@@ -29,37 +29,31 @@
#include "base/kernel/interfaces/IWatcherListener.h"
#include "base/io/Watcher.h"
#include "base/tools/Handle.h"
#include "base/tools/Timer.h"
xmrig::Watcher::Watcher(const String &path, IWatcherListener *listener) :
m_listener(listener),
m_path(path)
{
m_timer = new Timer(this);
m_fsEvent = new uv_fs_event_t;
m_fsEvent->data = this;
uv_fs_event_init(uv_default_loop(), m_fsEvent);
m_timer = new uv_timer_t;
uv_timer_init(uv_default_loop(), m_timer);
m_fsEvent->data = m_timer->data = this;
start();
}
xmrig::Watcher::~Watcher()
{
Handle::close(m_timer);
delete m_timer;
Handle::close(m_fsEvent);
}
void xmrig::Watcher::onTimer(uv_timer_t *handle)
{
static_cast<Watcher *>(handle->data)->reload();
}
void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int, int)
{
if (!filename) {
@@ -72,8 +66,8 @@ void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int,
void xmrig::Watcher::queueUpdate()
{
uv_timer_stop(m_timer);
uv_timer_start(m_timer, xmrig::Watcher::onTimer, kDelay, 0);
m_timer->stop();
m_timer->start(kDelay, 0);
}

View File

@@ -26,30 +26,33 @@
#define XMRIG_WATCHER_H
#include "base/kernel/interfaces/ITimerListener.h"
#include "base/tools/String.h"
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_timer_s uv_timer_t;
namespace xmrig {
class IWatcherListener;
class Timer;
class Watcher
class Watcher : public ITimerListener
{
public:
Watcher(const String &path, IWatcherListener *listener);
~Watcher();
~Watcher() override;
protected:
inline void onTimer(const Timer *) override { reload(); }
private:
constexpr static int kDelay = 500;
static void onFsEvent(uv_fs_event_t *handle, const char *filename, int events, int status);
static void onTimer(uv_timer_t *handle);
void queueUpdate();
void reload();
@@ -57,11 +60,12 @@ private:
IWatcherListener *m_listener;
String m_path;
Timer *m_timer;
uv_fs_event_t *m_fsEvent;
uv_timer_t *m_timer;
};
} /* namespace xmrig */
#endif /* XMRIG_WATCHER_H */

View File

@@ -23,10 +23,17 @@
*/
#include "base/io/Json.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
namespace xmrig {
static const rapidjson::Value kNullValue;
}
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
{
auto i = obj.FindMember(key);
@@ -49,6 +56,39 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
}
const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsArray()) {
return i->value;
}
return kNullValue;
}
const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsObject()) {
return i->value;
}
return kNullValue;
}
const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd()) {
return i->value;
}
return kNullValue;
}
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
{
auto i = obj.FindMember(key);
@@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi
return defaultValue;
}
bool xmrig::JsonReader::isEmpty() const
{
return !m_obj.IsObject() || m_obj.ObjectEmpty();
}

79
src/base/io/json/Json.h Normal file
View File

@@ -0,0 +1,79 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSON_H
#define XMRIG_JSON_H
#include "base/kernel/interfaces/IJsonReader.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Json
{
public:
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
static const rapidjson::Value &getArray(const rapidjson::Value &obj, const char *key);
static const rapidjson::Value &getObject(const rapidjson::Value &obj, const char *key);
static const rapidjson::Value &getValue(const rapidjson::Value &obj, const char *key);
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
static bool get(const char *fileName, rapidjson::Document &doc);
static bool save(const char *fileName, const rapidjson::Document &doc);
};
class JsonReader : public IJsonReader
{
public:
inline JsonReader(const rapidjson::Value &obj) : m_obj(obj) {}
inline bool getBool(const char *key, bool defaultValue = false) const override { return Json::getBool(m_obj, key, defaultValue); }
inline const char *getString(const char *key, const char *defaultValue = nullptr) const override { return Json::getString(m_obj, key, defaultValue); }
inline const rapidjson::Value &getArray(const char *key) const override { return Json::getArray(m_obj, key); }
inline const rapidjson::Value &getObject(const char *key) const override { return Json::getObject(m_obj, key); }
inline const rapidjson::Value &getValue(const char *key) const override { return Json::getValue(m_obj, key); }
inline int getInt(const char *key, int defaultValue = 0) const override { return Json::getInt(m_obj, key, defaultValue); }
inline int64_t getInt64(const char *key, int64_t defaultValue = 0) const override { return Json::getInt64(m_obj, key, defaultValue); }
inline uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override { return Json::getUint64(m_obj, key, defaultValue); }
inline unsigned getUint(const char *key, unsigned defaultValue = 0) const override { return Json::getUint(m_obj, key, defaultValue); }
bool isEmpty() const override;
private:
const rapidjson::Value &m_obj;
};
} /* namespace xmrig */
#endif /* XMRIG_JSON_H */

View File

@@ -0,0 +1,213 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/io/json/Json.h"
#include "base/io/json/JsonChain.h"
#include "base/io/log/Log.h"
#include "rapidjson/error/en.h"
namespace xmrig {
static const rapidjson::Value kNullValue;
}
xmrig::JsonChain::JsonChain()
{
}
bool xmrig::JsonChain::add(rapidjson::Document &&doc)
{
if (doc.HasParseError() || !doc.IsObject() || doc.ObjectEmpty()) {
return false;
}
m_chain.push_back(std::move(doc));
return true;
}
bool xmrig::JsonChain::addFile(const char *fileName)
{
using namespace rapidjson;
Document doc;
if (Json::get(fileName, doc)) {
m_fileName = fileName;
return add(std::move(doc));
}
if (doc.HasParseError()) {
LOG_ERR("%s<offset:%zu>: \"%s\"", fileName, doc.GetErrorOffset(), GetParseError_En(doc.GetParseError()));
}
else {
LOG_ERR("unable to open \"%s\".", fileName);
}
return false;
}
bool xmrig::JsonChain::addRaw(const char *json)
{
using namespace rapidjson;
Document doc;
doc.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(json);
return add(std::move(doc));
}
void xmrig::JsonChain::dump(const char *fileName)
{
rapidjson::Document doc(rapidjson::kArrayType);
for (rapidjson::Document &value : m_chain) {
doc.PushBack(value, doc.GetAllocator());
}
Json::save(fileName, doc);
}
bool xmrig::JsonChain::getBool(const char *key, bool defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsBool()) {
return i->value.GetBool();
}
}
return defaultValue;
}
const char *xmrig::JsonChain::getString(const char *key, const char *defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsString()) {
return i->value.GetString();
}
}
return defaultValue;
}
const rapidjson::Value &xmrig::JsonChain::getArray(const char *key) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsArray()) {
return i->value;
}
}
return kNullValue;
}
const rapidjson::Value &xmrig::JsonChain::getObject(const char *key) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsObject()) {
return i->value;
}
}
return kNullValue;
}
const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd()) {
return i->value;
}
}
return kNullValue;
}
int xmrig::JsonChain::getInt(const char *key, int defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsInt()) {
return i->value.GetInt();
}
}
return defaultValue;
}
int64_t xmrig::JsonChain::getInt64(const char *key, int64_t defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsInt64()) {
return i->value.GetInt64();
}
}
return defaultValue;
}
uint64_t xmrig::JsonChain::getUint64(const char *key, uint64_t defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsUint64()) {
return i->value.GetUint64();
}
}
return defaultValue;
}
unsigned xmrig::JsonChain::getUint(const char *key, unsigned defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsUint()) {
return i->value.GetUint();
}
}
return defaultValue;
}

View File

@@ -0,0 +1,76 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSONCHAIN_H
#define XMRIG_JSONCHAIN_H
#include <vector>
#include "base/kernel/interfaces/IJsonReader.h"
#include "base/tools/String.h"
#include "rapidjson/document.h"
namespace xmrig {
class JsonChain : public IJsonReader
{
public:
JsonChain();
bool add(rapidjson::Document &&doc);
bool addFile(const char *fileName);
bool addRaw(const char *json);
void dump(const char *fileName);
inline const String &fileName() const { return m_fileName; }
inline size_t size() const { return m_chain.size(); }
protected:
inline bool isEmpty() const override { return m_chain.empty(); }
bool getBool(const char *key, bool defaultValue = false) const override;
const char *getString(const char *key, const char *defaultValue = nullptr) const override;
const rapidjson::Value &getArray(const char *key) const override;
const rapidjson::Value &getObject(const char *key) const override;
const rapidjson::Value &getValue(const char *key) const override;
int getInt(const char *key, int defaultValue = 0) const override;
int64_t getInt64(const char *key, int64_t defaultValue = 0) const override;
uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override;
unsigned getUint(const char *key, unsigned defaultValue = 0) const override;
private:
std::vector<rapidjson::Document> m_chain;
String m_fileName;
};
} /* namespace xmrig */
#endif /* XMRIG_JSONCHAIN_H */

View File

@@ -0,0 +1,38 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/io/json/JsonRequest.h"
#include "rapidjson/document.h"
void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params)
{
auto &allocator = doc.GetAllocator();
doc.AddMember("id", id, allocator);
doc.AddMember("jsonrpc", "2.0", allocator);
doc.AddMember("method", rapidjson::StringRef(method), allocator);
doc.AddMember("params", params, allocator);
}

View File

@@ -0,0 +1,45 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSONREQUEST_H
#define XMRIG_JSONREQUEST_H
#include "rapidjson/fwd.h"
namespace xmrig {
class JsonRequest
{
public:
static void create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params);
};
} /* namespace xmrig */
#endif /* XMRIG_JSONREQUEST_H */

View File

@@ -26,7 +26,7 @@
#include <fstream>
#include "base/io/Json.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/ostreamwrapper.h"
@@ -56,6 +56,8 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
rapidjson::OStreamWrapper osw(ofs);
rapidjson::PrettyWriter<rapidjson::OStreamWrapper> writer(osw);
writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);
doc.Accept(writer);
return true;

View File

@@ -35,7 +35,7 @@
#include <fstream>
#include "base/io/Json.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/ostreamwrapper.h"
@@ -102,7 +102,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
return false;
}
# elif defined(__GNUC__)
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_TRUNC);
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC);
if (fd == -1) {
return false;
}
@@ -118,6 +118,8 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
OStreamWrapper osw(ofs);
PrettyWriter<OStreamWrapper> writer(osw);
writer.SetFormatOptions(kFormatSingleLineArray);
doc.Accept(writer);
return true;

243
src/base/io/log/Log.cpp Normal file
View File

@@ -0,0 +1,243 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <algorithm>
#include <mutex>
#include <string.h>
#include <string>
#include <time.h>
#include <uv.h>
#include <vector>
#include "base/io/log/Log.h"
#include "base/kernel/interfaces/ILogBackend.h"
#include "base/tools/Chrono.h"
namespace xmrig {
static const char *colors_map[] = {
RED_BOLD_S, // EMERG
RED_BOLD_S, // ALERT
RED_BOLD_S, // CRIT
RED_S, // ERR
YELLOW_S, // WARNING
WHITE_BOLD_S, // NOTICE
nullptr, // INFO
# ifdef WIN32
BLACK_BOLD_S // DEBUG
# else
BRIGHT_BLACK_S // DEBUG
# endif
};
class LogPrivate
{
public:
inline LogPrivate() :
m_buf()
{
}
inline ~LogPrivate()
{
for (ILogBackend *backend : m_backends) {
delete backend;
}
}
inline void add(ILogBackend *backend) { m_backends.push_back(backend); }
void print(Log::Level level, const char *fmt, va_list args)
{
size_t size = 0;
size_t offset = 0;
std::lock_guard<std::mutex> lock(m_mutex);
timestamp(level, size, offset);
color(level, size);
const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args);
if (rc < 0) {
return;
}
size += std::min(static_cast<size_t>(rc), sizeof (m_buf) - offset - 32);
endl(size);
std::string txt(m_buf);
size_t i;
while ((i = txt.find(CSI)) != std::string::npos) {
txt.erase(i, txt.find('m', i) - i + 1);
}
if (!m_backends.empty()) {
for (ILogBackend *backend : m_backends) {
backend->print(level, m_buf, offset, size, true);
backend->print(level, txt.c_str(), offset, txt.size(), false);
}
}
else {
fputs(txt.c_str(), stdout);
fflush(stdout);
}
}
private:
inline void timestamp(Log::Level level, size_t &size, size_t &offset)
{
if (level == Log::NONE) {
return;
}
const uint64_t ms = Chrono::currentMSecsSinceEpoch();
time_t now = ms / 1000;
tm stime;
# ifdef _WIN32
localtime_s(&stime, &now);
# else
localtime_r(&now, &stime);
# endif
const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
static_cast<int>(ms % 1000)
);
if (rc > 0) {
size = offset = static_cast<size_t>(rc);
}
}
inline void color(Log::Level level, size_t &size)
{
if (level == Log::NONE) {
return;
}
const char *color = colors_map[level];
if (color == nullptr) {
return;
}
const size_t s = strlen(color);
memcpy(m_buf + size, color, s);
size += s;
}
inline void endl(size_t &size)
{
# ifdef _WIN32
memcpy(m_buf + size, CLEAR "\r\n", 7);
size += 6;
# else
memcpy(m_buf + size, CLEAR "\n", 6);
size += 5;
# endif
}
char m_buf[4096];
std::mutex m_mutex;
std::vector<ILogBackend*> m_backends;
};
bool Log::colors = true;
LogPrivate *Log::d = new LogPrivate();
} /* namespace xmrig */
void xmrig::Log::add(ILogBackend *backend)
{
if (d) {
d->add(backend);
}
}
void xmrig::Log::destroy()
{
delete d;
d = nullptr;
}
void xmrig::Log::print(const char *fmt, ...)
{
if (!d) {
return;
}
va_list args;
va_start(args, fmt);
d->print(NONE, fmt, args);
va_end(args);
}
void xmrig::Log::print(Level level, const char *fmt, ...)
{
if (!d) {
return;
}
va_list args;
va_start(args, fmt);
d->print(level, fmt, args);
va_end(args);
}

143
src/base/io/log/Log.h Normal file
View File

@@ -0,0 +1,143 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_LOG_H
#define XMRIG_LOG_H
namespace xmrig {
class ILogBackend;
class LogPrivate;
class Log
{
public:
enum Level : int {
NONE = -1,
EMERG, // system is unusable
ALERT, // action must be taken immediately
CRIT, // critical conditions
ERR, // error conditions
WARNING, // warning conditions
NOTICE, // normal but significant condition
INFO, // informational
DEBUG, // debug-level messages
};
static void add(ILogBackend *backend);
static void destroy();
static void print(const char *fmt, ...);
static void print(Level level, const char *fmt, ...);
static bool colors;
private:
static LogPrivate *d;
};
#define CSI "\x1B[" // Control Sequence Introducer (ANSI spec name)
#define CLEAR CSI "0m" // all attributes off
#define BRIGHT_BLACK_S CSI "0;90m" // somewhat MD.GRAY
#define BLACK_S CSI "0;30m"
#define BLACK_BOLD_S CSI "1;30m" // another name for GRAY
#define RED_S CSI "0;31m"
#define RED_BOLD_S CSI "1;31m"
#define GREEN_S CSI "0;32m"
#define GREEN_BOLD_S CSI "1;32m"
#define YELLOW_S CSI "0;33m"
#define YELLOW_BOLD_S CSI "1;33m"
#define BLUE_S CSI "0;34m"
#define BLUE_BOLD_S CSI "1;34m"
#define MAGENTA_S CSI "0;35m"
#define MAGENTA_BOLD_S CSI "1;35m"
#define CYAN_S CSI "0;36m"
#define CYAN_BOLD_S CSI "1;36m"
#define WHITE_S CSI "0;37m" // another name for LT.GRAY
#define WHITE_BOLD_S CSI "1;37m" // actually white
#define BLUE_BG_S CSI "44m"
#define BLUE_BG_BOLD_S CSI "44;1m"
#define MAGENTA_BG_S CSI "45m"
#define MAGENTA_BG_BOLD_S CSI "45;1m"
#define CYAN_BG_S CSI "46m"
#define CYAN_BG_BOLD_S CSI "46;1m"
//color wrappings
#define BLACK(x) BLACK_S x CLEAR
#define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR
#define RED(x) RED_S x CLEAR
#define RED_BOLD(x) RED_BOLD_S x CLEAR
#define GREEN(x) GREEN_S x CLEAR
#define GREEN_BOLD(x) GREEN_BOLD_S x CLEAR
#define YELLOW(x) YELLOW_S x CLEAR
#define YELLOW_BOLD(x) YELLOW_BOLD_S x CLEAR
#define BLUE(x) BLUE_S x CLEAR
#define BLUE_BOLD(x) BLUE_BOLD_S x CLEAR
#define MAGENTA(x) MAGENTA_S x CLEAR
#define MAGENTA_BOLD(x) MAGENTA_BOLD_S x CLEAR
#define CYAN(x) CYAN_S x CLEAR
#define CYAN_BOLD(x) CYAN_BOLD_S x CLEAR
#define WHITE(x) WHITE_S x CLEAR
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
#define BLUE_BG(x) BLUE_BG_S x CLEAR
#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR
#define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR
#define MAGENTA_BG_BOLD(x) MAGENTA_BG_BOLD_S x CLEAR
#define CYAN_BG(x) CYAN_BG_S x CLEAR
#define CYAN_BG_BOLD(x) CYAN_BG_BOLD_S x CLEAR
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
#define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__)
#define LOG_CRIT(x, ...) xmrig::Log::print(xmrig::Log::CRIT, x, ##__VA_ARGS__)
#define LOG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
#define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__)
#define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__)
#ifdef APP_DEBUG
# define LOG_DEBUG(x, ...) xmrig::Log::print(xmrig::Log::DEBUG, x, ##__VA_ARGS__)
#else
# define LOG_DEBUG(x, ...)
#endif
#if defined(APP_DEBUG) || defined(APP_DEVEL)
# define LOG_DEBUG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
# define LOG_DEBUG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
#else
# define LOG_DEBUG_ERR(x, ...)
# define LOG_DEBUG_WARN(x, ...)
#endif
} /* namespace xmrig */
#endif /* XMRIG_LOG_H */

View File

@@ -5,7 +5,9 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,36 +24,26 @@
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include "common/log/ConsoleLog.h"
#include "common/log/Log.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "base/tools/Handle.h"
#include "base/io/log/backends/ConsoleLog.h"
#include "base/io/log/Log.h"
ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
m_stream(nullptr),
m_controller(controller)
xmrig::ConsoleLog::ConsoleLog() :
m_stream(nullptr)
{
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
m_tty = new uv_tty_t;
if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) {
Log::colors = false;
return;
}
uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
m_uvBuf.base = m_buf;
m_stream = reinterpret_cast<uv_stream_t*>(&m_tty);
uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
# ifdef WIN32
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
@@ -66,44 +58,35 @@ ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
}
void ConsoleLog::message(Level level, const char* fmt, va_list args)
xmrig::ConsoleLog::~ConsoleLog()
{
time_t now = time(nullptr);
tm stime;
Handle::close(m_tty);
}
void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors)
{
if (Log::colors != colors) {
return;
}
# ifdef _WIN32
localtime_s(&stime, &now);
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), static_cast<unsigned int>(size));
# else
localtime_r(&now, &stime);
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), size);
# endif
const bool isColors = m_controller->config()->isColors();
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
Log::colorByLevel(level, isColors),
fmt,
Log::endl(isColors)
);
print(args);
if (!isWritable()) {
fputs(line, stdout);
fflush(stdout);
}
else {
uv_try_write(m_stream, &buf, 1);
}
}
void ConsoleLog::text(const char* fmt, va_list args)
{
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(m_controller->config()->isColors()));
print(args);
}
bool ConsoleLog::isWritable() const
bool xmrig::ConsoleLog::isWritable() const
{
if (!m_stream || uv_is_writable(m_stream) != 1) {
return false;
@@ -112,20 +95,3 @@ bool ConsoleLog::isWritable() const
const uv_handle_type type = uv_guess_handle(1);
return type == UV_TTY || type == UV_NAMED_PIPE;
}
void ConsoleLog::print(va_list args)
{
m_uvBuf.len = vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args);
if (m_uvBuf.len <= 0) {
return;
}
if (!isWritable()) {
fputs(m_buf, stdout);
fflush(stdout);
}
else {
uv_try_write(m_stream, &m_uvBuf, 1);
}
}

View File

@@ -0,0 +1,60 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CONSOLELOG_H
#define XMRIG_CONSOLELOG_H
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tty_s uv_tty_t;
#include "base/kernel/interfaces/ILogBackend.h"
namespace xmrig {
class ConsoleLog : public ILogBackend
{
public:
ConsoleLog();
~ConsoleLog() override;
protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
private:
bool isWritable() const;
uv_stream_t *m_stream;
uv_tty_t *m_tty;
};
} /* namespace xmrig */
#endif /* XMRIG_CONSOLELOG_H */

View File

@@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
@@ -23,42 +24,44 @@
*/
#include "base/io/Watcher.h"
#include "base/kernel/interfaces/IConfigListener.h"
#include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h"
#include "common/log/Log.h"
#include "core/ConfigCreator.h"
#include <string.h>
#include <uv.h>
xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigCreator *creator, IConfigListener *listener) :
m_creator(creator),
m_listener(listener)
#include "base/io/log/backends/FileLog.h"
xmrig::FileLog::FileLog(const char *fileName)
{
m_watcher = new Watcher(path, this);
uv_fs_t req;
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
uv_fs_req_cleanup(&req);
}
xmrig::ConfigWatcher::~ConfigWatcher()
void xmrig::FileLog::print(int, const char *line, size_t, size_t size, bool colors)
{
delete m_watcher;
}
void xmrig::ConfigWatcher::onFileChanged(const String &fileName)
{
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
IConfig *config = m_creator->create();
ConfigLoader::loadFromFile(config, fileName);
if (!config->finalize()) {
LOG_ERR("reloading failed");
delete config;
if (m_file < 0 || colors) {
return;
}
m_listener->onNewConfig(config);
# ifdef _WIN32
uv_buf_t buf = uv_buf_init(strdup(line), static_cast<unsigned int>(size));
# else
uv_buf_t buf = uv_buf_init(strdup(line), size);
# endif
uv_fs_t *req = new uv_fs_t;
req->data = buf.base;
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, FileLog::onWrite);
}
void xmrig::FileLog::onWrite(uv_fs_t *req)
{
delete [] static_cast<char *>(req->data);
uv_fs_req_cleanup(req);
delete req;
}

View File

@@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
@@ -22,36 +23,36 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_SUBMITRESULT_H
#define XMRIG_SUBMITRESULT_H
#ifndef XMRIG_FILELOG_H
#define XMRIG_FILELOG_H
#include <uv.h>
typedef struct uv_fs_s uv_fs_t;
#include "base/kernel/interfaces/ILogBackend.h"
namespace xmrig {
class SubmitResult
class FileLog : public ILogBackend
{
public:
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);
FileLog(const char *fileName);
void done();
int64_t reqId;
int64_t seq;
uint32_t diff;
uint64_t actualDiff;
uint64_t elapsed;
protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
private:
uint64_t start;
static void onWrite(uv_fs_t *req);
int m_file;
};
} /* namespace xmrig */
#endif /* XMRIG_SUBMITRESULT_H */
#endif /* XMRIG_FILELOG_H */

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 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <syslog.h>
#include "base/io/log/backends/SysLog.h"
#include "version.h"
xmrig::SysLog::SysLog()
{
openlog(APP_ID, LOG_PID, LOG_USER);
}
xmrig::SysLog::~SysLog()
{
closelog();
}
void xmrig::SysLog::print(int level, const char *line, size_t offset, size_t, bool colors)
{
if (colors) {
return;
}
syslog(level == -1 ? LOG_INFO : level, "%s", line + offset);
}

View File

@@ -0,0 +1,50 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_SYSLOG_H
#define XMRIG_SYSLOG_H
#include "base/kernel/interfaces/ILogBackend.h"
namespace xmrig {
class SysLog : public ILogBackend
{
public:
SysLog();
~SysLog();
protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
};
} /* namespace xmrig */
#endif /* XMRIG_SYSLOG_H */

328
src/base/kernel/Base.cpp Normal file
View File

@@ -0,0 +1,328 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <memory>
#include "base/io/json/Json.h"
#include "base/io/json/JsonChain.h"
#include "base/io/log/backends/ConsoleLog.h"
#include "base/io/log/backends/FileLog.h"
#include "base/io/log/Log.h"
#include "base/io/Watcher.h"
#include "base/kernel/Base.h"
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/kernel/Platform.h"
#include "base/kernel/Process.h"
#include "core/config/Config.h"
#include "core/config/ConfigTransform.h"
#ifdef HAVE_SYSLOG_H
# include "base/io/log/backends/SysLog.h"
#endif
#ifdef XMRIG_FEATURE_API
# include "api/Api.h"
# include "api/interfaces/IApiRequest.h"
#endif
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
# include "core/config/Config_default.h"
#endif
namespace xmrig {
static const char *kConfigPathV1 = "/1/config";
static const char *kConfigPathV2 = "/2/config";
} // namespace xmrig
class xmrig::BasePrivate
{
public:
inline BasePrivate(Process *process) :
api(nullptr),
config(nullptr),
process(process),
watcher(nullptr)
{}
inline ~BasePrivate()
{
# ifdef XMRIG_FEATURE_API
delete api;
# endif
delete config;
delete watcher;
}
inline bool read(const JsonChain &chain, std::unique_ptr<Config> &config)
{
config = std::unique_ptr<Config>(new Config());
return config->read(chain, chain.fileName());
}
inline Config *load()
{
JsonChain chain;
ConfigTransform transform;
std::unique_ptr<Config> config;
transform.load(chain, process, transform);
if (read(chain, config)) {
return config.release();
}
chain.addFile(process->location(Process::ExeLocation, "config.json"));
if (read(chain, config)) {
return config.release();
}
# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
chain.addRaw(default_config);
if (read(chain, config)) {
return config.release();
}
# endif
return nullptr;
}
inline void replace(Config *newConfig)
{
Config *previousConfig = config;
config = newConfig;
for (IBaseListener *listener : listeners) {
listener->onConfigChanged(config, previousConfig);
}
delete previousConfig;
}
Api *api;
Config *config;
Process *process;
std::vector<IBaseListener *> listeners;
Watcher *watcher;
};
xmrig::Base::Base(Process *process)
: d_ptr(new BasePrivate(process))
{
}
xmrig::Base::~Base()
{
delete d_ptr;
}
bool xmrig::Base::isReady() const
{
return d_ptr->config != nullptr;
}
int xmrig::Base::init()
{
d_ptr->config = d_ptr->load();
if (!d_ptr->config) {
LOG_EMERG("No valid configuration found. Exiting.");
return 1;
}
# ifdef XMRIG_FEATURE_API
d_ptr->api = new Api(this);
d_ptr->api->addListener(this);
# endif
Platform::init(config()->userAgent());
# ifndef XMRIG_PROXY_PROJECT
Platform::setProcessPriority(config()->cpu().priority());
# endif
if (!config()->isBackground()) {
Log::add(new ConsoleLog());
}
if (config()->logFile()) {
Log::add(new FileLog(config()->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (config()->isSyslog()) {
Log::add(new SysLog());
}
# endif
return 0;
}
void xmrig::Base::start()
{
# ifdef XMRIG_FEATURE_API
api()->start();
# endif
if (config()->isShouldSave()) {
config()->save();
}
if (config()->isWatch()) {
d_ptr->watcher = new Watcher(config()->fileName(), this);
}
}
void xmrig::Base::stop()
{
# ifdef XMRIG_FEATURE_API
api()->stop();
# endif
delete d_ptr->watcher;
d_ptr->watcher = nullptr;
}
xmrig::Api *xmrig::Base::api() const
{
assert(d_ptr->api != nullptr);
return d_ptr->api;
}
bool xmrig::Base::reload(const rapidjson::Value &json)
{
JsonReader reader(json);
if (reader.isEmpty()) {
return false;
}
Config *config = new Config();
if (!config->read(reader, d_ptr->config->fileName())) {
delete config;
return false;
}
const bool saved = config->save();
if (config->isWatch() && d_ptr->watcher && saved) {
delete config;
return true;
}
d_ptr->replace(config);
return true;
}
xmrig::Config *xmrig::Base::config() const
{
assert(d_ptr->config != nullptr);
return d_ptr->config;
}
void xmrig::Base::addListener(IBaseListener *listener)
{
d_ptr->listeners.push_back(listener);
}
void xmrig::Base::onFileChanged(const String &fileName)
{
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
JsonChain chain;
chain.addFile(fileName);
Config *config = new Config();
if (!config->read(chain, chain.fileName())) {
LOG_ERR("reloading failed");
delete config;
return;
}
d_ptr->replace(config);
}
#ifdef XMRIG_FEATURE_API
void xmrig::Base::onRequest(IApiRequest &request)
{
if (request.method() == IApiRequest::METHOD_GET) {
if (request.url() == kConfigPathV1 || request.url() == kConfigPathV2) {
if (request.isRestricted()) {
return request.done(403);
}
request.accept();
config()->getJSON(request.doc());
}
}
else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) {
if (request.url() == kConfigPathV1 || request.url() == kConfigPathV2) {
request.accept();
if (!reload(request.json())) {
return request.done(400);
}
request.done(204);
}
}
}
#endif

View File

@@ -22,32 +22,55 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSON_H
#define XMRIG_JSON_H
#ifndef XMRIG_BASE_H
#define XMRIG_BASE_H
#include "api/interfaces/IApiListener.h"
#include "base/kernel/interfaces/IConfigListener.h"
#include "base/kernel/interfaces/IWatcherListener.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Json
class Api;
class BasePrivate;
class Config;
class IBaseListener;
class Process;
class Base : public IWatcherListener, public IApiListener
{
public:
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
Base(Process *process);
~Base() override;
static bool get(const char *fileName, rapidjson::Document &doc);
static bool save(const char *fileName, const rapidjson::Document &doc);
virtual bool isReady() const;
virtual int init();
virtual void start();
virtual void stop();
Api *api() const;
bool reload(const rapidjson::Value &json);
Config *config() const;
void addListener(IBaseListener *listener);
protected:
void onFileChanged(const String &fileName) override;
# ifdef XMRIG_FEATURE_API
void onRequest(IApiRequest &request) override;
# endif
private:
BasePrivate *d_ptr;
};
} /* namespace xmrig */
#endif /* XMRIG_JSON_H */
#endif /* XMRIG_BASE_H */

View File

@@ -27,22 +27,23 @@
#include <uv.h>
#ifndef XMRIG_NO_HTTPD
# include <microhttpd.h>
#endif
#ifndef XMRIG_NO_TLS
#ifdef XMRIG_FEATURE_TLS
# include <openssl/opensslv.h>
#endif
#ifdef XMRIG_FEATURE_HWLOC
# include <hwloc.h>
#endif
#include "base/kernel/Entry.h"
#include "base/kernel/Process.h"
#include "core/usage.h"
#include "core/config/usage.h"
#include "version.h"
namespace xmrig {
static int showVersion()
{
printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
@@ -73,21 +74,57 @@ static int showVersion()
printf("\nlibuv/%s\n", uv_version_string());
# ifndef XMRIG_NO_HTTPD
printf("microhttpd/%s\n", MHD_get_version());
# endif
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
{
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);
}
# endif
# if defined(XMRIG_FEATURE_HWLOC)
# if defined(HWLOC_VERSION)
printf("hwloc/%s\n", HWLOC_VERSION);
# elif HWLOC_API_VERSION >= 0x20000
printf("hwloc/2\n");
# else
printf("hwloc/1\n");
# endif
# endif
return 0;
}
#ifdef XMRIG_FEATURE_HWLOC
static int exportTopology(const Process &process)
{
const String path = process.location(Process::ExeLocation, "topology.xml");
hwloc_topology_t topology;
hwloc_topology_init(&topology);
hwloc_topology_load(topology);
# if HWLOC_API_VERSION >= 0x20000
if (hwloc_topology_export_xml(topology, path, 0) == -1) {
# else
if (hwloc_topology_export_xml(topology, path) == -1) {
# endif
printf("failed to export hwloc topology.\n");
}
else {
printf("hwloc topology successfully exported to \"%s\"\n", path.data());
}
hwloc_topology_destroy(topology);
return 0;
}
#endif
} // namespace xmrig
xmrig::Entry::Id xmrig::Entry::get(const Process &process)
{
const Arguments &args = process.arguments();
@@ -99,11 +136,17 @@ xmrig::Entry::Id xmrig::Entry::get(const Process &process)
return Version;
}
# ifdef XMRIG_FEATURE_HWLOC
if (args.hasArg("--export-topology")) {
return Topo;
}
# endif
return Default;
}
int xmrig::Entry::exec(const Process &, Id id)
int xmrig::Entry::exec(const Process &process, Id id)
{
switch (id) {
case Usage:
@@ -113,6 +156,11 @@ int xmrig::Entry::exec(const Process &, Id id)
case Version:
return showVersion();
# ifdef XMRIG_FEATURE_HWLOC
case Topo:
return exportTopology(process);
# endif
default:
break;
}

View File

@@ -38,7 +38,8 @@ public:
enum Id {
Default,
Usage,
Version
Version,
Topo
};
static Id get(const Process &process);

View File

@@ -27,7 +27,7 @@
#include <uv.h>
#ifndef XMRIG_NO_TLS
#ifdef XMRIG_FEATURE_TLS
# include <openssl/ssl.h>
# include <openssl/err.h>
#endif
@@ -41,7 +41,7 @@ xmrig::String Platform::m_userAgent;
void Platform::init(const char *userAgent)
{
# ifndef XMRIG_NO_TLS
# ifdef XMRIG_FEATURE_TLS
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();

View File

@@ -35,6 +35,15 @@
class Platform
{
public:
static inline bool trySetThreadAffinity(int64_t cpu_id)
{
if (cpu_id < 0) {
return false;
}
return setThreadAffinity(static_cast<uint64_t>(cpu_id));
}
static bool setThreadAffinity(uint64_t cpu_id);
static uint32_t setTimerResolution(uint32_t resolution);
static void init(const char *userAgent);

View File

@@ -29,7 +29,7 @@
#include <uv.h>
#include "log/Log.h"
#include "base/io/log/Log.h"
#include "Platform.h"
#include "version.h"

View File

@@ -28,6 +28,7 @@
#include "base/kernel/Process.h"
#include "base/tools/Chrono.h"
static size_t location(xmrig::Process::Location location, char *buf, size_t max)
@@ -50,7 +51,7 @@ static size_t location(xmrig::Process::Location location, char *buf, size_t max)
xmrig::Process::Process(int argc, char **argv) :
m_arguments(argc, argv)
{
srand(static_cast<unsigned int>(static_cast<uintptr_t>(time(nullptr)) ^ reinterpret_cast<uintptr_t>(this)));
srand(static_cast<unsigned int>(Chrono::currentMSecsSinceEpoch() ^ reinterpret_cast<uintptr_t>(this)));
}

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,20 +44,31 @@ xmrig::Signals::Signals(ISignalListener *listener)
m_signals[i] = signal;
uv_signal_init(uv_default_loop(), signal);
uv_signal_start(signal, xmrig::Signals::onSignal, signums[i]);
uv_signal_start(signal, Signals::onSignal, signums[i]);
}
}
xmrig::Signals::~Signals()
{
stop();
}
void xmrig::Signals::stop()
{
if (!m_signals[0]) {
return;
}
for (size_t i = 0; i < kSignalsCount; ++i) {
Handle::close(m_signals[i]);
m_signals[i] = nullptr;
}
}
void xmrig::Signals::onSignal(uv_signal_t *handle, int signum)
{
static_cast<xmrig::Signals *>(handle->data)->m_listener->onSignal(signum);
static_cast<Signals *>(handle->data)->m_listener->onSignal(signum);
}

View File

@@ -46,6 +46,8 @@ public:
Signals(ISignalListener *listener);
~Signals();
void stop();
private:
void close(int signum);

View File

@@ -0,0 +1,168 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#ifdef XMRIG_FEATURE_TLS
# include <openssl/opensslv.h>
#endif
#ifdef XMRIG_FEATURE_HWLOC
# include "backend/cpu/Cpu.h"
#endif
#ifdef XMRIG_AMD_PROJECT
# if defined(__APPLE__)
# include <OpenCL/cl.h>
# else
# include "3rdparty/CL/cl.h"
# endif
#endif
#ifdef XMRIG_NVIDIA_PROJECT
# include "nvidia/cryptonight.h"
#endif
#include "base/io/json/Json.h"
#include "base/io/log/Log.h"
#include "base/kernel/config/BaseConfig.h"
#include "base/kernel/interfaces/IJsonReader.h"
#include "donate.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
#include "version.h"
xmrig::BaseConfig::BaseConfig()
{
}
void xmrig::BaseConfig::printVersions()
{
char buf[256] = { 0 };
# if defined(__clang__)
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
# elif defined(__GNUC__)
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
# endif
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf);
# if defined(XMRIG_AMD_PROJECT)
# if CL_VERSION_2_0
const char *ocl = "2.0";
# elif CL_VERSION_1_2
const char *ocl = "1.2";
# elif CL_VERSION_1_1
const char *ocl = "1.1";
# elif CL_VERSION_1_0
const char *ocl = "1.0";
# else
const char *ocl = "0.0";
# endif
int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl);
# elif defined(XMRIG_NVIDIA_PROJECT)
const int cudaVersion = cuda_get_runtime_version();
int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100);
# endif
std::string libs;
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
{
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
snprintf(buf, sizeof buf, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
libs += buf;
}
# endif
# if defined(XMRIG_FEATURE_HWLOC)
libs += Cpu::info()->backend();
# endif
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), libs.c_str());
}
bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
{
m_fileName = fileName;
if (reader.isEmpty()) {
return false;
}
m_autoSave = reader.getBool("autosave", m_autoSave);
m_background = reader.getBool("background", m_background);
m_dryRun = reader.getBool("dry-run", m_dryRun);
m_syslog = reader.getBool("syslog", m_syslog);
m_watch = reader.getBool("watch", m_watch);
Log::colors = reader.getBool("colors", Log::colors);
m_logFile = reader.getString("log-file");
m_userAgent = reader.getString("user-agent");
setPrintTime(reader.getUint("print-time", 60));
const rapidjson::Value &api = reader.getObject("api");
if (api.IsObject()) {
m_apiId = Json::getString(api, "id");
m_apiWorkerId = Json::getString(api, "worker-id");
}
m_http.load(reader.getObject("http"));
m_pools.load(reader);
return m_pools.active() > 0;
}
bool xmrig::BaseConfig::save()
{
if (m_fileName.isNull()) {
return false;
}
rapidjson::Document doc;
getJSON(doc);
if (Json::save(m_fileName, doc)) {
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
return true;
}
return false;
}

View File

@@ -22,91 +22,72 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_COMMONCONFIG_H
#define XMRIG_COMMONCONFIG_H
#ifndef XMRIG_BASECONFIG_H
#define XMRIG_BASECONFIG_H
#include "base/net/Pools.h"
#include "base/tools/String.h"
#include "common/interfaces/IConfig.h"
#include "common/xmrig.h"
#include "base/kernel/interfaces/IConfig.h"
#include "base/net/http/Http.h"
#include "base/net/stratum/Pools.h"
struct option;
namespace xmrig {
class CommonConfig : public IConfig
class IJsonReader;
class BaseConfig : public IConfig
{
public:
CommonConfig();
BaseConfig();
inline bool isApiIPv6() const { return m_apiIPv6; }
inline bool isApiRestricted() const { return m_apiRestricted; }
inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; }
inline bool isDryRun() const { return m_dryRun; }
inline bool isSyslog() const { return m_syslog; }
inline const char *apiId() const { return m_apiId.data(); }
inline const char *apiToken() const { return m_apiToken.data(); }
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
inline const char *logFile() const { return m_logFile.data(); }
inline const char *userAgent() const { return m_userAgent.data(); }
inline const Http &http() const { return m_http; }
inline const Pools &pools() const { return m_pools; }
inline int apiPort() const { return m_apiPort; }
inline int donateLevel() const { return m_donateLevel; }
inline int printTime() const { return m_printTime; }
inline const String &apiId() const { return m_apiId; }
inline const String &apiWorkerId() const { return m_apiWorkerId; }
inline uint32_t printTime() const { return m_printTime; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const Algorithm &algorithm() const override { return m_algorithm; }
inline const String &fileName() const override { return m_fileName; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const String &fileName() const override { return m_fileName; }
inline void setFileName(const char *fileName) override { m_fileName = fileName; }
bool read(const IJsonReader &reader, const char *fileName) override;
bool save() override;
bool isColors() const;
void printAPI();
void printPools();
void printVersions();
protected:
enum State {
NoneState,
ReadyState,
ErrorState
};
bool finalize() override;
bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override;
void parseJSON(const rapidjson::Document &doc) override;
void setFileName(const char *fileName) override;
Algorithm m_algorithm;
bool m_adjusted;
bool m_apiIPv6;
bool m_apiRestricted;
bool m_autoSave;
bool m_background;
bool m_dryRun;
bool m_syslog;
bool m_watch;
int m_apiPort;
int m_donateLevel;
int m_printTime;
bool m_autoSave = true;
bool m_background = false;
bool m_dryRun = false;
bool m_syslog = false;
bool m_upgrade = false;
bool m_watch = true;
Http m_http;
Pools m_pools;
State m_state;
String m_apiId;
String m_apiToken;
String m_apiWorkerId;
String m_fileName;
String m_logFile;
String m_userAgent;
uint32_t m_printTime;
private:
bool parseInt(int key, int arg);
inline void setPrintTime(uint32_t printTime) { if (printTime <= 3600) { m_printTime = printTime; } }
};
} /* namespace xmrig */
} // namespace xmrig
#endif /* XMRIG_COMMONCONFIG_H */
#endif /* XMRIG_BASECONFIG_H */

View File

@@ -0,0 +1,269 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#ifdef _MSC_VER
# include "getopt/getopt.h"
#else
# include <getopt.h>
#endif
#include "base/kernel/config/BaseTransform.h"
#include "base/kernel/Process.h"
#include "base/io/log/Log.h"
#include "base/kernel/interfaces/IConfig.h"
#include "base/io/json/JsonChain.h"
#include "core/config/Config_platform.h"
namespace xmrig
{
static const char *kAlgo = "algo";
static const char *kApi = "api";
static const char *kHttp = "http";
static const char *kPools = "pools";
}
xmrig::BaseTransform::BaseTransform()
{
}
void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform)
{
using namespace rapidjson;
int key;
int argc = process->arguments().argc();
char **argv = process->arguments().argv();
Document doc(kObjectType);
while (1) {
key = getopt_long(argc, argv, short_options, options, nullptr);
if (key < 0) {
break;
}
if (key == IConfig::ConfigKey) {
chain.add(std::move(doc));
chain.addFile(optarg);
doc = Document(kObjectType);
}
else {
transform.transform(doc, key, optarg);
}
}
if (optind < argc) {
LOG_WARN("%s: unsupported non-option argument '%s'", argv[0], argv[optind]);
}
transform.finalize(doc);
chain.add(std::move(doc));
}
void xmrig::BaseTransform::finalize(rapidjson::Document &doc)
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
if (m_algorithm.isValid() && doc.HasMember(kPools)) {
auto &pools = doc[kPools];
for (Value &pool : pools.GetArray()) {
if (!pool.HasMember(kAlgo)) {
pool.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator);
}
}
}
}
void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const char *arg)
{
switch (key) {
case IConfig::AlgorithmKey: /* --algo */
if (!doc.HasMember(kPools)) {
m_algorithm = arg;
}
else {
return add(doc, kPools, kAlgo, arg);
}
break;
case IConfig::UserpassKey: /* --userpass */
{
const char *p = strrchr(arg, ':');
if (!p) {
return;
}
char *user = new char[p - arg + 1]();
strncpy(user, arg, static_cast<size_t>(p - arg));
add<const char *>(doc, kPools, "user", user);
add(doc, kPools, "pass", p + 1);
delete [] user;
}
break;
case IConfig::UrlKey: /* --url */
return add(doc, kPools, "url", arg, true);
case IConfig::UserKey: /* --user */
return add(doc, kPools, "user", arg);
case IConfig::PasswordKey: /* --pass */
return add(doc, kPools, "pass", arg);
case IConfig::RigIdKey: /* --rig-id */
return add(doc, kPools, "rig-id", arg);
case IConfig::FingerprintKey: /* --tls-fingerprint */
return add(doc, kPools, "tls-fingerprint", arg);
case IConfig::LogFileKey: /* --log-file */
return set(doc, "log-file", arg);
case IConfig::HttpAccessTokenKey: /* --http-access-token */
return set(doc, kHttp, "access-token", arg);
case IConfig::HttpHostKey: /* --http-host */
return set(doc, kHttp, "host", arg);
case IConfig::ApiWorkerIdKey: /* --api-worker-id */
return set(doc, kApi, "worker-id", arg);
case IConfig::ApiIdKey: /* --api-id */
return set(doc, kApi, "id", arg);
case IConfig::UserAgentKey: /* --user-agent */
return set(doc, "user-agent", arg);
case IConfig::RetriesKey: /* --retries */
case IConfig::RetryPauseKey: /* --retry-pause */
case IConfig::PrintTimeKey: /* --print-time */
case IConfig::HttpPort: /* --http-port */
case IConfig::DonateLevelKey: /* --donate-level */
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
case IConfig::BackgroundKey: /* --background */
case IConfig::SyslogKey: /* --syslog */
case IConfig::KeepAliveKey: /* --keepalive */
case IConfig::NicehashKey: /* --nicehash */
case IConfig::TlsKey: /* --tls */
case IConfig::DryRunKey: /* --dry-run */
case IConfig::HttpEnabledKey: /* --http-enabled */
case IConfig::DaemonKey: /* --daemon */
return transformBoolean(doc, key, true);
case IConfig::ColorKey: /* --no-color */
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
return transformBoolean(doc, key, false);
default:
break;
}
}
void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable)
{
switch (key) {
case IConfig::BackgroundKey: /* --background */
return set(doc, "background", enable);
case IConfig::SyslogKey: /* --syslog */
return set(doc, "syslog", enable);
case IConfig::KeepAliveKey: /* --keepalive */
return add(doc, kPools, "keepalive", enable);
case IConfig::TlsKey: /* --tls */
return add(doc, kPools, "tls", enable);
case IConfig::DaemonKey: /* --daemon */
return add(doc, kPools, "daemon", enable);
# ifndef XMRIG_PROXY_PROJECT
case IConfig::NicehashKey: /* --nicehash */
return add<bool>(doc, kPools, "nicehash", enable);
# endif
case IConfig::ColorKey: /* --no-color */
return set(doc, "colors", enable);
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
return set(doc, kHttp, "restricted", enable);
case IConfig::HttpEnabledKey: /* --http-enabled */
return set(doc, kHttp, "enabled", enable);
case IConfig::DryRunKey: /* --dry-run */
return set(doc, "dry-run", enable);
default:
break;
}
}
void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg)
{
switch (key) {
case IConfig::RetriesKey: /* --retries */
return set(doc, "retries", arg);
case IConfig::RetryPauseKey: /* --retry-pause */
return set(doc, "retry-pause", arg);
case IConfig::DonateLevelKey: /* --donate-level */
return set(doc, "donate-level", arg);
case IConfig::ProxyDonateKey: /* --donate-over-proxy */
return set(doc, "donate-over-proxy", arg);
case IConfig::HttpPort: /* --http-port */
return set(doc, kHttp, "port", arg);
case IConfig::PrintTimeKey: /* --print-time */
return set(doc, "print-time", arg);
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
return add(doc, kPools, "daemon-poll-interval", arg);
default:
break;
}
}

View File

@@ -0,0 +1,127 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_BASETRANSFORM_H
#define XMRIG_BASETRANSFORM_H
#include "base/kernel/interfaces/IConfigTransform.h"
#include "rapidjson/document.h"
struct option;
namespace xmrig {
class IConfigTransform;
class JsonChain;
class Process;
class BaseTransform : public IConfigTransform
{
public:
BaseTransform();
static void load(JsonChain &chain, Process *process, IConfigTransform &transform);
protected:
void finalize(rapidjson::Document &doc) override;
void transform(rapidjson::Document &doc, int key, const char *arg) override;
template<typename T>
inline void set(rapidjson::Document &doc, const char *key, T value) { set<T>(doc, doc, key, value); }
template<typename T>
inline void set(rapidjson::Document &doc, const char *objKey, const char *key, T value)
{
if (!doc.HasMember(objKey)) {
doc.AddMember(rapidjson::StringRef(objKey), rapidjson::kObjectType, doc.GetAllocator());
}
set<T>(doc, doc[objKey], key, value);
}
template<typename T>
inline void add(rapidjson::Document &doc, const char *arrayKey, const char *key, T value, bool force = false)
{
auto &allocator = doc.GetAllocator();
if (!doc.HasMember(arrayKey)) {
doc.AddMember(rapidjson::StringRef(arrayKey), rapidjson::kArrayType, allocator);
}
rapidjson::Value &array = doc[arrayKey];
if (force || array.Size() == 0) {
array.PushBack(rapidjson::kObjectType, allocator);
}
set<T>(doc, array[array.Size() - 1], key, value);
}
template<typename T>
inline void set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, T value)
{
if (obj.HasMember(key)) {
obj[key] = value;
}
else {
obj.AddMember(rapidjson::StringRef(key), value, doc.GetAllocator());
}
}
protected:
Algorithm m_algorithm;
private:
void transformBoolean(rapidjson::Document &doc, int key, bool enable);
void transformUint64(rapidjson::Document &doc, int key, uint64_t arg);
};
template<>
inline void BaseTransform::set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, const char *value)
{
auto &allocator = doc.GetAllocator();
if (obj.HasMember(key)) {
obj[key] = rapidjson::Value(value, allocator);
}
else {
obj.AddMember(rapidjson::StringRef(key), rapidjson::Value(value, allocator), allocator);
}
}
} // namespace xmrig
#endif /* XMRIG_BASETRANSFORM_H */

View File

@@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ICONTROLLERLISTENER_H
#define XMRIG_ICONTROLLERLISTENER_H
#ifndef XMRIG_IBASELISTENER_H
#define XMRIG_IBASELISTENER_H
namespace xmrig {
@@ -32,10 +32,10 @@ namespace xmrig {
class Config;
class IControllerListener
class IBaseListener
{
public:
virtual ~IControllerListener() = default;
virtual ~IBaseListener() = default;
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
};
@@ -44,4 +44,4 @@ public:
} /* namespace xmrig */
#endif // XMRIG_ICONTROLLERLISTENER_H
#endif // XMRIG_IBASELISTENER_H

View File

@@ -0,0 +1,85 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ICLIENT_H
#define XMRIG_ICLIENT_H
#include <stdint.h>
namespace xmrig {
class Algorithm;
class Job;
class JobResult;
class Pool;
class String;
class IClient
{
public:
enum Extension {
EXT_ALGO,
EXT_NICEHASH,
EXT_CONNECT,
EXT_TLS,
EXT_KEEPALIVE,
EXT_MAX
};
virtual ~IClient() = default;
virtual bool disconnect() = 0;
virtual bool hasExtension(Extension extension) const noexcept = 0;
virtual bool isEnabled() const = 0;
virtual bool isTLS() const = 0;
virtual const char *mode() const = 0;
virtual const char *tlsFingerprint() const = 0;
virtual const char *tlsVersion() const = 0;
virtual const Job &job() const = 0;
virtual const Pool &pool() const = 0;
virtual const String &ip() const = 0;
virtual int id() const = 0;
virtual int64_t submit(const JobResult &result) = 0;
virtual void connect() = 0;
virtual void connect(const Pool &pool) = 0;
virtual void deleteLater() = 0;
virtual void setAlgo(const Algorithm &algo) = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void setPool(const Pool &pool) = 0;
virtual void setQuiet(bool quiet) = 0;
virtual void setRetries(int retries) = 0;
virtual void setRetryPause(uint64_t ms) = 0;
virtual void tick(uint64_t now) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ICLIENT_H

View File

@@ -29,10 +29,14 @@
#include <stdint.h>
#include "rapidjson/fwd.h"
namespace xmrig {
class Client;
class Algorithm;
class IClient;
class Job;
class SubmitResult;
@@ -42,10 +46,12 @@ class IClientListener
public:
virtual ~IClientListener() = default;
virtual void onClose(Client *client, int failures) = 0;
virtual void onJobReceived(Client *client, const Job &job) = 0;
virtual void onLoginSuccess(Client *client) = 0;
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
virtual void onClose(IClient *client, int failures) = 0;
virtual void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &params) = 0;
virtual void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value &params) = 0;
virtual void onLoginSuccess(IClient *client) = 0;
virtual void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) = 0;
virtual void onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) = 0;
};

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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ICONFIG_H
#define XMRIG_ICONFIG_H
#include "crypto/common/Algorithm.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class IJsonReader;
class String;
class IConfig
{
public:
enum Keys {
// common
AlgorithmKey = 'a',
ApiWorkerIdKey = 4002,
ApiIdKey = 4005,
HttpPort = 4100,
HttpAccessTokenKey = 4101,
HttpRestrictedKey = 4104,
HttpEnabledKey = 4106,
HttpHostKey = 4107,
BackgroundKey = 'B',
ColorKey = 1002,
ConfigKey = 'c',
DonateLevelKey = 1003,
KeepAliveKey = 'k',
LogFileKey = 'l',
PasswordKey = 'p',
RetriesKey = 'r',
RetryPauseKey = 'R',
RigIdKey = 1012,
SyslogKey = 'S',
UrlKey = 'o',
UserAgentKey = 1008,
UserKey = 'u',
UserpassKey = 'O',
VerboseKey = 1100,
TlsKey = 1013,
FingerprintKey = 1014,
ProxyDonateKey = 1017,
DaemonKey = 1018,
DaemonPollKey = 1019,
// xmrig common
CPUPriorityKey = 1021,
NicehashKey = 1006,
PrintTimeKey = 1007,
// xmrig cpu
AVKey = 'v',
CPUAffinityKey = 1020,
DryRunKey = 5000,
HugePagesKey = 1009,
ThreadsKey = 't',
AssemblyKey = 1015,
RandomXInitKey = 1022,
RandomXNumaKey = 1023,
// xmrig amd
OclPlatformKey = 1400,
OclAffinityKey = 1401,
OclDevicesKey = 1402,
OclLaunchKey = 1403,
OclCacheKey = 1404,
OclPrintKey = 1405,
OclLoaderKey = 1406,
OclSridedIndexKey = 1407,
OclMemChunkKey = 1408,
OclUnrollKey = 1409,
OclCompModeKey = 1410,
// xmrig-proxy
AccessLogFileKey = 'A',
BindKey = 'b',
CustomDiffKey = 1102,
DebugKey = 1101,
ModeKey = 'm',
PoolCoinKey = 'C',
ReuseTimeoutKey = 1106,
WorkersKey = 1103,
WorkersAdvKey = 1107,
TlsBindKey = 1108,
TlsCertKey = 1109,
TlsCertKeyKey = 1110,
TlsDHparamKey = 1111,
TlsCiphersKey = 1112,
TlsCipherSuitesKey = 1113,
TlsProtocolsKey = 1114,
AlgoExtKey = 1115,
ProxyPasswordKey = 1116,
// xmrig nvidia
CudaMaxThreadsKey = 1200,
CudaBFactorKey = 1201,
CudaBSleepKey = 1202,
CudaDevicesKey = 1203,
CudaLaunchKey = 1204,
CudaAffinityKey = 1205,
CudaMaxUsageKey = 1206,
};
virtual ~IConfig() = default;
virtual bool isWatch() const = 0;
virtual bool read(const IJsonReader &reader, const char *fileName) = 0;
virtual bool save() = 0;
virtual const String &fileName() const = 0;
virtual void getJSON(rapidjson::Document &doc) const = 0;
virtual void setFileName(const char *fileName) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ICONFIG_H

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 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ICONFIGTRANSFORM_H
#define XMRIG_ICONFIGTRANSFORM_H
#include "crypto/common/Algorithm.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class IJsonReader;
class String;
class IConfigTransform
{
public:
virtual ~IConfigTransform() = default;
virtual void finalize(rapidjson::Document &doc) = 0;
virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ICONFIGTRANSFORM_H

View File

@@ -0,0 +1,44 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ICONSOLELISTENER_H
#define XMRIG_ICONSOLELISTENER_H
namespace xmrig {
class IConsoleListener
{
public:
virtual ~IConsoleListener() = default;
virtual void onConsoleCommand(char command) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ICONSOLELISTENER_H

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 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IDNSLISTENER_H
#define XMRIG_IDNSLISTENER_H
namespace xmrig {
class Dns;
class IDnsListener
{
public:
virtual ~IDnsListener() = default;
virtual void onResolved(const Dns &dns, int status) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_IDNSLISTENER_H

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 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IHTTPLISTENER_H
#define XMRIG_IHTTPLISTENER_H
namespace xmrig {
class HttpData;
class HttpResponse;
class IHttpListener
{
public:
virtual ~IHttpListener() = default;
virtual void onHttpData(const HttpData &data) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_IHTTPLISTENER_H

View File

@@ -0,0 +1,56 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IJSONREADER_H
#define XMRIG_IJSONREADER_H
#include "rapidjson/fwd.h"
namespace xmrig {
class IJsonReader
{
public:
virtual ~IJsonReader() = default;
virtual bool getBool(const char *key, bool defaultValue = false) const = 0;
virtual bool isEmpty() const = 0;
virtual const char *getString(const char *key, const char *defaultValue = nullptr) const = 0;
virtual const rapidjson::Value &getArray(const char *key) const = 0;
virtual const rapidjson::Value &getObject(const char *key) const = 0;
virtual const rapidjson::Value &getValue(const char *key) const = 0;
virtual int getInt(const char *key, int defaultValue = 0) const = 0;
virtual int64_t getInt64(const char *key, int64_t defaultValue = 0) const = 0;
virtual uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const = 0;
virtual unsigned getUint(const char *key, unsigned defaultValue = 0) const = 0;
};
} /* namespace xmrig */
#endif // XMRIG_IJSONREADER_H

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HTTPREPLY_H__
#define __HTTPREPLY_H__
#ifndef XMRIG_ILINELISTENER_H
#define XMRIG_ILINELISTENER_H
#include <stdint.h>
@@ -32,22 +32,19 @@
namespace xmrig {
class HttpReply
class String;
class ILineListener
{
public:
HttpReply() :
buf(nullptr),
status(200),
size(0)
{}
virtual ~ILineListener() = default;
char *buf;
int status;
size_t size;
virtual void onLine(char *line, size_t size) = 0;
};
} /* namespace xmrig */
#endif /* __HTTPREPLY_H__ */
#endif // XMRIG_ILINELISTENER_H

View File

@@ -0,0 +1,49 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ILOGBACKEND_H
#define XMRIG_ILOGBACKEND_H
#include <stdarg.h>
#include <stddef.h>
namespace xmrig {
class ILogBackend
{
public:
virtual ~ILogBackend() = default;
virtual void print(int level, const char *line, size_t offset, size_t size, bool colors) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ILOGBACKEND_H

View File

@@ -29,13 +29,12 @@
#include <stdint.h>
class JobResult;
namespace xmrig {
class Algorithm;
class IClient;
class JobResult;
class IStrategy
@@ -44,6 +43,7 @@ public:
virtual ~IStrategy() = default;
virtual bool isActive() const = 0;
virtual IClient *client() const = 0;
virtual int64_t submit(const JobResult &result) = 0;
virtual void connect() = 0;
virtual void resume() = 0;

View File

@@ -26,13 +26,14 @@
#define XMRIG_ISTRATEGYLISTENER_H
#include <stdint.h>
#include "rapidjson/fwd.h"
namespace xmrig {
class Client;
class Algorithm;
class IClient;
class IStrategy;
class Job;
class SubmitResult;
@@ -43,10 +44,12 @@ class IStrategyListener
public:
virtual ~IStrategyListener() = default;
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;
virtual void onActive(IStrategy *strategy, IClient *client) = 0;
virtual void onJob(IStrategy *strategy, IClient *client, const Job &job) = 0;
virtual void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value &params) = 0;
virtual void onPause(IStrategy *strategy) = 0;
virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0;
virtual void onVerifyAlgorithm(IStrategy *strategy, const IClient *client, const Algorithm &algorithm, bool *ok) = 0;
};

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 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ITCPSERVERLISTENER_H
#define XMRIG_ITCPSERVERLISTENER_H
#include <stdint.h>
typedef struct uv_stream_s uv_stream_t;
namespace xmrig {
class String;
class ITcpServerListener
{
public:
virtual ~ITcpServerListener() = default;
virtual void onConnection(uv_stream_t *stream, uint16_t port) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ITCPSERVERLISTENER_H

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 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ITIMERLISTENER_H
#define XMRIG_ITIMERLISTENER_H
namespace xmrig {
class Timer;
class ITimerListener
{
public:
virtual ~ITimerListener() = default;
virtual void onTimer(const Timer *timer) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_ITIMERLISTENER_H

View File

@@ -1,505 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "base/io/Json.h"
#include "base/net/Pool.h"
#include "rapidjson/document.h"
#ifdef APP_DEBUG
# include "common/log/Log.h"
#endif
#ifdef _MSC_VER
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
#endif
namespace xmrig {
static const char *kEnabled = "enabled";
static const char *kFingerprint = "tls-fingerprint";
static const char *kKeepalive = "keepalive";
static const char *kNicehash = "nicehash";
static const char *kPass = "pass";
static const char *kRigId = "rig-id";
static const char *kTls = "tls";
static const char *kUrl = "url";
static const char *kUser = "user";
static const char *kVariant = "variant";
}
xmrig::Pool::Pool() :
m_enabled(true),
m_nicehash(false),
m_tls(false),
m_keepAlive(0),
m_port(kDefaultPort)
{
}
/**
* @brief Parse url.
*
* Valid urls:
* example.com
* example.com:3333
* stratum+tcp://example.com
* stratum+tcp://example.com:3333
*
* @param url
*/
xmrig::Pool::Pool(const char *url) :
m_enabled(true),
m_nicehash(false),
m_tls(false),
m_keepAlive(0),
m_port(kDefaultPort)
{
parse(url);
}
xmrig::Pool::Pool(const rapidjson::Value &object) :
m_enabled(true),
m_nicehash(false),
m_tls(false),
m_keepAlive(0),
m_port(kDefaultPort)
{
if (!parse(Json::getString(object, kUrl))) {
return;
}
setUser(Json::getString(object, kUser));
setPassword(Json::getString(object, kPass));
setRigId(Json::getString(object, kRigId));
setNicehash(Json::getBool(object, kNicehash));
const rapidjson::Value &keepalive = object[kKeepalive];
if (keepalive.IsInt()) {
setKeepAlive(keepalive.GetInt());
}
else if (keepalive.IsBool()) {
setKeepAlive(keepalive.GetBool());
}
const rapidjson::Value &variant = object[kVariant];
if (variant.IsString()) {
algorithm().parseVariant(variant.GetString());
}
else if (variant.IsInt()) {
algorithm().parseVariant(variant.GetInt());
}
m_enabled = Json::getBool(object, kEnabled, true);
m_tls = Json::getBool(object, kTls);
m_fingerprint = Json::getString(object, kFingerprint);
}
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) :
m_enabled(true),
m_nicehash(nicehash),
m_tls(tls),
m_keepAlive(keepAlive),
m_host(host),
m_password(password),
m_user(user),
m_port(port)
{
const size_t size = m_host.size() + 8;
assert(size > 8);
char *url = new char[size]();
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
m_url = url;
}
bool xmrig::Pool::isCompatible(const Algorithm &algorithm) const
{
if (m_algorithms.empty()) {
return true;
}
for (const auto &a : m_algorithms) {
if (algorithm == a) {
return true;
}
}
# ifdef XMRIG_PROXY_PROJECT
if (m_algorithm.algo() == xmrig::CRYPTONIGHT && algorithm.algo() == xmrig::CRYPTONIGHT) {
return m_algorithm.variant() == xmrig::VARIANT_RWZ || m_algorithm.variant() == xmrig::VARIANT_ZLS;
}
# endif
return false;
}
bool xmrig::Pool::isEnabled() const
{
# ifdef XMRIG_NO_TLS
if (isTLS()) {
return false;
}
# endif
return m_enabled && isValid() && algorithm().isValid();
}
bool xmrig::Pool::isEqual(const Pool &other) const
{
return (m_nicehash == other.m_nicehash
&& m_enabled == other.m_enabled
&& m_tls == other.m_tls
&& m_keepAlive == other.m_keepAlive
&& m_port == other.m_port
&& m_algorithm == other.m_algorithm
&& m_fingerprint == other.m_fingerprint
&& m_host == other.m_host
&& m_password == other.m_password
&& m_rigId == other.m_rigId
&& m_url == other.m_url
&& m_user == other.m_user);
}
bool xmrig::Pool::parse(const char *url)
{
assert(url != nullptr);
const char *p = strstr(url, "://");
const char *base = url;
if (p) {
if (strncasecmp(url, "stratum+tcp://", 14) == 0) {
m_tls = false;
}
else if (strncasecmp(url, "stratum+ssl://", 14) == 0) {
m_tls = true;
}
else {
return false;
}
base = url + 14;
}
if (!strlen(base) || *base == '/') {
return false;
}
m_url = url;
if (base[0] == '[') {
return parseIPv6(base);
}
const char *port = strchr(base, ':');
if (!port) {
m_host = base;
return true;
}
const size_t size = static_cast<size_t>(port++ - base + 1);
char *host = new char[size]();
memcpy(host, base, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port, nullptr, 10));
return true;
}
bool xmrig::Pool::setUserpass(const char *userpass)
{
const char *p = strchr(userpass, ':');
if (!p) {
return false;
}
char *user = new char[p - userpass + 1]();
strncpy(user, userpass, static_cast<size_t>(p - userpass));
m_user = user;
m_password = p + 1;
return true;
}
rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value obj(kObjectType);
obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator);
obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator);
obj.AddMember(StringRef(kPass), m_password.toJSON(), allocator);
obj.AddMember(StringRef(kRigId), m_rigId.toJSON(), allocator);
# ifndef XMRIG_PROXY_PROJECT
obj.AddMember(StringRef(kNicehash), isNicehash(), allocator);
# endif
if (m_keepAlive == 0 || m_keepAlive == kKeepAliveTimeout) {
obj.AddMember(StringRef(kKeepalive), m_keepAlive > 0, allocator);
}
else {
obj.AddMember(StringRef(kKeepalive), m_keepAlive, allocator);
}
switch (m_algorithm.variant()) {
case VARIANT_AUTO:
case VARIANT_0:
case VARIANT_1:
obj.AddMember(StringRef(kVariant), m_algorithm.variant(), allocator);
break;
case VARIANT_2:
obj.AddMember(StringRef(kVariant), 2, allocator);
break;
default:
obj.AddMember(StringRef(kVariant), StringRef(m_algorithm.variantName()), allocator);
break;
}
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kTls), isTLS(), allocator);
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
return obj;
}
void xmrig::Pool::adjust(const Algorithm &algorithm)
{
if (!isValid()) {
return;
}
if (!m_algorithm.isValid()) {
m_algorithm.setAlgo(algorithm.algo());
adjustVariant(algorithm.variant());
}
rebuild();
}
void xmrig::Pool::setAlgo(const xmrig::Algorithm &algorithm)
{
m_algorithm = algorithm;
rebuild();
}
#ifdef APP_DEBUG
void xmrig::Pool::print() const
{
LOG_NOTICE("url: %s", m_url.data());
LOG_DEBUG ("host: %s", m_host.data());
LOG_DEBUG ("port: %d", static_cast<int>(m_port));
LOG_DEBUG ("user: %s", m_user.data());
LOG_DEBUG ("pass: %s", m_password.data());
LOG_DEBUG ("rig-id %s", m_rigId.data());
LOG_DEBUG ("algo: %s", m_algorithm.name());
LOG_DEBUG ("nicehash: %d", static_cast<int>(m_nicehash));
LOG_DEBUG ("keepAlive: %d", m_keepAlive);
}
#endif
bool xmrig::Pool::parseIPv6(const char *addr)
{
const char *end = strchr(addr, ']');
if (!end) {
return false;
}
const char *port = strchr(end, ':');
if (!port) {
return false;
}
const size_t size = static_cast<size_t>(end - addr);
char *host = new char[size]();
memcpy(host, addr + 1, size - 1);
m_host = host;
m_port = static_cast<uint16_t>(strtol(port + 1, nullptr, 10));
return true;
}
void xmrig::Pool::addVariant(xmrig::Variant variant)
{
const xmrig::Algorithm algorithm(m_algorithm.algo(), variant);
if (!algorithm.isValid() || m_algorithm == algorithm) {
return;
}
m_algorithms.push_back(algorithm);
}
void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint)
{
# ifndef XMRIG_PROXY_PROJECT
using namespace xmrig;
if (m_host.contains(".nicehash.com")) {
m_keepAlive = false;
m_nicehash = true;
bool valid = true;
switch (m_port) {
case 3355:
case 33355:
valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonight.");
m_algorithm.setVariant(VARIANT_0);
break;
case 3363:
case 33363:
valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonightv7.");
m_algorithm.setVariant(VARIANT_1);
break;
case 3364:
valid = m_algorithm.algo() == CRYPTONIGHT_HEAVY && m_host.contains("cryptonightheavy.");
m_algorithm.setVariant(VARIANT_0);
break;
case 3367:
case 33367:
valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonightv8.");
m_algorithm.setVariant(VARIANT_2);
break;
default:
break;
}
if (!valid) {
m_algorithm.setAlgo(INVALID_ALGO);
}
m_tls = m_port > 33000;
return;
}
if (m_host.contains(".minergate.com")) {
m_keepAlive = false;
bool valid = true;
m_algorithm.setVariant(VARIANT_1);
if (m_host.contains("xmr.pool.")) {
valid = m_algorithm.algo() == CRYPTONIGHT;
m_algorithm.setVariant(m_port == 45700 ? VARIANT_AUTO : VARIANT_0);
}
else if (m_host.contains("aeon.pool.") && m_port == 45690) {
valid = m_algorithm.algo() == CRYPTONIGHT_LITE;
m_algorithm.setVariant(VARIANT_1);
}
if (!valid) {
m_algorithm.setAlgo(INVALID_ALGO);
}
return;
}
if (variantHint != VARIANT_AUTO) {
m_algorithm.setVariant(variantHint);
return;
}
if (m_algorithm.variant() != VARIANT_AUTO) {
return;
}
if (m_algorithm.algo() == CRYPTONIGHT_HEAVY) {
m_algorithm.setVariant(VARIANT_0);
}
else if (m_algorithm.algo() == CRYPTONIGHT_LITE) {
m_algorithm.setVariant(VARIANT_1);
}
# endif
}
void xmrig::Pool::rebuild()
{
m_algorithms.clear();
if (!m_algorithm.isValid()) {
return;
}
m_algorithms.push_back(m_algorithm);
# ifndef XMRIG_PROXY_PROJECT
addVariant(VARIANT_4);
addVariant(VARIANT_WOW);
addVariant(VARIANT_2);
addVariant(VARIANT_1);
addVariant(VARIANT_0);
addVariant(VARIANT_HALF);
addVariant(VARIANT_XTL);
addVariant(VARIANT_TUBE);
addVariant(VARIANT_MSR);
addVariant(VARIANT_XHV);
addVariant(VARIANT_XAO);
addVariant(VARIANT_RTO);
addVariant(VARIANT_GPU);
addVariant(VARIANT_RWZ);
addVariant(VARIANT_ZLS);
addVariant(VARIANT_DOUBLE);
addVariant(VARIANT_AUTO);
# endif
}

163
src/base/net/dns/Dns.cpp Normal file
View File

@@ -0,0 +1,163 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/kernel/interfaces/IDnsListener.h"
#include "base/net/dns/Dns.h"
#include "base/tools/Handle.h"
namespace xmrig {
Storage<Dns> Dns::m_storage;
static const DnsRecord defaultRecord;
}
xmrig::Dns::Dns(IDnsListener *listener) :
m_hints(),
m_listener(listener),
m_status(0),
m_resolver(nullptr)
{
m_key = m_storage.add(this);
m_resolver = new uv_getaddrinfo_t;
m_resolver->data = m_storage.ptr(m_key);
m_hints.ai_family = AF_UNSPEC;
m_hints.ai_socktype = SOCK_STREAM;
m_hints.ai_protocol = IPPROTO_TCP;
}
xmrig::Dns::~Dns()
{
m_storage.release(m_key);
delete m_resolver;
}
bool xmrig::Dns::resolve(const String &host)
{
if (m_host != host) {
m_host = host;
clear();
}
m_status = uv_getaddrinfo(uv_default_loop(), m_resolver, Dns::onResolved, m_host.data(), nullptr, &m_hints);
return m_status == 0;
}
const char *xmrig::Dns::error() const
{
return uv_strerror(m_status);
}
const xmrig::DnsRecord &xmrig::Dns::get(DnsRecord::Type prefered) const
{
if (count() == 0) {
return defaultRecord;
}
const size_t ipv4 = m_ipv4.size();
const size_t ipv6 = m_ipv6.size();
if (ipv6 && (prefered == DnsRecord::AAAA || !ipv4)) {
return m_ipv6[ipv6 == 1 ? 0 : static_cast<size_t>(rand()) % ipv6];
}
if (ipv4) {
return m_ipv4[ipv4 == 1 ? 0 : static_cast<size_t>(rand()) % ipv4];
}
return defaultRecord;
}
size_t xmrig::Dns::count(DnsRecord::Type type) const
{
if (type == DnsRecord::A) {
return m_ipv4.size();
}
if (type == DnsRecord::AAAA) {
return m_ipv6.size();
}
return m_ipv4.size() + m_ipv6.size();
}
void xmrig::Dns::clear()
{
m_ipv4.clear();
m_ipv6.clear();
}
void xmrig::Dns::onResolved(int status, addrinfo *res)
{
m_status = status;
if (m_status < 0) {
return m_listener->onResolved(*this, status);
}
clear();
addrinfo *ptr = res;
while (ptr != nullptr) {
if (ptr->ai_family == AF_INET) {
m_ipv4.push_back(ptr);
}
if (ptr->ai_family == AF_INET6) {
m_ipv6.push_back(ptr);
}
ptr = ptr->ai_next;
}
if (isEmpty()) {
m_status = UV_EAI_NONAME;
}
m_listener->onResolved(*this, m_status);
}
void xmrig::Dns::onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res)
{
Dns *dns = m_storage.get(req->data);
if (dns) {
dns->onResolved(status, res);
}
uv_freeaddrinfo(res);
}

81
src/base/net/dns/Dns.h Normal file
View File

@@ -0,0 +1,81 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DNS_H
#define XMRIG_DNS_H
#include <vector>
#include <uv.h>
#include "base/net/dns/DnsRecord.h"
#include "base/net/tools/Storage.h"
#include "base/tools/String.h"
namespace xmrig {
class IDnsListener;
class Dns
{
public:
Dns(IDnsListener *listener);
~Dns();
inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); }
inline const String &host() const { return m_host; }
inline int status() const { return m_status; }
bool resolve(const String &host);
const char *error() const;
const DnsRecord &get(DnsRecord::Type prefered = DnsRecord::A) const;
size_t count(DnsRecord::Type type = DnsRecord::Unknown) const;
private:
void clear();
void onResolved(int status, addrinfo *res);
static void onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res);
addrinfo m_hints;
IDnsListener *m_listener;
int m_status;
std::vector<DnsRecord> m_ipv4;
std::vector<DnsRecord> m_ipv6;
String m_host;
uintptr_t m_key;
uv_getaddrinfo_t *m_resolver;
static Storage<Dns> m_storage;
};
} /* namespace xmrig */
#endif /* XMRIG_DNS_H */

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 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <uv.h>
#include "base/net/dns/DnsRecord.h"
xmrig::DnsRecord::DnsRecord(const addrinfo *addr) :
m_type(addr->ai_family == AF_INET6 ? AAAA : A)
{
char *buf = nullptr;
if (m_type == AAAA) {
buf = new char[45]();
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), buf, 45);
}
else {
buf = new char[16]();
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), buf, 16);
}
m_ip = buf;
}
sockaddr *xmrig::DnsRecord::addr(uint16_t port) const
{
if (m_type == A) {
sockaddr_in *addr = new sockaddr_in();
uv_ip4_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
}
else if (m_type == AAAA) {
sockaddr_in6 *addr = new sockaddr_in6();
uv_ip6_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr);
}
return nullptr;
}

View File

@@ -22,42 +22,45 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CONFIGWATCHER_H
#define XMRIG_CONFIGWATCHER_H
#ifndef XMRIG_DNSRECORD_H
#define XMRIG_DNSRECORD_H
struct addrinfo;
struct sockaddr;
#include "base/kernel/interfaces/IWatcherListener.h"
#include "base/tools/String.h"
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class IConfigCreator;
class IConfigListener;
class Watcher;
class ConfigWatcher : public IWatcherListener
class DnsRecord
{
public:
ConfigWatcher(const String &path, IConfigCreator *creator, IConfigListener *listener);
~ConfigWatcher() override;
enum Type {
Unknown,
A,
AAAA
};
protected:
void onFileChanged(const String &fileName) override;
inline DnsRecord() : m_type(Unknown) {}
DnsRecord(const addrinfo *addr);
sockaddr *addr(uint16_t port = 0) const;
inline bool isValid() const { return m_type != Unknown; }
inline const String &ip() const { return m_ip; }
inline Type type() const { return m_type; }
private:
IConfigCreator *m_creator;
IConfigListener *m_listener;
Watcher *m_watcher;
Type m_type;
String m_ip;
};
} /* namespace xmrig */
#endif /* __CONFIGWATCHER_H__ */
#endif /* XMRIG_DNSRECORD_H */

View File

@@ -0,0 +1,99 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "3rdparty/rapidjson/document.h"
#include "base/io/json/Json.h"
#include "base/net/http/Http.h"
namespace xmrig {
static const char *kEnabled = "enabled";
static const char *kHost = "host";
static const char *kLocalhost = "127.0.0.1";
static const char *kPort = "port";
static const char *kRestricted = "restricted";
static const char *kToken = "access-token";
}
xmrig::Http::Http() :
m_enabled(false),
m_restricted(true),
m_host(kLocalhost),
m_port(0)
{
}
bool xmrig::Http::isEqual(const Http &other) const
{
return other.m_enabled == m_enabled &&
other.m_restricted == m_restricted &&
other.m_host == m_host &&
other.m_token == m_token &&
other.m_port == m_port;
}
rapidjson::Value xmrig::Http::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value obj(kObjectType);
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kHost), m_host.toJSON(), allocator);
obj.AddMember(StringRef(kPort), m_port, allocator);
obj.AddMember(StringRef(kToken), m_token.toJSON(), allocator);
obj.AddMember(StringRef(kRestricted), m_restricted, allocator);
return obj;
}
void xmrig::Http::load(const rapidjson::Value &http)
{
if (!http.IsObject()) {
return;
}
m_enabled = Json::getBool(http, kEnabled);
m_restricted = Json::getBool(http, kRestricted, true);
m_host = Json::getString(http, kHost, kLocalhost);
m_token = Json::getString(http, kToken);
setPort(Json::getInt(http, kPort));
}
void xmrig::Http::setPort(int port)
{
if (port >= 0 && port <= 65536) {
m_port = static_cast<uint16_t>(port);
}
}

73
src/base/net/http/Http.h Normal file
View File

@@ -0,0 +1,73 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTP_H
#define XMRIG_HTTP_H
#include "base/tools/String.h"
namespace xmrig {
class Http
{
public:
Http();
inline bool isAuthRequired() const { return m_restricted == false || !m_token.isNull(); }
inline bool isEnabled() const { return m_enabled; }
inline bool isRestricted() const { return m_restricted; }
inline const String &host() const { return m_host; }
inline const String &token() const { return m_token; }
inline uint16_t port() const { return m_port; }
inline void setEnabled(bool enabled) { m_enabled = enabled; }
inline void setHost(const char *host) { m_host = host; }
inline void setRestricted(bool restricted) { m_restricted = restricted; }
inline void setToken(const char *token) { m_token = token; }
inline bool operator!=(const Http &other) const { return !isEqual(other); }
inline bool operator==(const Http &other) const { return isEqual(other); }
bool isEqual(const Http &other) const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
void load(const rapidjson::Value &http);
void setPort(int port);
private:
bool m_enabled;
bool m_restricted;
String m_host;
String m_token;
uint16_t m_port;
};
} // namespace xmrig
#endif // XMRIG_HTTP_H

View File

@@ -0,0 +1,88 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "3rdparty/http-parser/http_parser.h"
#include "base/net/http/HttpApiResponse.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
namespace xmrig {
static const char *kError = "error";
static const char *kStatus = "status";
} // namespace xmrig
xmrig::HttpApiResponse::HttpApiResponse(uint64_t id) :
HttpResponse(id),
m_doc(rapidjson::kObjectType)
{
}
xmrig::HttpApiResponse::HttpApiResponse(uint64_t id, int status) :
HttpResponse(id),
m_doc(rapidjson::kObjectType)
{
setStatus(status);
}
void xmrig::HttpApiResponse::end()
{
using namespace rapidjson;
setHeader("Access-Control-Allow-Origin", "*");
setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
if (statusCode() >= 400) {
if (!m_doc.HasMember(kStatus)) {
m_doc.AddMember(StringRef(kStatus), statusCode(), m_doc.GetAllocator());
}
if (!m_doc.HasMember(kError)) {
m_doc.AddMember(StringRef(kError), StringRef(http_status_str(static_cast<http_status>(statusCode()))), m_doc.GetAllocator());
}
}
if (!m_doc.MemberCount()) {
return HttpResponse::end();
}
setHeader("Content-Type", "application/json");
StringBuffer buffer(nullptr, 4096);
PrettyWriter<StringBuffer> writer(buffer);
writer.SetMaxDecimalPlaces(10);
writer.SetFormatOptions(kFormatSingleLineArray);
m_doc.Accept(writer);
HttpResponse::end(buffer.GetString(), buffer.GetSize());
}

View File

@@ -0,0 +1,57 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPAPIRESPONSE_H
#define XMRIG_HTTPAPIRESPONSE_H
#include "base/net/http/HttpResponse.h"
#include "rapidjson/document.h"
namespace xmrig {
class HttpApiResponse : public HttpResponse
{
public:
HttpApiResponse(uint64_t id);
HttpApiResponse(uint64_t id, int status);
inline rapidjson::Document &doc() { return m_doc; }
void end();
private:
rapidjson::Document m_doc;
};
} // namespace xmrig
#endif // XMRIG_HTTPAPIRESPONSE_H

View File

@@ -0,0 +1,224 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sstream>
#include "3rdparty/http-parser/http_parser.h"
#include "base/io/log/Log.h"
#include "base/kernel/Platform.h"
#include "base/net/dns/Dns.h"
#include "base/net/http/HttpClient.h"
#include "base/tools/Baton.h"
namespace xmrig {
static const char *kCRLF = "\r\n";
class ClientWriteBaton : public Baton<uv_write_t>
{
public:
inline ClientWriteBaton(const std::string &header, std::string &&body) :
m_body(std::move(body)),
m_header(header)
{
bufs[0].len = m_header.size();
bufs[0].base = const_cast<char *>(m_header.c_str());
if (!m_body.empty()) {
bufs[1].len = m_body.size();
bufs[1].base = const_cast<char *>(m_body.c_str());
}
else {
bufs[1].base = nullptr;
bufs[1].len = 0;
}
}
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
inline size_t size() const { return bufs[0].len + bufs[1].len; }
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<ClientWriteBaton *>(req->data); }
uv_buf_t bufs[2];
private:
std::string m_body;
std::string m_header;
};
} // namespace xmrig
xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
HttpContext(HTTP_RESPONSE, listener),
m_quiet(false),
m_port(0)
{
this->method = method;
this->url = url;
if (data) {
body = size ? std::string(data, size) : data;
}
m_dns = new Dns(this);
}
xmrig::HttpClient::~HttpClient()
{
delete m_dns;
}
bool xmrig::HttpClient::connect(const String &host, uint16_t port)
{
m_port = port;
return m_dns->resolve(host);
}
const xmrig::String &xmrig::HttpClient::host() const
{
return m_dns->host();
}
void xmrig::HttpClient::onResolved(const Dns &dns, int status)
{
this->status = status;
if (status < 0 && dns.isEmpty()) {
if (!m_quiet) {
LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), m_port, uv_strerror(status));
}
return;
}
sockaddr *addr = dns.get().addr(m_port);
uv_connect_t *req = new uv_connect_t;
req->data = this;
uv_tcp_connect(req, m_tcp, addr, onConnect);
}
void xmrig::HttpClient::handshake()
{
headers.insert({ "Host", m_dns->host().data() });
headers.insert({ "Connection", "close" });
headers.insert({ "User-Agent", Platform::userAgent() });
if (body.size()) {
headers.insert({ "Content-Length", std::to_string(body.size()) });
}
std::stringstream ss;
ss << http_method_str(static_cast<http_method>(method)) << " " << url << " HTTP/1.1" << kCRLF;
for (auto &header : headers) {
ss << header.first << ": " << header.second << kCRLF;
}
ss << kCRLF;
headers.clear();
write(ss.str());
}
void xmrig::HttpClient::read(const char *data, size_t size)
{
if (parse(data, size) < size) {
close(UV_EPROTO);
}
}
void xmrig::HttpClient::write(const std::string &header)
{
ClientWriteBaton *baton = new ClientWriteBaton(header, std::move(body));
uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite);
}
void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
{
HttpClient *client = static_cast<HttpClient *>(req->data);
if (!client) {
delete req;
return;
}
if (status < 0) {
if (!client->m_quiet) {
LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(status));
}
delete req;
client->close(status);
return;
}
uv_read_start(client->stream(),
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
{
buf->base = new char[suggested_size];
# ifdef _WIN32
buf->len = static_cast<unsigned int>(suggested_size);
# else
buf->len = suggested_size;
# endif
},
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
{
HttpClient *client = static_cast<HttpClient*>(tcp->data);
if (nread >= 0) {
client->read(buf->base, static_cast<size_t>(nread));
} else {
if (!client->m_quiet && nread != UV_EOF) {
LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(static_cast<int>(nread)));
}
client->close(static_cast<int>(nread));
}
delete [] buf->base;
});
client->handshake();
}

View File

@@ -0,0 +1,74 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPCLIENT_H
#define XMRIG_HTTPCLIENT_H
#include "base/net/http/HttpContext.h"
#include "base/kernel/interfaces/IDnsListener.h"
namespace xmrig {
class String;
class HttpClient : public HttpContext, public IDnsListener
{
public:
HttpClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0);
~HttpClient() override;
inline uint16_t port() const { return m_port; }
inline void setQuiet(bool quiet) { m_quiet = quiet; }
bool connect(const String &host, uint16_t port);
const String &host() const;
protected:
void onResolved(const Dns &dns, int status) override;
virtual void handshake();
virtual void read(const char *data, size_t size);
virtual void write(const std::string &header);
bool m_quiet;
private:
static void onConnect(uv_connect_t *req, int status);
Dns *m_dns;
uint16_t m_port;
};
} // namespace xmrig
#endif // XMRIG_HTTPCLIENT_H

View File

@@ -0,0 +1,228 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <uv.h>
#include "3rdparty/http-parser/http_parser.h"
#include "base/kernel/interfaces/IHttpListener.h"
#include "base/net/http/HttpContext.h"
namespace xmrig {
static http_parser_settings http_settings;
static std::map<uint64_t, HttpContext *> storage;
static uint64_t SEQUENCE = 0;
} // namespace xmrig
xmrig::HttpContext::HttpContext(int parser_type, IHttpListener *listener) :
HttpData(SEQUENCE++),
m_wasHeaderValue(false),
m_listener(listener)
{
storage[id()] = this;
m_parser = new http_parser;
m_tcp = new uv_tcp_t;
uv_tcp_init(uv_default_loop(), m_tcp);
uv_tcp_nodelay(m_tcp, 1);
http_parser_init(m_parser, static_cast<http_parser_type>(parser_type));
m_parser->data = m_tcp->data = this;
if (http_settings.on_message_complete == nullptr) {
attach(&http_settings);
}
}
xmrig::HttpContext::~HttpContext()
{
delete m_tcp;
delete m_parser;
}
size_t xmrig::HttpContext::parse(const char *data, size_t size)
{
return http_parser_execute(m_parser, &http_settings, data, size);
}
std::string xmrig::HttpContext::ip() const
{
char ip[46] = {};
sockaddr_storage addr = {};
int size = sizeof(addr);
uv_tcp_getpeername(m_tcp, reinterpret_cast<sockaddr*>(&addr), &size);
if (reinterpret_cast<sockaddr_in *>(&addr)->sin_family == AF_INET6) {
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(&addr), ip, 45);
}
else {
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), ip, 16);
}
return ip;
}
void xmrig::HttpContext::close(int status)
{
if (status < 0 && m_listener) {
this->status = status;
m_listener->onHttpData(*this);
}
auto it = storage.find(id());
if (it != storage.end()) {
storage.erase(it);
}
if (!uv_is_closing(handle())) {
uv_close(handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); });
}
}
xmrig::HttpContext *xmrig::HttpContext::get(uint64_t id)
{
if (storage.count(id) == 0) {
return nullptr;
}
return storage[id];
}
void xmrig::HttpContext::closeAll()
{
for (auto kv : storage) {
if (!uv_is_closing(kv.second->handle())) {
uv_close(kv.second->handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); });
}
}
}
int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_t length)
{
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
if (ctx->m_wasHeaderValue) {
if (!ctx->m_lastHeaderField.empty()) {
ctx->setHeader();
}
ctx->m_lastHeaderField = std::string(at, length);
ctx->m_wasHeaderValue = false;
} else {
ctx->m_lastHeaderField += std::string(at, length);
}
return 0;
}
int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_t length)
{
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
if (!ctx->m_wasHeaderValue) {
ctx->m_lastHeaderValue = std::string(at, length);
ctx->m_wasHeaderValue = true;
} else {
ctx->m_lastHeaderValue += std::string(at, length);
}
return 0;
}
void xmrig::HttpContext::attach(http_parser_settings *settings)
{
settings->on_message_begin = nullptr;
settings->on_status = nullptr;
settings->on_chunk_header = nullptr;
settings->on_chunk_complete = nullptr;
settings->on_url = [](http_parser *parser, const char *at, size_t length) -> int
{
static_cast<HttpContext*>(parser->data)->url = std::string(at, length);
return 0;
};
settings->on_header_field = onHeaderField;
settings->on_header_value = onHeaderValue;
settings->on_headers_complete = [](http_parser* parser) -> int {
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
ctx->status = parser->status_code;
if (parser->type == HTTP_REQUEST) {
ctx->method = parser->method;
}
if (!ctx->m_lastHeaderField.empty()) {
ctx->setHeader();
}
return 0;
};
settings->on_body = [](http_parser *parser, const char *at, size_t len) -> int
{
static_cast<HttpContext*>(parser->data)->body += std::string(at, len);
return 0;
};
settings->on_message_complete = [](http_parser *parser) -> int
{
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
ctx->m_listener->onHttpData(*ctx);
ctx->m_listener = nullptr;
return 0;
};
}
void xmrig::HttpContext::setHeader()
{
std::transform(m_lastHeaderField.begin(), m_lastHeaderField.end(), m_lastHeaderField.begin(), ::tolower);
headers.insert({ m_lastHeaderField, m_lastHeaderValue });
m_lastHeaderField.clear();
m_lastHeaderValue.clear();
}

View File

@@ -0,0 +1,86 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPCONTEXT_H
#define XMRIG_HTTPCONTEXT_H
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
typedef struct uv_connect_s uv_connect_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tcp_s uv_tcp_t;
#include "base/net/http/HttpData.h"
namespace xmrig {
class IHttpListener;
class HttpContext : public HttpData
{
public:
HttpContext(int parser_type, IHttpListener *listener);
virtual ~HttpContext();
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_tcp); }
inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(m_tcp); }
size_t parse(const char *data, size_t size);
std::string ip() const;
void close(int status = 0);
static HttpContext *get(uint64_t id);
static void closeAll();
protected:
uv_tcp_t *m_tcp;
private:
static int onHeaderField(http_parser *parser, const char *at, size_t length);
static int onHeaderValue(http_parser *parser, const char *at, size_t length);
static void attach(http_parser_settings *settings);
void setHeader();
bool m_wasHeaderValue;
http_parser *m_parser;
IHttpListener *m_listener;
std::string m_lastHeaderField;
std::string m_lastHeaderValue;
};
} // namespace xmrig
#endif // XMRIG_HTTPCONTEXT_H

View File

@@ -0,0 +1,60 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPDATA_H
#define XMRIG_HTTPDATA_H
#include <map>
#include <string>
namespace xmrig {
class HttpData
{
public:
inline HttpData(uint64_t id) : method(0), status(0), m_id(id) {}
inline uint64_t id() const { return m_id; }
int method;
int status;
std::map<const std::string, const std::string> headers;
std::string body;
std::string url;
private:
const uint64_t m_id;
};
} // namespace xmrig
#endif // XMRIG_HTTPDATA_H

View File

@@ -0,0 +1,153 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sstream>
#include <string.h>
#include <uv.h>
#include "3rdparty/http-parser/http_parser.h"
#include "base/io/log/Log.h"
#include "base/net/http/HttpContext.h"
#include "base/net/http/HttpResponse.h"
#include "base/tools/Baton.h"
namespace xmrig {
static const char *kCRLF = "\r\n";
static const char *kUserAgent = "user-agent";
class WriteBaton : public Baton<uv_write_t>
{
public:
inline WriteBaton(const std::stringstream &ss, const char *data, size_t size, HttpContext *ctx) :
m_ctx(ctx),
m_header(ss.str())
{
bufs[0].len = m_header.size();
bufs[0].base = const_cast<char *>(m_header.c_str());
if (data) {
bufs[1].len = size;
bufs[1].base = new char[size];
memcpy(bufs[1].base, data, size);
}
else {
bufs[1].base = nullptr;
bufs[1].len = 0;
}
}
inline ~WriteBaton()
{
if (count() == 2) {
delete [] bufs[1].base;
}
m_ctx->close();
}
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
inline size_t size() const { return bufs[0].len + bufs[1].len; }
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<WriteBaton *>(req->data); }
uv_buf_t bufs[2];
private:
HttpContext *m_ctx;
std::string m_header;
};
} // namespace xmrig
xmrig::HttpResponse::HttpResponse(uint64_t id, int statusCode) :
m_id(id),
m_statusCode(statusCode)
{
}
bool xmrig::HttpResponse::isAlive() const
{
HttpContext *ctx = HttpContext::get(m_id);
return ctx && uv_is_writable(ctx->stream());
}
void xmrig::HttpResponse::end(const char *data, size_t size)
{
if (!isAlive()) {
return;
}
if (data && !size) {
size = strlen(data);
}
if (size) {
setHeader("Content-Length", std::to_string(size));
}
setHeader("Connection", "close");
std::stringstream ss;
ss << "HTTP/1.1 " << statusCode() << " " << http_status_str(static_cast<http_status>(statusCode())) << kCRLF;
for (auto &header : m_headers) {
ss << header.first << ": " << header.second << kCRLF;
}
ss << kCRLF;
HttpContext *ctx = HttpContext::get(m_id);
WriteBaton *baton = new WriteBaton(ss, data, size, ctx);
# ifndef APP_DEBUG
if (statusCode() >= 400)
# endif
{
const bool err = statusCode() >= 400;
Log::print(err ? Log::ERR : Log::INFO, CYAN("%s ") CLEAR MAGENTA_BOLD("%s") WHITE_BOLD(" %s ") CSI "1;%dm%d " CLEAR WHITE_BOLD("%zu ") BLACK_BOLD("\"%s\""),
ctx->ip().c_str(),
http_method_str(static_cast<http_method>(ctx->method)),
ctx->url.c_str(),
err ? 31 : 32,
statusCode(),
baton->size(),
ctx->headers.count(kUserAgent) ? ctx->headers.at(kUserAgent).c_str() : nullptr
);
}
uv_write(&baton->req, ctx->stream(), baton->bufs, baton->count(), WriteBaton::onWrite);
}

View File

@@ -0,0 +1,61 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPRESPONSE_H
#define XMRIG_HTTPRESPONSE_H
#include <map>
#include <string>
namespace xmrig {
class HttpResponse
{
public:
HttpResponse(uint64_t id, int statusCode = 200);
inline int statusCode() const { return m_statusCode; }
inline void setHeader(const std::string &key, const std::string &value) { m_headers.insert({ key, value }); }
inline void setStatus(int code) { m_statusCode = code; }
bool isAlive() const;
void end(const char *data = nullptr, size_t size = 0);
private:
const uint64_t m_id;
int m_statusCode;
std::map<const std::string, const std::string> m_headers;
};
} // namespace xmrig
#endif // XMRIG_HTTPRESPONSE_H

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 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <functional>
#include <uv.h>
#include "3rdparty/http-parser/http_parser.h"
#include "base/kernel/interfaces/IHttpListener.h"
#include "base/net/http/HttpContext.h"
#include "base/net/http/HttpResponse.h"
#include "base/net/http/HttpServer.h"
xmrig::HttpServer::HttpServer(IHttpListener *listener) :
m_listener(listener)
{
}
xmrig::HttpServer::~HttpServer()
{
HttpContext::closeAll();
}
void xmrig::HttpServer::onConnection(uv_stream_t *stream, uint16_t)
{
HttpContext *ctx = new HttpContext(HTTP_REQUEST, m_listener);
uv_accept(stream, ctx->stream());
uv_read_start(ctx->stream(),
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
{
buf->base = new char[suggested_size];
# ifdef _WIN32
buf->len = static_cast<unsigned int>(suggested_size);
# else
buf->len = suggested_size;
# endif
},
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
{
HttpContext *ctx = static_cast<HttpContext*>(tcp->data);
if (nread >= 0) {
const size_t size = static_cast<size_t>(nread);
const size_t parsed = ctx->parse(buf->base, size);
if (parsed < size) {
ctx->close();
}
} else {
ctx->close();
}
delete [] buf->base;
});
}

View File

@@ -0,0 +1,62 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPSERVER_H
#define XMRIG_HTTPSERVER_H
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
#include "base/kernel/interfaces/ITcpServerListener.h"
namespace xmrig {
class IHttpListener;
class HttpServer : public ITcpServerListener
{
public:
HttpServer(IHttpListener *listener);
~HttpServer() override;
protected:
void onConnection(uv_stream_t *stream, uint16_t port) override;
private:
IHttpListener *m_listener;
};
} // namespace xmrig
#endif // XMRIG_HTTPSERVER_H

View File

@@ -0,0 +1,208 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <openssl/ssl.h>
#include <uv.h>
#include "base/io/log/Log.h"
#include "base/net/http/HttpsClient.h"
#include "base/tools/Buffer.h"
#ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint) :
HttpClient(method, url, listener, data, size),
m_ready(false),
m_buf(),
m_ssl(nullptr),
m_fp(fingerprint)
{
m_ctx = SSL_CTX_new(SSLv23_method());
assert(m_ctx != nullptr);
if (!m_ctx) {
return;
}
m_writeBio = BIO_new(BIO_s_mem());
m_readBio = BIO_new(BIO_s_mem());
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
}
xmrig::HttpsClient::~HttpsClient()
{
if (m_ctx) {
SSL_CTX_free(m_ctx);
}
if (m_ssl) {
SSL_free(m_ssl);
}
}
const char *xmrig::HttpsClient::fingerprint() const
{
return m_ready ? m_fingerprint : nullptr;
}
const char *xmrig::HttpsClient::version() const
{
return m_ready ? SSL_get_version(m_ssl) : nullptr;
}
void xmrig::HttpsClient::handshake()
{
m_ssl = SSL_new(m_ctx);
assert(m_ssl != nullptr);
if (!m_ssl) {
return;
}
SSL_set_connect_state(m_ssl);
SSL_set_bio(m_ssl, m_readBio, m_writeBio);
SSL_set_tlsext_host_name(m_ssl, host().data());
SSL_do_handshake(m_ssl);
flush();
}
void xmrig::HttpsClient::read(const char *data, size_t size)
{
BIO_write(m_readBio, data, size);
if (!SSL_is_init_finished(m_ssl)) {
const int rc = SSL_connect(m_ssl);
if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
flush();
} else if (rc == 1) {
X509 *cert = SSL_get_peer_certificate(m_ssl);
if (!verify(cert)) {
X509_free(cert);
return close(UV_EPROTO);
}
X509_free(cert);
m_ready = true;
HttpClient::handshake();
}
return;
}
int bytes_read = 0;
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
HttpClient::read(m_buf, static_cast<size_t>(bytes_read));
}
}
void xmrig::HttpsClient::write(const std::string &header)
{
SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
body.clear();
flush();
}
bool xmrig::HttpsClient::verify(X509 *cert)
{
if (cert == nullptr) {
return false;
}
if (!verifyFingerprint(cert)) {
if (!m_quiet) {
LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port());
if (strlen(m_fingerprint) == 64 && !m_fp.isNull()) {
LOG_ERR("\"%s\" was given", m_fingerprint);
LOG_ERR("\"%s\" was configured", m_fp.data());
}
}
return false;
}
return true;
}
bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
{
const EVP_MD *digest = EVP_get_digestbyname("sha256");
if (digest == nullptr) {
return false;
}
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int dlen;
if (X509_digest(cert, digest, md, &dlen) != 1) {
return false;
}
Buffer::toHex(md, 32, m_fingerprint);
return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0;
}
void xmrig::HttpsClient::flush()
{
uv_buf_t buf;
buf.len = BIO_get_mem_data(m_writeBio, &buf.base);
if (buf.len == 0) {
return;
}
bool result = false;
if (uv_is_writable(stream())) {
result = uv_try_write(stream(), &buf, 1) == static_cast<int>(buf.len);
if (!result) {
close(UV_EIO);
}
}
(void) BIO_reset(m_writeBio);
}

Some files were not shown because too many files have changed in this diff Show More