Skip to content

Commit bd629d7

Browse files
committed
Merge pull request #6639
58ef0ff doc: update docs for Tor listening (Wladimir J. van der Laan) 68ccdc4 doc: Mention Tor listening in release notes (Wladimir J. van der Laan) 09c1ae1 torcontrol improvements and fixes (Wladimir J. van der Laan) 2f796e5 Better error message if Tor version too old (Peter Todd) 8f4e67f net: Automatically create hidden service, listen on Tor (Wladimir J. van der Laan)
2 parents eb6172a + 58ef0ff commit bd629d7

File tree

12 files changed

+771
-4
lines changed

12 files changed

+771
-4
lines changed

doc/files.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
* fee_estimates.dat: stores statistics used to estimate minimum transaction fees and priorities required for confirmation; since 0.10.0
1313
* peers.dat: peer IP address database (custom format); since 0.7.0
1414
* wallet.dat: personal wallet (BDB) with keys and transactions
15+
* .cookie: session RPC authentication cookie (written at start when cookie authentication is used, deleted on shutdown): since 0.12.0
16+
* onion_private_key: cached Tor hidden service private key for `-listenonion`: since 0.12.0
1517

1618
Only used in pre-0.8.0
1719
---------------------

doc/release-notes.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,23 @@ mining with the getblocktemplate protocol to a pool: this will affect you at
151151
the pool operator's discretion, which must be no later than BIP65 achieving its
152152
951/1001 status.
153153

154+
Automatically listen on Tor
155+
----------------------------
156+
157+
Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket
158+
API, to create and destroy 'ephemeral' hidden services programmatically.
159+
Bitcoin Core has been updated to make use of this.
160+
161+
This means that if Tor is running (and proper authorization is available),
162+
Bitcoin Core automatically creates a hidden service to listen on, without
163+
manual configuration. This will positively affect the number of available
164+
.onion nodes.
165+
166+
This new feature is enabled by default if Bitcoin Core is listening, and
167+
a connection to Tor can be made. It can be configured with the `-listenonion`,
168+
`-torcontrol` and `-torpassword` settings. To show verbose debugging
169+
information, pass `-debug=tor`.
170+
154171
0.12.0 Change log
155172
=================
156173

doc/tor.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,20 @@ If you only want to use Tor to reach onion addresses, but not use it as a proxy
8787
for normal IPv4/IPv6 communication, use:
8888

8989
./bitcoin -onion=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -discover
90+
91+
3. Automatically listen on Tor
92+
--------------------------------
93+
94+
Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket
95+
API, to create and destroy 'ephemeral' hidden services programmatically.
96+
Bitcoin Core has been updated to make use of this.
97+
98+
This means that if Tor is running (and proper authorization is available),
99+
Bitcoin Core automatically creates a hidden service to listen on, without
100+
manual configuration. This will positively affect the number of available
101+
.onion nodes.
102+
103+
This new feature is enabled by default if Bitcoin Core is listening, and
104+
a connection to Tor can be made. It can be configured with the `-listenonion`,
105+
`-torcontrol` and `-torpassword` settings. To show verbose debugging
106+
information, pass `-debug=tor`.

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ BITCOIN_CORE_H = \
151151
threadsafety.h \
152152
timedata.h \
153153
tinyformat.h \
154+
torcontrol.h \
154155
txdb.h \
155156
txmempool.h \
156157
ui_interface.h \
@@ -209,6 +210,7 @@ libbitcoin_server_a_SOURCES = \
209210
rpcserver.cpp \
210211
script/sigcache.cpp \
211212
timedata.cpp \
213+
torcontrol.cpp \
212214
txdb.cpp \
213215
txmempool.cpp \
214216
validationinterface.cpp \

src/init.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "scheduler.h"
3030
#include "txdb.h"
3131
#include "txmempool.h"
32+
#include "torcontrol.h"
3233
#include "ui_interface.h"
3334
#include "util.h"
3435
#include "utilmoneystr.h"
@@ -160,6 +161,7 @@ void Interrupt(boost::thread_group& threadGroup)
160161
InterruptHTTPRPC();
161162
InterruptRPC();
162163
InterruptREST();
164+
InterruptTorControl();
163165
threadGroup.interrupt_all();
164166
}
165167

