diff --git a/CHANGELOG.md b/CHANGELOG.md index 989d193a3..ee495528d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# v6.11.0 +- [#2196](https://github.com/xmrig/xmrig/pull/2196) Improved DNS subsystem and added new DNS specific options. +- [#2172](https://github.com/xmrig/xmrig/pull/2172) Fixed build on Alpine 3.13. +- [#2177](https://github.com/xmrig/xmrig/pull/2177) Fixed ARM specific compilation error with GCC 10.2. +- [#2214](https://github.com/xmrig/xmrig/pull/2214) [#2216](https://github.com/xmrig/xmrig/pull/2216) [#2235](https://github.com/xmrig/xmrig/pull/2235) Optimized `cn-heavy` algorithm. +- [#2217](https://github.com/xmrig/xmrig/pull/2217) Fixed mining job creation sequence. +- [#2225](https://github.com/xmrig/xmrig/pull/2225) Fixed build without OpenCL support on some systems. +- [#2229](https://github.com/xmrig/xmrig/pull/2229) Don't use RandomX JIT if `WITH_ASM=OFF`. +- [#2228](https://github.com/xmrig/xmrig/pull/2228) Removed useless code for cryptonight algorithms. +- [#2234](https://github.com/xmrig/xmrig/pull/2234) Fixed build error on gcc 4.8. + # v6.10.0 - [#2122](https://github.com/xmrig/xmrig/pull/2122) Fixed pause logic when both pause on battery and user activity are enabled. - [#2123](https://github.com/xmrig/xmrig/issues/2123) Fixed compatibility with gcc 4.8. diff --git a/cmake/randomx.cmake b/cmake/randomx.cmake index 976f11862..7038774c6 100644 --- a/cmake/randomx.cmake +++ b/cmake/randomx.cmake @@ -42,13 +42,13 @@ if (WITH_RANDOMX) src/crypto/rx/RxVm.cpp ) - if (CMAKE_C_COMPILER_ID MATCHES MSVC) + if (WITH_ASM AND CMAKE_C_COMPILER_ID MATCHES MSVC) enable_language(ASM_MASM) list(APPEND SOURCES_CRYPTO src/crypto/randomx/jit_compiler_x86_static.asm src/crypto/randomx/jit_compiler_x86.cpp ) - elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8) + elseif (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8) list(APPEND SOURCES_CRYPTO src/crypto/randomx/jit_compiler_x86_static.S src/crypto/randomx/jit_compiler_x86.cpp diff --git a/src/backend/common/Workers.h b/src/backend/common/Workers.h index 0ef3b8894..664912431 100644 --- a/src/backend/common/Workers.h +++ b/src/backend/common/Workers.h @@ -20,6 +20,9 @@ #define XMRIG_WORKERS_H +#include <memory> + + #include "backend/common/Thread.h" #include "backend/cpu/CpuLaunchData.h" diff --git a/src/backend/opencl/wrappers/AdlLib_linux.cpp b/src/backend/opencl/wrappers/AdlLib_linux.cpp index 7d7adb31c..1f91a9bf2 100644 --- a/src/backend/opencl/wrappers/AdlLib_linux.cpp +++ b/src/backend/opencl/wrappers/AdlLib_linux.cpp @@ -24,6 +24,7 @@ #include "backend/opencl/wrappers/OclDevice.h" +#include <limits.h> #include <dirent.h> #include <fstream> #include <map> diff --git a/src/base/base.cmake b/src/base/base.cmake index 5949c0503..8c48fe752 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -32,6 +32,7 @@ set(HEADERS_BASE src/base/kernel/interfaces/IConfigListener.h src/base/kernel/interfaces/IConfigTransform.h src/base/kernel/interfaces/IConsoleListener.h + src/base/kernel/interfaces/IDnsBackend.h src/base/kernel/interfaces/IDnsListener.h src/base/kernel/interfaces/ILineListener.h src/base/kernel/interfaces/ILogBackend.h @@ -43,7 +44,11 @@ set(HEADERS_BASE src/base/kernel/Platform.h src/base/kernel/Process.h src/base/net/dns/Dns.h + src/base/net/dns/DnsConfig.h src/base/net/dns/DnsRecord.h + src/base/net/dns/DnsRecords.h + src/base/net/dns/DnsRequest.h + src/base/net/dns/DnsUvBackend.h src/base/net/http/Http.h src/base/net/http/HttpListener.h src/base/net/stratum/BaseClient.h @@ -99,7 +104,10 @@ set(SOURCES_BASE src/base/kernel/Platform.cpp src/base/kernel/Process.cpp src/base/net/dns/Dns.cpp + src/base/net/dns/DnsConfig.cpp src/base/net/dns/DnsRecord.cpp + src/base/net/dns/DnsRecords.cpp + src/base/net/dns/DnsUvBackend.cpp src/base/net/http/Http.cpp src/base/net/stratum/BaseClient.cpp src/base/net/stratum/Client.cpp diff --git a/src/base/io/log/FileLogWriter.cpp b/src/base/io/log/FileLogWriter.cpp index 352dec20f..b41f7f395 100644 --- a/src/base/io/log/FileLogWriter.cpp +++ b/src/base/io/log/FileLogWriter.cpp @@ -91,7 +91,7 @@ bool xmrig::FileLogWriter::writeLine(const char *data, size_t size) { const uv_buf_t buf[2] = { uv_buf_init(new char[size], size), - uv_buf_init(m_endl, sizeof(m_endl) - 1) + uv_buf_init(const_cast<char *>(m_endl), sizeof(m_endl) - 1) }; memcpy(buf[0].base, data, size); diff --git a/src/base/io/log/FileLogWriter.h b/src/base/io/log/FileLogWriter.h index 548d235ce..f3606aa32 100644 --- a/src/base/io/log/FileLogWriter.h +++ b/src/base/io/log/FileLogWriter.h @@ -42,9 +42,9 @@ public: private: # ifdef XMRIG_OS_WIN - char m_endl[3] = "\r\n"; + const char m_endl[3] = {'\r', '\n', 0}; # else - char m_endl[2] = "\n"; + const char m_endl[2] = {'\n', 0}; # endif int m_file = -1; diff --git a/src/base/kernel/config/BaseConfig.cpp b/src/base/kernel/config/BaseConfig.cpp index 1f2b09cb2..37982999e 100644 --- a/src/base/kernel/config/BaseConfig.cpp +++ b/src/base/kernel/config/BaseConfig.cpp @@ -23,6 +23,7 @@ #include "base/io/log/Log.h" #include "base/io/log/Tags.h" #include "base/kernel/interfaces/IJsonReader.h" +#include "base/net/dns/Dns.h" #include "version.h" @@ -105,6 +106,8 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName) m_http.load(reader.getObject(kHttp)); m_pools.load(reader); + Dns::set(reader.getObject(DnsConfig::kField)); + return m_pools.active() > 0; } diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index 55e082b61..3cd48d5a1 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -33,6 +33,7 @@ #include "base/kernel/config/BaseConfig.h" #include "base/kernel/interfaces/IConfig.h" #include "base/kernel/Process.h" +#include "base/net/dns/DnsConfig.h" #include "base/net/stratum/Pool.h" #include "base/net/stratum/Pools.h" #include "core/config/Config_platform.h" @@ -244,6 +245,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::HttpPort: /* --http-port */ case IConfig::DonateLevelKey: /* --donate-level */ case IConfig::DaemonPollKey: /* --daemon-poll-interval */ + case IConfig::DnsTtlKey: /* --dns-ttl */ return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10))); case IConfig::BackgroundKey: /* --background */ @@ -256,6 +258,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::DaemonKey: /* --daemon */ case IConfig::SubmitToOriginKey: /* --submit-to-origin */ case IConfig::VerboseKey: /* --verbose */ + case IConfig::DnsIPv6Key: /* --dns-ipv6 */ return transformBoolean(doc, key, true); case IConfig::ColorKey: /* --no-color */ @@ -316,6 +319,9 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b case IConfig::NoTitleKey: /* --no-title */ return set(doc, BaseConfig::kTitle, enable); + case IConfig::DnsIPv6Key: /* --dns-ipv6 */ + return set(doc, DnsConfig::kField, DnsConfig::kIPv6, enable); + default: break; } @@ -344,6 +350,9 @@ void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, ui case IConfig::PrintTimeKey: /* --print-time */ return set(doc, BaseConfig::kPrintTime, arg); + case IConfig::DnsTtlKey: /* --dns-ttl */ + return set(doc, DnsConfig::kField, DnsConfig::kTTL, arg); + # ifdef XMRIG_FEATURE_HTTP case IConfig::DaemonPollKey: /* --daemon-poll-interval */ return add(doc, Pools::kPools, Pool::kDaemonPollInterval, arg); diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 7a7f657ec..ec3d85103 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -82,6 +82,8 @@ public: HugePageSizeKey = 1050, PauseOnActiveKey = 1051, SubmitToOriginKey = 1052, + DnsIPv6Key = 1053, + DnsTtlKey = 1054, // xmrig common CPUPriorityKey = 1021, diff --git a/src/base/kernel/interfaces/IDnsBackend.h b/src/base/kernel/interfaces/IDnsBackend.h new file mode 100644 index 000000000..ca676f326 --- /dev/null +++ b/src/base/kernel/interfaces/IDnsBackend.h @@ -0,0 +1,54 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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_IDNSBACKEND_H +#define XMRIG_IDNSBACKEND_H + + +#include "base/tools/Object.h" + + +#include <memory> + + +namespace xmrig { + + +class DnsRecords; +class DnsRequest; +class IDnsListener; +class String; + + +class IDnsBackend +{ +public: + XMRIG_DISABLE_COPY_MOVE(IDnsBackend) + + IDnsBackend() = default; + virtual ~IDnsBackend() = default; + + virtual const DnsRecords &records() const = 0; + virtual std::shared_ptr<DnsRequest> resolve(const String &host, IDnsListener *listener, uint64_t ttl) = 0; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_IDNSBACKEND_H diff --git a/src/base/kernel/interfaces/IDnsListener.h b/src/base/kernel/interfaces/IDnsListener.h index 7d0e14e36..b9d20efa9 100644 --- a/src/base/kernel/interfaces/IDnsListener.h +++ b/src/base/kernel/interfaces/IDnsListener.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> - * Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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 @@ -26,7 +26,7 @@ namespace xmrig { -class Dns; +class DnsRecords; class IDnsListener @@ -37,7 +37,7 @@ public: IDnsListener() = default; virtual ~IDnsListener() = default; - virtual void onResolved(const Dns &dns, int status) = 0; + virtual void onResolved(const DnsRecords &records, int status, const char *error) = 0; }; diff --git a/src/base/net/dns/Dns.cpp b/src/base/net/dns/Dns.cpp index ef50b20dc..85590bb7d 100644 --- a/src/base/net/dns/Dns.cpp +++ b/src/base/net/dns/Dns.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> - * Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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 @@ -18,136 +18,24 @@ #include "base/net/dns/Dns.h" -#include "base/kernel/interfaces/IDnsListener.h" +#include "base/net/dns/DnsUvBackend.h" namespace xmrig { - Storage<Dns> Dns::m_storage; - static const DnsRecord defaultRecord; -} -xmrig::Dns::Dns(IDnsListener *listener) : - m_listener(listener) +DnsConfig Dns::m_config; +std::map<String, std::shared_ptr<IDnsBackend> > Dns::m_backends; + + +} // namespace xmrig + + +std::shared_ptr<xmrig::DnsRequest> xmrig::Dns::resolve(const String &host, IDnsListener *listener, uint64_t ttl) { - m_key = m_storage.add(this); + if (m_backends.find(host) == m_backends.end()) { + m_backends.insert({ host, std::make_shared<DnsUvBackend>() }); + } - m_resolver = new uv_getaddrinfo_t; - m_resolver->data = m_storage.ptr(m_key); - - m_hints.ai_family = AF_UNSPEC; - m_hints.ai_socktype = SOCK_STREAM; - m_hints.ai_protocol = IPPROTO_TCP; -} - - -xmrig::Dns::~Dns() -{ - m_storage.release(m_key); - - delete m_resolver; -} - - -bool xmrig::Dns::resolve(const String &host) -{ - if (m_host != host) { - m_host = host; - - clear(); - } - - m_status = uv_getaddrinfo(uv_default_loop(), m_resolver, Dns::onResolved, m_host.data(), nullptr, &m_hints); - - return m_status == 0; -} - - -const char *xmrig::Dns::error() const -{ - return uv_strerror(m_status); -} - - -const xmrig::DnsRecord &xmrig::Dns::get(DnsRecord::Type prefered) const -{ - if (count() == 0) { - return defaultRecord; - } - - const size_t ipv4 = m_ipv4.size(); - const size_t ipv6 = m_ipv6.size(); - - if (ipv6 && (prefered == DnsRecord::AAAA || !ipv4)) { - return m_ipv6[ipv6 == 1 ? 0 : static_cast<size_t>(rand()) % ipv6]; - } - - if (ipv4) { - return m_ipv4[ipv4 == 1 ? 0 : static_cast<size_t>(rand()) % ipv4]; - } - - return defaultRecord; -} - - -size_t xmrig::Dns::count(DnsRecord::Type type) const -{ - if (type == DnsRecord::A) { - return m_ipv4.size(); - } - - if (type == DnsRecord::AAAA) { - return m_ipv6.size(); - } - - return m_ipv4.size() + m_ipv6.size(); -} - - -void xmrig::Dns::clear() -{ - m_ipv4.clear(); - m_ipv6.clear(); -} - - -void xmrig::Dns::onResolved(int status, addrinfo *res) -{ - m_status = status; - - if (m_status < 0) { - return m_listener->onResolved(*this, status); - } - - clear(); - - addrinfo *ptr = res; - while (ptr != nullptr) { - if (ptr->ai_family == AF_INET) { - m_ipv4.emplace_back(ptr); - } - - if (ptr->ai_family == AF_INET6) { - m_ipv6.emplace_back(ptr); - } - - ptr = ptr->ai_next; - } - - if (isEmpty()) { - m_status = UV_EAI_NONAME; - } - - m_listener->onResolved(*this, m_status); -} - - -void xmrig::Dns::onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res) -{ - Dns *dns = m_storage.get(req->data); - if (dns) { - dns->onResolved(status, res); - } - - uv_freeaddrinfo(res); + return m_backends.at(host)->resolve(host, listener, ttl == 0 ? m_config.ttl() : ttl); } diff --git a/src/base/net/dns/Dns.h b/src/base/net/dns/Dns.h index 86f901451..cf054390f 100644 --- a/src/base/net/dns/Dns.h +++ b/src/base/net/dns/Dns.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> - * Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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 @@ -20,55 +20,34 @@ #define XMRIG_DNS_H -#include <vector> -#include <uv.h> - - -#include "base/net/dns/DnsRecord.h" -#include "base/net/tools/Storage.h" -#include "base/tools/Object.h" +#include "base/net/dns/DnsConfig.h" #include "base/tools/String.h" +#include <map> +#include <memory> + + namespace xmrig { +class DnsConfig; +class DnsRequest; +class IDnsBackend; class IDnsListener; class Dns { public: - XMRIG_DISABLE_COPY_MOVE_DEFAULT(Dns) + inline static const DnsConfig &config() { return m_config; } + inline static void set(const DnsConfig &config) { m_config = config; } - Dns(IDnsListener *listener); - ~Dns(); - - inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); } - inline const String &host() const { return m_host; } - inline int status() const { return m_status; } - - bool resolve(const String &host); - const char *error() const; - const DnsRecord &get(DnsRecord::Type prefered = DnsRecord::A) const; - size_t count(DnsRecord::Type type = DnsRecord::Unknown) const; + static std::shared_ptr<DnsRequest> resolve(const String &host, IDnsListener *listener, uint64_t ttl = 0); private: - void clear(); - void onResolved(int status, addrinfo *res); - - static void onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res); - - addrinfo m_hints{}; - IDnsListener *m_listener; - int m_status = 0; - std::vector<DnsRecord> m_ipv4; - std::vector<DnsRecord> m_ipv6; - String m_host; - uintptr_t m_key; - uv_getaddrinfo_t *m_resolver = nullptr; - - static Storage<Dns> m_storage; + static DnsConfig m_config; + static std::map<String, std::shared_ptr<IDnsBackend> > m_backends; }; diff --git a/src/base/net/dns/DnsConfig.cpp b/src/base/net/dns/DnsConfig.cpp new file mode 100644 index 000000000..c2446c2a6 --- /dev/null +++ b/src/base/net/dns/DnsConfig.cpp @@ -0,0 +1,57 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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/dns/DnsConfig.h" +#include "3rdparty/rapidjson/document.h" +#include "base/io/json/Json.h" + + +#include <algorithm> + + +namespace xmrig { + + +const char *DnsConfig::kField = "dns"; +const char *DnsConfig::kIPv6 = "ipv6"; +const char *DnsConfig::kTTL = "ttl"; + + +} // namespace xmrig + + +xmrig::DnsConfig::DnsConfig(const rapidjson::Value &value) +{ + m_ipv6 = Json::getBool(value, kIPv6, m_ipv6); + m_ttl = std::max(Json::getUint(value, kTTL, m_ttl), 1U); +} + + +rapidjson::Value xmrig::DnsConfig::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + auto &allocator = doc.GetAllocator(); + Value obj(kObjectType); + + obj.AddMember(StringRef(kIPv6), m_ipv6, allocator); + obj.AddMember(StringRef(kTTL), m_ttl, allocator); + + return obj; +} diff --git a/src/base/net/dns/DnsConfig.h b/src/base/net/dns/DnsConfig.h new file mode 100644 index 000000000..d42c8ad8b --- /dev/null +++ b/src/base/net/dns/DnsConfig.h @@ -0,0 +1,54 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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_DNSCONFIG_H +#define XMRIG_DNSCONFIG_H + + +#include "3rdparty/rapidjson/fwd.h" + + +namespace xmrig { + + +class DnsConfig +{ +public: + static const char *kField; + static const char *kIPv6; + static const char *kTTL; + + DnsConfig() = default; + DnsConfig(const rapidjson::Value &object); + + inline bool isIPv6() const { return m_ipv6; } + inline uint32_t ttl() const { return m_ttl * 1000U; } + + rapidjson::Value toJSON(rapidjson::Document &doc) const; + + +private: + bool m_ipv6 = false; + uint32_t m_ttl = 30U; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_DNSCONFIG_H */ diff --git a/src/base/net/dns/DnsRecord.cpp b/src/base/net/dns/DnsRecord.cpp index 1667c715c..bfa84613a 100644 --- a/src/base/net/dns/DnsRecord.cpp +++ b/src/base/net/dns/DnsRecord.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> - * Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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 @@ -24,38 +24,34 @@ xmrig::DnsRecord::DnsRecord(const addrinfo *addr) : - m_type(addr->ai_family == AF_INET6 ? AAAA : A) + m_type(addr->ai_family == AF_INET6 ? AAAA : (addr->ai_family == AF_INET ? A : Unknown)) +{ + static_assert(sizeof(m_data) >= sizeof(sockaddr_in6), "Not enough storage for IPv6 address."); + + memcpy(m_data, addr->ai_addr, m_type == AAAA ? sizeof(sockaddr_in6) : sizeof(sockaddr_in)); +} + + +const sockaddr *xmrig::DnsRecord::addr(uint16_t port) const +{ + reinterpret_cast<sockaddr_in*>(m_data)->sin_port = htons(port); + + return reinterpret_cast<const sockaddr *>(m_data); +} + + +xmrig::String xmrig::DnsRecord::ip() const { char *buf = nullptr; if (m_type == AAAA) { buf = new char[45](); - uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), buf, 45); + uv_ip6_name(reinterpret_cast<sockaddr_in6*>(m_data), buf, 45); } else { buf = new char[16](); - uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), buf, 16); + uv_ip4_name(reinterpret_cast<sockaddr_in*>(m_data), buf, 16); } - m_ip = buf; -} - - -sockaddr *xmrig::DnsRecord::addr(uint16_t port) const -{ - if (m_type == A) { - auto addr = new sockaddr_in(); - uv_ip4_addr(m_ip.data(), port, addr); - - return reinterpret_cast<sockaddr *>(addr); - } - - if (m_type == AAAA) { - auto addr = new sockaddr_in6(); - uv_ip6_addr(m_ip.data(), port, addr); - - return reinterpret_cast<sockaddr *>(addr); - } - - return nullptr; + return buf; } diff --git a/src/base/net/dns/DnsRecord.h b/src/base/net/dns/DnsRecord.h index cf6c25986..7a68ea2f7 100644 --- a/src/base/net/dns/DnsRecord.h +++ b/src/base/net/dns/DnsRecord.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> - * Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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 @@ -33,7 +33,7 @@ namespace xmrig { class DnsRecord { public: - enum Type { + enum Type : uint32_t { Unknown, A, AAAA @@ -42,15 +42,15 @@ public: DnsRecord() {} DnsRecord(const addrinfo *addr); - sockaddr *addr(uint16_t port = 0) const; + const sockaddr *addr(uint16_t port = 0) const; + String ip() const; inline bool isValid() const { return m_type != Unknown; } - inline const String &ip() const { return m_ip; } inline Type type() const { return m_type; } private: - Type m_type = Unknown; - String m_ip; + mutable uint8_t m_data[28]{}; + const Type m_type = Unknown; }; diff --git a/src/base/net/dns/DnsRecords.cpp b/src/base/net/dns/DnsRecords.cpp new file mode 100644 index 000000000..fb232f276 --- /dev/null +++ b/src/base/net/dns/DnsRecords.cpp @@ -0,0 +1,108 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <uv.h> + + +#include "base/net/dns/DnsRecords.h" +#include "base/net/dns/Dns.h" + + +const xmrig::DnsRecord &xmrig::DnsRecords::get(DnsRecord::Type prefered) const +{ + static const DnsRecord defaultRecord; + + if (isEmpty()) { + return defaultRecord; + } + + const size_t ipv4 = m_ipv4.size(); + const size_t ipv6 = m_ipv6.size(); + + if (ipv6 && (prefered == DnsRecord::AAAA || Dns::config().isIPv6() || !ipv4)) { + return m_ipv6[ipv6 == 1 ? 0 : static_cast<size_t>(rand()) % ipv6]; + } + + if (ipv4) { + return m_ipv4[ipv4 == 1 ? 0 : static_cast<size_t>(rand()) % ipv4]; + } + + return defaultRecord; +} + + +size_t xmrig::DnsRecords::count(DnsRecord::Type type) const +{ + if (type == DnsRecord::A) { + return m_ipv4.size(); + } + + if (type == DnsRecord::AAAA) { + return m_ipv6.size(); + } + + return m_ipv4.size() + m_ipv6.size(); +} + + +void xmrig::DnsRecords::clear() +{ + m_ipv4.clear(); + m_ipv6.clear(); +} + + +void xmrig::DnsRecords::parse(addrinfo *res) +{ + clear(); + + addrinfo *ptr = res; + size_t ipv4 = 0; + size_t ipv6 = 0; + + while (ptr != nullptr) { + if (ptr->ai_family == AF_INET) { + ++ipv4; + } + else if (ptr->ai_family == AF_INET6) { + ++ipv6; + } + + ptr = ptr->ai_next; + } + + if (ipv4 == 0 && ipv6 == 0) { + return; + } + + m_ipv4.reserve(ipv4); + m_ipv6.reserve(ipv6); + + ptr = res; + while (ptr != nullptr) { + if (ptr->ai_family == AF_INET) { + m_ipv4.emplace_back(ptr); + } + else if (ptr->ai_family == AF_INET6) { + m_ipv6.emplace_back(ptr); + } + + ptr = ptr->ai_next; + } +} diff --git a/src/base/net/dns/DnsRecords.h b/src/base/net/dns/DnsRecords.h new file mode 100644 index 000000000..cfa192179 --- /dev/null +++ b/src/base/net/dns/DnsRecords.h @@ -0,0 +1,48 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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_DNSRECORDS_H +#define XMRIG_DNSRECORDS_H + + +#include "base/net/dns/DnsRecord.h" + + +namespace xmrig { + + +class DnsRecords +{ +public: + inline bool isEmpty() const { return m_ipv4.empty() && m_ipv6.empty(); } + + const DnsRecord &get(DnsRecord::Type prefered = DnsRecord::Unknown) const; + size_t count(DnsRecord::Type type = DnsRecord::Unknown) const; + void clear(); + void parse(addrinfo *res); + +private: + std::vector<DnsRecord> m_ipv4; + std::vector<DnsRecord> m_ipv6; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_DNSRECORDS_H */ diff --git a/src/base/net/dns/DnsRequest.h b/src/base/net/dns/DnsRequest.h new file mode 100644 index 000000000..036eaa34f --- /dev/null +++ b/src/base/net/dns/DnsRequest.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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_DNSREQUEST_H +#define XMRIG_DNSREQUEST_H + + +#include "base/tools/Object.h" + + +#include <cstdint> + + +namespace xmrig { + + +class IDnsListener; + + +class DnsRequest +{ +public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(DnsRequest) + + DnsRequest(IDnsListener *listener) : listener(listener) {} + ~DnsRequest() = default; + + IDnsListener *listener; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_DNSREQUEST_H */ diff --git a/src/base/net/dns/DnsUvBackend.cpp b/src/base/net/dns/DnsUvBackend.cpp new file mode 100644 index 000000000..cb1c0c3eb --- /dev/null +++ b/src/base/net/dns/DnsUvBackend.cpp @@ -0,0 +1,134 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <uv.h> + + +#include "base/net/dns/DnsUvBackend.h" +#include "base/kernel/interfaces/IDnsListener.h" +#include "base/net/dns/DnsRequest.h" +#include "base/tools/Chrono.h" + + +namespace xmrig { + + +Storage<DnsUvBackend>& DnsUvBackend::getStorage() +{ + static Storage<DnsUvBackend>* storage = new Storage<DnsUvBackend>(); + return *storage; +} + +static addrinfo hints{}; + + +} // namespace xmrig + + +xmrig::DnsUvBackend::DnsUvBackend() +{ + if (!hints.ai_protocol) { + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + } + + m_key = getStorage().add(this); +} + + +xmrig::DnsUvBackend::~DnsUvBackend() +{ + getStorage().release(m_key); +} + + +std::shared_ptr<xmrig::DnsRequest> xmrig::DnsUvBackend::resolve(const String &host, IDnsListener *listener, uint64_t ttl) +{ + auto req = std::make_shared<DnsRequest>(listener); + + if (Chrono::currentMSecsSinceEpoch() - m_ts <= ttl && !m_records.isEmpty()) { + req->listener->onResolved(m_records, 0, nullptr); + } else { + m_queue.emplace(req); + } + + if (m_queue.size() == 1 && !resolve(host)) { + done(); + } + + return req; +} + + +bool xmrig::DnsUvBackend::resolve(const String &host) +{ + m_req = std::make_shared<uv_getaddrinfo_t>(); + m_req->data = getStorage().ptr(m_key); + + m_status = uv_getaddrinfo(uv_default_loop(), m_req.get(), DnsUvBackend::onResolved, host.data(), nullptr, &hints); + + return m_status == 0; +} + + +void xmrig::DnsUvBackend::done() +{ + const char *error = m_status < 0 ? uv_strerror(m_status) : nullptr; + + while (!m_queue.empty()) { + auto req = std::move(m_queue.front()).lock(); + if (req) { + req->listener->onResolved(m_records, m_status, error); + } + + m_queue.pop(); + } + + m_req.reset(); +} + + +void xmrig::DnsUvBackend::onResolved(int status, addrinfo *res) +{ + m_ts = Chrono::currentMSecsSinceEpoch(); + + if ((m_status = status) < 0) { + return done(); + } + + m_records.parse(res); + + if (m_records.isEmpty()) { + m_status = UV_EAI_NONAME; + } + + done(); +} + + +void xmrig::DnsUvBackend::onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res) +{ + auto backend = getStorage().get(req->data); + if (backend) { + backend->onResolved(status, res); + } + + uv_freeaddrinfo(res); +} diff --git a/src/base/net/dns/DnsUvBackend.h b/src/base/net/dns/DnsUvBackend.h new file mode 100644 index 000000000..f3733f5a4 --- /dev/null +++ b/src/base/net/dns/DnsUvBackend.h @@ -0,0 +1,71 @@ +/* XMRig + * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh> + * Copyright (c) 2016-2021 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_DNSUVBACKEND_H +#define XMRIG_DNSUVBACKEND_H + + +#include "base/kernel/interfaces/IDnsBackend.h" +#include "base/net/dns/DnsRecords.h" +#include "base/net/tools/Storage.h" + + +#include <queue> + + +using uv_getaddrinfo_t = struct uv_getaddrinfo_s; + + +namespace xmrig { + + +class DnsUvBackend : public IDnsBackend +{ +public: + XMRIG_DISABLE_COPY_MOVE(DnsUvBackend) + + DnsUvBackend(); + ~DnsUvBackend() override; + +protected: + inline const DnsRecords &records() const override { return m_records; } + + std::shared_ptr<DnsRequest> resolve(const String &host, IDnsListener *listener, uint64_t ttl) override; + +private: + bool resolve(const String &host); + void done(); + void onResolved(int status, addrinfo *res); + + static void onResolved(uv_getaddrinfo_t *req, int status, addrinfo *res); + + DnsRecords m_records; + int m_status = 0; + std::queue<std::weak_ptr<DnsRequest> > m_queue; + std::shared_ptr<uv_getaddrinfo_t> m_req; + uint64_t m_ts = 0; + uintptr_t m_key; + + static Storage<DnsUvBackend>& getStorage(); +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_DNSUVBACKEND_H */ diff --git a/src/base/net/http/HttpClient.cpp b/src/base/net/http/HttpClient.cpp index ea0d68c82..96f3f5563 100644 --- a/src/base/net/http/HttpClient.cpp +++ b/src/base/net/http/HttpClient.cpp @@ -23,11 +23,13 @@ #include "base/io/log/Log.h" #include "base/kernel/Platform.h" #include "base/net/dns/Dns.h" +#include "base/net/dns/DnsRecords.h" #include "base/net/tools/NetBuffer.h" #include "base/tools/Timer.h" #include <sstream> +#include <uv.h> namespace xmrig { @@ -48,7 +50,6 @@ xmrig::HttpClient::HttpClient(const char *tag, FetchRequest &&req, const std::we url = std::move(m_req.path); body = std::move(m_req.body); headers = std::move(m_req.headers); - m_dns = std::make_shared<Dns>(this); if (m_req.timeout) { m_timer = std::make_shared<Timer>(this, m_req.timeout, 0); @@ -58,30 +59,29 @@ xmrig::HttpClient::HttpClient(const char *tag, FetchRequest &&req, const std::we bool xmrig::HttpClient::connect() { - return m_dns->resolve(m_req.host); + m_dns = Dns::resolve(m_req.host, this); + + return true; } -void xmrig::HttpClient::onResolved(const Dns &dns, int status) +void xmrig::HttpClient::onResolved(const DnsRecords &records, int status, const char *error) { this->status = status; + m_dns.reset(); - if (status < 0 && dns.isEmpty()) { + if (status < 0 && records.isEmpty()) { if (!isQuiet()) { - LOG_ERR("%s " RED("DNS error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(status)); + LOG_ERR("%s " RED("DNS error: ") RED_BOLD("\"%s\""), tag(), error); } return; } - 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; + uv_tcp_connect(req, m_tcp, records.get().addr(port()), onConnect); } diff --git a/src/base/net/http/HttpClient.h b/src/base/net/http/HttpClient.h index d012d26fb..ccda2e567 100644 --- a/src/base/net/http/HttpClient.h +++ b/src/base/net/http/HttpClient.h @@ -32,7 +32,7 @@ namespace xmrig { -class String; +class DnsRequest; class HttpClient : public HttpContext, public IDnsListener, public ITimerListener @@ -51,7 +51,7 @@ public: bool connect(); protected: - void onResolved(const Dns &dns, int status) override; + void onResolved(const DnsRecords &records, int status, const char *error) override; void onTimer(const Timer *timer) override; virtual void handshake(); @@ -65,7 +65,7 @@ private: const char *m_tag; FetchRequest m_req; - std::shared_ptr<Dns> m_dns; + std::shared_ptr<DnsRequest> m_dns; std::shared_ptr<Timer> m_timer; }; diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 5327867e7..78c0976f7 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -48,10 +48,11 @@ #include "base/io/log/Log.h" #include "base/kernel/interfaces/IClientListener.h" #include "base/net/dns/Dns.h" +#include "base/net/dns/DnsRecords.h" #include "base/net/stratum/Socks5.h" #include "base/net/tools/NetBuffer.h" -#include "base/tools/Cvt.h" #include "base/tools/Chrono.h" +#include "base/tools/Cvt.h" #include "net/JobResult.h" @@ -86,13 +87,11 @@ xmrig::Client::Client(int id, const char *agent, IClientListener *listener) : { m_reader.setListener(this); m_key = m_storage.add(this); - m_dns = new Dns(this); } xmrig::Client::~Client() { - delete m_dns; delete m_socket; } @@ -295,22 +294,24 @@ void xmrig::Client::tick(uint64_t now) } -void xmrig::Client::onResolved(const Dns &dns, int status) +void xmrig::Client::onResolved(const DnsRecords &records, int status, const char *error) { + m_dns.reset(); + assert(m_listener != nullptr); if (!m_listener) { return reconnect(); } - if (status < 0 && dns.isEmpty()) { + if (status < 0 && records.isEmpty()) { if (!isQuiet()) { - LOG_ERR("%s " RED("DNS error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(status)); + LOG_ERR("%s " RED("DNS error: ") RED_BOLD("\"%s\""), tag(), error); } return reconnect(); } - const auto &record = dns.get(); + const auto &record = records.get(); m_ip = record.ip(); connect(record.addr(m_socks5 ? m_pool.proxy().port() : m_pool.port())); @@ -377,6 +378,14 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } + const char *algo = Json::getString(params, "algo"); + if (algo) { + job.setAlgorithm(algo); + } + else if (m_pool.coin().isValid()) { + job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0])); + } + # ifdef XMRIG_FEATURE_HTTP if (m_pool.mode() == Pool::MODE_SELF_SELECT) { job.setExtraNonce(Json::getString(params, "extra_nonce")); @@ -401,14 +410,6 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - const char *algo = Json::getString(params, "algo"); - if (algo) { - job.setAlgorithm(algo); - } - else if (m_pool.coin().isValid()) { - job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0])); - } - job.setHeight(Json::getUint64(params, "height")); if (!verifyAlgorithm(job.algorithm(), algo)) { @@ -524,13 +525,7 @@ int xmrig::Client::resolve(const String &host) m_failures = 0; } - if (!m_dns->resolve(host)) { - if (!isQuiet()) { - LOG_ERR("%s " RED("getaddrinfo error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(m_dns->status())); - } - - return 1; - } + m_dns = Dns::resolve(host, this); return 0; } @@ -566,7 +561,7 @@ int64_t xmrig::Client::send(size_t size) } -void xmrig::Client::connect(sockaddr *addr) +void xmrig::Client::connect(const sockaddr *addr) { setState(ConnectingState); @@ -584,8 +579,6 @@ void xmrig::Client::connect(sockaddr *addr) # endif uv_tcp_connect(req, m_socket, addr, onConnect); - - delete addr; } diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h index 33e3fd8fa..e6508c656 100644 --- a/src/base/net/stratum/Client.h +++ b/src/base/net/stratum/Client.h @@ -50,6 +50,7 @@ using BIO = struct bio_st; namespace xmrig { +class DnsRequest; class IClientListener; class JobResult; @@ -79,7 +80,7 @@ protected: void deleteLater() override; void tick(uint64_t now) override; - void onResolved(const Dns &dns, int status) override; + void onResolved(const DnsRecords &records, int status, const char *error) override; inline bool hasExtension(Extension extension) const noexcept override { return m_extensions.test(extension); } inline const char *mode() const override { return "pool"; } @@ -108,7 +109,7 @@ private: bool write(const uv_buf_t &buf); int resolve(const String &host); int64_t send(size_t size); - void connect(sockaddr *addr); + void connect(const sockaddr *addr); void handshake(); void parse(char *line, size_t len); void parseExtensions(const rapidjson::Value &result); @@ -131,10 +132,10 @@ private: static inline Client *getClient(void *data) { return m_storage.get(data); } const char *m_agent; - Dns *m_dns; LineReader m_reader; Socks5 *m_socks5 = nullptr; std::bitset<EXT_MAX> m_extensions; + std::shared_ptr<DnsRequest> m_dns; std::vector<char> m_sendBuf; String m_rpcId; Tls *m_tls = nullptr; diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 087fd0f76..c429039dd 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -247,6 +247,10 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize); } + if (m_pool.coin().isValid()) { + job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0])); + } + if (blocktemplate.isNull() || !job.setBlob(m_blockhashingblob)) { *code = 4; return false; @@ -257,10 +261,6 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) job.setDiff(Json::getUint64(params, "difficulty")); job.setId(blocktemplate.data() + blocktemplate.size() - 32); - if (m_pool.coin().isValid()) { - job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0])); - } - m_job = std::move(job); m_blocktemplate = std::move(blocktemplate); m_prevHash = Json::getString(params, "prev_hash"); diff --git a/src/base/net/stratum/benchmark/BenchClient.cpp b/src/base/net/stratum/benchmark/BenchClient.cpp index 0e1093a11..39b50e869 100644 --- a/src/base/net/stratum/benchmark/BenchClient.cpp +++ b/src/base/net/stratum/benchmark/BenchClient.cpp @@ -27,6 +27,7 @@ #include "base/io/log/Tags.h" #include "base/kernel/interfaces/IClientListener.h" #include "base/net/dns/Dns.h" +#include "base/net/dns/DnsRecords.h" #include "base/net/http/Fetch.h" #include "base/net/http/HttpData.h" #include "base/net/http/HttpListener.h" @@ -47,8 +48,8 @@ xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, I std::vector<char> blob(112 * 2 + 1, '0'); blob.back() = '\0'; - m_job.setBlob(blob.data()); m_job.setAlgorithm(m_benchmark->algorithm()); + m_job.setBlob(blob.data()); m_job.setDiff(std::numeric_limits<uint64_t>::max()); m_job.setHeight(1); m_job.setId("00000000"); @@ -185,16 +186,18 @@ void xmrig::BenchClient::onHttpData(const HttpData &data) } -void xmrig::BenchClient::onResolved(const Dns &dns, int status) +void xmrig::BenchClient::onResolved(const DnsRecords &records, int status, const char *error) { # ifdef XMRIG_FEATURE_HTTP assert(!m_httpListener); + m_dns.reset(); + if (status < 0) { - return setError(dns.error(), "DNS error"); + return setError(error, "DNS error"); } - m_ip = dns.get().ip(); + m_ip = records.get().ip(); m_httpListener = std::make_shared<HttpListener>(this, tag()); if (m_mode == ONLINE_BENCH) { @@ -307,11 +310,7 @@ void xmrig::BenchClient::onGetReply(const rapidjson::Value &value) void xmrig::BenchClient::resolve() { - m_dns = std::make_shared<Dns>(this); - - if (!m_dns->resolve(BenchConfig::kApiHost)) { - setError(m_dns->error(), "getaddrinfo error"); - } + m_dns = Dns::resolve(BenchConfig::kApiHost, this); } diff --git a/src/base/net/stratum/benchmark/BenchClient.h b/src/base/net/stratum/benchmark/BenchClient.h index 7eac1ee87..a4cedf612 100644 --- a/src/base/net/stratum/benchmark/BenchClient.h +++ b/src/base/net/stratum/benchmark/BenchClient.h @@ -70,7 +70,7 @@ protected: void onBenchDone(uint64_t result, uint64_t diff, uint64_t ts) override; void onBenchReady(uint64_t ts, uint32_t threads, const IBackend *backend) override; void onHttpData(const HttpData &data) override; - void onResolved(const Dns &dns, int status) override; + void onResolved(const DnsRecords &records, int status, const char *error) override; private: enum Mode : uint32_t { @@ -110,7 +110,7 @@ private: Pool m_pool; Request m_request = NO_REQUEST; std::shared_ptr<BenchConfig> m_benchmark; - std::shared_ptr<Dns> m_dns; + std::shared_ptr<DnsRequest> m_dns; std::shared_ptr<IHttpListener> m_httpListener; String m_ip; String m_token; diff --git a/src/base/tools/Handle.h b/src/base/tools/Handle.h index a25381d8c..fcd341478 100644 --- a/src/base/tools/Handle.h +++ b/src/base/tools/Handle.h @@ -45,7 +45,7 @@ public: return; } - uv_close(reinterpret_cast<uv_handle_t *>(handle), [](uv_handle_t *handle) { delete handle; }); + uv_close(reinterpret_cast<uv_handle_t *>(handle), [](uv_handle_t *handle) { delete reinterpret_cast<T>(handle); }); } }; diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 2b27ae58d..3924123f0 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -28,6 +28,7 @@ #include "backend/cpu/Cpu.h" #include "base/io/log/Log.h" #include "base/kernel/interfaces/IJsonReader.h" +#include "base/net/dns/Dns.h" #include "crypto/common/Assembly.h" @@ -295,6 +296,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember(StringRef(kTls), m_tls.toJSON(doc), allocator); # endif + doc.AddMember(StringRef(DnsConfig::kField), Dns::config().toJSON(doc), allocator); doc.AddMember(StringRef(kUserAgent), m_userAgent.toJSON(), allocator); doc.AddMember(StringRef(kVerbose), Log::verbose(), allocator); doc.AddMember(StringRef(kWatch), m_watch, allocator); diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index d54299753..f92a3158a 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -93,7 +93,9 @@ static const option options[] = { { "title", 1, nullptr, IConfig::TitleKey }, { "no-title", 0, nullptr, IConfig::NoTitleKey }, { "pause-on-battery", 0, nullptr, IConfig::PauseOnBatteryKey }, - { "pause-on-active", 1, nullptr, IConfig::PauseOnActiveKey }, + { "pause-on-active", 1, nullptr, IConfig::PauseOnActiveKey }, + { "dns-ipv6", 0, nullptr, IConfig::DnsIPv6Key }, + { "dns-ttl", 1, nullptr, IConfig::DnsTtlKey }, # ifdef XMRIG_FEATURE_BENCHMARK { "stress", 0, nullptr, IConfig::StressKey }, { "bench", 1, nullptr, IConfig::BenchKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index 57374620a..f16124cba 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -59,6 +59,9 @@ static inline const std::string &usage() u += " --tls-fingerprint=HEX pool TLS certificate fingerprint for strict certificate pinning\n"; # endif + u += " --dns-ipv6 prefer IPv6 records from DNS responses\n"; + u += " --dns-ttl=N N seconds (default: 30) TTL for internal DNS cache\n"; + # ifdef XMRIG_FEATURE_HTTP u += " --daemon use daemon RPC instead of pool for solo mining\n"; u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n"; diff --git a/src/crypto/cn/CryptoNight_monero.h b/src/crypto/cn/CryptoNight_monero.h index 8b192083f..f34c963c9 100644 --- a/src/crypto/cn/CryptoNight_monero.h +++ b/src/crypto/cn/CryptoNight_monero.h @@ -190,8 +190,8 @@ r##part[1] = static_cast<uint32_t>(h##part[12] >> 32); \ r##part[2] = static_cast<uint32_t>(h##part[13]); \ r##part[3] = static_cast<uint32_t>(h##part[13] >> 32); \ - } \ - v4_random_math_init<ALGO>(code##part, height); + v4_random_math_init<ALGO>(code##part, height); \ + } #define VARIANT4_RANDOM_MATH(part, al, ah, cl, bx0, bx1) \ if (props.isR()) { \ diff --git a/src/crypto/cn/CryptoNight_x86.h b/src/crypto/cn/CryptoNight_x86.h index 7cc4e062f..cd79f1df0 100644 --- a/src/crypto/cn/CryptoNight_x86.h +++ b/src/crypto/cn/CryptoNight_x86.h @@ -739,8 +739,18 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si # ifdef XMRIG_ALGO_CN_HEAVY if (props.isHeavy()) { int64_t n = ((int64_t*)&l0[interleaved_index<interleave>(idx0 & MASK)])[0]; - int32_t d = ((int32_t*)&l0[interleaved_index<interleave>(idx0 & MASK)])[2]; - int64_t q = n / (d | 0x5); + int64_t d = ((int32_t*)&l0[interleaved_index<interleave>(idx0 & MASK)])[2]; + + int64_t d5; + +# if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 8)) + d5 = d | 5; +# else + // Workaround for stupid GCC which converts to 32 bit before doing "| 5" and then converts back to 64 bit + asm("mov %1, %0\n\tor $5, %0" : "=r"(d5) : "r"(d)); +# endif + + int64_t q = n / d5; ((int64_t*)&l0[interleaved_index<interleave>(idx0 & MASK)])[0] = n ^ q; diff --git a/src/crypto/cn/sse2neon.h b/src/crypto/cn/sse2neon.h index 039697a69..2ca95f9a3 100644 --- a/src/crypto/cn/sse2neon.h +++ b/src/crypto/cn/sse2neon.h @@ -343,7 +343,7 @@ typedef union ALIGN_STRUCT(16) SIMDVec { // Older gcc does not define vld1q_u8_x4 type #if defined(__GNUC__) && !defined(__clang__) && \ - ((__GNUC__ == 10 && (__GNUC_MINOR__ <= 1)) || \ + ((__GNUC__ == 10 && (__GNUC_MINOR__ <= 2)) || \ (__GNUC__ == 9 && (__GNUC_MINOR__ <= 3)) || \ (__GNUC__ == 8 && (__GNUC_MINOR__ <= 4)) || __GNUC__ <= 7) FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) diff --git a/src/crypto/randomx/common.hpp b/src/crypto/randomx/common.hpp index aefbad032..98f96727b 100644 --- a/src/crypto/randomx/common.hpp +++ b/src/crypto/randomx/common.hpp @@ -103,7 +103,7 @@ namespace randomx { #endif #endif -#if defined(_M_X64) || defined(__x86_64__) +#if defined(XMRIG_FEATURE_ASM) && (defined(_M_X64) || defined(__x86_64__)) #define RANDOMX_HAVE_COMPILER 1 class JitCompilerX86; using JitCompiler = JitCompilerX86; diff --git a/src/crypto/randomx/jit_compiler.hpp b/src/crypto/randomx/jit_compiler.hpp index 03b605085..db635c6f4 100644 --- a/src/crypto/randomx/jit_compiler.hpp +++ b/src/crypto/randomx/jit_compiler.hpp @@ -28,7 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma once -#if defined(_M_X64) || defined(__x86_64__) +#if defined(XMRIG_FEATURE_ASM) && (defined(_M_X64) || defined(__x86_64__)) #include "crypto/randomx/jit_compiler_x86.hpp" #elif defined(__aarch64__) #include "crypto/randomx/jit_compiler_a64.hpp" diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index 9986a33fb..527cca92e 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -148,7 +148,7 @@ RandomX_ConfigurationBase::RandomX_ConfigurationBase() fillAes4Rx4_Key[6] = rx_set_int_vec_i128(0xf63befa7, 0x2ba9660a, 0xf765a38b, 0xf273c9e7); fillAes4Rx4_Key[7] = rx_set_int_vec_i128(0xc0b0762d, 0x0c06d1fd, 0x915839de, 0x7a7cd609); -# if defined(_M_X64) || defined(__x86_64__) +# if defined(XMRIG_FEATURE_ASM) && (defined(_M_X64) || defined(__x86_64__)) // Workaround for Visual Studio placing trampoline in debug builds. auto addr = [](void (*func)()) { const uint8_t* p = reinterpret_cast<const uint8_t*>(func); @@ -214,7 +214,7 @@ void RandomX_ConfigurationBase::Apply() ScratchpadL3Mask_Calculated = (((ScratchpadL3_Size / sizeof(uint64_t)) - 1) * 8); ScratchpadL3Mask64_Calculated = ((ScratchpadL3_Size / sizeof(uint64_t)) / 8 - 1) * 64; -#if defined(_M_X64) || defined(__x86_64__) +#if defined(XMRIG_FEATURE_ASM) && (defined(_M_X64) || defined(__x86_64__)) *(uint32_t*)(codeShhPrefetchTweaked + 3) = ArgonMemory * 16 - 1; // Not needed right now because all variants use default dataset base size //const uint32_t DatasetBaseMask = DatasetBaseSize - RANDOMX_DATASET_ITEM_SIZE; diff --git a/src/version.h b/src/version.h index 3b369927c..426f6544f 100644 --- a/src/version.h +++ b/src/version.h @@ -28,14 +28,14 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.10.0" +#define APP_VERSION "6.11.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com" #define APP_KIND "miner" #define APP_VER_MAJOR 6 -#define APP_VER_MINOR 10 +#define APP_VER_MINOR 11 #define APP_VER_PATCH 0 #ifdef _MSC_VER