Improve Tor startup diagnostics on Windows
This commit is contained in:
+4
-1
@@ -1223,7 +1223,10 @@ bool AppInit2()
|
||||
fUseUPnP = false;
|
||||
#endif
|
||||
} else {
|
||||
return InitError(_("Tor failed to start. Triangles requires Tor to operate."));
|
||||
std::string torError = CTorEmbedded::GetInstance()->GetLastError();
|
||||
if (torError.empty())
|
||||
torError = "No detailed Tor startup error was recorded.";
|
||||
return InitError(strprintf(_("Tor failed to start. Triangles requires Tor to operate.\n\nDetails: %s"), torError));
|
||||
}
|
||||
|
||||
// Initialize Tor V3 identity (Ed25519 keys, onion address)
|
||||
|
||||
@@ -114,6 +114,7 @@ bool CTorEmbedded::Start(int socks, int hsPort, bool enableHiddenService)
|
||||
{
|
||||
if (running.load()) return true;
|
||||
|
||||
lastError.clear();
|
||||
socksPort = socks;
|
||||
hiddenServiceEnabled = enableHiddenService;
|
||||
hiddenServicePort = hiddenServiceEnabled ? hsPort : 0;
|
||||
@@ -202,11 +203,13 @@ bool CTorEmbedded::Start(int socks, int hsPort, bool enableHiddenService)
|
||||
}
|
||||
|
||||
if (!running.load()) {
|
||||
lastError = "Embedded Tor thread exited during bootstrap before the SOCKS proxy became available.";
|
||||
printf("ERROR: Embedded Tor thread exited during bootstrap\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lastError = strprintf("Embedded Tor did not expose SOCKS port %d within 60 seconds.", socksPort);
|
||||
printf("WARNING: Embedded Tor started but SOCKS not ready after 60s (still bootstrapping)\n");
|
||||
return true;
|
||||
}
|
||||
@@ -241,8 +244,12 @@ bool CTorEmbedded::Start(int socks, int hsPort, bool enableHiddenService)
|
||||
hiddenServiceEnabled = enableHiddenService;
|
||||
hiddenServicePort = hiddenServiceEnabled ? hsPort : 0;
|
||||
onionHostname.clear();
|
||||
lastError.clear();
|
||||
torDataDir = (::GetDataDir() / "tor_data").string();
|
||||
running.store(StartTorProcess(torDataDir, socksPort, hiddenServicePort, hiddenServiceEnabled));
|
||||
if (!running.load()) {
|
||||
lastError = CTorProcess::GetInstance()->GetLastError();
|
||||
}
|
||||
return running.load();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ private:
|
||||
bool hiddenServiceEnabled;
|
||||
std::string torDataDir;
|
||||
std::string onionHostname;
|
||||
std::string lastError;
|
||||
|
||||
public:
|
||||
static CTorEmbedded* GetInstance();
|
||||
@@ -43,6 +44,8 @@ public:
|
||||
|
||||
// Get our .onion address (available after bootstrap)
|
||||
std::string GetOnionAddress() const { return onionHostname; }
|
||||
std::string GetLastError() const { return lastError; }
|
||||
void SetLastError(const std::string& value) { lastError = value; }
|
||||
|
||||
// Get the hidden service port
|
||||
int GetHiddenServicePort() const { return hiddenServicePort; }
|
||||
|
||||
+10
-1
@@ -232,6 +232,7 @@ bool CTorProcess::WriteTorrc()
|
||||
|
||||
bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool enableHiddenService)
|
||||
{
|
||||
lastError.clear();
|
||||
socksPort = socks;
|
||||
hiddenServiceEnabled = enableHiddenService;
|
||||
hiddenServicePort = hiddenServiceEnabled ? hsPort : 0;
|
||||
@@ -240,6 +241,7 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
// Check if something is already listening on our SOCKS port
|
||||
if (IsPortInUse(socksPort)) {
|
||||
printf("Tor SOCKS port %d already in use - assuming Tor is running\n", socksPort);
|
||||
lastError = strprintf("SOCKS port %d is already in use; assuming an existing Tor instance is serving it.", socksPort);
|
||||
running = true;
|
||||
return true;
|
||||
}
|
||||
@@ -247,6 +249,7 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
// Find Tor binary
|
||||
torBinaryPath = FindTorBinary();
|
||||
if (torBinaryPath.empty()) {
|
||||
lastError = "Tor binary was not found in the bundled install or standard search paths.";
|
||||
printf("WARNING: Tor binary not found. Install Tor for .onion connectivity.\n");
|
||||
printf(" Windows: Download from https://www.torproject.org/download/tor/\n");
|
||||
printf(" Linux: apt install tor or yum install tor\n");
|
||||
@@ -256,6 +259,7 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
|
||||
// Write configuration
|
||||
if (!WriteTorrc()) {
|
||||
lastError = strprintf("Failed to write Tor configuration to %s", torrcPath.c_str());
|
||||
printf("ERROR: Failed to write Tor configuration\n");
|
||||
return false;
|
||||
}
|
||||
@@ -282,7 +286,9 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
NULL, NULL,
|
||||
&si, &pi))
|
||||
{
|
||||
printf("ERROR: Failed to start Tor process (error %lu)\n", GetLastError());
|
||||
DWORD err = GetLastError();
|
||||
lastError = strprintf("CreateProcess failed for Tor binary '%s' with Windows error %lu", torBinaryPath.c_str(), err);
|
||||
printf("ERROR: Failed to start Tor process (error %lu)\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -329,6 +335,7 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
// Defensive check: Tor must not directly occupy the node's hidden-service
|
||||
// virtual port. If it does, node startup will fail with a bind collision.
|
||||
if (hiddenServiceEnabled && IsPortInUse(hiddenServicePort)) {
|
||||
lastError = strprintf("Port %d is already busy while Tor hidden service is enabled. Another process is likely blocking the node listener.", hiddenServicePort);
|
||||
printf("ERROR: Tor startup collision: hidden service port %d appears busy before node bind.\n",
|
||||
hiddenServicePort);
|
||||
printf(" Refusing to treat Tor as healthy because this would block the node listener.\n");
|
||||
@@ -353,12 +360,14 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
|
||||
// Check if Tor process is still alive
|
||||
if (!IsRunning()) {
|
||||
lastError = "Tor process exited during bootstrap before the SOCKS port became ready.";
|
||||
printf("ERROR: Tor process exited prematurely\n");
|
||||
running = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lastError = strprintf("Tor process started from '%s' but SOCKS port %d was not ready after 30 seconds.", torBinaryPath.c_str(), socksPort);
|
||||
printf("WARNING: Tor started but SOCKS proxy not yet ready after 30s\n");
|
||||
printf(" Tor may still be bootstrapping. .onion connections will work once ready.\n");
|
||||
return true;
|
||||
|
||||
@@ -19,6 +19,7 @@ private:
|
||||
std::string torBinaryPath;
|
||||
std::string torDataDir;
|
||||
std::string torrcPath;
|
||||
std::string lastError;
|
||||
int socksPort;
|
||||
int hiddenServicePort;
|
||||
bool hiddenServiceEnabled;
|
||||
@@ -59,6 +60,7 @@ public:
|
||||
|
||||
// Get the Tor binary path (for diagnostics)
|
||||
std::string GetBinaryPath() const { return torBinaryPath; }
|
||||
std::string GetLastError() const { return lastError; }
|
||||
|
||||
// Singleton access
|
||||
static CTorProcess* GetInstance();
|
||||
|
||||
Reference in New Issue
Block a user