Merge branch 'dev'

This commit is contained in:
XMRig 2020-03-06 13:17:44 +07:00
commit 4a7897b8bc
No known key found for this signature in database
GPG key ID: 446A53638BE94409
41 changed files with 689 additions and 323 deletions

View file

@ -381,7 +381,10 @@ enum header_states
, h_transfer_encoding , h_transfer_encoding
, h_upgrade , h_upgrade
, h_matching_transfer_encoding_token_start
, h_matching_transfer_encoding_chunked , h_matching_transfer_encoding_chunked
, h_matching_transfer_encoding_token
, h_matching_connection_token_start , h_matching_connection_token_start
, h_matching_connection_keep_alive , h_matching_connection_keep_alive
, h_matching_connection_close , h_matching_connection_close
@ -1257,9 +1260,9 @@ reexecute:
switch (parser->header_state) { switch (parser->header_state) {
case h_general: { case h_general: {
size_t limit = data + len - p; size_t left = data + len - p;
limit = MIN(limit, max_header_size); const char* pe = p + MIN(left, max_header_size);
while (p+1 < data + limit && TOKEN(p[1])) { while (p+1 < pe && TOKEN(p[1])) {
p++; p++;
} }
break; break;
@ -1335,6 +1338,7 @@ reexecute:
parser->header_state = h_general; parser->header_state = h_general;
} else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
parser->header_state = h_transfer_encoding; parser->header_state = h_transfer_encoding;
parser->flags |= F_TRANSFER_ENCODING;
} }
break; break;
@ -1416,10 +1420,14 @@ reexecute:
if ('c' == c) { if ('c' == c) {
parser->header_state = h_matching_transfer_encoding_chunked; parser->header_state = h_matching_transfer_encoding_chunked;
} else { } else {
parser->header_state = h_general; parser->header_state = h_matching_transfer_encoding_token;
} }
break; break;
/* Multi-value `Transfer-Encoding` header */
case h_matching_transfer_encoding_token_start:
break;
case h_content_length: case h_content_length:
if (UNLIKELY(!IS_NUM(ch))) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
@ -1497,24 +1505,21 @@ reexecute:
switch (h_state) { switch (h_state) {
case h_general: case h_general:
{ {
const char* p_cr; size_t left = data + len - p;
const char* p_lf; const char* pe = p + MIN(left, max_header_size);
size_t limit = data + len - p;
limit = MIN(limit, max_header_size); for (; p != pe; p++) {
ch = *p;
p_cr = (const char*) memchr(p, CR, limit); if (ch == CR || ch == LF) {
p_lf = (const char*) memchr(p, LF, limit); --p;
if (p_cr != NULL) { break;
if (p_lf != NULL && p_cr >= p_lf)
p = p_lf;
else
p = p_cr;
} else if (UNLIKELY(p_lf != NULL)) {
p = p_lf;
} else {
p = data + len;
} }
if (!lenient && !IS_HEADER_CHAR(ch)) {
SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
goto error;
}
}
if (p == data + len)
--p; --p;
break; break;
} }
@ -1566,16 +1571,41 @@ reexecute:
goto error; goto error;
/* Transfer-Encoding: chunked */ /* Transfer-Encoding: chunked */
case h_matching_transfer_encoding_token_start:
/* looking for 'Transfer-Encoding: chunked' */
if ('c' == c) {
h_state = h_matching_transfer_encoding_chunked;
} else if (STRICT_TOKEN(c)) {
/* TODO(indutny): similar code below does this, but why?
* At the very least it seems to be inconsistent given that
* h_matching_transfer_encoding_token does not check for
* `STRICT_TOKEN`
*/
h_state = h_matching_transfer_encoding_token;
} else if (c == ' ' || c == '\t') {
/* Skip lws */
} else {
h_state = h_general;
}
break;
case h_matching_transfer_encoding_chunked: case h_matching_transfer_encoding_chunked:
parser->index++; parser->index++;
if (parser->index > sizeof(CHUNKED)-1 if (parser->index > sizeof(CHUNKED)-1
|| c != CHUNKED[parser->index]) { || c != CHUNKED[parser->index]) {
h_state = h_general; h_state = h_matching_transfer_encoding_token;
} else if (parser->index == sizeof(CHUNKED)-2) { } else if (parser->index == sizeof(CHUNKED)-2) {
h_state = h_transfer_encoding_chunked; h_state = h_transfer_encoding_chunked;
} }
break; break;
case h_matching_transfer_encoding_token:
if (ch == ',') {
h_state = h_matching_transfer_encoding_token_start;
parser->index = 0;
}
break;
case h_matching_connection_token_start: case h_matching_connection_token_start:
/* looking for 'Connection: keep-alive' */ /* looking for 'Connection: keep-alive' */
if (c == 'k') { if (c == 'k') {
@ -1634,7 +1664,7 @@ reexecute:
break; break;
case h_transfer_encoding_chunked: case h_transfer_encoding_chunked:
if (ch != ' ') h_state = h_general; if (ch != ' ') h_state = h_matching_transfer_encoding_token;
break; break;
case h_connection_keep_alive: case h_connection_keep_alive:
@ -1768,13 +1798,18 @@ reexecute:
REEXECUTE(); REEXECUTE();
} }
/* Cannot use chunked encoding and a content-length header together /* Cannot us transfer-encoding and a content-length header together
per the HTTP specification. */ per the HTTP specification. (RFC 7230 Section 3.3.3) */
if ((parser->flags & F_CHUNKED) && if ((parser->flags & F_TRANSFER_ENCODING) &&
(parser->flags & F_CONTENTLENGTH)) { (parser->flags & F_CONTENTLENGTH)) {
/* Allow it for lenient parsing as long as `Transfer-Encoding` is
* not `chunked`
*/
if (!lenient || (parser->flags & F_CHUNKED)) {
SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);
goto error; goto error;
} }
}
UPDATE_STATE(s_headers_done); UPDATE_STATE(s_headers_done);
@ -1848,8 +1883,31 @@ reexecute:
UPDATE_STATE(NEW_MESSAGE()); UPDATE_STATE(NEW_MESSAGE());
CALLBACK_NOTIFY(message_complete); CALLBACK_NOTIFY(message_complete);
} else if (parser->flags & F_CHUNKED) { } else if (parser->flags & F_CHUNKED) {
/* chunked encoding - ignore Content-Length header */ /* chunked encoding - ignore Content-Length header,
* prepare for a chunk */
UPDATE_STATE(s_chunk_size_start); UPDATE_STATE(s_chunk_size_start);
} else if (parser->flags & F_TRANSFER_ENCODING) {
if (parser->type == HTTP_REQUEST && !lenient) {
/* RFC 7230 3.3.3 */
/* If a Transfer-Encoding header field
* is present in a request and the chunked transfer coding is not
* the final encoding, the message body length cannot be determined
* reliably; the server MUST respond with the 400 (Bad Request)
* status code and then close the connection.
*/
SET_ERRNO(HPE_INVALID_TRANSFER_ENCODING);
RETURN(p - data); /* Error */
} else {
/* RFC 7230 3.3.3 */
/* If a Transfer-Encoding header field is present in a response and
* the chunked transfer coding is not the final encoding, the
* message body length is determined by reading the connection until
* it is closed by the server.
*/
UPDATE_STATE(s_body_identity_eof);
}
} else { } else {
if (parser->content_length == 0) { if (parser->content_length == 0) {
/* Content-Length header given but zero: Content-Length: 0\r\n */ /* Content-Length header given but zero: Content-Length: 0\r\n */
@ -2103,6 +2161,12 @@ http_message_needs_eof (const http_parser *parser)
return 0; return 0;
} }
/* RFC 7230 3.3.3, see `s_headers_almost_done` */
if ((parser->flags & F_TRANSFER_ENCODING) &&
(parser->flags & F_CHUNKED) == 0) {
return 1;
}
if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
return 0; return 0;
} }

View file

