mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Merge #19991: net: Use alternative port for incoming Tor connections
96571b3d4c
doc: Update onion service target port numbers in tor.md (Hennadii Stepanov)bb145c9050
net: Extend -bind config option with optional network type (Hennadii Stepanov)92bd3c1da4
net, refactor: Move AddLocal call one level up (Hennadii Stepanov)57f17e57c8
net: Pass onion service target to Tor controller (Hennadii Stepanov)e3f07851f0
refactor: Rename TorController::target to m_tor_control_center (Hennadii Stepanov)fdd3ae4d26
net, refactor: Refactor CBaseChainParams::RPCPort function (Hennadii Stepanov)a5266d4546
net: Add alternative port for onion service (Hennadii Stepanov)b3273cf403
net: Use network byte order for in_addr.s_addr (Hennadii Stepanov) Pull request description: This PR adds ability to label incoming Tor connections as different from normal localhost connections. Closes #8973. Closes #16693. Default onion service target ports are: - 8334 on mainnnet - 18334 on testnet - 38334 on signet - 18445 on regtest To set the onion service target socket manually the extended `-bind` config option could be used: ``` $ src/bitcoind -help | grep -A 6 -e '-bind' -bind=<addr>[:<port>][=onion] Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:8334=onion, testnet: 127.0.0.1:18334=onion, signet: 127.0.0.1:38334=onion, regtest: 127.0.0.1:18445=onion) ``` Since [pr19991.02 update](https://github.com/bitcoin/bitcoin/pull/19991#issuecomment-698882284) this PR is an alternative to #19043. ACKs for top commit: Sjors: re-utACK96571b3d4c
vasild: ACK96571b3d4
laanwj: Re-ACK96571b3d4c
Tree-SHA512: cb0eade80f4b3395f405f775e1b89c086a1f09d5a4464df6cb4faf808d9c2245474e1720b2b538f203f6c1996507f69b09f5a6e35ea42633c10e22bd733d4438
This commit is contained in:
commit
df2129a234
8 changed files with 126 additions and 57 deletions
|
@ -45,11 +45,12 @@ config file): *Needed for Tor version 0.2.7.0 and older versions of Tor only. Fo
|
|||
versions of Tor see [Section 3](#3-automatically-listen-on-tor).*
|
||||
|
||||
HiddenServiceDir /var/lib/tor/bitcoin-service/
|
||||
HiddenServicePort 8333 127.0.0.1:8333
|
||||
HiddenServicePort 18333 127.0.0.1:18333
|
||||
HiddenServicePort 8333 127.0.0.1:8334
|
||||
HiddenServicePort 18333 127.0.0.1:18334
|
||||
|
||||
The directory can be different of course, but (both) port numbers should be equal to
|
||||
your bitcoind's P2P listen port (8333 by default).
|
||||
The directory can be different of course, but virtual port numbers should be equal to
|
||||
your bitcoind's P2P listen port (8333 by default), and target addresses and ports
|
||||
should be equal to binding address and port for inbound Tor connections (127.0.0.1:8334 by default).
|
||||
|
||||
-externalip=X You can tell bitcoin about its publicly reachable address using
|
||||
this option, and this can be a .onion address. Given the above
|
||||
|
|
|
@ -37,16 +37,20 @@ const CBaseChainParams& BaseParams()
|
|||
return *globalChainBaseParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Port numbers for incoming Tor connections (8334, 18334, 38334, 18445) have
|
||||
* been chosen arbitrarily to keep ranges of used ports tight.
|
||||
*/
|
||||
std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const std::string& chain)
|
||||
{
|
||||
if (chain == CBaseChainParams::MAIN) {
|
||||
return MakeUnique<CBaseChainParams>("", 8332);
|
||||
return MakeUnique<CBaseChainParams>("", 8332, 8334);
|
||||
} else if (chain == CBaseChainParams::TESTNET) {
|
||||
return MakeUnique<CBaseChainParams>("testnet3", 18332);
|
||||
return MakeUnique<CBaseChainParams>("testnet3", 18332, 18334);
|
||||
} else if (chain == CBaseChainParams::SIGNET) {
|
||||
return MakeUnique<CBaseChainParams>("signet", 38332);
|
||||
return MakeUnique<CBaseChainParams>("signet", 38332, 38334);
|
||||
} else if (chain == CBaseChainParams::REGTEST) {
|
||||
return MakeUnique<CBaseChainParams>("regtest", 18443);
|
||||
return MakeUnique<CBaseChainParams>("regtest", 18443, 18445);
|
||||
}
|
||||
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
|
||||
}
|
||||
|
|
|
@ -26,13 +26,16 @@ public:
|
|||
///@}
|
||||
|
||||
const std::string& DataDir() const { return strDataDir; }
|
||||
int RPCPort() const { return nRPCPort; }
|
||||
uint16_t RPCPort() const { return m_rpc_port; }
|
||||
uint16_t OnionServiceTargetPort() const { return m_onion_service_target_port; }
|
||||
|
||||
CBaseChainParams() = delete;
|
||||
CBaseChainParams(const std::string& data_dir, int rpc_port) : nRPCPort(rpc_port), strDataDir(data_dir) {}
|
||||
CBaseChainParams(const std::string& data_dir, uint16_t rpc_port, uint16_t onion_service_target_port)
|
||||
: m_rpc_port(rpc_port), m_onion_service_target_port(onion_service_target_port), strDataDir(data_dir) {}
|
||||
|
||||
private:
|
||||
int nRPCPort;
|
||||
const uint16_t m_rpc_port;
|
||||
const uint16_t m_onion_service_target_port;
|
||||
std::string strDataDir;
|
||||
};
|
||||
|
||||
|
|
41
src/init.cpp
41
src/init.cpp
|
@ -442,7 +442,7 @@ void SetupServerArgs(NodeContext& node)
|
|||
argsman.AddArg("-addnode=<ip>", "Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bind=<addr>", "Bind to given address and always listen on it. Use [host]:port notation for IPv6", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
|
@ -1918,9 +1918,6 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
|
|||
}
|
||||
LogPrintf("nBestHeight = %d\n", chain_active_height);
|
||||
|
||||
if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
|
||||
StartTorControl();
|
||||
|
||||
Discover();
|
||||
|
||||
// Map ports with UPnP
|
||||
|
@ -1947,13 +1944,39 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
|
|||
connOptions.nMaxOutboundLimit = nMaxOutboundLimit;
|
||||
connOptions.m_peer_connect_timeout = peer_connect_timeout;
|
||||
|
||||
for (const std::string& strBind : args.GetArgs("-bind")) {
|
||||
CService addrBind;
|
||||
if (!Lookup(strBind, addrBind, GetListenPort(), false)) {
|
||||
return InitError(ResolveErrMsg("bind", strBind));
|
||||
for (const std::string& bind_arg : args.GetArgs("-bind")) {
|
||||
CService bind_addr;
|
||||
const size_t index = bind_arg.rfind('=');
|
||||
if (index == std::string::npos) {
|
||||
if (Lookup(bind_arg, bind_addr, GetListenPort(), false)) {
|
||||
connOptions.vBinds.push_back(bind_addr);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const std::string network_type = bind_arg.substr(index + 1);
|
||||
if (network_type == "onion") {
|
||||
const std::string truncated_bind_arg = bind_arg.substr(0, index);
|
||||
if (Lookup(truncated_bind_arg, bind_addr, BaseParams().OnionServiceTargetPort(), false)) {
|
||||
connOptions.onion_binds.push_back(bind_addr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
connOptions.vBinds.push_back(addrBind);
|
||||
return InitError(ResolveErrMsg("bind", bind_arg));
|
||||
}
|
||||
|
||||
if (connOptions.onion_binds.empty()) {
|
||||
connOptions.onion_binds.push_back(DefaultOnionServiceTarget());
|
||||
}
|
||||
|
||||
if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) {
|
||||
const auto bind_addr = connOptions.onion_binds.front();
|
||||
if (connOptions.onion_binds.size() > 1) {
|
||||
InitWarning(strprintf(_("More than one onion bind address is provided. Using %s for the automatically created Tor onion service."), bind_addr.ToStringIPPort()));
|
||||
}
|
||||
StartTorControl(bind_addr);
|
||||
}
|
||||
|
||||
for (const std::string& strBind : args.GetArgs("-whitebind")) {
|
||||
NetWhitebindPermissions whitebind;
|
||||
bilingual_str error;
|
||||
|
|
28
src/net.cpp
28
src/net.cpp
|
@ -83,6 +83,11 @@ enum BindFlags {
|
|||
BF_NONE = 0,
|
||||
BF_EXPLICIT = (1U << 0),
|
||||
BF_REPORT_ERROR = (1U << 1),
|
||||
/**
|
||||
* Do not call AddLocal() for our special addresses, e.g., for incoming
|
||||
* Tor connections, to prevent gossiping them over the network.
|
||||
*/
|
||||
BF_DONT_ADVERTISE = (1U << 2),
|
||||
};
|
||||
|
||||
// The set of sockets cannot be modified while waiting
|
||||
|
@ -2241,10 +2246,6 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError,
|
|||
}
|
||||
|
||||
vhListenSocket.push_back(ListenSocket(hListenSocket, permissions));
|
||||
|
||||
if (addrBind.IsRoutable() && fDiscover && (permissions & PF_NOBAN) == 0)
|
||||
AddLocal(addrBind, LOCAL_BIND);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2338,10 +2339,18 @@ bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !(permissions & PF_NOBAN)) {
|
||||
AddLocal(addr, LOCAL_BIND);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds)
|
||||
bool CConnman::InitBinds(
|
||||
const std::vector<CService>& binds,
|
||||
const std::vector<NetWhitebindPermissions>& whiteBinds,
|
||||
const std::vector<CService>& onion_binds)
|
||||
{
|
||||
bool fBound = false;
|
||||
for (const auto& addrBind : binds) {
|
||||
|
@ -2352,11 +2361,16 @@ bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<N
|
|||
}
|
||||
if (binds.empty() && whiteBinds.empty()) {
|
||||
struct in_addr inaddr_any;
|
||||
inaddr_any.s_addr = INADDR_ANY;
|
||||
inaddr_any.s_addr = htonl(INADDR_ANY);
|
||||
struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
|
||||
fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE);
|
||||
fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE);
|
||||
}
|
||||
|
||||
for (const auto& addr_bind : onion_binds) {
|
||||
fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE, NetPermissionFlags::PF_NONE);
|
||||
}
|
||||
|
||||
return fBound;
|
||||
}
|
||||
|
||||
|
@ -2375,7 +2389,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
|
|||
nMaxOutboundCycleStartTime = 0;
|
||||
}
|
||||
|
||||
if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
|
||||
if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds, connOptions.onion_binds)) {
|
||||
if (clientInterface) {
|
||||
clientInterface->ThreadSafeMessageBox(
|
||||
_("Failed to listen on any port. Use -listen=0 if you want this."),
|
||||
|
|
|
@ -220,6 +220,7 @@ public:
|
|||
std::vector<NetWhitelistPermissions> vWhitelistedRange;
|
||||
std::vector<NetWhitebindPermissions> vWhiteBinds;
|
||||
std::vector<CService> vBinds;
|
||||
std::vector<CService> onion_binds;
|
||||
bool m_use_addrman_outgoing = true;
|
||||
std::vector<std::string> m_specified_outgoing;
|
||||
std::vector<std::string> m_added_nodes;
|
||||
|
@ -417,7 +418,11 @@ private:
|
|||
|
||||
bool BindListenPort(const CService& bindAddr, bilingual_str& strError, NetPermissionFlags permissions);
|
||||
bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions);
|
||||
bool InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds);
|
||||
bool InitBinds(
|
||||
const std::vector<CService>& binds,
|
||||
const std::vector<NetWhitebindPermissions>& whiteBinds,
|
||||
const std::vector<CService>& onion_binds);
|
||||
|
||||
void ThreadOpenAddedConnections();
|
||||
void AddAddrFetch(const std::string& strDest);
|
||||
void ProcessAddrFetch();
|
||||
|
|
|
@ -3,13 +3,16 @@
|
|||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <torcontrol.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <netbase.h>
|
||||
#include <net.h>
|
||||
#include <util/system.h>
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <chainparamsbase.h>
|
||||
#include <crypto/hmac_sha256.h>
|
||||
#include <net.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/system.h>
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
@ -81,12 +84,12 @@ public:
|
|||
|
||||
/**
|
||||
* Connect to a Tor control port.
|
||||
* target is address of the form host:port.
|
||||
* tor_control_center is address of the form host:port.
|
||||
* connected is the handler that is called when connection is successfully established.
|
||||
* disconnected is a handler that is called when the connection is broken.
|
||||
* Return true on success.
|
||||
*/
|
||||
bool Connect(const std::string &target, const ConnectionCB& connected, const ConnectionCB& disconnected);
|
||||
bool Connect(const std::string& tor_control_center, const ConnectionCB& connected, const ConnectionCB& disconnected);
|
||||
|
||||
/**
|
||||
* Disconnect from Tor control port.
|
||||
|
@ -193,16 +196,16 @@ void TorControlConnection::eventcb(struct bufferevent *bev, short what, void *ct
|
|||
}
|
||||
}
|
||||
|
||||
bool TorControlConnection::Connect(const std::string &target, const ConnectionCB& _connected, const ConnectionCB& _disconnected)
|
||||
bool TorControlConnection::Connect(const std::string& tor_control_center, const ConnectionCB& _connected, const ConnectionCB& _disconnected)
|
||||
{
|
||||
if (b_conn)
|
||||
Disconnect();
|
||||
// Parse target address:port
|
||||
// Parse tor_control_center address:port
|
||||
struct sockaddr_storage connect_to_addr;
|
||||
int connect_to_addrlen = sizeof(connect_to_addr);
|
||||
if (evutil_parse_sockaddr_port(target.c_str(),
|
||||
if (evutil_parse_sockaddr_port(tor_control_center.c_str(),
|
||||
(struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) {
|
||||
LogPrintf("tor: Error parsing socket address %s\n", target);
|
||||
LogPrintf("tor: Error parsing socket address %s\n", tor_control_center);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -215,9 +218,9 @@ bool TorControlConnection::Connect(const std::string &target, const ConnectionCB
|
|||
this->connected = _connected;
|
||||
this->disconnected = _disconnected;
|
||||
|
||||
// Finally, connect to target
|
||||
// Finally, connect to tor_control_center
|
||||
if (bufferevent_socket_connect(b_conn, (struct sockaddr*)&connect_to_addr, connect_to_addrlen) < 0) {
|
||||
LogPrintf("tor: Error connecting to address %s\n", target);
|
||||
LogPrintf("tor: Error connecting to address %s\n", tor_control_center);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -410,7 +413,7 @@ static bool WriteBinaryFile(const fs::path &filename, const std::string &data)
|
|||
class TorController
|
||||
{
|
||||
public:
|
||||
TorController(struct event_base* base, const std::string& target);
|
||||
TorController(struct event_base* base, const std::string& tor_control_center, const CService& target);
|
||||
~TorController();
|
||||
|
||||
/** Get name of file to store private key in */
|
||||
|
@ -420,7 +423,7 @@ public:
|
|||
void Reconnect();
|
||||
private:
|
||||
struct event_base* base;
|
||||
std::string target;
|
||||
const std::string m_tor_control_center;
|
||||
TorControlConnection conn;
|
||||
std::string private_key;
|
||||
std::string service_id;
|
||||
|
@ -428,6 +431,7 @@ private:
|
|||
struct event *reconnect_ev;
|
||||
float reconnect_timeout;
|
||||
CService service;
|
||||
const CService m_target;
|
||||
/** Cookie for SAFECOOKIE auth */
|
||||
std::vector<uint8_t> cookie;
|
||||
/** ClientNonce for SAFECOOKIE auth */
|
||||
|
@ -450,18 +454,19 @@ private:
|
|||
static void reconnect_cb(evutil_socket_t fd, short what, void *arg);
|
||||
};
|
||||
|
||||
TorController::TorController(struct event_base* _base, const std::string& _target):
|
||||
TorController::TorController(struct event_base* _base, const std::string& tor_control_center, const CService& target):
|
||||
base(_base),
|
||||
target(_target), conn(base), reconnect(true), reconnect_ev(0),
|
||||
reconnect_timeout(RECONNECT_TIMEOUT_START)
|
||||
m_tor_control_center(tor_control_center), conn(base), reconnect(true), reconnect_ev(0),
|
||||
reconnect_timeout(RECONNECT_TIMEOUT_START),
|
||||
m_target(target)
|
||||
{
|
||||
reconnect_ev = event_new(base, -1, 0, reconnect_cb, this);
|
||||
if (!reconnect_ev)
|
||||
LogPrintf("tor: Failed to create event for reconnection: out of memory?\n");
|
||||
// Start connection attempts immediately
|
||||
if (!conn.Connect(_target, std::bind(&TorController::connected_cb, this, std::placeholders::_1),
|
||||
if (!conn.Connect(m_tor_control_center, std::bind(&TorController::connected_cb, this, std::placeholders::_1),
|
||||
std::bind(&TorController::disconnected_cb, this, std::placeholders::_1) )) {
|
||||
LogPrintf("tor: Initiating connection to Tor control port %s failed\n", _target);
|
||||
LogPrintf("tor: Initiating connection to Tor control port %s failed\n", m_tor_control_center);
|
||||
}
|
||||
// Read service private key if cached
|
||||
std::pair<bool,std::string> pkf = ReadBinaryFile(GetPrivateKeyFile());
|
||||
|
@ -536,7 +541,7 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
|
|||
private_key = "NEW:RSA1024"; // Explicitly request RSA1024 - see issue #9214
|
||||
// Request onion service, redirect port.
|
||||
// Note that the 'virtual' port is always the default port to avoid decloaking nodes using other ports.
|
||||
_conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, Params().GetDefaultPort(), GetListenPort()),
|
||||
_conn.Command(strprintf("ADD_ONION %s Port=%i,%s", private_key, Params().GetDefaultPort(), m_target.ToStringIPPort()),
|
||||
std::bind(&TorController::add_onion_cb, this, std::placeholders::_1, std::placeholders::_2));
|
||||
} else {
|
||||
LogPrintf("tor: Authentication failed\n");
|
||||
|
@ -696,7 +701,7 @@ void TorController::disconnected_cb(TorControlConnection& _conn)
|
|||
if (!reconnect)
|
||||
return;
|
||||
|
||||
LogPrint(BCLog::TOR, "tor: Not connected to Tor control port %s, trying to reconnect\n", target);
|
||||
LogPrint(BCLog::TOR, "tor: Not connected to Tor control port %s, trying to reconnect\n", m_tor_control_center);
|
||||
|
||||
// Single-shot timer for reconnect. Use exponential backoff.
|
||||
struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0));
|
||||
|
@ -710,9 +715,9 @@ void TorController::Reconnect()
|
|||
/* Try to reconnect and reestablish if we get booted - for example, Tor
|
||||
* may be restarting.
|
||||
*/
|
||||
if (!conn.Connect(target, std::bind(&TorController::connected_cb, this, std::placeholders::_1),
|
||||
if (!conn.Connect(m_tor_control_center, std::bind(&TorController::connected_cb, this, std::placeholders::_1),
|
||||
std::bind(&TorController::disconnected_cb, this, std::placeholders::_1) )) {
|
||||
LogPrintf("tor: Re-initiating connection to Tor control port %s failed\n", target);
|
||||
LogPrintf("tor: Re-initiating connection to Tor control port %s failed\n", m_tor_control_center);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -731,14 +736,14 @@ void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg)
|
|||
static struct event_base *gBase;
|
||||
static std::thread torControlThread;
|
||||
|
||||
static void TorControlThread()
|
||||
static void TorControlThread(CService onion_service_target)
|
||||
{
|
||||
TorController ctrl(gBase, gArgs.GetArg("-torcontrol", DEFAULT_TOR_CONTROL));
|
||||
TorController ctrl(gBase, gArgs.GetArg("-torcontrol", DEFAULT_TOR_CONTROL), onion_service_target);
|
||||
|
||||
event_base_dispatch(gBase);
|
||||
}
|
||||
|
||||
void StartTorControl()
|
||||
void StartTorControl(CService onion_service_target)
|
||||
{
|
||||
assert(!gBase);
|
||||
#ifdef WIN32
|
||||
|
@ -752,7 +757,9 @@ void StartTorControl()
|
|||
return;
|
||||
}
|
||||
|
||||
torControlThread = std::thread(std::bind(&TraceThread<void (*)()>, "torcontrol", &TorControlThread));
|
||||
torControlThread = std::thread(&TraceThread<std::function<void()>>, "torcontrol", [onion_service_target] {
|
||||
TorControlThread(onion_service_target);
|
||||
});
|
||||
}
|
||||
|
||||
void InterruptTorControl()
|
||||
|
@ -773,3 +780,10 @@ void StopTorControl()
|
|||
gBase = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CService DefaultOnionServiceTarget()
|
||||
{
|
||||
struct in_addr onion_service_target;
|
||||
onion_service_target.s_addr = htonl(INADDR_LOOPBACK);
|
||||
return {onion_service_target, BaseParams().OnionServiceTargetPort()};
|
||||
}
|
||||
|
|
|
@ -8,12 +8,17 @@
|
|||
#ifndef BITCOIN_TORCONTROL_H
|
||||
#define BITCOIN_TORCONTROL_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class CService;
|
||||
|
||||
extern const std::string DEFAULT_TOR_CONTROL;
|
||||
static const bool DEFAULT_LISTEN_ONION = true;
|
||||
|
||||
void StartTorControl();
|
||||
void StartTorControl(CService onion_service_target);
|
||||
void InterruptTorControl();
|
||||
void StopTorControl();
|
||||
|
||||
CService DefaultOnionServiceTarget();
|
||||
|
||||
#endif /* BITCOIN_TORCONTROL_H */
|
||||
|
|
Loading…
Reference in a new issue