mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-08 00:15:04 -05:00
Compare commits
108 Commits
v2.15.0-be
...
v2.15.4-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
277f188cd5 | ||
|
|
e28c3db019 | ||
|
|
5dde5dbf4e | ||
|
|
9726f8cf9d | ||
|
|
833a532e7a | ||
|
|
3dde8cacff | ||
|
|
84b359f29c | ||
|
|
2d8e8c92ab | ||
|
|
651009e1b9 | ||
|
|
1d4bc030fb | ||
|
|
809efb4700 | ||
|
|
10165da53e | ||
|
|
51b92f66cf | ||
|
|
6fb014d0b1 | ||
|
|
ffb282a11a | ||
|
|
a000544fdc | ||
|
|
378bc504fc | ||
|
|
304d7bd09a | ||
|
|
e9e2d7d152 | ||
|
|
8b0d35b619 | ||
|
|
e46a2a508a | ||
|
|
fe9aa9f3c4 | ||
|
|
552858b9e3 | ||
|
|
ff6544a14c | ||
|
|
d77e404439 | ||
|
|
ff4d54dc4c | ||
|
|
699269bbae | ||
|
|
9137f59ec1 | ||
|
|
f9f7ef26b8 | ||
|
|
32c3d4b9f6 | ||
|
|
ee1d61d117 | ||
|
|
a3b303e885 | ||
|
|
074b3869d2 | ||
|
|
c0e668f36f | ||
|
|
21798edb8b | ||
|
|
23b0e3799e | ||
|
|
83a7a88b11 | ||
|
|
60f6817d21 | ||
|
|
867478b983 | ||
|
|
5e369a5af8 | ||
|
|
62012a1a50 | ||
|
|
54a1c614f7 | ||
|
|
cf7ce13986 | ||
|
|
0d496aaf2f | ||
|
|
9a6944d694 | ||
|
|
1bd8d63508 | ||
|
|
c41889477c | ||
|
|
c823c54f9b | ||
|
|
6812d22d63 | ||
|
|
241383068c | ||
|
|
35d868fb48 | ||
|
|
d6da0652ce | ||
|
|
9561570c50 | ||
|
|
466aad8543 | ||
|
|
db456a3e63 | ||
|
|
09df8c3846 | ||
|
|
5d9648956b | ||
|
|
1774b42345 | ||
|
|
fa2a0b9b79 | ||
|
|
85ee55f309 | ||
|
|
4aa7f01f13 | ||
|
|
496870a59d | ||
|
|
89d7e84f88 | ||
|
|
29f683b01f | ||
|
|
1e3e8df43c | ||
|
|
1f45e77848 | ||
|
|
356fd04b0f | ||
|
|
5a4720cf4a | ||
|
|
c0e2a15614 | ||
|
|
cf7245b469 | ||
|
|
3b91817caf | ||
|
|
4457089502 | ||
|
|
40d9f53743 | ||
|
|
24e4328915 | ||
|
|
0245ce5f35 | ||
|
|
96f5bd32b5 | ||
|
|
e759ccf385 | ||
|
|
ca249f1f1c | ||
|
|
f8f9d6c0ef | ||
|
|
e39ddeeea2 | ||
|
|
d8aba7da7d | ||
|
|
bd6c7c64aa | ||
|
|
106e149324 | ||
|
|
c9f9e6787c | ||
|
|
9c66c9b30f | ||
|
|
dd036368e2 | ||
|
|
9cb43f9883 | ||
|
|
3f1eefb131 | ||
|
|
202b74367a | ||
|
|
9daa5874f5 | ||
|
|
01ad6bf2d9 | ||
|
|
725796a1ab | ||
|
|
1e0c410eea | ||
|
|
034720e888 | ||
|
|
22483dd231 | ||
|
|
5db458efd4 | ||
|
|
3f4886bb86 | ||
|
|
82bbef614e | ||
|
|
933c0d40b7 | ||
|
|
cad3e7a101 | ||
|
|
d7795ca990 | ||
|
|
ba910a46ba | ||
|
|
f43929db98 | ||
|
|
17e9e036f1 | ||
|
|
ced25c3fa0 | ||
|
|
0a893c2172 | ||
|
|
1f77b049e3 | ||
|
|
29373c4226 |
25
CHANGELOG.md
25
CHANGELOG.md
@@ -1,8 +1,33 @@
|
|||||||
|
# v2.15.4-beta
|
||||||
|
- Added global uptime and extended connection information in API.
|
||||||
|
- API now return current algorithm instead of global algorithm specified in config.
|
||||||
|
- This version also include all changes from stable version v2.14.4.
|
||||||
|
|
||||||
|
# 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).
|
||||||
|
- [#1012](https://github.com/xmrig/xmrig/pull/1012) Fixed compatibility with clang 9.
|
||||||
|
- 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
|
# v2.15.0-beta
|
||||||
- [#314](https://github.com/xmrig/xmrig-proxy/issues/314) Added donate over proxy feature.
|
- [#314](https://github.com/xmrig/xmrig-proxy/issues/314) Added donate over proxy feature.
|
||||||
- Added new option `donate-over-proxy`.
|
- Added new option `donate-over-proxy`.
|
||||||
- Added real graceful exit.
|
- Added real graceful exit.
|
||||||
|
|
||||||
|
# v2.14.4
|
||||||
|
- [#992](https://github.com/xmrig/xmrig/pull/992) Fixed compilation with Clang 3.5.
|
||||||
|
- [#1012](https://github.com/xmrig/xmrig/pull/1012) Fixed compilation with Clang 9.0.
|
||||||
|
- In HTTP API for unknown hashrate now used `null` instead of `0.0`.
|
||||||
|
- Fixed MSVC 2019 version detection.
|
||||||
|
- Removed obsolete automatic variants.
|
||||||
|
|
||||||
# v2.14.1
|
# v2.14.1
|
||||||
* [#975](https://github.com/xmrig/xmrig/issues/975) Fixed crash on Linux if double thread mode used.
|
* [#975](https://github.com/xmrig/xmrig/issues/975) Fixed crash on Linux if double thread mode used.
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ option(WITH_AEON "CryptoNight-Lite support" ON)
|
|||||||
option(WITH_SUMO "CryptoNight-Heavy support" ON)
|
option(WITH_SUMO "CryptoNight-Heavy support" ON)
|
||||||
option(WITH_CN_PICO "CryptoNight-Pico support" ON)
|
option(WITH_CN_PICO "CryptoNight-Pico support" ON)
|
||||||
option(WITH_CN_GPU "CryptoNight-GPU support" ON)
|
option(WITH_CN_GPU "CryptoNight-GPU support" ON)
|
||||||
option(WITH_HTTPD "HTTP REST API" ON)
|
option(WITH_HTTP "HTTP protocol support (client/server)" ON)
|
||||||
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
|
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
|
||||||
option(WITH_TLS "Enable OpenSSL support" ON)
|
option(WITH_TLS "Enable OpenSSL support" ON)
|
||||||
option(WITH_ASM "Enable ASM PoW implementations" ON)
|
option(WITH_ASM "Enable ASM PoW implementations" ON)
|
||||||
@@ -21,28 +21,21 @@ include (src/base/base.cmake)
|
|||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
"${HEADERS_BASE}"
|
"${HEADERS_BASE}"
|
||||||
src/api/NetworkState.h
|
"${HEADERS_BASE_HTTP}"
|
||||||
|
src/api/interfaces/IApiListener.h
|
||||||
src/App.h
|
src/App.h
|
||||||
src/common/config/CommonConfig.h
|
|
||||||
src/common/config/ConfigLoader.h
|
|
||||||
src/common/config/ConfigWatcher.h
|
|
||||||
src/common/cpu/Cpu.h
|
src/common/cpu/Cpu.h
|
||||||
src/common/crypto/Algorithm.h
|
src/common/crypto/Algorithm.h
|
||||||
src/common/crypto/keccak.h
|
src/common/crypto/keccak.h
|
||||||
src/common/interfaces/IConfig.h
|
|
||||||
src/common/interfaces/IConfigCreator.h
|
|
||||||
src/common/interfaces/IControllerListener.h
|
|
||||||
src/common/interfaces/ICpuInfo.h
|
src/common/interfaces/ICpuInfo.h
|
||||||
src/common/interfaces/ILogBackend.h
|
|
||||||
src/common/log/BasicLog.h
|
|
||||||
src/common/log/ConsoleLog.h
|
|
||||||
src/common/log/FileLog.h
|
|
||||||
src/common/log/Log.h
|
|
||||||
src/common/Platform.h
|
src/common/Platform.h
|
||||||
src/common/utils/mm_malloc.h
|
src/common/utils/mm_malloc.h
|
||||||
src/common/xmrig.h
|
src/common/xmrig.h
|
||||||
src/core/ConfigLoader_default.h
|
src/core/config/Config_default.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/Controller.h
|
||||||
src/interfaces/IJobResultListener.h
|
src/interfaces/IJobResultListener.h
|
||||||
src/interfaces/IThread.h
|
src/interfaces/IThread.h
|
||||||
@@ -50,13 +43,14 @@ set(HEADERS
|
|||||||
src/Mem.h
|
src/Mem.h
|
||||||
src/net/JobResult.h
|
src/net/JobResult.h
|
||||||
src/net/Network.h
|
src/net/Network.h
|
||||||
|
src/net/NetworkState.h
|
||||||
src/net/strategies/DonateStrategy.h
|
src/net/strategies/DonateStrategy.h
|
||||||
src/Summary.h
|
src/Summary.h
|
||||||
src/version.h
|
src/version.h
|
||||||
src/workers/CpuThread.h
|
src/workers/CpuThread.h
|
||||||
src/workers/ThreadHandle.h
|
|
||||||
src/workers/Hashrate.h
|
src/workers/Hashrate.h
|
||||||
src/workers/MultiWorker.h
|
src/workers/MultiWorker.h
|
||||||
|
src/workers/ThreadHandle.h
|
||||||
src/workers/Worker.h
|
src/workers/Worker.h
|
||||||
src/workers/Workers.h
|
src/workers/Workers.h
|
||||||
)
|
)
|
||||||
@@ -85,28 +79,23 @@ endif()
|
|||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
"${SOURCES_BASE}"
|
"${SOURCES_BASE}"
|
||||||
src/api/NetworkState.cpp
|
"${SOURCES_BASE_HTTP}"
|
||||||
src/App.cpp
|
src/App.cpp
|
||||||
src/common/config/CommonConfig.cpp
|
|
||||||
src/common/config/ConfigLoader.cpp
|
|
||||||
src/common/config/ConfigWatcher.cpp
|
|
||||||
src/common/crypto/Algorithm.cpp
|
src/common/crypto/Algorithm.cpp
|
||||||
src/common/crypto/keccak.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/Platform.cpp
|
src/common/Platform.cpp
|
||||||
src/core/Config.cpp
|
src/core/config/Config.cpp
|
||||||
|
src/core/config/ConfigTransform.cpp
|
||||||
src/core/Controller.cpp
|
src/core/Controller.cpp
|
||||||
src/Mem.cpp
|
src/Mem.cpp
|
||||||
src/net/Network.cpp
|
src/net/Network.cpp
|
||||||
|
src/net/NetworkState.cpp
|
||||||
src/net/strategies/DonateStrategy.cpp
|
src/net/strategies/DonateStrategy.cpp
|
||||||
src/Summary.cpp
|
src/Summary.cpp
|
||||||
src/workers/CpuThread.cpp
|
src/workers/CpuThread.cpp
|
||||||
src/workers/ThreadHandle.cpp
|
|
||||||
src/workers/Hashrate.cpp
|
src/workers/Hashrate.cpp
|
||||||
src/workers/MultiWorker.cpp
|
src/workers/MultiWorker.cpp
|
||||||
|
src/workers/ThreadHandle.cpp
|
||||||
src/workers/Worker.cpp
|
src/workers/Worker.cpp
|
||||||
src/workers/Workers.cpp
|
src/workers/Workers.cpp
|
||||||
src/xmrig.cpp
|
src/xmrig.cpp
|
||||||
@@ -189,12 +178,6 @@ include(cmake/OpenSSL.cmake)
|
|||||||
include(cmake/asm.cmake)
|
include(cmake/asm.cmake)
|
||||||
include(cmake/cn-gpu.cmake)
|
include(cmake/cn-gpu.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 (NOT WITH_AEON)
|
if (NOT WITH_AEON)
|
||||||
add_definitions(/DXMRIG_NO_AEON)
|
add_definitions(/DXMRIG_NO_AEON)
|
||||||
endif()
|
endif()
|
||||||
@@ -215,31 +198,22 @@ if (WITH_EMBEDDED_CONFIG)
|
|||||||
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
|
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WITH_HTTPD)
|
if (WITH_HTTP)
|
||||||
find_package(MHD)
|
set(HTTP_SOURCES
|
||||||
|
|
||||||
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/Api.cpp
|
||||||
src/api/ApiRouter.cpp
|
src/api/Api.h
|
||||||
src/common/api/Httpd.cpp
|
src/api/Httpd.cpp
|
||||||
src/common/api/HttpRequest.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()
|
|
||||||
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
set(HTTPD_SOURCES "")
|
set(HTTP_SOURCES "")
|
||||||
set(MHD_LIBRARY "")
|
|
||||||
add_definitions(/DXMRIG_NO_HTTPD)
|
|
||||||
add_definitions(/DXMRIG_NO_API)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
@@ -254,5 +228,5 @@ if (WITH_DEBUG_LOG)
|
|||||||
add_definitions(/DAPP_DEBUG)
|
add_definitions(/DAPP_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
|
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTP_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
|
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB})
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
|
|||||||
* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
|
* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
|
||||||
* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
|
* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
|
||||||
|
|
||||||
<img src="http://i.imgur.com/OKZRVDh.png" width="619" >
|
<img src="http://i.imgur.com/Ymumes5.png" width="670" >
|
||||||
|
|
||||||
#### Table of contents
|
#### Table of contents
|
||||||
* [Features](#features)
|
* [Features](#features)
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
# - Try to find MHD
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# MHD_FOUND - system has MHD
|
|
||||||
# MHD_INCLUDE_DIRS - the MHD include directory
|
|
||||||
# MHD_LIBRARY - Link these to use MHD
|
|
||||||
|
|
||||||
find_path(
|
|
||||||
MHD_INCLUDE_DIR
|
|
||||||
NAMES microhttpd.h
|
|
||||||
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
|
|
||||||
PATH_SUFFIXES "include"
|
|
||||||
DOC "microhttpd include dir"
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(MHD_INCLUDE_DIR NAMES microhttpd.h)
|
|
||||||
|
|
||||||
find_library(
|
|
||||||
MHD_LIBRARY
|
|
||||||
NAMES libmicrohttpd.a microhttpd libmicrohttpd
|
|
||||||
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
|
|
||||||
PATH_SUFFIXES "lib"
|
|
||||||
DOC "microhttpd library"
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(MHD_LIBRARY NAMES microhttpd libmicrohttpd)
|
|
||||||
|
|
||||||
set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
|
|
||||||
set(MHD_LIBRARIES ${MHD_LIBRARY})
|
|
||||||
|
|
||||||
# debug library on windows
|
|
||||||
# same naming convention as in qt (appending debug library with d)
|
|
||||||
# boost is using the same "hack" as us with "optimized" and "debug"
|
|
||||||
# official MHD project actually uses _d suffix
|
|
||||||
if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
|
|
||||||
find_library(
|
|
||||||
MHD_LIBRARY_DEBUG
|
|
||||||
NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d
|
|
||||||
DOC "mhd debug library"
|
|
||||||
)
|
|
||||||
set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(MHD DEFAULT_MSG MHD_LIBRARY MHD_INCLUDE_DIR)
|
|
||||||
mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)
|
|
||||||
|
|
||||||
@@ -13,17 +13,19 @@ if (WITH_TLS)
|
|||||||
if (OPENSSL_FOUND)
|
if (OPENSSL_FOUND)
|
||||||
set(TLS_SOURCES src/base/net/stratum/Tls.h src/base/net/stratum/Tls.cpp)
|
set(TLS_SOURCES src/base/net/stratum/Tls.h src/base/net/stratum/Tls.cpp)
|
||||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
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()
|
else()
|
||||||
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
|
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(/DXMRIG_FEATURE_TLS)
|
add_definitions(/DXMRIG_FEATURE_TLS)
|
||||||
remove_definitions(/DXMRIG_NO_TLS)
|
|
||||||
else()
|
else()
|
||||||
set(TLS_SOURCES "")
|
set(TLS_SOURCES "")
|
||||||
set(OPENSSL_LIBRARIES "")
|
set(OPENSSL_LIBRARIES "")
|
||||||
remove_definitions(/DXMRIG_FEATURE_TLS)
|
remove_definitions(/DXMRIG_FEATURE_TLS)
|
||||||
add_definitions(/DXMRIG_NO_TLS)
|
|
||||||
|
|
||||||
set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
|
set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
|||||||
add_definitions(/DNDEBUG)
|
add_definitions(/DNDEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
|
||||||
@@ -27,6 +29,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
|||||||
else()
|
else()
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||||
|
|
||||||
|
add_definitions(/DHAVE_ROTR)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
@@ -50,6 +54,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
|||||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||||
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
|
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
|
||||||
add_definitions(/DNOMINMAX)
|
add_definitions(/DNOMINMAX)
|
||||||
|
add_definitions(/DHAVE_ROTR)
|
||||||
|
|
||||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||||
|
|
||||||
@@ -68,6 +73,11 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
|||||||
else()
|
else()
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
|
||||||
|
|
||||||
|
check_symbol_exists("_rotr" "x86intrin.h" HAVE_ROTR)
|
||||||
|
if (HAVE_ROTR)
|
||||||
|
add_definitions(/DHAVE_ROTR)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "../src/version.h"
|
#include "../src/version.h"
|
||||||
|
|
||||||
IDI_ICON1 ICON DISCARDABLE "app.ico"
|
101 ICON "app.ico"
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0
|
FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0
|
||||||
|
|||||||
68
src/3rdparty/http-parser/AUTHORS
vendored
Normal file
68
src/3rdparty/http-parser/AUTHORS
vendored
Normal 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
19
src/3rdparty/http-parser/LICENSE-MIT
vendored
Normal 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
246
src/3rdparty/http-parser/README.md
vendored
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
HTTP Parser
|
||||||
|
===========
|
||||||
|
|
||||||
|
[](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
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
439
src/3rdparty/http-parser/http_parser.h
vendored
Normal 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
|
||||||
41
src/App.cpp
41
src/App.cpp
@@ -31,11 +31,11 @@
|
|||||||
#include "api/Api.h"
|
#include "api/Api.h"
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "base/io/Console.h"
|
#include "base/io/Console.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
#include "base/kernel/Signals.h"
|
#include "base/kernel/Signals.h"
|
||||||
#include "common/cpu/Cpu.h"
|
#include "common/cpu/Cpu.h"
|
||||||
#include "common/log/Log.h"
|
|
||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
#include "core/Config.h"
|
#include "core/config/Config.h"
|
||||||
#include "core/Controller.h"
|
#include "core/Controller.h"
|
||||||
#include "crypto/CryptoNight.h"
|
#include "crypto/CryptoNight.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
@@ -45,14 +45,8 @@
|
|||||||
#include "workers/Workers.h"
|
#include "workers/Workers.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_HTTPD
|
|
||||||
# include "common/api/Httpd.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
xmrig::App::App(Process *process) :
|
xmrig::App::App(Process *process) :
|
||||||
m_console(nullptr),
|
m_console(nullptr),
|
||||||
m_httpd(nullptr),
|
|
||||||
m_signals(nullptr)
|
m_signals(nullptr)
|
||||||
{
|
{
|
||||||
m_controller = new Controller(process);
|
m_controller = new Controller(process);
|
||||||
@@ -71,10 +65,6 @@ xmrig::App::~App()
|
|||||||
delete m_signals;
|
delete m_signals;
|
||||||
delete m_console;
|
delete m_console;
|
||||||
delete m_controller;
|
delete m_controller;
|
||||||
|
|
||||||
# ifndef XMRIG_NO_HTTPD
|
|
||||||
delete m_httpd;
|
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -98,24 +88,9 @@ int xmrig::App::exec()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifndef XMRIG_NO_API
|
|
||||||
Api::start(m_controller);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
Workers::start(m_controller);
|
Workers::start(m_controller);
|
||||||
|
|
||||||
m_controller->network()->connect();
|
m_controller->start();
|
||||||
|
|
||||||
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||||
uv_loop_close(uv_default_loop());
|
uv_loop_close(uv_default_loop());
|
||||||
@@ -135,7 +110,7 @@ void xmrig::App::onConsoleCommand(char command)
|
|||||||
case 'p':
|
case 'p':
|
||||||
case 'P':
|
case 'P':
|
||||||
if (Workers::isEnabled()) {
|
if (Workers::isEnabled()) {
|
||||||
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume");
|
LOG_INFO(YELLOW_BOLD("paused") ", press " MAGENTA_BOLD("r") " to resume");
|
||||||
Workers::setEnabled(false);
|
Workers::setEnabled(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -143,7 +118,7 @@ void xmrig::App::onConsoleCommand(char command)
|
|||||||
case 'r':
|
case 'r':
|
||||||
case 'R':
|
case 'R':
|
||||||
if (!Workers::isEnabled()) {
|
if (!Workers::isEnabled()) {
|
||||||
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;32mresumed" : "resumed");
|
LOG_INFO(GREEN_BOLD("resumed"));
|
||||||
Workers::setEnabled(true);
|
Workers::setEnabled(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -185,14 +160,10 @@ void xmrig::App::onSignal(int signum)
|
|||||||
|
|
||||||
void xmrig::App::close()
|
void xmrig::App::close()
|
||||||
{
|
{
|
||||||
# ifndef XMRIG_NO_HTTPD
|
|
||||||
m_httpd->stop();
|
|
||||||
# endif
|
|
||||||
|
|
||||||
m_signals->stop();
|
m_signals->stop();
|
||||||
m_console->stop();
|
m_console->stop();
|
||||||
m_controller->stop();
|
m_controller->stop();
|
||||||
|
|
||||||
Workers::stop();
|
Workers::stop();
|
||||||
Log::release();
|
Log::destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ namespace xmrig {
|
|||||||
|
|
||||||
class Console;
|
class Console;
|
||||||
class Controller;
|
class Controller;
|
||||||
class Httpd;
|
|
||||||
class Network;
|
class Network;
|
||||||
class Process;
|
class Process;
|
||||||
class Signals;
|
class Signals;
|
||||||
@@ -60,7 +59,6 @@ private:
|
|||||||
|
|
||||||
Console *m_console;
|
Console *m_console;
|
||||||
Controller *m_controller;
|
Controller *m_controller;
|
||||||
Httpd *m_httpd;
|
|
||||||
Signals *m_signals;
|
Signals *m_signals;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "common/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
#include "core/Config.h"
|
#include "core/config/Config.h"
|
||||||
#include "core/Controller.h"
|
#include "core/Controller.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "core/Controller.h"
|
#include "core/Controller.h"
|
||||||
#include "core/Config.h"
|
#include "core/config/Config.h"
|
||||||
|
|
||||||
|
|
||||||
void xmrig::App::background()
|
void xmrig::App::background()
|
||||||
|
|||||||
@@ -28,13 +28,18 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
|
||||||
#include "common/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
#include "common/utils/mm_malloc.h"
|
#include "common/utils/mm_malloc.h"
|
||||||
#include "common/xmrig.h"
|
#include "common/xmrig.h"
|
||||||
#include "crypto/CryptoNight.h"
|
#include "crypto/CryptoNight.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
# include <mach/vm_statistics.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void Mem::init(bool enabled)
|
void Mem::init(bool enabled)
|
||||||
{
|
{
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
|
|
||||||
#include "common/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
#include "common/utils/mm_malloc.h"
|
#include "common/utils/mm_malloc.h"
|
||||||
#include "common/xmrig.h"
|
#include "common/xmrig.h"
|
||||||
#include "crypto/CryptoNight.h"
|
#include "crypto/CryptoNight.h"
|
||||||
@@ -67,11 +67,11 @@ static BOOL SetLockPagesPrivilege() {
|
|||||||
tp.PrivilegeCount = 1;
|
tp.PrivilegeCount = 1;
|
||||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
if (LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) {
|
if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, NULL, NULL);
|
BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, nullptr, nullptr);
|
||||||
if (rc != TRUE || GetLastError() != ERROR_SUCCESS) {
|
if (rc != TRUE || GetLastError() != ERROR_SUCCESS) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -95,12 +95,12 @@ static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) {
|
|||||||
|
|
||||||
static BOOL ObtainLockPagesPrivilege() {
|
static BOOL ObtainLockPagesPrivilege() {
|
||||||
HANDLE token;
|
HANDLE token;
|
||||||
PTOKEN_USER user = NULL;
|
PTOKEN_USER user = nullptr;
|
||||||
|
|
||||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) {
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) {
|
||||||
DWORD size = 0;
|
DWORD size = 0;
|
||||||
|
|
||||||
GetTokenInformation(token, TokenUser, NULL, 0, &size);
|
GetTokenInformation(token, TokenUser, nullptr, 0, &size);
|
||||||
if (size) {
|
if (size) {
|
||||||
user = (PTOKEN_USER) LocalAlloc(LPTR, size);
|
user = (PTOKEN_USER) LocalAlloc(LPTR, size);
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ static BOOL ObtainLockPagesPrivilege() {
|
|||||||
ZeroMemory(&attributes, sizeof(attributes));
|
ZeroMemory(&attributes, sizeof(attributes));
|
||||||
|
|
||||||
BOOL result = FALSE;
|
BOOL result = FALSE;
|
||||||
if (LsaOpenPolicy(NULL, &attributes, POLICY_ALL_ACCESS, &handle) == 0) {
|
if (LsaOpenPolicy(nullptr, &attributes, POLICY_ALL_ACCESS, &handle) == 0) {
|
||||||
LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME));
|
LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME));
|
||||||
|
|
||||||
if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) {
|
if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) {
|
||||||
@@ -187,7 +187,7 @@ void Mem::release(MemInfo &info)
|
|||||||
|
|
||||||
void *Mem::allocateExecutableMemory(size_t size)
|
void *Mem::allocateExecutableMemory(size_t size)
|
||||||
{
|
{
|
||||||
return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
return VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,10 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
#include "base/net/stratum/Pool.h"
|
#include "base/net/stratum/Pool.h"
|
||||||
#include "common/cpu/Cpu.h"
|
#include "common/cpu/Cpu.h"
|
||||||
#include "common/log/Log.h"
|
#include "core/config/Config.h"
|
||||||
#include "core/Config.h"
|
|
||||||
#include "core/Controller.h"
|
#include "core/Controller.h"
|
||||||
#include "crypto/Asm.h"
|
#include "crypto/Asm.h"
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
@@ -41,62 +41,44 @@
|
|||||||
|
|
||||||
#ifndef XMRIG_NO_ASM
|
#ifndef XMRIG_NO_ASM
|
||||||
static const char *coloredAsmNames[] = {
|
static const char *coloredAsmNames[] = {
|
||||||
"\x1B[1;31mnone\x1B[0m",
|
RED_BOLD("none"),
|
||||||
"auto",
|
"auto",
|
||||||
"\x1B[1;32mintel\x1B[0m",
|
GREEN_BOLD("intel"),
|
||||||
"\x1B[1;32mryzen\x1B[0m",
|
GREEN_BOLD("ryzen"),
|
||||||
"\x1B[1;32mbulldozer\x1B[0m"
|
GREEN_BOLD("bulldozer")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline static const char *asmName(xmrig::Assembly assembly, bool colors)
|
inline static const char *asmName(xmrig::Assembly assembly)
|
||||||
{
|
{
|
||||||
return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly);
|
return coloredAsmNames[assembly];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void print_memory(xmrig::Config *config) {
|
static void print_memory(xmrig::Config *) {
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
if (config->isColors()) {
|
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
|
||||||
xmrig::Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
|
"HUGE PAGES", Mem::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable"));
|
||||||
"HUGE PAGES", Mem::isHugepagesAvailable() ? "\x1B[1;32mavailable" : "\x1B[01;31munavailable");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xmrig::Log::i()->text(" * %-13s%s", "HUGE PAGES", Mem::isHugepagesAvailable() ? "available" : "unavailable");
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_cpu(xmrig::Config *config)
|
static void print_cpu(xmrig::Config *)
|
||||||
{
|
{
|
||||||
using namespace xmrig;
|
using namespace xmrig;
|
||||||
|
|
||||||
if (config->isColors()) {
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES %sAVX2",
|
||||||
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES %sAVX2",
|
|
||||||
"CPU",
|
"CPU",
|
||||||
Cpu::info()->brand(),
|
Cpu::info()->brand(),
|
||||||
Cpu::info()->sockets(),
|
Cpu::info()->sockets(),
|
||||||
Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
|
Cpu::info()->isX64() ? GREEN_BOLD_S : RED_BOLD_S "-",
|
||||||
Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-",
|
Cpu::info()->hasAES() ? GREEN_BOLD_S : RED_BOLD_S "-",
|
||||||
Cpu::info()->hasAVX2() ? "\x1B[1;32m" : "\x1B[1;31m-");
|
Cpu::info()->hasAVX2() ? GREEN_BOLD_S : RED_BOLD_S "-"
|
||||||
|
);
|
||||||
# ifndef XMRIG_NO_LIBCPUID
|
# ifndef XMRIG_NO_LIBCPUID
|
||||||
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
|
||||||
# endif
|
# endif
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log::i()->text(" * %-13s%s (%d) %sx64 %sAES %sAVX2",
|
|
||||||
"CPU",
|
|
||||||
Cpu::info()->brand(),
|
|
||||||
Cpu::info()->sockets(),
|
|
||||||
Cpu::info()->isX64() ? "" : "-",
|
|
||||||
Cpu::info()->hasAES() ? "" : "-",
|
|
||||||
Cpu::info()->hasAVX2() ? "" : "-");
|
|
||||||
# ifndef XMRIG_NO_LIBCPUID
|
|
||||||
Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -108,49 +90,48 @@ static void print_threads(xmrig::Config *config)
|
|||||||
snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity());
|
snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity());
|
||||||
}
|
}
|
||||||
|
|
||||||
xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s")
|
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s"),
|
||||||
: " * %-13s%d, %s, av=%d, %sdonate=%d%%%s",
|
|
||||||
"THREADS",
|
"THREADS",
|
||||||
config->threadsCount(),
|
config->threadsCount(),
|
||||||
config->algorithm().name(),
|
config->algorithm().shortName(),
|
||||||
config->algoVariant(),
|
config->algoVariant(),
|
||||||
config->isColors() && config->pools().donateLevel() == 0 ? "\x1B[1;31m" : "",
|
config->pools().donateLevel() == 0 ? RED_BOLD_S : "",
|
||||||
config->pools().donateLevel(),
|
config->pools().donateLevel(),
|
||||||
buf);
|
buf
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%")
|
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%"),
|
||||||
: " * %-13s%d, %s, %sdonate=%d%%",
|
|
||||||
"THREADS",
|
"THREADS",
|
||||||
config->threadsCount(),
|
config->threadsCount(),
|
||||||
config->algorithm().name(),
|
config->algorithm().shortName(),
|
||||||
config->isColors() && config->pools().donateLevel() == 0 ? "\x1B[1;31m" : "",
|
config->pools().donateLevel() == 0 ? RED_BOLD_S : "",
|
||||||
config->pools().donateLevel());
|
config->pools().donateLevel()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifndef XMRIG_NO_ASM
|
# ifndef XMRIG_NO_ASM
|
||||||
if (config->assembly() == xmrig::ASM_AUTO) {
|
if (config->assembly() == xmrig::ASM_AUTO) {
|
||||||
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
|
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
|
||||||
|
|
||||||
xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
|
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s"), "ASSEMBLY", asmName(assembly));
|
||||||
: " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xmrig::Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
|
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s"), "ASSEMBLY", asmName(config->assembly()));
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_commands(xmrig::Config *config)
|
static void print_commands(xmrig::Config *)
|
||||||
{
|
{
|
||||||
if (config->isColors()) {
|
if (xmrig::Log::colors) {
|
||||||
xmrig::Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
|
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
|
||||||
MAGENTA_BOLD("p") WHITE_BOLD("ause, ")
|
MAGENTA_BOLD("p") WHITE_BOLD("ause, ")
|
||||||
MAGENTA_BOLD("r") WHITE_BOLD("esume"));
|
MAGENTA_BOLD("r") WHITE_BOLD("esume"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xmrig::Log::i()->text(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume");
|
xmrig::Log::print(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +142,7 @@ void Summary::print(xmrig::Controller *controller)
|
|||||||
print_memory(controller->config());
|
print_memory(controller->config());
|
||||||
print_cpu(controller->config());
|
print_cpu(controller->config());
|
||||||
print_threads(controller->config());
|
print_threads(controller->config());
|
||||||
controller->config()->printPools();
|
controller->config()->pools().print();
|
||||||
controller->config()->printAPI();
|
|
||||||
|
|
||||||
print_commands(controller->config());
|
print_commands(controller->config());
|
||||||
}
|
}
|
||||||
|
|||||||
168
src/api/Api.cpp
168
src/api/Api.cpp
@@ -22,52 +22,172 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* 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/Api.h"
|
||||||
#include "api/ApiRouter.h"
|
#include "api/interfaces/IApiListener.h"
|
||||||
#include "common/api/HttpReply.h"
|
#include "api/requests/HttpApiRequest.h"
|
||||||
#include "common/api/HttpRequest.h"
|
#include "api/v1/ApiRouter.h"
|
||||||
|
#include "base/kernel/Base.h"
|
||||||
|
#include "base/tools/Buffer.h"
|
||||||
|
#include "base/tools/Chrono.h"
|
||||||
|
#include "common/crypto/keccak.h"
|
||||||
|
#include "core/config/Config.h"
|
||||||
|
#include "core/Controller.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_httpd(nullptr),
|
||||||
|
m_timestamp(Chrono::steadyMSecs())
|
||||||
{
|
{
|
||||||
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) {
|
HttpApiRequest request(req, m_base->config()->http().isRestricted());
|
||||||
reply.status = 500;
|
|
||||||
|
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.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) {
|
||||||
|
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::steadyMSecs() - m_timestamp) / 1000, 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.method() == xmrig::HttpRequest::Get) {
|
uv_interface_address_t *interfaces;
|
||||||
return m_router->get(req, reply);
|
int count = 0;
|
||||||
}
|
|
||||||
|
|
||||||
m_router->exec(req, reply);
|
if (uv_interface_addresses(&interfaces, &count) < 0) {
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Api::tick(const xmrig::NetworkState &network)
|
|
||||||
{
|
|
||||||
if (!m_router) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_router->tick(network);
|
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));
|
||||||
|
|
||||||
|
xmrig::keccak(input, inSize, hash);
|
||||||
|
xmrig::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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,32 +26,58 @@
|
|||||||
#define XMRIG_API_H
|
#define XMRIG_API_H
|
||||||
|
|
||||||
|
|
||||||
#include <uv.h>
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
class ApiRouter;
|
#include "base/kernel/interfaces/IBaseListener.h"
|
||||||
class Hashrate;
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
class Controller;
|
|
||||||
class HttpReply;
|
|
||||||
class HttpRequest;
|
|
||||||
class NetworkState;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Api
|
class ApiRouter;
|
||||||
|
class Base;
|
||||||
|
class Httpd;
|
||||||
|
class HttpData;
|
||||||
|
class IApiListener;
|
||||||
|
class IApiRequest;
|
||||||
|
class String;
|
||||||
|
|
||||||
|
|
||||||
|
class Api : public IBaseListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool start(xmrig::Controller *controller);
|
Api(Base *base);
|
||||||
static void release();
|
~Api() override;
|
||||||
|
|
||||||
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
inline const char *id() const { return m_id; }
|
||||||
static void tick(const xmrig::NetworkState &results);
|
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:
|
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];
|
||||||
|
Httpd *m_httpd;
|
||||||
|
std::vector<IApiListener *> m_listeners;
|
||||||
|
uint64_t m_timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
#endif /* XMRIG_API_H */
|
#endif /* XMRIG_API_H */
|
||||||
|
|||||||
@@ -1,339 +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 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 <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <uv.h>
|
|
||||||
|
|
||||||
#if _WIN32
|
|
||||||
# include "winsock2.h"
|
|
||||||
#else
|
|
||||||
# include "unistd.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "api/ApiRouter.h"
|
|
||||||
#include "base/tools/Buffer.h"
|
|
||||||
#include "common/api/HttpReply.h"
|
|
||||||
#include "common/api/HttpRequest.h"
|
|
||||||
#include "common/cpu/Cpu.h"
|
|
||||||
#include "common/crypto/keccak.h"
|
|
||||||
#include "common/Platform.h"
|
|
||||||
#include "core/Config.h"
|
|
||||||
#include "core/Controller.h"
|
|
||||||
#include "interfaces/IThread.h"
|
|
||||||
#include "rapidjson/document.h"
|
|
||||||
#include "rapidjson/prettywriter.h"
|
|
||||||
#include "rapidjson/stringbuffer.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "workers/Hashrate.h"
|
|
||||||
#include "workers/Workers.h"
|
|
||||||
|
|
||||||
|
|
||||||
static inline double normalize(double d)
|
|
||||||
{
|
|
||||||
if (!isnormal(d)) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return floor(d * 100.0) / 100.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ApiRouter::ApiRouter(xmrig::Controller *controller) :
|
|
||||||
m_controller(controller)
|
|
||||||
{
|
|
||||||
memset(m_workerId, 0, sizeof(m_workerId));
|
|
||||||
|
|
||||||
setWorkerId(controller->config()->apiWorkerId());
|
|
||||||
genId(controller->config()->apiId());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ApiRouter::~ApiRouter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
|
|
||||||
{
|
|
||||||
rapidjson::Document 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/threads")) {
|
|
||||||
getThreads(doc);
|
|
||||||
|
|
||||||
return finalize(reply, doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.SetObject();
|
|
||||||
|
|
||||||
getIdentify(doc);
|
|
||||||
getMiner(doc);
|
|
||||||
getHashrate(doc);
|
|
||||||
getResults(doc);
|
|
||||||
getConnection(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::tick(const xmrig::NetworkState &network)
|
|
||||||
{
|
|
||||||
m_network = network;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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::Buffer::toHex(hash, 8, m_id);
|
|
||||||
|
|
||||||
delete [] input;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uv_free_interface_addresses(interfaces, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApiRouter::getConnection(rapidjson::Document &doc) const
|
|
||||||
{
|
|
||||||
auto &allocator = doc.GetAllocator();
|
|
||||||
|
|
||||||
rapidjson::Value connection(rapidjson::kObjectType);
|
|
||||||
connection.AddMember("pool", rapidjson::StringRef(m_network.pool), allocator);
|
|
||||||
connection.AddMember("uptime", m_network.connectionTime(), allocator);
|
|
||||||
connection.AddMember("ping", m_network.latency(), allocator);
|
|
||||||
connection.AddMember("failures", m_network.failures, allocator);
|
|
||||||
connection.AddMember("error_log", rapidjson::Value(rapidjson::kArrayType), allocator);
|
|
||||||
|
|
||||||
doc.AddMember("connection", connection, allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApiRouter::getHashrate(rapidjson::Document &doc) const
|
|
||||||
{
|
|
||||||
auto &allocator = doc.GetAllocator();
|
|
||||||
|
|
||||||
rapidjson::Value hashrate(rapidjson::kObjectType);
|
|
||||||
rapidjson::Value total(rapidjson::kArrayType);
|
|
||||||
rapidjson::Value threads(rapidjson::kArrayType);
|
|
||||||
|
|
||||||
const Hashrate *hr = Workers::hashrate();
|
|
||||||
|
|
||||||
total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator);
|
|
||||||
total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator);
|
|
||||||
total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < Workers::threads(); i++) {
|
|
||||||
rapidjson::Value thread(rapidjson::kArrayType);
|
|
||||||
thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
|
||||||
thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
|
||||||
thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
|
||||||
|
|
||||||
threads.PushBack(thread, allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
hashrate.AddMember("total", total, allocator);
|
|
||||||
hashrate.AddMember("highest", normalize(hr->highest()), allocator);
|
|
||||||
hashrate.AddMember("threads", threads, 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
|
|
||||||
{
|
|
||||||
using namespace xmrig;
|
|
||||||
auto &allocator = doc.GetAllocator();
|
|
||||||
|
|
||||||
rapidjson::Value cpu(rapidjson::kObjectType);
|
|
||||||
cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator);
|
|
||||||
cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
|
|
||||||
cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
|
|
||||||
cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
|
|
||||||
|
|
||||||
doc.AddMember("version", APP_VERSION, allocator);
|
|
||||||
doc.AddMember("kind", APP_KIND, allocator);
|
|
||||||
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
|
|
||||||
doc.AddMember("cpu", cpu, allocator);
|
|
||||||
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator);
|
|
||||||
doc.AddMember("hugepages", Workers::hugePages() > 0, allocator);
|
|
||||||
doc.AddMember("donate_level", m_controller->config()->pools().donateLevel(), allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApiRouter::getResults(rapidjson::Document &doc) const
|
|
||||||
{
|
|
||||||
auto &allocator = doc.GetAllocator();
|
|
||||||
|
|
||||||
rapidjson::Value results(rapidjson::kObjectType);
|
|
||||||
|
|
||||||
results.AddMember("diff_current", m_network.diff, allocator);
|
|
||||||
results.AddMember("shares_good", m_network.accepted, allocator);
|
|
||||||
results.AddMember("shares_total", m_network.accepted + m_network.rejected, allocator);
|
|
||||||
results.AddMember("avg_time", m_network.avgTime(), allocator);
|
|
||||||
results.AddMember("hashes_total", m_network.total, allocator);
|
|
||||||
|
|
||||||
rapidjson::Value best(rapidjson::kArrayType);
|
|
||||||
for (size_t i = 0; i < m_network.topDiff.size(); ++i) {
|
|
||||||
best.PushBack(m_network.topDiff[i], allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
results.AddMember("best", best, allocator);
|
|
||||||
results.AddMember("error_log", rapidjson::Value(rapidjson::kArrayType), allocator);
|
|
||||||
|
|
||||||
doc.AddMember("results", results, allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApiRouter::getThreads(rapidjson::Document &doc) const
|
|
||||||
{
|
|
||||||
doc.SetObject();
|
|
||||||
auto &allocator = doc.GetAllocator();
|
|
||||||
const Hashrate *hr = Workers::hashrate();
|
|
||||||
|
|
||||||
Workers::threadsSummary(doc);
|
|
||||||
|
|
||||||
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
|
|
||||||
rapidjson::Value list(rapidjson::kArrayType);
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
for (const xmrig::IThread *thread : threads) {
|
|
||||||
rapidjson::Value value = thread->toAPI(doc);
|
|
||||||
|
|
||||||
rapidjson::Value hashrate(rapidjson::kArrayType);
|
|
||||||
hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
|
||||||
hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
|
||||||
hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
|
|
||||||
value.AddMember("hashrate", hashrate, allocator);
|
|
||||||
list.PushBack(value, allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.AddMember("threads", list, 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);
|
|
||||||
}
|
|
||||||
@@ -1,76 +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 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_APIROUTER_H
|
|
||||||
#define XMRIG_APIROUTER_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "api/NetworkState.h"
|
|
||||||
#include "common/interfaces/IControllerListener.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() override;
|
|
||||||
|
|
||||||
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
|
|
||||||
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
|
||||||
|
|
||||||
void tick(const xmrig::NetworkState &results);
|
|
||||||
|
|
||||||
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 getConnection(rapidjson::Document &doc) const;
|
|
||||||
void getHashrate(rapidjson::Document &doc) const;
|
|
||||||
void getIdentify(rapidjson::Document &doc) const;
|
|
||||||
void getMiner(rapidjson::Document &doc) const;
|
|
||||||
void getResults(rapidjson::Document &doc) const;
|
|
||||||
void getThreads(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::NetworkState m_network;
|
|
||||||
xmrig::Controller *m_controller;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* XMRIG_APIROUTER_H */
|
|
||||||
193
src/api/Httpd.cpp
Normal file
193
src/api/Httpd.cpp
Normal 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
70
src/api/Httpd.h
Normal 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 */
|
||||||
@@ -20,31 +20,26 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIGCREATOR_H__
|
#ifndef XMRIG_IAPILISTENER_H
|
||||||
#define __CONFIGCREATOR_H__
|
#define XMRIG_IAPILISTENER_H
|
||||||
|
|
||||||
|
|
||||||
#include "common/interfaces/IConfigCreator.h"
|
|
||||||
#include "core/Config.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class IConfig;
|
class IApiRequest;
|
||||||
|
|
||||||
|
|
||||||
class ConfigCreator : public IConfigCreator
|
class IApiListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline IConfig *create() const override
|
virtual ~IApiListener() = default;
|
||||||
{
|
|
||||||
return new Config();
|
virtual void onRequest(IApiRequest &request) = 0;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} /* namespace xmrig */
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
#endif // __CONFIGCREATOR_H__
|
#endif // XMRIG_IAPILISTENER_H
|
||||||
72
src/api/interfaces/IApiRequest.h
Normal file
72
src/api/interfaces/IApiRequest.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2016-2018 XMRig <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef 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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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 Method method() const = 0;
|
||||||
|
virtual rapidjson::Document &doc() = 0;
|
||||||
|
virtual rapidjson::Value &reply() = 0;
|
||||||
|
virtual Source source() const = 0;
|
||||||
|
virtual void accept() = 0;
|
||||||
|
virtual void done(int status) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_IAPIREQUEST_H
|
||||||
39
src/api/requests/ApiRequest.cpp
Normal file
39
src/api/requests/ApiRequest.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/* 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/ApiRequest.h"
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::ApiRequest::ApiRequest(Source source, bool restricted) :
|
||||||
|
m_restricted(restricted),
|
||||||
|
m_source(source),
|
||||||
|
m_state(STATE_NEW)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::ApiRequest::~ApiRequest()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -22,32 +22,46 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XMRIG_JSON_H
|
|
||||||
#define XMRIG_JSON_H
|
#ifndef XMRIG_APIREQUEST_H
|
||||||
|
#define XMRIG_APIREQUEST_H
|
||||||
|
|
||||||
|
|
||||||
#include "rapidjson/fwd.h"
|
#include "api/interfaces/IApiRequest.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class Json
|
class ApiRequest : public IApiRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
|
ApiRequest(Source source, bool restricted);
|
||||||
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
|
~ApiRequest() override;
|
||||||
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);
|
protected:
|
||||||
static bool save(const char *fileName, const rapidjson::Document &doc);
|
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 Source source() const override { return m_source; }
|
||||||
|
inline void accept() override { m_state = STATE_ACCEPTED; }
|
||||||
|
inline void done(int) override { m_state = STATE_DONE; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum State {
|
||||||
|
STATE_NEW,
|
||||||
|
STATE_ACCEPTED,
|
||||||
|
STATE_DONE
|
||||||
|
};
|
||||||
|
|
||||||
|
bool m_restricted;
|
||||||
|
Source m_source;
|
||||||
|
State m_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} /* namespace xmrig */
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
#endif /* XMRIG_JSON_H */
|
#endif // XMRIG_APIREQUEST_H
|
||||||
|
|
||||||
@@ -23,42 +23,54 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "base/io/Watcher.h"
|
#include "api/requests/HttpApiRequest.h"
|
||||||
#include "base/kernel/interfaces/IConfigListener.h"
|
#include "base/net/http/HttpData.h"
|
||||||
#include "common/config/ConfigLoader.h"
|
#include "rapidjson/error/en.h"
|
||||||
#include "common/config/ConfigWatcher.h"
|
|
||||||
#include "common/log/Log.h"
|
|
||||||
#include "core/ConfigCreator.h"
|
|
||||||
|
|
||||||
|
|
||||||
xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigCreator *creator, IConfigListener *listener) :
|
xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) :
|
||||||
m_creator(creator),
|
ApiRequest(SOURCE_HTTP, restricted),
|
||||||
m_listener(listener)
|
m_parsed(false),
|
||||||
|
m_req(req),
|
||||||
|
m_res(req.id()),
|
||||||
|
m_url(req.url.c_str())
|
||||||
{
|
{
|
||||||
m_watcher = new Watcher(path, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::ConfigWatcher::~ConfigWatcher()
|
const rapidjson::Value &xmrig::HttpApiRequest::json() const
|
||||||
{
|
{
|
||||||
delete m_watcher;
|
return m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::IApiRequest::Method xmrig::HttpApiRequest::method() const
|
||||||
void xmrig::ConfigWatcher::onFileChanged(const String &fileName)
|
|
||||||
{
|
{
|
||||||
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
|
return static_cast<IApiRequest::Method>(m_req.method);
|
||||||
|
}
|
||||||
|
|
||||||
IConfig *config = m_creator->create();
|
|
||||||
ConfigLoader::loadFromFile(config, fileName);
|
|
||||||
|
|
||||||
if (!config->finalize()) {
|
void xmrig::HttpApiRequest::accept()
|
||||||
LOG_ERR("reloading failed");
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
|
||||||
delete config;
|
ApiRequest::accept();
|
||||||
return;
|
|
||||||
|
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());;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_listener->onNewConfig(config);
|
|
||||||
|
|
||||||
|
void xmrig::HttpApiRequest::done(int status)
|
||||||
|
{
|
||||||
|
ApiRequest::done(status);
|
||||||
|
|
||||||
|
m_res.setStatus(status);
|
||||||
|
m_res.end();
|
||||||
}
|
}
|
||||||
69
src/api/requests/HttpApiRequest.h
Normal file
69
src/api/requests/HttpApiRequest.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_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
|
||||||
|
|
||||||
179
src/api/v1/ApiRouter.cpp
Normal file
179
src/api/v1/ApiRouter.cpp
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
/* 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 <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/interfaces/IApiRequest.h"
|
||||||
|
#include "api/v1/ApiRouter.h"
|
||||||
|
#include "base/kernel/Base.h"
|
||||||
|
#include "common/cpu/Cpu.h"
|
||||||
|
#include "common/Platform.h"
|
||||||
|
#include "core/config/Config.h"
|
||||||
|
#include "interfaces/IThread.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "workers/Hashrate.h"
|
||||||
|
#include "workers/Workers.h"
|
||||||
|
|
||||||
|
|
||||||
|
static inline rapidjson::Value normalize(double d)
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
|
||||||
|
if (!isnormal(d)) {
|
||||||
|
return Value(kNullType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value(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.url() == "/1/summary" || request.url() == "/api.json") {
|
||||||
|
request.accept();
|
||||||
|
getMiner(request.reply(), request.doc());
|
||||||
|
getHashrate(request.reply(), request.doc());
|
||||||
|
}
|
||||||
|
else if (request.url() == "/1/threads") {
|
||||||
|
request.accept();
|
||||||
|
getThreads(request.reply(), request.doc());
|
||||||
|
}
|
||||||
|
else if (request.url() == "/1/config") {
|
||||||
|
if (request.isRestricted()) {
|
||||||
|
return request.done(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
request.accept();
|
||||||
|
m_base->config()->getJSON(request.doc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) {
|
||||||
|
if (request.url() == "/1/config") {
|
||||||
|
request.accept();
|
||||||
|
|
||||||
|
if (!m_base->reload(request.json())) {
|
||||||
|
return request.done(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
request.done(204);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
Value hashrate(kObjectType);
|
||||||
|
Value total(kArrayType);
|
||||||
|
Value threads(kArrayType);
|
||||||
|
|
||||||
|
const Hashrate *hr = Workers::hashrate();
|
||||||
|
|
||||||
|
total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator);
|
||||||
|
total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator);
|
||||||
|
total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < Workers::threads(); i++) {
|
||||||
|
Value thread(kArrayType);
|
||||||
|
thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||||
|
thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||||
|
thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
||||||
|
|
||||||
|
threads.PushBack(thread, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashrate.AddMember("total", total, allocator);
|
||||||
|
hashrate.AddMember("highest", normalize(hr->highest()), allocator);
|
||||||
|
hashrate.AddMember("threads", threads, allocator);
|
||||||
|
reply.AddMember("hashrate", hashrate, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
Value cpu(kObjectType);
|
||||||
|
cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator);
|
||||||
|
cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
|
||||||
|
cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
|
||||||
|
cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
|
||||||
|
|
||||||
|
reply.AddMember("version", APP_VERSION, allocator);
|
||||||
|
reply.AddMember("kind", APP_KIND, allocator);
|
||||||
|
reply.AddMember("ua", StringRef(Platform::userAgent()), allocator);
|
||||||
|
reply.AddMember("cpu", cpu, allocator);
|
||||||
|
reply.AddMember("hugepages", Workers::hugePages() > 0, allocator);
|
||||||
|
reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
const Hashrate *hr = Workers::hashrate();
|
||||||
|
|
||||||
|
Workers::threadsSummary(doc);
|
||||||
|
|
||||||
|
const std::vector<IThread *> &threads = m_base->config()->threads();
|
||||||
|
Value list(kArrayType);
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
for (const xmrig::IThread *thread : threads) {
|
||||||
|
Value value = thread->toAPI(doc);
|
||||||
|
|
||||||
|
Value hashrate(kArrayType);
|
||||||
|
hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||||
|
hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||||
|
hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
value.AddMember("hashrate", hashrate, allocator);
|
||||||
|
list.PushBack(value, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply.AddMember("threads", list, allocator);
|
||||||
|
}
|
||||||
63
src/api/v1/ApiRouter.h
Normal file
63
src/api/v1/ApiRouter.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* 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_APIROUTER_H
|
||||||
|
#define XMRIG_APIROUTER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "api/interfaces/IApiListener.h"
|
||||||
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Hashrate;
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class Base;
|
||||||
|
|
||||||
|
|
||||||
|
class ApiRouter : public xmrig::IApiListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ApiRouter(Base *base);
|
||||||
|
~ApiRouter() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onRequest(IApiRequest &request) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||||
|
void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||||
|
void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||||
|
|
||||||
|
Base *m_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_APIROUTER_H */
|
||||||
@@ -1,13 +1,26 @@
|
|||||||
set(HEADERS_BASE
|
set(HEADERS_BASE
|
||||||
src/base/io/Console.h
|
src/base/io/Console.h
|
||||||
src/base/io/Json.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/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/Entry.h
|
||||||
|
src/base/kernel/interfaces/IBaseListener.h
|
||||||
|
src/base/kernel/interfaces/IClient.h
|
||||||
src/base/kernel/interfaces/IClientListener.h
|
src/base/kernel/interfaces/IClientListener.h
|
||||||
|
src/base/kernel/interfaces/IConfig.h
|
||||||
src/base/kernel/interfaces/IConfigListener.h
|
src/base/kernel/interfaces/IConfigListener.h
|
||||||
|
src/base/kernel/interfaces/IConfigTransform.h
|
||||||
src/base/kernel/interfaces/IConsoleListener.h
|
src/base/kernel/interfaces/IConsoleListener.h
|
||||||
src/base/kernel/interfaces/IDnsListener.h
|
src/base/kernel/interfaces/IDnsListener.h
|
||||||
src/base/kernel/interfaces/ILineListener.h
|
src/base/kernel/interfaces/ILineListener.h
|
||||||
|
src/base/kernel/interfaces/ILogBackend.h
|
||||||
src/base/kernel/interfaces/ISignalListener.h
|
src/base/kernel/interfaces/ISignalListener.h
|
||||||
src/base/kernel/interfaces/IStrategy.h
|
src/base/kernel/interfaces/IStrategy.h
|
||||||
src/base/kernel/interfaces/IStrategyListener.h
|
src/base/kernel/interfaces/IStrategyListener.h
|
||||||
@@ -17,6 +30,8 @@ set(HEADERS_BASE
|
|||||||
src/base/kernel/Signals.h
|
src/base/kernel/Signals.h
|
||||||
src/base/net/dns/Dns.h
|
src/base/net/dns/Dns.h
|
||||||
src/base/net/dns/DnsRecord.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/Client.h
|
||||||
src/base/net/stratum/Job.h
|
src/base/net/stratum/Job.h
|
||||||
src/base/net/stratum/Pool.h
|
src/base/net/stratum/Pool.h
|
||||||
@@ -27,6 +42,7 @@ set(HEADERS_BASE
|
|||||||
src/base/net/tools/RecvBuf.h
|
src/base/net/tools/RecvBuf.h
|
||||||
src/base/net/tools/Storage.h
|
src/base/net/tools/Storage.h
|
||||||
src/base/tools/Arguments.h
|
src/base/tools/Arguments.h
|
||||||
|
src/base/tools/Baton.h
|
||||||
src/base/tools/Buffer.h
|
src/base/tools/Buffer.h
|
||||||
src/base/tools/Chrono.h
|
src/base/tools/Chrono.h
|
||||||
src/base/tools/Handle.h
|
src/base/tools/Handle.h
|
||||||
@@ -36,13 +52,23 @@ set(HEADERS_BASE
|
|||||||
|
|
||||||
set(SOURCES_BASE
|
set(SOURCES_BASE
|
||||||
src/base/io/Console.cpp
|
src/base/io/Console.cpp
|
||||||
src/base/io/Json.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/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/Entry.cpp
|
||||||
src/base/kernel/Process.cpp
|
src/base/kernel/Process.cpp
|
||||||
src/base/kernel/Signals.cpp
|
src/base/kernel/Signals.cpp
|
||||||
src/base/net/dns/Dns.cpp
|
src/base/net/dns/Dns.cpp
|
||||||
src/base/net/dns/DnsRecord.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/Client.cpp
|
||||||
src/base/net/stratum/Job.cpp
|
src/base/net/stratum/Job.cpp
|
||||||
src/base/net/stratum/Pool.cpp
|
src/base/net/stratum/Pool.cpp
|
||||||
@@ -57,7 +83,55 @@ set(SOURCES_BASE
|
|||||||
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(SOURCES_OS src/base/io/Json_win.cpp)
|
set(SOURCES_OS src/base/io/json/Json_win.cpp)
|
||||||
else()
|
else()
|
||||||
set(SOURCES_OS src/base/io/Json_unix.cpp)
|
set(SOURCES_OS src/base/io/json/Json_unix.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if (NOT WIN32)
|
||||||
|
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
|
||||||
|
if (HAVE_SYSLOG_H)
|
||||||
|
add_definitions(/DHAVE_SYSLOG_H)
|
||||||
|
set(SOURCES_SYSLOG src/base/io/log/backends/SysLog.h src/base/io/log/backends/SysLog.cpp)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if (WITH_HTTP)
|
||||||
|
set(HEADERS_BASE_HTTP
|
||||||
|
src/3rdparty/http-parser/http_parser.h
|
||||||
|
src/base/kernel/interfaces/IHttpListener.h
|
||||||
|
src/base/kernel/interfaces/IJsonReader.h
|
||||||
|
src/base/kernel/interfaces/ITcpServerListener.h
|
||||||
|
src/base/net/http/HttpApiResponse.h
|
||||||
|
src/base/net/http/HttpClient.h
|
||||||
|
src/base/net/http/HttpContext.h
|
||||||
|
src/base/net/http/HttpData.h
|
||||||
|
src/base/net/http/HttpResponse.h
|
||||||
|
src/base/net/http/HttpServer.h
|
||||||
|
src/base/net/stratum/DaemonClient.h
|
||||||
|
src/base/net/tools/TcpServer.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES_BASE_HTTP
|
||||||
|
src/3rdparty/http-parser/http_parser.c
|
||||||
|
src/base/net/http/HttpApiResponse.cpp
|
||||||
|
src/base/net/http/HttpClient.cpp
|
||||||
|
src/base/net/http/HttpContext.cpp
|
||||||
|
src/base/net/http/HttpResponse.cpp
|
||||||
|
src/base/net/http/HttpServer.cpp
|
||||||
|
src/base/net/stratum/DaemonClient.cpp
|
||||||
|
src/base/net/tools/TcpServer.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(/DXMRIG_FEATURE_HTTP)
|
||||||
|
add_definitions(/DXMRIG_FEATURE_API)
|
||||||
|
else()
|
||||||
|
set(HEADERS_BASE_HTTP "")
|
||||||
|
set(SOURCES_BASE_HTTP "")
|
||||||
|
remove_definitions(/DXMRIG_FEATURE_HTTP)
|
||||||
|
remove_definitions(/DXMRIG_FEATURE_API)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(/DXMRIG_DEPRECATED)
|
||||||
|
|||||||
@@ -23,10 +23,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "base/io/Json.h"
|
#include "base/io/json/Json.h"
|
||||||
#include "rapidjson/document.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)
|
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
|
||||||
{
|
{
|
||||||
auto i = obj.FindMember(key);
|
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)
|
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
|
||||||
{
|
{
|
||||||
auto i = obj.FindMember(key);
|
auto i = obj.FindMember(key);
|
||||||
@@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi
|
|||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::JsonReader::isEmpty() const
|
||||||
|
{
|
||||||
|
return !m_obj.IsObject() || m_obj.ObjectEmpty();
|
||||||
|
}
|
||||||
79
src/base/io/json/Json.h
Normal file
79
src/base/io/json/Json.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_JSON_H
|
||||||
|
#define XMRIG_JSON_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/IJsonReader.h"
|
||||||
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class Json
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
|
||||||
|
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
|
||||||
|
static const rapidjson::Value &getArray(const rapidjson::Value &obj, const char *key);
|
||||||
|
static const rapidjson::Value &getObject(const rapidjson::Value &obj, const char *key);
|
||||||
|
static const rapidjson::Value &getValue(const rapidjson::Value &obj, const char *key);
|
||||||
|
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
|
||||||
|
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
|
||||||
|
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
|
||||||
|
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
|
||||||
|
|
||||||
|
static bool get(const char *fileName, rapidjson::Document &doc);
|
||||||
|
static bool save(const char *fileName, const rapidjson::Document &doc);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JsonReader : public IJsonReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline JsonReader(const rapidjson::Value &obj) : m_obj(obj) {}
|
||||||
|
|
||||||
|
inline bool getBool(const char *key, bool defaultValue = false) const override { return Json::getBool(m_obj, key, defaultValue); }
|
||||||
|
inline const char *getString(const char *key, const char *defaultValue = nullptr) const override { return Json::getString(m_obj, key, defaultValue); }
|
||||||
|
inline const rapidjson::Value &getArray(const char *key) const override { return Json::getArray(m_obj, key); }
|
||||||
|
inline const rapidjson::Value &getObject(const char *key) const override { return Json::getObject(m_obj, key); }
|
||||||
|
inline const rapidjson::Value &getValue(const char *key) const override { return Json::getValue(m_obj, key); }
|
||||||
|
inline int getInt(const char *key, int defaultValue = 0) const override { return Json::getInt(m_obj, key, defaultValue); }
|
||||||
|
inline int64_t getInt64(const char *key, int64_t defaultValue = 0) const override { return Json::getInt64(m_obj, key, defaultValue); }
|
||||||
|
inline uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override { return Json::getUint64(m_obj, key, defaultValue); }
|
||||||
|
inline unsigned getUint(const char *key, unsigned defaultValue = 0) const override { return Json::getUint(m_obj, key, defaultValue); }
|
||||||
|
|
||||||
|
bool isEmpty() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const rapidjson::Value &m_obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_JSON_H */
|
||||||
213
src/base/io/json/JsonChain.cpp
Normal file
213
src/base/io/json/JsonChain.cpp
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/json/Json.h"
|
||||||
|
#include "base/io/json/JsonChain.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "rapidjson/error/en.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const rapidjson::Value kNullValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::JsonChain::JsonChain()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::JsonChain::add(rapidjson::Document &&doc)
|
||||||
|
{
|
||||||
|
if (doc.HasParseError() || !doc.IsObject() || doc.ObjectEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_chain.push_back(std::move(doc));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::JsonChain::addFile(const char *fileName)
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
Document doc;
|
||||||
|
if (Json::get(fileName, doc)) {
|
||||||
|
m_fileName = fileName;
|
||||||
|
|
||||||
|
return add(std::move(doc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc.HasParseError()) {
|
||||||
|
LOG_ERR("%s<offset:%zu>: \"%s\"", fileName, doc.GetErrorOffset(), GetParseError_En(doc.GetParseError()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_ERR("unable to open \"%s\".", fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::JsonChain::addRaw(const char *json)
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
Document doc;
|
||||||
|
doc.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(json);
|
||||||
|
|
||||||
|
return add(std::move(doc));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::JsonChain::dump(const char *fileName)
|
||||||
|
{
|
||||||
|
rapidjson::Document doc(rapidjson::kArrayType);
|
||||||
|
|
||||||
|
for (rapidjson::Document &value : m_chain) {
|
||||||
|
doc.PushBack(value, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::save(fileName, doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::JsonChain::getBool(const char *key, bool defaultValue) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsBool()) {
|
||||||
|
return i->value.GetBool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *xmrig::JsonChain::getString(const char *key, const char *defaultValue) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsString()) {
|
||||||
|
return i->value.GetString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const rapidjson::Value &xmrig::JsonChain::getArray(const char *key) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsArray()) {
|
||||||
|
return i->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kNullValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const rapidjson::Value &xmrig::JsonChain::getObject(const char *key) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsObject()) {
|
||||||
|
return i->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kNullValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd()) {
|
||||||
|
return i->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kNullValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int xmrig::JsonChain::getInt(const char *key, int defaultValue) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsInt()) {
|
||||||
|
return i->value.GetInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t xmrig::JsonChain::getInt64(const char *key, int64_t defaultValue) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsInt64()) {
|
||||||
|
return i->value.GetInt64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t xmrig::JsonChain::getUint64(const char *key, uint64_t defaultValue) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsUint64()) {
|
||||||
|
return i->value.GetUint64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned xmrig::JsonChain::getUint(const char *key, unsigned defaultValue) const
|
||||||
|
{
|
||||||
|
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
|
||||||
|
auto i = it->FindMember(key);
|
||||||
|
if (i != it->MemberEnd() && i->value.IsUint()) {
|
||||||
|
return i->value.GetUint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
76
src/base/io/json/JsonChain.h
Normal file
76
src/base/io/json/JsonChain.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_JSONCHAIN_H
|
||||||
|
#define XMRIG_JSONCHAIN_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/IJsonReader.h"
|
||||||
|
#include "base/tools/String.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class JsonChain : public IJsonReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JsonChain();
|
||||||
|
|
||||||
|
bool add(rapidjson::Document &&doc);
|
||||||
|
bool addFile(const char *fileName);
|
||||||
|
bool addRaw(const char *json);
|
||||||
|
|
||||||
|
void dump(const char *fileName);
|
||||||
|
|
||||||
|
inline const String &fileName() const { return m_fileName; }
|
||||||
|
inline size_t size() const { return m_chain.size(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline bool isEmpty() const override { return m_chain.empty(); }
|
||||||
|
|
||||||
|
bool getBool(const char *key, bool defaultValue = false) const override;
|
||||||
|
const char *getString(const char *key, const char *defaultValue = nullptr) const override;
|
||||||
|
const rapidjson::Value &getArray(const char *key) const override;
|
||||||
|
const rapidjson::Value &getObject(const char *key) const override;
|
||||||
|
const rapidjson::Value &getValue(const char *key) const override;
|
||||||
|
int getInt(const char *key, int defaultValue = 0) const override;
|
||||||
|
int64_t getInt64(const char *key, int64_t defaultValue = 0) const override;
|
||||||
|
uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override;
|
||||||
|
unsigned getUint(const char *key, unsigned defaultValue = 0) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<rapidjson::Document> m_chain;
|
||||||
|
String m_fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_JSONCHAIN_H */
|
||||||
38
src/base/io/json/JsonRequest.cpp
Normal file
38
src/base/io/json/JsonRequest.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/json/JsonRequest.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value ¶ms)
|
||||||
|
{
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
doc.AddMember("id", id, allocator);
|
||||||
|
doc.AddMember("jsonrpc", "2.0", allocator);
|
||||||
|
doc.AddMember("method", rapidjson::StringRef(method), allocator);
|
||||||
|
doc.AddMember("params", params, allocator);
|
||||||
|
}
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,32 +22,24 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __HTTPREPLY_H__
|
#ifndef XMRIG_JSONREQUEST_H
|
||||||
#define __HTTPREPLY_H__
|
#define XMRIG_JSONREQUEST_H
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class HttpReply
|
class JsonRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HttpReply() :
|
static void create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value ¶ms);
|
||||||
buf(nullptr),
|
|
||||||
status(200),
|
|
||||||
size(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
char *buf;
|
|
||||||
int status;
|
|
||||||
size_t size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} /* namespace xmrig */
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
#endif /* __HTTPREPLY_H__ */
|
#endif /* XMRIG_JSONREQUEST_H */
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
#include "base/io/Json.h"
|
#include "base/io/json/Json.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
#include "rapidjson/istreamwrapper.h"
|
#include "rapidjson/istreamwrapper.h"
|
||||||
#include "rapidjson/ostreamwrapper.h"
|
#include "rapidjson/ostreamwrapper.h"
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
#include "base/io/Json.h"
|
#include "base/io/json/Json.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
#include "rapidjson/istreamwrapper.h"
|
#include "rapidjson/istreamwrapper.h"
|
||||||
#include "rapidjson/ostreamwrapper.h"
|
#include "rapidjson/ostreamwrapper.h"
|
||||||
@@ -102,7 +102,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
# elif defined(__GNUC__)
|
# 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) {
|
if (fd == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
250
src/base/io/log/Log.cpp
Normal file
250
src/base/io/log/Log.cpp
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <time.h>
|
||||||
|
#include <uv.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/kernel/interfaces/ILogBackend.h"
|
||||||
|
#include "base/tools/Chrono.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
static const char *colors_map[] = {
|
||||||
|
RED_BOLD_S, // EMERG
|
||||||
|
RED_BOLD_S, // ALERT
|
||||||
|
RED_BOLD_S, // CRIT
|
||||||
|
RED_S, // ERR
|
||||||
|
YELLOW_S, // WARNING
|
||||||
|
WHITE_BOLD_S, // NOTICE
|
||||||
|
nullptr, // INFO
|
||||||
|
# ifdef WIN32
|
||||||
|
BLACK_BOLD_S // DEBUG
|
||||||
|
# else
|
||||||
|
BRIGHT_BLACK_S // DEBUG
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LogPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline LogPrivate() :
|
||||||
|
m_buf()
|
||||||
|
{
|
||||||
|
uv_mutex_init(&m_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline ~LogPrivate()
|
||||||
|
{
|
||||||
|
uv_mutex_destroy(&m_mutex);
|
||||||
|
|
||||||
|
for (ILogBackend *backend : m_backends) {
|
||||||
|
delete backend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void add(ILogBackend *backend) { m_backends.push_back(backend); }
|
||||||
|
|
||||||
|
|
||||||
|
void print(Log::Level level, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
|
lock();
|
||||||
|
timestamp(level, size, offset);
|
||||||
|
color(level, size);
|
||||||
|
|
||||||
|
const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args);
|
||||||
|
if (rc < 0) {
|
||||||
|
return unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
size += std::min(static_cast<size_t>(rc), sizeof (m_buf) - offset - 32);
|
||||||
|
endl(size);
|
||||||
|
|
||||||
|
std::string txt(m_buf);
|
||||||
|
size_t i;
|
||||||
|
while ((i = txt.find(CSI)) != std::string::npos) {
|
||||||
|
txt.erase(i, txt.find('m', i) - i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_backends.empty()) {
|
||||||
|
for (ILogBackend *backend : m_backends) {
|
||||||
|
backend->print(level, m_buf, offset, size, true);
|
||||||
|
backend->print(level, txt.c_str(), offset, txt.size(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fputs(txt.c_str(), stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline void lock() { uv_mutex_lock(&m_mutex); }
|
||||||
|
inline void unlock() { uv_mutex_unlock(&m_mutex); }
|
||||||
|
|
||||||
|
|
||||||
|
inline void timestamp(Log::Level level, size_t &size, size_t &offset)
|
||||||
|
{
|
||||||
|
if (level == Log::NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t ms = Chrono::currentMSecsSinceEpoch();
|
||||||
|
time_t now = ms / 1000;
|
||||||
|
tm stime;
|
||||||
|
|
||||||
|
# ifdef _WIN32
|
||||||
|
localtime_s(&stime, &now);
|
||||||
|
# else
|
||||||
|
localtime_r(&now, &stime);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ",
|
||||||
|
stime.tm_year + 1900,
|
||||||
|
stime.tm_mon + 1,
|
||||||
|
stime.tm_mday,
|
||||||
|
stime.tm_hour,
|
||||||
|
stime.tm_min,
|
||||||
|
stime.tm_sec,
|
||||||
|
static_cast<int>(ms % 1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rc > 0) {
|
||||||
|
size = offset = static_cast<size_t>(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void color(Log::Level level, size_t &size)
|
||||||
|
{
|
||||||
|
if (level == Log::NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *color = colors_map[level];
|
||||||
|
if (color == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t s = strlen(color);
|
||||||
|
memcpy(m_buf + size, color, s);
|
||||||
|
|
||||||
|
size += s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void endl(size_t &size)
|
||||||
|
{
|
||||||
|
# ifdef _WIN32
|
||||||
|
memcpy(m_buf + size, CLEAR "\r\n", 7);
|
||||||
|
size += 6;
|
||||||
|
# else
|
||||||
|
memcpy(m_buf + size, CLEAR "\n", 6);
|
||||||
|
size += 5;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char m_buf[4096];
|
||||||
|
std::vector<ILogBackend*> m_backends;
|
||||||
|
uv_mutex_t m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool Log::colors = true;
|
||||||
|
LogPrivate *Log::d = new LogPrivate();
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Log::add(ILogBackend *backend)
|
||||||
|
{
|
||||||
|
if (d) {
|
||||||
|
d->add(backend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Log::destroy()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
d = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Log::print(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (!d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
d->print(NONE, fmt, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Log::print(Level level, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (!d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
d->print(level, fmt, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
129
src/base/io/log/Log.h
Normal file
129
src/base/io/log/Log.h
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_LOG_H
|
||||||
|
#define XMRIG_LOG_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class ILogBackend;
|
||||||
|
class LogPrivate;
|
||||||
|
|
||||||
|
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Level : int {
|
||||||
|
NONE = -1,
|
||||||
|
EMERG, // system is unusable
|
||||||
|
ALERT, // action must be taken immediately
|
||||||
|
CRIT, // critical conditions
|
||||||
|
ERR, // error conditions
|
||||||
|
WARNING, // warning conditions
|
||||||
|
NOTICE, // normal but significant condition
|
||||||
|
INFO, // informational
|
||||||
|
DEBUG, // debug-level messages
|
||||||
|
};
|
||||||
|
|
||||||
|
static void add(ILogBackend *backend);
|
||||||
|
static void destroy();
|
||||||
|
static void print(const char *fmt, ...);
|
||||||
|
static void print(Level level, const char *fmt, ...);
|
||||||
|
|
||||||
|
static bool colors;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static LogPrivate *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define CSI "\x1B[" // Control Sequence Introducer (ANSI spec name)
|
||||||
|
#define CLEAR CSI "0m" // all attributes off
|
||||||
|
#define BRIGHT_BLACK_S CSI "0;90m" // somewhat MD.GRAY
|
||||||
|
#define BLACK_S CSI "0;30m"
|
||||||
|
#define BLACK_BOLD_S CSI "1;30m" // another name for GRAY
|
||||||
|
#define RED_S CSI "0;31m"
|
||||||
|
#define RED_BOLD_S CSI "1;31m"
|
||||||
|
#define GREEN_S CSI "0;32m"
|
||||||
|
#define GREEN_BOLD_S CSI "1;32m"
|
||||||
|
#define YELLOW_S CSI "0;33m"
|
||||||
|
#define YELLOW_BOLD_S CSI "1;33m"
|
||||||
|
#define BLUE_S CSI "0;34m"
|
||||||
|
#define BLUE_BOLD_S CSI "1;34m"
|
||||||
|
#define MAGENTA_S CSI "0;35m"
|
||||||
|
#define MAGENTA_BOLD_S CSI "1;35m"
|
||||||
|
#define CYAN_S CSI "0;36m"
|
||||||
|
#define CYAN_BOLD_S CSI "1;36m"
|
||||||
|
#define WHITE_S CSI "0;37m" // another name for LT.GRAY
|
||||||
|
#define WHITE_BOLD_S CSI "1;37m" // actually white
|
||||||
|
|
||||||
|
//color wrappings
|
||||||
|
#define BLACK(x) BLACK_S x CLEAR
|
||||||
|
#define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR
|
||||||
|
#define RED(x) RED_S x CLEAR
|
||||||
|
#define RED_BOLD(x) RED_BOLD_S x CLEAR
|
||||||
|
#define GREEN(x) GREEN_S x CLEAR
|
||||||
|
#define GREEN_BOLD(x) GREEN_BOLD_S x CLEAR
|
||||||
|
#define YELLOW(x) YELLOW_S x CLEAR
|
||||||
|
#define YELLOW_BOLD(x) YELLOW_BOLD_S x CLEAR
|
||||||
|
#define BLUE(x) BLUE_S x CLEAR
|
||||||
|
#define BLUE_BOLD(x) BLUE_BOLD_S x CLEAR
|
||||||
|
#define MAGENTA(x) MAGENTA_S x CLEAR
|
||||||
|
#define MAGENTA_BOLD(x) MAGENTA_BOLD_S x CLEAR
|
||||||
|
#define CYAN(x) CYAN_S x CLEAR
|
||||||
|
#define CYAN_BOLD(x) CYAN_BOLD_S x CLEAR
|
||||||
|
#define WHITE(x) WHITE_S x CLEAR
|
||||||
|
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
|
||||||
|
|
||||||
|
|
||||||
|
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
|
||||||
|
#define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__)
|
||||||
|
#define LOG_CRIT(x, ...) xmrig::Log::print(xmrig::Log::CRIT, x, ##__VA_ARGS__)
|
||||||
|
#define LOG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
|
||||||
|
#define LOG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
|
||||||
|
#define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__)
|
||||||
|
#define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef APP_DEBUG
|
||||||
|
# define LOG_DEBUG(x, ...) xmrig::Log::print(xmrig::Log::DEBUG, x, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
# define LOG_DEBUG(x, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(APP_DEBUG) || defined(APP_DEVEL)
|
||||||
|
# define LOG_DEBUG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
|
||||||
|
# define LOG_DEBUG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
# define LOG_DEBUG_ERR(x, ...)
|
||||||
|
# define LOG_DEBUG_WARN(x, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_LOG_H */
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -23,21 +24,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
# include <winsock2.h>
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "base/tools/Handle.h"
|
#include "base/tools/Handle.h"
|
||||||
#include "common/log/ConsoleLog.h"
|
#include "base/io/log/backends/ConsoleLog.h"
|
||||||
#include "common/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
|
|
||||||
|
|
||||||
xmrig::ConsoleLog::ConsoleLog() :
|
xmrig::ConsoleLog::ConsoleLog() :
|
||||||
@@ -51,7 +43,6 @@ xmrig::ConsoleLog::ConsoleLog() :
|
|||||||
}
|
}
|
||||||
|
|
||||||
uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
|
uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
|
||||||
m_uvBuf.base = m_buf;
|
|
||||||
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
|
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
|
||||||
|
|
||||||
# ifdef WIN32
|
# ifdef WIN32
|
||||||
@@ -73,38 +64,25 @@ xmrig::ConsoleLog::~ConsoleLog()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::ConsoleLog::message(Level level, const char* fmt, va_list args)
|
void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors)
|
||||||
{
|
{
|
||||||
time_t now = time(nullptr);
|
if (Log::colors != colors) {
|
||||||
tm stime;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
localtime_s(&stime, &now);
|
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), static_cast<unsigned int>(size));
|
||||||
# else
|
# else
|
||||||
localtime_r(&now, &stime);
|
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), size);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
|
if (!isWritable()) {
|
||||||
stime.tm_year + 1900,
|
fputs(line, stdout);
|
||||||
stime.tm_mon + 1,
|
fflush(stdout);
|
||||||
stime.tm_mday,
|
}
|
||||||
stime.tm_hour,
|
else {
|
||||||
stime.tm_min,
|
uv_try_write(m_stream, &buf, 1);
|
||||||
stime.tm_sec,
|
}
|
||||||
Log::colorByLevel(level, Log::colors),
|
|
||||||
fmt,
|
|
||||||
Log::endl(Log::colors)
|
|
||||||
);
|
|
||||||
|
|
||||||
print(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::ConsoleLog::text(const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(Log::colors));
|
|
||||||
|
|
||||||
print(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,20 +95,3 @@ bool xmrig::ConsoleLog::isWritable() const
|
|||||||
const uv_handle_type type = uv_guess_handle(1);
|
const uv_handle_type type = uv_guess_handle(1);
|
||||||
return type == UV_TTY || type == UV_NAMED_PIPE;
|
return type == UV_TTY || type == UV_NAMED_PIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -26,10 +27,11 @@
|
|||||||
#define XMRIG_CONSOLELOG_H
|
#define XMRIG_CONSOLELOG_H
|
||||||
|
|
||||||
|
|
||||||
#include <uv.h>
|
typedef struct uv_stream_s uv_stream_t;
|
||||||
|
typedef struct uv_tty_s uv_tty_t;
|
||||||
|
|
||||||
|
|
||||||
#include "common/interfaces/ILogBackend.h"
|
#include "base/kernel/interfaces/ILogBackend.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
@@ -42,16 +44,11 @@ public:
|
|||||||
~ConsoleLog() override;
|
~ConsoleLog() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void message(Level level, const char *fmt, va_list args) override;
|
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
|
||||||
void text(const char *fmt, va_list args) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isWritable() const;
|
bool isWritable() const;
|
||||||
void print(va_list args);
|
|
||||||
|
|
||||||
char m_buf[kBufferSize];
|
|
||||||
char m_fmt[256];
|
|
||||||
uv_buf_t m_uvBuf;
|
|
||||||
uv_stream_t *m_stream;
|
uv_stream_t *m_stream;
|
||||||
uv_tty_t *m_tty;
|
uv_tty_t *m_tty;
|
||||||
};
|
};
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -23,15 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
#include "common/log/FileLog.h"
|
#include "base/io/log/backends/FileLog.h"
|
||||||
#include "common/log/Log.h"
|
|
||||||
|
|
||||||
|
|
||||||
xmrig::FileLog::FileLog(const char *fileName)
|
xmrig::FileLog::FileLog(const char *fileName)
|
||||||
@@ -42,43 +39,22 @@ xmrig::FileLog::FileLog(const char *fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::FileLog::message(Level level, const char* fmt, va_list args)
|
void xmrig::FileLog::print(int, const char *line, size_t, size_t size, bool colors)
|
||||||
{
|
{
|
||||||
if (m_file < 0) {
|
if (m_file < 0 || colors) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t now = time(nullptr);
|
|
||||||
tm stime;
|
|
||||||
|
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
localtime_s(&stime, &now);
|
uv_buf_t buf = uv_buf_init(strdup(line), static_cast<unsigned int>(size));
|
||||||
# else
|
# else
|
||||||
localtime_r(&now, &stime);
|
uv_buf_t buf = uv_buf_init(strdup(line), size);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
|
uv_fs_t *req = new uv_fs_t;
|
||||||
stime.tm_year + 1900,
|
req->data = buf.base;
|
||||||
stime.tm_mon + 1,
|
|
||||||
stime.tm_mday,
|
|
||||||
stime.tm_hour,
|
|
||||||
stime.tm_min,
|
|
||||||
stime.tm_sec,
|
|
||||||
Log::colorByLevel(level, Log::colors),
|
|
||||||
fmt,
|
|
||||||
Log::endl(Log::colors)
|
|
||||||
);
|
|
||||||
|
|
||||||
char *buf = new char[kBufferSize];
|
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, FileLog::onWrite);
|
||||||
const int size = vsnprintf(buf, kBufferSize - 1, m_fmt, args);
|
|
||||||
|
|
||||||
write(buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::FileLog::text(const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
message(INFO, fmt, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -89,13 +65,3 @@ void xmrig::FileLog::onWrite(uv_fs_t *req)
|
|||||||
uv_fs_req_cleanup(req);
|
uv_fs_req_cleanup(req);
|
||||||
delete req;
|
delete req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::FileLog::write(char *data, size_t size)
|
|
||||||
{
|
|
||||||
uv_buf_t buf = uv_buf_init(data, (unsigned int) size);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -26,10 +27,10 @@
|
|||||||
#define XMRIG_FILELOG_H
|
#define XMRIG_FILELOG_H
|
||||||
|
|
||||||
|
|
||||||
#include <uv.h>
|
typedef struct uv_fs_s uv_fs_t;
|
||||||
|
|
||||||
|
|
||||||
#include "common/interfaces/ILogBackend.h"
|
#include "base/kernel/interfaces/ILogBackend.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
@@ -40,15 +41,13 @@ class FileLog : public ILogBackend
|
|||||||
public:
|
public:
|
||||||
FileLog(const char *fileName);
|
FileLog(const char *fileName);
|
||||||
|
|
||||||
void message(Level level, const char* fmt, va_list args) override;
|
|
||||||
void text(const char* fmt, va_list args) override;
|
protected:
|
||||||
|
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void onWrite(uv_fs_t *req);
|
static void onWrite(uv_fs_t *req);
|
||||||
|
|
||||||
void write(char *data, size_t size);
|
|
||||||
|
|
||||||
char m_fmt[256];
|
|
||||||
int m_file;
|
int m_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
|
|
||||||
#include "common/log/SysLog.h"
|
#include "base/io/log/backends/SysLog.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -36,13 +37,17 @@ xmrig::SysLog::SysLog()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::SysLog::message(Level level, const char *fmt, va_list args)
|
xmrig::SysLog::~SysLog()
|
||||||
{
|
{
|
||||||
vsyslog(static_cast<int>(level), fmt, args);
|
closelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::SysLog::text(const char *fmt, va_list args)
|
void xmrig::SysLog::print(int level, const char *line, size_t offset, size_t, bool colors)
|
||||||
{
|
{
|
||||||
vsyslog(LOG_INFO, fmt, args);
|
if (colors) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
syslog(level == -1 ? LOG_INFO : level, "%s", line + offset);
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
#define XMRIG_SYSLOG_H
|
#define XMRIG_SYSLOG_H
|
||||||
|
|
||||||
|
|
||||||
#include "common/interfaces/ILogBackend.h"
|
#include "base/kernel/interfaces/ILogBackend.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
@@ -36,9 +37,10 @@ class SysLog : public ILogBackend
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SysLog();
|
SysLog();
|
||||||
|
~SysLog();
|
||||||
|
|
||||||
void message(Level level, const char *fmt, va_list args) override;
|
protected:
|
||||||
void text(const char *fmt, va_list args) override;
|
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
290
src/base/kernel/Base.cpp
Normal file
290
src/base/kernel/Base.cpp
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/json/Json.h"
|
||||||
|
#include "base/io/json/JsonChain.h"
|
||||||
|
#include "base/io/log/backends/ConsoleLog.h"
|
||||||
|
#include "base/io/log/backends/FileLog.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/io/Watcher.h"
|
||||||
|
#include "base/kernel/Base.h"
|
||||||
|
#include "base/kernel/interfaces/IBaseListener.h"
|
||||||
|
#include "base/kernel/Process.h"
|
||||||
|
#include "common/Platform.h"
|
||||||
|
#include "core/config/Config.h"
|
||||||
|
#include "core/config/ConfigTransform.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_SYSLOG_H
|
||||||
|
# include "base/io/log/backends/SysLog.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_API
|
||||||
|
# include "api/Api.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||||
|
# include "core/config/Config_default.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
class xmrig::BasePrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline BasePrivate(Process *process) :
|
||||||
|
api(nullptr),
|
||||||
|
config(nullptr),
|
||||||
|
process(process),
|
||||||
|
watcher(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
inline ~BasePrivate()
|
||||||
|
{
|
||||||
|
# ifdef XMRIG_FEATURE_API
|
||||||
|
delete api;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
delete config;
|
||||||
|
delete watcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool read(const JsonChain &chain, std::unique_ptr<Config> &config)
|
||||||
|
{
|
||||||
|
config = std::unique_ptr<Config>(new Config());
|
||||||
|
|
||||||
|
return config->read(chain, chain.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Config *load()
|
||||||
|
{
|
||||||
|
JsonChain chain;
|
||||||
|
ConfigTransform transform;
|
||||||
|
std::unique_ptr<Config> config;
|
||||||
|
|
||||||
|
transform.load(chain, process, transform);
|
||||||
|
|
||||||
|
if (read(chain, config)) {
|
||||||
|
return config.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.addFile(process->location(Process::ExeLocation, "config.json"));
|
||||||
|
|
||||||
|
if (read(chain, config)) {
|
||||||
|
return config.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||||
|
chain.addRaw(default_config);
|
||||||
|
|
||||||
|
if (read(chain, config)) {
|
||||||
|
return config.release();
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void replace(Config *newConfig)
|
||||||
|
{
|
||||||
|
Config *previousConfig = config;
|
||||||
|
config = newConfig;
|
||||||
|
|
||||||
|
for (IBaseListener *listener : listeners) {
|
||||||
|
listener->onConfigChanged(config, previousConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete previousConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Api *api;
|
||||||
|
Config *config;
|
||||||
|
Process *process;
|
||||||
|
std::vector<IBaseListener *> listeners;
|
||||||
|
Watcher *watcher;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::Base::Base(Process *process)
|
||||||
|
: d_ptr(new BasePrivate(process))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::Base::~Base()
|
||||||
|
{
|
||||||
|
delete d_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::Base::isReady() const
|
||||||
|
{
|
||||||
|
return d_ptr->config != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int xmrig::Base::init()
|
||||||
|
{
|
||||||
|
d_ptr->config = d_ptr->load();
|
||||||
|
|
||||||
|
if (!d_ptr->config) {
|
||||||
|
LOG_EMERG("No valid configuration found. Exiting.");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_API
|
||||||
|
d_ptr->api = new Api(this);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
Platform::init(config()->userAgent());
|
||||||
|
|
||||||
|
# ifndef XMRIG_PROXY_PROJECT
|
||||||
|
Platform::setProcessPriority(config()->priority());
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (!config()->isBackground()) {
|
||||||
|
Log::add(new ConsoleLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config()->logFile()) {
|
||||||
|
Log::add(new FileLog(config()->logFile()));
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef HAVE_SYSLOG_H
|
||||||
|
if (config()->isSyslog()) {
|
||||||
|
Log::add(new SysLog());
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Base::start()
|
||||||
|
{
|
||||||
|
# ifdef XMRIG_FEATURE_API
|
||||||
|
api()->start();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (config()->isShouldSave()) {
|
||||||
|
config()->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config()->isWatch()) {
|
||||||
|
d_ptr->watcher = new Watcher(config()->fileName(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Base::stop()
|
||||||
|
{
|
||||||
|
# ifdef XMRIG_FEATURE_API
|
||||||
|
api()->stop();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
delete d_ptr->watcher;
|
||||||
|
d_ptr->watcher = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::Api *xmrig::Base::api() const
|
||||||
|
{
|
||||||
|
assert(d_ptr->api != nullptr);
|
||||||
|
|
||||||
|
return d_ptr->api;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::Base::reload(const rapidjson::Value &json)
|
||||||
|
{
|
||||||
|
JsonReader reader(json);
|
||||||
|
if (reader.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Config *config = new Config();
|
||||||
|
if (!config->read(reader, d_ptr->config->fileName())) {
|
||||||
|
delete config;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool saved = config->save();
|
||||||
|
|
||||||
|
if (config->isWatch() && d_ptr->watcher && saved) {
|
||||||
|
delete config;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
d_ptr->replace(config);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::Config *xmrig::Base::config() const
|
||||||
|
{
|
||||||
|
assert(d_ptr->config != nullptr);
|
||||||
|
|
||||||
|
return d_ptr->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Base::addListener(IBaseListener *listener)
|
||||||
|
{
|
||||||
|
d_ptr->listeners.push_back(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Base::onFileChanged(const String &fileName)
|
||||||
|
{
|
||||||
|
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
|
||||||
|
|
||||||
|
JsonChain chain;
|
||||||
|
chain.addFile(fileName);
|
||||||
|
|
||||||
|
Config *config = new Config();
|
||||||
|
|
||||||
|
if (!config->read(chain, chain.fileName())) {
|
||||||
|
LOG_ERR("reloading failed");
|
||||||
|
|
||||||
|
delete config;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d_ptr->replace(config);
|
||||||
|
}
|
||||||
@@ -22,42 +22,50 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XMRIG_CONFIGWATCHER_H
|
#ifndef XMRIG_BASE_H
|
||||||
#define XMRIG_CONFIGWATCHER_H
|
#define XMRIG_BASE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/IConfigListener.h"
|
||||||
#include "base/kernel/interfaces/IWatcherListener.h"
|
#include "base/kernel/interfaces/IWatcherListener.h"
|
||||||
#include "base/tools/String.h"
|
|
||||||
#include "rapidjson/fwd.h"
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
|
|
||||||
struct option;
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class IConfigCreator;
|
class Api;
|
||||||
class IConfigListener;
|
class Config;
|
||||||
class Watcher;
|
class BasePrivate;
|
||||||
|
class IBaseListener;
|
||||||
|
class Process;
|
||||||
|
|
||||||
|
|
||||||
class ConfigWatcher : public IWatcherListener
|
class Base : public IWatcherListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConfigWatcher(const String &path, IConfigCreator *creator, IConfigListener *listener);
|
Base(Process *process);
|
||||||
~ConfigWatcher() override;
|
~Base() override;
|
||||||
|
|
||||||
|
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:
|
protected:
|
||||||
void onFileChanged(const String &fileName) override;
|
void onFileChanged(const String &fileName) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IConfigCreator *m_creator;
|
BasePrivate *d_ptr;
|
||||||
IConfigListener *m_listener;
|
|
||||||
Watcher *m_watcher;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} /* namespace xmrig */
|
} /* namespace xmrig */
|
||||||
|
|
||||||
#endif /* __CONFIGWATCHER_H__ */
|
|
||||||
|
#endif /* XMRIG_BASE_H */
|
||||||
@@ -27,19 +27,14 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_HTTPD
|
#ifdef XMRIG_FEATURE_TLS
|
||||||
# include <microhttpd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
|
||||||
# include <openssl/opensslv.h>
|
# include <openssl/opensslv.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "base/kernel/Entry.h"
|
#include "base/kernel/Entry.h"
|
||||||
#include "base/kernel/Process.h"
|
#include "base/kernel/Process.h"
|
||||||
#include "core/usage.h"
|
#include "core/config/usage.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -73,11 +68,7 @@ static int showVersion()
|
|||||||
|
|
||||||
printf("\nlibuv/%s\n", uv_version_string());
|
printf("\nlibuv/%s\n", uv_version_string());
|
||||||
|
|
||||||
# ifndef XMRIG_NO_HTTPD
|
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||||
printf("microhttpd/%s\n", MHD_get_version());
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
|
|
||||||
{
|
{
|
||||||
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
||||||
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);
|
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);
|
||||||
|
|||||||
196
src/base/kernel/config/BaseConfig.cpp
Normal file
196
src/base/kernel/config/BaseConfig.cpp
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_TLS
|
||||||
|
# include <openssl/opensslv.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_AMD_PROJECT
|
||||||
|
# if defined(__APPLE__)
|
||||||
|
# include <OpenCL/cl.h>
|
||||||
|
# else
|
||||||
|
# include "3rdparty/CL/cl.h"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_NVIDIA_PROJECT
|
||||||
|
# include "nvidia/cryptonight.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/json/Json.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/kernel/config/BaseConfig.h"
|
||||||
|
#include "base/kernel/interfaces/IJsonReader.h"
|
||||||
|
#include "donate.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
#include "rapidjson/filewritestream.h"
|
||||||
|
#include "rapidjson/prettywriter.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::BaseConfig::BaseConfig() :
|
||||||
|
m_algorithm(CRYPTONIGHT, VARIANT_AUTO),
|
||||||
|
m_autoSave(true),
|
||||||
|
m_background(false),
|
||||||
|
m_dryRun(false),
|
||||||
|
m_syslog(false),
|
||||||
|
m_upgrade(false),
|
||||||
|
m_watch(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BaseConfig::printVersions()
|
||||||
|
{
|
||||||
|
char buf[256] = { 0 };
|
||||||
|
|
||||||
|
# if defined(__clang__)
|
||||||
|
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
|
||||||
|
# elif defined(__GNUC__)
|
||||||
|
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
|
||||||
|
# elif defined(_MSC_VER)
|
||||||
|
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf);
|
||||||
|
|
||||||
|
# if defined(XMRIG_AMD_PROJECT)
|
||||||
|
# if CL_VERSION_2_0
|
||||||
|
const char *ocl = "2.0";
|
||||||
|
# elif CL_VERSION_1_2
|
||||||
|
const char *ocl = "1.2";
|
||||||
|
# elif CL_VERSION_1_1
|
||||||
|
const char *ocl = "1.1";
|
||||||
|
# elif CL_VERSION_1_0
|
||||||
|
const char *ocl = "1.0";
|
||||||
|
# else
|
||||||
|
const char *ocl = "0.0";
|
||||||
|
# endif
|
||||||
|
int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl);
|
||||||
|
# elif defined(XMRIG_NVIDIA_PROJECT)
|
||||||
|
const int cudaVersion = cuda_get_runtime_version();
|
||||||
|
int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100);
|
||||||
|
# else
|
||||||
|
memset(buf, 0, 16);
|
||||||
|
|
||||||
|
# if defined(XMRIG_FEATURE_HTTP) || defined(XMRIG_FEATURE_TLS)
|
||||||
|
int length = 0;
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||||
|
{
|
||||||
|
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
||||||
|
length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
|
||||||
|
{
|
||||||
|
m_fileName = fileName;
|
||||||
|
|
||||||
|
if (reader.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_autoSave = reader.getBool("autosave", m_autoSave);
|
||||||
|
m_background = reader.getBool("background", m_background);
|
||||||
|
m_dryRun = reader.getBool("dry-run", m_dryRun);
|
||||||
|
m_syslog = reader.getBool("syslog", m_syslog);
|
||||||
|
m_watch = reader.getBool("watch", m_watch);
|
||||||
|
Log::colors = reader.getBool("colors", Log::colors);
|
||||||
|
m_logFile = reader.getString("log-file");
|
||||||
|
m_userAgent = reader.getString("user-agent");
|
||||||
|
|
||||||
|
setPrintTime(reader.getUint("print-time", 60));
|
||||||
|
|
||||||
|
const rapidjson::Value &api = reader.getObject("api");
|
||||||
|
if (api.IsObject()) {
|
||||||
|
m_apiId = Json::getString(api, "id");
|
||||||
|
m_apiWorkerId = Json::getString(api, "worker-id");
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_DEPRECATED
|
||||||
|
if (api.IsObject() && api.HasMember("port")) {
|
||||||
|
m_upgrade = true;
|
||||||
|
m_http.load(api);
|
||||||
|
m_http.setEnabled(Json::getUint(api, "port") > 0);
|
||||||
|
m_http.setHost("0.0.0.0");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_http.load(reader.getObject("http"));
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
m_http.load(chain.getObject("http"));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
m_algorithm.parseAlgorithm(reader.getString("algo", "cn"));
|
||||||
|
|
||||||
|
m_pools.load(reader.getArray("pools"));
|
||||||
|
m_pools.setDonateLevel(reader.getInt("donate-level", kDefaultDonateLevel));
|
||||||
|
m_pools.setProxyDonate(reader.getInt("donate-over-proxy", Pools::PROXY_DONATE_AUTO));
|
||||||
|
m_pools.setRetries(reader.getInt("retries"));
|
||||||
|
m_pools.setRetryPause(reader.getInt("retry-pause"));
|
||||||
|
|
||||||
|
if (!m_algorithm.isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pools.adjust(m_algorithm);
|
||||||
|
|
||||||
|
return m_pools.active() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BaseConfig::save()
|
||||||
|
{
|
||||||
|
if (m_fileName.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Document doc;
|
||||||
|
getJSON(doc);
|
||||||
|
|
||||||
|
if (Json::save(m_fileName, doc)) {
|
||||||
|
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -22,89 +22,75 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XMRIG_COMMONCONFIG_H
|
#ifndef XMRIG_BASECONFIG_H
|
||||||
#define XMRIG_COMMONCONFIG_H
|
#define XMRIG_BASECONFIG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/IConfig.h"
|
||||||
|
#include "base/net/http/Http.h"
|
||||||
#include "base/net/stratum/Pools.h"
|
#include "base/net/stratum/Pools.h"
|
||||||
#include "base/tools/String.h"
|
|
||||||
#include "common/interfaces/IConfig.h"
|
|
||||||
#include "common/xmrig.h"
|
#include "common/xmrig.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct option;
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class CommonConfig : public IConfig
|
class IJsonReader;
|
||||||
|
|
||||||
|
|
||||||
|
class BaseConfig : public IConfig
|
||||||
{
|
{
|
||||||
public:
|
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 isAutoSave() const { return m_autoSave; }
|
||||||
inline bool isBackground() const { return m_background; }
|
inline bool isBackground() const { return m_background; }
|
||||||
inline bool isDryRun() const { return m_dryRun; }
|
inline bool isDryRun() const { return m_dryRun; }
|
||||||
inline bool isSyslog() const { return m_syslog; }
|
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 *logFile() const { return m_logFile.data(); }
|
||||||
inline const char *userAgent() const { return m_userAgent.data(); }
|
inline const char *userAgent() const { return m_userAgent.data(); }
|
||||||
|
inline const Http &http() const { return m_http; }
|
||||||
inline const Pools &pools() const { return m_pools; }
|
inline const Pools &pools() const { return m_pools; }
|
||||||
inline int apiPort() const { return m_apiPort; }
|
inline const String &apiId() const { return m_apiId; }
|
||||||
inline int printTime() const { return m_printTime; }
|
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 bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
|
||||||
inline const Algorithm &algorithm() const override { return m_algorithm; }
|
inline const Algorithm &algorithm() const override { return m_algorithm; }
|
||||||
inline const String &fileName() const override { return m_fileName; }
|
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 save() override;
|
||||||
|
|
||||||
bool isColors() const;
|
|
||||||
void printAPI();
|
|
||||||
void printPools();
|
|
||||||
void printVersions();
|
void printVersions();
|
||||||
|
|
||||||
protected:
|
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;
|
Algorithm m_algorithm;
|
||||||
bool m_adjusted;
|
|
||||||
bool m_apiIPv6;
|
|
||||||
bool m_apiRestricted;
|
|
||||||
bool m_autoSave;
|
bool m_autoSave;
|
||||||
bool m_background;
|
bool m_background;
|
||||||
bool m_dryRun;
|
bool m_dryRun;
|
||||||
bool m_syslog;
|
bool m_syslog;
|
||||||
|
bool m_upgrade;
|
||||||
bool m_watch;
|
bool m_watch;
|
||||||
int m_apiPort;
|
Http m_http;
|
||||||
int m_printTime;
|
|
||||||
Pools m_pools;
|
Pools m_pools;
|
||||||
State m_state;
|
|
||||||
String m_apiId;
|
String m_apiId;
|
||||||
String m_apiToken;
|
|
||||||
String m_apiWorkerId;
|
String m_apiWorkerId;
|
||||||
String m_fileName;
|
String m_fileName;
|
||||||
String m_logFile;
|
String m_logFile;
|
||||||
String m_userAgent;
|
String m_userAgent;
|
||||||
|
uint32_t m_printTime;
|
||||||
|
|
||||||
private:
|
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 */
|
||||||
279
src/base/kernel/config/BaseTransform.cpp
Normal file
279
src/base/kernel/config/BaseTransform.cpp
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# include "getopt/getopt.h"
|
||||||
|
#else
|
||||||
|
# include <getopt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/config/BaseTransform.h"
|
||||||
|
#include "base/kernel/Process.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/kernel/interfaces/IConfig.h"
|
||||||
|
#include "base/io/json/JsonChain.h"
|
||||||
|
#include "core/config/Config_platform.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig
|
||||||
|
{
|
||||||
|
|
||||||
|
static const char *kApi = "api";
|
||||||
|
static const char *kHttp = "http";
|
||||||
|
static const char *kPools = "pools";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::BaseTransform::BaseTransform()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform)
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
|
||||||
|
int key;
|
||||||
|
int argc = process->arguments().argc();
|
||||||
|
char **argv = process->arguments().argv();
|
||||||
|
|
||||||
|
Document doc(kObjectType);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
key = getopt_long(argc, argv, short_options, options, nullptr);
|
||||||
|
if (key < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == IConfig::ConfigKey) {
|
||||||
|
chain.add(std::move(doc));
|
||||||
|
chain.addFile(optarg);
|
||||||
|
|
||||||
|
doc = Document(kObjectType);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
transform.transform(doc, key, optarg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind < argc) {
|
||||||
|
LOG_WARN("%s: unsupported non-option argument '%s'", argv[0], argv[optind]);
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.add(std::move(doc));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const char *arg)
|
||||||
|
{
|
||||||
|
switch (key) {
|
||||||
|
case IConfig::AlgorithmKey: /* --algo */
|
||||||
|
return set(doc, "algo", arg);
|
||||||
|
|
||||||
|
case IConfig::UserpassKey: /* --userpass */
|
||||||
|
{
|
||||||
|
const char *p = strrchr(arg, ':');
|
||||||
|
if (!p) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *user = new char[p - arg + 1]();
|
||||||
|
strncpy(user, arg, static_cast<size_t>(p - arg));
|
||||||
|
|
||||||
|
add<const char *>(doc, kPools, "user", user);
|
||||||
|
add(doc, kPools, "pass", p + 1);
|
||||||
|
delete [] user;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IConfig::UrlKey: /* --url */
|
||||||
|
return add(doc, kPools, "url", arg, true);
|
||||||
|
|
||||||
|
case IConfig::UserKey: /* --user */
|
||||||
|
return add(doc, kPools, "user", arg);
|
||||||
|
|
||||||
|
case IConfig::PasswordKey: /* --pass */
|
||||||
|
return add(doc, kPools, "pass", arg);
|
||||||
|
|
||||||
|
case IConfig::RigIdKey: /* --rig-id */
|
||||||
|
return add(doc, kPools, "rig-id", arg);
|
||||||
|
|
||||||
|
case IConfig::FingerprintKey: /* --tls-fingerprint */
|
||||||
|
return add(doc, kPools, "tls-fingerprint", arg);
|
||||||
|
|
||||||
|
case IConfig::VariantKey: /* --variant */
|
||||||
|
return add(doc, kPools, "variant", arg);
|
||||||
|
|
||||||
|
case IConfig::LogFileKey: /* --log-file */
|
||||||
|
return set(doc, "log-file", arg);
|
||||||
|
|
||||||
|
# ifdef XMRIG_DEPRECATED
|
||||||
|
case IConfig::ApiAccessTokenKey: /* --api-access-token */
|
||||||
|
fputs("option \"--api-access-token\" deprecated, use \"--http-access-token\" instead.\n", stderr);
|
||||||
|
fflush(stdout);
|
||||||
|
return set(doc, kHttp, "access-token", arg);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
case IConfig::HttpAccessTokenKey: /* --http-access-token */
|
||||||
|
return set(doc, kHttp, "access-token", arg);
|
||||||
|
|
||||||
|
case IConfig::HttpHostKey: /* --http-host */
|
||||||
|
return set(doc, kHttp, "host", arg);
|
||||||
|
|
||||||
|
case IConfig::ApiWorkerIdKey: /* --api-worker-id */
|
||||||
|
return set(doc, kApi, "worker-id", arg);
|
||||||
|
|
||||||
|
case IConfig::ApiIdKey: /* --api-id */
|
||||||
|
return set(doc, kApi, "id", arg);
|
||||||
|
|
||||||
|
case IConfig::UserAgentKey: /* --user-agent */
|
||||||
|
return set(doc, "user-agent", arg);
|
||||||
|
|
||||||
|
case IConfig::RetriesKey: /* --retries */
|
||||||
|
case IConfig::RetryPauseKey: /* --retry-pause */
|
||||||
|
case IConfig::PrintTimeKey: /* --print-time */
|
||||||
|
case IConfig::HttpPort: /* --http-port */
|
||||||
|
case IConfig::DonateLevelKey: /* --donate-level */
|
||||||
|
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
|
||||||
|
# ifdef XMRIG_DEPRECATED
|
||||||
|
case IConfig::ApiPort: /* --api-port */
|
||||||
|
# endif
|
||||||
|
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||||
|
|
||||||
|
case IConfig::BackgroundKey: /* --background */
|
||||||
|
case IConfig::SyslogKey: /* --syslog */
|
||||||
|
case IConfig::KeepAliveKey: /* --keepalive */
|
||||||
|
case IConfig::NicehashKey: /* --nicehash */
|
||||||
|
case IConfig::TlsKey: /* --tls */
|
||||||
|
case IConfig::DryRunKey: /* --dry-run */
|
||||||
|
case IConfig::HttpEnabledKey: /* --http-enabled */
|
||||||
|
case IConfig::DaemonKey: /* --daemon */
|
||||||
|
return transformBoolean(doc, key, true);
|
||||||
|
|
||||||
|
case IConfig::ColorKey: /* --no-color */
|
||||||
|
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
|
||||||
|
# ifdef XMRIG_DEPRECATED
|
||||||
|
case IConfig::ApiRestrictedKey: /* --api-no-restricted */
|
||||||
|
case IConfig::ApiIPv6Key: /* --api-ipv6 */
|
||||||
|
# endif
|
||||||
|
return transformBoolean(doc, key, false);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable)
|
||||||
|
{
|
||||||
|
switch (key) {
|
||||||
|
case IConfig::BackgroundKey: /* --background */
|
||||||
|
return set(doc, "background", enable);
|
||||||
|
|
||||||
|
case IConfig::SyslogKey: /* --syslog */
|
||||||
|
return set(doc, "syslog", enable);
|
||||||
|
|
||||||
|
case IConfig::KeepAliveKey: /* --keepalive */
|
||||||
|
return add(doc, kPools, "keepalive", enable);
|
||||||
|
|
||||||
|
case IConfig::TlsKey: /* --tls */
|
||||||
|
return add(doc, kPools, "tls", enable);
|
||||||
|
|
||||||
|
case IConfig::DaemonKey: /* --daemon */
|
||||||
|
return add(doc, kPools, "daemon", enable);
|
||||||
|
|
||||||
|
# ifndef XMRIG_PROXY_PROJECT
|
||||||
|
case IConfig::NicehashKey: /* --nicehash */
|
||||||
|
return add<bool>(doc, kPools, "nicehash", enable);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
case IConfig::ColorKey: /* --no-color */
|
||||||
|
return set(doc, "colors", enable);
|
||||||
|
|
||||||
|
# ifdef XMRIG_DEPRECATED
|
||||||
|
case IConfig::ApiIPv6Key: /* --api-ipv6 */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IConfig::ApiRestrictedKey: /* --api-no-restricted */
|
||||||
|
fputs("option \"--api-no-restricted\" deprecated, use \"--http-no-restricted\" instead.\n", stderr);
|
||||||
|
fflush(stdout);
|
||||||
|
return set(doc, kHttp, "restricted", enable);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
|
||||||
|
return set(doc, kHttp, "restricted", enable);
|
||||||
|
|
||||||
|
case IConfig::HttpEnabledKey: /* --http-enabled */
|
||||||
|
return set(doc, kHttp, "enabled", enable);
|
||||||
|
|
||||||
|
case IConfig::DryRunKey: /* --dry-run */
|
||||||
|
return set(doc, "dry-run", enable);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg)
|
||||||
|
{
|
||||||
|
switch (key) {
|
||||||
|
case IConfig::RetriesKey: /* --retries */
|
||||||
|
return set(doc, "retries", arg);
|
||||||
|
|
||||||
|
case IConfig::RetryPauseKey: /* --retry-pause */
|
||||||
|
return set(doc, "retry-pause", arg);
|
||||||
|
|
||||||
|
case IConfig::DonateLevelKey: /* --donate-level */
|
||||||
|
return set(doc, "donate-level", arg);
|
||||||
|
|
||||||
|
case IConfig::ProxyDonateKey: /* --donate-over-proxy */
|
||||||
|
return set(doc, "donate-over-proxy", arg);
|
||||||
|
|
||||||
|
# ifdef XMRIG_DEPRECATED
|
||||||
|
case IConfig::ApiPort: /* --api-port */
|
||||||
|
fputs("option \"--api-port\" deprecated, use \"--http-port\" instead.\n", stderr);
|
||||||
|
fflush(stdout);
|
||||||
|
return set(doc, kHttp, "port", arg);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
case IConfig::HttpPort: /* --http-port */
|
||||||
|
return set(doc, kHttp, "port", arg);
|
||||||
|
|
||||||
|
case IConfig::PrintTimeKey: /* --print-time */
|
||||||
|
return set(doc, "print-time", arg);
|
||||||
|
|
||||||
|
case IConfig::DaemonPollKey: /* --daemon-poll-interval */
|
||||||
|
return add(doc, kPools, "daemon-poll-interval", arg);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
123
src/base/kernel/config/BaseTransform.h
Normal file
123
src/base/kernel/config/BaseTransform.h
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_BASETRANSFORM_H
|
||||||
|
#define XMRIG_BASETRANSFORM_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/IConfigTransform.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct option;
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class IConfigTransform;
|
||||||
|
class JsonChain;
|
||||||
|
class Process;
|
||||||
|
|
||||||
|
|
||||||
|
class BaseTransform : public IConfigTransform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseTransform();
|
||||||
|
|
||||||
|
static void load(JsonChain &chain, Process *process, IConfigTransform &transform);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void transform(rapidjson::Document &doc, int key, const char *arg) override;
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void set(rapidjson::Document &doc, const char *key, T value) { set<T>(doc, doc, key, value); }
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void set(rapidjson::Document &doc, const char *objKey, const char *key, T value)
|
||||||
|
{
|
||||||
|
if (!doc.HasMember(objKey)) {
|
||||||
|
doc.AddMember(rapidjson::StringRef(objKey), rapidjson::kObjectType, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
set<T>(doc, doc[objKey], key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void add(rapidjson::Document &doc, const char *arrayKey, const char *key, T value, bool force = false)
|
||||||
|
{
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
if (!doc.HasMember(arrayKey)) {
|
||||||
|
doc.AddMember(rapidjson::StringRef(arrayKey), rapidjson::kArrayType, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
rapidjson::Value &array = doc[arrayKey];
|
||||||
|
if (force || array.Size() == 0) {
|
||||||
|
array.PushBack(rapidjson::kObjectType, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
set<T>(doc, array[array.Size() - 1], key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, T value)
|
||||||
|
{
|
||||||
|
if (obj.HasMember(key)) {
|
||||||
|
obj[key] = value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.AddMember(rapidjson::StringRef(key), value, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void transformBoolean(rapidjson::Document &doc, int key, bool enable);
|
||||||
|
void transformUint64(rapidjson::Document &doc, int key, uint64_t arg);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void BaseTransform::set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
if (obj.HasMember(key)) {
|
||||||
|
obj[key] = rapidjson::Value(value, allocator);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.AddMember(rapidjson::StringRef(key), rapidjson::Value(value, allocator), allocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_BASETRANSFORM_H */
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XMRIG_ICONTROLLERLISTENER_H
|
#ifndef XMRIG_IBASELISTENER_H
|
||||||
#define XMRIG_ICONTROLLERLISTENER_H
|
#define XMRIG_IBASELISTENER_H
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
@@ -32,10 +32,10 @@ namespace xmrig {
|
|||||||
class Config;
|
class Config;
|
||||||
|
|
||||||
|
|
||||||
class IControllerListener
|
class IBaseListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IControllerListener() = default;
|
virtual ~IBaseListener() = default;
|
||||||
|
|
||||||
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
||||||
};
|
};
|
||||||
@@ -44,4 +44,4 @@ public:
|
|||||||
} /* namespace xmrig */
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
#endif // XMRIG_ICONTROLLERLISTENER_H
|
#endif // XMRIG_IBASELISTENER_H
|
||||||
85
src/base/kernel/interfaces/IClient.h
Normal file
85
src/base/kernel/interfaces/IClient.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_ICLIENT_H
|
||||||
|
#define XMRIG_ICLIENT_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class Algorithm;
|
||||||
|
class Job;
|
||||||
|
class JobResult;
|
||||||
|
class Pool;
|
||||||
|
class String;
|
||||||
|
|
||||||
|
|
||||||
|
class IClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Extension {
|
||||||
|
EXT_ALGO,
|
||||||
|
EXT_NICEHASH,
|
||||||
|
EXT_CONNECT,
|
||||||
|
EXT_TLS,
|
||||||
|
EXT_KEEPALIVE,
|
||||||
|
EXT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~IClient() = default;
|
||||||
|
|
||||||
|
virtual bool disconnect() = 0;
|
||||||
|
virtual bool hasExtension(Extension extension) const noexcept = 0;
|
||||||
|
virtual bool isEnabled() const = 0;
|
||||||
|
virtual bool isTLS() const = 0;
|
||||||
|
virtual const char *mode() const = 0;
|
||||||
|
virtual const char *tlsFingerprint() const = 0;
|
||||||
|
virtual const char *tlsVersion() const = 0;
|
||||||
|
virtual const Job &job() const = 0;
|
||||||
|
virtual const Pool &pool() const = 0;
|
||||||
|
virtual const String &ip() const = 0;
|
||||||
|
virtual int id() const = 0;
|
||||||
|
virtual int64_t submit(const JobResult &result) = 0;
|
||||||
|
virtual void connect() = 0;
|
||||||
|
virtual void connect(const Pool &pool) = 0;
|
||||||
|
virtual void deleteLater() = 0;
|
||||||
|
virtual void setAlgo(const Algorithm &algo) = 0;
|
||||||
|
virtual void setEnabled(bool enabled) = 0;
|
||||||
|
virtual void setPool(const Pool &pool) = 0;
|
||||||
|
virtual void setQuiet(bool quiet) = 0;
|
||||||
|
virtual void setRetries(int retries) = 0;
|
||||||
|
virtual void setRetryPause(uint64_t ms) = 0;
|
||||||
|
virtual void tick(uint64_t now) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_ICLIENT_H
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class Client;
|
class IClient;
|
||||||
class Job;
|
class Job;
|
||||||
class SubmitResult;
|
class SubmitResult;
|
||||||
|
|
||||||
@@ -45,11 +45,11 @@ class IClientListener
|
|||||||
public:
|
public:
|
||||||
virtual ~IClientListener() = default;
|
virtual ~IClientListener() = default;
|
||||||
|
|
||||||
virtual void onClose(Client *client, int failures) = 0;
|
virtual void onClose(IClient *client, int failures) = 0;
|
||||||
virtual void onJobReceived(Client *client, const Job &job, const rapidjson::Value ¶ms) = 0;
|
virtual void onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms) = 0;
|
||||||
virtual void onLogin(Client *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0;
|
virtual void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0;
|
||||||
virtual void onLoginSuccess(Client *client) = 0;
|
virtual void onLoginSuccess(IClient *client) = 0;
|
||||||
virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
|
virtual void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
157
src/base/kernel/interfaces/IConfig.h
Normal file
157
src/base/kernel/interfaces/IConfig.h
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_ICONFIG_H
|
||||||
|
#define XMRIG_ICONFIG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "common/crypto/Algorithm.h"
|
||||||
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class IJsonReader;
|
||||||
|
class String;
|
||||||
|
|
||||||
|
|
||||||
|
class IConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Keys {
|
||||||
|
// common
|
||||||
|
AlgorithmKey = 'a',
|
||||||
|
ApiWorkerIdKey = 4002,
|
||||||
|
ApiIdKey = 4005,
|
||||||
|
HttpPort = 4100,
|
||||||
|
HttpAccessTokenKey = 4101,
|
||||||
|
HttpRestrictedKey = 4104,
|
||||||
|
HttpEnabledKey = 4106,
|
||||||
|
HttpHostKey = 4107,
|
||||||
|
BackgroundKey = 'B',
|
||||||
|
ColorKey = 1002,
|
||||||
|
ConfigKey = 'c',
|
||||||
|
DonateLevelKey = 1003,
|
||||||
|
KeepAliveKey = 'k',
|
||||||
|
LogFileKey = 'l',
|
||||||
|
PasswordKey = 'p',
|
||||||
|
RetriesKey = 'r',
|
||||||
|
RetryPauseKey = 'R',
|
||||||
|
RigIdKey = 1012,
|
||||||
|
SyslogKey = 'S',
|
||||||
|
UrlKey = 'o',
|
||||||
|
UserAgentKey = 1008,
|
||||||
|
UserKey = 'u',
|
||||||
|
UserpassKey = 'O',
|
||||||
|
VariantKey = 1010,
|
||||||
|
VerboseKey = 1100,
|
||||||
|
TlsKey = 1013,
|
||||||
|
FingerprintKey = 1014,
|
||||||
|
ProxyDonateKey = 1017,
|
||||||
|
DaemonKey = 1018,
|
||||||
|
DaemonPollKey = 1019,
|
||||||
|
|
||||||
|
# ifdef XMRIG_DEPRECATED
|
||||||
|
ApiPort = 4000,
|
||||||
|
ApiAccessTokenKey = 4001,
|
||||||
|
ApiIPv6Key = 4003,
|
||||||
|
ApiRestrictedKey = 4004,
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// xmrig common
|
||||||
|
CPUPriorityKey = 1021,
|
||||||
|
NicehashKey = 1006,
|
||||||
|
PrintTimeKey = 1007,
|
||||||
|
|
||||||
|
// xmrig cpu
|
||||||
|
AVKey = 'v',
|
||||||
|
CPUAffinityKey = 1020,
|
||||||
|
DryRunKey = 5000,
|
||||||
|
HugePagesKey = 1009,
|
||||||
|
MaxCPUUsageKey = 1004,
|
||||||
|
SafeKey = 1005,
|
||||||
|
ThreadsKey = 't',
|
||||||
|
// HardwareAESKey = 1011,
|
||||||
|
AssemblyKey = 1015,
|
||||||
|
|
||||||
|
// xmrig amd
|
||||||
|
OclPlatformKey = 1400,
|
||||||
|
OclAffinityKey = 1401,
|
||||||
|
OclDevicesKey = 1402,
|
||||||
|
OclLaunchKey = 1403,
|
||||||
|
OclCacheKey = 1404,
|
||||||
|
OclPrintKey = 1405,
|
||||||
|
OclLoaderKey = 1406,
|
||||||
|
OclSridedIndexKey = 1407,
|
||||||
|
OclMemChunkKey = 1408,
|
||||||
|
OclUnrollKey = 1409,
|
||||||
|
OclCompModeKey = 1410,
|
||||||
|
|
||||||
|
// xmrig-proxy
|
||||||
|
AccessLogFileKey = 'A',
|
||||||
|
BindKey = 'b',
|
||||||
|
CustomDiffKey = 1102,
|
||||||
|
DebugKey = 1101,
|
||||||
|
ModeKey = 'm',
|
||||||
|
PoolCoinKey = 'C',
|
||||||
|
ReuseTimeoutKey = 1106,
|
||||||
|
WorkersKey = 1103,
|
||||||
|
WorkersAdvKey = 1107,
|
||||||
|
TlsBindKey = 1108,
|
||||||
|
TlsCertKey = 1109,
|
||||||
|
TlsCertKeyKey = 1110,
|
||||||
|
TlsDHparamKey = 1111,
|
||||||
|
TlsCiphersKey = 1112,
|
||||||
|
TlsCipherSuitesKey = 1113,
|
||||||
|
TlsProtocolsKey = 1114,
|
||||||
|
AlgoExtKey = 1115,
|
||||||
|
ProxyPasswordKey = 1116,
|
||||||
|
|
||||||
|
// xmrig nvidia
|
||||||
|
CudaMaxThreadsKey = 1200,
|
||||||
|
CudaBFactorKey = 1201,
|
||||||
|
CudaBSleepKey = 1202,
|
||||||
|
CudaDevicesKey = 1203,
|
||||||
|
CudaLaunchKey = 1204,
|
||||||
|
CudaAffinityKey = 1205,
|
||||||
|
CudaMaxUsageKey = 1206,
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~IConfig() = default;
|
||||||
|
|
||||||
|
virtual bool isWatch() const = 0;
|
||||||
|
virtual bool read(const IJsonReader &reader, const char *fileName) = 0;
|
||||||
|
virtual bool save() = 0;
|
||||||
|
virtual const Algorithm &algorithm() const = 0;
|
||||||
|
virtual const String &fileName() const = 0;
|
||||||
|
virtual void getJSON(rapidjson::Document &doc) const = 0;
|
||||||
|
virtual void setFileName(const char *fileName) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_ICONFIG_H
|
||||||
52
src/base/kernel/interfaces/IConfigTransform.h
Normal file
52
src/base/kernel/interfaces/IConfigTransform.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* 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 "common/crypto/Algorithm.h"
|
||||||
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class IJsonReader;
|
||||||
|
class String;
|
||||||
|
|
||||||
|
|
||||||
|
class IConfigTransform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IConfigTransform() = default;
|
||||||
|
|
||||||
|
virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_ICONFIGTRANSFORM_H
|
||||||
48
src/base/kernel/interfaces/IHttpListener.h
Normal file
48
src/base/kernel/interfaces/IHttpListener.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_IHTTPLISTENER_H
|
||||||
|
#define XMRIG_IHTTPLISTENER_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class HttpData;
|
||||||
|
class HttpResponse;
|
||||||
|
|
||||||
|
|
||||||
|
class IHttpListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IHttpListener() = default;
|
||||||
|
|
||||||
|
virtual void onHttpData(const HttpData &data) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_IHTTPLISTENER_H
|
||||||
@@ -22,51 +22,35 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XMRIG_CONFIGLOADER_H
|
#ifndef XMRIG_IJSONREADER_H
|
||||||
#define XMRIG_CONFIGLOADER_H
|
#define XMRIG_IJSONREADER_H
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "rapidjson/fwd.h"
|
#include "rapidjson/fwd.h"
|
||||||
|
|
||||||
|
|
||||||
struct option;
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class ConfigWatcher;
|
class IJsonReader
|
||||||
class IConfigCreator;
|
|
||||||
class IConfigListener;
|
|
||||||
class IConfig;
|
|
||||||
class Process;
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigLoader
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool loadFromFile(IConfig *config, const char *fileName);
|
virtual ~IJsonReader() = default;
|
||||||
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();
|
|
||||||
|
|
||||||
private:
|
virtual bool getBool(const char *key, bool defaultValue = false) const = 0;
|
||||||
static bool getJSON(const char *fileName, rapidjson::Document &doc);
|
virtual bool isEmpty() const = 0;
|
||||||
static bool parseArg(IConfig *config, int key, const char *arg);
|
virtual const char *getString(const char *key, const char *defaultValue = nullptr) const = 0;
|
||||||
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
|
virtual const rapidjson::Value &getArray(const char *key) const = 0;
|
||||||
|
virtual const rapidjson::Value &getObject(const char *key) const = 0;
|
||||||
static ConfigWatcher *m_watcher;
|
virtual const rapidjson::Value &getValue(const char *key) const = 0;
|
||||||
static IConfigCreator *m_creator;
|
virtual int getInt(const char *key, int defaultValue = 0) const = 0;
|
||||||
static IConfigListener *m_listener;
|
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 */
|
} /* namespace xmrig */
|
||||||
|
|
||||||
#endif /* XMRIG_CONFIGLOADER_H */
|
|
||||||
|
#endif // XMRIG_IJSONREADER_H
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -36,24 +37,9 @@ namespace xmrig {
|
|||||||
class ILogBackend
|
class ILogBackend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Level {
|
|
||||||
ERR,
|
|
||||||
WARNING,
|
|
||||||
NOTICE,
|
|
||||||
INFO,
|
|
||||||
DEBUG
|
|
||||||
};
|
|
||||||
|
|
||||||
# ifdef APP_DEBUG
|
|
||||||
constexpr static const size_t kBufferSize = 1024;
|
|
||||||
# else
|
|
||||||
constexpr static const size_t kBufferSize = 512;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
virtual ~ILogBackend() = default;
|
virtual ~ILogBackend() = default;
|
||||||
|
|
||||||
virtual void message(Level level, const char* fmt, va_list args) = 0;
|
virtual void print(int level, const char *line, size_t offset, size_t size, bool colors) = 0;
|
||||||
virtual void text(const char* fmt, va_list args) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace xmrig {
|
|||||||
|
|
||||||
|
|
||||||
class Algorithm;
|
class Algorithm;
|
||||||
class Client;
|
class IClient;
|
||||||
class JobResult;
|
class JobResult;
|
||||||
|
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
virtual ~IStrategy() = default;
|
virtual ~IStrategy() = default;
|
||||||
|
|
||||||
virtual bool isActive() const = 0;
|
virtual bool isActive() const = 0;
|
||||||
virtual Client *client() const = 0;
|
virtual IClient *client() const = 0;
|
||||||
virtual int64_t submit(const JobResult &result) = 0;
|
virtual int64_t submit(const JobResult &result) = 0;
|
||||||
virtual void connect() = 0;
|
virtual void connect() = 0;
|
||||||
virtual void resume() = 0;
|
virtual void resume() = 0;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class Client;
|
class IClient;
|
||||||
class IStrategy;
|
class IStrategy;
|
||||||
class Job;
|
class Job;
|
||||||
class SubmitResult;
|
class SubmitResult;
|
||||||
@@ -43,10 +43,10 @@ class IStrategyListener
|
|||||||
public:
|
public:
|
||||||
virtual ~IStrategyListener() = default;
|
virtual ~IStrategyListener() = default;
|
||||||
|
|
||||||
virtual void onActive(IStrategy *strategy, Client *client) = 0;
|
virtual void onActive(IStrategy *strategy, IClient *client) = 0;
|
||||||
virtual void onJob(IStrategy *strategy, Client *client, const Job &job) = 0;
|
virtual void onJob(IStrategy *strategy, IClient *client, const Job &job) = 0;
|
||||||
virtual void onPause(IStrategy *strategy) = 0;
|
virtual void onPause(IStrategy *strategy) = 0;
|
||||||
virtual void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) = 0;
|
virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,36 +22,32 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XMRIG_BASICLOG_H
|
#ifndef XMRIG_ITCPSERVERLISTENER_H
|
||||||
#define XMRIG_BASICLOG_H
|
#define XMRIG_ITCPSERVERLISTENER_H
|
||||||
|
|
||||||
|
|
||||||
#include <uv.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
#include "common/interfaces/ILogBackend.h"
|
typedef struct uv_stream_s uv_stream_t;
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class BasicLog : public ILogBackend
|
class String;
|
||||||
|
|
||||||
|
|
||||||
|
class ITcpServerListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BasicLog();
|
virtual ~ITcpServerListener() = default;
|
||||||
|
|
||||||
void message(Level level, const char *fmt, va_list args) override;
|
virtual void onConnection(uv_stream_t *stream, uint16_t port) = 0;
|
||||||
void text(const char *fmt, va_list args) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isWritable() const;
|
|
||||||
void print(va_list args);
|
|
||||||
|
|
||||||
char m_buf[kBufferSize];
|
|
||||||
char m_fmt[256];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} /* namespace xmrig */
|
} /* namespace xmrig */
|
||||||
|
|
||||||
#endif /* XMRIG_BASICLOG_H */
|
|
||||||
|
#endif // XMRIG_ITCPSERVERLISTENER_H
|
||||||
@@ -37,7 +37,8 @@ namespace xmrig {
|
|||||||
xmrig::Dns::Dns(IDnsListener *listener) :
|
xmrig::Dns::Dns(IDnsListener *listener) :
|
||||||
m_hints(),
|
m_hints(),
|
||||||
m_listener(listener),
|
m_listener(listener),
|
||||||
m_status(0)
|
m_status(0),
|
||||||
|
m_resolver(nullptr)
|
||||||
{
|
{
|
||||||
m_key = m_storage.add(this);
|
m_key = m_storage.add(this);
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ xmrig::Dns::~Dns()
|
|||||||
{
|
{
|
||||||
m_storage.release(m_key);
|
m_storage.release(m_key);
|
||||||
|
|
||||||
Handle::close(m_resolver);
|
delete m_resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -143,7 +144,11 @@ void xmrig::Dns::onResolved(int status, addrinfo *res)
|
|||||||
ptr = ptr->ai_next;
|
ptr = ptr->ai_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_listener->onResolved(*this, status);
|
if (isEmpty()) {
|
||||||
|
m_status = UV_EAI_NONAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_listener->onResolved(*this, m_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public:
|
|||||||
~Dns();
|
~Dns();
|
||||||
|
|
||||||
inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); }
|
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; }
|
inline int status() const { return m_status; }
|
||||||
|
|
||||||
bool resolve(const String &host);
|
bool resolve(const String &host);
|
||||||
|
|||||||
99
src/base/net/http/Http.cpp
Normal file
99
src/base/net/http/Http.cpp
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "3rdparty/rapidjson/document.h"
|
||||||
|
#include "base/io/json/Json.h"
|
||||||
|
#include "base/net/http/Http.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const char *kEnabled = "enabled";
|
||||||
|
static const char *kHost = "host";
|
||||||
|
static const char *kLocalhost = "127.0.0.1";
|
||||||
|
static const char *kPort = "port";
|
||||||
|
static const char *kRestricted = "restricted";
|
||||||
|
static const char *kToken = "access-token";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::Http::Http() :
|
||||||
|
m_enabled(false),
|
||||||
|
m_restricted(true),
|
||||||
|
m_host(kLocalhost),
|
||||||
|
m_port(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::Http::isEqual(const Http &other) const
|
||||||
|
{
|
||||||
|
return other.m_enabled == m_enabled &&
|
||||||
|
other.m_restricted == m_restricted &&
|
||||||
|
other.m_host == m_host &&
|
||||||
|
other.m_token == m_token &&
|
||||||
|
other.m_port == m_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rapidjson::Value xmrig::Http::toJSON(rapidjson::Document &doc) const
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
Value obj(kObjectType);
|
||||||
|
|
||||||
|
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
||||||
|
obj.AddMember(StringRef(kHost), m_host.toJSON(), allocator);
|
||||||
|
obj.AddMember(StringRef(kPort), m_port, allocator);
|
||||||
|
obj.AddMember(StringRef(kToken), m_token.toJSON(), allocator);
|
||||||
|
obj.AddMember(StringRef(kRestricted), m_restricted, allocator);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Http::load(const rapidjson::Value &http)
|
||||||
|
{
|
||||||
|
if (!http.IsObject()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_enabled = Json::getBool(http, kEnabled);
|
||||||
|
m_restricted = Json::getBool(http, kRestricted, true);
|
||||||
|
m_host = Json::getString(http, kHost, kLocalhost);
|
||||||
|
m_token = Json::getString(http, kToken);
|
||||||
|
|
||||||
|
setPort(Json::getInt(http, kPort));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Http::setPort(int port)
|
||||||
|
{
|
||||||
|
if (port >= 0 && port <= 65536) {
|
||||||
|
m_port = static_cast<uint16_t>(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
73
src/base/net/http/Http.h
Normal file
73
src/base/net/http/Http.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_HTTP_H
|
||||||
|
#define XMRIG_HTTP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/tools/String.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class Http
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Http();
|
||||||
|
|
||||||
|
inline bool isAuthRequired() const { return m_restricted == false || !m_token.isNull(); }
|
||||||
|
inline bool isEnabled() const { return m_enabled; }
|
||||||
|
inline bool isRestricted() const { return m_restricted; }
|
||||||
|
inline const String &host() const { return m_host; }
|
||||||
|
inline const String &token() const { return m_token; }
|
||||||
|
inline uint16_t port() const { return m_port; }
|
||||||
|
inline void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||||
|
inline void setHost(const char *host) { m_host = host; }
|
||||||
|
inline void setRestricted(bool restricted) { m_restricted = restricted; }
|
||||||
|
inline void setToken(const char *token) { m_token = token; }
|
||||||
|
|
||||||
|
inline bool operator!=(const Http &other) const { return !isEqual(other); }
|
||||||
|
inline bool operator==(const Http &other) const { return isEqual(other); }
|
||||||
|
|
||||||
|
bool isEqual(const Http &other) const;
|
||||||
|
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||||
|
void load(const rapidjson::Value &http);
|
||||||
|
void setPort(int port);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_enabled;
|
||||||
|
bool m_restricted;
|
||||||
|
String m_host;
|
||||||
|
String m_token;
|
||||||
|
uint16_t m_port;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_HTTP_H
|
||||||
|
|
||||||
86
src/base/net/http/HttpApiResponse.cpp
Normal file
86
src/base/net/http/HttpApiResponse.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "3rdparty/http-parser/http_parser.h"
|
||||||
|
#include "base/net/http/HttpApiResponse.h"
|
||||||
|
#include "rapidjson/prettywriter.h"
|
||||||
|
#include "rapidjson/stringbuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const char *kError = "error";
|
||||||
|
static const char *kStatus = "status";
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpApiResponse::HttpApiResponse(uint64_t id) :
|
||||||
|
HttpResponse(id),
|
||||||
|
m_doc(rapidjson::kObjectType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpApiResponse::HttpApiResponse(uint64_t id, int status) :
|
||||||
|
HttpResponse(id),
|
||||||
|
m_doc(rapidjson::kObjectType)
|
||||||
|
{
|
||||||
|
setStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpApiResponse::end()
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
|
||||||
|
setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
|
||||||
|
setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
|
||||||
|
|
||||||
|
if (statusCode() >= 400) {
|
||||||
|
if (!m_doc.HasMember(kStatus)) {
|
||||||
|
m_doc.AddMember(StringRef(kStatus), statusCode(), m_doc.GetAllocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_doc.HasMember(kError)) {
|
||||||
|
m_doc.AddMember(StringRef(kError), StringRef(http_status_str(static_cast<http_status>(statusCode()))), m_doc.GetAllocator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_doc.MemberCount()) {
|
||||||
|
return HttpResponse::end();
|
||||||
|
}
|
||||||
|
|
||||||
|
setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
StringBuffer buffer(nullptr, 4096);
|
||||||
|
PrettyWriter<StringBuffer> writer(buffer);
|
||||||
|
writer.SetMaxDecimalPlaces(10);
|
||||||
|
m_doc.Accept(writer);
|
||||||
|
|
||||||
|
HttpResponse::end(buffer.GetString(), buffer.GetSize());
|
||||||
|
}
|
||||||
57
src/base/net/http/HttpApiResponse.h
Normal file
57
src/base/net/http/HttpApiResponse.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_HTTPAPIRESPONSE_H
|
||||||
|
#define XMRIG_HTTPAPIRESPONSE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/net/http/HttpResponse.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class HttpApiResponse : public HttpResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HttpApiResponse(uint64_t id);
|
||||||
|
HttpApiResponse(uint64_t id, int status);
|
||||||
|
|
||||||
|
inline rapidjson::Document &doc() { return m_doc; }
|
||||||
|
|
||||||
|
void end();
|
||||||
|
|
||||||
|
private:
|
||||||
|
rapidjson::Document m_doc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_HTTPAPIRESPONSE_H
|
||||||
|
|
||||||
224
src/base/net/http/HttpClient.cpp
Normal file
224
src/base/net/http/HttpClient.cpp
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
#include "3rdparty/http-parser/http_parser.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/net/dns/Dns.h"
|
||||||
|
#include "base/net/http/HttpClient.h"
|
||||||
|
#include "base/tools/Baton.h"
|
||||||
|
#include "common/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const char *kCRLF = "\r\n";
|
||||||
|
|
||||||
|
|
||||||
|
class ClientWriteBaton : public Baton<uv_write_t>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline ClientWriteBaton(const std::string &header, std::string &&body) :
|
||||||
|
m_body(std::move(body)),
|
||||||
|
m_header(header)
|
||||||
|
{
|
||||||
|
bufs[0].len = m_header.size();
|
||||||
|
bufs[0].base = const_cast<char *>(m_header.c_str());
|
||||||
|
|
||||||
|
if (!m_body.empty()) {
|
||||||
|
bufs[1].len = m_body.size();
|
||||||
|
bufs[1].base = const_cast<char *>(m_body.c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bufs[1].base = nullptr;
|
||||||
|
bufs[1].len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
|
||||||
|
inline size_t size() const { return bufs[0].len + bufs[1].len; }
|
||||||
|
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<ClientWriteBaton *>(req->data); }
|
||||||
|
|
||||||
|
|
||||||
|
uv_buf_t bufs[2];
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_body;
|
||||||
|
std::string m_header;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) :
|
||||||
|
HttpContext(HTTP_RESPONSE, listener),
|
||||||
|
m_quiet(false),
|
||||||
|
m_port(0)
|
||||||
|
{
|
||||||
|
this->method = method;
|
||||||
|
this->url = url;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
body = size ? std::string(data, size) : data;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dns = new Dns(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpClient::~HttpClient()
|
||||||
|
{
|
||||||
|
delete m_dns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::HttpClient::connect(const String &host, uint16_t port)
|
||||||
|
{
|
||||||
|
m_port = port;
|
||||||
|
|
||||||
|
return m_dns->resolve(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const xmrig::String &xmrig::HttpClient::host() const
|
||||||
|
{
|
||||||
|
return m_dns->host();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpClient::onResolved(const Dns &dns, int status)
|
||||||
|
{
|
||||||
|
this->status = status;
|
||||||
|
|
||||||
|
if (status < 0 && dns.isEmpty()) {
|
||||||
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), m_port, uv_strerror(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr *addr = dns.get().addr(m_port);
|
||||||
|
|
||||||
|
uv_connect_t *req = new uv_connect_t;
|
||||||
|
req->data = this;
|
||||||
|
|
||||||
|
uv_tcp_connect(req, m_tcp, addr, onConnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpClient::handshake()
|
||||||
|
{
|
||||||
|
headers.insert({ "Host", m_dns->host().data() });
|
||||||
|
headers.insert({ "Connection", "close" });
|
||||||
|
headers.insert({ "User-Agent", Platform::userAgent() });
|
||||||
|
|
||||||
|
if (body.size()) {
|
||||||
|
headers.insert({ "Content-Length", std::to_string(body.size()) });
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << http_method_str(static_cast<http_method>(method)) << " " << url << " HTTP/1.1" << kCRLF;
|
||||||
|
|
||||||
|
for (auto &header : headers) {
|
||||||
|
ss << header.first << ": " << header.second << kCRLF;
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << kCRLF;
|
||||||
|
|
||||||
|
headers.clear();
|
||||||
|
|
||||||
|
write(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpClient::read(const char *data, size_t size)
|
||||||
|
{
|
||||||
|
if (parse(data, size) < size) {
|
||||||
|
close(UV_EPROTO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpClient::write(const std::string &header)
|
||||||
|
{
|
||||||
|
ClientWriteBaton *baton = new ClientWriteBaton(header, std::move(body));
|
||||||
|
uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
|
||||||
|
{
|
||||||
|
HttpClient *client = static_cast<HttpClient *>(req->data);
|
||||||
|
if (!client) {
|
||||||
|
delete req;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status < 0) {
|
||||||
|
if (!client->m_quiet) {
|
||||||
|
LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete req;
|
||||||
|
client->close(status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_read_start(client->stream(),
|
||||||
|
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
|
||||||
|
{
|
||||||
|
buf->base = new char[suggested_size];
|
||||||
|
|
||||||
|
# ifdef _WIN32
|
||||||
|
buf->len = static_cast<unsigned int>(suggested_size);
|
||||||
|
# else
|
||||||
|
buf->len = suggested_size;
|
||||||
|
# endif
|
||||||
|
},
|
||||||
|
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
|
||||||
|
{
|
||||||
|
HttpClient *client = static_cast<HttpClient*>(tcp->data);
|
||||||
|
|
||||||
|
if (nread >= 0) {
|
||||||
|
client->read(buf->base, static_cast<size_t>(nread));
|
||||||
|
} else {
|
||||||
|
if (!client->m_quiet && nread != UV_EOF) {
|
||||||
|
LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(static_cast<int>(nread)));
|
||||||
|
}
|
||||||
|
|
||||||
|
client->close(static_cast<int>(nread));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] buf->base;
|
||||||
|
});
|
||||||
|
|
||||||
|
client->handshake();
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* 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 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
@@ -22,60 +23,52 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XMRIG_HTTPD_H
|
|
||||||
#define XMRIG_HTTPD_H
|
#ifndef XMRIG_HTTPCLIENT_H
|
||||||
|
#define XMRIG_HTTPCLIENT_H
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include "base/net/http/HttpContext.h"
|
||||||
|
#include "base/kernel/interfaces/IDnsListener.h"
|
||||||
|
|
||||||
#include "base/kernel/interfaces/ITimerListener.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct MHD_Connection;
|
|
||||||
struct MHD_Daemon;
|
|
||||||
struct MHD_Response;
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
class HttpRequest;
|
class String;
|
||||||
class Timer;
|
|
||||||
|
|
||||||
|
|
||||||
class Httpd : public ITimerListener
|
class HttpClient : public HttpContext, public IDnsListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Httpd(int port, const char *accessToken, bool IPv6, bool restricted);
|
HttpClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0);
|
||||||
~Httpd() override;
|
~HttpClient() override;
|
||||||
|
|
||||||
bool start();
|
inline uint16_t port() const { return m_port; }
|
||||||
void stop();
|
inline void setQuiet(bool quiet) { m_quiet = quiet; }
|
||||||
|
|
||||||
|
bool connect(const String &host, uint16_t port);
|
||||||
|
const String &host() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onTimer(const Timer *) override { run(); }
|
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:
|
private:
|
||||||
constexpr static const int kIdleInterval = 200;
|
static void onConnect(uv_connect_t *req, int status);
|
||||||
constexpr static const int kActiveInterval = 25;
|
|
||||||
|
|
||||||
int process(HttpRequest &req);
|
Dns *m_dns;
|
||||||
void run();
|
uint16_t m_port;
|
||||||
|
|
||||||
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls);
|
|
||||||
|
|
||||||
bool m_idle;
|
|
||||||
bool m_IPv6;
|
|
||||||
bool m_restricted;
|
|
||||||
const char *m_accessToken;
|
|
||||||
const int m_port;
|
|
||||||
MHD_Daemon *m_daemon;
|
|
||||||
Timer *m_timer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} /* namespace xmrig */
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
#endif /* XMRIG_HTTPD_H */
|
#endif // XMRIG_HTTPCLIENT_H
|
||||||
|
|
||||||
228
src/base/net/http/HttpContext.cpp
Normal file
228
src/base/net/http/HttpContext.cpp
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "3rdparty/http-parser/http_parser.h"
|
||||||
|
#include "base/kernel/interfaces/IHttpListener.h"
|
||||||
|
#include "base/net/http/HttpContext.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
static http_parser_settings http_settings;
|
||||||
|
static std::map<uint64_t, HttpContext *> storage;
|
||||||
|
static uint64_t SEQUENCE = 0;
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpContext::HttpContext(int parser_type, IHttpListener *listener) :
|
||||||
|
HttpData(SEQUENCE++),
|
||||||
|
m_wasHeaderValue(false),
|
||||||
|
m_listener(listener)
|
||||||
|
{
|
||||||
|
storage[id()] = this;
|
||||||
|
|
||||||
|
m_parser = new http_parser;
|
||||||
|
m_tcp = new uv_tcp_t;
|
||||||
|
|
||||||
|
uv_tcp_init(uv_default_loop(), m_tcp);
|
||||||
|
uv_tcp_nodelay(m_tcp, 1);
|
||||||
|
|
||||||
|
http_parser_init(m_parser, static_cast<http_parser_type>(parser_type));
|
||||||
|
|
||||||
|
m_parser->data = m_tcp->data = this;
|
||||||
|
|
||||||
|
if (http_settings.on_message_complete == nullptr) {
|
||||||
|
attach(&http_settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpContext::~HttpContext()
|
||||||
|
{
|
||||||
|
delete m_tcp;
|
||||||
|
delete m_parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t xmrig::HttpContext::parse(const char *data, size_t size)
|
||||||
|
{
|
||||||
|
return http_parser_execute(m_parser, &http_settings, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string xmrig::HttpContext::ip() const
|
||||||
|
{
|
||||||
|
char ip[46] = {};
|
||||||
|
sockaddr_storage addr = {};
|
||||||
|
int size = sizeof(addr);
|
||||||
|
|
||||||
|
uv_tcp_getpeername(m_tcp, reinterpret_cast<sockaddr*>(&addr), &size);
|
||||||
|
if (reinterpret_cast<sockaddr_in *>(&addr)->sin_family == AF_INET6) {
|
||||||
|
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(&addr), ip, 45);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uv_ip4_name(reinterpret_cast<sockaddr_in*>(&addr), ip, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpContext::close(int status)
|
||||||
|
{
|
||||||
|
if (status < 0 && m_listener) {
|
||||||
|
this->status = status;
|
||||||
|
m_listener->onHttpData(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = storage.find(id());
|
||||||
|
if (it != storage.end()) {
|
||||||
|
storage.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uv_is_closing(handle())) {
|
||||||
|
uv_close(handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpContext *xmrig::HttpContext::get(uint64_t id)
|
||||||
|
{
|
||||||
|
if (storage.count(id) == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return storage[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpContext::closeAll()
|
||||||
|
{
|
||||||
|
for (auto kv : storage) {
|
||||||
|
if (!uv_is_closing(kv.second->handle())) {
|
||||||
|
uv_close(kv.second->handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int xmrig::HttpContext::onHeaderField(http_parser *parser, const char *at, size_t length)
|
||||||
|
{
|
||||||
|
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||||
|
|
||||||
|
if (ctx->m_wasHeaderValue) {
|
||||||
|
if (!ctx->m_lastHeaderField.empty()) {
|
||||||
|
ctx->setHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->m_lastHeaderField = std::string(at, length);
|
||||||
|
ctx->m_wasHeaderValue = false;
|
||||||
|
} else {
|
||||||
|
ctx->m_lastHeaderField += std::string(at, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int xmrig::HttpContext::onHeaderValue(http_parser *parser, const char *at, size_t length)
|
||||||
|
{
|
||||||
|
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||||
|
|
||||||
|
if (!ctx->m_wasHeaderValue) {
|
||||||
|
ctx->m_lastHeaderValue = std::string(at, length);
|
||||||
|
ctx->m_wasHeaderValue = true;
|
||||||
|
} else {
|
||||||
|
ctx->m_lastHeaderValue += std::string(at, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpContext::attach(http_parser_settings *settings)
|
||||||
|
{
|
||||||
|
settings->on_message_begin = nullptr;
|
||||||
|
settings->on_status = nullptr;
|
||||||
|
settings->on_chunk_header = nullptr;
|
||||||
|
settings->on_chunk_complete = nullptr;
|
||||||
|
|
||||||
|
settings->on_url = [](http_parser *parser, const char *at, size_t length) -> int
|
||||||
|
{
|
||||||
|
static_cast<HttpContext*>(parser->data)->url = std::string(at, length);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings->on_header_field = onHeaderField;
|
||||||
|
settings->on_header_value = onHeaderValue;
|
||||||
|
|
||||||
|
settings->on_headers_complete = [](http_parser* parser) -> int {
|
||||||
|
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||||
|
ctx->status = parser->status_code;
|
||||||
|
|
||||||
|
if (parser->type == HTTP_REQUEST) {
|
||||||
|
ctx->method = parser->method;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx->m_lastHeaderField.empty()) {
|
||||||
|
ctx->setHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings->on_body = [](http_parser *parser, const char *at, size_t len) -> int
|
||||||
|
{
|
||||||
|
static_cast<HttpContext*>(parser->data)->body += std::string(at, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings->on_message_complete = [](http_parser *parser) -> int
|
||||||
|
{
|
||||||
|
HttpContext *ctx = static_cast<HttpContext*>(parser->data);
|
||||||
|
ctx->m_listener->onHttpData(*ctx);
|
||||||
|
ctx->m_listener = nullptr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpContext::setHeader()
|
||||||
|
{
|
||||||
|
std::transform(m_lastHeaderField.begin(), m_lastHeaderField.end(), m_lastHeaderField.begin(), ::tolower);
|
||||||
|
headers.insert({ m_lastHeaderField, m_lastHeaderValue });
|
||||||
|
|
||||||
|
m_lastHeaderField.clear();
|
||||||
|
m_lastHeaderValue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
86
src/base/net/http/HttpContext.h
Normal file
86
src/base/net/http/HttpContext.h
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_HTTPCONTEXT_H
|
||||||
|
#define XMRIG_HTTPCONTEXT_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct http_parser http_parser;
|
||||||
|
typedef struct http_parser_settings http_parser_settings;
|
||||||
|
typedef struct uv_connect_s uv_connect_t;
|
||||||
|
typedef struct uv_handle_s uv_handle_t;
|
||||||
|
typedef struct uv_stream_s uv_stream_t;
|
||||||
|
typedef struct uv_tcp_s uv_tcp_t;
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/net/http/HttpData.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class IHttpListener;
|
||||||
|
|
||||||
|
|
||||||
|
class HttpContext : public HttpData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HttpContext(int parser_type, IHttpListener *listener);
|
||||||
|
virtual ~HttpContext();
|
||||||
|
|
||||||
|
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_tcp); }
|
||||||
|
inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(m_tcp); }
|
||||||
|
|
||||||
|
size_t parse(const char *data, size_t size);
|
||||||
|
std::string ip() const;
|
||||||
|
void close(int status = 0);
|
||||||
|
|
||||||
|
static HttpContext *get(uint64_t id);
|
||||||
|
static void closeAll();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uv_tcp_t *m_tcp;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int onHeaderField(http_parser *parser, const char *at, size_t length);
|
||||||
|
static int onHeaderValue(http_parser *parser, const char *at, size_t length);
|
||||||
|
static void attach(http_parser_settings *settings);
|
||||||
|
|
||||||
|
void setHeader();
|
||||||
|
|
||||||
|
bool m_wasHeaderValue;
|
||||||
|
http_parser *m_parser;
|
||||||
|
IHttpListener *m_listener;
|
||||||
|
std::string m_lastHeaderField;
|
||||||
|
std::string m_lastHeaderValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_HTTPCONTEXT_H
|
||||||
|
|
||||||
60
src/base/net/http/HttpData.h
Normal file
60
src/base/net/http/HttpData.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_HTTPDATA_H
|
||||||
|
#define XMRIG_HTTPDATA_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class HttpData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline HttpData(uint64_t id) : method(0), status(0), m_id(id) {}
|
||||||
|
|
||||||
|
inline uint64_t id() const { return m_id; }
|
||||||
|
|
||||||
|
int method;
|
||||||
|
int status;
|
||||||
|
std::map<const std::string, const std::string> headers;
|
||||||
|
std::string body;
|
||||||
|
std::string url;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint64_t m_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_HTTPDATA_H
|
||||||
|
|
||||||
153
src/base/net/http/HttpResponse.cpp
Normal file
153
src/base/net/http/HttpResponse.cpp
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "3rdparty/http-parser/http_parser.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/net/http/HttpContext.h"
|
||||||
|
#include "base/net/http/HttpResponse.h"
|
||||||
|
#include "base/tools/Baton.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const char *kCRLF = "\r\n";
|
||||||
|
static const char *kUserAgent = "user-agent";
|
||||||
|
|
||||||
|
|
||||||
|
class WriteBaton : public Baton<uv_write_t>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline WriteBaton(const std::stringstream &ss, const char *data, size_t size, HttpContext *ctx) :
|
||||||
|
m_ctx(ctx),
|
||||||
|
m_header(ss.str())
|
||||||
|
{
|
||||||
|
bufs[0].len = m_header.size();
|
||||||
|
bufs[0].base = const_cast<char *>(m_header.c_str());
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
bufs[1].len = size;
|
||||||
|
bufs[1].base = new char[size];
|
||||||
|
memcpy(bufs[1].base, data, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bufs[1].base = nullptr;
|
||||||
|
bufs[1].len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline ~WriteBaton()
|
||||||
|
{
|
||||||
|
if (count() == 2) {
|
||||||
|
delete [] bufs[1].base;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ctx->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; }
|
||||||
|
inline size_t size() const { return bufs[0].len + bufs[1].len; }
|
||||||
|
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<WriteBaton *>(req->data); }
|
||||||
|
|
||||||
|
|
||||||
|
uv_buf_t bufs[2];
|
||||||
|
|
||||||
|
private:
|
||||||
|
HttpContext *m_ctx;
|
||||||
|
std::string m_header;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpResponse::HttpResponse(uint64_t id, int statusCode) :
|
||||||
|
m_id(id),
|
||||||
|
m_statusCode(statusCode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::HttpResponse::isAlive() const
|
||||||
|
{
|
||||||
|
HttpContext *ctx = HttpContext::get(m_id);
|
||||||
|
|
||||||
|
return ctx && uv_is_writable(ctx->stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpResponse::end(const char *data, size_t size)
|
||||||
|
{
|
||||||
|
if (!isAlive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data && !size) {
|
||||||
|
size = strlen(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
setHeader("Content-Length", std::to_string(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
setHeader("Connection", "close");
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "HTTP/1.1 " << statusCode() << " " << http_status_str(static_cast<http_status>(statusCode())) << kCRLF;
|
||||||
|
|
||||||
|
for (auto &header : m_headers) {
|
||||||
|
ss << header.first << ": " << header.second << kCRLF;
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << kCRLF;
|
||||||
|
|
||||||
|
HttpContext *ctx = HttpContext::get(m_id);
|
||||||
|
WriteBaton *baton = new WriteBaton(ss, data, size, ctx);
|
||||||
|
|
||||||
|
# ifndef APP_DEBUG
|
||||||
|
if (statusCode() >= 400)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
const bool err = statusCode() >= 400;
|
||||||
|
|
||||||
|
Log::print(err ? Log::ERR : Log::INFO, CYAN("%s ") CLEAR MAGENTA_BOLD("%s") WHITE_BOLD(" %s ") CSI "1;%dm%d " CLEAR WHITE_BOLD("%zu ") BLACK_BOLD("\"%s\""),
|
||||||
|
ctx->ip().c_str(),
|
||||||
|
http_method_str(static_cast<http_method>(ctx->method)),
|
||||||
|
ctx->url.c_str(),
|
||||||
|
err ? 31 : 32,
|
||||||
|
statusCode(),
|
||||||
|
baton->size(),
|
||||||
|
ctx->headers.count(kUserAgent) ? ctx->headers.at(kUserAgent).c_str() : nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_write(&baton->req, ctx->stream(), baton->bufs, baton->count(), WriteBaton::onWrite);
|
||||||
|
}
|
||||||
61
src/base/net/http/HttpResponse.h
Normal file
61
src/base/net/http/HttpResponse.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_HTTPRESPONSE_H
|
||||||
|
#define XMRIG_HTTPRESPONSE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class HttpResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HttpResponse(uint64_t id, int statusCode = 200);
|
||||||
|
|
||||||
|
inline int statusCode() const { return m_statusCode; }
|
||||||
|
inline void setHeader(const std::string &key, const std::string &value) { m_headers.insert({ key, value }); }
|
||||||
|
inline void setStatus(int code) { m_statusCode = code; }
|
||||||
|
|
||||||
|
bool isAlive() const;
|
||||||
|
void end(const char *data = nullptr, size_t size = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint64_t m_id;
|
||||||
|
int m_statusCode;
|
||||||
|
std::map<const std::string, const std::string> m_headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_HTTPRESPONSE_H
|
||||||
|
|
||||||
83
src/base/net/http/HttpServer.cpp
Normal file
83
src/base/net/http/HttpServer.cpp
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "3rdparty/http-parser/http_parser.h"
|
||||||
|
#include "base/kernel/interfaces/IHttpListener.h"
|
||||||
|
#include "base/net/http/HttpContext.h"
|
||||||
|
#include "base/net/http/HttpResponse.h"
|
||||||
|
#include "base/net/http/HttpServer.h"
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpServer::HttpServer(IHttpListener *listener) :
|
||||||
|
m_listener(listener)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpServer::~HttpServer()
|
||||||
|
{
|
||||||
|
HttpContext::closeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpServer::onConnection(uv_stream_t *stream, uint16_t)
|
||||||
|
{
|
||||||
|
HttpContext *ctx = new HttpContext(HTTP_REQUEST, m_listener);
|
||||||
|
uv_accept(stream, ctx->stream());
|
||||||
|
|
||||||
|
uv_read_start(ctx->stream(),
|
||||||
|
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
|
||||||
|
{
|
||||||
|
buf->base = new char[suggested_size];
|
||||||
|
|
||||||
|
# ifdef _WIN32
|
||||||
|
buf->len = static_cast<unsigned int>(suggested_size);
|
||||||
|
# else
|
||||||
|
buf->len = suggested_size;
|
||||||
|
# endif
|
||||||
|
},
|
||||||
|
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
|
||||||
|
{
|
||||||
|
HttpContext *ctx = static_cast<HttpContext*>(tcp->data);
|
||||||
|
|
||||||
|
if (nread >= 0) {
|
||||||
|
const size_t size = static_cast<size_t>(nread);
|
||||||
|
const size_t parsed = ctx->parse(buf->base, size);
|
||||||
|
|
||||||
|
if (parsed < size) {
|
||||||
|
ctx->close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] buf->base;
|
||||||
|
});
|
||||||
|
}
|
||||||
62
src/base/net/http/HttpServer.h
Normal file
62
src/base/net/http/HttpServer.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_HTTPSERVER_H
|
||||||
|
#define XMRIG_HTTPSERVER_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct http_parser http_parser;
|
||||||
|
typedef struct http_parser_settings http_parser_settings;
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/ITcpServerListener.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class IHttpListener;
|
||||||
|
|
||||||
|
|
||||||
|
class HttpServer : public ITcpServerListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HttpServer(IHttpListener *listener);
|
||||||
|
~HttpServer() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onConnection(uv_stream_t *stream, uint16_t port) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IHttpListener *m_listener;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_HTTPSERVER_H
|
||||||
|
|
||||||
208
src/base/net/http/HttpsClient.cpp
Normal file
208
src/base/net/http/HttpsClient.cpp
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/net/http/HttpsClient.h"
|
||||||
|
#include "base/tools/Buffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint) :
|
||||||
|
HttpClient(method, url, listener, data, size),
|
||||||
|
m_ready(false),
|
||||||
|
m_buf(),
|
||||||
|
m_ssl(nullptr),
|
||||||
|
m_fp(fingerprint)
|
||||||
|
{
|
||||||
|
m_ctx = SSL_CTX_new(SSLv23_method());
|
||||||
|
assert(m_ctx != nullptr);
|
||||||
|
|
||||||
|
if (!m_ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_writeBio = BIO_new(BIO_s_mem());
|
||||||
|
m_readBio = BIO_new(BIO_s_mem());
|
||||||
|
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::HttpsClient::~HttpsClient()
|
||||||
|
{
|
||||||
|
if (m_ctx) {
|
||||||
|
SSL_CTX_free(m_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_ssl) {
|
||||||
|
SSL_free(m_ssl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *xmrig::HttpsClient::fingerprint() const
|
||||||
|
{
|
||||||
|
return m_ready ? m_fingerprint : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *xmrig::HttpsClient::version() const
|
||||||
|
{
|
||||||
|
return m_ready ? SSL_get_version(m_ssl) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpsClient::handshake()
|
||||||
|
{
|
||||||
|
m_ssl = SSL_new(m_ctx);
|
||||||
|
assert(m_ssl != nullptr);
|
||||||
|
|
||||||
|
if (!m_ssl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_set_connect_state(m_ssl);
|
||||||
|
SSL_set_bio(m_ssl, m_readBio, m_writeBio);
|
||||||
|
SSL_set_tlsext_host_name(m_ssl, host().data());
|
||||||
|
|
||||||
|
SSL_do_handshake(m_ssl);
|
||||||
|
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpsClient::read(const char *data, size_t size)
|
||||||
|
{
|
||||||
|
BIO_write(m_readBio, data, size);
|
||||||
|
|
||||||
|
if (!SSL_is_init_finished(m_ssl)) {
|
||||||
|
const int rc = SSL_connect(m_ssl);
|
||||||
|
|
||||||
|
if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
|
||||||
|
flush();
|
||||||
|
} else if (rc == 1) {
|
||||||
|
X509 *cert = SSL_get_peer_certificate(m_ssl);
|
||||||
|
if (!verify(cert)) {
|
||||||
|
X509_free(cert);
|
||||||
|
return close(UV_EPROTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_free(cert);
|
||||||
|
m_ready = true;
|
||||||
|
|
||||||
|
HttpClient::handshake();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytes_read = 0;
|
||||||
|
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
|
||||||
|
HttpClient::read(m_buf, static_cast<size_t>(bytes_read));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpsClient::write(const std::string &header)
|
||||||
|
{
|
||||||
|
SSL_write(m_ssl, (header + body).c_str(), header.size() + body.size());
|
||||||
|
body.clear();
|
||||||
|
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::HttpsClient::verify(X509 *cert)
|
||||||
|
{
|
||||||
|
if (cert == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!verifyFingerprint(cert)) {
|
||||||
|
if (!m_quiet) {
|
||||||
|
LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port());
|
||||||
|
|
||||||
|
if (strlen(m_fingerprint) == 64 && !m_fp.isNull()) {
|
||||||
|
LOG_ERR("\"%s\" was given", m_fingerprint);
|
||||||
|
LOG_ERR("\"%s\" was configured", m_fp.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
|
||||||
|
{
|
||||||
|
const EVP_MD *digest = EVP_get_digestbyname("sha256");
|
||||||
|
if (digest == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int dlen;
|
||||||
|
|
||||||
|
if (X509_digest(cert, digest, md, &dlen) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::toHex(md, 32, m_fingerprint);
|
||||||
|
|
||||||
|
return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HttpsClient::flush()
|
||||||
|
{
|
||||||
|
uv_buf_t buf;
|
||||||
|
buf.len = BIO_get_mem_data(m_writeBio, &buf.base);
|
||||||
|
|
||||||
|
if (buf.len == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
if (uv_is_writable(stream())) {
|
||||||
|
result = uv_try_write(stream(), &buf, 1) == static_cast<int>(buf.len);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
close(UV_EIO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) BIO_reset(m_writeBio);
|
||||||
|
}
|
||||||
77
src/base/net/http/HttpsClient.h
Normal file
77
src/base/net/http/HttpsClient.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_HTTPSCLIENT_H
|
||||||
|
#define XMRIG_HTTPSCLIENT_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct bio_st BIO;
|
||||||
|
typedef struct ssl_ctx_st SSL_CTX;
|
||||||
|
typedef struct ssl_st SSL;
|
||||||
|
typedef struct x509_st X509;
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/net/http/HttpClient.h"
|
||||||
|
#include "base/tools/String.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class HttpsClient : public HttpClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint);
|
||||||
|
~HttpsClient() override;
|
||||||
|
|
||||||
|
const char *fingerprint() const;
|
||||||
|
const char *version() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void handshake() override;
|
||||||
|
void read(const char *data, size_t size) override;
|
||||||
|
void write(const std::string &header) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool verify(X509 *cert);
|
||||||
|
bool verifyFingerprint(X509 *cert);
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
BIO *m_readBio;
|
||||||
|
BIO *m_writeBio;
|
||||||
|
bool m_ready;
|
||||||
|
char m_buf[1024 * 2];
|
||||||
|
char m_fingerprint[32 * 2 + 8];
|
||||||
|
SSL *m_ssl;
|
||||||
|
SSL_CTX *m_ctx;
|
||||||
|
String m_fp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMRIG_HTTPSCLIENT_H
|
||||||
62
src/base/net/stratum/BaseClient.cpp
Normal file
62
src/base/net/stratum/BaseClient.cpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/IClientListener.h"
|
||||||
|
#include "base/net/stratum/BaseClient.h"
|
||||||
|
#include "base/net/stratum/SubmitResult.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
int64_t BaseClient::m_sequence = 1;
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::BaseClient::BaseClient(int id, IClientListener *listener) :
|
||||||
|
m_quiet(false),
|
||||||
|
m_listener(listener),
|
||||||
|
m_id(id),
|
||||||
|
m_retries(5),
|
||||||
|
m_failures(0),
|
||||||
|
m_state(UnconnectedState),
|
||||||
|
m_retryPause(5000)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::BaseClient::handleSubmitResponse(int64_t id, const char *error)
|
||||||
|
{
|
||||||
|
auto it = m_results.find(id);
|
||||||
|
if (it != m_results.end()) {
|
||||||
|
it->second.done();
|
||||||
|
m_listener->onResultAccepted(this, it->second, error);
|
||||||
|
m_results.erase(it);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
96
src/base/net/stratum/BaseClient.h
Normal file
96
src/base/net/stratum/BaseClient.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_BASECLIENT_H
|
||||||
|
#define XMRIG_BASECLIENT_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/kernel/interfaces/IClient.h"
|
||||||
|
#include "base/net/stratum/Job.h"
|
||||||
|
#include "base/net/stratum/Pool.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class IClientListener;
|
||||||
|
class SubmitResult;
|
||||||
|
|
||||||
|
|
||||||
|
class BaseClient : public IClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseClient(int id, IClientListener *listener);
|
||||||
|
|
||||||
|
inline bool isEnabled() const override { return m_enabled; }
|
||||||
|
inline const Job &job() const override { return m_job; }
|
||||||
|
inline const Pool &pool() const override { return m_pool; }
|
||||||
|
inline const String &ip() const override { return m_ip; }
|
||||||
|
inline int id() const override { return m_id; }
|
||||||
|
inline void setAlgo(const Algorithm &algo) override { m_pool.setAlgo(algo); }
|
||||||
|
inline void setEnabled(bool enabled) override { m_enabled = enabled; }
|
||||||
|
inline void setPool(const Pool &pool) override { if (pool.isValid()) { m_pool = pool; } }
|
||||||
|
inline void setQuiet(bool quiet) override { m_quiet = quiet; }
|
||||||
|
inline void setRetries(int retries) override { m_retries = retries; }
|
||||||
|
inline void setRetryPause(uint64_t ms) override { m_retryPause = ms; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum SocketState {
|
||||||
|
UnconnectedState,
|
||||||
|
HostLookupState,
|
||||||
|
ConnectingState,
|
||||||
|
ConnectedState,
|
||||||
|
ClosingState
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
|
||||||
|
|
||||||
|
bool handleSubmitResponse(int64_t id, const char *error = nullptr);
|
||||||
|
|
||||||
|
bool m_quiet;
|
||||||
|
IClientListener *m_listener;
|
||||||
|
int m_id;
|
||||||
|
int m_retries;
|
||||||
|
int64_t m_failures;
|
||||||
|
Job m_job;
|
||||||
|
Pool m_pool;
|
||||||
|
SocketState m_state;
|
||||||
|
std::map<int64_t, SubmitResult> m_results;
|
||||||
|
String m_ip;
|
||||||
|
uint64_t m_retryPause;
|
||||||
|
|
||||||
|
static int64_t m_sequence;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_BASECLIENT_H */
|
||||||
@@ -30,19 +30,20 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
#ifndef XMRIG_NO_TLS
|
#ifdef XMRIG_FEATURE_TLS
|
||||||
# include <openssl/ssl.h>
|
# include <openssl/ssl.h>
|
||||||
# include <openssl/err.h>
|
# include <openssl/err.h>
|
||||||
# include "base/net/stratum/Tls.h"
|
# include "base/net/stratum/Tls.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/json/JsonRequest.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
#include "base/kernel/interfaces/IClientListener.h"
|
#include "base/kernel/interfaces/IClientListener.h"
|
||||||
#include "base/net/dns/Dns.h"
|
#include "base/net/dns/Dns.h"
|
||||||
#include "base/net/stratum/Client.h"
|
#include "base/net/stratum/Client.h"
|
||||||
#include "base/tools/Buffer.h"
|
#include "base/tools/Buffer.h"
|
||||||
#include "base/tools/Chrono.h"
|
#include "base/tools/Chrono.h"
|
||||||
#include "common/log/Log.h"
|
|
||||||
#include "net/JobResult.h"
|
#include "net/JobResult.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
#include "rapidjson/error/en.h"
|
#include "rapidjson/error/en.h"
|
||||||
@@ -57,7 +58,6 @@
|
|||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
int64_t Client::m_sequence = 1;
|
|
||||||
Storage<Client> Client::m_storage;
|
Storage<Client> Client::m_storage;
|
||||||
|
|
||||||
} /* namespace xmrig */
|
} /* namespace xmrig */
|
||||||
@@ -75,16 +75,8 @@ static const char *states[] = {
|
|||||||
|
|
||||||
|
|
||||||
xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
|
xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
|
||||||
m_enabled(true),
|
BaseClient(id, listener),
|
||||||
m_ipv6(false),
|
|
||||||
m_quiet(false),
|
|
||||||
m_agent(agent),
|
m_agent(agent),
|
||||||
m_listener(listener),
|
|
||||||
m_id(id),
|
|
||||||
m_retries(5),
|
|
||||||
m_retryPause(5000),
|
|
||||||
m_failures(0),
|
|
||||||
m_state(UnconnectedState),
|
|
||||||
m_tls(nullptr),
|
m_tls(nullptr),
|
||||||
m_expire(0),
|
m_expire(0),
|
||||||
m_jobs(0),
|
m_jobs(0),
|
||||||
@@ -105,73 +97,6 @@ xmrig::Client::~Client()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Client::connect()
|
|
||||||
{
|
|
||||||
# ifndef XMRIG_NO_TLS
|
|
||||||
if (m_pool.isTLS()) {
|
|
||||||
m_tls = new Tls(this);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
resolve(m_pool.host());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Connect to server.
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
*/
|
|
||||||
void xmrig::Client::connect(const Pool &url)
|
|
||||||
{
|
|
||||||
setPool(url);
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Client::deleteLater()
|
|
||||||
{
|
|
||||||
if (!m_listener) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_listener = nullptr;
|
|
||||||
|
|
||||||
if (!disconnect()) {
|
|
||||||
m_storage.remove(m_key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Client::setPool(const Pool &pool)
|
|
||||||
{
|
|
||||||
if (!pool.isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pool = pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Client::tick(uint64_t now)
|
|
||||||
{
|
|
||||||
if (m_state == ConnectedState) {
|
|
||||||
if (m_expire && now > m_expire) {
|
|
||||||
LOG_DEBUG_ERR("[%s] timeout", url());
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
else if (m_keepAlive && now > m_keepAlive) {
|
|
||||||
ping();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_expire && now > m_expire && m_state == ConnectingState) {
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Client::disconnect()
|
bool xmrig::Client::disconnect()
|
||||||
{
|
{
|
||||||
m_keepAlive = 0;
|
m_keepAlive = 0;
|
||||||
@@ -184,7 +109,7 @@ bool xmrig::Client::disconnect()
|
|||||||
|
|
||||||
bool xmrig::Client::isTLS() const
|
bool xmrig::Client::isTLS() const
|
||||||
{
|
{
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
return m_pool.isTLS() && m_tls;
|
return m_pool.isTLS() && m_tls;
|
||||||
# else
|
# else
|
||||||
return false;
|
return false;
|
||||||
@@ -194,7 +119,7 @@ bool xmrig::Client::isTLS() const
|
|||||||
|
|
||||||
const char *xmrig::Client::tlsFingerprint() const
|
const char *xmrig::Client::tlsFingerprint() const
|
||||||
{
|
{
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
if (isTLS() && m_pool.fingerprint() == nullptr) {
|
if (isTLS() && m_pool.fingerprint() == nullptr) {
|
||||||
return m_tls->fingerprint();
|
return m_tls->fingerprint();
|
||||||
}
|
}
|
||||||
@@ -206,7 +131,7 @@ const char *xmrig::Client::tlsFingerprint() const
|
|||||||
|
|
||||||
const char *xmrig::Client::tlsVersion() const
|
const char *xmrig::Client::tlsVersion() const
|
||||||
{
|
{
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
if (isTLS()) {
|
if (isTLS()) {
|
||||||
return m_tls->version();
|
return m_tls->version();
|
||||||
}
|
}
|
||||||
@@ -243,10 +168,6 @@ int64_t xmrig::Client::submit(const JobResult &result)
|
|||||||
Document doc(kObjectType);
|
Document doc(kObjectType);
|
||||||
auto &allocator = doc.GetAllocator();
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
doc.AddMember("id", m_sequence, allocator);
|
|
||||||
doc.AddMember("jsonrpc", "2.0", allocator);
|
|
||||||
doc.AddMember("method", "submit", allocator);
|
|
||||||
|
|
||||||
Value params(kObjectType);
|
Value params(kObjectType);
|
||||||
params.AddMember("id", StringRef(m_rpcId.data()), allocator);
|
params.AddMember("id", StringRef(m_rpcId.data()), allocator);
|
||||||
params.AddMember("job_id", StringRef(result.jobId.data()), allocator);
|
params.AddMember("job_id", StringRef(result.jobId.data()), allocator);
|
||||||
@@ -257,7 +178,7 @@ int64_t xmrig::Client::submit(const JobResult &result)
|
|||||||
params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator);
|
params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.AddMember("params", params, allocator);
|
JsonRequest::create(doc, m_sequence, "submit", params);
|
||||||
|
|
||||||
# ifdef XMRIG_PROXY_PROJECT
|
# ifdef XMRIG_PROXY_PROJECT
|
||||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
|
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
|
||||||
@@ -269,6 +190,57 @@ int64_t xmrig::Client::submit(const JobResult &result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Client::connect()
|
||||||
|
{
|
||||||
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
|
if (m_pool.isTLS()) {
|
||||||
|
m_tls = new Tls(this);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
resolve(m_pool.host());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Client::connect(const Pool &pool)
|
||||||
|
{
|
||||||
|
setPool(pool);
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Client::deleteLater()
|
||||||
|
{
|
||||||
|
if (!m_listener) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_listener = nullptr;
|
||||||
|
|
||||||
|
if (!disconnect()) {
|
||||||
|
m_storage.remove(m_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Client::tick(uint64_t now)
|
||||||
|
{
|
||||||
|
if (m_state == ConnectedState) {
|
||||||
|
if (m_expire && now > m_expire) {
|
||||||
|
LOG_DEBUG_ERR("[%s] timeout", url());
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
else if (m_keepAlive && now > m_keepAlive) {
|
||||||
|
ping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_expire && now > m_expire && m_state == ConnectingState) {
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Client::onResolved(const Dns &dns, int status)
|
void xmrig::Client::onResolved(const Dns &dns, int status)
|
||||||
{
|
{
|
||||||
assert(m_listener != nullptr);
|
assert(m_listener != nullptr);
|
||||||
@@ -284,14 +256,6 @@ void xmrig::Client::onResolved(const Dns &dns, int status)
|
|||||||
return reconnect();
|
return reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dns.isEmpty()) {
|
|
||||||
if (!isQuiet()) {
|
|
||||||
LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", url());
|
|
||||||
}
|
|
||||||
|
|
||||||
return reconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
const DnsRecord &record = dns.get();
|
const DnsRecord &record = dns.get();
|
||||||
m_ip = record.ip();
|
m_ip = record.ip();
|
||||||
|
|
||||||
@@ -435,7 +399,7 @@ bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code)
|
|||||||
|
|
||||||
bool xmrig::Client::send(BIO *bio)
|
bool xmrig::Client::send(BIO *bio)
|
||||||
{
|
{
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
uv_buf_t buf;
|
uv_buf_t buf;
|
||||||
buf.len = BIO_get_mem_data(bio, &buf.base);
|
buf.len = BIO_get_mem_data(bio, &buf.base);
|
||||||
|
|
||||||
@@ -541,9 +505,9 @@ int64_t xmrig::Client::send(const rapidjson::Document &doc)
|
|||||||
|
|
||||||
int64_t xmrig::Client::send(size_t size)
|
int64_t xmrig::Client::send(size_t size)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", url(), size, m_sendBuf);
|
LOG_DEBUG("[%s] send (%d bytes): \"%.*s\"", url(), size, static_cast<int>(size) - 1, m_sendBuf);
|
||||||
|
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
if (isTLS()) {
|
if (isTLS()) {
|
||||||
if (!m_tls->send(m_sendBuf, size)) {
|
if (!m_tls->send(m_sendBuf, size)) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -574,8 +538,6 @@ void xmrig::Client::connect(sockaddr *addr)
|
|||||||
{
|
{
|
||||||
setState(ConnectingState);
|
setState(ConnectingState);
|
||||||
|
|
||||||
reinterpret_cast<sockaddr_in*>(addr)->sin_port = htons(m_pool.port());
|
|
||||||
|
|
||||||
uv_connect_t *req = new uv_connect_t;
|
uv_connect_t *req = new uv_connect_t;
|
||||||
req->data = m_storage.ptr(m_key);
|
req->data = m_storage.ptr(m_key);
|
||||||
|
|
||||||
@@ -589,7 +551,7 @@ void xmrig::Client::connect(sockaddr *addr)
|
|||||||
uv_tcp_keepalive(m_socket, 1, 60);
|
uv_tcp_keepalive(m_socket, 1, 60);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
uv_tcp_connect(req, m_socket, reinterpret_cast<const sockaddr*>(addr), Client::onConnect);
|
uv_tcp_connect(req, m_socket, addr, onConnect);
|
||||||
|
|
||||||
delete addr;
|
delete addr;
|
||||||
}
|
}
|
||||||
@@ -597,7 +559,7 @@ void xmrig::Client::connect(sockaddr *addr)
|
|||||||
|
|
||||||
void xmrig::Client::handshake()
|
void xmrig::Client::handshake()
|
||||||
{
|
{
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
if (isTLS()) {
|
if (isTLS()) {
|
||||||
m_expire = Chrono::steadyMSecs() + kResponseTimeout;
|
m_expire = Chrono::steadyMSecs() + kResponseTimeout;
|
||||||
|
|
||||||
@@ -619,10 +581,6 @@ void xmrig::Client::login()
|
|||||||
Document doc(kObjectType);
|
Document doc(kObjectType);
|
||||||
auto &allocator = doc.GetAllocator();
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
doc.AddMember("id", 1, allocator);
|
|
||||||
doc.AddMember("jsonrpc", "2.0", allocator);
|
|
||||||
doc.AddMember("method", "login", allocator);
|
|
||||||
|
|
||||||
Value params(kObjectType);
|
Value params(kObjectType);
|
||||||
params.AddMember("login", m_pool.user().toJSON(), allocator);
|
params.AddMember("login", m_pool.user().toJSON(), allocator);
|
||||||
params.AddMember("pass", m_pool.password().toJSON(), allocator);
|
params.AddMember("pass", m_pool.password().toJSON(), allocator);
|
||||||
@@ -647,7 +605,7 @@ void xmrig::Client::login()
|
|||||||
|
|
||||||
m_listener->onLogin(this, doc, params);
|
m_listener->onLogin(this, doc, params);
|
||||||
|
|
||||||
doc.AddMember("params", params, allocator);
|
JsonRequest::create(doc, 1, "login", params);
|
||||||
|
|
||||||
send(doc);
|
send(doc);
|
||||||
}
|
}
|
||||||
@@ -661,7 +619,7 @@ void xmrig::Client::onClose()
|
|||||||
m_socket = nullptr;
|
m_socket = nullptr;
|
||||||
setState(UnconnectedState);
|
setState(UnconnectedState);
|
||||||
|
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
if (m_tls) {
|
if (m_tls) {
|
||||||
delete m_tls;
|
delete m_tls;
|
||||||
m_tls = nullptr;
|
m_tls = nullptr;
|
||||||
@@ -676,7 +634,7 @@ void xmrig::Client::parse(char *line, size_t len)
|
|||||||
{
|
{
|
||||||
startTimeout();
|
startTimeout();
|
||||||
|
|
||||||
LOG_DEBUG("[%s] received (%d bytes): \"%s\"", url(), len, line);
|
LOG_DEBUG("[%s] received (%d bytes): \"%.*s\"", url(), len, static_cast<int>(len), line);
|
||||||
|
|
||||||
if (len < 32 || line[0] != '{') {
|
if (len < 32 || line[0] != '{') {
|
||||||
if (!isQuiet()) {
|
if (!isQuiet()) {
|
||||||
@@ -781,14 +739,8 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
|
|||||||
if (error.IsObject()) {
|
if (error.IsObject()) {
|
||||||
const char *message = error["message"].GetString();
|
const char *message = error["message"].GetString();
|
||||||
|
|
||||||
auto it = m_results.find(id);
|
if (!handleSubmitResponse(id, message) && !isQuiet()) {
|
||||||
if (it != m_results.end()) {
|
LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", url(), message, error["code"].GetInt());
|
||||||
it->second.done();
|
|
||||||
m_listener->onResultAccepted(this, it->second, message);
|
|
||||||
m_results.erase(it);
|
|
||||||
}
|
|
||||||
else if (!isQuiet()) {
|
|
||||||
LOG_ERR("[%s] error: \"%s\", code: %d", url(), message, error["code"].GetInt());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCriticalError(message)) {
|
if (isCriticalError(message)) {
|
||||||
@@ -819,12 +771,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = m_results.find(id);
|
handleSubmitResponse(id);
|
||||||
if (it != m_results.end()) {
|
|
||||||
it->second.done();
|
|
||||||
m_listener->onResultAccepted(this, it->second, nullptr);
|
|
||||||
m_results.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -858,7 +805,7 @@ void xmrig::Client::read(ssize_t nread)
|
|||||||
|
|
||||||
m_recvBuf.nread(size);
|
m_recvBuf.nread(size);
|
||||||
|
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
if (isTLS()) {
|
if (isTLS()) {
|
||||||
LOG_DEBUG("[%s] TLS received (%d bytes)", url(), static_cast<int>(nread));
|
LOG_DEBUG("[%s] TLS received (%d bytes)", url(), static_cast<int>(nread));
|
||||||
|
|
||||||
@@ -970,7 +917,7 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
|
|||||||
client->m_stream->data = req->data;
|
client->m_stream->data = req->data;
|
||||||
client->setState(ConnectedState);
|
client->setState(ConnectedState);
|
||||||
|
|
||||||
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
|
uv_read_start(client->m_stream, onAllocBuffer, onRead);
|
||||||
delete req;
|
delete req;
|
||||||
|
|
||||||
client->handshake();
|
client->handshake();
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "base/kernel/interfaces/IDnsListener.h"
|
#include "base/kernel/interfaces/IDnsListener.h"
|
||||||
#include "base/kernel/interfaces/ILineListener.h"
|
#include "base/kernel/interfaces/ILineListener.h"
|
||||||
|
#include "base/net/stratum/BaseClient.h"
|
||||||
#include "base/net/stratum/Job.h"
|
#include "base/net/stratum/Job.h"
|
||||||
#include "base/net/stratum/Pool.h"
|
#include "base/net/stratum/Pool.h"
|
||||||
#include "base/net/stratum/SubmitResult.h"
|
#include "base/net/stratum/SubmitResult.h"
|
||||||
@@ -42,7 +43,6 @@
|
|||||||
#include "common/crypto/Algorithm.h"
|
#include "common/crypto/Algorithm.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct bio_st BIO;
|
typedef struct bio_st BIO;
|
||||||
|
|
||||||
|
|
||||||
@@ -53,29 +53,12 @@ class IClientListener;
|
|||||||
class JobResult;
|
class JobResult;
|
||||||
|
|
||||||
|
|
||||||
class Client : public IDnsListener, public ILineListener
|
class Client : public BaseClient, public IDnsListener, public ILineListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum SocketState {
|
|
||||||
UnconnectedState,
|
|
||||||
HostLookupState,
|
|
||||||
ConnectingState,
|
|
||||||
ConnectedState,
|
|
||||||
ClosingState
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Extension {
|
|
||||||
EXT_ALGO,
|
|
||||||
EXT_NICEHASH,
|
|
||||||
EXT_CONNECT,
|
|
||||||
EXT_TLS,
|
|
||||||
EXT_KEEPALIVE,
|
|
||||||
EXT_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr static int kResponseTimeout = 20 * 1000;
|
constexpr static int kResponseTimeout = 20 * 1000;
|
||||||
|
|
||||||
# ifndef XMRIG_NO_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
constexpr static int kInputBufferSize = 1024 * 16;
|
constexpr static int kInputBufferSize = 1024 * 16;
|
||||||
# else
|
# else
|
||||||
constexpr static int kInputBufferSize = 1024 * 2;
|
constexpr static int kInputBufferSize = 1024 * 2;
|
||||||
@@ -84,39 +67,23 @@ public:
|
|||||||
Client(int id, const char *agent, IClientListener *listener);
|
Client(int id, const char *agent, IClientListener *listener);
|
||||||
~Client() override;
|
~Client() override;
|
||||||
|
|
||||||
bool disconnect();
|
|
||||||
bool isTLS() const;
|
|
||||||
const char *tlsFingerprint() const;
|
|
||||||
const char *tlsVersion() const;
|
|
||||||
int64_t submit(const JobResult &result);
|
|
||||||
void connect();
|
|
||||||
void connect(const Pool &pool);
|
|
||||||
void deleteLater();
|
|
||||||
void setPool(const Pool &pool);
|
|
||||||
void tick(uint64_t now);
|
|
||||||
|
|
||||||
inline bool isEnabled() const { return m_enabled; }
|
|
||||||
inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; }
|
|
||||||
inline const char *host() const { return m_pool.host(); }
|
|
||||||
inline const char *ip() const { return m_ip; }
|
|
||||||
inline const Job &job() const { return m_job; }
|
|
||||||
inline const Pool &pool() const { return m_pool; }
|
|
||||||
inline int id() const { return m_id; }
|
|
||||||
inline SocketState state() const { return m_state; }
|
|
||||||
inline uint16_t port() const { return m_pool.port(); }
|
|
||||||
inline void setAlgo(const Algorithm &algo) { m_pool.setAlgo(algo); }
|
|
||||||
inline void setEnabled(bool enabled) { m_enabled = enabled; }
|
|
||||||
inline void setQuiet(bool quiet) { m_quiet = quiet; }
|
|
||||||
inline void setRetries(int retries) { m_retries = retries; }
|
|
||||||
inline void setRetryPause(int ms) { m_retryPause = ms; }
|
|
||||||
|
|
||||||
template<Extension ext> inline bool has() const noexcept { return m_extensions.test(ext); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline void onLine(char *line, size_t size) override { parse(line, size); }
|
bool disconnect() override;
|
||||||
|
bool isTLS() const override;
|
||||||
|
const char *tlsFingerprint() const override;
|
||||||
|
const char *tlsVersion() const override;
|
||||||
|
int64_t submit(const JobResult &result) override;
|
||||||
|
void connect() override;
|
||||||
|
void connect(const Pool &pool) override;
|
||||||
|
void deleteLater() override;
|
||||||
|
void tick(uint64_t now) override;
|
||||||
|
|
||||||
void onResolved(const Dns &dns, int status) override;
|
void onResolved(const Dns &dns, int status) override;
|
||||||
|
|
||||||
|
inline bool hasExtension(Extension extension) const noexcept override { return m_extensions.test(extension); }
|
||||||
|
inline const char *mode() const override { return "pool"; }
|
||||||
|
inline void onLine(char *line, size_t size) override { parse(line, size); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Tls;
|
class Tls;
|
||||||
|
|
||||||
@@ -143,9 +110,10 @@ private:
|
|||||||
void setState(SocketState state);
|
void setState(SocketState state);
|
||||||
void startTimeout();
|
void startTimeout();
|
||||||
|
|
||||||
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
|
|
||||||
inline const char *url() const { return m_pool.url(); }
|
inline const char *url() const { return m_pool.url(); }
|
||||||
|
inline SocketState state() const { return m_state; }
|
||||||
inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
|
inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
|
||||||
|
template<Extension ext> inline bool has() const noexcept { return m_extensions.test(ext); }
|
||||||
|
|
||||||
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||||
static void onClose(uv_handle_t *handle);
|
static void onClose(uv_handle_t *handle);
|
||||||
@@ -154,24 +122,11 @@ private:
|
|||||||
|
|
||||||
static inline Client *getClient(void *data) { return m_storage.get(data); }
|
static inline Client *getClient(void *data) { return m_storage.get(data); }
|
||||||
|
|
||||||
bool m_enabled;
|
|
||||||
bool m_ipv6;
|
|
||||||
bool m_quiet;
|
|
||||||
char m_sendBuf[2048];
|
char m_sendBuf[2048];
|
||||||
const char *m_agent;
|
const char *m_agent;
|
||||||
Dns *m_dns;
|
Dns *m_dns;
|
||||||
IClientListener *m_listener;
|
|
||||||
int m_id;
|
|
||||||
int m_retries;
|
|
||||||
int m_retryPause;
|
|
||||||
int64_t m_failures;
|
|
||||||
Job m_job;
|
|
||||||
Pool m_pool;
|
|
||||||
RecvBuf<kInputBufferSize> m_recvBuf;
|
RecvBuf<kInputBufferSize> m_recvBuf;
|
||||||
SocketState m_state;
|
|
||||||
std::bitset<EXT_MAX> m_extensions;
|
std::bitset<EXT_MAX> m_extensions;
|
||||||
std::map<int64_t, SubmitResult> m_results;
|
|
||||||
String m_ip;
|
|
||||||
String m_rpcId;
|
String m_rpcId;
|
||||||
Tls *m_tls;
|
Tls *m_tls;
|
||||||
uint64_t m_expire;
|
uint64_t m_expire;
|
||||||
@@ -181,7 +136,6 @@ private:
|
|||||||
uv_stream_t *m_stream;
|
uv_stream_t *m_stream;
|
||||||
uv_tcp_t *m_socket;
|
uv_tcp_t *m_socket;
|
||||||
|
|
||||||
static int64_t m_sequence;
|
|
||||||
static Storage<Client> m_storage;
|
static Storage<Client> m_storage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
378
src/base/net/stratum/DaemonClient.cpp
Normal file
378
src/base/net/stratum/DaemonClient.cpp
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "3rdparty/http-parser/http_parser.h"
|
||||||
|
#include "base/io/json/Json.h"
|
||||||
|
#include "base/io/json/JsonRequest.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/kernel/interfaces/IClientListener.h"
|
||||||
|
#include "base/net/http/HttpClient.h"
|
||||||
|
#include "base/net/stratum/DaemonClient.h"
|
||||||
|
#include "base/net/stratum/SubmitResult.h"
|
||||||
|
#include "base/tools/Buffer.h"
|
||||||
|
#include "base/tools/Timer.h"
|
||||||
|
#include "net/JobResult.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
#include "rapidjson/error/en.h"
|
||||||
|
#include "rapidjson/stringbuffer.h"
|
||||||
|
#include "rapidjson/writer.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_TLS
|
||||||
|
# include "base/net/http/HttpsClient.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const char *kBlocktemplateBlob = "blocktemplate_blob";
|
||||||
|
static const char *kGetHeight = "/getheight";
|
||||||
|
static const char *kGetInfo = "/getinfo";
|
||||||
|
static const char *kHash = "hash";
|
||||||
|
static const char *kHeight = "height";
|
||||||
|
static const char *kJsonRPC = "/json_rpc";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) :
|
||||||
|
BaseClient(id, listener),
|
||||||
|
m_monero(true)
|
||||||
|
{
|
||||||
|
m_timer = new Timer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::DaemonClient::~DaemonClient()
|
||||||
|
{
|
||||||
|
delete m_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::DaemonClient::disconnect()
|
||||||
|
{
|
||||||
|
if (m_state != UnconnectedState) {
|
||||||
|
setState(UnconnectedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::DaemonClient::isTLS() const
|
||||||
|
{
|
||||||
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
|
return m_pool.isTLS();
|
||||||
|
# else
|
||||||
|
return false;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t xmrig::DaemonClient::submit(const JobResult &result)
|
||||||
|
{
|
||||||
|
if (result.jobId != (m_blocktemplate.data() + m_blocktemplate.size() - 32)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_PROXY_PROJECT
|
||||||
|
memcpy(m_blocktemplate.data() + 78, result.nonce, 8);
|
||||||
|
# else
|
||||||
|
Buffer::toHex(reinterpret_cast<const uint8_t *>(&result.nonce), 4, m_blocktemplate.data() + 78);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
using namespace rapidjson;
|
||||||
|
Document doc(kObjectType);
|
||||||
|
|
||||||
|
Value params(kArrayType);
|
||||||
|
params.PushBack(m_blocktemplate.toJSON(), doc.GetAllocator());
|
||||||
|
|
||||||
|
JsonRequest::create(doc, m_sequence, "submitblock", params);
|
||||||
|
|
||||||
|
# ifdef XMRIG_PROXY_PROJECT
|
||||||
|
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
|
||||||
|
# else
|
||||||
|
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
|
||||||
|
# endif
|
||||||
|
|
||||||
|
send(HTTP_POST, kJsonRPC, doc);
|
||||||
|
|
||||||
|
return m_sequence++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::connect()
|
||||||
|
{
|
||||||
|
setState(ConnectingState);
|
||||||
|
getBlockTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::connect(const Pool &pool)
|
||||||
|
{
|
||||||
|
setPool(pool);
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::onHttpData(const HttpData &data)
|
||||||
|
{
|
||||||
|
if (data.status != HTTP_STATUS_OK) {
|
||||||
|
return retry();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("[%s:%d] received (%d bytes): \"%.*s\"", m_pool.host().data(), m_pool.port(), static_cast<int>(data.body.size()), static_cast<int>(data.body.size()), data.body.c_str());
|
||||||
|
|
||||||
|
m_ip = static_cast<const HttpContext &>(data).ip().c_str();
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
|
if (isTLS()) {
|
||||||
|
m_tlsVersion = static_cast<const HttpsClient &>(data).version();
|
||||||
|
m_tlsFingerprint = static_cast<const HttpsClient &>(data).fingerprint();
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
rapidjson::Document doc;
|
||||||
|
if (doc.Parse(data.body.c_str()).HasParseError()) {
|
||||||
|
if (!isQuiet()) {
|
||||||
|
LOG_ERR("[%s:%d] JSON decode failed: \"%s\"", m_pool.host().data(), m_pool.port(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retry();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.method == HTTP_GET) {
|
||||||
|
if (data.url == kGetHeight) {
|
||||||
|
if (!doc.HasMember(kHash)) {
|
||||||
|
m_monero = false;
|
||||||
|
|
||||||
|
return send(HTTP_GET, kGetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, kHash))) {
|
||||||
|
getBlockTemplate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data.url == kGetInfo && isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, "top_block_hash"))) {
|
||||||
|
getBlockTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parseResponse(Json::getInt64(doc, "id", -1), Json::getObject(doc, "result"), Json::getObject(doc, "error"))) {
|
||||||
|
retry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::onTimer(const Timer *)
|
||||||
|
{
|
||||||
|
if (m_state == ConnectingState) {
|
||||||
|
getBlockTemplate();
|
||||||
|
}
|
||||||
|
else if (m_state == ConnectedState) {
|
||||||
|
send(HTTP_GET, m_monero ? kGetHeight : kGetInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::DaemonClient::isOutdated(uint64_t height, const char *hash) const
|
||||||
|
{
|
||||||
|
return m_job.height() != height || m_prevHash != hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||||
|
{
|
||||||
|
Job job(m_id, false, m_pool.algorithm(), String());
|
||||||
|
|
||||||
|
String blocktemplate = Json::getString(params, kBlocktemplateBlob);
|
||||||
|
if (blocktemplate.isNull() || !job.setBlob(Json::getString(params, "blockhashing_blob"))) {
|
||||||
|
*code = 4;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
job.setHeight(Json::getUint64(params, kHeight));
|
||||||
|
job.setDiff(Json::getUint64(params, "difficulty"));
|
||||||
|
job.setId(blocktemplate.data() + blocktemplate.size() - 32);
|
||||||
|
|
||||||
|
m_job = std::move(job);
|
||||||
|
m_blocktemplate = std::move(blocktemplate);
|
||||||
|
m_prevHash = Json::getString(params, "prev_hash");
|
||||||
|
|
||||||
|
if (m_state == ConnectingState) {
|
||||||
|
setState(ConnectedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_listener->onJobReceived(this, m_job, params);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::DaemonClient::parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
|
||||||
|
{
|
||||||
|
if (id == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.IsObject()) {
|
||||||
|
const char *message = error["message"].GetString();
|
||||||
|
|
||||||
|
if (!handleSubmitResponse(id, message) && !isQuiet()) {
|
||||||
|
LOG_ERR("[%s:%d] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", m_pool.host().data(), m_pool.port(), message, error["code"].GetInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.IsObject()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int code = -1;
|
||||||
|
if (result.HasMember(kBlocktemplateBlob) && parseJob(result, &code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handleSubmitResponse(id)) {
|
||||||
|
getBlockTemplate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t xmrig::DaemonClient::getBlockTemplate()
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
Document doc(kObjectType);
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
Value params(kObjectType);
|
||||||
|
params.AddMember("wallet_address", m_pool.user().toJSON(), allocator);
|
||||||
|
params.AddMember("reserve_size", 8, allocator);
|
||||||
|
|
||||||
|
JsonRequest::create(doc, m_sequence, "getblocktemplate", params);
|
||||||
|
|
||||||
|
send(HTTP_POST, kJsonRPC, doc);
|
||||||
|
|
||||||
|
return m_sequence++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::retry()
|
||||||
|
{
|
||||||
|
m_failures++;
|
||||||
|
m_listener->onClose(this, static_cast<int>(m_failures));
|
||||||
|
|
||||||
|
if (m_failures == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_state == ConnectedState) {
|
||||||
|
setState(ConnectingState);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_timer->stop();
|
||||||
|
m_timer->start(m_retryPause, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::send(int method, const char *url, const char *data, size_t size)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("[%s:%d] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"",
|
||||||
|
m_pool.host().data(),
|
||||||
|
m_pool.port(),
|
||||||
|
http_method_str(static_cast<http_method>(method)),
|
||||||
|
url,
|
||||||
|
size,
|
||||||
|
static_cast<int>(size),
|
||||||
|
data);
|
||||||
|
|
||||||
|
HttpClient *client;
|
||||||
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
|
if (m_pool.isTLS()) {
|
||||||
|
client = new HttpsClient(method, url, this, data, size, m_pool.fingerprint());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
client = new HttpClient(method, url, this, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
client->setQuiet(isQuiet());
|
||||||
|
client->connect(m_pool.host(), m_pool.port());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::send(int method, const char *url, const rapidjson::Document &doc)
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
|
||||||
|
StringBuffer buffer(nullptr, 512);
|
||||||
|
Writer<StringBuffer> writer(buffer);
|
||||||
|
doc.Accept(writer);
|
||||||
|
|
||||||
|
send(method, url, buffer.GetString(), buffer.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::DaemonClient::setState(SocketState state)
|
||||||
|
{
|
||||||
|
assert(m_state != state);
|
||||||
|
if (m_state == state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_state = state;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case ConnectedState:
|
||||||
|
{
|
||||||
|
m_failures = 0;
|
||||||
|
m_listener->onLoginSuccess(this);
|
||||||
|
|
||||||
|
const uint64_t interval = std::max<uint64_t>(20, m_pool.pollInterval());
|
||||||
|
m_timer->start(interval, interval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UnconnectedState:
|
||||||
|
m_failures = -1;
|
||||||
|
m_timer->stop();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
83
src/base/net/stratum/DaemonClient.h
Normal file
83
src/base/net/stratum/DaemonClient.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_DAEMONCLIENT_H
|
||||||
|
#define XMRIG_DAEMONCLIENT_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/net/stratum/BaseClient.h"
|
||||||
|
#include "base/kernel/interfaces/ITimerListener.h"
|
||||||
|
#include "base/kernel/interfaces/IHttpListener.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class DaemonClient : public BaseClient, public ITimerListener, public IHttpListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DaemonClient(int id, IClientListener *listener);
|
||||||
|
~DaemonClient() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool disconnect() override;
|
||||||
|
bool isTLS() const override;
|
||||||
|
int64_t submit(const JobResult &result) override;
|
||||||
|
void connect() override;
|
||||||
|
void connect(const Pool &pool) override;
|
||||||
|
|
||||||
|
void onHttpData(const HttpData &data) override;
|
||||||
|
void onTimer(const Timer *timer) override;
|
||||||
|
|
||||||
|
inline bool hasExtension(Extension) const noexcept override { return false; }
|
||||||
|
inline const char *mode() const override { return "daemon"; }
|
||||||
|
inline const char *tlsFingerprint() const override { return m_tlsFingerprint; }
|
||||||
|
inline const char *tlsVersion() const override { return m_tlsVersion; }
|
||||||
|
inline void deleteLater() override { delete this; }
|
||||||
|
inline void tick(uint64_t) override {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isOutdated(uint64_t height, const char *hash) const;
|
||||||
|
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
||||||
|
bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||||
|
int64_t getBlockTemplate();
|
||||||
|
void retry();
|
||||||
|
void send(int method, const char *url, const char *data = nullptr, size_t size = 0);
|
||||||
|
void send(int method, const char *url, const rapidjson::Document &doc);
|
||||||
|
void setState(SocketState state);
|
||||||
|
|
||||||
|
bool m_monero;
|
||||||
|
String m_blocktemplate;
|
||||||
|
String m_prevHash;
|
||||||
|
String m_tlsFingerprint;
|
||||||
|
String m_tlsVersion;
|
||||||
|
Timer *m_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_DAEMONCLIENT_H */
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||||
* Copyright 2018 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@@ -101,24 +102,6 @@ bool xmrig::Job::setBlob(const char *blob)
|
|||||||
m_algorithm.setVariant(variant());
|
m_algorithm.setVariant(variant());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_algorithm.isForced()) {
|
|
||||||
if (m_algorithm.variant() == VARIANT_XTL && m_blob[0] >= 9) {
|
|
||||||
m_algorithm.setVariant(VARIANT_HALF);
|
|
||||||
}
|
|
||||||
else if (m_algorithm.variant() == VARIANT_MSR && m_blob[0] >= 8) {
|
|
||||||
m_algorithm.setVariant(VARIANT_HALF);
|
|
||||||
}
|
|
||||||
else if (m_algorithm.variant() == VARIANT_WOW && m_blob[0] < 11) {
|
|
||||||
m_algorithm.setVariant(VARIANT_2);
|
|
||||||
}
|
|
||||||
else if (m_algorithm.variant() == VARIANT_RWZ && m_blob[0] < 12) {
|
|
||||||
m_algorithm.setVariant(VARIANT_2);
|
|
||||||
}
|
|
||||||
else if (m_algorithm.variant() == VARIANT_ZLS && m_blob[0] < 8) {
|
|
||||||
m_algorithm.setVariant(VARIANT_2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ifdef XMRIG_PROXY_PROJECT
|
# ifdef XMRIG_PROXY_PROJECT
|
||||||
memset(m_rawBlob, 0, sizeof(m_rawBlob));
|
memset(m_rawBlob, 0, sizeof(m_rawBlob));
|
||||||
memcpy(m_rawBlob, blob, m_size * 2);
|
memcpy(m_rawBlob, blob, m_size * 2);
|
||||||
@@ -180,9 +163,15 @@ void xmrig::Job::setAlgorithm(const char *algo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Job::setHeight(uint64_t height)
|
void xmrig::Job::setDiff(uint64_t diff)
|
||||||
{
|
{
|
||||||
m_height = height;
|
m_diff = diff;
|
||||||
|
m_target = toDiff(diff);
|
||||||
|
|
||||||
|
# ifdef XMRIG_PROXY_PROJECT
|
||||||
|
Buffer::toHex(reinterpret_cast<uint8_t *>(&m_target), 8, m_rawTarget);
|
||||||
|
m_rawTarget[16] = '\0';
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@@ -53,7 +54,7 @@ public:
|
|||||||
bool setBlob(const char *blob);
|
bool setBlob(const char *blob);
|
||||||
bool setTarget(const char *target);
|
bool setTarget(const char *target);
|
||||||
void setAlgorithm(const char *algo);
|
void setAlgorithm(const char *algo);
|
||||||
void setHeight(uint64_t height);
|
void setDiff(uint64_t diff);
|
||||||
|
|
||||||
inline bool isNicehash() const { return m_nicehash; }
|
inline bool isNicehash() const { return m_nicehash; }
|
||||||
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
inline bool isValid() const { return m_size > 0 && m_diff > 0; }
|
||||||
@@ -67,12 +68,13 @@ public:
|
|||||||
inline int threadId() const { return m_threadId; }
|
inline int threadId() const { return m_threadId; }
|
||||||
inline size_t size() const { return m_size; }
|
inline size_t size() const { return m_size; }
|
||||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
||||||
inline uint32_t diff() const { return static_cast<uint32_t>(m_diff); }
|
inline uint64_t diff() const { return m_diff; }
|
||||||
inline uint64_t height() const { return m_height; }
|
inline uint64_t height() const { return m_height; }
|
||||||
inline uint64_t target() const { return m_target; }
|
inline uint64_t target() const { return m_target; }
|
||||||
inline uint8_t fixedByte() const { return *(m_blob + 42); }
|
inline uint8_t fixedByte() const { return *(m_blob + 42); }
|
||||||
inline void reset() { m_size = 0; m_diff = 0; }
|
inline void reset() { m_size = 0; m_diff = 0; }
|
||||||
inline void setClientId(const String &id) { m_clientId = id; }
|
inline void setClientId(const String &id) { m_clientId = id; }
|
||||||
|
inline void setHeight(uint64_t height) { m_height = height; }
|
||||||
inline void setPoolId(int poolId) { m_poolId = poolId; }
|
inline void setPoolId(int poolId) { m_poolId = poolId; }
|
||||||
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
inline void setThreadId(int threadId) { m_threadId = threadId; }
|
||||||
inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); }
|
inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@@ -29,24 +30,25 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#include "base/io/Json.h"
|
#include "base/io/json/Json.h"
|
||||||
#include "base/net/stratum/Pool.h"
|
#include "base/net/stratum/Pool.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef APP_DEBUG
|
#ifdef APP_DEBUG
|
||||||
# include "common/log/Log.h"
|
# include "base/io/log/Log.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define strncasecmp _strnicmp
|
# define strncasecmp _strnicmp
|
||||||
# define strcasecmp _stricmp
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const char *kDaemon = "daemon";
|
||||||
|
static const char *kDaemonPollInterval = "daemon-poll-interval";
|
||||||
static const char *kEnabled = "enabled";
|
static const char *kEnabled = "enabled";
|
||||||
static const char *kFingerprint = "tls-fingerprint";
|
static const char *kFingerprint = "tls-fingerprint";
|
||||||
static const char *kKeepalive = "keepalive";
|
static const char *kKeepalive = "keepalive";
|
||||||
@@ -61,15 +63,22 @@ static const char *kVariant = "variant";
|
|||||||
const String Pool::kDefaultPassword = "x";
|
const String Pool::kDefaultPassword = "x";
|
||||||
const String Pool::kDefaultUser = "x";
|
const String Pool::kDefaultUser = "x";
|
||||||
|
|
||||||
|
static const char kStratumTcp[] = "stratum+tcp://";
|
||||||
|
static const char kStratumSsl[] = "stratum+ssl://";
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_HTTP
|
||||||
|
static const char kDaemonHttp[] = "daemon+http://";
|
||||||
|
static const char kDaemonHttps[] = "daemon+https://";
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::Pool::Pool() :
|
xmrig::Pool::Pool() :
|
||||||
m_enabled(true),
|
|
||||||
m_nicehash(false),
|
|
||||||
m_tls(false),
|
|
||||||
m_keepAlive(0),
|
m_keepAlive(0),
|
||||||
m_port(kDefaultPort)
|
m_flags(0),
|
||||||
|
m_port(kDefaultPort),
|
||||||
|
m_pollInterval(kDefaultPollInterval)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,33 +95,37 @@ xmrig::Pool::Pool() :
|
|||||||
* @param url
|
* @param url
|
||||||
*/
|
*/
|
||||||
xmrig::Pool::Pool(const char *url) :
|
xmrig::Pool::Pool(const char *url) :
|
||||||
m_enabled(true),
|
|
||||||
m_nicehash(false),
|
|
||||||
m_tls(false),
|
|
||||||
m_keepAlive(0),
|
m_keepAlive(0),
|
||||||
m_port(kDefaultPort)
|
m_flags(1),
|
||||||
|
m_port(kDefaultPort),
|
||||||
|
m_pollInterval(kDefaultPollInterval)
|
||||||
{
|
{
|
||||||
parse(url);
|
parse(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::Pool::Pool(const rapidjson::Value &object) :
|
xmrig::Pool::Pool(const rapidjson::Value &object) :
|
||||||
m_enabled(true),
|
|
||||||
m_nicehash(false),
|
|
||||||
m_tls(false),
|
|
||||||
m_keepAlive(0),
|
m_keepAlive(0),
|
||||||
m_port(kDefaultPort)
|
m_flags(1),
|
||||||
|
m_port(kDefaultPort),
|
||||||
|
m_pollInterval(kDefaultPollInterval)
|
||||||
{
|
{
|
||||||
if (!parse(Json::getString(object, kUrl))) {
|
if (!parse(Json::getString(object, kUrl))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setUser(Json::getString(object, kUser));
|
m_user = Json::getString(object, kUser);
|
||||||
setPassword(Json::getString(object, kPass));
|
m_password = Json::getString(object, kPass);
|
||||||
setRigId(Json::getString(object, kRigId));
|
m_rigId = Json::getString(object, kRigId);
|
||||||
setNicehash(Json::getBool(object, kNicehash));
|
m_fingerprint = Json::getString(object, kFingerprint);
|
||||||
|
m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval);
|
||||||
|
|
||||||
const rapidjson::Value &keepalive = object[kKeepalive];
|
m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true));
|
||||||
|
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash));
|
||||||
|
m_flags.set(FLAG_TLS, Json::getBool(object, kTls, m_flags.test(FLAG_TLS)));
|
||||||
|
m_flags.set(FLAG_DAEMON, Json::getBool(object, kDaemon, m_flags.test(FLAG_DAEMON)));
|
||||||
|
|
||||||
|
const rapidjson::Value &keepalive = Json::getValue(object, kKeepalive);
|
||||||
if (keepalive.IsInt()) {
|
if (keepalive.IsInt()) {
|
||||||
setKeepAlive(keepalive.GetInt());
|
setKeepAlive(keepalive.GetInt());
|
||||||
}
|
}
|
||||||
@@ -120,7 +133,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
|
|||||||
setKeepAlive(keepalive.GetBool());
|
setKeepAlive(keepalive.GetBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
const rapidjson::Value &variant = object[kVariant];
|
const rapidjson::Value &variant = Json::getValue(object, kVariant);
|
||||||
if (variant.IsString()) {
|
if (variant.IsString()) {
|
||||||
algorithm().parseVariant(variant.GetString());
|
algorithm().parseVariant(variant.GetString());
|
||||||
}
|
}
|
||||||
@@ -128,21 +141,17 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
|
|||||||
algorithm().parseVariant(variant.GetInt());
|
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) :
|
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_keepAlive(keepAlive),
|
||||||
|
m_flags(1),
|
||||||
m_host(host),
|
m_host(host),
|
||||||
m_password(password),
|
m_password(password),
|
||||||
m_user(user),
|
m_user(user),
|
||||||
m_port(port)
|
m_port(port),
|
||||||
|
m_pollInterval(kDefaultPollInterval)
|
||||||
{
|
{
|
||||||
const size_t size = m_host.size() + 8;
|
const size_t size = m_host.size() + 8;
|
||||||
assert(size > 8);
|
assert(size > 8);
|
||||||
@@ -151,6 +160,9 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char
|
|||||||
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
|
snprintf(url, size - 1, "%s:%d", m_host.data(), m_port);
|
||||||
|
|
||||||
m_url = url;
|
m_url = url;
|
||||||
|
|
||||||
|
m_flags.set(FLAG_NICEHASH, nicehash);
|
||||||
|
m_flags.set(FLAG_TLS, tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -178,21 +190,25 @@ bool xmrig::Pool::isCompatible(const Algorithm &algorithm) const
|
|||||||
|
|
||||||
bool xmrig::Pool::isEnabled() const
|
bool xmrig::Pool::isEnabled() const
|
||||||
{
|
{
|
||||||
# ifdef XMRIG_NO_TLS
|
# ifndef XMRIG_FEATURE_TLS
|
||||||
if (isTLS()) {
|
if (isTLS()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
return m_enabled && isValid() && algorithm().isValid();
|
# ifndef XMRIG_FEATURE_HTTP
|
||||||
|
if (isDaemon()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return m_flags.test(FLAG_ENABLED) && isValid() && algorithm().isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Pool::isEqual(const Pool &other) const
|
bool xmrig::Pool::isEqual(const Pool &other) const
|
||||||
{
|
{
|
||||||
return (m_nicehash == other.m_nicehash
|
return (m_flags == other.m_flags
|
||||||
&& m_enabled == other.m_enabled
|
|
||||||
&& m_tls == other.m_tls
|
|
||||||
&& m_keepAlive == other.m_keepAlive
|
&& m_keepAlive == other.m_keepAlive
|
||||||
&& m_port == other.m_port
|
&& m_port == other.m_port
|
||||||
&& m_algorithm == other.m_algorithm
|
&& m_algorithm == other.m_algorithm
|
||||||
@@ -201,7 +217,8 @@ bool xmrig::Pool::isEqual(const Pool &other) const
|
|||||||
&& m_password == other.m_password
|
&& m_password == other.m_password
|
||||||
&& m_rigId == other.m_rigId
|
&& m_rigId == other.m_rigId
|
||||||
&& m_url == other.m_url
|
&& m_url == other.m_url
|
||||||
&& m_user == other.m_user);
|
&& m_user == other.m_user
|
||||||
|
&& m_pollInterval == other.m_pollInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -213,17 +230,29 @@ bool xmrig::Pool::parse(const char *url)
|
|||||||
const char *base = url;
|
const char *base = url;
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
if (strncasecmp(url, "stratum+tcp://", 14) == 0) {
|
if (strncasecmp(url, kStratumTcp, sizeof(kStratumTcp) - 1) == 0) {
|
||||||
m_tls = false;
|
m_flags.set(FLAG_DAEMON, false);
|
||||||
|
m_flags.set(FLAG_TLS, false);
|
||||||
}
|
}
|
||||||
else if (strncasecmp(url, "stratum+ssl://", 14) == 0) {
|
else if (strncasecmp(url, kStratumSsl, sizeof(kStratumSsl) - 1) == 0) {
|
||||||
m_tls = true;
|
m_flags.set(FLAG_DAEMON, false);
|
||||||
|
m_flags.set(FLAG_TLS, true);
|
||||||
}
|
}
|
||||||
|
# ifdef XMRIG_FEATURE_HTTP
|
||||||
|
else if (strncasecmp(url, kDaemonHttps, sizeof(kDaemonHttps) - 1) == 0) {
|
||||||
|
m_flags.set(FLAG_DAEMON, true);
|
||||||
|
m_flags.set(FLAG_TLS, true);
|
||||||
|
}
|
||||||
|
else if (strncasecmp(url, kDaemonHttp, sizeof(kDaemonHttp) - 1) == 0) {
|
||||||
|
m_flags.set(FLAG_DAEMON, true);
|
||||||
|
m_flags.set(FLAG_TLS, false);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
base = url + 14;
|
base = p + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strlen(base) || *base == '/') {
|
if (!strlen(base) || *base == '/') {
|
||||||
@@ -252,23 +281,6 @@ bool xmrig::Pool::parse(const char *url)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Pool::setUserpass(const char *userpass)
|
|
||||||
{
|
|
||||||
const char *p = strchr(userpass, ':');
|
|
||||||
if (!p) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *user = new char[p - userpass + 1]();
|
|
||||||
strncpy(user, userpass, static_cast<size_t>(p - userpass));
|
|
||||||
|
|
||||||
m_user = user;
|
|
||||||
m_password = p + 1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
|
rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
|
||||||
{
|
{
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
@@ -309,9 +321,11 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator);
|
||||||
obj.AddMember(StringRef(kTls), isTLS(), allocator);
|
obj.AddMember(StringRef(kTls), isTLS(), allocator);
|
||||||
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
|
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
|
||||||
|
obj.AddMember(StringRef(kDaemon), m_flags.test(FLAG_DAEMON), allocator);
|
||||||
|
obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@@ -350,7 +364,7 @@ void xmrig::Pool::print() const
|
|||||||
LOG_DEBUG ("pass: %s", m_password.data());
|
LOG_DEBUG ("pass: %s", m_password.data());
|
||||||
LOG_DEBUG ("rig-id %s", m_rigId.data());
|
LOG_DEBUG ("rig-id %s", m_rigId.data());
|
||||||
LOG_DEBUG ("algo: %s", m_algorithm.name());
|
LOG_DEBUG ("algo: %s", m_algorithm.name());
|
||||||
LOG_DEBUG ("nicehash: %d", static_cast<int>(m_nicehash));
|
LOG_DEBUG ("nicehash: %d", static_cast<int>(m_flags.test(FLAG_NICEHASH)));
|
||||||
LOG_DEBUG ("keepAlive: %d", m_keepAlive);
|
LOG_DEBUG ("keepAlive: %d", m_keepAlive);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -396,8 +410,8 @@ void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint)
|
|||||||
using namespace xmrig;
|
using namespace xmrig;
|
||||||
|
|
||||||
if (m_host.contains(".nicehash.com")) {
|
if (m_host.contains(".nicehash.com")) {
|
||||||
|
m_flags.set(FLAG_NICEHASH, true);
|
||||||
m_keepAlive = false;
|
m_keepAlive = false;
|
||||||
m_nicehash = true;
|
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
|
|
||||||
switch (m_port) {
|
switch (m_port) {
|
||||||
@@ -432,7 +446,7 @@ void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint)
|
|||||||
m_algorithm.setAlgo(INVALID_ALGO);
|
m_algorithm.setAlgo(INVALID_ALGO);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_tls = m_port > 33000;
|
m_flags.set(FLAG_TLS, m_port > 33000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
#define XMRIG_POOL_H
|
#define XMRIG_POOL_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
@@ -40,11 +42,20 @@ namespace xmrig {
|
|||||||
class Pool
|
class Pool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum Flags {
|
||||||
|
FLAG_ENABLED,
|
||||||
|
FLAG_NICEHASH,
|
||||||
|
FLAG_TLS,
|
||||||
|
FLAG_DAEMON,
|
||||||
|
FLAG_MAX
|
||||||
|
};
|
||||||
|
|
||||||
static const String kDefaultPassword;
|
static const String kDefaultPassword;
|
||||||
static const String kDefaultUser;
|
static const String kDefaultUser;
|
||||||
|
|
||||||
constexpr static uint16_t kDefaultPort = 3333;
|
|
||||||
constexpr static int kKeepAliveTimeout = 60;
|
constexpr static int kKeepAliveTimeout = 60;
|
||||||
|
constexpr static uint16_t kDefaultPort = 3333;
|
||||||
|
constexpr static uint64_t kDefaultPollInterval = 1000;
|
||||||
|
|
||||||
Pool();
|
Pool();
|
||||||
Pool(const char *url);
|
Pool(const char *url);
|
||||||
@@ -59,8 +70,9 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
inline Algorithm &algorithm() { return m_algorithm; }
|
inline Algorithm &algorithm() { return m_algorithm; }
|
||||||
inline bool isNicehash() const { return m_nicehash; }
|
inline bool isDaemon() const { return m_flags.test(FLAG_DAEMON); }
|
||||||
inline bool isTLS() const { return m_tls; }
|
inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); }
|
||||||
|
inline bool isTLS() const { return m_flags.test(FLAG_TLS); }
|
||||||
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
|
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
|
||||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||||
inline const Algorithms &algorithms() const { return m_algorithms; }
|
inline const Algorithms &algorithms() const { return m_algorithms; }
|
||||||
@@ -72,14 +84,10 @@ public:
|
|||||||
inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; }
|
inline const String &user() const { return !m_user.isNull() ? m_user : kDefaultUser; }
|
||||||
inline int keepAlive() const { return m_keepAlive; }
|
inline int keepAlive() const { return m_keepAlive; }
|
||||||
inline uint16_t port() const { return m_port; }
|
inline uint16_t port() const { return m_port; }
|
||||||
inline void setFingerprint(const char *fingerprint) { m_fingerprint = fingerprint; }
|
inline uint64_t pollInterval() const { return m_pollInterval; }
|
||||||
inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); }
|
inline void setPassword(const String &password) { m_password = password; }
|
||||||
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
|
inline void setRigId(const String &rigId) { m_rigId = rigId; }
|
||||||
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
|
inline void setUser(const String &user) { m_user = user; }
|
||||||
inline void setPassword(const char *password) { m_password = password; }
|
|
||||||
inline void setRigId(const char *rigId) { m_rigId = rigId; }
|
|
||||||
inline void setTLS(bool tls) { m_tls = tls; }
|
|
||||||
inline void setUser(const char *user) { m_user = user; }
|
|
||||||
|
|
||||||
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
|
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
|
||||||
inline bool operator==(const Pool &other) const { return isEqual(other); }
|
inline bool operator==(const Pool &other) const { return isEqual(other); }
|
||||||
@@ -88,7 +96,6 @@ public:
|
|||||||
bool isEnabled() const;
|
bool isEnabled() const;
|
||||||
bool isEqual(const Pool &other) const;
|
bool isEqual(const Pool &other) const;
|
||||||
bool parse(const char *url);
|
bool parse(const char *url);
|
||||||
bool setUserpass(const char *userpass);
|
|
||||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||||
void adjust(const Algorithm &algorithm);
|
void adjust(const Algorithm &algorithm);
|
||||||
void setAlgo(const Algorithm &algorithm);
|
void setAlgo(const Algorithm &algorithm);
|
||||||
@@ -98,6 +105,9 @@ public:
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline void setKeepAlive(bool enable) { setKeepAlive(enable ? kKeepAliveTimeout : 0); }
|
||||||
|
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
|
||||||
|
|
||||||
bool parseIPv6(const char *addr);
|
bool parseIPv6(const char *addr);
|
||||||
void addVariant(Variant variant);
|
void addVariant(Variant variant);
|
||||||
void adjustVariant(const Variant variantHint);
|
void adjustVariant(const Variant variantHint);
|
||||||
@@ -105,10 +115,8 @@ private:
|
|||||||
|
|
||||||
Algorithm m_algorithm;
|
Algorithm m_algorithm;
|
||||||
Algorithms m_algorithms;
|
Algorithms m_algorithms;
|
||||||
bool m_enabled;
|
|
||||||
bool m_nicehash;
|
|
||||||
bool m_tls;
|
|
||||||
int m_keepAlive;
|
int m_keepAlive;
|
||||||
|
std::bitset<FLAG_MAX> m_flags;
|
||||||
String m_fingerprint;
|
String m_fingerprint;
|
||||||
String m_host;
|
String m_host;
|
||||||
String m_password;
|
String m_password;
|
||||||
@@ -116,6 +124,7 @@ private:
|
|||||||
String m_url;
|
String m_url;
|
||||||
String m_user;
|
String m_user;
|
||||||
uint16_t m_port;
|
uint16_t m_port;
|
||||||
|
uint64_t m_pollInterval;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
#include "base/net/stratum/Pools.h"
|
#include "base/net/stratum/Pools.h"
|
||||||
#include "base/net/stratum/strategies/FailoverStrategy.h"
|
#include "base/net/stratum/strategies/FailoverStrategy.h"
|
||||||
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
|
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
|
||||||
#include "common/log/Log.h"
|
|
||||||
#include "donate.h"
|
#include "donate.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
@@ -44,16 +44,6 @@ xmrig::Pools::Pools() :
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::Pool &xmrig::Pools::current()
|
|
||||||
{
|
|
||||||
if (m_data.empty()) {
|
|
||||||
m_data.push_back(Pool());
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_data.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Pools::isEqual(const Pools &other) const
|
bool xmrig::Pools::isEqual(const Pools &other) const
|
||||||
{
|
{
|
||||||
if (m_data.size() != other.m_data.size() || m_retries != other.m_retries || m_retryPause != other.m_retryPause) {
|
if (m_data.size() != other.m_data.size() || m_retries != other.m_retries || m_retryPause != other.m_retryPause) {
|
||||||
@@ -64,25 +54,6 @@ bool xmrig::Pools::isEqual(const Pools &other) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Pools::setUrl(const char *url)
|
|
||||||
{
|
|
||||||
if (m_data.empty() || m_data.back().isValid()) {
|
|
||||||
Pool pool(url);
|
|
||||||
|
|
||||||
if (pool.isValid()) {
|
|
||||||
m_data.push_back(std::move(pool));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
current().parse(url);
|
|
||||||
|
|
||||||
return m_data.back().isValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) const
|
xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) const
|
||||||
{
|
{
|
||||||
if (active() == 1) {
|
if (active() == 1) {
|
||||||
@@ -144,6 +115,10 @@ void xmrig::Pools::load(const rapidjson::Value &pools)
|
|||||||
{
|
{
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
|
|
||||||
|
if (!pools.IsArray()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const rapidjson::Value &value : pools.GetArray()) {
|
for (const rapidjson::Value &value : pools.GetArray()) {
|
||||||
if (!value.IsObject()) {
|
if (!value.IsObject()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -161,25 +136,12 @@ void xmrig::Pools::print() const
|
|||||||
{
|
{
|
||||||
size_t i = 1;
|
size_t i = 1;
|
||||||
for (const Pool &pool : m_data) {
|
for (const Pool &pool : m_data) {
|
||||||
if (Log::colors) {
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " variant " WHITE_BOLD("%s"),
|
||||||
const int color = pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31;
|
|
||||||
|
|
||||||
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "\x1B[1;%dm%s\x1B[0m variant " WHITE_BOLD("%s"),
|
|
||||||
i,
|
i,
|
||||||
color,
|
(pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31),
|
||||||
pool.url().data(),
|
pool.url().data(),
|
||||||
pool.algorithm().variantName()
|
pool.algorithm().variantName()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log::i()->text(" * POOL #%-7zu%s%s variant=%s %s",
|
|
||||||
i,
|
|
||||||
pool.isEnabled() ? "" : "-",
|
|
||||||
pool.url().data(),
|
|
||||||
pool.algorithm().variantName(),
|
|
||||||
pool.isTLS() ? "TLS" : ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,28 +50,16 @@ public:
|
|||||||
|
|
||||||
Pools();
|
Pools();
|
||||||
|
|
||||||
inline bool setUserpass(const char *userpass) { return current().setUserpass(userpass); }
|
|
||||||
inline const std::vector<Pool> &data() const { return m_data; }
|
inline const std::vector<Pool> &data() const { return m_data; }
|
||||||
inline int donateLevel() const { return m_donateLevel; }
|
inline int donateLevel() const { return m_donateLevel; }
|
||||||
inline int retries() const { return m_retries; }
|
inline int retries() const { return m_retries; }
|
||||||
inline int retryPause() const { return m_retryPause; }
|
inline int retryPause() const { return m_retryPause; }
|
||||||
inline ProxyDonate proxyDonate() const { return m_proxyDonate; }
|
inline ProxyDonate proxyDonate() const { return m_proxyDonate; }
|
||||||
inline void setFingerprint(const char *fingerprint) { current().setFingerprint(fingerprint); }
|
|
||||||
inline void setKeepAlive(bool enable) { current().setKeepAlive(enable); }
|
|
||||||
inline void setKeepAlive(int keepAlive) { current().setKeepAlive(keepAlive); }
|
|
||||||
inline void setNicehash(bool enable) { current().setNicehash(enable); }
|
|
||||||
inline void setPassword(const char *password) { current().setPassword(password); }
|
|
||||||
inline void setRigId(const char *rigId) { current().setRigId(rigId); }
|
|
||||||
inline void setTLS(bool enable) { current().setTLS(enable); }
|
|
||||||
inline void setUser(const char *user) { current().setUser(user); }
|
|
||||||
inline void setVariant(const char *variant) { current().algorithm().parseVariant(variant); }
|
|
||||||
inline void setVariant(int variant) { current().algorithm().parseVariant(variant); }
|
|
||||||
|
|
||||||
inline bool operator!=(const Pools &other) const { return !isEqual(other); }
|
inline bool operator!=(const Pools &other) const { return !isEqual(other); }
|
||||||
inline bool operator==(const Pools &other) const { return isEqual(other); }
|
inline bool operator==(const Pools &other) const { return isEqual(other); }
|
||||||
|
|
||||||
bool isEqual(const Pools &other) const;
|
bool isEqual(const Pools &other) const;
|
||||||
bool setUrl(const char *url);
|
|
||||||
IStrategy *createStrategy(IStrategyListener *listener) const;
|
IStrategy *createStrategy(IStrategyListener *listener) const;
|
||||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||||
size_t active() const;
|
size_t active() const;
|
||||||
@@ -84,8 +72,6 @@ public:
|
|||||||
void setRetryPause(int retryPause);
|
void setRetryPause(int retryPause);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pool ¤t();
|
|
||||||
|
|
||||||
int m_donateLevel;
|
int m_donateLevel;
|
||||||
int m_retries;
|
int m_retries;
|
||||||
int m_retryPause;
|
int m_retryPause;
|
||||||
|
|||||||
@@ -38,17 +38,17 @@ public:
|
|||||||
inline SubmitResult() :
|
inline SubmitResult() :
|
||||||
reqId(0),
|
reqId(0),
|
||||||
seq(0),
|
seq(0),
|
||||||
diff(0),
|
|
||||||
actualDiff(0),
|
actualDiff(0),
|
||||||
|
diff(0),
|
||||||
elapsed(0),
|
elapsed(0),
|
||||||
m_start(0)
|
m_start(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0) :
|
inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId = 0) :
|
||||||
reqId(reqId),
|
reqId(reqId),
|
||||||
seq(seq),
|
seq(seq),
|
||||||
diff(diff),
|
|
||||||
actualDiff(actualDiff),
|
actualDiff(actualDiff),
|
||||||
|
diff(diff),
|
||||||
elapsed(0),
|
elapsed(0),
|
||||||
m_start(Chrono::steadyMSecs())
|
m_start(Chrono::steadyMSecs())
|
||||||
{}
|
{}
|
||||||
@@ -57,8 +57,8 @@ public:
|
|||||||
|
|
||||||
int64_t reqId;
|
int64_t reqId;
|
||||||
int64_t seq;
|
int64_t seq;
|
||||||
uint32_t diff;
|
|
||||||
uint64_t actualDiff;
|
uint64_t actualDiff;
|
||||||
|
uint64_t diff;
|
||||||
uint64_t elapsed;
|
uint64_t elapsed;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -27,10 +27,10 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
#include "base/net/stratum/Client.h"
|
#include "base/net/stratum/Client.h"
|
||||||
#include "base/net/stratum/Tls.h"
|
#include "base/net/stratum/Tls.h"
|
||||||
#include "base/tools/Buffer.h"
|
#include "base/tools/Buffer.h"
|
||||||
#include "common/log/Log.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|||||||
@@ -29,6 +29,11 @@
|
|||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_HTTP
|
||||||
|
# include "base/net/stratum/DaemonClient.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
xmrig::FailoverStrategy::FailoverStrategy(const std::vector<Pool> &pools, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
xmrig::FailoverStrategy::FailoverStrategy(const std::vector<Pool> &pools, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
|
||||||
m_quiet(quiet),
|
m_quiet(quiet),
|
||||||
m_retries(retries),
|
m_retries(retries),
|
||||||
@@ -56,7 +61,7 @@ xmrig::FailoverStrategy::FailoverStrategy(int retryPause, int retries, IStrategy
|
|||||||
|
|
||||||
xmrig::FailoverStrategy::~FailoverStrategy()
|
xmrig::FailoverStrategy::~FailoverStrategy()
|
||||||
{
|
{
|
||||||
for (Client *client : m_pools) {
|
for (IClient *client : m_pools) {
|
||||||
client->deleteLater();
|
client->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +69,15 @@ xmrig::FailoverStrategy::~FailoverStrategy()
|
|||||||
|
|
||||||
void xmrig::FailoverStrategy::add(const Pool &pool)
|
void xmrig::FailoverStrategy::add(const Pool &pool)
|
||||||
{
|
{
|
||||||
Client *client = new Client(static_cast<int>(m_pools.size()), Platform::userAgent(), this);
|
const int id = static_cast<int>(m_pools.size());
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_HTTP
|
||||||
|
IClient *client = !pool.isDaemon() ? static_cast<IClient *>(new Client(id, Platform::userAgent(), this))
|
||||||
|
: static_cast<IClient *>(new DaemonClient(id, this));
|
||||||
|
# else
|
||||||
|
IClient *client = new Client(id, Platform::userAgent(), this);
|
||||||
|
# endif
|
||||||
|
|
||||||
client->setPool(pool);
|
client->setPool(pool);
|
||||||
client->setRetries(m_retries);
|
client->setRetries(m_retries);
|
||||||
client->setRetryPause(m_retryPause * 1000);
|
client->setRetryPause(m_retryPause * 1000);
|
||||||
@@ -76,7 +89,7 @@ void xmrig::FailoverStrategy::add(const Pool &pool)
|
|||||||
|
|
||||||
int64_t xmrig::FailoverStrategy::submit(const JobResult &result)
|
int64_t xmrig::FailoverStrategy::submit(const JobResult &result)
|
||||||
{
|
{
|
||||||
if (m_active == -1) {
|
if (!isActive()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +115,7 @@ void xmrig::FailoverStrategy::resume()
|
|||||||
|
|
||||||
void xmrig::FailoverStrategy::setAlgo(const xmrig::Algorithm &algo)
|
void xmrig::FailoverStrategy::setAlgo(const xmrig::Algorithm &algo)
|
||||||
{
|
{
|
||||||
for (Client *client : m_pools) {
|
for (IClient *client : m_pools) {
|
||||||
client->setAlgo(algo);
|
client->setAlgo(algo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,13 +136,13 @@ void xmrig::FailoverStrategy::stop()
|
|||||||
|
|
||||||
void xmrig::FailoverStrategy::tick(uint64_t now)
|
void xmrig::FailoverStrategy::tick(uint64_t now)
|
||||||
{
|
{
|
||||||
for (Client *client : m_pools) {
|
for (IClient *client : m_pools) {
|
||||||
client->tick(now);
|
client->tick(now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::FailoverStrategy::onClose(Client *client, int failures)
|
void xmrig::FailoverStrategy::onClose(IClient *client, int failures)
|
||||||
{
|
{
|
||||||
if (failures == -1) {
|
if (failures == -1) {
|
||||||
return;
|
return;
|
||||||
@@ -150,7 +163,7 @@ void xmrig::FailoverStrategy::onClose(Client *client, int failures)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::FailoverStrategy::onJobReceived(Client *client, const Job &job, const rapidjson::Value &)
|
void xmrig::FailoverStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &)
|
||||||
{
|
{
|
||||||
if (m_active == client->id()) {
|
if (m_active == client->id()) {
|
||||||
m_listener->onJob(this, client, job);
|
m_listener->onJob(this, client, job);
|
||||||
@@ -158,7 +171,7 @@ void xmrig::FailoverStrategy::onJobReceived(Client *client, const Job &job, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::FailoverStrategy::onLoginSuccess(Client *client)
|
void xmrig::FailoverStrategy::onLoginSuccess(IClient *client)
|
||||||
{
|
{
|
||||||
int active = m_active;
|
int active = m_active;
|
||||||
|
|
||||||
@@ -179,7 +192,7 @@ void xmrig::FailoverStrategy::onLoginSuccess(Client *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
|
void xmrig::FailoverStrategy::onResultAccepted(IClient *client, const SubmitResult &result, const char *error)
|
||||||
{
|
{
|
||||||
m_listener->onResultAccepted(this, client, result, error);
|
m_listener->onResultAccepted(this, client, result, error);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user