@ -27,7 +27,7 @@ extern "C" {
/* Also update SONAME in the Makefile whenever you change these. */ /* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2 #define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9 #define HTTP_PARSER_VERSION_MINOR 9
#define HTTP_PARSER_VERSION_PATCH 0 #define HTTP_PARSER_VERSION_PATCH 3
#include <stddef.h> #include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \ #if defined(_WIN32) && !defined(__MINGW32__) && \
@ -225,6 +225,7 @@ enum flags
, F_UPGRADE = 1 << 5 , F_UPGRADE = 1 << 5
, F_SKIPBODY = 1 << 6 , F_SKIPBODY = 1 << 6
, F_CONTENTLENGTH = 1 << 7 , F_CONTENTLENGTH = 1 << 7
, F_TRANSFER_ENCODING = 1 << 8
}; };
@ -271,6 +272,8 @@ enum flags
"unexpected content-length header") \ "unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \ XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \ "invalid character in chunk size header") \
XX(INVALID_TRANSFER_ENCODING, \
"request has invalid transfer-encoding") \
XX(INVALID_CONSTANT, "invalid constant string") \ XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \ XX(STRICT, "strict mode assertion failed") \
@ -293,11 +296,11 @@ enum http_errno {
struct http_parser { struct http_parser {
/** PRIVATE **/ /** PRIVATE **/
unsigned int type : 2; /* enum http_parser_type */ 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 state : 7; /* enum state from http_parser.c */
unsigned int header_state : 7; /* enum header_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 index : 7; /* index into current matcher */
unsigned int lenient_http_headers : 1; unsigned int lenient_http_headers : 1;
unsigned int flags : 16; /* F_* values from 'flags' enum; semi-public */
uint32_t nread; /* # bytes read in various scenarios */ uint32_t nread; /* # bytes read in various scenarios */
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */

View file

@ -416,6 +416,10 @@ rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const
out.AddMember("argon2-impl", argon2::Impl::name().toJSON(), allocator); out.AddMember("argon2-impl", argon2::Impl::name().toJSON(), allocator);
# endif # endif
# ifdef XMRIG_ALGO_ASTROBWT
out.AddMember("astrobwt-max-size", cpu.astrobwtMaxSize(), allocator);
# endif
out.AddMember("hugepages", d_ptr->hugePages(2, doc), allocator); out.AddMember("hugepages", d_ptr->hugePages(2, doc), allocator);
out.AddMember("memory", static_cast<uint64_t>(d_ptr->algo.isValid() ? (d_ptr->ways() * d_ptr->algo.l3()) : 0), allocator); out.AddMember("memory", static_cast<uint64_t>(d_ptr->algo.isValid() ? (d_ptr->ways() * d_ptr->algo.l3()) : 0), allocator);

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -29,6 +29,8 @@
#include "base/io/json/Json.h" #include "base/io/json/Json.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include <algorithm>
namespace xmrig { namespace xmrig {
@ -48,6 +50,11 @@ static const char *kAsm = "asm";
static const char *kArgon2Impl = "argon2-impl"; static const char *kArgon2Impl = "argon2-impl";
#endif #endif
#ifdef XMRIG_ALGO_ASTROBWT
static const char* kAstroBWTMaxSize = "astrobwt-max-size";
#endif
extern template class Threads<CpuThreads>; extern template class Threads<CpuThreads>;
} }
@ -85,6 +92,10 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kArgon2Impl), m_argon2Impl.toJSON(), allocator); obj.AddMember(StringRef(kArgon2Impl), m_argon2Impl.toJSON(), allocator);
# endif # endif
# ifdef XMRIG_ALGO_ASTROBWT
obj.AddMember(StringRef(kAstroBWTMaxSize), m_astrobwtMaxSize, allocator);
# endif
m_threads.toJSON(obj, doc); m_threads.toJSON(obj, doc);
return obj; return obj;
@ -136,6 +147,16 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
m_argon2Impl = Json::getString(value, kArgon2Impl); m_argon2Impl = Json::getString(value, kArgon2Impl);
# endif # endif
# ifdef XMRIG_ALGO_ASTROBWT
const auto& obj = Json::getValue(value, kAstroBWTMaxSize);
if (obj.IsNull() || !obj.IsInt()) {
m_shouldSave = true;
}
else {
m_astrobwtMaxSize = std::min(std::max(obj.GetInt(), 400), 1200);
}
# endif
m_threads.read(value); m_threads.read(value);
generate(); generate();
@ -167,7 +188,7 @@ void xmrig::CpuConfig::generate()
count += xmrig::generate<Algorithm::ARGON2>(m_threads, m_limit); count += xmrig::generate<Algorithm::ARGON2>(m_threads, m_limit);
count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, m_limit); count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, m_limit);
m_shouldSave = count > 0; m_shouldSave |= count > 0;
} }

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -58,6 +58,7 @@ public:
inline bool isYield() const { return m_yield; } inline bool isYield() const { return m_yield; }
inline const Assembly &assembly() const { return m_assembly; } inline const Assembly &assembly() const { return m_assembly; }
inline const String &argon2Impl() const { return m_argon2Impl; } inline const String &argon2Impl() const { return m_argon2Impl; }
inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; }
inline const Threads<CpuThreads> &threads() const { return m_threads; } inline const Threads<CpuThreads> &threads() const { return m_threads; }
inline int priority() const { return m_priority; } inline int priority() const { return m_priority; }
inline uint32_t limit() const { return m_limit; } inline uint32_t limit() const { return m_limit; }
@ -78,6 +79,7 @@ private:
int m_memoryPool = 0; int m_memoryPool = 0;
int m_priority = -1; int m_priority = -1;
String m_argon2Impl; String m_argon2Impl;
int m_astrobwtMaxSize = 550;
Threads<CpuThreads> m_threads; Threads<CpuThreads> m_threads;
uint32_t m_limit = 100; uint32_t m_limit = 100;
}; };

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,7 +25,6 @@
#include "backend/cpu/CpuLaunchData.h" #include "backend/cpu/CpuLaunchData.h"
#include "backend/common/Tags.h" #include "backend/common/Tags.h"
#include "backend/cpu/CpuConfig.h" #include "backend/cpu/CpuConfig.h"
@ -39,6 +38,7 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit
hugePages(config.isHugePages()), hugePages(config.isHugePages()),
hwAES(config.isHwAES()), hwAES(config.isHwAES()),
yield(config.isYield()), yield(config.isYield()),
astrobwtMaxSize(config.astrobwtMaxSize()),
priority(config.priority()), priority(config.priority()),
affinity(thread.affinity()), affinity(thread.affinity()),
miner(miner), miner(miner),

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -61,6 +61,7 @@ public:
const bool hugePages; const bool hugePages;
const bool hwAES; const bool hwAES;
const bool yield; const bool yield;
const int astrobwtMaxSize;
const int priority; const int priority;
const int64_t affinity; const int64_t affinity;
const Miner *miner; const Miner *miner;

View file

