Skip to content

Commit 9811b8c

Browse files
committed
net: run tor control based on networkactive
When -networkactive=0 is set, Tor control connection attempts were still running and logging retry messages. Wire tor control lifecycle to CConnman similar to mapport: add EnableTorControl() called from Start() and SetNetworkActive(). TorController starts disconnected and waits for EnableTorControl(true) from CConnman::Start() before connecting. The event loop stays alive (unlike mapport's thread start/stop) since restructuring libevent lifecycle would be more invasive.
1 parent 887d3a8 commit 9811b8c

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

src/net.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <unordered_map>
4949

5050
void EnableMapPort(bool enable);
51+
void EnableTorControl(bool enable);
5152

5253
TRACEPOINT_SEMAPHORE(net, closed_connection);
5354
TRACEPOINT_SEMAPHORE(net, evicted_inbound_connection);
@@ -3227,6 +3228,7 @@ void CConnman::SetNetworkActive(bool active)
32273228
fNetworkActive = active;
32283229

32293230
EnableMapPort(m_mapport_enabled && active);
3231+
EnableTorControl(active);
32303232

32313233
if (m_client_interface) {
32323234
m_client_interface->NotifyNetworkActiveChanged(fNetworkActive);
@@ -3434,6 +3436,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
34343436
}
34353437

34363438
EnableMapPort(m_mapport_enabled && fNetworkActive);
3439+
EnableTorControl(fNetworkActive);
34373440

34383441
return true;
34393442
}

src/torcontrol.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <util/time.h>
2626

2727
#include <algorithm>
28+
#include <atomic>
2829
#include <cassert>
2930
#include <cstdint>
3031
#include <cstdlib>
@@ -331,11 +332,11 @@ TorController::TorController(struct event_base* _base, const std::string& tor_co
331332
reconnect_ev = event_new(base, -1, 0, reconnect_cb, this);
332333
if (!reconnect_ev)
333334
LogWarning("tor: Failed to create event for reconnection: out of memory?");
334-
// Start connection attempts immediately
335-
if (!conn.Connect(m_tor_control_center, std::bind(&TorController::connected_cb, this, std::placeholders::_1),
336-
std::bind(&TorController::disconnected_cb, this, std::placeholders::_1) )) {
337-
LogWarning("tor: Initiating connection to Tor control port %s failed", m_tor_control_center);
338-
}
335+
// Schedule initial connection attempt after event loop starts and
336+
// EnableTorControl has been called from CConnman::Start()
337+
struct timeval timeout = {1, 0};
338+
if (reconnect_ev)
339+
event_add(reconnect_ev, &timeout);
339340
// Read service private key if cached
340341
std::pair<bool,std::string> pkf = ReadBinaryFile(GetPrivateKeyFile());
341342
if (pkf.first) {
@@ -640,6 +641,11 @@ void TorController::disconnected_cb(TorControlConnection& _conn)
640641
if (!reconnect)
641642
return;
642643

644+
if (!m_network_active) {
645+
LogDebug(BCLog::TOR, "Network inactive, not reconnecting to Tor control port\n");
646+
return;
647+
}
648+
643649
LogDebug(BCLog::TOR, "Not connected to Tor control port %s, retrying in %.2f s\n",
644650
m_tor_control_center, reconnect_timeout);
645651

@@ -653,6 +659,13 @@ void TorController::disconnected_cb(TorControlConnection& _conn)
653659

654660
void TorController::Reconnect()
655661
{
662+
if (!m_network_active) {
663+
// Reschedule to keep the event loop alive while waiting for network
664+
struct timeval timeout = {60, 0};
665+
if (reconnect_ev)
666+
event_add(reconnect_ev, &timeout);
667+
return;
668+
}
656669
/* Try to reconnect and reestablish if we get booted - for example, Tor
657670
* may be restarting.
658671
*/
@@ -662,6 +675,21 @@ void TorController::Reconnect()
662675
}
663676
}
664677

678+
void TorController::SetNetworkActive(bool active)
679+
{
680+
m_network_active = active;
681+
// Cancel any pending reconnect timer
682+
if (reconnect_ev) {
683+
event_del(reconnect_ev);
684+
}
685+
if (!active) {
686+
// Disconnect if currently connected
687+
conn.Disconnect();
688+
}
689+
// Reconnect handles both cases: connects if active, reschedules if inactive
690+
Reconnect();
691+
}
692+
665693
fs::path TorController::GetPrivateKeyFile()
666694
{
667695
return gArgs.GetDataDirNet() / "onion_v3_private_key";
@@ -676,12 +704,16 @@ void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg)
676704
/****** Thread ********/
677705
static struct event_base *gBase;
678706
static std::thread torControlThread;
707+
static std::atomic<TorController*> gTorController{nullptr};
679708

680709
static void TorControlThread(CService onion_service_target)
681710
{
682711
TorController ctrl(gBase, gArgs.GetArg("-torcontrol", DEFAULT_TOR_CONTROL), onion_service_target);
712+
gTorController.store(&ctrl);
683713

684714
event_base_dispatch(gBase);
715+
716+
gTorController.store(nullptr);
685717
}
686718

687719
void StartTorControl(CService onion_service_target)
@@ -722,6 +754,13 @@ void StopTorControl()
722754
}
723755
}
724756

757+
void EnableTorControl(bool enable)
758+
{
759+
if (TorController* ctrl = gTorController.load()) {
760+
ctrl->SetNetworkActive(enable);
761+
}
762+
}
763+
725764
CService DefaultOnionServiceTarget(uint16_t port)
726765
{
727766
struct in_addr onion_service_target;

src/torcontrol.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static const bool DEFAULT_LISTEN_ONION = true;
2727
void StartTorControl(CService onion_service_target);
2828
void InterruptTorControl();
2929
void StopTorControl();
30+
void EnableTorControl(bool enable);
3031

3132
CService DefaultOnionServiceTarget(uint16_t port);
3233

@@ -118,13 +119,18 @@ class TorController
118119

119120
/** Reconnect, after getting disconnected */
120121
void Reconnect();
122+
123+
/** Set network active state - controls whether to attempt connections */
124+
void SetNetworkActive(bool active);
125+
121126
private:
122127
struct event_base* base;
123128
const std::string m_tor_control_center;
124129
TorControlConnection conn;
125130
std::string private_key;
126131
std::string service_id;
127132
bool reconnect;
133+
bool m_network_active{false};
128134
struct event *reconnect_ev = nullptr;
129135
float reconnect_timeout;
130136
CService service;

0 commit comments

Comments
 (0)