@@ -188,6 +190,7 @@ void Shutdown()
188190
#endif
189191
GenerateBitcoins(false, 0, Params());
190192
StopNode();
193+
StopTorControl();
191194
UnregisterNodeSignals(GetNodeSignals());
192195

193196
if (fFeeEstimatesInitialized)
@@ -348,6 +351,7 @@ std::string HelpMessage(HelpMessageMode mode)
348351
strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
349352
strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
350353
strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
354+
strUsage += HelpMessageOpt("-listenonion", strprintf(_("Automatically create Tor hidden service (default: %d)"), DEFAULT_LISTEN_ONION));
351355
strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS));
352356
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
353357
strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
@@ -359,6 +363,8 @@ std::string HelpMessage(HelpMessageMode mode)
359363
strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1));
360364
strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
361365
strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
366+
strUsage += HelpMessageOpt("-torcontrol=<ip>:<port>", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL));
367+
strUsage += HelpMessageOpt("-torpassword=<pass>", _("Tor control port password (default: empty)"));
362368
#ifdef USE_UPNP
363369
#if USE_UPNP
364370
strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening and no -proxy)"));
@@ -778,6 +784,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
778784
LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
779785
if (SoftSetBoolArg("-discover", false))
780786
LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
787+
if (SoftSetBoolArg("-listenonion", false))
788+
LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__);
781789
}
782790

783791
if (mapArgs.count("-externalip")) {
@@ -1568,6 +1576,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
15681576
LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
15691577
#endif
15701578

1579+
if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
1580+
StartTorControl(threadGroup, scheduler);
1581+
15711582
StartNode(threadGroup, scheduler);
15721583

15731584
// Monitor the chain, and alert if we get blocks much quicker or slower than expected

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4059,9 +4059,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
40594059
CAddress addr = GetLocalAddress(&pfrom->addr);
40604060
if (addr.IsRoutable())
40614061
{
4062+
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
40624063
pfrom->PushAddress(addr);
40634064
} else if (IsPeerAddrLocalGood(pfrom)) {
40644065
addr.SetIP(pfrom->addrLocal);
4066+
LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
40654067
pfrom->PushAddress(addr);
40664068
}
40674069
}

src/net.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ void AdvertizeLocal(CNode *pnode)
216216
}
217217
if (addrLocal.IsRoutable())
218218
{
219+
LogPrintf("AdvertizeLocal: advertizing address %s\n", addrLocal.ToString());
219220
pnode->PushAddress(addrLocal);
220221
}
221222
}
@@ -262,6 +263,14 @@ bool AddLocal(const CNetAddr &addr, int nScore)
262263
return AddLocal(CService(addr, GetListenPort()), nScore);
263264
}
264265

266+
bool RemoveLocal(const CService& addr)
267+
{
268+
LOCK(cs_mapLocalHost);
269+
LogPrintf("RemoveLocal(%s)\n", addr.ToString());
270+
mapLocalHost.erase(addr);
271+
return true;
272+
}
273+
265274
/** Make a particular network entirely off-limits (no automatic connects to it) */
266275
void SetLimited(enum Network net, bool fLimited)
267276
{

src/net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ bool IsLimited(enum Network net);
128128
bool IsLimited(const CNetAddr& addr);
129129
bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
130130
bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
131+
bool RemoveLocal(const CService& addr);
131132
bool SeenLocal(const CService& addr);
132133
bool IsLocal(const CService& addr);
133134
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);

src/netbase.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,7 @@ bool LookupNumeric(const char *pszName, CService& addr, int portDefault)
227227
return Lookup(pszName, addr, portDefault, false);
228228
}
229229

230-
/**
231-
* Convert milliseconds to a struct timeval for select.
232-
*/
233-
struct timeval static MillisToTimeval(int64_t nTimeout)
230+
struct timeval MillisToTimeval(int64_t nTimeout)
234231
{
235232
struct timeval timeout;
236233
timeout.tv_sec = nTimeout / 1000;

src/netbase.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,9 @@ std::string NetworkErrorString(int err);
215215
bool CloseSocket(SOCKET& hSocket);
216216
/** Disable or enable blocking-mode for a socket */
217217
bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking);
218+
/**
219+
* Convert milliseconds to a struct timeval for e.g. select.
220+
*/
221+
struct timeval MillisToTimeval(int64_t nTimeout);
218222

219223
#endif // BITCOIN_NETBASE_H

0 commit comments

Comments
 (0)