@ -32,6 +32,7 @@
#include "core/Miner.h" #include "core/Miner.h"
#include "crypto/cn/CnCtx.h" #include "crypto/cn/CnCtx.h"
#include "crypto/cn/CryptoNight_test.h" #include "crypto/cn/CryptoNight_test.h"
#include "crypto/cn/CryptoNight.h"
#include "crypto/common/Nonce.h" #include "crypto/common/Nonce.h"
#include "crypto/common/VirtualMemory.h" #include "crypto/common/VirtualMemory.h"
#include "crypto/rx/Rx.h" #include "crypto/rx/Rx.h"
@ -79,6 +80,7 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
m_hwAES(data.hwAES), m_hwAES(data.hwAES),
m_yield(data.yield), m_yield(data.yield),
m_av(data.av()), m_av(data.av()),
m_astrobwtMaxSize(data.astrobwtMaxSize * 1000),
m_miner(data.miner), m_miner(data.miner),
m_ctx() m_ctx()
{ {
@ -240,6 +242,8 @@ void xmrig::CpuWorker<N>::start()
current_job_nonces[i] = *m_job.nonce(i); current_job_nonces[i] = *m_job.nonce(i);
} }
bool valid = true;
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
if (job.algorithm().family() == Algorithm::RANDOM_X) { if (job.algorithm().family() == Algorithm::RANDOM_X) {
if (first) { if (first) {
@ -254,21 +258,32 @@ void xmrig::CpuWorker<N>::start()
randomx_calculate_hash_next(m_vm->get(), tempHash, m_job.blob(), job.size(), m_hash); randomx_calculate_hash_next(m_vm->get(), tempHash, m_job.blob(), job.size(), m_hash);
} }
else else
# endif
{
# ifdef XMRIG_ALGO_ASTROBWT
if (job.algorithm().family() == Algorithm::ASTROBWT) {
if (!astrobwt::astrobwt_dero(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash, m_astrobwtMaxSize))
valid = false;
}
else
# endif # endif
{ {
fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height()); fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height());
}
if (!nextRound(m_job)) { if (!nextRound(m_job)) {
break; break;
}; };
} }
if (valid) {
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < job.target()) { if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < job.target()) {
JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32)); JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32));
} }
} }
m_count += N; m_count += N;
}
if (m_yield) { if (m_yield) {
std::this_thread::yield(); std::this_thread::yield();

View file

@ -73,6 +73,7 @@ private:
const bool m_hwAES; const bool m_hwAES;
const bool m_yield; const bool m_yield;
const CnHash::AlgoVariant m_av; const CnHash::AlgoVariant m_av;
const int m_astrobwtMaxSize;
const Miner *m_miner; const Miner *m_miner;
cryptonight_ctx *m_ctx[N]; cryptonight_ctx *m_ctx[N];
uint8_t m_hash[N * 32]{ 0 }; uint8_t m_hash[N * 32]{ 0 };

View file

@ -38,7 +38,6 @@
namespace xmrig { namespace xmrig {
static const char *kAuthorization = "authorization"; static const char *kAuthorization = "authorization";
static const char *kContentType = "content-type";
#ifdef _WIN32 #ifdef _WIN32
static const char *favicon = nullptr; static const char *favicon = nullptr;
@ -138,7 +137,7 @@ void xmrig::Httpd::onHttpData(const HttpData &data)
# ifdef _WIN32 # ifdef _WIN32
if (favicon != nullptr) { if (favicon != nullptr) {
HttpResponse response(data.id()); HttpResponse response(data.id());
response.setHeader("Content-Type", "image/x-icon"); response.setHeader(HttpData::kContentType, "image/x-icon");
return response.end(favicon, faviconSize); return response.end(favicon, faviconSize);
} }
@ -161,7 +160,7 @@ void xmrig::Httpd::onHttpData(const HttpData &data)
return HttpApiResponse(data.id(), HTTP_STATUS_FORBIDDEN).end(); return HttpApiResponse(data.id(), HTTP_STATUS_FORBIDDEN).end();
} }
if (!data.headers.count(kContentType) || data.headers.at(kContentType) != "application/json") { if (!data.headers.count(HttpData::kContentTypeL) || data.headers.at(HttpData::kContentTypeL) != HttpData::kApplicationJson) {
return HttpApiResponse(data.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end(); return HttpApiResponse(data.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end();
} }
} }

View file

@ -34,6 +34,7 @@ set(HEADERS_BASE
src/base/kernel/Signals.h src/base/kernel/Signals.h
src/base/net/dns/Dns.h src/base/net/dns/Dns.h
src/base/net/dns/DnsRecord.h src/base/net/dns/DnsRecord.h
src/base/net/http/Fetch.h
src/base/net/http/Http.h src/base/net/http/Http.h
src/base/net/http/HttpListener.h src/base/net/http/HttpListener.h
src/base/net/stratum/BaseClient.h src/base/net/stratum/BaseClient.h
@ -80,7 +81,10 @@ set(SOURCES_BASE
src/base/kernel/Signals.cpp src/base/kernel/Signals.cpp
src/base/net/dns/Dns.cpp src/base/net/dns/Dns.cpp
src/base/net/dns/DnsRecord.cpp src/base/net/dns/DnsRecord.cpp
src/base/net/http/Fetch.cpp
src/base/net/http/Http.cpp src/base/net/http/Http.cpp
src/base/net/http/HttpData.cpp
src/base/net/http/HttpListener.cpp
src/base/net/stratum/BaseClient.cpp src/base/net/stratum/BaseClient.cpp
src/base/net/stratum/Client.cpp src/base/net/stratum/Client.cpp
src/base/net/stratum/Job.cpp src/base/net/stratum/Job.cpp

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -27,12 +27,40 @@
#include "rapidjson/document.h" #include "rapidjson/document.h"
void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params) namespace xmrig {
static const char *k2_0 = "2.0";
static const char *kId = "id";
static const char *kJsonRPC = "jsonrpc";
static const char *kMethod = "method";
const char *JsonRequest::kParams = "params";
} // namespace xmrig
rapidjson::Document xmrig::JsonRequest::create(int64_t id, const char *method)
{ {
using namespace rapidjson;
Document doc(kObjectType);
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
doc.AddMember("id", id, allocator); doc.AddMember(StringRef(kId), id, allocator);
doc.AddMember("jsonrpc", "2.0", allocator); doc.AddMember(StringRef(kJsonRPC), StringRef(k2_0), allocator);
doc.AddMember("method", rapidjson::StringRef(method), allocator); doc.AddMember(StringRef(kMethod), StringRef(method), allocator);
doc.AddMember("params", params, allocator);
return doc;
}
void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params)
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
doc.AddMember(StringRef(kId), id, allocator);
doc.AddMember(StringRef(kJsonRPC), StringRef(k2_0), allocator);
doc.AddMember(StringRef(kMethod), StringRef(method), allocator);
doc.AddMember(StringRef(kParams), params, allocator);
} }

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -35,6 +35,9 @@ namespace xmrig {
class JsonRequest class JsonRequest
{ {
public: public:
static const char *kParams;
static rapidjson::Document create(int64_t id, const char *method);
static void create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params); static void create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params);
}; };

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76> * Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -189,7 +189,7 @@ private:
} }
char m_buf[4096]{}; char m_buf[Log::kMaxBufferSize]{};
std::mutex m_mutex; std::mutex m_mutex;
std::vector<ILogBackend*> m_backends; std::vector<ILogBackend*> m_backends;
}; };

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76> * Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -27,6 +27,7 @@
#define XMRIG_LOG_H #define XMRIG_LOG_H
#include <cstddef>
#include <cstdint> #include <cstdint>
@ -52,6 +53,8 @@ public:
DEBUG, // debug-level messages DEBUG, // debug-level messages
}; };
constexpr static size_t kMaxBufferSize = 16384;
static void add(ILogBackend *backend); static void add(ILogBackend *backend);
static void destroy(); static void destroy();
static void print(const char *fmt, ...); static void print(const char *fmt, ...);

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -50,13 +50,14 @@ xmrig::DnsRecord::DnsRecord(const addrinfo *addr) :
sockaddr *xmrig::DnsRecord::addr(uint16_t port) const sockaddr *xmrig::DnsRecord::addr(uint16_t port) const
{ {
if (m_type == A) { if (m_type == A) {
sockaddr_in *addr = new sockaddr_in(); auto addr = new sockaddr_in();
uv_ip4_addr(m_ip.data(), port, addr); uv_ip4_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr); return reinterpret_cast<sockaddr *>(addr);
} }
else if (m_type == AAAA) {
sockaddr_in6 *addr = new sockaddr_in6(); if (m_type == AAAA) {
auto addr = new sockaddr_in6();
uv_ip6_addr(m_ip.data(), port, addr); uv_ip6_addr(m_ip.data(), port, addr);
return reinterpret_cast<sockaddr *>(addr); return reinterpret_cast<sockaddr *>(addr);

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -45,7 +45,7 @@ public:
AAAA AAAA
}; };
inline DnsRecord() : m_type(Unknown) {} DnsRecord() = default;
DnsRecord(const addrinfo *addr); DnsRecord(const addrinfo *addr);
sockaddr *addr(uint16_t port = 0) const; sockaddr *addr(uint16_t port = 0) const;
@ -55,7 +55,7 @@ public:
inline Type type() const { return m_type; } inline Type type() const { return m_type; }
private: private:
Type m_type; Type m_type = Unknown;
String m_ip; String m_ip;
}; };

