From 34306b11803bcaaae077d51ab0a89a5a6b99e06d Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 4 Mar 2020 12:30:28 +0700 Subject: [PATCH 1/4] v5.8.2-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 30c21b9d1..788bed782 100644 --- a/src/version.h +++ b/src/version.h @@ -28,7 +28,7 @@ #define APP_ID "xmrig-proxy" #define APP_NAME "xmrig-proxy" #define APP_DESC "XMRig Stratum proxy" -#define APP_VERSION "5.8.1" +#define APP_VERSION "5.8.2-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2020 xmrig.com" @@ -36,7 +36,7 @@ #define APP_VER_MAJOR 5 #define APP_VER_MINOR 8 -#define APP_VER_PATCH 1 +#define APP_VER_PATCH 2 #ifdef _MSC_VER # if (_MSC_VER >= 1920) From bd828a8d2e7ff113e6285d061a4237bdb92f3caa Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 8 Mar 2020 01:48:26 +0700 Subject: [PATCH 2/4] Added new rx/keva algorithm for upcoming Kevacoin fork. --- CHANGELOG.md | 3 + src/base/api/Httpd.cpp | 5 +- src/base/base.cmake | 4 + src/base/io/json/JsonRequest.cpp | 40 +++++- src/base/io/json/JsonRequest.h | 7 +- src/base/io/log/Log.cpp | 6 +- src/base/io/log/Log.h | 7 +- src/base/kernel/interfaces/IConfig.h | 1 + src/base/net/dns/DnsRecord.cpp | 11 +- src/base/net/dns/DnsRecord.h | 8 +- src/base/net/http/Fetch.cpp | 155 ++++++++++++++++++++++ src/base/net/http/Fetch.h | 74 +++++++++++ src/base/net/http/HttpApiResponse.cpp | 9 +- src/base/net/http/HttpApiResponse.h | 4 +- src/base/net/http/HttpClient.cpp | 99 ++++++-------- src/base/net/http/HttpClient.h | 18 +-- src/base/net/http/HttpContext.cpp | 6 + src/base/net/http/HttpContext.h | 10 +- src/base/net/http/HttpData.cpp | 31 +++++ src/base/net/http/HttpData.h | 27 +++- src/base/net/http/HttpListener.cpp | 41 ++++++ src/base/net/http/HttpListener.h | 2 +- src/base/net/http/HttpsClient.cpp | 26 ++-- src/base/net/http/HttpsClient.h | 21 ++- src/base/net/stratum/DaemonClient.cpp | 95 +++---------- src/base/net/stratum/DaemonClient.h | 6 +- src/base/net/stratum/SelfSelectClient.cpp | 55 +------- src/base/net/stratum/SelfSelectClient.h | 2 - src/base/net/tools/Storage.h | 13 +- src/crypto/common/Algorithm.cpp | 7 +- src/crypto/common/Algorithm.h | 1 + src/crypto/common/Coin.cpp | 4 + src/crypto/common/Coin.h | 3 +- src/version.h | 6 +- 34 files changed, 534 insertions(+), 273 deletions(-) create mode 100644 src/base/net/http/Fetch.cpp create mode 100644 src/base/net/http/Fetch.h create mode 100644 src/base/net/http/HttpData.cpp create mode 100644 src/base/net/http/HttpListener.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 45a603546..5bffece7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# v5.9.0 +- [#1578](https://github.com/xmrig/xmrig/pull/1578) Added new RandomKEVA algorithm for upcoming Kevacoin fork, as `"algo": "rx/keva"` or `"coin": "keva"`. + # v5.8.1 - [#1575](https://github.com/xmrig/xmrig/pull/1575) Fixed new block detection for DERO solo mining. diff --git a/src/base/api/Httpd.cpp b/src/base/api/Httpd.cpp index 36f046164..37db1ad67 100644 --- a/src/base/api/Httpd.cpp +++ b/src/base/api/Httpd.cpp @@ -38,7 +38,6 @@ namespace xmrig { static const char *kAuthorization = "authorization"; -static const char *kContentType = "content-type"; #ifdef _WIN32 static const char *favicon = nullptr; @@ -138,7 +137,7 @@ void xmrig::Httpd::onHttpData(const HttpData &data) # ifdef _WIN32 if (favicon != nullptr) { HttpResponse response(data.id()); - response.setHeader("Content-Type", "image/x-icon"); + response.setHeader(HttpData::kContentType, "image/x-icon"); return response.end(favicon, faviconSize); } @@ -161,7 +160,7 @@ void xmrig::Httpd::onHttpData(const HttpData &data) 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(); } } diff --git a/src/base/base.cmake b/src/base/base.cmake index 33ec9954f..b57622651 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -34,6 +34,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/Fetch.h src/base/net/http/Http.h src/base/net/http/HttpListener.h src/base/net/stratum/BaseClient.h @@ -80,7 +81,10 @@ set(SOURCES_BASE src/base/kernel/Signals.cpp src/base/net/dns/Dns.cpp src/base/net/dns/DnsRecord.cpp + src/base/net/http/Fetch.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/Client.cpp src/base/net/stratum/Job.cpp diff --git a/src/base/io/json/JsonRequest.cpp b/src/base/io/json/JsonRequest.cpp index 4556f3f08..d66040a7b 100644 --- a/src/base/io/json/JsonRequest.cpp +++ b/src/base/io/json/JsonRequest.cpp @@ -5,8 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,12 +27,40 @@ #include "rapidjson/document.h" +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(); + + doc.AddMember(StringRef(kId), id, allocator); + doc.AddMember(StringRef(kJsonRPC), StringRef(k2_0), allocator); + doc.AddMember(StringRef(kMethod), StringRef(method), allocator); + + return doc; +} + + void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value ¶ms) { + using namespace rapidjson; auto &allocator = doc.GetAllocator(); - doc.AddMember("id", id, allocator); - doc.AddMember("jsonrpc", "2.0", allocator); - doc.AddMember("method", rapidjson::StringRef(method), allocator); - doc.AddMember("params", params, allocator); + 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); } diff --git a/src/base/io/json/JsonRequest.h b/src/base/io/json/JsonRequest.h index e98c0baec..b2e0b156e 100644 --- a/src/base/io/json/JsonRequest.h +++ b/src/base/io/json/JsonRequest.h @@ -5,8 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * 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 @@ -35,6 +35,9 @@ namespace xmrig { class JsonRequest { 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 ¶ms); }; diff --git a/src/base/io/log/Log.cpp b/src/base/io/log/Log.cpp index a091f923f..2c2b2d14c 100644 --- a/src/base/io/log/Log.cpp +++ b/src/base/io/log/Log.cpp @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2019 Spudz76 - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * 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 @@ -189,7 +189,7 @@ class LogPrivate } - char m_buf[4096]{}; + char m_buf[Log::kMaxBufferSize]{}; std::mutex m_mutex; std::vector m_backends; }; diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index 3181f9342..45183d1ce 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2019 Spudz76 - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ #define XMRIG_LOG_H +#include #include @@ -52,6 +53,8 @@ class Log DEBUG, // debug-level messages }; + constexpr static size_t kMaxBufferSize = 16384; + static void add(ILogBackend *backend); static void destroy(); static void print(const char *fmt, ...); diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 470f36ef8..af1c3d169 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -97,6 +97,7 @@ class IConfig CPUMaxThreadsKey = 1026, MemoryPoolKey = 1027, YieldKey = 1030, + AstroBWTMaxSizeKey = 1034, // xmrig amd OclPlatformKey = 1400, diff --git a/src/base/net/dns/DnsRecord.cpp b/src/base/net/dns/DnsRecord.cpp index 7a85799b2..e722ad6a6 100644 --- a/src/base/net/dns/DnsRecord.cpp +++ b/src/base/net/dns/DnsRecord.cpp @@ -5,8 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * 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 @@ -50,13 +50,14 @@ xmrig::DnsRecord::DnsRecord(const addrinfo *addr) : sockaddr *xmrig::DnsRecord::addr(uint16_t port) const { if (m_type == A) { - sockaddr_in *addr = new sockaddr_in(); + auto addr = new sockaddr_in(); uv_ip4_addr(m_ip.data(), port, addr); return reinterpret_cast(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); return reinterpret_cast(addr); diff --git a/src/base/net/dns/DnsRecord.h b/src/base/net/dns/DnsRecord.h index 71d1e9c84..82932bb93 100644 --- a/src/base/net/dns/DnsRecord.h +++ b/src/base/net/dns/DnsRecord.h @@ -5,8 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,7 +45,7 @@ class DnsRecord AAAA }; - inline DnsRecord() : m_type(Unknown) {} + DnsRecord() = default; DnsRecord(const addrinfo *addr); sockaddr *addr(uint16_t port = 0) const; @@ -55,7 +55,7 @@ class DnsRecord inline Type type() const { return m_type; } private: - Type m_type; + Type m_type = Unknown; String m_ip; }; diff --git a/src/base/net/http/Fetch.cpp b/src/base/net/http/Fetch.cpp new file mode 100644 index 000000000..361769e9d --- /dev/null +++ b/src/base/net/http/Fetch.cpp @@ -0,0 +1,155 @@ +/* XMRig + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , + * + * 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 . + */ + + +#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(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(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 writer(buffer); + doc.Accept(writer); + + setBody(buffer.GetString(), buffer.GetSize(), HttpData::kApplicationJson.c_str()); +} + + +void xmrig::fetch(FetchRequest &&req, const std::weak_ptr &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(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(); +} diff --git a/src/base/net/http/Fetch.h b/src/base/net/http/Fetch.h new file mode 100644 index 000000000..db1e899b6 --- /dev/null +++ b/src/base/net/http/Fetch.h @@ -0,0 +1,74 @@ +/* XMRig + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , + * + * 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 . + */ + + +#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 +#include +#include + + +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 headers; + std::string body; + String fingerprint; + String host; + String path; + uint16_t port = 0; +}; + + +void fetch(FetchRequest &&req, const std::weak_ptr &listener, int type = 0); + + +} // namespace xmrig + + +#endif // XMRIG_FETCH_H + diff --git a/src/base/net/http/HttpApiResponse.cpp b/src/base/net/http/HttpApiResponse.cpp index 5fe926368..6bf23c45b 100644 --- a/src/base/net/http/HttpApiResponse.cpp +++ b/src/base/net/http/HttpApiResponse.cpp @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2014-2019 heapwolf - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,8 +24,9 @@ */ -#include "3rdparty/http-parser/http_parser.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/stringbuffer.h" @@ -75,7 +76,7 @@ void xmrig::HttpApiResponse::end() return HttpResponse::end(); } - setHeader("Content-Type", "application/json"); + setHeader(HttpData::kContentType, HttpData::kApplicationJson); StringBuffer buffer(nullptr, 4096); PrettyWriter writer(buffer); diff --git a/src/base/net/http/HttpApiResponse.h b/src/base/net/http/HttpApiResponse.h index bbaf132ed..a50707354 100644 --- a/src/base/net/http/HttpApiResponse.h +++ b/src/base/net/http/HttpApiResponse.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2014-2019 heapwolf - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * 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 diff --git a/src/base/net/http/HttpClient.cpp b/src/base/net/http/HttpClient.cpp index 364b3248a..b684ddae0 100644 --- a/src/base/net/http/HttpClient.cpp +++ b/src/base/net/http/HttpClient.cpp @@ -24,70 +24,60 @@ */ -#include - - +#include "base/net/http/HttpClient.h" #include "3rdparty/http-parser/http_parser.h" #include "base/io/log/Log.h" #include "base/kernel/Platform.h" #include "base/net/dns/Dns.h" -#include "base/net/http/HttpClient.h" #include "base/tools/Baton.h" +#include + + namespace xmrig { + static const char *kCRLF = "\r\n"; -class ClientWriteBaton : public Baton +class HttpClientWriteBaton : public Baton { 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_header(header) { - bufs[0].len = m_header.size(); - bufs[0].base = const_cast(m_header.c_str()); - - if (!m_body.empty()) { - bufs[1].len = m_body.size(); - bufs[1].base = const_cast(m_body.c_str()); - } - else { - bufs[1].base = nullptr; - bufs[1].len = 0; - } + m_bufs[0] = uv_buf_init(const_cast(m_header.c_str()), m_header.size()); + m_bufs[1] = m_body.empty() ? uv_buf_init(nullptr, 0) : uv_buf_init(const_cast(m_body.c_str()), m_body.size()); } - - inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; } - inline size_t size() const { return bufs[0].len + bufs[1].len; } - inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast(req->data); } - - - uv_buf_t bufs[2]{}; + void write(uv_stream_t *stream) + { + uv_write(&req, stream, m_bufs, nbufs(), [](uv_write_t *req, int) { delete reinterpret_cast(req->data); }); + } private: + inline size_t nbufs() const { return m_bufs[1].len > 0 ? 2 : 1; } + std::string m_body; std::string m_header; + uv_buf_t m_bufs[2]{}; }; } // namespace xmrig -xmrig::HttpClient::HttpClient(int method, const String &url, const std::weak_ptr &listener, const char *data, size_t size) : - HttpContext(HTTP_RESPONSE, listener) +xmrig::HttpClient::HttpClient(FetchRequest &&req, const std::weak_ptr &listener) : + HttpContext(HTTP_RESPONSE, listener), + m_req(std::move(req)) { - this->method = method; - this->url = url; - - if (data) { - body = size ? std::string(data, size) : data; - } - - m_dns = new Dns(this); + method = m_req.method; + url = std::move(m_req.path); + body = std::move(m_req.body); + headers = std::move(m_req.headers); + 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(host); -} - - -const xmrig::String &xmrig::HttpClient::host() const -{ - return m_dns->host(); + return m_dns->resolve(m_req.host); } @@ -116,25 +98,27 @@ void xmrig::HttpClient::onResolved(const Dns &dns, int status) this->status = status; if (status < 0 && dns.isEmpty()) { - if (!m_quiet) { - LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), m_port, uv_strerror(status)); + if (!isQuiet()) { + LOG_ERR("[%s:%d] DNS error: \"%s\"", dns.host().data(), port(), uv_strerror(status)); } return; } - sockaddr *addr = dns.get().addr(m_port); + sockaddr *addr = dns.get().addr(port()); auto req = new uv_connect_t; req->data = this; uv_tcp_connect(req, m_tcp, addr, onConnect); + + delete addr; } void xmrig::HttpClient::handshake() { - headers.insert({ "Host", m_dns->host().data() }); + headers.insert({ "Host", host() }); headers.insert({ "Connection", "close" }); 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) { - auto baton = new ClientWriteBaton(header, std::move(body)); - uv_write(&baton->req, stream(), baton->bufs, baton->count(), ClientWriteBaton::onWrite); + auto baton = new HttpClientWriteBaton(header, std::move(body)); + baton->write(stream()); } @@ -181,8 +165,8 @@ void xmrig::HttpClient::onConnect(uv_connect_t *req, int status) } if (status < 0) { - if (!client->m_quiet) { - LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(status)); + if (!client->isQuiet()) { + LOG_ERR("[%s:%d] connect error: \"%s\"", client->m_dns->host().data(), client->port(), uv_strerror(status)); } 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) { buf->base = new char[suggested_size]; - -# ifdef _WIN32 - buf->len = static_cast(suggested_size); -# else - buf->len = suggested_size; -# endif + buf->len = suggested_size; }, [](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) { client->read(buf->base, static_cast(nread)); } else { - if (!client->m_quiet && nread != UV_EOF) { - LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->m_port, uv_strerror(static_cast(nread))); + if (!client->isQuiet() && nread != UV_EOF) { + LOG_ERR("[%s:%d] read error: \"%s\"", client->m_dns->host().data(), client->port(), uv_strerror(static_cast(nread))); } client->close(static_cast(nread)); diff --git a/src/base/net/http/HttpClient.h b/src/base/net/http/HttpClient.h index 62ac72977..b54882a0e 100644 --- a/src/base/net/http/HttpClient.h +++ b/src/base/net/http/HttpClient.h @@ -28,8 +28,9 @@ #define XMRIG_HTTPCLIENT_H -#include "base/net/http/HttpContext.h" #include "base/kernel/interfaces/IDnsListener.h" +#include "base/net/http/Fetch.h" +#include "base/net/http/HttpContext.h" #include "base/tools/Object.h" @@ -44,14 +45,14 @@ class HttpClient : public HttpContext, public IDnsListener public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpClient); - HttpClient(int method, const String &url, const std::weak_ptr &listener, const char *data = nullptr, size_t size = 0); + HttpClient(FetchRequest &&req, const std::weak_ptr &listener); ~HttpClient() override; - inline uint16_t port() const { return m_port; } - inline void setQuiet(bool quiet) { m_quiet = quiet; } + inline bool isQuiet() const { return m_req.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); - const String &host() const; + bool connect(); protected: void onResolved(const Dns &dns, int status) override; @@ -60,13 +61,14 @@ class HttpClient : public HttpContext, public IDnsListener virtual void read(const char *data, size_t size); virtual void write(const std::string &header); - bool m_quiet = false; +protected: + inline const FetchRequest &req() const { return m_req; } private: static void onConnect(uv_connect_t *req, int status); Dns *m_dns; - uint16_t m_port = 0; + FetchRequest m_req; }; diff --git a/src/base/net/http/HttpContext.cpp b/src/base/net/http/HttpContext.cpp index 81479f2aa..66a25d6a1 100644 --- a/src/base/net/http/HttpContext.cpp +++ b/src/base/net/http/HttpContext.cpp @@ -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) { return http_parser_execute(m_parser, &http_settings, data, size); diff --git a/src/base/net/http/HttpContext.h b/src/base/net/http/HttpContext.h index 5091c24bc..784bb7ed1 100644 --- a/src/base/net/http/HttpContext.h +++ b/src/base/net/http/HttpContext.h @@ -55,13 +55,19 @@ class HttpContext : public HttpData XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpContext) HttpContext(int parser_type, const std::weak_ptr &listener); - virtual ~HttpContext(); + ~HttpContext() override; inline uv_stream_t *stream() const { return reinterpret_cast(m_tcp); } inline uv_handle_t *handle() const { return reinterpret_cast(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); - std::string ip() const; + std::string ip() const override; uint64_t elapsed() const; void close(int status = 0); diff --git a/src/base/net/http/HttpData.cpp b/src/base/net/http/HttpData.cpp new file mode 100644 index 000000000..5aa575a80 --- /dev/null +++ b/src/base/net/http/HttpData.cpp @@ -0,0 +1,31 @@ +/* XMRig + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , + * + * 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 . + */ + + +#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 diff --git a/src/base/net/http/HttpData.h b/src/base/net/http/HttpData.h index 1705e8816..cd852639c 100644 --- a/src/base/net/http/HttpData.h +++ b/src/base/net/http/HttpData.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2014-2019 heapwolf - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +28,9 @@ #define XMRIG_HTTPDATA_H +#include "base/tools/Object.h" + + #include #include @@ -38,12 +41,28 @@ namespace xmrig { class HttpData { 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) {} + virtual ~HttpData() = default; inline uint64_t id() const { return m_id; } - int method = 0; - int status = 0; + 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 status = 0; + int userType = 0; std::map headers; std::string body; std::string url; diff --git a/src/base/net/http/HttpListener.cpp b/src/base/net/http/HttpListener.cpp new file mode 100644 index 000000000..e58d5e55e --- /dev/null +++ b/src/base/net/http/HttpListener.cpp @@ -0,0 +1,41 @@ +/* XMRig + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , + * + * 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 . + */ + + +#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(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(data.body.size()), data.body.c_str()); + } + } +# endif + + m_listener->onHttpData(data); +} diff --git a/src/base/net/http/HttpListener.h b/src/base/net/http/HttpListener.h index 428f9c49a..36975db48 100644 --- a/src/base/net/http/HttpListener.h +++ b/src/base/net/http/HttpListener.h @@ -32,7 +32,7 @@ class HttpListener : public IHttpListener inline HttpListener(IHttpListener *listener) : m_listener(listener) {} protected: - inline void onHttpData(const HttpData &data) override { m_listener->onHttpData(data); }; + void onHttpData(const HttpData &data) override; private: IHttpListener *m_listener; diff --git a/src/base/net/http/HttpsClient.cpp b/src/base/net/http/HttpsClient.cpp index 7bebb3bd0..96162e9c4 100644 --- a/src/base/net/http/HttpsClient.cpp +++ b/src/base/net/http/HttpsClient.cpp @@ -29,8 +29,8 @@ #include -#include "base/io/log/Log.h" #include "base/net/http/HttpsClient.h" +#include "base/io/log/Log.h" #include "base/tools/Buffer.h" @@ -39,12 +39,8 @@ #endif -xmrig::HttpsClient::HttpsClient(int method, const String &url, const std::weak_ptr &listener, const char *data, size_t size, const String &fingerprint) : - HttpClient(method, url, listener, data, size), - m_ready(false), - m_buf(), - m_ssl(nullptr), - m_fp(fingerprint) +xmrig::HttpsClient::HttpsClient(FetchRequest &&req, const std::weak_ptr &listener) : + HttpClient(std::move(req), listener) { m_ctx = SSL_CTX_new(SSLv23_method()); 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; } -const char *xmrig::HttpsClient::version() const +const char *xmrig::HttpsClient::tlsVersion() const { 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_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); @@ -150,12 +146,12 @@ bool xmrig::HttpsClient::verify(X509 *cert) } if (!verifyFingerprint(cert)) { - if (!m_quiet) { - LOG_ERR("[%s:%d] Failed to verify server certificate fingerprint", host().data(), port()); + if (!isQuiet()) { + 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 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); - return m_fp.isNull() || strncasecmp(m_fingerprint, m_fp.data(), 64) == 0; + return req().fingerprint.isNull() || strncasecmp(m_fingerprint, req().fingerprint.data(), 64) == 0; } diff --git a/src/base/net/http/HttpsClient.h b/src/base/net/http/HttpsClient.h index 13eb5f679..afac6e018 100644 --- a/src/base/net/http/HttpsClient.h +++ b/src/base/net/http/HttpsClient.h @@ -46,11 +46,11 @@ class HttpsClient : public HttpClient public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsClient) - HttpsClient(int method, const String &url, const std::weak_ptr &listener, const char *data, size_t size, const String &fingerprint); + HttpsClient(FetchRequest &&req, const std::weak_ptr &listener); ~HttpsClient() override; - const char *fingerprint() const; - const char *version() const; + const char *tlsFingerprint() const override; + const char *tlsVersion() const override; protected: void handshake() override; @@ -62,14 +62,13 @@ class HttpsClient : public HttpClient bool verifyFingerprint(X509 *cert); void flush(); - BIO *m_readBio; - BIO *m_writeBio; - bool m_ready; - char m_buf[1024 * 2]; - char m_fingerprint[32 * 2 + 8]; - SSL *m_ssl; - SSL_CTX *m_ctx; - String m_fp; + BIO *m_readBio = nullptr; + BIO *m_writeBio = nullptr; + bool m_ready = false; + char m_buf[1024 * 2]{}; + char m_fingerprint[32 * 2 + 8]{}; + SSL *m_ssl = nullptr; + SSL_CTX *m_ctx = nullptr; }; diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index c54596826..bdf6d5ca1 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -30,20 +30,14 @@ #include "base/io/json/JsonRequest.h" #include "base/io/log/Log.h" #include "base/kernel/interfaces/IClientListener.h" -#include "base/net/http/HttpClient.h" +#include "base/net/http/Fetch.h" +#include "base/net/http/HttpData.h" #include "base/net/stratum/SubmitResult.h" #include "base/tools/Buffer.h" #include "base/tools/Timer.h" #include "net/JobResult.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" - - -#ifdef XMRIG_FEATURE_TLS -# include "base/net/http/HttpsClient.h" -#endif #include @@ -65,8 +59,7 @@ static const size_t BlobReserveSize = 8; xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) : - BaseClient(id, listener), - m_apiVersion(API_MONERO) + BaseClient(id, listener) { m_httpListener = std::make_shared(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); # endif - send(HTTP_POST, kJsonRPC, doc); - - return m_sequence++; + return rpcSend(doc); } @@ -163,15 +154,11 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data) return retry(); } - LOG_DEBUG("[%s:%d] received (%d bytes): \"%.*s\"", m_pool.host().data(), m_pool.port(), static_cast(data.body.size()), static_cast(data.body.size()), data.body.c_str()); - - m_ip = static_cast(data).ip().c_str(); + m_ip = data.ip().c_str(); # ifdef XMRIG_FEATURE_TLS - if (isTLS()) { - m_tlsVersion = static_cast(data).version(); - m_tlsFingerprint = static_cast(data).fingerprint(); - } + m_tlsVersion = data.tlsVersion(); + m_tlsFingerprint = data.tlsFingerprint(); # endif rapidjson::Document doc; @@ -188,7 +175,7 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data) if (!doc.HasMember(kHash)) { m_apiVersion = API_CRYPTONOTE_DEFAULT; - return send(HTTP_GET, kGetInfo); + return send(kGetInfo); } 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) { if (m_apiVersion == API_DERO) { - using namespace rapidjson; - 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; + rpcSend(JsonRequest::create(m_sequence, "get_info")); } 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); params.AddMember("wallet_address", m_user.toJSON(), allocator); if (m_apiVersion == API_DERO) { - params.AddMember("reserve_size", BlobReserveSize, allocator); + params.AddMember("reserve_size", static_cast(BlobReserveSize), allocator); } else { 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); - 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++; } @@ -368,46 +353,10 @@ void xmrig::DaemonClient::retry() } -void xmrig::DaemonClient::send(int method, const char *url, const char *data, size_t size) -{ - LOG_DEBUG("[%s:%d] " MAGENTA_BOLD("\"%s %s\"") BLACK_BOLD_S " send (%zu bytes): \"%.*s\"", - m_pool.host().data(), - m_pool.port(), - http_method_str(static_cast(method)), - url, - size, - static_cast(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) +void xmrig::DaemonClient::send(const char *path) { - using namespace rapidjson; - - StringBuffer buffer(nullptr, 512); - Writer writer(buffer); - doc.Accept(writer); - - send(method, url, buffer.GetString(), buffer.GetSize()); + FetchRequest req(HTTP_GET, m_pool, path, isQuiet()); + fetch(std::move(req), m_httpListener); } diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 0b14f5dda..0c3df6a1b 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -71,16 +71,16 @@ class DaemonClient : public BaseClient, public ITimerListener, public IHttpListe bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); int64_t getBlockTemplate(); + int64_t rpcSend(const rapidjson::Document &doc); 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 send(const char *path); void setState(SocketState state); enum { API_CRYPTONOTE_DEFAULT, API_MONERO, API_DERO, - } m_apiVersion; + } m_apiVersion = API_MONERO; std::shared_ptr m_httpListener; String m_blocktemplate; diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index d69bc0fb8..6fdcf14d6 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -29,17 +29,11 @@ #include "base/io/json/Json.h" #include "base/io/json/JsonRequest.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 "rapidjson/document.h" #include "rapidjson/error/en.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" - - -#ifdef XMRIG_FEATURE_TLS -# include "base/net/http/HttpsClient.h" -#endif namespace xmrig { @@ -159,7 +153,8 @@ void xmrig::SelfSelectClient::getBlockTemplate() 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(method)), - url, - size, - static_cast(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 writer(buffer); - doc.Accept(writer); - - send(method, url, buffer.GetString(), buffer.GetSize()); -} - - void xmrig::SelfSelectClient::setState(State state) { if (m_state == state) { @@ -256,7 +213,7 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result) 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 (!isQuiet()) { 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(); } - LOG_DEBUG("[%s] received (%d bytes): \"%.*s\"", pool().daemon().url().data(), static_cast(data.body.size()), static_cast(data.body.size()), data.body.c_str()); - rapidjson::Document doc; if (doc.Parse(data.body.c_str()).HasParseError()) { if (!isQuiet()) { diff --git a/src/base/net/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h index 5c9431c76..c54cf8dff 100644 --- a/src/base/net/stratum/SelfSelectClient.h +++ b/src/base/net/stratum/SelfSelectClient.h @@ -102,8 +102,6 @@ class SelfSelectClient : public IClient, public IClientListener, public IHttpLis bool parseResponse(int64_t id, rapidjson::Value &result, const rapidjson::Value &error); void getBlockTemplate(); void retry(); - void send(int method, const char *url, const char *data = nullptr, size_t size = 0); - void send(int method, const char *url, const rapidjson::Document &doc); void setState(State state); void submitBlockTemplate(rapidjson::Value &result); diff --git a/src/base/net/tools/Storage.h b/src/base/net/tools/Storage.h index aff624816..0af4db263 100644 --- a/src/base/net/tools/Storage.h +++ b/src/base/net/tools/Storage.h @@ -5,8 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,7 +26,7 @@ #define XMRIG_STORAGE_H -#include +#include #include @@ -37,10 +37,7 @@ template class Storage { public: - inline Storage() : - m_counter(0) - { - } + inline Storage() = default; inline uintptr_t add(TYPE *ptr) @@ -87,7 +84,7 @@ class Storage private: std::map m_data; - uint64_t m_counter; + uint64_t m_counter = 0; }; diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index 0b3904f5d..ef438ab91 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -116,6 +116,8 @@ static AlgoName const algorithm_names[] = { { "RandomARQ", nullptr, Algorithm::RX_ARQ }, { "randomx/sfx", "rx/sfx", Algorithm::RX_SFX }, { "RandomSFX", nullptr, Algorithm::RX_SFX }, + { "randomx/keva", "rx/keva", Algorithm::RX_KEVA }, + { "RandomKEVA", nullptr, Algorithm::RX_KEVA }, # endif # ifdef XMRIG_ALGO_ARGON2 { "argon2/chukwa", nullptr, Algorithm::AR2_CHUKWA }, @@ -150,6 +152,7 @@ size_t xmrig::Algorithm::l2() const return 0x40000; case RX_WOW: + case RX_KEVA: return 0x20000; case RX_ARQ: @@ -166,7 +169,7 @@ size_t xmrig::Algorithm::l2() const size_t xmrig::Algorithm::l3() const { -# if defined(XMRIG_ALGO_RANDOMX) || defined(XMRIG_ALGO_ARGON2) +# if defined(XMRIG_ALGO_RANDOMX) || defined(XMRIG_ALGO_ARGON2) || defined(XMRIG_ALGO_ASTROBWT) constexpr size_t oneMiB = 0x100000; # endif @@ -186,6 +189,7 @@ size_t xmrig::Algorithm::l3() const return oneMiB * 2; case RX_WOW: + case RX_KEVA: return oneMiB; case RX_ARQ: @@ -302,6 +306,7 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id) case RX_LOKI: case RX_ARQ: case RX_SFX: + case RX_KEVA: return RANDOM_X; # endif diff --git a/src/crypto/common/Algorithm.h b/src/crypto/common/Algorithm.h index fa821f23c..198ca4f21 100644 --- a/src/crypto/common/Algorithm.h +++ b/src/crypto/common/Algorithm.h @@ -69,6 +69,7 @@ class Algorithm RX_LOKI, // "rx/loki" RandomXL (Loki). RX_ARQ, // "rx/arq" RandomARQ (Arqma). RX_SFX, // "rx/sfx" RandomSFX (Safex Cash). + RX_KEVA, // "rx/keva" RandomKEVA (Keva). AR2_CHUKWA, // "argon2/chukwa" Argon2id (Chukwa). AR2_WRKZ, // "argon2/wrkz" Argon2id (WRKZ) ASTROBWT_DERO, // "astrobwt" AstroBWT (Dero) diff --git a/src/crypto/common/Coin.cpp b/src/crypto/common/Coin.cpp index f8f389430..b17b340e7 100644 --- a/src/crypto/common/Coin.cpp +++ b/src/crypto/common/Coin.cpp @@ -52,6 +52,7 @@ static CoinName const coin_names[] = { { "arqma", Coin::ARQMA }, { "arq", Coin::ARQMA }, { "dero", Coin::DERO }, + { "keva", Coin::KEVA } }; @@ -71,6 +72,9 @@ xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const case DERO: return (blobVersion >= 4) ? Algorithm::ASTROBWT_DERO : Algorithm::CN_0; + case KEVA: + return (blobVersion >= 11) ? Algorithm::RX_KEVA : Algorithm::CN_R; + case INVALID: break; } diff --git a/src/crypto/common/Coin.h b/src/crypto/common/Coin.h index d4b2aaa3f..9e57a8e95 100644 --- a/src/crypto/common/Coin.h +++ b/src/crypto/common/Coin.h @@ -41,7 +41,8 @@ class Coin INVALID = -1, MONERO, ARQMA, - DERO + DERO, + KEVA }; diff --git a/src/version.h b/src/version.h index 788bed782..86a5a90ba 100644 --- a/src/version.h +++ b/src/version.h @@ -28,15 +28,15 @@ #define APP_ID "xmrig-proxy" #define APP_NAME "xmrig-proxy" #define APP_DESC "XMRig Stratum proxy" -#define APP_VERSION "5.8.2-dev" +#define APP_VERSION "5.9.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2020 xmrig.com" #define APP_KIND "proxy" #define APP_VER_MAJOR 5 -#define APP_VER_MINOR 8 -#define APP_VER_PATCH 2 +#define APP_VER_MINOR 9 +#define APP_VER_PATCH 0 #ifdef _MSC_VER # if (_MSC_VER >= 1920) From 25f59b8f12c96ab2871e89d0354c2dd9b7460bac Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 8 Mar 2020 02:36:20 +0700 Subject: [PATCH 3/4] Added FileLogWriter::writeLine --- src/base/io/log/FileLogWriter.cpp | 41 +++++++++++++++++++++++++++---- src/base/io/log/FileLogWriter.h | 1 + src/proxy/log/AccessLog.cpp | 5 +--- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/base/io/log/FileLogWriter.cpp b/src/base/io/log/FileLogWriter.cpp index 3386929a7..8ae31273c 100644 --- a/src/base/io/log/FileLogWriter.cpp +++ b/src/base/io/log/FileLogWriter.cpp @@ -25,6 +25,24 @@ #include +namespace xmrig { + + +static void fsWriteCallback(uv_fs_t *req) +{ + delete [] static_cast(req->data); + + uv_fs_req_cleanup(req); + delete req; +} + + +static const char *kNewLine = "\n"; + + +} // namespace xmrig + + bool xmrig::FileLogWriter::open(const char *fileName) { assert(fileName != nullptr); @@ -52,12 +70,25 @@ bool xmrig::FileLogWriter::write(const char *data, size_t size) auto req = new uv_fs_t; req->data = buf.base; - uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, [](uv_fs_t *req) { - delete [] static_cast(req->data); + uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, fsWriteCallback); + + return true; +} + + +bool xmrig::FileLogWriter::writeLine(const char *data, size_t size) +{ + uv_buf_t buf[2] = { + uv_buf_init(new char[size], size), + uv_buf_init(const_cast(kNewLine), 1) + }; + + memcpy(buf[0].base, data, size); + + auto req = new uv_fs_t; + req->data = buf[0].base; - uv_fs_req_cleanup(req); - delete req; - }); + uv_fs_write(uv_default_loop(), req, m_file, buf, 2, -1, fsWriteCallback); return true; } diff --git a/src/base/io/log/FileLogWriter.h b/src/base/io/log/FileLogWriter.h index f451f2b86..5dca4c58c 100644 --- a/src/base/io/log/FileLogWriter.h +++ b/src/base/io/log/FileLogWriter.h @@ -36,6 +36,7 @@ class FileLogWriter bool open(const char *fileName); bool write(const char *data, size_t size); + bool writeLine(const char *data, size_t size); private: int m_file = -1; diff --git a/src/proxy/log/AccessLog.cpp b/src/proxy/log/AccessLog.cpp index 629b1ede3..513aaa4c9 100644 --- a/src/proxy/log/AccessLog.cpp +++ b/src/proxy/log/AccessLog.cpp @@ -128,8 +128,5 @@ void xmrig::AccessLog::write(const char *fmt, ...) return; } - size = std::min(sizeof (buf) - 1, size + rc); - buf[size] = '\n'; - - m_writer.write(buf, static_cast(size) + 1); + m_writer.writeLine(buf, std::min(sizeof(buf), size + rc)); } From 006c131b13cafdae849e7f76e12fb4a387795873 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 8 Mar 2020 12:30:37 +0700 Subject: [PATCH 4/4] Fixed build without HTTP support. --- src/base/base.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/base.cmake b/src/base/base.cmake index b57622651..871b045d4 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -34,7 +34,6 @@ set(HEADERS_BASE src/base/kernel/Signals.h src/base/net/dns/Dns.h src/base/net/dns/DnsRecord.h - src/base/net/http/Fetch.h src/base/net/http/Http.h src/base/net/http/HttpListener.h src/base/net/stratum/BaseClient.h @@ -81,10 +80,7 @@ set(SOURCES_BASE src/base/kernel/Signals.cpp src/base/net/dns/Dns.cpp src/base/net/dns/DnsRecord.cpp - src/base/net/http/Fetch.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/Client.cpp src/base/net/stratum/Job.cpp @@ -148,6 +144,7 @@ if (WITH_HTTP) src/base/kernel/interfaces/IHttpListener.h src/base/kernel/interfaces/IJsonReader.h src/base/kernel/interfaces/ITcpServerListener.h + src/base/net/http/Fetch.h src/base/net/http/HttpApiResponse.h src/base/net/http/HttpClient.h src/base/net/http/HttpContext.h @@ -165,9 +162,12 @@ if (WITH_HTTP) src/base/api/Httpd.cpp src/base/api/requests/ApiRequest.cpp src/base/api/requests/HttpApiRequest.cpp + src/base/net/http/Fetch.cpp src/base/net/http/HttpApiResponse.cpp src/base/net/http/HttpClient.cpp src/base/net/http/HttpContext.cpp + src/base/net/http/HttpData.cpp + src/base/net/http/HttpListener.cpp src/base/net/http/HttpResponse.cpp src/base/net/http/HttpServer.cpp src/base/net/stratum/DaemonClient.cpp