Added SOCKS5 proxy type command line parameter
- Auto-detect by default, based on the port number - Don't run TOR-specific code if it's not the TOR proxy
This commit is contained in:
@@ -35,7 +35,7 @@ static constexpr int DEFAULT_BACKLOG = 1;
|
||||
namespace p2pool {
|
||||
|
||||
ConsoleCommands::ConsoleCommands(p2pool* pool)
|
||||
: TCPServer(DEFAULT_BACKLOG, ConsoleClient::allocate, std::string())
|
||||
: TCPServer(DEFAULT_BACKLOG, ConsoleClient::allocate, std::string(), Params::ProxyType::INVALID)
|
||||
, m_pool(pool)
|
||||
, m_tty{}
|
||||
, m_stdin_pipe{}
|
||||
|
||||
@@ -89,6 +89,7 @@ void p2pool_usage()
|
||||
"--no-autodiff Disable automatic difficulty adjustment for miners connected to stratum (WARNING: incompatible with Nicehash and MRR)\n"
|
||||
"--rpc-login Specify username[:password] required for Monero RPC server\n"
|
||||
"--socks5 Specify IP:port of a SOCKS5 proxy to use for outgoing connections\n"
|
||||
"--socks5-proxy-type The type of SOCKS5 proxy. Can be one of the following values: auto, plain, tor. Default is auto (auto-detect by the port number)\n"
|
||||
"--no-dns Disable DNS queries, use only IP addresses to connect to peers (seed node DNS will be unavailable too)\n"
|
||||
"--p2p-external-port Port number that your router uses for mapping to your local p2p port. Use it if you are behind a NAT and still want to accept incoming connections\n"
|
||||
#ifdef WITH_UPNP
|
||||
|
||||
@@ -42,7 +42,7 @@ MergeMiningClientTari::MergeMiningClientTari(p2pool* pool, std::string host, con
|
||||
, m_auxWallet(wallet)
|
||||
, m_pool(pool)
|
||||
, m_tariJobParams{}
|
||||
, m_server(new TariServer(pool->params().m_socks5Proxy))
|
||||
, m_server(new TariServer(pool->params().m_socks5Proxy, pool->params().m_socks5ProxyType))
|
||||
, m_hostStr(host)
|
||||
, m_workerStop(0)
|
||||
, m_pushBlockStop(0)
|
||||
@@ -863,8 +863,8 @@ void MergeMiningClientTari::run()
|
||||
// TariServer and TariClient are simply a proxy from a localhost TCP port to the external Tari node
|
||||
// This is needed for SOCKS5 proxy support (gRPC library doesn't support it natively)
|
||||
|
||||
MergeMiningClientTari::TariServer::TariServer(const std::string& socks5Proxy)
|
||||
: TCPServer(1, MergeMiningClientTari::TariClient::allocate, socks5Proxy)
|
||||
MergeMiningClientTari::TariServer::TariServer(const std::string& socks5Proxy, Params::ProxyType socks5ProxyType)
|
||||
: TCPServer(1, MergeMiningClientTari::TariClient::allocate, socks5Proxy, socks5ProxyType)
|
||||
, m_TariNodeIsV6(false)
|
||||
, m_TariNodeHost()
|
||||
, m_TariNodePort(0)
|
||||
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
|
||||
struct TariServer : public TCPServer
|
||||
{
|
||||
explicit TariServer(const std::string& socks5Proxy);
|
||||
TariServer(const std::string& socks5Proxy, Params::ProxyType socks5ProxyType);
|
||||
~TariServer() {}
|
||||
|
||||
[[nodiscard]] bool start();
|
||||
|
||||
+23
-8
@@ -64,7 +64,7 @@ static constexpr hash seed_onion_nodes[] = {
|
||||
};
|
||||
|
||||
P2PServer::P2PServer(p2pool* pool)
|
||||
: TCPServer(DEFAULT_BACKLOG, P2PClient::allocate, pool->params().m_socks5Proxy)
|
||||
: TCPServer(DEFAULT_BACKLOG, P2PClient::allocate, pool->params().m_socks5Proxy, pool->params().m_socks5ProxyType)
|
||||
, m_pool(pool)
|
||||
, m_cache(pool->params().m_blockCache ? new BlockCache(pool->params()) : nullptr)
|
||||
, m_cacheLoaded(false)
|
||||
@@ -426,14 +426,16 @@ void P2PServer::update_peer_connections()
|
||||
|
||||
uint32_t num_outgoing = m_numConnections - m_numIncomingConnections;
|
||||
|
||||
// Try to have at least N/2 outgoing onion connections
|
||||
if (!m_socks5Proxy.empty()) {
|
||||
// Try to have at least N/2 (or N if clearnet P2P is disabled) outgoing onion connections
|
||||
if (!m_socks5Proxy.empty() && (m_socks5ProxyType == Params::ProxyType::TOR)) {
|
||||
std::vector<hash> pubkeys = m_pool->side_chain().seen_onion_pubkeys();
|
||||
|
||||
// Add seed nodes
|
||||
pubkeys.insert(pubkeys.end(), seed_onion_nodes, seed_onion_nodes + array_size(seed_onion_nodes));
|
||||
|
||||
for (uint32_t i = m_numOnionConnections, n = N / 2; (i < n) && !pubkeys.empty();) {
|
||||
const uint32_t n = m_pool->params().m_noClearnetP2P ? N : (N / 2);
|
||||
|
||||
for (uint32_t i = m_numOnionConnections; (i < n) && !pubkeys.empty();) {
|
||||
const uint64_t k = get_random64() % pubkeys.size();
|
||||
const std::string addr = to_onion_v3(pubkeys[k]);
|
||||
|
||||
@@ -727,8 +729,21 @@ void P2PServer::load_peer_list()
|
||||
}
|
||||
|
||||
// Finally load peers from p2pool_peers.txt and p2pool_onion_peers.txt
|
||||
for (size_t i = 0, n = (m_socks5Proxy.empty() ? 1 : 2); i < n; ++i) {
|
||||
const std::string path = m_pool->params().m_dataDir + (i ? saved_onion_peer_list_file_name : saved_peer_list_file_name);
|
||||
std::vector<std::string> paths;
|
||||
paths.resize(Params::ProxyType::MAX);
|
||||
|
||||
paths[Params::ProxyType::PLAIN] = saved_peer_list_file_name;
|
||||
|
||||
if (!m_socks5Proxy.empty() && (m_socks5ProxyType == Params::ProxyType::TOR)) {
|
||||
paths[Params::ProxyType::TOR] = saved_onion_peer_list_file_name;
|
||||
}
|
||||
|
||||
for (int i = Params::ProxyType::PLAIN; i < Params::ProxyType::MAX; ++i) {
|
||||
const std::string& path = paths[i];
|
||||
|
||||
if (path.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::ifstream f(path);
|
||||
|
||||
@@ -740,7 +755,7 @@ void P2PServer::load_peer_list()
|
||||
std::getline(f, address);
|
||||
|
||||
if (!address.empty()) {
|
||||
if (i > 0) {
|
||||
if (i == Params::ProxyType::TOR) {
|
||||
const hash h = from_onion_v3(address);
|
||||
if (!h.empty()) {
|
||||
pubkeys.emplace_back(h);
|
||||
@@ -756,7 +771,7 @@ void P2PServer::load_peer_list()
|
||||
}
|
||||
f.close();
|
||||
|
||||
if (i > 0) {
|
||||
if (i == Params::ProxyType::TOR) {
|
||||
s.add_onion_pubkeys(pubkeys);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,6 +238,18 @@ Params::Params(const std::vector<std::vector<std::string>>& args)
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if ((arg[0] == "socks5-proxy-type") && has1(arg)) {
|
||||
const std::string s = tolower(arg[1]);
|
||||
|
||||
m_socks5ProxyType = ProxyType::INVALID;
|
||||
|
||||
if (s == "auto") m_socks5ProxyType = ProxyType::AUTO;
|
||||
if (s == "plain") m_socks5ProxyType = ProxyType::PLAIN;
|
||||
if (s == "tor") m_socks5ProxyType = ProxyType::TOR;
|
||||
|
||||
ok = m_socks5ProxyType != ProxyType::INVALID;
|
||||
}
|
||||
|
||||
if (arg[0] == "no-dns") {
|
||||
m_dns = false;
|
||||
disable_resolve_host = true;
|
||||
@@ -426,6 +438,29 @@ Params::Params(const std::vector<std::vector<std::string>>& args)
|
||||
else {
|
||||
fixup_path(m_dataDir);
|
||||
}
|
||||
|
||||
// Detect the proxy type
|
||||
if (!m_socks5Proxy.empty() && (m_socks5ProxyType == ProxyType::AUTO)) {
|
||||
m_socks5ProxyType = ProxyType::INVALID;
|
||||
|
||||
const size_t k = m_socks5Proxy.find_last_of(':');
|
||||
|
||||
if ((k != std::string::npos) && (k < m_socks5Proxy.length() - 1)) {
|
||||
const uint32_t port = std::stoul(m_socks5Proxy.substr(k + 1), nullptr, 10);
|
||||
|
||||
if ((port > 0) && (port < 65536)) {
|
||||
switch (port) {
|
||||
case 9050:
|
||||
m_socks5ProxyType = ProxyType::TOR;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_socks5ProxyType = ProxyType::PLAIN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Params::valid() const
|
||||
@@ -478,6 +513,11 @@ bool Params::valid() const
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_socks5ProxyType == ProxyType::INVALID) {
|
||||
LOGERR(1, "Invalid SOCKS5 proxy type. Check the --socks5 parameter.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,17 @@ struct Params
|
||||
bool m_mini = false;
|
||||
bool m_nano = false;
|
||||
bool m_autoDiff = true;
|
||||
|
||||
std::string m_socks5Proxy;
|
||||
|
||||
enum ProxyType {
|
||||
INVALID = -1,
|
||||
AUTO = 0,
|
||||
PLAIN = 1,
|
||||
TOR = 2,
|
||||
MAX = 3,
|
||||
} m_socks5ProxyType = ProxyType::AUTO;
|
||||
|
||||
bool m_dns = true;
|
||||
int32_t m_p2pExternalPort = 0;
|
||||
#ifdef WITH_UPNP
|
||||
|
||||
@@ -44,7 +44,7 @@ static constexpr int32_t BAN_THRESHOLD_POINTS = -15;
|
||||
namespace p2pool {
|
||||
|
||||
StratumServer::StratumServer(p2pool* pool)
|
||||
: TCPServer(DEFAULT_BACKLOG, StratumClient::allocate, std::string())
|
||||
: TCPServer(DEFAULT_BACKLOG, StratumClient::allocate, std::string(), Params::ProxyType::INVALID)
|
||||
, m_pool(pool)
|
||||
, m_autoDiff(pool->params().m_autoDiff)
|
||||
, m_enableFullValidation(pool->params().m_enableFullValidation)
|
||||
|
||||
+2
-1
@@ -23,7 +23,7 @@ static thread_local const char* log_category_prefix = "TCPServer ";
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
TCPServer::TCPServer(int default_backlog, allocate_client_callback allocate_new_client, const std::string& socks5Proxy)
|
||||
TCPServer::TCPServer(int default_backlog, allocate_client_callback allocate_new_client, const std::string& socks5Proxy, Params::ProxyType socks5ProxyType)
|
||||
: m_allocateNewClient(allocate_new_client)
|
||||
, m_defaultBacklog(default_backlog)
|
||||
, m_loopThread{}
|
||||
@@ -32,6 +32,7 @@ TCPServer::TCPServer(int default_backlog, allocate_client_callback allocate_new_
|
||||
, m_portMapping(0)
|
||||
#endif
|
||||
, m_socks5Proxy(socks5Proxy)
|
||||
, m_socks5ProxyType(socks5ProxyType)
|
||||
, m_socks5ProxyV6(false)
|
||||
, m_socks5ProxyIP{}
|
||||
, m_socks5ProxyPort(-1)
|
||||
|
||||
+3
-1
@@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "uv_util.h"
|
||||
#include "params.h"
|
||||
|
||||
#ifdef WITH_TLS
|
||||
#include "tls.h"
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
struct Client;
|
||||
typedef Client* (*allocate_client_callback)();
|
||||
|
||||
TCPServer(int default_backlog, allocate_client_callback allocate_new_client, const std::string& socks5Proxy);
|
||||
TCPServer(int default_backlog, allocate_client_callback allocate_new_client, const std::string& socks5Proxy, Params::ProxyType socks5ProxyType);
|
||||
virtual ~TCPServer();
|
||||
|
||||
[[nodiscard]] bool connect_to_peer(bool is_v6, const char* ip, int port);
|
||||
@@ -191,6 +192,7 @@ protected:
|
||||
#endif
|
||||
|
||||
std::string m_socks5Proxy;
|
||||
Params::ProxyType m_socks5ProxyType;
|
||||
bool m_socks5ProxyV6;
|
||||
raw_ip m_socks5ProxyIP;
|
||||
int m_socks5ProxyPort;
|
||||
|
||||
+1
-5
@@ -1014,12 +1014,8 @@ hash from_onion_v3(const std::string& address)
|
||||
return {};
|
||||
}
|
||||
|
||||
// Convert address to lowercase
|
||||
std::string s = address;
|
||||
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
// Checksum validation
|
||||
if (to_onion_v3(result) != s) {
|
||||
if (to_onion_v3(result) != tolower(address)) {
|
||||
LOGWARN(3, "Invalid onion address \"" << address << "\": checksum failed");
|
||||
return {};
|
||||
}
|
||||
|
||||
+12
@@ -395,6 +395,18 @@ FORCEINLINE void secure_zero_memory(T& value)
|
||||
secure_zero_memory(&value, sizeof(T));
|
||||
}
|
||||
|
||||
FORCEINLINE std::string tolower(const std::string& s)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(s.size() + 1);
|
||||
|
||||
for (char c : s) {
|
||||
result.push_back(static_cast<char>(std::tolower(c)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string to_onion_v3(const hash& pubkey);
|
||||
hash from_onion_v3(const std::string& address);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user