155
src/base/net/http/Fetch.cpp Normal file
View file

@ -0,0 +1,155 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 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/net/http/Fetch.h"
#include "base/io/log/Log.h"
#include "base/net/http/HttpClient.h"
#include "base/net/stratum/Pool.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#ifdef XMRIG_FEATURE_TLS
# include "base/net/http/HttpsClient.h"
#endif
xmrig::FetchRequest::FetchRequest(http_method method, const String &host, uint16_t port, const String &path, bool tls, bool quiet, const char *data, size_t size, const char *contentType) :
quiet(quiet),
tls(tls),
method(method),
host(host),
path(path),
port(port)
{
assert(port > 0);
setBody(data, size, contentType);
}
xmrig::FetchRequest::FetchRequest(http_method method, const String &host, uint16_t port, const String &path, const rapidjson::Document &doc, bool tls, bool quiet) :
quiet(quiet),
tls(tls),
method(method),
host(host),
path(path),
port(port)
{
assert(port > 0);
setBody(doc);
}
xmrig::FetchRequest::FetchRequest(int method, const Pool &pool, const String &path, bool quiet, const char *data, size_t size, const char *contentType) :
quiet(quiet),
tls(pool.isTLS()),
method(static_cast<http_method>(method)),
fingerprint(pool.fingerprint()),
host(pool.host()),
path(path),
port(pool.port())
{
assert(pool.isValid());
setBody(data, size, contentType);
}
xmrig::FetchRequest::FetchRequest(int method, const Pool &pool, const String &path, const rapidjson::Document &doc, bool quiet) :
quiet(quiet),
tls(pool.isTLS()),
method(static_cast<http_method>(method)),
fingerprint(pool.fingerprint()),
host(pool.host()),
path(path),
port(pool.port())
{
assert(pool.isValid());
setBody(doc);
}
void xmrig::FetchRequest::setBody(const char *data, size_t size, const char *contentType)
{
if (!data) {
return;
}
assert(method != HTTP_GET && method != HTTP_HEAD);
if (method == HTTP_GET || method == HTTP_HEAD) {
return;
}
body = size ? std::string(data, size) : data;
if (contentType) {
headers.insert({ HttpData::kContentType, contentType });
}
}
void xmrig::FetchRequest::setBody(const rapidjson::Document &doc)
{
assert(method != HTTP_GET && method != HTTP_HEAD);
if (method == HTTP_GET || method == HTTP_HEAD) {
return;
}
using namespace rapidjson;
StringBuffer buffer(nullptr, 512);
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
setBody(buffer.GetString(), buffer.GetSize(), HttpData::kApplicationJson.c_str());
}
void xmrig::fetch(FetchRequest &&req, const std::weak_ptr<IHttpListener> &listener, int type)
{
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("http%s://%s:%u ") MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD(" body: ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes"),
req.tls ? "s" : "", req.host.data(), req.port, http_method_str(req.method), req.path.data(), req.body.size());
if (req.hasBody() && req.body.size() < (Log::kMaxBufferSize - 1024) && req.headers.count(HttpData::kContentType) && req.headers.at(HttpData::kContentType) == HttpData::kApplicationJson) {
Log::print(BLUE_BG_BOLD("%s:") BLACK_BOLD_S " %.*s", req.headers.at(HttpData::kContentType).c_str(), static_cast<int>(req.body.size()), req.body.c_str());
}
# endif
HttpClient *client;
# ifdef XMRIG_FEATURE_TLS
if (req.tls) {
client = new HttpsClient(std::move(req), listener);
}
else
# endif
{
client = new HttpClient(std::move(req), listener);
}
client->userType = type;
client->connect();
}

74
src/base/net/http/Fetch.h Normal file
View file

@ -0,0 +1,74 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 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_FETCH_H
#define XMRIG_FETCH_H
#include "3rdparty/http-parser/http_parser.h"
#include "base/tools/String.h"
#include "rapidjson/fwd.h"
#include <map>
#include <memory>
#include <string>
namespace xmrig {
class IHttpListener;
class Pool;
class FetchRequest
{
public:
FetchRequest() = default;
FetchRequest(http_method method, const String &host, uint16_t port, const String &path, bool tls = false, bool quiet = false, const char *data = nullptr, size_t size = 0, const char *contentType = nullptr);
FetchRequest(http_method method, const String &host, uint16_t port, const String &path, const rapidjson::Document &doc, bool tls = false, bool quiet = false);
FetchRequest(int method, const Pool &pool, const String &path, bool quiet = false, const char *data = nullptr, size_t size = 0, const char *contentType = nullptr);
FetchRequest(int method, const Pool &pool, const String &path, const rapidjson::Document &doc, bool quiet = false);
void setBody(const char *data, size_t size, const char *contentType = nullptr);
void setBody(const rapidjson::Document &doc);
inline bool hasBody() const { return method != HTTP_GET && method != HTTP_HEAD && !body.empty(); }
bool quiet = false;
bool tls = false;
http_method method = HTTP_GET;
std::map<const std::string, const std::string> headers;
std::string body;
String fingerprint;
String host;
String path;
uint16_t port = 0;
};
void fetch(FetchRequest &&req, const std::weak_ptr<IHttpListener> &listener, int type = 0);
} // namespace xmrig
#endif // XMRIG_FETCH_H

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,8 +24,9 @@
*/ */
#include "3rdparty/http-parser/http_parser.h"
#include "base/net/http/HttpApiResponse.h" #include "base/net/http/HttpApiResponse.h"
#include "3rdparty/http-parser/http_parser.h"
#include "base/net/http/HttpData.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h" #include "rapidjson/stringbuffer.h"
@ -75,7 +76,7 @@ void xmrig::HttpApiResponse::end()
return HttpResponse::end(); return HttpResponse::end();
} }
setHeader("Content-Type", "application/json"); setHeader(HttpData::kContentType, HttpData::kApplicationJson);
StringBuffer buffer(nullptr, 4096); StringBuffer buffer(nullptr, 4096);
PrettyWriter<StringBuffer> writer(buffer); PrettyWriter<StringBuffer> writer(buffer);

View file

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

View file

