Skip to content

Commit 1443e62

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 1443e62

File tree

3 files changed

+52
-5
lines changed

3 files changed

+52
-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: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,11 @@ TorController::TorController(struct event_base* _base, const std::string& tor_co
331331
reconnect_ev = event_new(base, -1, 0, reconnect_cb, this);
332332
if (!reconnect_ev)
333333
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-
}
334+
// Schedule initial connection attempt after event loop starts and
335+
// EnableTorControl has been called from CConnman::Start()
336+
struct timeval timeout = {1, 0};
337+
if (reconnect_ev)
338+
event_add(reconnect_ev, &timeout);
339339
// Read service private key if cached
340340
std::pair<bool,std::string> pkf = ReadBinaryFile(GetPrivateKeyFile());
341341
if (pkf.first) {
@@ -640,6 +640,11 @@ void TorController::disconnected_cb(TorControlConnection& _conn)
640640
if (!reconnect)
641641
return;
642642

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

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

654659
void TorController::Reconnect()
655660
{
661+
if (!m_network_active) {
662+
// Reschedule to keep the event loop alive while waiting for network
663+
struct timeval timeout = {60, 0};
664+
if (reconnect_ev)
665+
event_add(reconnect_ev, &timeout);
666+
return;
667+
}
656668
/* Try to reconnect and reestablish if we get booted - for example, Tor
657669
* may be restarting.
658670
*/
@@ -662,6 +674,21 @@ void TorController::Reconnect()
662674
}
663675
}
664676

677+
void TorController::SetNetworkActive(bool active)
678+
{
679+
m_network_active = active;
680+
// Cancel any pending reconnect timer
681+
if (reconnect_ev) {
682+
event_del(reconnect_ev);
683+
}
684+
if (!active) {
685+
// Disconnect if currently connected
686+
conn.Disconnect();
687+
}
688+
// Reconnect handles both cases: connects if active, reschedules if inactive
689+
Reconnect();
690+
}
691+
665692
fs::path TorController::GetPrivateKeyFile()
666693
{
667694
return gArgs.GetDataDirNet() / "onion_v3_private_key";
@@ -676,12 +703,16 @@ void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg)
676703
/****** Thread ********/
677704
static struct event_base *gBase;
678705
static std::thread torControlThread;
706+
static TorController *gTorController{nullptr};
679707

680708
static void TorControlThread(CService onion_service_target)
681709
{
682710
TorController ctrl(gBase, gArgs.GetArg("-torcontrol", DEFAULT_TOR_CONTROL), onion_service_target);
711+
gTorController = &ctrl;
683712

684713
event_base_dispatch(gBase);
714+
715+
gTorController = nullptr;
685716
}
686717

687718
void StartTorControl(CService onion_service_target)
@@ -722,6 +753,13 @@ void StopTorControl()
722753
}
723754
}
724755

756+
void EnableTorControl(bool enable)
757+
{
758+
if (gTorController) {
759+
gTorController->SetNetworkActive(enable);
760+
}
761+
}
762+
725763
CService DefaultOnionServiceTarget(uint16_t port)
726764
{
727765
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)