diff --git a/README.md b/README.md index 99d798f1..2110d280 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Network: -u, --user=USERNAME username for mining server -p, --pass=PASSWORD password for mining server -O, --userpass=U:P username:password pair for mining server + -x, --proxy=HOST:PORT connect through a SOCKS5 proxy -k, --keepalive send keepalive packet for prevent timeout (needs pool support) --nicehash enable nicehash.com support --rig-id=ID rig identifier for pool-side statistics (needs pool support) diff --git a/src/base/base.cmake b/src/base/base.cmake index 85ee7131..47996f33 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -40,6 +40,8 @@ set(HEADERS_BASE src/base/net/stratum/NetworkState.h src/base/net/stratum/Pool.h src/base/net/stratum/Pools.h + src/base/net/stratum/ProxyUrl.h + src/base/net/stratum/Socks5.h src/base/net/stratum/strategies/FailoverStrategy.h src/base/net/stratum/strategies/SinglePoolStrategy.h src/base/net/stratum/strategies/StrategyProxy.h @@ -82,6 +84,8 @@ set(SOURCES_BASE src/base/net/stratum/NetworkState.cpp src/base/net/stratum/Pool.cpp src/base/net/stratum/Pools.cpp + src/base/net/stratum/ProxyUrl.cpp + src/base/net/stratum/Socks5.cpp src/base/net/stratum/strategies/FailoverStrategy.cpp src/base/net/stratum/strategies/SinglePoolStrategy.cpp src/base/net/stratum/Url.cpp diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index 71b3b3ad..1894f0c6 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -176,6 +176,9 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::SelfSelectKey: /* --self-select */ return add(doc, Pools::kPools, Pool::kSelfSelect, arg); + case IConfig::ProxyKey: /* --proxy */ + return add(doc, Pools::kPools, Pool::kSOCKS5, arg); + case IConfig::LogFileKey: /* --log-file */ return set(doc, BaseConfig::kLogFile, arg); diff --git a/src/base/kernel/interfaces/IClient.h b/src/base/kernel/interfaces/IClient.h index db88638a..9349aa6a 100644 --- a/src/base/kernel/interfaces/IClient.h +++ b/src/base/kernel/interfaces/IClient.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 @@ -39,6 +39,7 @@ class Algorithm; class Job; class JobResult; class Pool; +class ProxyUrl; class String; @@ -79,6 +80,7 @@ public: virtual void setAlgo(const Algorithm &algo) = 0; virtual void setEnabled(bool enabled) = 0; virtual void setPool(const Pool &pool) = 0; + virtual void setProxy(const ProxyUrl &proxy) = 0; virtual void setQuiet(bool quiet) = 0; virtual void setRetries(int retries) = 0; virtual void setRetryPause(uint64_t ms) = 0; diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 26f71469..470f36ef 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -66,6 +66,7 @@ public: UserAgentKey = 1008, UserKey = 'u', UserpassKey = 'O', + ProxyKey = 'x', VerboseKey = 1100, TlsKey = 1013, FingerprintKey = 1014, diff --git a/src/base/kernel/interfaces/IStrategy.h b/src/base/kernel/interfaces/IStrategy.h index a0a24987..fc34521d 100644 --- a/src/base/kernel/interfaces/IStrategy.h +++ b/src/base/kernel/interfaces/IStrategy.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,7 @@ namespace xmrig { class Algorithm; class IClient; class JobResult; +class ProxyUrl; class IStrategy @@ -48,6 +49,7 @@ public: virtual void connect() = 0; virtual void resume() = 0; virtual void setAlgo(const Algorithm &algo) = 0; + virtual void setProxy(const ProxyUrl &proxy) = 0; virtual void stop() = 0; virtual void tick(uint64_t now) = 0; }; diff --git a/src/base/net/stratum/BaseClient.h b/src/base/net/stratum/BaseClient.h index 5726b3e5..700f78e9 100644 --- a/src/base/net/stratum/BaseClient.h +++ b/src/base/net/stratum/BaseClient.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 @@ -56,6 +56,7 @@ protected: inline int64_t sequence() const override { return m_sequence; } inline void setAlgo(const Algorithm &algo) override { m_pool.setAlgo(algo); } inline void setEnabled(bool enabled) override { m_enabled = enabled; } + inline void setProxy(const ProxyUrl &proxy) override { m_pool.setProxy(proxy); } inline void setQuiet(bool quiet) override { m_quiet = quiet; } inline void setRetries(int retries) override { m_retries = retries; } inline void setRetryPause(uint64_t ms) override { m_retryPause = ms; } diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index b5036e92..bd7b2219 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -44,6 +44,7 @@ #include "base/kernel/interfaces/IClientListener.h" #include "base/net/dns/Dns.h" #include "base/net/stratum/Client.h" +#include "base/net/stratum/Socks5.h" #include "base/tools/Buffer.h" #include "base/tools/Chrono.h" #include "net/JobResult.h" @@ -235,6 +236,13 @@ int64_t xmrig::Client::submit(const JobResult &result) void xmrig::Client::connect() { + if (m_pool.proxy().isValid()) { + m_socks5 = new Socks5(this); + resolve(m_pool.proxy().host()); + + return; + } + # ifdef XMRIG_FEATURE_TLS if (m_pool.isTLS()) { m_tls = new Tls(this); @@ -305,10 +313,10 @@ void xmrig::Client::onResolved(const Dns &dns, int status) return reconnect(); } - const DnsRecord &record = dns.get(); + const auto &record = dns.get(); m_ip = record.ip(); - connect(record.addr(m_pool.port())); + connect(record.addr(m_socks5 ? m_pool.proxy().port() : m_pool.port())); } @@ -607,6 +615,10 @@ void xmrig::Client::connect(sockaddr *addr) void xmrig::Client::handshake() { + if (m_socks5) { + return m_socks5->handshake(); + } + # ifdef XMRIG_FEATURE_TLS if (isTLS()) { m_expire = Chrono::steadyMSecs() + kResponseTimeout; @@ -849,6 +861,27 @@ void xmrig::Client::read(ssize_t nread) m_recvBuf.nread(size); + if (m_socks5) { + if (m_socks5->read(m_recvBuf.base(), m_recvBuf.pos())) { + m_recvBuf.reset(); + } + + if (m_socks5->isReady()) { + delete m_socks5; + m_socks5 = nullptr; + +# ifdef XMRIG_FEATURE_TLS + if (m_pool.isTLS() && !m_tls) { + m_tls = new Tls(this); + } +# endif + + handshake(); + } + + return; + } + # ifdef XMRIG_FEATURE_TLS if (isTLS()) { LOG_DEBUG("[%s] TLS received (%d bytes)", url(), static_cast(nread)); diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h index ec90dd85..e26eaa7b 100644 --- a/src/base/net/stratum/Client.h +++ b/src/base/net/stratum/Client.h @@ -5,9 +5,9 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh * Copyright 2019 jtgrassie - * 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 @@ -88,6 +88,7 @@ protected: inline void onLine(char *line, size_t size) override { parse(line, size); } private: + class Socks5; class Tls; bool close(); @@ -128,6 +129,7 @@ private: const char *m_agent; Dns *m_dns; RecvBuf m_recvBuf; + Socks5 *m_socks5 = nullptr; std::bitset m_extensions; std::vector m_sendBuf; String m_rpcId; diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index 78dd2554..e112feca 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -63,6 +63,7 @@ const char *Pool::kNicehash = "nicehash"; const char *Pool::kPass = "pass"; const char *Pool::kRigId = "rig-id"; const char *Pool::kSelfSelect = "self-select"; +const char *Pool::kSOCKS5 = "socks5"; const char *Pool::kTls = "tls"; const char *Pool::kUrl = "url"; const char *Pool::kUser = "user"; @@ -96,6 +97,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : m_algorithm = Json::getString(object, kAlgo); m_coin = Json::getString(object, kCoin); m_daemon = Json::getString(object, kSelfSelect); + m_proxy = Json::getValue(object, kSOCKS5); m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash)); @@ -173,6 +175,7 @@ bool xmrig::Pool::isEqual(const Pool &other) const && m_user == other.m_user && m_pollInterval == other.m_pollInterval && m_daemon == other.m_daemon + && m_proxy == other.m_proxy ); } @@ -232,10 +235,11 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const } } - obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator); - obj.AddMember(StringRef(kTls), isTLS(), allocator); - obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator); - obj.AddMember(StringRef(kDaemon), m_mode == MODE_DAEMON, allocator); + obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator); + obj.AddMember(StringRef(kTls), isTLS(), allocator); + obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator); + obj.AddMember(StringRef(kDaemon), m_mode == MODE_DAEMON, allocator); + obj.AddMember(StringRef(kSOCKS5), m_proxy.toJSON(doc), allocator); if (m_mode == MODE_DAEMON) { obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator); diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index 782ae449..35238771 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -31,7 +31,7 @@ #include -#include "base/net/stratum/Url.h" +#include "base/net/stratum/ProxyUrl.h" #include "crypto/common/Coin.h" #include "rapidjson/fwd.h" @@ -66,6 +66,7 @@ public: static const char *kPass; static const char *kRigId; static const char *kSelfSelect; + static const char *kSOCKS5; static const char *kTls; static const char *kUrl; static const char *kUser; @@ -91,6 +92,7 @@ public: inline bool isValid() const { return m_url.isValid(); } inline const Algorithm &algorithm() const { return m_algorithm; } inline const Coin &coin() const { return m_coin; } + inline const ProxyUrl &proxy() const { return m_proxy; } inline const String &fingerprint() const { return m_fingerprint; } inline const String &host() const { return m_url.host(); } inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; } @@ -104,6 +106,7 @@ public: inline uint64_t pollInterval() const { return m_pollInterval; } inline void setAlgo(const Algorithm &algorithm) { m_algorithm = algorithm; } inline void setPassword(const String &password) { m_password = password; } + inline void setProxy(const ProxyUrl &proxy) { m_proxy = proxy; } inline void setRigId(const String &rigId) { m_rigId = rigId; } inline void setUser(const String &user) { m_user = user; } @@ -135,6 +138,7 @@ private: Coin m_coin; int m_keepAlive = 0; Mode m_mode = MODE_POOL; + ProxyUrl m_proxy; std::bitset m_flags = 0; String m_fingerprint; String m_password; diff --git a/src/base/net/stratum/ProxyUrl.cpp b/src/base/net/stratum/ProxyUrl.cpp new file mode 100644 index 00000000..5b0ff281 --- /dev/null +++ b/src/base/net/stratum/ProxyUrl.cpp @@ -0,0 +1,62 @@ +/* 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/stratum/ProxyUrl.h" +#include "rapidjson/document.h" + + +namespace xmrig { + +static const String kLocalhost = "127.0.0.1"; + +} // namespace xmrig + + +xmrig::ProxyUrl::ProxyUrl(const rapidjson::Value &value) +{ + m_port = 0; + + if (value.IsString()) { + parse(value.GetString()); + } + else if (value.IsUint()) { + m_port = value.GetUint(); + } +} + + +const xmrig::String &xmrig::ProxyUrl::host() const +{ + return m_host.isNull() && isValid() ? kLocalhost : m_host; +} + + +rapidjson::Value xmrig::ProxyUrl::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + if (!isValid()) { + return Value(kNullType); + } + + if (!m_host.isNull()) { + return m_url.toJSON(doc); + } + + return Value(m_port); +} diff --git a/src/base/net/stratum/ProxyUrl.h b/src/base/net/stratum/ProxyUrl.h new file mode 100644 index 00000000..0604dd9d --- /dev/null +++ b/src/base/net/stratum/ProxyUrl.h @@ -0,0 +1,46 @@ +/* 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_PROXYURL_H +#define XMRIG_PROXYURL_H + + +#include "base/net/stratum/Url.h" + + +namespace xmrig { + + +class ProxyUrl : public Url +{ +public: + inline ProxyUrl() { m_port = 0; } + + ProxyUrl(const rapidjson::Value &value); + + inline bool isValid() const { return m_port > 0 && (m_scheme == UNSPECIFIED || m_scheme == SOCKS5); } + + const String &host() const; + rapidjson::Value toJSON(rapidjson::Document &doc) const; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_PROXYURL_H */ diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index 4de49f6e..cc442cd8 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -5,9 +5,9 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh * Copyright 2019 jtgrassie - * 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/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h index 44b07212..ba675ffe 100644 --- a/src/base/net/stratum/SelfSelectClient.h +++ b/src/base/net/stratum/SelfSelectClient.h @@ -5,9 +5,9 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh * Copyright 2019 jtgrassie - * 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 @@ -68,6 +68,7 @@ protected: inline void setAlgo(const Algorithm &algo) override { m_client->setAlgo(algo); } inline void setEnabled(bool enabled) override { m_client->setEnabled(enabled); } inline void setPool(const Pool &pool) override { m_client->setPool(pool); } + inline void setProxy(const ProxyUrl &proxy) override { m_client->setProxy(proxy); } inline void setQuiet(bool quiet) override { m_client->setQuiet(quiet); m_quiet = quiet; } inline void setRetries(int retries) override { m_client->setRetries(retries); m_retries = retries; } inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); m_retryPause = ms; } diff --git a/src/base/net/stratum/Socks5.cpp b/src/base/net/stratum/Socks5.cpp new file mode 100644 index 00000000..f27ee0d0 --- /dev/null +++ b/src/base/net/stratum/Socks5.cpp @@ -0,0 +1,108 @@ +/* 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/stratum/Socks5.h" + + +xmrig::Client::Socks5::Socks5(Client *client) : + m_client(client) +{ +} + + +bool xmrig::Client::Socks5::read(const char *data, size_t size) +{ + if (size < m_nextSize) { + return false; + } + + if (data[0] == 0x05 && data[1] == 0x00) { + if (m_state == SentInitialHandshake) { + connect(); + } + else { + m_state = Ready; + } + } + else { + m_client->close(); + } + + return true; +} + + +void xmrig::Client::Socks5::handshake() +{ + m_nextSize = 2; + m_state = SentInitialHandshake; + + char buf[3] = { 0x05, 0x01, 0x00 }; + + m_client->write(uv_buf_init(buf, sizeof (buf))); +} + + +bool xmrig::Client::Socks5::isIPv4(const String &host, sockaddr_storage *addr) const +{ + return uv_ip4_addr(host.data(), 0, reinterpret_cast(addr)) == 0; +} + + +bool xmrig::Client::Socks5::isIPv6(const String &host, sockaddr_storage *addr) const +{ + return uv_ip6_addr(host.data(), 0, reinterpret_cast(addr)) == 0; +} + + +void xmrig::Client::Socks5::connect() +{ + m_nextSize = 5; + m_state = SentFinalHandshake; + + const auto &host = m_client->pool().host(); + std::vector buf; + sockaddr_storage addr; + + if (isIPv4(host, &addr)) { + buf.resize(10); + buf[3] = 0x01; + memcpy(buf.data() + 4, &reinterpret_cast(&addr)->sin_addr, 4); + } + else if (isIPv6(host, &addr)) { + buf.resize(22); + buf[3] = 0x04; + memcpy(buf.data() + 4, &reinterpret_cast(&addr)->sin6_addr, 16); + } + else { + buf.resize(host.size() + 7); + buf[3] = 0x03; + buf[4] = static_cast(host.size()); + memcpy(buf.data() + 5, host.data(), host.size()); + } + + buf[0] = 0x05; + buf[1] = 0x01; + buf[2] = 0x00; + + const uint16_t port = htons(m_client->pool().port()); + memcpy(buf.data() + (buf.size() - sizeof(port)), &port, sizeof(port)); + + m_client->write(uv_buf_init(reinterpret_cast(buf.data()), buf.size())); +} diff --git a/src/base/net/stratum/Socks5.h b/src/base/net/stratum/Socks5.h new file mode 100644 index 00000000..74ff6643 --- /dev/null +++ b/src/base/net/stratum/Socks5.h @@ -0,0 +1,60 @@ +/* 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_SOCKS5_H +#define XMRIG_SOCKS5_H + + +#include "base/net/stratum/Client.h" + + +namespace xmrig { + + +class Client::Socks5 +{ +public: + Socks5(Client *client); + + inline bool isReady() const { return m_state == Ready; } + + bool read(const char *data, size_t size); + void handshake(); + +private: + enum State { + Created, + SentInitialHandshake, + SentFinalHandshake, + Ready + }; + + bool isIPv4(const String &host, sockaddr_storage *addr) const; + bool isIPv6(const String &host, sockaddr_storage *addr) const; + void connect(); + + Client *m_client; + size_t m_nextSize = 0; + State m_state = Created; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_SOCKS5_H */ diff --git a/src/base/net/stratum/Url.cpp b/src/base/net/stratum/Url.cpp index 3de6bc9b..5e2bdb9a 100644 --- a/src/base/net/stratum/Url.cpp +++ b/src/base/net/stratum/Url.cpp @@ -4,10 +4,10 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2017-2019 XMR-Stak , - * Copyright 2018-2019 SChernykh + * Copyright 2017-2018 XMR-Stak , * Copyright 2019 Howard Chu - * 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 @@ -42,6 +42,7 @@ namespace xmrig { static const char kStratumTcp[] = "stratum+tcp://"; static const char kStratumSsl[] = "stratum+ssl://"; +static const char kSOCKS5[] = "socks5://"; #ifdef XMRIG_FEATURE_HTTP static const char kDaemonHttp[] = "daemon+http://"; @@ -97,6 +98,10 @@ bool xmrig::Url::parse(const char *url) m_scheme = STRATUM; m_tls = true; } + else if (strncasecmp(url, kSOCKS5, sizeof(kSOCKS5) - 1) == 0) { + m_scheme = SOCKS5; + m_tls = false; + } # ifdef XMRIG_FEATURE_HTTP else if (strncasecmp(url, kDaemonHttps, sizeof(kDaemonHttps) - 1) == 0) { m_scheme = DAEMON; diff --git a/src/base/net/stratum/Url.h b/src/base/net/stratum/Url.h index 23fd750e..647612c1 100644 --- a/src/base/net/stratum/Url.h +++ b/src/base/net/stratum/Url.h @@ -5,9 +5,9 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh * Copyright 2019 Howard Chu - * 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 @@ -39,7 +39,8 @@ public: enum Scheme { UNSPECIFIED, STRATUM, - DAEMON + DAEMON, + SOCKS5 }; Url() = default; @@ -57,9 +58,8 @@ public: inline bool operator==(const Url &other) const { return isEqual(other); } bool isEqual(const Url &other) const; - rapidjson::Value toJSON(rapidjson::Document &doc) const; -private: +protected: bool parse(const char *url); bool parseIPv6(const char *addr); diff --git a/src/base/net/stratum/strategies/FailoverStrategy.cpp b/src/base/net/stratum/strategies/FailoverStrategy.cpp index 28c1ad99..ddeeb21f 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.cpp +++ b/src/base/net/stratum/strategies/FailoverStrategy.cpp @@ -108,6 +108,14 @@ void xmrig::FailoverStrategy::setAlgo(const Algorithm &algo) } +void xmrig::FailoverStrategy::setProxy(const ProxyUrl &proxy) +{ + for (IClient *client : m_pools) { + client->setProxy(proxy); + } +} + + void xmrig::FailoverStrategy::stop() { for (auto &pool : m_pools) { diff --git a/src/base/net/stratum/strategies/FailoverStrategy.h b/src/base/net/stratum/strategies/FailoverStrategy.h index c69160ee..18e92dd1 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.h +++ b/src/base/net/stratum/strategies/FailoverStrategy.h @@ -61,6 +61,7 @@ protected: void connect() override; void resume() override; void setAlgo(const Algorithm &algo) override; + void setProxy(const ProxyUrl &proxy) override; void stop() override; void tick(uint64_t now) override; diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp index a45be658..36031189 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.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 @@ -75,6 +75,12 @@ void xmrig::SinglePoolStrategy::setAlgo(const Algorithm &algo) } +void xmrig::SinglePoolStrategy::setProxy(const ProxyUrl &proxy) +{ + m_client->setProxy(proxy); +} + + void xmrig::SinglePoolStrategy::stop() { m_client->disconnect(); diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.h b/src/base/net/stratum/strategies/SinglePoolStrategy.h index f2c8b229..90b85c7d 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.h +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.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 @@ -55,6 +55,7 @@ protected: void connect() override; void resume() override; void setAlgo(const Algorithm &algo) override; + void setProxy(const ProxyUrl &proxy) override; void stop() override; void tick(uint64_t now) override; diff --git a/src/config.json b/src/config.json index ad08dfb0..c2ea9219 100644 --- a/src/config.json +++ b/src/config.json @@ -67,6 +67,7 @@ "tls": false, "tls-fingerprint": null, "daemon": false, + "socks5": null, "self-select": null } ], diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index 1cf12337..cd5567db 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.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 @@ -40,7 +40,7 @@ namespace xmrig { -static const char short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S"; +static const char short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:Sx:"; static const option options[] = { @@ -88,6 +88,7 @@ static const option options[] = { { "cpu-memory-pool", 1, nullptr, IConfig::MemoryPoolKey }, { "cpu-no-yield", 0, nullptr, IConfig::YieldKey }, { "verbose", 0, nullptr, IConfig::VerboseKey }, + { "proxy", 1, nullptr, IConfig::ProxyKey }, # ifdef XMRIG_FEATURE_TLS { "tls", 0, nullptr, IConfig::TlsKey }, { "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index cfda7ff4..bc2cff3d 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.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 @@ -50,6 +50,7 @@ static inline const std::string &usage() u += " -u, --user=USERNAME username for mining server\n"; u += " -p, --pass=PASSWORD password for mining server\n"; u += " -O, --userpass=U:P username:password pair for mining server\n"; + u += " -x, --proxy=HOST:PORT connect through a SOCKS5 proxy"; u += " -k, --keepalive send keepalived packet for prevent timeout (needs pool support)\n"; u += " --nicehash enable nicehash.com support\n"; u += " --rig-id=ID rig identifier for pool-side statistics (needs pool support)\n"; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 643f30e4..5b36575f 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -256,6 +256,7 @@ void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) if (!donate && m_donate) { m_donate->setAlgo(job.algorithm()); + m_donate->setProxy(client->pool().proxy()); } m_controller->miner()->setJob(job, donate); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 86d1c4f7..4559334b 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -125,6 +125,12 @@ void xmrig::DonateStrategy::setAlgo(const xmrig::Algorithm &algo) } +void xmrig::DonateStrategy::setProxy(const ProxyUrl &proxy) +{ + m_strategy->setProxy(proxy); +} + + void xmrig::DonateStrategy::stop() { m_timer->stop(); @@ -246,8 +252,9 @@ xmrig::IClient *xmrig::DonateStrategy::createProxy() const IClient *client = strategy->client(); m_tls = client->hasExtension(IClient::EXT_TLS); - Pool pool(client->ip(), client->pool().port(), m_userId, client->pool().password(), 0, true, client->isTLS()); + Pool pool(client->pool().proxy().isValid() ? client->pool().host() : client->ip(), client->pool().port(), m_userId, client->pool().password(), 0, true, client->isTLS()); pool.setAlgo(client->pool().algorithm()); + pool.setProxy(client->pool().proxy()); IClient *proxy = new Client(-1, Platform::userAgent(), this); proxy->setPool(pool); diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 6bc0c075..91590034 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -65,6 +65,7 @@ protected: int64_t submit(const JobResult &result) override; void connect() override; void setAlgo(const Algorithm &algo) override; + void setProxy(const ProxyUrl &proxy) override; void stop() override; void tick(uint64_t now) override;