@ -24,69 +24,59 @@
*/ */
#include <sstream> #include "base/net/http/HttpClient.h"
#include "3rdparty/http-parser/http_parser.h" #include "3rdparty/http-parser/http_parser.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "base/kernel/Platform.h" #include "base/kernel/Platform.h"
#include "base/net/dns/Dns.h" #include "base/net/dns/Dns.h"
#include "base/net/http/HttpClient.h"
#include "base/tools/Baton.h" #include "base/tools/Baton.h"
#include <sstream>
namespace xmrig { namespace xmrig {
static const char *kCRLF = "\r\n"; static const char *kCRLF = "\r\n";
class ClientWriteBaton : public Baton<uv_write_t> class HttpClientWriteBaton : public Baton<uv_write_t>
{ {
public: public:
inline ClientWriteBaton(const std::string &header, std::string &&body) : inline HttpClientWriteBaton(const std::string &header, std::string &&body) :
m_body(std::move(body)), m_body(std::move(body)),
m_header(header) m_header(header)
{ {
bufs[0].len = m_header.size(); m_bufs[0] = uv_buf_init(const_cast<char *>(m_header.c_str()), m_header.size());
bufs[0].base = const_cast<char *>(m_header.c_str()); m_bufs[1] = m_body.empty() ? uv_buf_init(nullptr, 0) : uv_buf_init(const_cast<char *>(m_body.c_str()), m_body.size());
if (!m_body.empty()) {
bufs[1].len = m_body.size();
bufs[1].base = const_cast<char *>(m_body.c_str());
}
else {
bufs[1].base = nullptr;
bufs[1].len = 0;
}
} }
void write(uv_stream_t *stream)
inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; } {
inline size_t size() const { return bufs[0].len + bufs[1].len; } uv_write(&req, stream, m_bufs, nbufs(), [](uv_write_t *req, int) { delete reinterpret_cast<HttpClientWriteBaton *>(req->data); });
inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast<ClientWriteBaton *>(req->data); } }
uv_buf_t bufs[2]{};
private: private:
inline size_t nbufs() const { return m_bufs[1].len > 0 ? 2 : 1; }
std::string m_body; std::string m_body;
std::string m_header; std::string m_header;
uv_buf_t m_bufs[2]{};
}; };
} // namespace xmrig } // namespace xmrig
xmrig::HttpClient::HttpClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data, size_t size) : xmrig::HttpClient::HttpClient(FetchRequest &&req, const std::weak_ptr<IHttpListener> &listener) :
HttpContext(HTTP_RESPONSE, listener) HttpContext(HTTP_RESPONSE, listener),
m_req(std::move(req))
{ {
this->method = method; method = m_req.method;
this->url = url; url = std::move(m_req.path);
body = std::move(m_req.body);
if (data) { headers = std::move(m_req.headers);
body = size ? std::string(data, size) : data;
}
m_dns = new Dns(this); m_dns = new Dns(this);
} }
@ -97,17 +87,9 @@ xmrig::HttpClient::~HttpClient()
} }
bool xmrig::HttpClient::connect(const String &host, uint16_t port) bool xmrig::HttpClient::connect()
{ {
m_port = port; return m_dns->resolve(m_req.host);
return m_dns->resolve(host);
}
const xmrig::String &xmrig::HttpClient::host() const
{
return m_dns->host();
} }
@ -116,25 +98,27 @@ void xmrig::HttpClient::onResolved(const Dns &dns, int status)
this->status = status; this->status = status;
if (status < 0 && dns.isEmpty()) { if (status < 0 && dns.isEmpty()) {
if (!m_quiet) { if (!isQuiet()) {
LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), m_port, uv_strerror(status)); LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), port(), uv_strerror(status));
} }
return; return;
} }
sockaddr *addr = dns.get().addr(m_port); sockaddr *addr = dns.get().addr(port());
auto req = new uv_connect_t; auto req = new uv_connect_t;
req->data = this; req->data = this;
uv_tcp_connect(req, m_tcp, addr, onConnect); uv_tcp_connect(req, m_tcp, addr, onConnect);
delete addr;
} }
void xmrig::HttpClient::handshake() void xmrig::HttpClient::handshake()
{ {
headers.insert({ "Host", m_dns->host().data() }); headers.insert({ "Host", host() });
headers.insert({ "Connection", "close" }); headers.insert({ "Connection", "close" });
headers.insert({ "User-Agent", Platform::userAgent() }); headers.insert({ "User-Agent", Platform::userAgent() });
@ -167,8 +151,8 @@ void xmrig::HttpClient::read(const char *data, size_t size)
void xmrig::HttpClient::write(const std::string &header) void xmrig::HttpClient::write(const std::string &header)
{ {
auto baton = new ClientWriteBaton(header, std::move(body)); auto baton = new HttpClientWriteBaton(header, std::move(body));
uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite); baton->write(stream());
} }
@ -181,8 +165,8 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
} }
if (status < 0) { if (status < 0) {
if (!client->m_quiet) { if (!client->isQuiet()) {
LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(status)); LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->port(), uv_strerror(status));
} }
delete req; delete req;
@ -194,12 +178,7 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
[](uv_handle_t *, size_t suggested_size, uv_buf_t *buf) [](uv_handle_t *, size_t suggested_size, uv_buf_t *buf)
{ {
buf->base = new char[suggested_size]; buf->base = new char[suggested_size];
# ifdef _WIN32
buf->len = static_cast<unsigned int>(suggested_size);
# else
buf->len = suggested_size; buf->len = suggested_size;
# endif
}, },
[](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) [](uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf)
{ {
@ -208,8 +187,8 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status)
if (nread >= 0) { if (nread >= 0) {
client->read(buf->base, static_cast<size_t>(nread)); client->read(buf->base, static_cast<size_t>(nread));
} else { } else {
if (!client->m_quiet && nread != UV_EOF) { if (!client->isQuiet() && nread != UV_EOF) {
LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(static_cast<int>(nread))); LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->port(), uv_strerror(static_cast<int>(nread)));
} }
client->close(static_cast<int>(nread)); client->close(static_cast<int>(nread));

View file

@ -28,8 +28,9 @@
#define XMRIG_HTTPCLIENT_H #define XMRIG_HTTPCLIENT_H
#include "base/net/http/HttpContext.h"
#include "base/kernel/interfaces/IDnsListener.h" #include "base/kernel/interfaces/IDnsListener.h"
#include "base/net/http/Fetch.h"
#include "base/net/http/HttpContext.h"
#include "base/tools/Object.h" #include "base/tools/Object.h"
@ -44,14 +45,14 @@ class HttpClient : public HttpContext, public IDnsListener
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpClient); XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpClient);
HttpClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data = nullptr, size_t size = 0); HttpClient(FetchRequest &&req, const std::weak_ptr<IHttpListener> &listener);
~HttpClient() override; ~HttpClient() override;
inline uint16_t port() const { return m_port; } inline bool isQuiet() const { return m_req.quiet; }
inline void setQuiet(bool quiet) { m_quiet = quiet; } inline const char *host() const override { return m_req.host; }
inline uint16_t port() const override { return m_req.port; }
bool connect(const String &host, uint16_t port); bool connect();
const String &host() const;
protected: protected:
void onResolved(const Dns &dns, int status) override; void onResolved(const Dns &dns, int status) override;
@ -60,13 +61,14 @@ protected:
virtual void read(const char *data, size_t size); virtual void read(const char *data, size_t size);
virtual void write(const std::string &header); virtual void write(const std::string &header);
bool m_quiet = false; protected:
inline const FetchRequest &req() const { return m_req; }
private: private:
static void onConnect(uv_connect_t *req, int status); static void onConnect(uv_connect_t *req, int status);
Dns *m_dns; Dns *m_dns;
uint16_t m_port = 0; FetchRequest m_req;
}; };

View file

@ -75,6 +75,12 @@ xmrig::HttpContext::~HttpContext()
} }
bool xmrig::HttpContext::isRequest() const
{
return m_parser->type == HTTP_REQUEST;
}
size_t xmrig::HttpContext::parse(const char *data, size_t size) size_t xmrig::HttpContext::parse(const char *data, size_t size)
{ {
return http_parser_execute(m_parser, &http_settings, data, size); return http_parser_execute(m_parser, &http_settings, data, size);

View file

@ -55,13 +55,19 @@ public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpContext) XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpContext)
HttpContext(int parser_type, const std::weak_ptr<IHttpListener> &listener); HttpContext(int parser_type, const std::weak_ptr<IHttpListener> &listener);
virtual ~HttpContext(); ~HttpContext() override;
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_tcp); } inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_tcp); }
inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(m_tcp); } inline uv_handle_t *handle() const { return reinterpret_cast<uv_handle_t *>(m_tcp); }
inline const char *host() const override { return nullptr; }
inline const char *tlsFingerprint() const override { return nullptr; }
inline const char *tlsVersion() const override { return nullptr; }
inline uint16_t port() const override { return 0; }
bool isRequest() const override;
size_t parse(const char *data, size_t size); size_t parse(const char *data, size_t size);
std::string ip() const; std::string ip() const override;
uint64_t elapsed() const; uint64_t elapsed() const;
void close(int status = 0); void close(int status = 0);

