mirror of
https://github.com/xmrig/xmrig-proxy.git
synced 2026-02-10 03:29:17 +08:00
Compare commits
16 Commits
test-amd-b
...
feature-ht
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce0a5ac20b | ||
|
|
76e47c864f | ||
|
|
2822d65150 | ||
|
|
7fd1ac53ee | ||
|
|
d10846fde6 | ||
|
|
a32de74384 | ||
|
|
9cdaad7c74 | ||
|
|
f890145a6d | ||
|
|
8879b0119e | ||
|
|
518923879a | ||
|
|
73456ec126 | ||
|
|
441822eb0b | ||
|
|
7d5b9d0154 | ||
|
|
398646b7f4 | ||
|
|
3d6be9ef77 | ||
|
|
aae906e5d3 |
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,3 +1,14 @@
|
||||
# v2.15.1-beta
|
||||
- [#257](https://github.com/xmrig/xmrig-nvidia/pull/257) New logging subsystem, file and syslog now always without colors.
|
||||
|
||||
# v2.15.0-beta
|
||||
- [#314](https://github.com/xmrig/xmrig-proxy/issues/314) Added donate over proxy feature and changed donation model.
|
||||
- Added new options `algo-ext` and `access-password`.
|
||||
- Added real graceful exit.
|
||||
|
||||
# v2.14.1
|
||||
- [#306](https://github.com/xmrig/xmrig-proxy/issues/306) [#310](https://github.com/xmrig/xmrig-proxy/issues/310) Fixed compile issues and random crashing if verbose mode or access log was enabled.
|
||||
|
||||
# v2.14.0
|
||||
- **[#969](https://github.com/xmrig/xmrig/pull/969) Added new algorithm `cryptonight/rwz`, short alias `cn/rwz` (also known as CryptoNight ReverseWaltz), for upcoming [Graft](https://www.graft.network/) fork.**
|
||||
- **[#931](https://github.com/xmrig/xmrig/issues/931) Added new algorithm `cryptonight/zls`, short alias `cn/zls` for [Zelerius Network](https://zelerius.org) fork.**
|
||||
|
||||
@@ -14,6 +14,7 @@ include (src/base/base.cmake)
|
||||
|
||||
set(HEADERS
|
||||
"${HEADERS_BASE}"
|
||||
"${HEADERS_BASE_HTTP}"
|
||||
src/3rdparty/align.h
|
||||
src/App.h
|
||||
src/common/config/CommonConfig.h
|
||||
@@ -22,19 +23,12 @@ set(HEADERS
|
||||
src/common/crypto/Algorithm.h
|
||||
src/common/crypto/keccak.h
|
||||
src/common/interfaces/IConfig.h
|
||||
src/common/interfaces/IConfigCreator.h
|
||||
src/common/interfaces/IControllerListener.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/xmrig.h
|
||||
src/core/Config.h
|
||||
src/core/ConfigLoader_platform.h
|
||||
src/core/config/Config.h
|
||||
src/core/config/ConfigLoader_platform.h
|
||||
src/core/config/usage.h
|
||||
src/core/Controller.h
|
||||
src/core/usage.h
|
||||
src/donate.h
|
||||
src/interfaces/IEvent.h
|
||||
src/interfaces/IEventListener.h
|
||||
@@ -81,18 +75,15 @@ set(HEADERS
|
||||
|
||||
set(SOURCES
|
||||
"${SOURCES_BASE}"
|
||||
"${SOURCES_BASE_HTTP}"
|
||||
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/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/core/Config.cpp
|
||||
src/core/config/Config.cpp
|
||||
src/core/Controller.cpp
|
||||
src/log/AccessLog.cpp
|
||||
src/log/ShareLog.cpp
|
||||
@@ -227,12 +218,6 @@ endif()
|
||||
|
||||
include(cmake/OpenSSL.cmake)
|
||||
|
||||
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
|
||||
if (HAVE_SYSLOG_H)
|
||||
add_definitions(/DHAVE_SYSLOG_H)
|
||||
set(SOURCES_SYSLOG src/common/log/SysLog.h src/common/log/SysLog.cpp)
|
||||
endif()
|
||||
|
||||
if (WITH_GOOGLE_BREAKPAD)
|
||||
include_directories(/usr/local/include/breakpad)
|
||||
set(GOOGLE_BREAKPAD_LIBS breakpad_client)
|
||||
@@ -241,28 +226,21 @@ else()
|
||||
endif()
|
||||
|
||||
if (WITH_HTTPD)
|
||||
find_package(MHD)
|
||||
|
||||
if (MHD_FOUND)
|
||||
include_directories(${MHD_INCLUDE_DIRS})
|
||||
set(HTTPD_SOURCES
|
||||
src/api/Api.h
|
||||
src/api/ApiRouter.h
|
||||
src/common/api/HttpBody.h
|
||||
src/common/api/Httpd.h
|
||||
src/common/api/HttpReply.h
|
||||
src/common/api/HttpRequest.h
|
||||
src/api/Api.cpp
|
||||
src/api/ApiRouter.cpp
|
||||
src/common/api/Httpd.cpp
|
||||
src/common/api/HttpRequest.cpp
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
|
||||
endif()
|
||||
set(HTTPD_SOURCES
|
||||
src/api/Api.cpp
|
||||
src/api/Api.h
|
||||
src/api/Httpd.cpp
|
||||
src/api/Httpd.h
|
||||
src/api/interfaces/IApiRequest.h
|
||||
src/api/requests/ApiRequest.cpp
|
||||
src/api/requests/ApiRequest.h
|
||||
src/api/requests/HttpApiRequest.cpp
|
||||
src/api/requests/HttpApiRequest.h
|
||||
src/api/v1/ApiRouter.cpp
|
||||
src/api/v1/ApiRouter.h
|
||||
)
|
||||
else()
|
||||
set(HTTPD_SOURCES "")
|
||||
set(MHD_LIBRARY "")
|
||||
add_definitions(/DXMRIG_NO_HTTPD)
|
||||
add_definitions(/DXMRIG_NO_API)
|
||||
endif()
|
||||
@@ -276,4 +254,4 @@ include_directories(src/3rdparty)
|
||||
include_directories(${UV_INCLUDE_DIR})
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${GOOGLE_BREAKPAD_LIBS})
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${GOOGLE_BREAKPAD_LIBS})
|
||||
|
||||
@@ -27,12 +27,10 @@ if (WITH_TLS)
|
||||
endif()
|
||||
|
||||
add_definitions(/DXMRIG_FEATURE_TLS)
|
||||
remove_definitions(/DXMRIG_NO_TLS)
|
||||
else()
|
||||
set(TLS_SOURCES "")
|
||||
set(OPENSSL_LIBRARIES "")
|
||||
remove_definitions(/DXMRIG_FEATURE_TLS)
|
||||
add_definitions(/DXMRIG_NO_TLS)
|
||||
|
||||
set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
|
||||
endif()
|
||||
|
||||
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
|
||||
39
src/App.cpp
39
src/App.cpp
@@ -30,23 +30,18 @@
|
||||
#include "api/Api.h"
|
||||
#include "App.h"
|
||||
#include "base/io/Console.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/Signals.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/Proxy.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include "common/api/Httpd.h"
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::App::App(Process *process) :
|
||||
m_console(nullptr),
|
||||
m_httpd(nullptr),
|
||||
m_signals(nullptr)
|
||||
{
|
||||
m_controller = new Controller(process);
|
||||
@@ -65,12 +60,6 @@ xmrig::App::~App()
|
||||
delete m_signals;
|
||||
delete m_console;
|
||||
delete m_controller;
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
delete m_httpd;
|
||||
# endif
|
||||
|
||||
Log::release();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,23 +75,7 @@ int xmrig::App::exec()
|
||||
|
||||
Summary::print(m_controller);
|
||||
|
||||
# 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
|
||||
|
||||
m_controller->watch();
|
||||
m_controller->proxy()->connect();
|
||||
m_controller->start();
|
||||
|
||||
const int rc = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
uv_loop_close(uv_default_loop());
|
||||
@@ -184,13 +157,9 @@ void xmrig::App::onSignal(int signum)
|
||||
|
||||
void xmrig::App::close()
|
||||
{
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
m_httpd->stop();
|
||||
# endif
|
||||
|
||||
m_signals->stop();
|
||||
m_console->stop();
|
||||
m_controller->stop();
|
||||
|
||||
Log::release();
|
||||
Log::destroy();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "base/kernel/interfaces/ISignalListener.h"
|
||||
|
||||
|
||||
class Httpd;
|
||||
class Proxy;
|
||||
|
||||
|
||||
@@ -61,7 +60,6 @@ private:
|
||||
|
||||
Console *m_console;
|
||||
Controller *m_controller;
|
||||
Httpd *m_httpd;
|
||||
Signals *m_signals;
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
|
||||
#include "App.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
|
||||
#include "App.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/BindHost.h"
|
||||
#include "Summary.h"
|
||||
@@ -37,17 +37,13 @@
|
||||
|
||||
static void print_mode(xmrig::Controller *controller)
|
||||
{
|
||||
xmrig::Log::i()->text(controller->config()->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") MAGENTA_BOLD("%s")
|
||||
: " * %-13s%s",
|
||||
"MODE", controller->config()->modeName());
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") MAGENTA_BOLD("%s"), "MODE", controller->config()->modeName());
|
||||
}
|
||||
|
||||
|
||||
static void print_algo(xmrig::Controller *controller)
|
||||
{
|
||||
xmrig::Log::i()->text(controller->config()->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") MAGENTA_BOLD("%s")
|
||||
: " * %-13s%s",
|
||||
"ALGO", controller->config()->algorithm().name());
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") MAGENTA_BOLD("%s"), "ALGO", controller->config()->algorithm().name());
|
||||
}
|
||||
|
||||
|
||||
@@ -55,41 +51,28 @@ static void print_bind(xmrig::Controller *controller)
|
||||
{
|
||||
const xmrig::BindHosts &bind = controller->config()->bind();
|
||||
|
||||
if (controller->config()->isColors()) {
|
||||
for (size_t i = 0; i < bind.size(); ++i) {
|
||||
xmrig::Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("BIND #%-7zu") CYAN("%s%s%s:") "\x1B[1;%dm%d\x1B[0m",
|
||||
i + 1,
|
||||
bind[i].isIPv6() ? "[" : "",
|
||||
bind[i].host(),
|
||||
bind[i].isIPv6() ? "]" : "",
|
||||
bind[i].isTLS() ? 32 : 36,
|
||||
bind[i].port());
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < bind.size(); ++i) {
|
||||
xmrig::Log::i()->text(" * BIND #%-7zu%s%s%s:%d TLS=%d",
|
||||
i + 1,
|
||||
bind[i].isIPv6() ? "[" : "",
|
||||
bind[i].host(),
|
||||
bind[i].isIPv6() ? "]" : "",
|
||||
bind[i].port(),
|
||||
static_cast<int>(bind[i].isTLS()));
|
||||
}
|
||||
for (size_t i = 0; i < bind.size(); ++i) {
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("BIND #%-7zu") CYAN("%s%s%s:") "\x1B[1;%dm%d\x1B[0m",
|
||||
i + 1,
|
||||
bind[i].isIPv6() ? "[" : "",
|
||||
bind[i].host(),
|
||||
bind[i].isIPv6() ? "]" : "",
|
||||
bind[i].isTLS() ? 32 : 36,
|
||||
bind[i].port());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void print_commands(xmrig::Controller *controller)
|
||||
static void print_commands(xmrig::Controller *)
|
||||
{
|
||||
if (controller->config()->isColors()) {
|
||||
xmrig::Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
|
||||
MAGENTA_BOLD("c") WHITE_BOLD("onnections, ")
|
||||
MAGENTA_BOLD("v") WHITE_BOLD("erbose, ")
|
||||
MAGENTA_BOLD("w") WHITE_BOLD("orkers"));
|
||||
if (xmrig::Log::colors) {
|
||||
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
|
||||
MAGENTA_BOLD("c") WHITE_BOLD("onnections, ")
|
||||
MAGENTA_BOLD("v") WHITE_BOLD("erbose, ")
|
||||
MAGENTA_BOLD("w") WHITE_BOLD("orkers"));
|
||||
}
|
||||
else {
|
||||
xmrig::Log::i()->text(" * COMMANDS 'h' hashrate, 'c' connections, 'v' verbose, 'w' workers");
|
||||
xmrig::Log::print(" * COMMANDS 'h' hashrate, 'c' connections, 'v' verbose, 'w' workers");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +82,7 @@ void Summary::print(xmrig::Controller *controller)
|
||||
controller->config()->printVersions();
|
||||
print_mode(controller);
|
||||
print_algo(controller);
|
||||
controller->config()->printPools();
|
||||
controller->config()->pools().print();
|
||||
print_bind(controller);
|
||||
controller->config()->printAPI();
|
||||
print_commands(controller);
|
||||
}
|
||||
|
||||
160
src/api/Api.cpp
160
src/api/Api.cpp
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,42 +22,166 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "3rdparty/http-parser/http_parser.h"
|
||||
#include "api/Api.h"
|
||||
#include "api/ApiRouter.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "api/interfaces/IApiListener.h"
|
||||
#include "api/requests/HttpApiRequest.h"
|
||||
#include "api/v1/ApiRouter.h"
|
||||
#include "base/tools/Buffer.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(Controller *controller) :
|
||||
m_id(),
|
||||
m_workerId(),
|
||||
m_controller(controller),
|
||||
m_httpd(nullptr)
|
||||
{
|
||||
m_router = new ApiRouter(controller);
|
||||
controller->addListener(this);
|
||||
|
||||
return true;
|
||||
genId(m_controller->config()->apiId());
|
||||
|
||||
m_v1 = new ApiRouter(controller);
|
||||
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 HttpRequest &req)
|
||||
{
|
||||
if (!m_router) {
|
||||
reply.status = 500;
|
||||
HttpApiRequest request(req, m_controller->config()->http().isRestricted());
|
||||
|
||||
exec(request);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Api::start()
|
||||
{
|
||||
genWorkerId(m_controller->config()->apiWorkerId());
|
||||
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
m_httpd = new Httpd(m_controller);
|
||||
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")) {
|
||||
request.accept();
|
||||
request.reply().AddMember("id", StringRef(m_id), request.doc().GetAllocator());
|
||||
request.reply().AddMember("worker_id", StringRef(m_workerId), request.doc().GetAllocator());;
|
||||
}
|
||||
|
||||
for (IApiListener *listener : m_listeners) {
|
||||
listener->onRequest(request);
|
||||
|
||||
if (request.isDone()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
request.done(request.isNew() ? HTTP_STATUS_NOT_FOUND : HTTP_STATUS_OK);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Api::genId(const String &id)
|
||||
{
|
||||
memset(m_id, 0, sizeof(m_id));
|
||||
|
||||
if (id.size() > 0) {
|
||||
strncpy(m_id, id.data(), sizeof(m_id) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method() == xmrig::HttpRequest::Get) {
|
||||
return m_router->get(req, reply);
|
||||
uv_interface_address_t *interfaces;
|
||||
int count = 0;
|
||||
|
||||
if (uv_interface_addresses(&interfaces, &count) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_router->exec(req, reply);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
|
||||
uint8_t hash[200];
|
||||
const size_t addrSize = sizeof(interfaces[i].phys_addr);
|
||||
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
|
||||
const uint16_t port = static_cast<uint16_t>(m_controller->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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,30 +22,60 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __API_H__
|
||||
#define __API_H__
|
||||
#ifndef XMRIG_API_H
|
||||
#define XMRIG_API_H
|
||||
|
||||
|
||||
class ApiRouter;
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IControllerListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
class HttpReply;
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
|
||||
class Api
|
||||
class ApiRouter;
|
||||
class Controller;
|
||||
class Httpd;
|
||||
class HttpRequest;
|
||||
class IApiListener;
|
||||
class IApiRequest;
|
||||
class String;
|
||||
|
||||
|
||||
class Api : public IControllerListener
|
||||
{
|
||||
public:
|
||||
static bool start(xmrig::Controller *controller);
|
||||
static void release();
|
||||
Api(Controller *controller);
|
||||
~Api() override;
|
||||
|
||||
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
inline const char *id() const { return m_id; }
|
||||
inline const char *workerId() const { return m_workerId; }
|
||||
inline void addListener(IApiListener *listener) { m_listeners.push_back(listener); }
|
||||
|
||||
void request(const HttpRequest &req);
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
void onConfigChanged(Config *config, Config *previousConfig) override;
|
||||
|
||||
private:
|
||||
static ApiRouter *m_router;
|
||||
void exec(IApiRequest &request);
|
||||
void genId(const String &id);
|
||||
void genWorkerId(const String &id);
|
||||
|
||||
ApiRouter *m_v1;
|
||||
char m_id[32];
|
||||
char m_workerId[128];
|
||||
Controller *m_controller;
|
||||
Httpd *m_httpd;
|
||||
std::vector<IApiListener *> m_listeners;
|
||||
};
|
||||
|
||||
#endif /* __API_H__ */
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_API_H */
|
||||
|
||||
@@ -1,439 +0,0 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
#include <thread>
|
||||
|
||||
#if _WIN32
|
||||
# include "winsock2.h"
|
||||
#else
|
||||
# include "unistd.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "api/ApiRouter.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/crypto/keccak.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
static inline double normalize(double d)
|
||||
{
|
||||
if (!std::isnormal(d)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return std::floor(d * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
|
||||
ApiRouter::ApiRouter(xmrig::Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
setWorkerId(controller->config()->apiWorkerId());
|
||||
genId(controller->config()->apiId());
|
||||
|
||||
controller->addListener(this);
|
||||
}
|
||||
|
||||
|
||||
ApiRouter::~ApiRouter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.SetObject();
|
||||
|
||||
if (req.match("/1/workers") || req.match("/workers.json")) {
|
||||
getHashrate(doc);
|
||||
getWorkers(doc);
|
||||
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
if (req.match("/1/miners")) {
|
||||
getMiners(doc);
|
||||
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
if (req.match("/1/config")) {
|
||||
if (req.isRestricted()) {
|
||||
reply.status = 403;
|
||||
return;
|
||||
}
|
||||
|
||||
m_controller->config()->getJSON(doc);
|
||||
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
if (req.match("/1/resources") || req.match("/resources.json")) {
|
||||
getResources(doc);
|
||||
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
getIdentify(doc);
|
||||
getMiner(doc);
|
||||
getHashrate(doc);
|
||||
getResourcesSummary(doc);
|
||||
getMinersSummary(doc, req.match("/1/summary"));
|
||||
getResults(doc);
|
||||
|
||||
return finalize(reply, doc);
|
||||
}
|
||||
|
||||
void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
|
||||
{
|
||||
if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) {
|
||||
m_controller->config()->reload(req.body());
|
||||
return;
|
||||
}
|
||||
|
||||
reply.status = 404;
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
|
||||
{
|
||||
updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId());
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
rapidjson::StringBuffer buffer(nullptr, 4096);
|
||||
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
|
||||
writer.SetMaxDecimalPlaces(10);
|
||||
doc.Accept(writer);
|
||||
|
||||
reply.status = 200;
|
||||
reply.buf = strdup(buffer.GetString());
|
||||
reply.size = buffer.GetSize();
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::genId(const char *id)
|
||||
{
|
||||
memset(m_id, 0, sizeof(m_id));
|
||||
|
||||
if (id && strlen(id) > 0) {
|
||||
strncpy(m_id, id, sizeof(m_id) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
uv_interface_address_t *interfaces;
|
||||
int count = 0;
|
||||
|
||||
if (uv_interface_addresses(&interfaces, &count) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
|
||||
uint8_t hash[200];
|
||||
const size_t addrSize = sizeof(interfaces[i].phys_addr);
|
||||
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
|
||||
const uint16_t port = static_cast<uint16_t>(m_controller->config()->apiPort());
|
||||
|
||||
uint8_t *input = new uint8_t[inSize]();
|
||||
memcpy(input, &port, sizeof(uint16_t));
|
||||
memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize);
|
||||
memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
|
||||
|
||||
xmrig::keccak(input, inSize, hash);
|
||||
xmrig::Buffer::toHex(hash, 8, m_id);
|
||||
|
||||
delete [] input;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uv_free_interface_addresses(interfaces, count);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getHashrate(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
rapidjson::Value hashrate(rapidjson::kObjectType);
|
||||
rapidjson::Value total(rapidjson::kArrayType);
|
||||
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
for (size_t i = 0; i < sizeof(stats.hashrate) / sizeof(stats.hashrate[0]); i++) {
|
||||
total.PushBack(normalize(stats.hashrate[i]), allocator);
|
||||
}
|
||||
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
doc.AddMember("hashrate", hashrate, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getIdentify(rapidjson::Document &doc) const
|
||||
{
|
||||
doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator());
|
||||
doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator());
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getMiner(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
doc.AddMember("version", APP_VERSION, allocator);
|
||||
doc.AddMember("kind", APP_KIND, allocator);
|
||||
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator);
|
||||
doc.AddMember("mode", rapidjson::StringRef(m_controller->config()->modeName()), allocator);
|
||||
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
|
||||
doc.AddMember("uptime", stats.uptime(), allocator);
|
||||
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
|
||||
|
||||
if (stats.hashes && stats.donateHashes) {
|
||||
doc.AddMember("donated", normalize((double) stats.donateHashes / stats.hashes * 100.0), allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("donated", 0.0, allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getMiners(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto list = m_controller->miners();
|
||||
|
||||
Value miners(kArrayType);
|
||||
|
||||
for (const xmrig::Miner *miner : list) {
|
||||
if (miner->mapperId() == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Value value(kArrayType);
|
||||
value.PushBack(miner->id(), allocator);
|
||||
value.PushBack(StringRef(miner->ip()), allocator);
|
||||
value.PushBack(miner->tx(), allocator);
|
||||
value.PushBack(miner->rx(), allocator);
|
||||
value.PushBack(miner->state(), allocator);
|
||||
value.PushBack(miner->diff(), allocator);
|
||||
value.PushBack(miner->user().toJSON(), allocator);
|
||||
value.PushBack(miner->password().toJSON(), allocator);
|
||||
value.PushBack(miner->rigId().toJSON(), allocator);
|
||||
value.PushBack(miner->agent().toJSON(), allocator);
|
||||
|
||||
miners.PushBack(value, allocator);
|
||||
}
|
||||
|
||||
Value format(kArrayType);
|
||||
format.PushBack("id", allocator);
|
||||
format.PushBack("ip", allocator);
|
||||
format.PushBack("tx", allocator);
|
||||
format.PushBack("rx", allocator);
|
||||
format.PushBack("state", allocator);
|
||||
format.PushBack("diff", allocator);
|
||||
format.PushBack("user", allocator);
|
||||
format.PushBack("password", allocator);
|
||||
format.PushBack("rig_id", allocator);
|
||||
format.PushBack("agent", allocator);
|
||||
|
||||
doc.AddMember("format", format, allocator);
|
||||
doc.AddMember("miners", miners, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getMinersSummary(rapidjson::Document &doc, bool advanced) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
rapidjson::Value miners(rapidjson::kObjectType);
|
||||
|
||||
miners.AddMember("now", stats.miners, allocator);
|
||||
miners.AddMember("max", stats.maxMiners, allocator);
|
||||
|
||||
doc.AddMember("miners", miners, allocator);
|
||||
doc.AddMember("workers", static_cast<uint64_t>(m_controller->workers().size()), allocator);
|
||||
|
||||
if (advanced) {
|
||||
rapidjson::Value upstreams(rapidjson::kObjectType);
|
||||
|
||||
upstreams.AddMember("active", stats.upstreams.active, allocator);
|
||||
upstreams.AddMember("sleep", stats.upstreams.sleep, allocator);
|
||||
upstreams.AddMember("error", stats.upstreams.error, allocator);
|
||||
upstreams.AddMember("total", stats.upstreams.total, allocator);
|
||||
upstreams.AddMember("ratio", normalize(stats.upstreams.ratio), allocator);
|
||||
|
||||
doc.AddMember("upstreams", upstreams, allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("upstreams", stats.upstreams.active, allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ApiRouter::getResourcesSummary(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
size_t rss = 0;
|
||||
uv_resident_set_memory(&rss);
|
||||
|
||||
Value resources(kObjectType);
|
||||
Value memory(kObjectType);
|
||||
Value load_average(kArrayType);
|
||||
|
||||
memory.AddMember("total", uv_get_total_memory(), allocator);
|
||||
memory.AddMember("resident_set_memory", static_cast<uint64_t>(rss), allocator);
|
||||
|
||||
double loadavg[3] = { 1.0 };
|
||||
uv_loadavg(loadavg);
|
||||
load_average.PushBack(loadavg[0], allocator);
|
||||
load_average.PushBack(loadavg[1], allocator);
|
||||
load_average.PushBack(loadavg[2], allocator);
|
||||
|
||||
resources.AddMember("memory", memory, allocator);
|
||||
resources.AddMember("load_average", load_average, allocator);
|
||||
resources.AddMember("hardware_concurrency", std::thread::hardware_concurrency(), allocator);
|
||||
|
||||
doc.AddMember("resources", resources, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getResources(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
size_t rss = 0;
|
||||
uv_resident_set_memory(&rss);
|
||||
|
||||
doc.AddMember("total_memory", uv_get_total_memory(), allocator);
|
||||
doc.AddMember("resident_set_memory", static_cast<uint64_t>(rss), allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getResults(rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
rapidjson::Value results(rapidjson::kObjectType);
|
||||
|
||||
results.AddMember("accepted", stats.accepted, allocator);
|
||||
results.AddMember("rejected", stats.rejected, allocator);
|
||||
results.AddMember("invalid", stats.invalid, allocator);
|
||||
results.AddMember("expired", stats.expired, allocator);
|
||||
results.AddMember("avg_time", stats.avgTime(), allocator);
|
||||
results.AddMember("latency", stats.avgLatency(), allocator);
|
||||
results.AddMember("hashes_total", stats.hashes, allocator);
|
||||
results.AddMember("hashes_donate", stats.donateHashes, allocator);
|
||||
|
||||
rapidjson::Value best(rapidjson::kArrayType);
|
||||
for (size_t i = 0; i < stats.topDiff.size(); ++i) {
|
||||
best.PushBack(stats.topDiff[i], allocator);
|
||||
}
|
||||
|
||||
results.AddMember("best", best, allocator);
|
||||
|
||||
doc.AddMember("results", results, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::getWorkers(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &list = m_controller->workers();
|
||||
|
||||
Value workers(kArrayType);
|
||||
|
||||
for (const xmrig::Worker &worker : list) {
|
||||
Value array(kArrayType);
|
||||
array.PushBack(StringRef(worker.name()), allocator);
|
||||
array.PushBack(StringRef(worker.ip()), allocator);
|
||||
array.PushBack(worker.connections(), allocator);
|
||||
array.PushBack(worker.accepted(), allocator);
|
||||
array.PushBack(worker.rejected(), allocator);
|
||||
array.PushBack(worker.invalid(), allocator);
|
||||
array.PushBack(worker.hashes(), allocator);
|
||||
array.PushBack(worker.lastHash(), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(60)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(600)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(3600)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(3600 * 12)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(3600 * 24)), allocator);
|
||||
|
||||
workers.PushBack(array, allocator);
|
||||
}
|
||||
|
||||
doc.AddMember("mode", StringRef(xmrig::Workers::modeName(m_controller->config()->workersMode())), allocator);
|
||||
doc.AddMember("workers", workers, allocator);
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::setWorkerId(const char *id)
|
||||
{
|
||||
memset(m_workerId, 0, sizeof(m_workerId));
|
||||
|
||||
if (id && strlen(id) > 0) {
|
||||
strncpy(m_workerId, id, sizeof(m_workerId) - 1);
|
||||
}
|
||||
else {
|
||||
gethostname(m_workerId, sizeof(m_workerId) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApiRouter::updateWorkerId(const char *id, const char *previousId)
|
||||
{
|
||||
if (id == previousId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id != nullptr && previousId != nullptr && strcmp(id, previousId) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWorkerId(id);
|
||||
}
|
||||
164
src/api/Httpd.cpp
Normal file
164
src/api/Httpd.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/* 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/HttpRequest.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";
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::Httpd::Httpd(Controller *controller) :
|
||||
m_controller(controller),
|
||||
m_http(nullptr),
|
||||
m_server(nullptr),
|
||||
m_port(0)
|
||||
{
|
||||
controller->addListener(this);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Httpd::~Httpd()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Httpd::start()
|
||||
{
|
||||
const Http &config = m_controller->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);
|
||||
|
||||
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::onHttpRequest(const HttpRequest &req)
|
||||
{
|
||||
if (req.method == HTTP_OPTIONS) {
|
||||
return HttpApiResponse(req.id()).end();
|
||||
}
|
||||
|
||||
if (req.method > 4) {
|
||||
return HttpApiResponse(req.id(), HTTP_STATUS_METHOD_NOT_ALLOWED).end();
|
||||
}
|
||||
|
||||
const int status = auth(req);
|
||||
if (status != HTTP_STATUS_OK) {
|
||||
return HttpApiResponse(req.id(), status).end();
|
||||
}
|
||||
|
||||
if (req.method != HTTP_GET) {
|
||||
if (m_controller->config()->http().isRestricted()) {
|
||||
return HttpApiResponse(req.id(), HTTP_STATUS_FORBIDDEN).end();
|
||||
}
|
||||
|
||||
if (!req.headers.count(kContentType) || req.headers.at(kContentType) != "application/json") {
|
||||
return HttpApiResponse(req.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end();
|
||||
}
|
||||
}
|
||||
|
||||
m_controller->api()->request(req);
|
||||
}
|
||||
|
||||
|
||||
int xmrig::Httpd::auth(const HttpRequest &req) const
|
||||
{
|
||||
const Http &config = m_controller->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;
|
||||
}
|
||||
@@ -26,47 +26,45 @@
|
||||
#define XMRIG_HTTPD_H
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
struct MHD_Connection;
|
||||
struct MHD_Daemon;
|
||||
struct MHD_Response;
|
||||
|
||||
|
||||
class UploadCtx;
|
||||
#include "base/kernel/interfaces/IControllerListener.h"
|
||||
#include "base/kernel/interfaces/IHttpListener.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
|
||||
class Httpd
|
||||
class Controller;
|
||||
class HttpServer;
|
||||
class TcpServer;
|
||||
|
||||
|
||||
class Httpd : public IControllerListener, public IHttpListener
|
||||
{
|
||||
public:
|
||||
Httpd(int port, const char *accessToken, bool IPv6, bool restricted);
|
||||
~Httpd();
|
||||
Httpd(Controller *controller);
|
||||
~Httpd() override;
|
||||
|
||||
bool start();
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
void onConfigChanged(Config *config, Config *previousConfig) override;
|
||||
void onHttpRequest(const HttpRequest &req) override;
|
||||
|
||||
private:
|
||||
constexpr static const int kIdleInterval = 200;
|
||||
constexpr static const int kActiveInterval = 25;
|
||||
int auth(const HttpRequest &req) const;
|
||||
|
||||
int process(xmrig::HttpRequest &req);
|
||||
void run();
|
||||
|
||||
static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls);
|
||||
static void onTimer(uv_timer_t *handle);
|
||||
|
||||
bool m_idle;
|
||||
bool m_IPv6;
|
||||
bool m_restricted;
|
||||
const char *m_accessToken;
|
||||
const int m_port;
|
||||
MHD_Daemon *m_daemon;
|
||||
uv_timer_t *m_timer;
|
||||
Controller *m_controller;
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIGCREATOR_H__
|
||||
#define __CONFIGCREATOR_H__
|
||||
|
||||
|
||||
#include "common/interfaces/IConfigCreator.h"
|
||||
#include "core/Config.h"
|
||||
#ifndef XMRIG_IAPILISTENER_H
|
||||
#define XMRIG_IAPILISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfig;
|
||||
class IApiRequest;
|
||||
|
||||
|
||||
class ConfigCreator : public IConfigCreator
|
||||
class IApiListener
|
||||
{
|
||||
public:
|
||||
inline IConfig *create() const override
|
||||
{
|
||||
return new Config();
|
||||
}
|
||||
virtual ~IApiListener() = default;
|
||||
|
||||
virtual void onRequest(IApiRequest &request) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* 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
|
||||
@@ -5,8 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,32 +22,18 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HTTPREPLY_H__
|
||||
#define __HTTPREPLY_H__
|
||||
|
||||
#include "api/requests/ApiRequest.h"
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpReply
|
||||
xmrig::ApiRequest::ApiRequest(Source source, bool restricted) :
|
||||
m_restricted(restricted),
|
||||
m_source(source),
|
||||
m_state(STATE_NEW)
|
||||
{
|
||||
public:
|
||||
HttpReply() :
|
||||
buf(nullptr),
|
||||
status(200),
|
||||
size(0)
|
||||
{}
|
||||
|
||||
char *buf;
|
||||
int status;
|
||||
size_t size;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __HTTPREPLY_H__ */
|
||||
xmrig::ApiRequest::~ApiRequest()
|
||||
{
|
||||
}
|
||||
67
src/api/requests/ApiRequest.h
Normal file
67
src/api/requests/ApiRequest.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef XMRIG_APIREQUEST_H
|
||||
#define XMRIG_APIREQUEST_H
|
||||
|
||||
|
||||
#include "api/interfaces/IApiRequest.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ApiRequest : public IApiRequest
|
||||
{
|
||||
public:
|
||||
ApiRequest(Source source, bool restricted);
|
||||
~ApiRequest() override;
|
||||
|
||||
protected:
|
||||
inline bool isDone() const override { return m_state == STATE_DONE; }
|
||||
inline bool isNew() const override { return m_state == STATE_NEW; }
|
||||
inline bool isRestricted() const override { return m_restricted; }
|
||||
inline 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
|
||||
|
||||
|
||||
#endif // XMRIG_APIREQUEST_H
|
||||
|
||||
@@ -23,68 +23,54 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#include "api/requests/HttpApiRequest.h"
|
||||
#include "base/net/http/HttpRequest.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
|
||||
|
||||
#include "common/log/BasicLog.h"
|
||||
#include "common/log/Log.h"
|
||||
|
||||
|
||||
xmrig::BasicLog::BasicLog()
|
||||
xmrig::HttpApiRequest::HttpApiRequest(const HttpRequest &req, bool restricted) :
|
||||
ApiRequest(SOURCE_HTTP, restricted),
|
||||
m_parsed(false),
|
||||
m_req(req),
|
||||
m_res(req.id()),
|
||||
m_url(req.url.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BasicLog::message(Level level, const char* fmt, va_list args)
|
||||
const rapidjson::Value &xmrig::HttpApiRequest::json() const
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
tm stime;
|
||||
|
||||
# ifdef _WIN32
|
||||
localtime_s(&stime, &now);
|
||||
# else
|
||||
localtime_r(&now, &stime);
|
||||
# endif
|
||||
|
||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
|
||||
stime.tm_year + 1900,
|
||||
stime.tm_mon + 1,
|
||||
stime.tm_mday,
|
||||
stime.tm_hour,
|
||||
stime.tm_min,
|
||||
stime.tm_sec,
|
||||
Log::colorByLevel(level, false),
|
||||
fmt,
|
||||
Log::endl(false)
|
||||
);
|
||||
|
||||
print(args);
|
||||
return m_body;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BasicLog::text(const char* fmt, va_list args)
|
||||
xmrig::IApiRequest::Method xmrig::HttpApiRequest::method() const
|
||||
{
|
||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(false));
|
||||
|
||||
print(args);
|
||||
return static_cast<IApiRequest::Method>(m_req.method);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BasicLog::print(va_list args)
|
||||
void xmrig::HttpApiRequest::accept()
|
||||
{
|
||||
if (vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args) <= 0) {
|
||||
return;
|
||||
using namespace rapidjson;
|
||||
|
||||
ApiRequest::accept();
|
||||
|
||||
if (!m_parsed && !m_req.body.empty()) {
|
||||
m_parsed = true;
|
||||
m_body.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(m_req.body.c_str());
|
||||
|
||||
if (m_body.HasParseError()) {
|
||||
reply().AddMember("error", StringRef(GetParseError_En(m_body.GetParseError())), doc().GetAllocator());;
|
||||
}
|
||||
}
|
||||
|
||||
fputs(m_buf, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
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 HttpRequest;
|
||||
|
||||
|
||||
class HttpApiRequest : public ApiRequest
|
||||
{
|
||||
public:
|
||||
HttpApiRequest(const HttpRequest &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 HttpRequest &m_req;
|
||||
HttpApiResponse m_res;
|
||||
rapidjson::Document m_body;
|
||||
String m_url;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPAPIREQUEST_H
|
||||
|
||||
306
src/api/v1/ApiRouter.cpp
Normal file
306
src/api/v1/ApiRouter.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
#include <thread>
|
||||
|
||||
|
||||
#include "api/v1/ApiRouter.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "common/crypto/keccak.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/Miner.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "version.h"
|
||||
#include "api/interfaces/IApiRequest.h"
|
||||
|
||||
|
||||
static inline double normalize(double d)
|
||||
{
|
||||
if (!std::isnormal(d)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return std::floor(d * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
|
||||
xmrig::ApiRouter::ApiRouter(Controller *controller) :
|
||||
m_controller(controller)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::ApiRouter::~ApiRouter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::onRequest(IApiRequest &request)
|
||||
{
|
||||
if (request.method() == IApiRequest::METHOD_GET) {
|
||||
if (request.url() == "/1/summary") {
|
||||
request.accept();
|
||||
getMiner(request.reply(), request.doc());
|
||||
getHashrate(request.reply(), request.doc());
|
||||
getResourcesSummary(request.reply(), request.doc());
|
||||
getMinersSummary(request.reply(), request.doc());
|
||||
getResults(request.reply(), request.doc());
|
||||
}
|
||||
else if (request.url() == "/1/workers") {
|
||||
request.accept();
|
||||
getHashrate(request.reply(), request.doc());
|
||||
getWorkers(request.reply(), request.doc());
|
||||
}
|
||||
else if (request.url() == "/1/miners") {
|
||||
request.accept();
|
||||
getMiners(request.reply(), request.doc());
|
||||
}
|
||||
else if (request.url() == "/1/config") {
|
||||
if (request.isRestricted()) {
|
||||
return request.done(403);
|
||||
}
|
||||
|
||||
m_controller->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_controller->config()->reload(request.json())) {
|
||||
return request.done(400);
|
||||
}
|
||||
|
||||
request.done(204);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
rapidjson::Value hashrate(rapidjson::kObjectType);
|
||||
rapidjson::Value total(rapidjson::kArrayType);
|
||||
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
for (size_t i = 0; i < sizeof(stats.hashrate) / sizeof(stats.hashrate[0]); i++) {
|
||||
total.PushBack(normalize(stats.hashrate[i]), allocator);
|
||||
}
|
||||
|
||||
hashrate.AddMember("total", total, allocator);
|
||||
reply.AddMember("hashrate", hashrate, allocator);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
reply.AddMember("version", APP_VERSION, allocator);
|
||||
reply.AddMember("kind", APP_KIND, allocator);
|
||||
reply.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator);
|
||||
reply.AddMember("mode", rapidjson::StringRef(m_controller->config()->modeName()), allocator);
|
||||
reply.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
|
||||
reply.AddMember("uptime", stats.uptime(), allocator);
|
||||
reply.AddMember("donate_level", m_controller->config()->pools().donateLevel(), allocator);
|
||||
|
||||
if (stats.hashes && stats.donateHashes) {
|
||||
reply.AddMember("donated", normalize((double) stats.donateHashes / stats.hashes * 100.0), allocator);
|
||||
}
|
||||
else {
|
||||
reply.AddMember("donated", 0.0, allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getMiners(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto list = m_controller->miners();
|
||||
|
||||
Value miners(kArrayType);
|
||||
|
||||
for (const xmrig::Miner *miner : list) {
|
||||
if (miner->mapperId() == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Value value(kArrayType);
|
||||
value.PushBack(miner->id(), allocator);
|
||||
value.PushBack(StringRef(miner->ip()), allocator);
|
||||
value.PushBack(miner->tx(), allocator);
|
||||
value.PushBack(miner->rx(), allocator);
|
||||
value.PushBack(miner->state(), allocator);
|
||||
value.PushBack(miner->diff(), allocator);
|
||||
value.PushBack(miner->user().toJSON(), allocator);
|
||||
value.PushBack(miner->password().toJSON(), allocator);
|
||||
value.PushBack(miner->rigId().toJSON(), allocator);
|
||||
value.PushBack(miner->agent().toJSON(), allocator);
|
||||
|
||||
miners.PushBack(value, allocator);
|
||||
}
|
||||
|
||||
Value format(kArrayType);
|
||||
format.PushBack("id", allocator);
|
||||
format.PushBack("ip", allocator);
|
||||
format.PushBack("tx", allocator);
|
||||
format.PushBack("rx", allocator);
|
||||
format.PushBack("state", allocator);
|
||||
format.PushBack("diff", allocator);
|
||||
format.PushBack("user", allocator);
|
||||
format.PushBack("password", allocator);
|
||||
format.PushBack("rig_id", allocator);
|
||||
format.PushBack("agent", allocator);
|
||||
|
||||
reply.AddMember("format", format, allocator);
|
||||
reply.AddMember("miners", miners, allocator);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getMinersSummary(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
rapidjson::Value miners(rapidjson::kObjectType);
|
||||
|
||||
miners.AddMember("now", stats.miners, allocator);
|
||||
miners.AddMember("max", stats.maxMiners, allocator);
|
||||
|
||||
reply.AddMember("miners", miners, allocator);
|
||||
reply.AddMember("workers", static_cast<uint64_t>(m_controller->workers().size()), allocator);
|
||||
|
||||
rapidjson::Value upstreams(rapidjson::kObjectType);
|
||||
|
||||
upstreams.AddMember("active", stats.upstreams.active, allocator);
|
||||
upstreams.AddMember("sleep", stats.upstreams.sleep, allocator);
|
||||
upstreams.AddMember("error", stats.upstreams.error, allocator);
|
||||
upstreams.AddMember("total", stats.upstreams.total, allocator);
|
||||
upstreams.AddMember("ratio", normalize(stats.upstreams.ratio), allocator);
|
||||
|
||||
reply.AddMember("upstreams", upstreams, allocator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getResourcesSummary(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
size_t rss = 0;
|
||||
uv_resident_set_memory(&rss);
|
||||
|
||||
Value resources(kObjectType);
|
||||
Value memory(kObjectType);
|
||||
Value load_average(kArrayType);
|
||||
|
||||
memory.AddMember("total", uv_get_total_memory(), allocator);
|
||||
memory.AddMember("resident_set_memory", static_cast<uint64_t>(rss), allocator);
|
||||
|
||||
double loadavg[3] = { 1.0 };
|
||||
uv_loadavg(loadavg);
|
||||
load_average.PushBack(loadavg[0], allocator);
|
||||
load_average.PushBack(loadavg[1], allocator);
|
||||
load_average.PushBack(loadavg[2], allocator);
|
||||
|
||||
resources.AddMember("memory", memory, allocator);
|
||||
resources.AddMember("load_average", load_average, allocator);
|
||||
resources.AddMember("hardware_concurrency", std::thread::hardware_concurrency(), allocator);
|
||||
|
||||
reply.AddMember("resources", resources, allocator);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getResults(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &stats = m_controller->statsData();
|
||||
|
||||
rapidjson::Value results(rapidjson::kObjectType);
|
||||
|
||||
results.AddMember("accepted", stats.accepted, allocator);
|
||||
results.AddMember("rejected", stats.rejected, allocator);
|
||||
results.AddMember("invalid", stats.invalid, allocator);
|
||||
results.AddMember("expired", stats.expired, allocator);
|
||||
results.AddMember("avg_time", stats.avgTime(), allocator);
|
||||
results.AddMember("latency", stats.avgLatency(), allocator);
|
||||
results.AddMember("hashes_total", stats.hashes, allocator);
|
||||
results.AddMember("hashes_donate", stats.donateHashes, allocator);
|
||||
|
||||
rapidjson::Value best(rapidjson::kArrayType);
|
||||
for (size_t i = 0; i < stats.topDiff.size(); ++i) {
|
||||
best.PushBack(stats.topDiff[i], allocator);
|
||||
}
|
||||
|
||||
results.AddMember("best", best, allocator);
|
||||
|
||||
reply.AddMember("results", results, allocator);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ApiRouter::getWorkers(rapidjson::Value &reply, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
auto &list = m_controller->workers();
|
||||
|
||||
Value workers(kArrayType);
|
||||
|
||||
for (const Worker &worker : list) {
|
||||
Value array(kArrayType);
|
||||
array.PushBack(StringRef(worker.name()), allocator);
|
||||
array.PushBack(StringRef(worker.ip()), allocator);
|
||||
array.PushBack(worker.connections(), allocator);
|
||||
array.PushBack(worker.accepted(), allocator);
|
||||
array.PushBack(worker.rejected(), allocator);
|
||||
array.PushBack(worker.invalid(), allocator);
|
||||
array.PushBack(worker.hashes(), allocator);
|
||||
array.PushBack(worker.lastHash(), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(60)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(600)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(3600)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(3600 * 12)), allocator);
|
||||
array.PushBack(normalize(worker.hashrate(3600 * 24)), allocator);
|
||||
|
||||
workers.PushBack(array, allocator);
|
||||
}
|
||||
|
||||
reply.AddMember("mode", StringRef(Workers::modeName(m_controller->config()->workersMode())), allocator);
|
||||
reply.AddMember("workers", workers, allocator);
|
||||
}
|
||||
@@ -5,7 +5,8 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,51 +26,47 @@
|
||||
#define XMRIG_APIROUTER_H
|
||||
|
||||
|
||||
#include "common/interfaces/IControllerListener.h"
|
||||
#include "api/interfaces/IApiListener.h"
|
||||
#include "proxy/StatsData.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
class Hashrate;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
class Controller;
|
||||
class HttpReply;
|
||||
class HttpRequest;
|
||||
}
|
||||
|
||||
|
||||
class ApiRouter : public xmrig::IControllerListener
|
||||
class Controller;
|
||||
class HttpReply;
|
||||
class HttpRequest;
|
||||
|
||||
|
||||
|
||||
class ApiRouter : public xmrig::IApiListener
|
||||
{
|
||||
public:
|
||||
ApiRouter(xmrig::Controller *controller);
|
||||
ApiRouter(Controller *controller);
|
||||
~ApiRouter() override;
|
||||
|
||||
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
|
||||
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
// void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
|
||||
// void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
|
||||
|
||||
protected:
|
||||
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
|
||||
void onRequest(IApiRequest &request) override;
|
||||
|
||||
private:
|
||||
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
|
||||
void genId(const char *id);
|
||||
void getHashrate(rapidjson::Document &doc) const;
|
||||
void getIdentify(rapidjson::Document &doc) const;
|
||||
void getMiner(rapidjson::Document &doc) const;
|
||||
void getMiners(rapidjson::Document &doc) const;
|
||||
void getMinersSummary(rapidjson::Document &doc, bool advanced) const;
|
||||
void getResourcesSummary(rapidjson::Document &doc) const;
|
||||
void getResources(rapidjson::Document &doc) const;
|
||||
void getResults(rapidjson::Document &doc) const;
|
||||
void getWorkers(rapidjson::Document &doc) const;
|
||||
void setWorkerId(const char *id);
|
||||
void updateWorkerId(const char *id, const char *previousId);
|
||||
void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
void getIdentify(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
void getMiners(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
void getMinersSummary(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
void getResourcesSummary(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
void getResults(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
void getWorkers(rapidjson::Value &reply, rapidjson::Document &doc) const;
|
||||
|
||||
char m_id[32];
|
||||
char m_workerId[128];
|
||||
xmrig::Controller *m_controller;
|
||||
Controller *m_controller;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_APIROUTER_H */
|
||||
@@ -1,13 +1,18 @@
|
||||
set(HEADERS_BASE
|
||||
src/base/io/Console.h
|
||||
src/base/io/Json.h
|
||||
src/base/io/log/backends/ConsoleLog.h
|
||||
src/base/io/log/backends/FileLog.h
|
||||
src/base/io/log/Log.h
|
||||
src/base/io/Watcher.h
|
||||
src/base/kernel/Entry.h
|
||||
src/base/kernel/interfaces/IClientListener.h
|
||||
src/base/kernel/interfaces/IConfigListener.h
|
||||
src/base/kernel/interfaces/IConsoleListener.h
|
||||
src/base/kernel/interfaces/IControllerListener.h
|
||||
src/base/kernel/interfaces/IDnsListener.h
|
||||
src/base/kernel/interfaces/ILineListener.h
|
||||
src/base/kernel/interfaces/ILogBackend.h
|
||||
src/base/kernel/interfaces/ISignalListener.h
|
||||
src/base/kernel/interfaces/IStrategy.h
|
||||
src/base/kernel/interfaces/IStrategyListener.h
|
||||
@@ -17,6 +22,7 @@ set(HEADERS_BASE
|
||||
src/base/kernel/Signals.h
|
||||
src/base/net/dns/Dns.h
|
||||
src/base/net/dns/DnsRecord.h
|
||||
src/base/net/http/Http.h
|
||||
src/base/net/stratum/Client.h
|
||||
src/base/net/stratum/Job.h
|
||||
src/base/net/stratum/Pool.h
|
||||
@@ -37,12 +43,16 @@ set(HEADERS_BASE
|
||||
set(SOURCES_BASE
|
||||
src/base/io/Console.cpp
|
||||
src/base/io/Json.cpp
|
||||
src/base/io/log/backends/ConsoleLog.cpp
|
||||
src/base/io/log/backends/FileLog.cpp
|
||||
src/base/io/log/Log.cpp
|
||||
src/base/io/Watcher.cpp
|
||||
src/base/kernel/Entry.cpp
|
||||
src/base/kernel/Process.cpp
|
||||
src/base/kernel/Signals.cpp
|
||||
src/base/net/dns/Dns.cpp
|
||||
src/base/net/dns/DnsRecord.cpp
|
||||
src/base/net/http/Http.cpp
|
||||
src/base/net/stratum/Client.cpp
|
||||
src/base/net/stratum/Job.cpp
|
||||
src/base/net/stratum/Pool.cpp
|
||||
@@ -61,3 +71,46 @@ if (WIN32)
|
||||
else()
|
||||
set(SOURCES_OS src/base/io/Json_unix.cpp)
|
||||
endif()
|
||||
|
||||
|
||||
if (NOT WIN32)
|
||||
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
|
||||
if (HAVE_SYSLOG_H)
|
||||
add_definitions(/DHAVE_SYSLOG_H)
|
||||
set(SOURCES_SYSLOG src/base/io/log/backends/SysLog.h src/base/io/log/backends/SysLog.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if (WITH_HTTPD)
|
||||
set(HEADERS_BASE_HTTP
|
||||
src/3rdparty/http-parser/http_parser.h
|
||||
src/base/kernel/interfaces/IHttpListener.h
|
||||
src/base/kernel/interfaces/ITcpServerListener.h
|
||||
src/base/net/http/HttpApiResponse.h
|
||||
src/base/net/http/HttpContext.h
|
||||
src/base/net/http/HttpRequest.h
|
||||
src/base/net/http/HttpResponse.h
|
||||
src/base/net/http/HttpServer.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/HttpContext.cpp
|
||||
src/base/net/http/HttpResponse.cpp
|
||||
src/base/net/http/HttpServer.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)
|
||||
|
||||
246
src/base/io/log/Log.cpp
Normal file
246
src/base/io/log/Log.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 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 <string.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/ILogBackend.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;
|
||||
}
|
||||
|
||||
time_t now = time(nullptr);
|
||||
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] ",
|
||||
stime.tm_year + 1900,
|
||||
stime.tm_mon + 1,
|
||||
stime.tm_mday,
|
||||
stime.tm_hour,
|
||||
stime.tm_min,
|
||||
stime.tm_sec
|
||||
);
|
||||
|
||||
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 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
@@ -23,21 +24,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/tools/Handle.h"
|
||||
#include "common/log/ConsoleLog.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "base/io/log/backends/ConsoleLog.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
xmrig::ConsoleLog::ConsoleLog() :
|
||||
@@ -51,8 +43,7 @@ xmrig::ConsoleLog::ConsoleLog() :
|
||||
}
|
||||
|
||||
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
|
||||
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
@@ -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);
|
||||
tm stime;
|
||||
if (Log::colors != colors) {
|
||||
return;
|
||||
}
|
||||
|
||||
# ifdef _WIN32
|
||||
localtime_s(&stime, &now);
|
||||
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), static_cast<unsigned int>(size));
|
||||
# else
|
||||
localtime_r(&now, &stime);
|
||||
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), size);
|
||||
# endif
|
||||
|
||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
|
||||
stime.tm_year + 1900,
|
||||
stime.tm_mon + 1,
|
||||
stime.tm_mday,
|
||||
stime.tm_hour,
|
||||
stime.tm_min,
|
||||
stime.tm_sec,
|
||||
Log::colorByLevel(level, 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);
|
||||
if (!isWritable()) {
|
||||
fputs(line, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
else {
|
||||
uv_try_write(m_stream, &buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,20 +95,3 @@ bool xmrig::ConsoleLog::isWritable() const
|
||||
const uv_handle_type type = uv_guess_handle(1);
|
||||
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 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>
|
||||
*
|
||||
@@ -26,10 +27,11 @@
|
||||
#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 {
|
||||
@@ -42,16 +44,11 @@ public:
|
||||
~ConsoleLog() override;
|
||||
|
||||
protected:
|
||||
void message(Level level, const char *fmt, va_list args) override;
|
||||
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;
|
||||
|
||||
private:
|
||||
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_tty_t *m_tty;
|
||||
};
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
@@ -23,15 +24,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "common/log/FileLog.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "base/io/log/backends/FileLog.h"
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
time_t now = time(nullptr);
|
||||
tm stime;
|
||||
|
||||
# ifdef _WIN32
|
||||
localtime_s(&stime, &now);
|
||||
uv_buf_t buf = uv_buf_init(strdup(line), static_cast<unsigned int>(size));
|
||||
# else
|
||||
localtime_r(&now, &stime);
|
||||
uv_buf_t buf = uv_buf_init(strdup(line), size);
|
||||
# endif
|
||||
|
||||
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
|
||||
stime.tm_year + 1900,
|
||||
stime.tm_mon + 1,
|
||||
stime.tm_mday,
|
||||
stime.tm_hour,
|
||||
stime.tm_min,
|
||||
stime.tm_sec,
|
||||
Log::colorByLevel(level, Log::colors),
|
||||
fmt,
|
||||
Log::endl(Log::colors)
|
||||
);
|
||||
uv_fs_t *req = new uv_fs_t;
|
||||
req->data = buf.base;
|
||||
|
||||
char *buf = new char[kBufferSize];
|
||||
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);
|
||||
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, FileLog::onWrite);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,13 +65,3 @@ void xmrig::FileLog::onWrite(uv_fs_t *req)
|
||||
uv_fs_req_cleanup(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 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>
|
||||
*
|
||||
@@ -26,10 +27,10 @@
|
||||
#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 {
|
||||
@@ -40,15 +41,13 @@ class FileLog : public ILogBackend
|
||||
public:
|
||||
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:
|
||||
static void onWrite(uv_fs_t *req);
|
||||
|
||||
void write(char *data, size_t size);
|
||||
|
||||
char m_fmt[256];
|
||||
int m_file;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
@@ -26,7 +27,7 @@
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
#include "common/log/SysLog.h"
|
||||
#include "base/io/log/backends/SysLog.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 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>
|
||||
*
|
||||
@@ -26,7 +27,7 @@
|
||||
#define XMRIG_SYSLOG_H
|
||||
|
||||
|
||||
#include "common/interfaces/ILogBackend.h"
|
||||
#include "base/kernel/interfaces/ILogBackend.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
@@ -36,9 +37,10 @@ class SysLog : public ILogBackend
|
||||
{
|
||||
public:
|
||||
SysLog();
|
||||
~SysLog();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -27,19 +27,14 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include <microhttpd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/kernel/Entry.h"
|
||||
#include "base/kernel/Process.h"
|
||||
#include "core/usage.h"
|
||||
#include "core/config/usage.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
@@ -73,11 +68,7 @@ static int showVersion()
|
||||
|
||||
printf("\nlibuv/%s\n", uv_version_string());
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
printf("microhttpd/%s\n", MHD_get_version());
|
||||
# endif
|
||||
|
||||
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
{
|
||||
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
||||
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);
|
||||
|
||||
@@ -22,26 +22,27 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ICONFIGCREATOR_H
|
||||
#define XMRIG_ICONFIGCREATOR_H
|
||||
#ifndef XMRIG_IHTTPLISTENER_H
|
||||
#define XMRIG_IHTTPLISTENER_H
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfig;
|
||||
class HttpRequest;
|
||||
class HttpResponse;
|
||||
|
||||
|
||||
class IConfigCreator
|
||||
class IHttpListener
|
||||
{
|
||||
public:
|
||||
virtual ~IConfigCreator() = default;
|
||||
virtual ~IHttpListener() = default;
|
||||
|
||||
virtual IConfig *create() const = 0;
|
||||
virtual void onHttpRequest(const HttpRequest &req) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_ICONFIGCREATOR_H
|
||||
#endif // XMRIG_IHTTPLISTENER_H
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
@@ -36,24 +37,9 @@ namespace xmrig {
|
||||
class ILogBackend
|
||||
{
|
||||
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 void message(Level level, const char* fmt, va_list args) = 0;
|
||||
virtual void text(const char* fmt, va_list args) = 0;
|
||||
virtual void print(int level, const char *line, size_t offset, size_t size, bool colors) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,36 +22,32 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_BASICLOG_H
|
||||
#define XMRIG_BASICLOG_H
|
||||
#ifndef XMRIG_ITCPSERVERLISTENER_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 {
|
||||
|
||||
|
||||
class BasicLog : public ILogBackend
|
||||
class String;
|
||||
|
||||
|
||||
class ITcpServerListener
|
||||
{
|
||||
public:
|
||||
BasicLog();
|
||||
virtual ~ITcpServerListener() = default;
|
||||
|
||||
void message(Level level, const char *fmt, va_list args) override;
|
||||
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];
|
||||
virtual void onConnection(uv_stream_t *stream, uint16_t port) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* XMRIG_BASICLOG_H */
|
||||
|
||||
#endif // XMRIG_ITCPSERVERLISTENER_H
|
||||
@@ -37,7 +37,8 @@ namespace xmrig {
|
||||
xmrig::Dns::Dns(IDnsListener *listener) :
|
||||
m_hints(),
|
||||
m_listener(listener),
|
||||
m_status(0)
|
||||
m_status(0),
|
||||
m_resolver(nullptr)
|
||||
{
|
||||
m_key = m_storage.add(this);
|
||||
|
||||
@@ -54,7 +55,7 @@ xmrig::Dns::~Dns()
|
||||
{
|
||||
m_storage.release(m_key);
|
||||
|
||||
Handle::close(m_resolver);
|
||||
delete m_resolver;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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.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());
|
||||
}
|
||||
@@ -5,8 +5,9 @@
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* Copyright 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
|
||||
@@ -22,48 +23,35 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HTTPBODY_H__
|
||||
#define __HTTPBODY_H__
|
||||
|
||||
#ifndef XMRIG_HTTPAPIRESPONSE_H
|
||||
#define XMRIG_HTTPAPIRESPONSE_H
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "base/net/http/HttpResponse.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpBody
|
||||
class HttpApiResponse : public HttpResponse
|
||||
{
|
||||
public:
|
||||
inline HttpBody() :
|
||||
m_pos(0)
|
||||
{}
|
||||
HttpApiResponse(uint64_t id);
|
||||
HttpApiResponse(uint64_t id, int status);
|
||||
|
||||
inline rapidjson::Document &doc() { return m_doc; }
|
||||
|
||||
inline bool write(const char *data, size_t size)
|
||||
{
|
||||
if (size > (sizeof(m_data) - m_pos - 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(m_data + m_pos, data, size);
|
||||
|
||||
m_pos += size;
|
||||
m_data[m_pos] = '\0';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline const char *data() const { return m_data; }
|
||||
void end();
|
||||
|
||||
private:
|
||||
char m_data[32768];
|
||||
size_t m_pos;
|
||||
rapidjson::Document m_doc;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* __HTTPBODY_H__ */
|
||||
#endif // XMRIG_HTTPAPIRESPONSE_H
|
||||
|
||||
193
src/base/net/http/HttpContext.cpp
Normal file
193
src/base/net/http/HttpContext.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 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 uint64_t SEQUENCE = 0;
|
||||
std::map<uint64_t, HttpContext *> HttpContext::m_storage;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpContext::HttpContext(int parser_type, IHttpListener *listener) :
|
||||
HttpRequest(SEQUENCE++),
|
||||
listener(listener),
|
||||
connect(nullptr),
|
||||
m_wasHeaderValue(false)
|
||||
{
|
||||
m_storage[id()] = this;
|
||||
|
||||
parser = new http_parser;
|
||||
tcp = new uv_tcp_t;
|
||||
|
||||
uv_tcp_init(uv_default_loop(), tcp);
|
||||
http_parser_init(parser, static_cast<http_parser_type>(parser_type));
|
||||
|
||||
parser->data = tcp->data = this;
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpContext::~HttpContext()
|
||||
{
|
||||
delete connect;
|
||||
delete tcp;
|
||||
delete parser;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::close()
|
||||
{
|
||||
auto it = m_storage.find(id());
|
||||
if (it != m_storage.end()) {
|
||||
m_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 (m_storage.count(id) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_storage[id];
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::attach(http_parser_settings *settings)
|
||||
{
|
||||
if (settings->on_message_complete != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
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->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
|
||||
{
|
||||
const HttpContext *ctx = reinterpret_cast<const HttpContext*>(parser->data);
|
||||
ctx->listener->onHttpRequest(*ctx);
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HttpContext::closeAll()
|
||||
{
|
||||
for (auto kv : m_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::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/HttpRequest.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IHttpListener;
|
||||
|
||||
|
||||
class HttpContext : public HttpRequest
|
||||
{
|
||||
public:
|
||||
HttpContext(int parser_type, IHttpListener *listener);
|
||||
~HttpContext();
|
||||
|
||||
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(tcp); }
|
||||
inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(tcp); }
|
||||
|
||||
void close();
|
||||
|
||||
static HttpContext *get(uint64_t id);
|
||||
static void attach(http_parser_settings *settings);
|
||||
static void closeAll();
|
||||
|
||||
http_parser *parser;
|
||||
IHttpListener *listener;
|
||||
uv_connect_t *connect;
|
||||
uv_tcp_t *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);
|
||||
|
||||
void setHeader();
|
||||
|
||||
bool m_wasHeaderValue;
|
||||
std::string m_lastHeaderField;
|
||||
std::string m_lastHeaderValue;
|
||||
|
||||
static std::map<uint64_t, HttpContext *> m_storage;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif // XMRIG_HTTPCONTEXT_H
|
||||
|
||||
60
src/base/net/http/HttpRequest.h
Normal file
60
src/base/net/http/HttpRequest.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_HTTPREQUEST_H
|
||||
#define XMRIG_HTTPREQUEST_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpRequest
|
||||
{
|
||||
public:
|
||||
inline HttpRequest(uint64_t id) : method(0), m_id(id) {}
|
||||
|
||||
inline uint64_t id() const { return m_id; }
|
||||
|
||||
int method;
|
||||
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_HTTPREQUEST_H
|
||||
|
||||
108
src/base/net/http/HttpResponse.cpp
Normal file
108
src/base/net/http/HttpResponse.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/* 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/net/http/HttpContext.h"
|
||||
#include "base/net/http/HttpResponse.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kCRLF = "\r\n";
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpResponse::HttpResponse(uint64_t id) :
|
||||
m_id(id),
|
||||
m_statusCode(HTTP_STATUS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
const std::string header = ss.str();
|
||||
|
||||
uv_buf_t bufs[2];
|
||||
bufs[0].base = const_cast<char *>(header.c_str());
|
||||
|
||||
# ifdef _WIN32
|
||||
bufs[0].len = static_cast<unsigned int>(header.size());
|
||||
# else
|
||||
bufs[0].len = header.size();
|
||||
# endif
|
||||
|
||||
if (data) {
|
||||
bufs[1].base = const_cast<char *>(data);
|
||||
|
||||
# ifdef _WIN32
|
||||
bufs[1].len = static_cast<unsigned int>(size);
|
||||
# else
|
||||
bufs[0].len = size;
|
||||
# endif
|
||||
}
|
||||
|
||||
HttpContext *ctx = HttpContext::get(m_id);
|
||||
uv_try_write(ctx->stream(), bufs, data ? 2 : 1);
|
||||
|
||||
ctx->close();
|
||||
}
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
91
src/base/net/http/HttpServer.cpp
Normal file
91
src/base/net/http/HttpServer.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/* 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"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static http_parser_settings http_settings;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HttpServer::HttpServer(IHttpListener *listener) :
|
||||
m_listener(listener)
|
||||
{
|
||||
HttpContext::attach(&http_settings);
|
||||
}
|
||||
|
||||
|
||||
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 = http_parser_execute(ctx->parser, &http_settings, 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
|
||||
|
||||
@@ -30,19 +30,19 @@
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
# include "base/net/stratum/Tls.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "base/net/dns/Dns.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
@@ -107,7 +107,7 @@ xmrig::Client::~Client()
|
||||
|
||||
void xmrig::Client::connect()
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_pool.isTLS()) {
|
||||
m_tls = new Tls(this);
|
||||
}
|
||||
@@ -184,7 +184,7 @@ bool xmrig::Client::disconnect()
|
||||
|
||||
bool xmrig::Client::isTLS() const
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
return m_pool.isTLS() && m_tls;
|
||||
# else
|
||||
return false;
|
||||
@@ -194,7 +194,7 @@ bool xmrig::Client::isTLS() const
|
||||
|
||||
const char *xmrig::Client::tlsFingerprint() const
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS() && m_pool.fingerprint() == nullptr) {
|
||||
return m_tls->fingerprint();
|
||||
}
|
||||
@@ -206,7 +206,7 @@ const char *xmrig::Client::tlsFingerprint() const
|
||||
|
||||
const char *xmrig::Client::tlsVersion() const
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
return m_tls->version();
|
||||
}
|
||||
@@ -435,7 +435,7 @@ bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||
|
||||
bool xmrig::Client::send(BIO *bio)
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
uv_buf_t buf;
|
||||
buf.len = BIO_get_mem_data(bio, &buf.base);
|
||||
|
||||
@@ -543,7 +543,7 @@ int64_t xmrig::Client::send(size_t size)
|
||||
{
|
||||
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", url(), size, m_sendBuf);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
if (!m_tls->send(m_sendBuf, size)) {
|
||||
return -1;
|
||||
@@ -597,7 +597,7 @@ void xmrig::Client::connect(sockaddr *addr)
|
||||
|
||||
void xmrig::Client::handshake()
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
m_expire = Chrono::steadyMSecs() + kResponseTimeout;
|
||||
|
||||
@@ -661,7 +661,7 @@ void xmrig::Client::onClose()
|
||||
m_socket = nullptr;
|
||||
setState(UnconnectedState);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_tls) {
|
||||
delete m_tls;
|
||||
m_tls = nullptr;
|
||||
@@ -858,7 +858,7 @@ void xmrig::Client::read(ssize_t nread)
|
||||
|
||||
m_recvBuf.nread(size);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
LOG_DEBUG("[%s] TLS received (%d bytes)", url(), static_cast<int>(nread));
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
|
||||
constexpr static int kResponseTimeout = 20 * 1000;
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
constexpr static int kInputBufferSize = 1024 * 16;
|
||||
# else
|
||||
constexpr static int kInputBufferSize = 1024 * 2;
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
# include "common/log/Log.h"
|
||||
# include "base/io/log/Log.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ bool xmrig::Pool::isCompatible(const Algorithm &algorithm) const
|
||||
|
||||
bool xmrig::Pool::isEnabled() const
|
||||
{
|
||||
# ifdef XMRIG_NO_TLS
|
||||
# ifndef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
#include "base/net/stratum/strategies/FailoverStrategy.h"
|
||||
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "donate.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
@@ -161,25 +161,12 @@ void xmrig::Pools::print() const
|
||||
{
|
||||
size_t i = 1;
|
||||
for (const Pool &pool : m_data) {
|
||||
if (Log::colors) {
|
||||
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,
|
||||
color,
|
||||
pool.url().data(),
|
||||
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" : ""
|
||||
);
|
||||
}
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " variant " WHITE_BOLD("%s"),
|
||||
i,
|
||||
(pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31),
|
||||
pool.url().data(),
|
||||
pool.algorithm().variantName()
|
||||
);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
#include "base/net/stratum/Tls.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "common/log/Log.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
102
src/base/net/tools/TcpServer.cpp
Normal file
102
src/base/net/tools/TcpServer.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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/ITcpServerListener.h"
|
||||
#include "base/net/tools/TcpServer.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
static const xmrig::String kLocalHost("127.0.0.1");
|
||||
|
||||
|
||||
xmrig::TcpServer::TcpServer(const String &host, uint16_t port, ITcpServerListener *listener) :
|
||||
m_host(host.isNull() ? kLocalHost : host),
|
||||
m_version(0),
|
||||
m_listener(listener),
|
||||
m_addr(),
|
||||
m_port(port)
|
||||
{
|
||||
m_tcp = new uv_tcp_t;
|
||||
uv_tcp_init(uv_default_loop(), m_tcp);
|
||||
m_tcp->data = this;
|
||||
|
||||
uv_tcp_nodelay(m_tcp, 1);
|
||||
|
||||
if (m_host.contains(":") && uv_ip6_addr(m_host.data(), m_port, reinterpret_cast<sockaddr_in6 *>(&m_addr)) == 0) {
|
||||
m_version = 6;
|
||||
}
|
||||
else if (uv_ip4_addr(m_host.data(), m_port, reinterpret_cast<sockaddr_in *>(&m_addr)) == 0) {
|
||||
m_version = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::TcpServer::~TcpServer()
|
||||
{
|
||||
Handle::close(m_tcp);
|
||||
}
|
||||
|
||||
|
||||
int xmrig::TcpServer::bind()
|
||||
{
|
||||
if (!m_version) {
|
||||
return UV_EAI_ADDRFAMILY;
|
||||
}
|
||||
|
||||
uv_tcp_bind(m_tcp, reinterpret_cast<const sockaddr*>(&m_addr), 0);
|
||||
|
||||
const int rc = uv_listen(reinterpret_cast<uv_stream_t*>(m_tcp), 511, TcpServer::onConnection);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!m_port) {
|
||||
sockaddr_storage storage = {};
|
||||
int size = sizeof(storage);
|
||||
|
||||
uv_tcp_getsockname(m_tcp, reinterpret_cast<sockaddr*>(&storage), &size);
|
||||
|
||||
m_port = ntohs(reinterpret_cast<sockaddr_in *>(&storage)->sin_port);
|
||||
}
|
||||
|
||||
return m_port;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::TcpServer::create(uv_stream_t *stream, int status)
|
||||
{
|
||||
if (status < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_listener->onConnection(stream, m_port);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::TcpServer::onConnection(uv_stream_t *stream, int status)
|
||||
{
|
||||
static_cast<TcpServer *>(stream->data)->create(stream, status);
|
||||
}
|
||||
64
src/base/net/tools/TcpServer.h
Normal file
64
src/base/net/tools/TcpServer.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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_TCPSERVER_H
|
||||
#define XMRIG_TCPSERVER_H
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class ITcpServerListener;
|
||||
class String;
|
||||
|
||||
|
||||
class TcpServer
|
||||
{
|
||||
public:
|
||||
TcpServer(const String &host, uint16_t port, ITcpServerListener *listener);
|
||||
~TcpServer();
|
||||
|
||||
int bind();
|
||||
|
||||
private:
|
||||
void create(uv_stream_t *stream, int status);
|
||||
|
||||
static void onConnection(uv_stream_t *stream, int status);
|
||||
|
||||
const String &m_host;
|
||||
int m_version;
|
||||
ITcpServerListener *m_listener;
|
||||
sockaddr_storage m_addr;
|
||||
uint16_t m_port;
|
||||
uv_tcp_t *m_tcp;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_TCPSERVER_H */
|
||||
@@ -76,17 +76,6 @@ inline void Handle::close(uv_signal_t *handle)
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline void Handle::close(uv_getaddrinfo_t *handle)
|
||||
{
|
||||
if (handle) {
|
||||
uv_cancel(reinterpret_cast<uv_req_t *>(handle));
|
||||
|
||||
delete handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline void Handle::close(uv_fs_event_t *handle)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
#endif
|
||||
@@ -41,7 +41,7 @@ xmrig::String Platform::m_userAgent;
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
ERR_load_BIO_strings();
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "log/Log.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "Platform.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <microhttpd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/api/HttpBody.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
|
||||
|
||||
#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE
|
||||
# define MHD_HTTP_PAYLOAD_TOO_LARGE 413
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::HttpRequest::HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls) :
|
||||
m_fulfilled(true),
|
||||
m_restricted(true),
|
||||
m_uploadData(uploadData),
|
||||
m_url(url),
|
||||
m_body(static_cast<HttpBody*>(*cls)),
|
||||
m_method(Unsupported),
|
||||
m_connection(connection),
|
||||
m_uploadSize(uploadSize),
|
||||
m_cls(cls)
|
||||
{
|
||||
if (strcmp(method, MHD_HTTP_METHOD_OPTIONS) == 0) {
|
||||
m_method = Options;
|
||||
}
|
||||
else if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) {
|
||||
m_method = Get;
|
||||
}
|
||||
else if (strcmp(method, MHD_HTTP_METHOD_PUT) == 0) {
|
||||
m_method = Put;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::HttpRequest::~HttpRequest()
|
||||
{
|
||||
if (m_fulfilled) {
|
||||
delete m_body;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpRequest::match(const char *path) const
|
||||
{
|
||||
return strcmp(m_url, path) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::HttpRequest::process(const char *accessToken, bool restricted, xmrig::HttpReply &reply)
|
||||
{
|
||||
m_restricted = restricted || !accessToken;
|
||||
|
||||
if (m_body) {
|
||||
if (*m_uploadSize != 0) {
|
||||
if (!m_body->write(m_uploadData, *m_uploadSize)) {
|
||||
*m_cls = nullptr;
|
||||
m_fulfilled = true;
|
||||
reply.status = MHD_HTTP_PAYLOAD_TOO_LARGE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*m_uploadSize = 0;
|
||||
m_fulfilled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_fulfilled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
reply.status = auth(accessToken);
|
||||
if (reply.status != MHD_HTTP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_restricted && m_method != Get) {
|
||||
reply.status = MHD_HTTP_FORBIDDEN;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_method == Get) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *contentType = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Content-Type");
|
||||
if (!contentType || strcmp(contentType, "application/json") != 0) {
|
||||
reply.status = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_body = new xmrig::HttpBody();
|
||||
m_fulfilled = false;
|
||||
*m_cls = m_body;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::HttpRequest::body() const
|
||||
{
|
||||
return m_body ? m_body->data() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpRequest::end(const HttpReply &reply)
|
||||
{
|
||||
if (reply.buf) {
|
||||
return end(reply.status, MHD_create_response_from_buffer(reply.size ? reply.size : strlen(reply.buf), (void*) reply.buf, MHD_RESPMEM_MUST_FREE));
|
||||
}
|
||||
|
||||
return end(reply.status, nullptr);
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpRequest::end(int status, MHD_Response *rsp)
|
||||
{
|
||||
if (!rsp) {
|
||||
rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT);
|
||||
}
|
||||
|
||||
MHD_add_response_header(rsp, "Content-Type", "application/json");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT");
|
||||
MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization, Content-Type");
|
||||
|
||||
const int ret = MHD_queue_response(m_connection, status, rsp);
|
||||
MHD_destroy_response(rsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int xmrig::HttpRequest::auth(const char *accessToken)
|
||||
{
|
||||
if (!accessToken) {
|
||||
return MHD_HTTP_OK;
|
||||
}
|
||||
|
||||
const char *header = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Authorization");
|
||||
if (accessToken && !header) {
|
||||
return MHD_HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
||||
const size_t size = strlen(header);
|
||||
if (size < 8 || strlen(accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) {
|
||||
return MHD_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
return strncmp(accessToken, header + 7, strlen(accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HTTPREQUEST_H__
|
||||
#define __HTTPREQUEST_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
struct MHD_Connection;
|
||||
struct MHD_Response;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class HttpBody;
|
||||
class HttpReply;
|
||||
|
||||
|
||||
class HttpRequest
|
||||
{
|
||||
public:
|
||||
enum Method {
|
||||
Unsupported,
|
||||
Options,
|
||||
Get,
|
||||
Put
|
||||
};
|
||||
|
||||
HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls);
|
||||
~HttpRequest();
|
||||
|
||||
inline bool isFulfilled() const { return m_fulfilled; }
|
||||
inline bool isRestricted() const { return m_restricted; }
|
||||
inline Method method() const { return m_method; }
|
||||
|
||||
bool match(const char *path) const;
|
||||
bool process(const char *accessToken, bool restricted, xmrig::HttpReply &reply);
|
||||
const char *body() const;
|
||||
int end(const HttpReply &reply);
|
||||
int end(int status, MHD_Response *rsp);
|
||||
|
||||
private:
|
||||
int auth(const char *accessToken);
|
||||
|
||||
bool m_fulfilled;
|
||||
bool m_restricted;
|
||||
const char *m_uploadData;
|
||||
const char *m_url;
|
||||
HttpBody *m_body;
|
||||
Method m_method;
|
||||
MHD_Connection *m_connection;
|
||||
size_t *m_uploadSize;
|
||||
void **m_cls;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* __HTTPREQUEST_H__ */
|
||||
@@ -1,158 +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 <microhttpd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "api/Api.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "common/api/Httpd.h"
|
||||
#include "common/api/HttpReply.h"
|
||||
#include "common/api/HttpRequest.h"
|
||||
#include "common/log/Log.h"
|
||||
|
||||
|
||||
Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) :
|
||||
m_idle(true),
|
||||
m_IPv6(IPv6),
|
||||
m_restricted(restricted),
|
||||
m_accessToken(accessToken ? strdup(accessToken) : nullptr),
|
||||
m_port(port),
|
||||
m_daemon(nullptr)
|
||||
{
|
||||
m_timer = new uv_timer_t;
|
||||
uv_timer_init(uv_default_loop(), m_timer);
|
||||
m_timer->data = this;
|
||||
}
|
||||
|
||||
|
||||
Httpd::~Httpd()
|
||||
{
|
||||
stop();
|
||||
|
||||
if (m_daemon) {
|
||||
MHD_stop_daemon(m_daemon);
|
||||
}
|
||||
|
||||
delete m_accessToken;
|
||||
}
|
||||
|
||||
|
||||
bool Httpd::start()
|
||||
{
|
||||
if (!m_port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int flags = 0;
|
||||
# if MHD_VERSION >= 0x00093500
|
||||
if (m_IPv6 && MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
|
||||
flags |= MHD_USE_DUAL_STACK;
|
||||
}
|
||||
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
|
||||
flags |= MHD_USE_EPOLL_LINUX_ONLY;
|
||||
}
|
||||
# endif
|
||||
|
||||
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
|
||||
if (!m_daemon) {
|
||||
LOG_ERR("HTTP Daemon failed to start.");
|
||||
return false;
|
||||
}
|
||||
|
||||
# if MHD_VERSION >= 0x00093900
|
||||
uv_timer_start(m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval);
|
||||
# else
|
||||
uv_timer_start(m_timer, Httpd::onTimer, kActiveInterval, kActiveInterval);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Httpd::stop()
|
||||
{
|
||||
xmrig::Handle::close(m_timer);
|
||||
m_timer = nullptr;
|
||||
}
|
||||
|
||||
|
||||
int Httpd::process(xmrig::HttpRequest &req)
|
||||
{
|
||||
xmrig::HttpReply reply;
|
||||
if (!req.process(m_accessToken, m_restricted, reply)) {
|
||||
return req.end(reply);
|
||||
}
|
||||
|
||||
if (!req.isFulfilled()) {
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
Api::exec(req, reply);
|
||||
|
||||
return req.end(reply);
|
||||
}
|
||||
|
||||
|
||||
void Httpd::run()
|
||||
{
|
||||
MHD_run(m_daemon);
|
||||
|
||||
# if MHD_VERSION >= 0x00093900
|
||||
const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
|
||||
if (m_idle && info->num_connections) {
|
||||
uv_timer_set_repeat(m_timer, kActiveInterval);
|
||||
m_idle = false;
|
||||
}
|
||||
else if (!m_idle && !info->num_connections) {
|
||||
uv_timer_set_repeat(m_timer, kIdleInterval);
|
||||
m_idle = true;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls)
|
||||
{
|
||||
xmrig::HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls);
|
||||
|
||||
if (req.method() == xmrig::HttpRequest::Options) {
|
||||
return req.end(MHD_HTTP_OK, nullptr);
|
||||
}
|
||||
|
||||
if (req.method() == xmrig::HttpRequest::Unsupported) {
|
||||
return req.end(MHD_HTTP_METHOD_NOT_ALLOWED, nullptr);
|
||||
}
|
||||
|
||||
return static_cast<Httpd*>(cls)->process(req);
|
||||
}
|
||||
|
||||
|
||||
void Httpd::onTimer(uv_timer_t *handle)
|
||||
{
|
||||
static_cast<Httpd*>(handle->data)->run();
|
||||
}
|
||||
@@ -30,12 +30,7 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include <microhttpd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
@@ -55,9 +50,8 @@
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "common/config/CommonConfig.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "donate.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
@@ -67,47 +61,18 @@
|
||||
xmrig::CommonConfig::CommonConfig() :
|
||||
m_algorithm(CRYPTONIGHT, VARIANT_AUTO),
|
||||
m_adjusted(false),
|
||||
m_apiIPv6(false),
|
||||
m_apiRestricted(true),
|
||||
m_autoSave(true),
|
||||
m_background(false),
|
||||
m_dryRun(false),
|
||||
m_syslog(false),
|
||||
m_upgrade(false),
|
||||
m_watch(true),
|
||||
m_apiPort(0),
|
||||
m_donateLevel(kDefaultDonateLevel),
|
||||
m_printTime(60),
|
||||
m_state(NoneState)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CommonConfig::isColors() const
|
||||
{
|
||||
return Log::colors;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CommonConfig::printAPI()
|
||||
{
|
||||
# ifndef XMRIG_NO_API
|
||||
if (apiPort() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN("%s:") CYAN_BOLD("%d")
|
||||
: " * %-13s%s:%d",
|
||||
"API BIND", isApiIPv6() ? "[::]" : "0.0.0.0", apiPort());
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CommonConfig::printPools()
|
||||
{
|
||||
m_pools.print();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CommonConfig::printVersions()
|
||||
{
|
||||
char buf[256] = { 0 };
|
||||
@@ -120,9 +85,7 @@ void xmrig::CommonConfig::printVersions()
|
||||
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
|
||||
# endif
|
||||
|
||||
Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s")
|
||||
: " * %-13s%s/%s %s",
|
||||
"ABOUT", APP_NAME, APP_VERSION, buf);
|
||||
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
|
||||
@@ -143,25 +106,19 @@ void xmrig::CommonConfig::printVersions()
|
||||
# else
|
||||
memset(buf, 0, 16);
|
||||
|
||||
# if !defined(XMRIG_NO_HTTPD) || !defined(XMRIG_NO_TLS)
|
||||
# if defined(XMRIG_FEATURE_HTTP) || defined(XMRIG_FEATURE_TLS)
|
||||
int length = 0;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
|
||||
{
|
||||
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
|
||||
length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef XMRIG_NO_HTTPD
|
||||
length += snprintf(buf + length, (sizeof buf) - length, "microhttpd/%s ", MHD_get_version());
|
||||
# endif
|
||||
|
||||
Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s")
|
||||
: " * %-13slibuv/%s %s",
|
||||
"LIBS", uv_version_string(), buf);
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -242,12 +199,23 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
|
||||
m_watch = enable;
|
||||
break;
|
||||
|
||||
case ApiIPv6Key: /* ipv6 */
|
||||
m_apiIPv6 = enable;
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case ApiIPv6Key: /* --api-ipv6 */
|
||||
break;
|
||||
|
||||
case ApiRestrictedKey: /* restricted */
|
||||
m_apiRestricted = enable;
|
||||
case ApiRestrictedKey: /* --api-no-restricted */
|
||||
fputs("option \"--api-no-restricted\" deprecated, use \"--http-no-restricted\" instead.\n", stderr);
|
||||
fflush(stdout);
|
||||
m_http.setRestricted(enable);
|
||||
break;
|
||||
# endif
|
||||
|
||||
case HttpRestrictedKey: /* --http-no-restricted */
|
||||
m_http.setRestricted(enable);
|
||||
break;
|
||||
|
||||
case HttpEnabledKey: /* --http-enabled */
|
||||
m_http.setEnabled(enable);
|
||||
break;
|
||||
|
||||
case DryRunKey: /* --dry-run */
|
||||
@@ -303,8 +271,20 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
|
||||
m_logFile = arg;
|
||||
break;
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case ApiAccessTokenKey: /* --api-access-token */
|
||||
m_apiToken = arg;
|
||||
fputs("option \"--api-access-token\" deprecated, use \"--http-access-token\" instead.\n", stderr);
|
||||
fflush(stdout);
|
||||
m_http.setToken(arg);
|
||||
break;
|
||||
# endif
|
||||
|
||||
case HttpAccessTokenKey: /* --http-access-token */
|
||||
m_http.setToken(arg);
|
||||
break;
|
||||
|
||||
case HttpHostKey: /* --http-host */
|
||||
m_http.setHost(arg);
|
||||
break;
|
||||
|
||||
case ApiWorkerIdKey: /* --api-worker-id */
|
||||
@@ -321,32 +301,33 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
|
||||
|
||||
case RetriesKey: /* --retries */
|
||||
case RetryPauseKey: /* --retry-pause */
|
||||
case ApiPort: /* --api-port */
|
||||
case PrintTimeKey: /* --print-time */
|
||||
return parseUint64(key, strtol(arg, nullptr, 10));
|
||||
case HttpPort: /* --http-port */
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case ApiPort: /* --api-port */
|
||||
# endif
|
||||
return parseUint64(key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
|
||||
case BackgroundKey: /* --background */
|
||||
case SyslogKey: /* --syslog */
|
||||
case KeepAliveKey: /* --keepalive */
|
||||
case NicehashKey: /* --nicehash */
|
||||
case TlsKey: /* --tls */
|
||||
case ApiIPv6Key: /* --api-ipv6 */
|
||||
case DryRunKey: /* --dry-run */
|
||||
case BackgroundKey: /* --background */
|
||||
case SyslogKey: /* --syslog */
|
||||
case KeepAliveKey: /* --keepalive */
|
||||
case NicehashKey: /* --nicehash */
|
||||
case TlsKey: /* --tls */
|
||||
case DryRunKey: /* --dry-run */
|
||||
case HttpEnabledKey: /* --http-enabled */
|
||||
return parseBoolean(key, true);
|
||||
|
||||
case ColorKey: /* --no-color */
|
||||
case WatchKey: /* --no-watch */
|
||||
case ColorKey: /* --no-color */
|
||||
case WatchKey: /* --no-watch */
|
||||
case HttpRestrictedKey: /* --http-no-restricted */
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case ApiRestrictedKey: /* --api-no-restricted */
|
||||
case ApiIPv6Key: /* --api-ipv6 */
|
||||
# endif
|
||||
return parseBoolean(key, false);
|
||||
|
||||
case DonateLevelKey: /* --donate-level */
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
if (strncmp(arg, "minemonero.pro", 14) == 0) {
|
||||
m_donateLevel = 0;
|
||||
return true;
|
||||
}
|
||||
# endif
|
||||
return parseUint64(key, strtol(arg, nullptr, 10));
|
||||
return parseUint64(key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -362,12 +343,25 @@ bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg)
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CommonConfig::parseJSON(const rapidjson::Document &doc)
|
||||
void xmrig::CommonConfig::parseJSON(const rapidjson::Value &json)
|
||||
{
|
||||
const rapidjson::Value &pools = doc["pools"];
|
||||
const rapidjson::Value &pools = json["pools"];
|
||||
if (pools.IsArray()) {
|
||||
m_pools.load(pools);
|
||||
}
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
const rapidjson::Value &api = json["api"];
|
||||
if (api.IsObject() && api.HasMember("port")) {
|
||||
m_upgrade = true;
|
||||
m_http.load(api);
|
||||
}
|
||||
else {
|
||||
m_http.load(json["http"]);
|
||||
}
|
||||
# else
|
||||
m_http.load(doc["http"]);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
@@ -397,15 +391,23 @@ bool xmrig::CommonConfig::parseInt(int key, int arg)
|
||||
break;
|
||||
|
||||
case DonateLevelKey: /* --donate-level */
|
||||
if (arg >= kMinimumDonateLevel && arg <= 99) {
|
||||
m_donateLevel = arg;
|
||||
}
|
||||
m_pools.setDonateLevel(arg);
|
||||
break;
|
||||
|
||||
case ProxyDonateKey: /* --donate-over-proxy */
|
||||
m_pools.setProxyDonate(arg);
|
||||
break;
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
case ApiPort: /* --api-port */
|
||||
if (arg > 0 && arg <= 65536) {
|
||||
m_apiPort = arg;
|
||||
}
|
||||
fputs("option \"--api-port\" deprecated, use \"--http-port\" instead.\n", stderr);
|
||||
fflush(stdout);
|
||||
m_http.setPort(arg);
|
||||
break;
|
||||
# endif
|
||||
|
||||
case HttpPort: /* --http-port */
|
||||
m_http.setPort(arg);
|
||||
break;
|
||||
|
||||
case PrintTimeKey: /* --print-time */
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#define XMRIG_COMMONCONFIG_H
|
||||
|
||||
|
||||
#include "base/net/http/Http.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
#include "base/tools/String.h"
|
||||
#include "common/interfaces/IConfig.h"
|
||||
#include "common/xmrig.h"
|
||||
|
||||
@@ -40,20 +40,16 @@ class CommonConfig : public IConfig
|
||||
public:
|
||||
CommonConfig();
|
||||
|
||||
inline bool isApiIPv6() const { return m_apiIPv6; }
|
||||
inline bool isApiRestricted() const { return m_apiRestricted; }
|
||||
inline bool isAutoSave() const { return m_autoSave; }
|
||||
inline bool isBackground() const { return m_background; }
|
||||
inline bool isDryRun() const { return m_dryRun; }
|
||||
inline bool isSyslog() const { return m_syslog; }
|
||||
inline const char *apiId() const { return m_apiId.data(); }
|
||||
inline const char *apiToken() const { return m_apiToken.data(); }
|
||||
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
|
||||
inline const String &apiId() const { return m_apiId; }
|
||||
inline const String &apiWorkerId() const { return m_apiWorkerId; }
|
||||
inline const char *logFile() const { return m_logFile.data(); }
|
||||
inline const char *userAgent() const { return m_userAgent.data(); }
|
||||
inline const Http &http() const { return m_http; }
|
||||
inline const Pools &pools() const { return m_pools; }
|
||||
inline int apiPort() const { return m_apiPort; }
|
||||
inline int donateLevel() const { return m_donateLevel; }
|
||||
inline int printTime() const { return m_printTime; }
|
||||
|
||||
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
|
||||
@@ -62,9 +58,6 @@ public:
|
||||
|
||||
bool save() override;
|
||||
|
||||
bool isColors() const;
|
||||
void printAPI();
|
||||
void printPools();
|
||||
void printVersions();
|
||||
|
||||
protected:
|
||||
@@ -78,25 +71,22 @@ protected:
|
||||
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 parseJSON(const rapidjson::Value &json) override;
|
||||
void setFileName(const char *fileName) override;
|
||||
|
||||
Algorithm m_algorithm;
|
||||
bool m_adjusted;
|
||||
bool m_apiIPv6;
|
||||
bool m_apiRestricted;
|
||||
bool m_autoSave;
|
||||
bool m_background;
|
||||
bool m_dryRun;
|
||||
bool m_syslog;
|
||||
bool m_upgrade;
|
||||
bool m_watch;
|
||||
int m_apiPort;
|
||||
int m_donateLevel;
|
||||
Http m_http;
|
||||
int m_printTime;
|
||||
Pools m_pools;
|
||||
State m_state;
|
||||
String m_apiId;
|
||||
String m_apiToken;
|
||||
String m_apiWorkerId;
|
||||
String m_fileName;
|
||||
String m_logFile;
|
||||
|
||||
@@ -29,16 +29,6 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_HTTPD
|
||||
# include <microhttpd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
# include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/kernel/interfaces/IConfigListener.h"
|
||||
#include "base/kernel/Process.h"
|
||||
@@ -46,21 +36,24 @@
|
||||
#include "common/config/ConfigWatcher.h"
|
||||
#include "common/interfaces/IConfig.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "core/ConfigLoader_platform.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/config/ConfigLoader_platform.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/error/en.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||
# include "core/ConfigLoader_default.h"
|
||||
# include "core/config/ConfigLoader_default.h"
|
||||
#endif
|
||||
|
||||
|
||||
xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr;
|
||||
xmrig::IConfigCreator *xmrig::ConfigLoader::m_creator = nullptr;
|
||||
xmrig::IConfigListener *xmrig::ConfigLoader::m_listener = nullptr;
|
||||
namespace xmrig {
|
||||
|
||||
ConfigWatcher *ConfigLoader::m_watcher = nullptr;
|
||||
IConfigListener *ConfigLoader::m_listener = nullptr;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
@@ -95,28 +88,28 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const char *json)
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Document &doc)
|
||||
bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Value &json)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
|
||||
parseJSON(config, &config_options[i], doc);
|
||||
parseJSON(config, &config_options[i], json);
|
||||
}
|
||||
|
||||
const rapidjson::Value &api = doc["api"];
|
||||
const rapidjson::Value &api = json["api"];
|
||||
if (api.IsObject()) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) {
|
||||
parseJSON(config, &api_options[i], api);
|
||||
}
|
||||
}
|
||||
|
||||
config->parseJSON(doc);
|
||||
config->parseJSON(json);
|
||||
|
||||
return config->finalize();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const char *json)
|
||||
bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const rapidjson::Value &json)
|
||||
{
|
||||
xmrig::IConfig *config = m_creator->create();
|
||||
IConfig *config = Config::create();
|
||||
if (!loadFromJSON(config, json)) {
|
||||
delete config;
|
||||
|
||||
@@ -145,17 +138,16 @@ bool xmrig::ConfigLoader::watch(IConfig *config)
|
||||
|
||||
assert(m_watcher == nullptr);
|
||||
|
||||
m_watcher = new xmrig::ConfigWatcher(config->fileName(), m_creator, m_listener);
|
||||
m_watcher = new ConfigWatcher(config->fileName(), m_listener);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
xmrig::IConfig *xmrig::ConfigLoader::load(Process *process, IConfigCreator *creator, IConfigListener *listener)
|
||||
xmrig::IConfig *xmrig::ConfigLoader::load(Process *process, IConfigListener *listener)
|
||||
{
|
||||
m_creator = creator;
|
||||
m_listener = listener;
|
||||
|
||||
xmrig::IConfig *config = m_creator->create();
|
||||
IConfig *config = Config::create();
|
||||
int key;
|
||||
int argc = process->arguments().argc();
|
||||
char **argv = process->arguments().argv();
|
||||
@@ -181,7 +173,7 @@ xmrig::IConfig *xmrig::ConfigLoader::load(Process *process, IConfigCreator *crea
|
||||
if (!config->finalize()) {
|
||||
delete config;
|
||||
|
||||
config = m_creator->create();
|
||||
config = Config::create();
|
||||
loadFromFile(config, process->location(Process::ExeLocation, "config.json"));
|
||||
}
|
||||
|
||||
@@ -189,7 +181,7 @@ xmrig::IConfig *xmrig::ConfigLoader::load(Process *process, IConfigCreator *crea
|
||||
if (!config->finalize()) {
|
||||
delete config;
|
||||
|
||||
config = m_creator->create();
|
||||
config = Config::create();
|
||||
loadFromJSON(config, default_config);
|
||||
}
|
||||
# endif
|
||||
@@ -213,10 +205,8 @@ xmrig::IConfig *xmrig::ConfigLoader::load(Process *process, IConfigCreator *crea
|
||||
void xmrig::ConfigLoader::release()
|
||||
{
|
||||
delete m_watcher;
|
||||
delete m_creator;
|
||||
|
||||
m_watcher = nullptr;
|
||||
m_creator = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +229,7 @@ bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc
|
||||
|
||||
bool xmrig::ConfigLoader::parseArg(xmrig::IConfig *config, int key, const char *arg)
|
||||
{
|
||||
if (key == xmrig::IConfig::ConfigKey) {
|
||||
if (key == IConfig::ConfigKey) {
|
||||
return loadFromFile(config, arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace xmrig {
|
||||
|
||||
|
||||
class ConfigWatcher;
|
||||
class IConfigCreator;
|
||||
class IConfigListener;
|
||||
class IConfig;
|
||||
class Process;
|
||||
@@ -50,10 +49,10 @@ class ConfigLoader
|
||||
public:
|
||||
static bool loadFromFile(IConfig *config, const char *fileName);
|
||||
static bool loadFromJSON(IConfig *config, const char *json);
|
||||
static bool loadFromJSON(IConfig *config, const rapidjson::Document &doc);
|
||||
static bool reload(IConfig *oldConfig, const char *json);
|
||||
static bool loadFromJSON(IConfig *config, const rapidjson::Value &json);
|
||||
static bool reload(IConfig *oldConfig, const rapidjson::Value &json);
|
||||
static bool watch(IConfig *config);
|
||||
static IConfig *load(Process *process, IConfigCreator *creator, IConfigListener *listener);
|
||||
static IConfig *load(Process *process, IConfigListener *listener);
|
||||
static void release();
|
||||
|
||||
private:
|
||||
@@ -62,11 +61,11 @@ private:
|
||||
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
|
||||
|
||||
static ConfigWatcher *m_watcher;
|
||||
static IConfigCreator *m_creator;
|
||||
static IConfigListener *m_listener;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CONFIGLOADER_H */
|
||||
|
||||
@@ -23,16 +23,15 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/Watcher.h"
|
||||
#include "base/kernel/interfaces/IConfigListener.h"
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/config/ConfigWatcher.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "core/config/Config.h"
|
||||
|
||||
|
||||
xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigCreator *creator, IConfigListener *listener) :
|
||||
m_creator(creator),
|
||||
xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigListener *listener) :
|
||||
m_listener(listener)
|
||||
{
|
||||
m_watcher = new Watcher(path, this);
|
||||
@@ -50,7 +49,7 @@ void xmrig::ConfigWatcher::onFileChanged(const String &fileName)
|
||||
{
|
||||
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
|
||||
|
||||
IConfig *config = m_creator->create();
|
||||
IConfig *config = Config::create();
|
||||
ConfigLoader::loadFromFile(config, fileName);
|
||||
|
||||
if (!config->finalize()) {
|
||||
|
||||
@@ -37,7 +37,6 @@ struct option;
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IConfigCreator;
|
||||
class IConfigListener;
|
||||
class Watcher;
|
||||
|
||||
@@ -45,14 +44,13 @@ class Watcher;
|
||||
class ConfigWatcher : public IWatcherListener
|
||||
{
|
||||
public:
|
||||
ConfigWatcher(const String &path, IConfigCreator *creator, IConfigListener *listener);
|
||||
ConfigWatcher(const String &path, IConfigListener *listener);
|
||||
~ConfigWatcher() override;
|
||||
|
||||
protected:
|
||||
void onFileChanged(const String &fileName) override;
|
||||
|
||||
private:
|
||||
IConfigCreator *m_creator;
|
||||
IConfigListener *m_listener;
|
||||
Watcher *m_watcher;
|
||||
};
|
||||
|
||||
@@ -41,93 +41,102 @@ class IConfig
|
||||
public:
|
||||
enum Keys {
|
||||
// common
|
||||
AlgorithmKey = 'a',
|
||||
ApiAccessTokenKey = 4001,
|
||||
ApiIPv6Key = 4003,
|
||||
ApiPort = 4000,
|
||||
ApiRestrictedKey = 4004,
|
||||
ApiWorkerIdKey = 4002,
|
||||
ApiIdKey = 4005,
|
||||
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,
|
||||
WatchKey = 1105,
|
||||
TlsKey = 1013,
|
||||
FingerprintKey = 1014,
|
||||
AutoSaveKey = 1016,
|
||||
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,
|
||||
WatchKey = 1105,
|
||||
TlsKey = 1013,
|
||||
FingerprintKey = 1014,
|
||||
AutoSaveKey = 1016,
|
||||
ProxyDonateKey = 1017,
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
ApiPort = 4000,
|
||||
ApiAccessTokenKey = 4001,
|
||||
ApiIPv6Key = 4003,
|
||||
ApiRestrictedKey = 4004,
|
||||
# endif
|
||||
|
||||
// xmrig common
|
||||
CPUPriorityKey = 1021,
|
||||
NicehashKey = 1006,
|
||||
PrintTimeKey = 1007,
|
||||
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,
|
||||
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,
|
||||
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',
|
||||
CoinKey = 1104,
|
||||
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,
|
||||
AccessLogFileKey = 'A',
|
||||
BindKey = 'b',
|
||||
CoinKey = 1104,
|
||||
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,
|
||||
CudaMaxThreadsKey = 1200,
|
||||
CudaBFactorKey = 1201,
|
||||
CudaBSleepKey = 1202,
|
||||
CudaDevicesKey = 1203,
|
||||
CudaLaunchKey = 1204,
|
||||
CudaAffinityKey = 1205,
|
||||
CudaMaxUsageKey = 1206,
|
||||
};
|
||||
|
||||
virtual ~IConfig() = default;
|
||||
@@ -141,7 +150,7 @@ public:
|
||||
virtual const Algorithm &algorithm() const = 0;
|
||||
virtual const String &fileName() const = 0;
|
||||
virtual void getJSON(rapidjson::Document &doc) const = 0;
|
||||
virtual void parseJSON(const rapidjson::Document &doc) = 0;
|
||||
virtual void parseJSON(const rapidjson::Value &json) = 0;
|
||||
virtual void setFileName(const char *fileName) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,134 +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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "common/interfaces/ILogBackend.h"
|
||||
#include "common/log/BasicLog.h"
|
||||
#include "common/log/Log.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
Log *Log::m_self = nullptr;
|
||||
bool Log::colors = true;
|
||||
|
||||
|
||||
static const char *color[5] = {
|
||||
"\x1B[0;31m", /* ERR */
|
||||
"\x1B[0;33m", /* WARNING */
|
||||
"\x1B[1;37m", /* NOTICE */
|
||||
"", /* INFO */
|
||||
# ifdef WIN32
|
||||
"\x1B[1;30m" /* DEBUG */
|
||||
# else
|
||||
"\x1B[90m" /* DEBUG */
|
||||
# endif
|
||||
};
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
void xmrig::Log::message(ILogBackend::Level level, const char* fmt, ...)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
|
||||
va_list args;
|
||||
va_list copy;
|
||||
va_start(args, fmt);
|
||||
|
||||
for (ILogBackend *backend : m_backends) {
|
||||
va_copy(copy, args);
|
||||
backend->message(level, fmt, copy);
|
||||
va_end(copy);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Log::text(const char* fmt, ...)
|
||||
{
|
||||
uv_mutex_lock(&m_mutex);
|
||||
|
||||
va_list args;
|
||||
va_list copy;
|
||||
va_start(args, fmt);
|
||||
|
||||
for (ILogBackend *backend : m_backends) {
|
||||
va_copy(copy, args);
|
||||
backend->text(fmt, copy);
|
||||
va_end(copy);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
uv_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Log::colorByLevel(ILogBackend::Level level, bool isColors)
|
||||
{
|
||||
if (!isColors) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return color[level];
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Log::endl(bool isColors)
|
||||
{
|
||||
# ifdef _WIN32
|
||||
return isColors ? "\x1B[0m\r\n" : "\r\n";
|
||||
# else
|
||||
return isColors ? "\x1B[0m\n" : "\n";
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Log::defaultInit()
|
||||
{
|
||||
m_self = new Log();
|
||||
|
||||
add(new BasicLog());
|
||||
}
|
||||
|
||||
|
||||
xmrig::Log::~Log()
|
||||
{
|
||||
m_self = nullptr;
|
||||
|
||||
for (auto backend : m_backends) {
|
||||
delete backend;
|
||||
}
|
||||
}
|
||||
@@ -1,111 +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_LOG_H
|
||||
#define XMRIG_LOG_H
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "common/interfaces/ILogBackend.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
static inline Log* i() { if (!m_self) { defaultInit(); } return m_self; }
|
||||
static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); }
|
||||
static inline void init() { if (!m_self) { new Log(); } }
|
||||
static inline void release() { delete m_self; }
|
||||
|
||||
void message(ILogBackend::Level level, const char* fmt, ...);
|
||||
void text(const char* fmt, ...);
|
||||
|
||||
static const char *colorByLevel(ILogBackend::Level level, bool isColors = true);
|
||||
static const char *endl(bool isColors = true);
|
||||
static void defaultInit();
|
||||
|
||||
static bool colors;
|
||||
|
||||
private:
|
||||
inline Log() {
|
||||
assert(m_self == nullptr);
|
||||
|
||||
uv_mutex_init(&m_mutex);
|
||||
|
||||
m_self = this;
|
||||
}
|
||||
|
||||
~Log();
|
||||
|
||||
static Log *m_self;
|
||||
std::vector<ILogBackend*> m_backends;
|
||||
uv_mutex_t m_mutex;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m"
|
||||
#define RED(x) "\x1B[0;31m" x "\x1B[0m"
|
||||
#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m"
|
||||
#define GREEN(x) "\x1B[0;32m" x "\x1B[0m"
|
||||
#define YELLOW(x) "\x1B[0;33m" x "\x1B[0m"
|
||||
#define YELLOW_BOLD(x) "\x1B[1;33m" x "\x1B[0m"
|
||||
#define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m"
|
||||
#define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m"
|
||||
#define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m"
|
||||
#define CYAN(x) "\x1B[0;36m" x "\x1B[0m"
|
||||
#define WHITE_BOLD(x) "\x1B[1;37m" x "\x1B[0m"
|
||||
#define WHITE(x) "\x1B[0;37m" x "\x1B[0m"
|
||||
#define GRAY(x) "\x1B[1;30m" x "\x1B[0m"
|
||||
|
||||
|
||||
#define LOG_ERR(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::ERR, x, ##__VA_ARGS__)
|
||||
#define LOG_WARN(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::WARNING, x, ##__VA_ARGS__)
|
||||
#define LOG_NOTICE(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::NOTICE, x, ##__VA_ARGS__)
|
||||
#define LOG_INFO(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::INFO, x, ##__VA_ARGS__)
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
# define LOG_DEBUG(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::DEBUG, x, ##__VA_ARGS__)
|
||||
#else
|
||||
# define LOG_DEBUG(x, ...)
|
||||
#endif
|
||||
|
||||
#if defined(APP_DEBUG) || defined(APP_DEVEL)
|
||||
# define LOG_DEBUG_ERR(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::ERR, x, ##__VA_ARGS__)
|
||||
# define LOG_DEBUG_WARN(x, ...) xmrig::Log::i()->message(xmrig::ILogBackend::WARNING, x, ##__VA_ARGS__)
|
||||
#else
|
||||
# define LOG_DEBUG_ERR(x, ...)
|
||||
# define LOG_DEBUG_WARN(x, ...)
|
||||
#endif
|
||||
|
||||
#endif /* XMRIG_LOG_H */
|
||||
@@ -4,8 +4,9 @@
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2016-2018 XMRig <support@xmrig.com>
|
||||
*
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,19 +23,27 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "base/io/log/backends/ConsoleLog.h"
|
||||
#include "base/io/log/backends/FileLog.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/IControllerListener.h"
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/interfaces/IControllerListener.h"
|
||||
#include "common/log/ConsoleLog.h"
|
||||
#include "common/log/FileLog.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/Proxy.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include "common/log/SysLog.h"
|
||||
# include "base/io/log/backends/SysLog.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
# include "api/Api.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -50,11 +59,15 @@ public:
|
||||
|
||||
inline ~ControllerPrivate()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
delete api;
|
||||
# endif
|
||||
|
||||
delete proxy;
|
||||
delete config;
|
||||
}
|
||||
|
||||
|
||||
Api *api;
|
||||
Process *process;
|
||||
Proxy *proxy;
|
||||
std::vector<IControllerListener *> listeners;
|
||||
@@ -74,8 +87,18 @@ xmrig::Controller::~Controller()
|
||||
}
|
||||
|
||||
|
||||
xmrig::Api *xmrig::Controller::api() const
|
||||
{
|
||||
assert(d_ptr->api != nullptr);
|
||||
|
||||
return d_ptr->api;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Config *xmrig::Controller::config() const
|
||||
{
|
||||
assert(d_ptr->config != nullptr);
|
||||
|
||||
return d_ptr->config;
|
||||
}
|
||||
|
||||
@@ -99,7 +122,10 @@ int xmrig::Controller::init()
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log::init();
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
d_ptr->api = new Api(this);
|
||||
# endif
|
||||
|
||||
Platform::init(config()->userAgent());
|
||||
|
||||
if (!config()->isBackground()) {
|
||||
@@ -139,25 +165,45 @@ void xmrig::Controller::addListener(IControllerListener *listener)
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::stop()
|
||||
{
|
||||
ConfigLoader::release();
|
||||
|
||||
delete d_ptr->proxy;
|
||||
d_ptr->proxy = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::watch()
|
||||
void xmrig::Controller::save()
|
||||
{
|
||||
if (!config()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (d_ptr->config->isShouldSave()) {
|
||||
d_ptr->config->save();
|
||||
}
|
||||
|
||||
ConfigLoader::watch(d_ptr->config);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::start()
|
||||
{
|
||||
proxy()->connect();
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
api()->start();
|
||||
# endif
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::stop()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
api()->stop();
|
||||
# endif
|
||||
|
||||
ConfigLoader::release();
|
||||
|
||||
delete d_ptr->proxy;
|
||||
d_ptr->proxy = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Controller::onNewConfig(IConfig *config)
|
||||
{
|
||||
Config *previousConfig = d_ptr->config;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Api;
|
||||
class Config;
|
||||
class ControllerPrivate;
|
||||
class IControllerListener;
|
||||
@@ -48,6 +49,7 @@ public:
|
||||
Controller(Process *process);
|
||||
~Controller() override;
|
||||
|
||||
Api *api() const;
|
||||
Config *config() const;
|
||||
const StatsData &statsData() const;
|
||||
const std::vector<Worker> &workers() const;
|
||||
@@ -55,8 +57,9 @@ public:
|
||||
Proxy *proxy() const;
|
||||
std::vector<Miner*> miners() const;
|
||||
void addListener(IControllerListener *listener);
|
||||
void save();
|
||||
void start();
|
||||
void stop();
|
||||
void watch();
|
||||
|
||||
protected:
|
||||
void onNewConfig(IConfig *config) override;
|
||||
@@ -65,6 +68,8 @@ private:
|
||||
ControllerPrivate *d_ptr;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CONTROLLER_H */
|
||||
|
||||
@@ -22,16 +22,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "common/config/ConfigLoader.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/ConfigCreator.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "donate.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/filewritestream.h"
|
||||
@@ -52,7 +52,6 @@ static const char *modeNames[] = {
|
||||
xmrig::Config::Config() : xmrig::CommonConfig(),
|
||||
m_algoExt(true),
|
||||
m_debug(false),
|
||||
m_ready(false),
|
||||
m_verbose(false),
|
||||
m_mode(NICEHASH_MODE),
|
||||
m_reuseTimeout(0),
|
||||
@@ -64,7 +63,7 @@ xmrig::Config::Config() : xmrig::CommonConfig(),
|
||||
|
||||
bool xmrig::Config::isTLS() const
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
for (const BindHost &host : m_bind) {
|
||||
if (host.isTLS()) {
|
||||
return true;
|
||||
@@ -76,9 +75,9 @@ bool xmrig::Config::isTLS() const
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Config::reload(const char *json)
|
||||
bool xmrig::Config::reload(const rapidjson::Value &json)
|
||||
{
|
||||
return xmrig::ConfigLoader::reload(this, json);
|
||||
return ConfigLoader::reload(this, json);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,13 +101,10 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
||||
doc.AddMember("algo-ext", m_algoExt, allocator);
|
||||
|
||||
Value api(kObjectType);
|
||||
api.AddMember("port", apiPort(), allocator);
|
||||
api.AddMember("access-token", m_apiToken.toJSON(), allocator);
|
||||
api.AddMember("id", m_apiId.toJSON(), allocator);
|
||||
api.AddMember("worker-id", m_apiWorkerId.toJSON(), allocator);
|
||||
api.AddMember("ipv6", isApiIPv6(), allocator);
|
||||
api.AddMember("restricted", isApiRestricted(), allocator);
|
||||
doc.AddMember("api", api, allocator);
|
||||
doc.AddMember("http", m_http.toJSON(doc), allocator);
|
||||
|
||||
doc.AddMember("background", isBackground(), allocator);
|
||||
|
||||
@@ -118,9 +114,9 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
||||
}
|
||||
|
||||
doc.AddMember("bind", bind, allocator);
|
||||
doc.AddMember("colors", isColors(), allocator);
|
||||
doc.AddMember("colors", Log::colors, allocator);
|
||||
doc.AddMember("custom-diff", diff(), allocator);
|
||||
doc.AddMember("donate-level", donateLevel(), allocator);
|
||||
doc.AddMember("donate-level", m_pools.donateLevel(), allocator);
|
||||
doc.AddMember("log-file", m_logFile.toJSON(), allocator);
|
||||
doc.AddMember("mode", StringRef(modeName()), allocator);
|
||||
doc.AddMember("pools", m_pools.toJSON(doc), allocator);
|
||||
@@ -128,16 +124,12 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
||||
doc.AddMember("retry-pause", m_pools.retryPause(), allocator);
|
||||
doc.AddMember("reuse-timeout", reuseTimeout(), allocator);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
doc.AddMember("tls", m_tls.toJSON(doc), allocator);
|
||||
# endif
|
||||
|
||||
doc.AddMember("user-agent", m_userAgent.toJSON(), allocator);
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
doc.AddMember("syslog", isSyslog(), allocator);
|
||||
# endif
|
||||
|
||||
doc.AddMember("user-agent", m_userAgent.toJSON(), allocator);
|
||||
doc.AddMember("syslog", isSyslog(), allocator);
|
||||
doc.AddMember("verbose", isVerbose(), allocator);
|
||||
doc.AddMember("watch", m_watch, allocator);
|
||||
doc.AddMember("workers", Workers::modeToJSON(workersMode()), allocator);
|
||||
@@ -146,7 +138,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
||||
|
||||
xmrig::Config *xmrig::Config::load(Process *process, IConfigListener *listener)
|
||||
{
|
||||
return static_cast<Config*>(ConfigLoader::load(process, new ConfigCreator(), listener));
|
||||
return static_cast<Config*>(ConfigLoader::load(process, listener));
|
||||
}
|
||||
|
||||
|
||||
@@ -309,11 +301,11 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Config::parseJSON(const rapidjson::Document &doc)
|
||||
void xmrig::Config::parseJSON(const rapidjson::Value &json)
|
||||
{
|
||||
CommonConfig::parseJSON(doc);
|
||||
CommonConfig::parseJSON(json);
|
||||
|
||||
const rapidjson::Value &bind = doc["bind"];
|
||||
const rapidjson::Value &bind = json["bind"];
|
||||
if (bind.IsArray()) {
|
||||
for (const rapidjson::Value &value : bind.GetArray()) {
|
||||
if (value.IsObject()) {
|
||||
@@ -328,8 +320,8 @@ void xmrig::Config::parseJSON(const rapidjson::Document &doc)
|
||||
}
|
||||
}
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
const rapidjson::Value &tls = doc["tls"];
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
const rapidjson::Value &tls = json["tls"];
|
||||
if (tls.IsObject()) {
|
||||
m_tls = std::move(TlsConfig(tls));
|
||||
}
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include "proxy/tls/TlsConfig.h"
|
||||
#endif
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
Config();
|
||||
|
||||
bool isTLS() const;
|
||||
bool reload(const char *json);
|
||||
bool reload(const rapidjson::Value &json);
|
||||
const char *modeName() const;
|
||||
|
||||
void getJSON(rapidjson::Document &doc) const override;
|
||||
@@ -81,13 +81,15 @@ public:
|
||||
|
||||
inline bool hasAlgoExt() const { return isDonateOverProxy() ? m_algoExt : true; }
|
||||
inline bool isDebug() const { return m_debug; }
|
||||
inline bool isDonateOverProxy() const { return m_donateLevel == 0 || m_mode == SIMPLE_MODE; }
|
||||
inline bool isDonateOverProxy() const { return m_pools.donateLevel() == 0 || m_mode == SIMPLE_MODE; }
|
||||
inline bool isShouldSave() const { return m_upgrade && isAutoSave(); }
|
||||
inline bool isVerbose() const { return m_verbose; }
|
||||
inline const String &accessLog() const { return m_accessLog; }
|
||||
inline const String &password() const { return m_password; }
|
||||
inline const xmrig::BindHosts &bind() const { return m_bind; }
|
||||
inline int mode() const { return m_mode; }
|
||||
inline int reuseTimeout() const { return m_reuseTimeout; }
|
||||
inline static IConfig *create() { return new Config(); }
|
||||
inline uint64_t diff() const { return m_diff; }
|
||||
inline void setVerbose(bool verbose) { m_verbose = verbose; }
|
||||
inline void toggleVerbose() { m_verbose = !m_verbose; }
|
||||
@@ -102,7 +104,7 @@ protected:
|
||||
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 parseJSON(const rapidjson::Value &json) override;
|
||||
|
||||
private:
|
||||
void setMode(const char *mode);
|
||||
@@ -110,7 +112,6 @@ private:
|
||||
BindHosts m_bind;
|
||||
bool m_algoExt;
|
||||
bool m_debug;
|
||||
bool m_ready;
|
||||
bool m_verbose;
|
||||
int m_mode;
|
||||
int m_reuseTimeout;
|
||||
@@ -46,12 +46,13 @@ static char const short_options[] = "c:khBp:Px:r:R:s:T:o:u:O:Vl:Sb:A:a:C:m:";
|
||||
static struct option const options[] = {
|
||||
{ "access-log-file", 1, nullptr, IConfig::AccessLogFileKey },
|
||||
{ "algo", 1, nullptr, IConfig::AlgorithmKey },
|
||||
{ "api-access-token", 1, nullptr, IConfig::ApiAccessTokenKey },
|
||||
{ "api-ipv6", 0, nullptr, IConfig::ApiIPv6Key },
|
||||
{ "api-no-restricted", 0, nullptr, IConfig::ApiRestrictedKey },
|
||||
{ "api-port", 1, nullptr, IConfig::ApiPort },
|
||||
{ "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
|
||||
{ "api-id", 1, nullptr, IConfig::ApiIdKey },
|
||||
{ "http-enabled", 0, nullptr, IConfig::HttpEnabledKey },
|
||||
{ "http-host", 1, nullptr, IConfig::HttpHostKey },
|
||||
{ "http-access-token", 1, nullptr, IConfig::HttpAccessTokenKey},
|
||||
{ "http-port", 1, nullptr, IConfig::HttpPort },
|
||||
{ "http-no-restricted",0, nullptr, IConfig::HttpRestrictedKey },
|
||||
{ "background", 0, nullptr, IConfig::BackgroundKey },
|
||||
{ "bind", 1, nullptr, IConfig::BindKey },
|
||||
{ "coin", 1, nullptr, IConfig::CoinKey },
|
||||
@@ -90,6 +91,14 @@ static struct option const options[] = {
|
||||
{ "tls-ciphersuites", 1, nullptr, IConfig::TlsCipherSuitesKey},
|
||||
{ "no-algo-ext", 0, nullptr, IConfig::AlgoExtKey },
|
||||
{ "access-password", 1, nullptr, IConfig::ProxyPasswordKey },
|
||||
|
||||
# ifdef XMRIG_DEPRECATED
|
||||
{ "api-port", 1, nullptr, IConfig::ApiPort },
|
||||
{ "api-access-token", 1, nullptr, IConfig::ApiAccessTokenKey },
|
||||
{ "api-no-restricted", 0, nullptr, IConfig::ApiRestrictedKey },
|
||||
{ "api-ipv6", 0, nullptr, IConfig::ApiIPv6Key },
|
||||
# endif
|
||||
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
@@ -120,11 +129,7 @@ static struct option const config_options[] = {
|
||||
|
||||
|
||||
static struct option const api_options[] = {
|
||||
{ "port", 1, nullptr, IConfig::ApiPort },
|
||||
{ "access-token", 1, nullptr, IConfig::ApiAccessTokenKey },
|
||||
{ "worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
|
||||
{ "ipv6", 0, nullptr, IConfig::ApiIPv6Key },
|
||||
{ "restricted", 0, nullptr, IConfig::ApiRestrictedKey },
|
||||
{ "id", 1, nullptr, IConfig::ApiIdKey },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
96
src/core/config/usage.h
Normal file
96
src/core/config/usage.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_USAGE_H
|
||||
#define XMRIG_USAGE_H
|
||||
|
||||
|
||||
#include "version.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static char const usage[] = "\
|
||||
Usage: " APP_ID " [OPTIONS]\n\
|
||||
Options:\n\
|
||||
-b, --bind=ADDR bind to specified address, example \"0.0.0.0:3333\"\n\
|
||||
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
|
||||
-m, --mode=MODE proxy mode, nicehash (default) or simple\n\
|
||||
-o, --url=URL URL of mining server\n\
|
||||
-O, --userpass=U:P username:password pair for mining server\n\
|
||||
-u, --user=USERNAME username for mining server\n\
|
||||
-p, --pass=PASSWORD password for mining server\n\
|
||||
--rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\
|
||||
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n\
|
||||
-k, --keepalive prevent timeout (needs pool support)\n\
|
||||
-r, --retries=N number of times to retry before switch to backup server (default: 1)\n\
|
||||
-R, --retry-pause=N time to pause between retries (default: 1 second)\n\
|
||||
--custom-diff=N override pool diff\n\
|
||||
--reuse-timeout=N timeout in seconds for reuse pool connections in simple mode\n\
|
||||
--verbose verbose output\n\
|
||||
--user-agent=AGENT set custom user-agent string for pool\n\
|
||||
--no-color disable colored output\n\
|
||||
--no-workers disable per worker statistics\n\
|
||||
--variant algorithm PoW variant\n\
|
||||
--donate-level=N donate level, default 2%%\n\
|
||||
-B, --background run the miner in the background\n\
|
||||
-c, --config=FILE load a JSON-format configuration file\n\
|
||||
--no-watch disable configuration file watching\n\
|
||||
-l, --log-file=FILE log all output to a file\n"
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
"\
|
||||
-S, --syslog use system log for output messages\n"
|
||||
#endif
|
||||
"\
|
||||
-A --access-log-file=N log all workers access to a file\n\
|
||||
--access-password=P set password to restrict connections to the proxy\n\
|
||||
--no-algo-ext disable \"algo\" protocol extension\n\
|
||||
--api-worker-id=ID custom worker-id (instance name) for API\n\
|
||||
--api-id=ID custom instance ID for API\n\
|
||||
--http-enabled enable HTTP API\n\
|
||||
--http-host=HOST bind host for HTTP API (by default 127.0.0.1)\n\
|
||||
--http-port=N bind port for HTTP API\n\
|
||||
--http-access-token=T access token for HTTP API\n\
|
||||
--http-no-restricted enable full remote access to HTTP API (only if access token set)\n"
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
"\
|
||||
--tls enable SSL/TLS support for pool connection (needs pool support)\n\
|
||||
--tls-bind=ADDR bind to specified address with enabled TLS\n\
|
||||
--tls-cert=FILE load TLS certificate chain from a file in the PEM format\n\
|
||||
--tls-cert-key=FILE load TLS certificate private key from a file in the PEM format\n\
|
||||
--tls-dhparam=FILE load DH parameters for DHE ciphers from a file in the PEM format\n\
|
||||
--tls-protocols=N enable specified TLS protocols, example: \"TLSv1 TLSv1.1 TLSv1.2 TLSv1.3\"\n\
|
||||
--tls-ciphers=S set list of available ciphers (TLSv1.2 and below)\n\
|
||||
--tls-ciphersuites=S set list of available TLSv1.3 ciphersuites\n"
|
||||
#endif
|
||||
"\
|
||||
-h, --help display this help and exit\n\
|
||||
-V, --version output version information and exit\n\
|
||||
";
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* XMRIG_USAGE_H */
|
||||
@@ -1,95 +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_USAGE_H
|
||||
#define XMRIG_USAGE_H
|
||||
|
||||
|
||||
#include "version.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static char const usage[] = "\
|
||||
Usage: " APP_ID " [OPTIONS]\n\
|
||||
Options:\n\
|
||||
-b, --bind=ADDR bind to specified address, example \"0.0.0.0:3333\"\n\
|
||||
-a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\
|
||||
-m, --mode=MODE proxy mode, nicehash (default) or simple\n\
|
||||
-o, --url=URL URL of mining server\n\
|
||||
-O, --userpass=U:P username:password pair for mining server\n\
|
||||
-u, --user=USERNAME username for mining server\n\
|
||||
-p, --pass=PASSWORD password for mining server\n\
|
||||
--rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\
|
||||
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n\
|
||||
-k, --keepalive prevent timeout (needs pool support)\n\
|
||||
-r, --retries=N number of times to retry before switch to backup server (default: 1)\n\
|
||||
-R, --retry-pause=N time to pause between retries (default: 1 second)\n\
|
||||
--custom-diff=N override pool diff\n\
|
||||
--reuse-timeout=N timeout in seconds for reuse pool connections in simple mode\n\
|
||||
--verbose verbose output\n\
|
||||
--user-agent=AGENT set custom user-agent string for pool\n\
|
||||
--no-color disable colored output\n\
|
||||
--no-workers disable per worker statistics\n\
|
||||
--variant algorithm PoW variant\n\
|
||||
--donate-level=N donate level, default 2%%\n\
|
||||
-B, --background run the miner in the background\n\
|
||||
-c, --config=FILE load a JSON-format configuration file\n\
|
||||
--no-watch disable configuration file watching\n\
|
||||
-l, --log-file=FILE log all output to a file\n"
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
"\
|
||||
-S, --syslog use system log for output messages\n"
|
||||
#endif
|
||||
"\
|
||||
-A --access-log-file=N log all workers access to a file\n\
|
||||
--access-password=P set password to restrict connections to the proxy\n\
|
||||
--no-algo-ext disable \"algo\" protocol extension\n\
|
||||
--api-port=N port for the miner API\n\
|
||||
--api-access-token=T use Bearer access token for API\n\
|
||||
--api-worker-id=ID custom worker-id (instance name) for API\n\
|
||||
--api-id=ID custom instance ID for API\n\
|
||||
--api-ipv6 enable IPv6 support for API\n\
|
||||
--api-no-restricted enable full remote access (only if API token set)\n"
|
||||
#ifndef XMRIG_NO_TLS
|
||||
"\
|
||||
--tls enable SSL/TLS support for pool connection (needs pool support)\n\
|
||||
--tls-bind=ADDR bind to specified address with enabled TLS\n\
|
||||
--tls-cert=FILE load TLS certificate chain from a file in the PEM format\n\
|
||||
--tls-cert-key=FILE load TLS certificate private key from a file in the PEM format\n\
|
||||
--tls-dhparam=FILE load DH parameters for DHE ciphers from a file in the PEM format\n\
|
||||
--tls-protocols=N enable specified TLS protocols, example: \"TLSv1 TLSv1.1 TLSv1.2 TLSv1.3\"\n\
|
||||
--tls-ciphers=S set list of available ciphers (TLSv1.2 and below)\n\
|
||||
--tls-ciphersuites=S set list of available TLSv1.3 ciphersuites\n"
|
||||
#endif
|
||||
"\
|
||||
-h, --help display this help and exit\n\
|
||||
-V, --version output version information and exit\n\
|
||||
";
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
#endif /* XMRIG_USAGE_H */
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/AccessLog.h"
|
||||
#include "proxy/Counters.h"
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/SubmitResult.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "log/ShareLog.h"
|
||||
#include "proxy/events/AcceptEvent.h"
|
||||
@@ -75,20 +75,13 @@ void xmrig::ShareLog::onRejectedEvent(IEvent *event)
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::ShareLog::isColors() const
|
||||
{
|
||||
return m_controller->config()->isColors();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::ShareLog::accept(const AcceptEvent *event)
|
||||
{
|
||||
if (!m_controller->config()->isVerbose() || event->isDonate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[01;30m(%" PRIu64 " ms)"
|
||||
: "#%03u accepted (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u ip %s (%" PRIu64 " ms)",
|
||||
LOG_INFO("#%03u \x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[01;30m(%" PRIu64 " ms)",
|
||||
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->ip(), event->result.elapsed);
|
||||
}
|
||||
|
||||
@@ -99,7 +92,6 @@ void xmrig::ShareLog::reject(const AcceptEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(isColors() ? "#%03u \x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRId64 " ms)"
|
||||
: "#%03u rejected (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff %u ip %s \"%s\" (%" PRId64 " ms)",
|
||||
LOG_INFO("#%03u \x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 "+%" PRId64 ") diff \x1B[01;37m%u\x1B[0m ip \x1B[01;37m%s \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRId64 " ms)",
|
||||
event->mapperId(), m_stats.data().accepted, m_stats.data().rejected, m_stats.data().invalid, event->result.diff, event->ip(), event->error(), event->result.elapsed);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ protected:
|
||||
void onRejectedEvent(IEvent *event) override;
|
||||
|
||||
private:
|
||||
bool isColors() const;
|
||||
void accept(const AcceptEvent *event);
|
||||
void reject(const AcceptEvent *event);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "common/crypto/keccak.h"
|
||||
#include "common/Platform.h"
|
||||
#include "common/xmrig.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "donate.h"
|
||||
#include "net/strategies/DonateStrategy.h"
|
||||
@@ -59,7 +59,7 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener
|
||||
|
||||
m_client = new Client(-1, Platform::userAgent(), this);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
m_client->setPool(Pool("donate.ssl.xmrig.com", 8443, userId, nullptr, Pool::kKeepAliveTimeout, false, true));
|
||||
# else
|
||||
m_client->setPool(Pool("donate.v2.xmrig.com", 5555, userId, nullptr));
|
||||
@@ -69,7 +69,7 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener
|
||||
m_client->setAlgo(controller->config()->algorithm());
|
||||
m_client->setQuiet(true);
|
||||
|
||||
m_target = (100 - controller->config()->donateLevel()) * 60 * randomf(0.5, 1.5);
|
||||
m_target = (100 - controller->config()->pools().donateLevel()) * 60 * randomf(0.5, 1.5);
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ xmrig::DonateStrategy::~DonateStrategy()
|
||||
|
||||
bool xmrig::DonateStrategy::reschedule()
|
||||
{
|
||||
const uint64_t level = m_controller->config()->donateLevel() * 60;
|
||||
const uint64_t level = m_controller->config()->pools().donateLevel() * 60;
|
||||
if (m_donateTicks < level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/CustomDiff.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "proxy/Events.h"
|
||||
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
#include "proxy/Login.h"
|
||||
@@ -106,7 +106,6 @@ void xmrig::Login::reject(LoginEvent *event, const char *message)
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(m_controller->config()->isColors() ? RED_BOLD("deny") " " WHITE_BOLD("\"%s\"") " from " CYAN_BOLD("%s") WHITE_BOLD(" (%s)") " reason " RED("\"%s\"")
|
||||
: "deny \"%s\" from %s (%s) reason \"%s\"",
|
||||
LOG_INFO(RED_BOLD("deny") " " WHITE_BOLD("\"%s\"") " from " CYAN_BOLD("%s") WHITE_BOLD(" (%s)") " reason " RED("\"%s\""),
|
||||
event->miner()->rigId(true).data(), event->miner()->ip(), event->miner()->agent().data(), message);
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Job.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/Error.h"
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "rapidjson/writer.h"
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include "proxy/tls/Tls.h"
|
||||
#endif
|
||||
|
||||
@@ -91,7 +91,7 @@ xmrig::Miner::Miner(const TlsContext *ctx, bool ipv6, uint16_t port) :
|
||||
m_recvBuf.base = m_buf;
|
||||
m_recvBuf.len = sizeof(m_buf);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (ctx != nullptr) {
|
||||
m_tls = new Tls(ctx->ctx(), this);
|
||||
}
|
||||
@@ -105,7 +105,7 @@ xmrig::Miner::~Miner()
|
||||
{
|
||||
Handle::close(m_socket);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
delete m_tls;
|
||||
# endif
|
||||
|
||||
@@ -134,7 +134,7 @@ bool xmrig::Miner::accept(uv_stream_t *server)
|
||||
|
||||
uv_read_start(reinterpret_cast<uv_stream_t*>(m_socket), Miner::onAllocBuffer, Miner::onRead);
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
return m_tls->accept();
|
||||
}
|
||||
@@ -285,7 +285,7 @@ bool xmrig::Miner::parseRequest(int64_t id, const char *method, const rapidjson:
|
||||
|
||||
bool xmrig::Miner::send(BIO *bio)
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
uv_buf_t buf;
|
||||
buf.len = BIO_get_mem_data(bio, &buf.base);
|
||||
|
||||
@@ -388,7 +388,7 @@ void xmrig::Miner::read()
|
||||
|
||||
void xmrig::Miner::readTLS(int nread)
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
LOG_DEBUG("[%s] TLS received (%d bytes)", m_ip, nread);
|
||||
|
||||
@@ -438,7 +438,7 @@ void xmrig::Miner::send(int size)
|
||||
}
|
||||
|
||||
int rc = -1;
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (isTLS()) {
|
||||
rc = m_tls->send(m_sendBuf, size) ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "proxy/events/CloseEvent.h"
|
||||
#include "proxy/events/ConnectionEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "common/Platform.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "Counters.h"
|
||||
#include "log/AccessLog.h"
|
||||
@@ -54,7 +54,7 @@
|
||||
#include "proxy/workers/Workers.h"
|
||||
|
||||
|
||||
#ifndef XMRIG_NO_TLS
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
# include "proxy/tls/TlsContext.h"
|
||||
#endif
|
||||
|
||||
@@ -137,7 +137,7 @@ xmrig::Proxy::~Proxy()
|
||||
delete m_debug;
|
||||
delete m_workers;
|
||||
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
delete m_tls;
|
||||
# endif
|
||||
}
|
||||
@@ -145,9 +145,9 @@ xmrig::Proxy::~Proxy()
|
||||
|
||||
void xmrig::Proxy::connect()
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_controller->config()->isTLS()) {
|
||||
m_tls = new xmrig::TlsContext();
|
||||
m_tls = new TlsContext();
|
||||
|
||||
if (!m_tls->load(m_controller->config()->tls())) {
|
||||
delete m_tls;
|
||||
@@ -175,8 +175,7 @@ void xmrig::Proxy::printConnections()
|
||||
|
||||
void xmrig::Proxy::printHashrate()
|
||||
{
|
||||
LOG_INFO(isColors() ? "\x1B[01;32m* \x1B[01;37mspeed\x1B[0m \x1B[01;30m(1m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(10m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(1h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(12h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(24h) \x1B[01;36m%03.2f kH/s"
|
||||
: "* speed (1m) %03.2f, (10m) %03.2f, (1h) %03.2f, (12h) %03.2f, (24h) %03.2f kH/s",
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mspeed\x1B[0m \x1B[01;30m(1m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(10m) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(1h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(12h) \x1B[01;36m%03.2f\x1B[0m, \x1B[01;30m(24h) \x1B[01;36m%03.2f kH/s",
|
||||
m_stats.hashrate(60), m_stats.hashrate(600), m_stats.hashrate(3600), m_stats.hashrate(3600 * 12), m_stats.hashrate(3600 * 24));
|
||||
}
|
||||
|
||||
@@ -229,15 +228,9 @@ void xmrig::Proxy::onConfigChanged(xmrig::Config *config, xmrig::Config *)
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Proxy::isColors() const
|
||||
{
|
||||
return m_controller->config()->isColors();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Proxy::bind(const xmrig::BindHost &host)
|
||||
{
|
||||
# ifndef XMRIG_NO_TLS
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (host.isTLS() && !m_tls) {
|
||||
LOG_ERR("Failed to bind \"%s:%d\" error: \"TLS not available\".", host.host(), host.port());
|
||||
|
||||
@@ -264,9 +257,8 @@ void xmrig::Proxy::gc()
|
||||
|
||||
void xmrig::Proxy::print()
|
||||
{
|
||||
LOG_INFO(isColors() ? "\x1B[01;36m%03.2f kH/s\x1B[0m, shares: \x1B[01;37m%" PRIu64 "\x1B[0m/%s%" PRIu64 "\x1B[0m +%" PRIu64 ", upstreams: \x1B[01;37m%" PRIu64 "\x1B[0m, miners: \x1B[01;37m%" PRIu64 "\x1B[0m (max \x1B[01;37m%" PRIu64 "\x1B[0m) +%u/-%u"
|
||||
: "%03.2f kH/s, shares: %" PRIu64 "/%s%" PRIu64 " +%" PRIu64 ", upstreams: %" PRIu64 ", miners: %" PRIu64 " (max %" PRIu64 " +%u/-%u",
|
||||
m_stats.hashrate(60), m_stats.data().accepted, isColors() ? (m_stats.data().rejected ? "\x1B[31m" : "\x1B[01;37m") : "", m_stats.data().rejected,
|
||||
LOG_INFO("\x1B[01;36m%03.2f kH/s\x1B[0m, shares: \x1B[01;37m%" PRIu64 "\x1B[0m/%s%" PRIu64 "\x1B[0m +%" PRIu64 ", upstreams: \x1B[01;37m%" PRIu64 "\x1B[0m, miners: \x1B[01;37m%" PRIu64 "\x1B[0m (max \x1B[01;37m%" PRIu64 "\x1B[0m) +%u/-%u",
|
||||
m_stats.hashrate(60), m_stats.data().accepted, (m_stats.data().rejected ? "\x1B[0;31m" : "\x1B[1;37m"), m_stats.data().rejected,
|
||||
Counters::accepted, m_splitter->upstreams().active, Counters::miners(), Counters::maxMiners(), Counters::added(), Counters::removed());
|
||||
|
||||
Counters::reset();
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "common/interfaces/IControllerListener.h"
|
||||
#include "base/kernel/interfaces/IControllerListener.h"
|
||||
#include "proxy/CustomDiff.h"
|
||||
#include "proxy/Stats.h"
|
||||
#include "proxy/workers/Worker.h"
|
||||
@@ -81,7 +81,6 @@ private:
|
||||
constexpr static int kPrintInterval = 60;
|
||||
constexpr static int kGCInterval = 60;
|
||||
|
||||
bool isColors() const;
|
||||
void bind(const BindHost &host);
|
||||
void gc();
|
||||
void print();
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/SubmitResult.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "proxy/Events.h"
|
||||
#include "proxy/events/AcceptEvent.h"
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "proxy/BindHost.h"
|
||||
#include "proxy/events/ConnectionEvent.h"
|
||||
#include "proxy/Miner.h"
|
||||
|
||||
@@ -50,7 +50,7 @@ void xmrig::Stats::tick(uint64_t ticks, const ISplitter *splitter)
|
||||
if ((ticks % m_hashrate.tickTime()) == 0) {
|
||||
m_hashrate.tick();
|
||||
|
||||
# ifndef XMRIG_NO_API
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
m_data.hashrate[0] = hashrate(60);
|
||||
m_data.hashrate[1] = hashrate(600);
|
||||
m_data.hashrate[2] = hashrate(3600);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define XMRIG_SPLITTER_H
|
||||
|
||||
|
||||
#include "common/interfaces/IControllerListener.h"
|
||||
#include "base/kernel/interfaces/IControllerListener.h"
|
||||
#include "interfaces/IEventListener.h"
|
||||
#include "interfaces/ISplitter.h"
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "base/io/Json.h"
|
||||
#include "base/net/stratum/Pool.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/events/CloseEvent.h"
|
||||
#include "proxy/events/LoginEvent.h"
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
#include "common/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "net/JobResult.h"
|
||||
#include "net/strategies/DonateStrategy.h"
|
||||
@@ -54,7 +54,7 @@ xmrig::NonceMapper::NonceMapper(size_t id, Controller *controller) :
|
||||
m_storage = new NonceStorage();
|
||||
m_strategy = controller->config()->pools().createStrategy(this);
|
||||
|
||||
if (controller->config()->donateLevel() > 0) {
|
||||
if (controller->config()->pools().donateLevel() > 0) {
|
||||
m_donate = new DonateStrategy(controller, this);
|
||||
}
|
||||
}
|
||||
@@ -199,8 +199,7 @@ void xmrig::NonceMapper::onActive(IStrategy *strategy, Client *client)
|
||||
if (m_controller->config()->isVerbose()) {
|
||||
const char *tlsVersion = client->tlsVersion();
|
||||
|
||||
LOG_INFO(isColors() ? "#%03u " WHITE_BOLD("use pool ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " \x1B[1;30m%s "
|
||||
: "#%03u use pool %s:%d %s %s",
|
||||
LOG_INFO("#%03u " WHITE_BOLD("use pool ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " \x1B[1;30m%s ",
|
||||
m_id, client->host(), client->port(), tlsVersion ? tlsVersion : "", client->ip());
|
||||
|
||||
const char *fingerprint = client->tlsFingerprint();
|
||||
@@ -255,12 +254,6 @@ void xmrig::NonceMapper::onResultAccepted(IStrategy *, Client *client, const Sub
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::NonceMapper::isColors() const
|
||||
{
|
||||
return m_controller->config()->isColors();
|
||||
}
|
||||
|
||||
|
||||
xmrig::SubmitCtx xmrig::NonceMapper::submitCtx(int64_t seq)
|
||||
{
|
||||
if (!m_results.count(seq)) {
|
||||
@@ -294,13 +287,11 @@ void xmrig::NonceMapper::setJob(const char *host, int port, const Job &job)
|
||||
{
|
||||
if (m_controller->config()->isVerbose()) {
|
||||
if (job.height()) {
|
||||
LOG_INFO(isColors() ? "#%03u " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64)
|
||||
: "#%03u new job from %s:%d diff %d algo %s height %" PRIu64,
|
||||
LOG_INFO("#%03u " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64),
|
||||
m_id, host, port, job.diff(), job.algorithm().shortName(), job.height());
|
||||
}
|
||||
else {
|
||||
LOG_INFO(isColors() ? "#%03u " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s")
|
||||
: "#%03u new job from %s:%d diff %d algo %s",
|
||||
LOG_INFO("#%03u " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s"),
|
||||
m_id, host, port, job.diff(), job.algorithm().shortName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,6 @@ protected:
|
||||
void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
private:
|
||||
bool isColors() const;
|
||||
SubmitCtx submitCtx(int64_t seq);
|
||||
void connect();
|
||||
void setJob(const char *host, int port, const Job &job);
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#include "common/log/Log.h"
|
||||
#include "core/Config.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "proxy/Counters.h"
|
||||
#include "proxy/events/CloseEvent.h"
|
||||
@@ -102,20 +102,11 @@ void xmrig::NonceSplitter::printConnections()
|
||||
{
|
||||
const Upstreams info = upstreams();
|
||||
|
||||
if (m_controller->config()->isColors()) {
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("sleep") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("error") "%s%" PRIu64 "\x1B[0m" LABEL("total") "\x1B[01;37m%" PRIu64,
|
||||
info.active ? "\x1B[01;32m" : "\x1B[01;31m", info.active, info.sleep, info.error ? "\x1B[01;31m" : "\x1B[01;37m", info.error, info.total);
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mupstreams\x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("sleep") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("error") "%s%" PRIu64 "\x1B[0m" LABEL("total") "\x1B[01;37m%" PRIu64,
|
||||
info.active ? "\x1B[01;32m" : "\x1B[01;31m", info.active, info.sleep, info.error ? "\x1B[01;31m" : "\x1B[01;37m", info.error, info.total);
|
||||
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mminers \x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("max") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("ratio") "%s1:%3.1f",
|
||||
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners(), (info.ratio > 200 ? "\x1B[01;32m" : "\x1B[01;33m"), info.ratio);
|
||||
}
|
||||
else {
|
||||
LOG_INFO("* upstreams: active %" PRIu64 " sleep %" PRIu64 " error %" PRIu64 " total %" PRIu64,
|
||||
info.active, info.sleep, info.error, info.total);
|
||||
|
||||
LOG_INFO("* miners: active %" PRIu64 " max %" PRIu64 " ratio 1:%3.1f",
|
||||
Counters::miners(), Counters::maxMiners(), info.ratio);
|
||||
}
|
||||
LOG_INFO("\x1B[01;32m* \x1B[01;37mminers \x1B[0m" LABEL("active") "%s%" PRIu64 "\x1B[0m" LABEL("max") "\x1B[01;37m%" PRIu64 "\x1B[0m" LABEL("ratio") "%s1:%3.1f",
|
||||
Counters::miners() ? "\x1B[01;32m" : "\x1B[01;31m", Counters::miners(), Counters::maxMiners(), (info.ratio > 200 ? "\x1B[01;32m" : "\x1B[01;33m"), info.ratio);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +133,7 @@ void xmrig::NonceSplitter::printState()
|
||||
void xmrig::NonceSplitter::onConfigChanged(Config *config, Config *previousConfig)
|
||||
{
|
||||
if (config->pools() != previousConfig->pools()) {
|
||||
config->printPools();
|
||||
config->pools().print();
|
||||
|
||||
for (NonceMapper *mapper : m_upstreams) {
|
||||
mapper->reload(config->pools());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user