View file

@ -0,0 +1,31 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 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/net/http/HttpData.h"
namespace xmrig {
const std::string HttpData::kApplicationJson = "application/json";
const std::string HttpData::kContentType = "Content-Type";
const std::string HttpData::kContentTypeL = "content-type";
} // namespace xmrig

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -28,6 +28,9 @@
#define XMRIG_HTTPDATA_H #define XMRIG_HTTPDATA_H
#include "base/tools/Object.h"
#include <map> #include <map>
#include <string> #include <string>
@ -38,12 +41,28 @@ namespace xmrig {
class HttpData class HttpData
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpData)
static const std::string kApplicationJson;
static const std::string kContentType;
static const std::string kContentTypeL;
inline HttpData(uint64_t id) : m_id(id) {} inline HttpData(uint64_t id) : m_id(id) {}
virtual ~HttpData() = default;
inline uint64_t id() const { return m_id; } inline uint64_t id() const { return m_id; }
virtual bool isRequest() const = 0;
virtual const char *host() const = 0;
virtual const char *tlsFingerprint() const = 0;
virtual const char *tlsVersion() const = 0;
virtual std::string ip() const = 0;
virtual uint16_t port() const = 0;
int method = 0; int method = 0;
int status = 0; int status = 0;
int userType = 0;
std::map<const std::string, const std::string> headers; std::map<const std::string, const std::string> headers;
std::string body; std::string body;
std::string url; std::string url;

View file

@ -0,0 +1,41 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 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/net/http/HttpListener.h"
#include "3rdparty/http-parser/http_parser.h"
#include "base/io/log/Log.h"
#include "base/net/http/HttpData.h"
void xmrig::HttpListener::onHttpData(const HttpData &data)
{
# ifdef APP_DEBUG
if (!data.isRequest()) {
LOG_DEBUG(CYAN("http%s://%s:%u ") MAGENTA_BOLD("\"%s %s\" ") CSI "1;%dm%d" CLEAR BLACK_BOLD(" received: ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes"),
data.tlsVersion() ? "s" : "", data.host(), data.port(), http_method_str(static_cast<http_method>(data.method)), data.url.data(),
data.status >= 400 ? 31 : 32, data.status, data.body.size());
if (data.body.size() < (Log::kMaxBufferSize - 1024) && data.headers.count(HttpData::kContentTypeL) && data.headers.at(HttpData::kContentTypeL) == HttpData::kApplicationJson) {
Log::print(BLUE_BG_BOLD("%s:") BLACK_BOLD_S " %.*s", data.headers.at(HttpData::kContentTypeL).c_str(), static_cast<int>(data.body.size()), data.body.c_str());
}
}
# endif
m_listener->onHttpData(data);
}

View file

@ -32,7 +32,7 @@ public:
inline HttpListener(IHttpListener *listener) : m_listener(listener) {} inline HttpListener(IHttpListener *listener) : m_listener(listener) {}
protected: protected:
inline void onHttpData(const HttpData &data) override { m_listener->onHttpData(data); }; void onHttpData(const HttpData &data) override;
private: private:
IHttpListener *m_listener; IHttpListener *m_listener;

View file

@ -29,8 +29,8 @@
#include <uv.h> #include <uv.h>
#include "base/io/log/Log.h"
#include "base/net/http/HttpsClient.h" #include "base/net/http/HttpsClient.h"
#include "base/io/log/Log.h"
#include "base/tools/Buffer.h" #include "base/tools/Buffer.h"
@ -39,12 +39,8 @@
#endif #endif
xmrig::HttpsClient::HttpsClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data, size_t size, const String &fingerprint) : xmrig::HttpsClient::HttpsClient(FetchRequest &&req, const std::weak_ptr<IHttpListener> &listener) :
HttpClient(method, url, listener, data, size), HttpClient(std::move(req), listener)
m_ready(false),
m_buf(),
m_ssl(nullptr),
m_fp(fingerprint)
{ {
m_ctx = SSL_CTX_new(SSLv23_method()); m_ctx = SSL_CTX_new(SSLv23_method());
assert(m_ctx != nullptr); assert(m_ctx != nullptr);
@ -71,13 +67,13 @@ xmrig::HttpsClient::~HttpsClient()
} }
const char *xmrig::HttpsClient::fingerprint() const const char *xmrig::HttpsClient::tlsFingerprint() const
{ {
return m_ready ? m_fingerprint : nullptr; return m_ready ? m_fingerprint : nullptr;
} }
const char *xmrig::HttpsClient::version() const const char *xmrig::HttpsClient::tlsVersion() const
{ {
return m_ready ? SSL_get_version(m_ssl) : nullptr; return m_ready ? SSL_get_version(m_ssl) : nullptr;
} }
@ -94,7 +90,7 @@ void xmrig::HttpsClient::handshake()
SSL_set_connect_state(m_ssl); SSL_set_connect_state(m_ssl);
SSL_set_bio(m_ssl, m_readBio, m_writeBio); SSL_set_bio(m_ssl, m_readBio, m_writeBio);
SSL_set_tlsext_host_name(m_ssl, host().data()); SSL_set_tlsext_host_name(m_ssl, host());
SSL_do_handshake(m_ssl); SSL_do_handshake(m_ssl);
@ -150,12 +146,12 @@ bool xmrig::HttpsClient::verify(X509 *cert)
} }
if (!verifyFingerprint(cert)) { if (!verifyFingerprint(cert)) {
if (!m_quiet) { if (!isQuiet()) {
LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port()); LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host(), port());
if (strlen(m_fingerprint) == 64 && !m_fp.isNull()) { if (strlen(m_fingerprint) == 64 && !req().fingerprint.isNull()) {
LOG_ERR("\"%s\" was given", m_fingerprint); LOG_ERR("\"%s\" was given", m_fingerprint);
LOG_ERR("\"%s\" was configured", m_fp.data()); LOG_ERR("\"%s\" was configured", req().fingerprint.data());
} }
} }
@ -182,7 +178,7 @@ bool xmrig::HttpsClient::verifyFingerprint(X509 *cert)
Buffer::toHex(md, 32, m_fingerprint); Buffer::toHex(md, 32, m_fingerprint);
return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0; return req().fingerprint.isNull() || strncasecmp(m_fingerprint, req().fingerprint.data(), 64) == 0;
} }

View file

@ -46,11 +46,11 @@ class HttpsClient : public HttpClient
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsClient) XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsClient)
HttpsClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data, size_t size, const String &fingerprint); HttpsClient(FetchRequest &&req, const std::weak_ptr<IHttpListener> &listener);
~HttpsClient() override; ~HttpsClient() override;
const char *fingerprint() const; const char *tlsFingerprint() const override;
const char *version() const; const char *tlsVersion() const override;
protected: protected:
void handshake() override; void handshake() override;
@ -62,14 +62,13 @@ private:
bool verifyFingerprint(X509 *cert); bool verifyFingerprint(X509 *cert);
void flush(); void flush();
BIO *m_readBio; BIO *m_readBio = nullptr;
BIO *m_writeBio; BIO *m_writeBio = nullptr;
bool m_ready; bool m_ready = false;
char m_buf[1024 * 2]; char m_buf[1024 * 2]{};
char m_fingerprint[32 * 2 + 8]; char m_fingerprint[32 * 2 + 8]{};
SSL *m_ssl; SSL *m_ssl = nullptr;
SSL_CTX *m_ctx; SSL_CTX *m_ctx = nullptr;
String m_fp;
}; };

View file

@ -30,20 +30,14 @@
#include "base/io/json/JsonRequest.h" #include "base/io/json/JsonRequest.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "base/kernel/interfaces/IClientListener.h" #include "base/kernel/interfaces/IClientListener.h"
#include "base/net/http/HttpClient.h" #include "base/net/http/Fetch.h"
#include "base/net/http/HttpData.h"
#include "base/net/stratum/SubmitResult.h" #include "base/net/stratum/SubmitResult.h"
#include "base/tools/Buffer.h" #include "base/tools/Buffer.h"
#include "base/tools/Timer.h" #include "base/tools/Timer.h"
#include "net/JobResult.h" #include "net/JobResult.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#ifdef XMRIG_FEATURE_TLS
# include "base/net/http/HttpsClient.h"
#endif
#include <algorithm> #include <algorithm>
@ -65,8 +59,7 @@ static const size_t BlobReserveSize = 8;
xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) : xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) :
BaseClient(id, listener), BaseClient(id, listener)
m_apiVersion(API_MONERO)
{ {
m_httpListener = std::make_shared<HttpListener>(this); m_httpListener = std::make_shared<HttpListener>(this);
m_timer = new Timer(this); m_timer = new Timer(this);
@ -133,9 +126,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend); m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend);
# endif # endif
send(HTTP_POST, kJsonRPC, doc); return rpcSend(doc);
return m_sequence++;
} }
@ -163,15 +154,11 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data)
return retry(); return retry();
} }
LOG_DEBUG("[%s:%d] received (%d bytes): \"%.*s\"", m_pool.host().data(), m_pool.port(), static_cast<int>(data.body.size()), static_cast<int>(data.body.size()), data.body.c_str()); m_ip = data.ip().c_str();
m_ip = static_cast<const HttpContext &>(data).ip().c_str();
# ifdef XMRIG_FEATURE_TLS # ifdef XMRIG_FEATURE_TLS
if (isTLS()) { m_tlsVersion = data.tlsVersion();
m_tlsVersion = static_cast<const HttpsClient &>(data).version(); m_tlsFingerprint = data.tlsFingerprint();
m_tlsFingerprint = static_cast<const HttpsClient &>(data).fingerprint();
}
# endif # endif
rapidjson::Document doc; rapidjson::Document doc;
@ -188,7 +175,7 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data)
if (!doc.HasMember(kHash)) { if (!doc.HasMember(kHash)) {
m_apiVersion = API_CRYPTONOTE_DEFAULT; m_apiVersion = API_CRYPTONOTE_DEFAULT;
return send(HTTP_GET, kGetInfo); return send(kGetInfo);
} }
if (isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, kHash))) { if (isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, kHash))) {
@ -215,19 +202,10 @@ void xmrig::DaemonClient::onTimer(const Timer *)
} }
else if (m_state == ConnectedState) { else if (m_state == ConnectedState) {
if (m_apiVersion == API_DERO) { if (m_apiVersion == API_DERO) {
using namespace rapidjson; rpcSend(JsonRequest::create(m_sequence, "get_info"));
Document doc(kObjectType);
auto& allocator = doc.GetAllocator();
doc.AddMember("id", m_sequence, allocator);
doc.AddMember("jsonrpc", "2.0", allocator);
doc.AddMember("method", "get_info", allocator);
send(HTTP_POST, kJsonRPC, doc);
++m_sequence;
} }
else { else {
send(HTTP_GET, (m_apiVersion == API_MONERO) ? kGetHeight : kGetInfo); send((m_apiVersion == API_MONERO) ? kGetHeight : kGetInfo);
} }
} }
} }
@ -336,7 +314,7 @@ int64_t xmrig::DaemonClient::getBlockTemplate()
Value params(kObjectType); Value params(kObjectType);
params.AddMember("wallet_address", m_user.toJSON(), allocator); params.AddMember("wallet_address", m_user.toJSON(), allocator);
if (m_apiVersion == API_DERO) { if (m_apiVersion == API_DERO) {
params.AddMember("reserve_size", BlobReserveSize, allocator); params.AddMember("reserve_size", static_cast<uint64_t>(BlobReserveSize), allocator);
} }
else { else {
params.AddMember("extra_nonce", Buffer::randomBytes(BlobReserveSize).toHex().toJSON(doc), allocator); params.AddMember("extra_nonce", Buffer::randomBytes(BlobReserveSize).toHex().toJSON(doc), allocator);
@ -344,7 +322,14 @@ int64_t xmrig::DaemonClient::getBlockTemplate()
JsonRequest::create(doc, m_sequence, "getblocktemplate", params); JsonRequest::create(doc, m_sequence, "getblocktemplate", params);
send(HTTP_POST, kJsonRPC, doc); return rpcSend(doc);
}
int64_t xmrig::DaemonClient::rpcSend(const rapidjson::Document &doc)
{
FetchRequest req(HTTP_POST, m_pool, kJsonRPC, doc, isQuiet());
fetch(std::move(req), m_httpListener);
return m_sequence++; return m_sequence++;
} }
@ -368,46 +353,10 @@ void xmrig::DaemonClient::retry()
} }
void xmrig::DaemonClient::send(int method, const char *url, const char *data, size_t size) void xmrig::DaemonClient::send(const char *path)
{ {
LOG_DEBUG("[%s:%d] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"", FetchRequest req(HTTP_GET, m_pool, path, isQuiet());
m_pool.host().data(), fetch(std::move(req), m_httpListener);
m_pool.port(),
http_method_str(static_cast<http_method>(method)),
url,
size,
static_cast<int>(size),
data);
HttpClient *client;
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isTLS()) {
client = new HttpsClient(method, url, m_httpListener, data, size, m_pool.fingerprint());
}
else
# endif
{
client = new HttpClient(method, url, m_httpListener, data, size);
}
client->setQuiet(isQuiet());
client->connect(m_pool.host(), m_pool.port());
if (method != HTTP_GET) {
client->headers.insert({ "Content-Type", "application/json" });
}
}
void xmrig::DaemonClient::send(int method, const char *url, const rapidjson::Document &doc)
{
using namespace rapidjson;
StringBuffer buffer(nullptr, 512);
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
send(method, url, buffer.GetString(), buffer.GetSize());
} }

View file

@ -71,16 +71,16 @@ private:
bool parseJob(const rapidjson::Value &params, int *code); bool parseJob(const rapidjson::Value &params, int *code);
bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
int64_t getBlockTemplate(); int64_t getBlockTemplate();
int64_t rpcSend(const rapidjson::Document &doc);
void retry(); void retry();
void send(int method, const char *url, const char *data = nullptr, size_t size = 0); void send(const char *path);
void send(int method, const char *url, const rapidjson::Document &doc);
void setState(SocketState state); void setState(SocketState state);
enum { enum {
API_CRYPTONOTE_DEFAULT, API_CRYPTONOTE_DEFAULT,
API_MONERO, API_MONERO,
API_DERO, API_DERO,
} m_apiVersion; } m_apiVersion = API_MONERO;
std::shared_ptr<IHttpListener> m_httpListener; std::shared_ptr<IHttpListener> m_httpListener;
String m_blocktemplate; String m_blocktemplate;

View file

@ -29,17 +29,11 @@
#include "base/io/json/Json.h" #include "base/io/json/Json.h"
#include "base/io/json/JsonRequest.h" #include "base/io/json/JsonRequest.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "base/net/http/HttpClient.h" #include "base/net/http/Fetch.h"
#include "base/net/http/HttpData.h"
#include "base/net/stratum/Client.h" #include "base/net/stratum/Client.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#ifdef XMRIG_FEATURE_TLS
# include "base/net/http/HttpsClient.h"
#endif
namespace xmrig { namespace xmrig {
@ -159,7 +153,8 @@ void xmrig::SelfSelectClient::getBlockTemplate()
JsonRequest::create(doc, m_sequence++, "getblocktemplate", params); JsonRequest::create(doc, m_sequence++, "getblocktemplate", params);
send(HTTP_POST, "/json_rpc", doc); FetchRequest req(HTTP_POST, pool().daemon().host(), pool().daemon().port(), "/json_rpc", doc, pool().daemon().isTLS(), isQuiet());
fetch(std::move(req), m_httpListener);
} }
@ -169,44 +164,6 @@ void xmrig::SelfSelectClient::retry()
} }
void xmrig::SelfSelectClient::send(int method, const char *url, const char *data, size_t size)
{
LOG_DEBUG("[%s] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"",
pool().daemon().url().data(),
http_method_str(static_cast<http_method>(method)),
url,
size,
static_cast<int>(size),
data);
HttpClient *client;
# ifdef XMRIG_FEATURE_TLS
if (pool().daemon().isTLS()) {
client = new HttpsClient(method, url, m_httpListener, data, size, String());
}
else
# endif
{
client = new HttpClient(method, url, m_httpListener, data, size);
}
client->setQuiet(isQuiet());
client->connect(pool().daemon().host(), pool().daemon().port());
}
void xmrig::SelfSelectClient::send(int method, const char *url, const rapidjson::Document &doc)
{
using namespace rapidjson;
StringBuffer buffer(nullptr, 512);
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
send(method, url, buffer.GetString(), buffer.GetSize());
}
void xmrig::SelfSelectClient::setState(State state) void xmrig::SelfSelectClient::setState(State state)
{ {
if (m_state == state) { if (m_state == state) {
@ -256,7 +213,7 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result)
JsonRequest::create(doc, sequence(), "block_template", params); JsonRequest::create(doc, sequence(), "block_template", params);
send(doc, [this](const rapidjson::Value &result, bool success, uint64_t elapsed) { send(doc, [this](const rapidjson::Value &result, bool success, uint64_t) {
if (!success) { if (!success) {
if (!isQuiet()) { if (!isQuiet()) {
LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().url().data(), Json::getString(result, "message"), Json::getInt(result, "code")); LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", pool().daemon().url().data(), Json::getString(result, "message"), Json::getInt(result, "code"));
@ -285,8 +242,6 @@ void xmrig::SelfSelectClient::onHttpData(const HttpData &data)
return retry(); return retry();
} }
LOG_DEBUG("[%s] received (%d bytes): \"%.*s\"", pool().daemon().url().data(), static_cast<int>(data.body.size()), static_cast<int>(data.body.size()), data.body.c_str());
rapidjson::Document doc; rapidjson::Document doc;
if (doc.Parse(data.body.c_str()).HasParseError()) { if (doc.Parse(data.body.c_str()).HasParseError()) {
if (!isQuiet()) { if (!isQuiet()) {

View file

@ -102,8 +102,6 @@ private:
bool parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error); bool parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error);
void getBlockTemplate(); void getBlockTemplate();
void retry(); void retry();
void send(int method, const char *url, const char *data = nullptr, size_t size = 0);
void send(int method, const char *url, const rapidjson::Document &doc);
void setState(State state); void setState(State state);
void submitBlockTemplate(rapidjson::Value &result); void submitBlockTemplate(rapidjson::Value &result);

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh> * Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@
#define XMRIG_STORAGE_H #define XMRIG_STORAGE_H
#include <assert.h> #include <cassert>
#include <map> #include <map>
@ -37,10 +37,7 @@ template <class TYPE>
class Storage class Storage
{ {
public: public:
inline Storage() : inline Storage() = default;
m_counter(0)
{
}
inline uintptr_t add(TYPE *ptr) inline uintptr_t add(TYPE *ptr)
@ -87,7 +84,7 @@ public:
private: private:
std::map<uintptr_t, TYPE *> m_data; std::map<uintptr_t, TYPE *> m_data;
uint64_t m_counter; uint64_t m_counter = 0;
}; };

View file

@ -31,6 +31,7 @@
"max-threads-hint": 100, "max-threads-hint": 100,
"asm": true, "asm": true,
"argon2-impl": null, "argon2-impl": null,
"astrobwt-max-size": 550,
"cn/0": false, "cn/0": false,
"cn-lite/0": false "cn-lite/0": false
}, },

View file

@ -63,6 +63,7 @@ R"===(
"max-threads-hint": 100, "max-threads-hint": 100,
"asm": true, "asm": true,
"argon2-impl": null, "argon2-impl": null,
"astrobwt-max-size": 550,
"cn/0": false, "cn/0": false,
"cn-lite/0": false "cn-lite/0": false
}, },

View file

@ -30,6 +30,7 @@
#include "AstroBWT.h" #include "AstroBWT.h"
#include "sha3.h" #include "sha3.h"
#include "crypto/cn/CryptoNight.h" #include "crypto/cn/CryptoNight.h"
#include <limits>
constexpr int STAGE1_SIZE = 147253; constexpr int STAGE1_SIZE = 147253;
constexpr int ALLOCATION_SIZE = (STAGE1_SIZE + 1048576) + (128 - (STAGE1_SIZE & 63)); constexpr int ALLOCATION_SIZE = (STAGE1_SIZE + 1048576) + (128 - (STAGE1_SIZE & 63));
@ -152,7 +153,7 @@ void sort_indices(int N, const uint8_t* v, uint64_t* indices, uint64_t* tmp_indi
} }
} }
void astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash) bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size)
{ {
uint8_t key[32]; uint8_t key[32];
uint8_t* scratchpad_ptr = (uint8_t*)(scratchpad) + 64; uint8_t* scratchpad_ptr = (uint8_t*)(scratchpad) + 64;
@ -178,6 +179,9 @@ void astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad
sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage1_result, STAGE1_SIZE + 1, key, sizeof(key)); sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage1_result, STAGE1_SIZE + 1, key, sizeof(key));
const int stage2_size = STAGE1_SIZE + (*(uint32_t*)(key) & 0xfffff); const int stage2_size = STAGE1_SIZE + (*(uint32_t*)(key) & 0xfffff);
if (stage2_size > stage2_max_size)
return false;
Salsa20_XORKeyStream(key, stage2_output, stage2_size); Salsa20_XORKeyStream(key, stage2_output, stage2_size);
sort_indices(stage2_size + 1, stage2_output, indices, tmp_indices); sort_indices(stage2_size + 1, stage2_output, indices, tmp_indices);
@ -198,10 +202,12 @@ void astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad
} }
sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage2_result, stage2_size + 1, output_hash, 32); sha3_HashBuffer(256, SHA3_FLAGS_NONE, stage2_result, stage2_size + 1, output_hash, 32);
return true;
} }
template<> template<>
void xmrig::astrobwt::single_hash<xmrig::Algorithm::ASTROBWT_DERO>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t) void xmrig::astrobwt::single_hash<xmrig::Algorithm::ASTROBWT_DERO>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t)
{ {
astrobwt_dero(input, static_cast<uint32_t>(size), ctx[0]->memory, output); astrobwt_dero(input, static_cast<uint32_t>(size), ctx[0]->memory, output, std::numeric_limits<int>::max());
} }

View file

@ -34,6 +34,7 @@ struct cryptonight_ctx;
namespace xmrig { namespace astrobwt { namespace xmrig { namespace astrobwt {
bool astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size);
template<Algorithm::Id ALGO> template<Algorithm::Id ALGO>
void single_hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t); void single_hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t);

View file

@ -28,7 +28,7 @@
#define APP_ID "xmrig" #define APP_ID "xmrig"
#define APP_NAME "XMRig" #define APP_NAME "XMRig"
#define APP_DESC "XMRig miner" #define APP_DESC "XMRig miner"
#define APP_VERSION "5.8.1" #define APP_VERSION "5.8.2-dev"
#define APP_DOMAIN "xmrig.com" #define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com" #define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2020 xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2020 xmrig.com"
@ -36,7 +36,7 @@
#define APP_VER_MAJOR 5 #define APP_VER_MAJOR 5
#define APP_VER_MINOR 8 #define APP_VER_MINOR 8
#define APP_VER_PATCH 1 #define APP_VER_PATCH 2
#ifdef _MSC_VER #ifdef _MSC_VER
# if (_MSC_VER >= 1920) # if (_MSC_VER >= 1920)