fixed a few bugs that may cause the bootstrap process to hang

This commit is contained in:
csoler 2021-12-28 18:29:33 +01:00
parent a37802ca96
commit efe2ec03ff
3 changed files with 25 additions and 16 deletions

View File

@ -65,14 +65,9 @@ static std::ostream& torctrldebug()
using namespace Tor; using namespace Tor;
TorControl::TorControl() TorControl::TorControl()
: mControlPort(0),mSocksPort(0),mStatus(NotConnected), mTorStatus(TorOffline),mHasOwnership(false) : mControlPort(0),mSocksPort(0),mStatus(NotConnected), mTorStatus(TorUnknown),mHasOwnership(false)
{ {
mSocket = new TorControlSocket(this); mSocket = new TorControlSocket(this);
mControlPort = 0;
mSocksPort = 0;
mStatus = NotConnected;
mTorStatus = TorUnknown;
mHasOwnership = false;
} }
static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t)
@ -127,6 +122,7 @@ void TorControl::setTorStatus(TorControl::TorStatus n)
if (n == mTorStatus) if (n == mTorStatus)
return; return;
RsDbg() << "Setting TorStatus=" << n ;
mTorStatus = n; mTorStatus = n;
if(rsEvents) if(rsEvents)
@ -216,7 +212,10 @@ void TorControl::connect(const std::string &address, uint16_t port)
setStatus(Connecting); setStatus(Connecting);
if(mSocket->connectToHost(address, port)) if(mSocket->connectToHost(address, port))
{
setStatus(SocketConnected); setStatus(SocketConnected);
setTorStatus(TorOffline); // connected and running, but not yet ready
}
} }
void TorControl::reconnect() void TorControl::reconnect()
@ -246,8 +245,6 @@ void TorControl::authenticateReply(TorControlCommand *sender)
torCtrlDebug() << "torctrl: Authentication successful" << std::endl; torCtrlDebug() << "torctrl: Authentication successful" << std::endl;
setStatus(TorControl::Authenticated); setStatus(TorControl::Authenticated);
setTorStatus(TorControl::TorUnknown);
TorControlCommand *clientEvents = new TorControlCommand; TorControlCommand *clientEvents = new TorControlCommand;
clientEvents->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data);}); clientEvents->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data);});
@ -442,8 +439,8 @@ void TorControl::getTorInfoReply(TorControlCommand *sender)
torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl; torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl;
setTorStatus(TorControl::TorReady); setTorStatus(TorControl::TorReady);
} }
else // else
setTorStatus(TorControl::TorOffline); // setTorStatus(TorControl::TorOffline);
auto bootstrap = command->get("status/bootstrap-phase"); auto bootstrap = command->get("status/bootstrap-phase");
if (!bootstrap.empty()) if (!bootstrap.empty())
@ -562,14 +559,15 @@ void TorControl::statusEvent(int /* code */, const ByteArray &data)
if (tokens.size() < 3) if (tokens.size() < 3)
return; return;
torCtrlDebug() << "torctrl: status event:" << data.trimmed().toString() << std::endl; const ByteArray& tok2 = *(++(++tokens.begin()));
const ByteArray& tok2 = *(++tokens.begin()); torCtrlDebug() << "torctrl: status event:" << data.trimmed().toString() << " tok2=\"" << tok2.toString() << "\"" << std::endl;
if (tok2 == "CIRCUIT_ESTABLISHED") { if (tok2 == "CIRCUIT_ESTABLISHED")
setTorStatus(TorControl::TorReady); setTorStatus(TorControl::TorReady);
} else if (tok2 == "CIRCUIT_NOT_ESTABLISHED") { else if (tok2 == "CIRCUIT_NOT_ESTABLISHED")
setTorStatus(TorControl::TorOffline); setTorStatus(TorControl::TorOffline);
} else if (tok2 == "BOOTSTRAP") { else if (tok2 == "BOOTSTRAP")
{
tokens.pop_front(); tokens.pop_front();
updateBootstrap(tokens); updateBootstrap(tokens);
} }

View File

@ -51,7 +51,7 @@ bool TorControlSocket::connectToHost(const std::string& tcp_address,uint16_t tcp
{ {
if(RsTcpSocket::connect(tcp_address,tcp_port)) if(RsTcpSocket::connect(tcp_address,tcp_port))
{ {
start(); start("TorControlSocket");
return true; return true;
} }
else else
@ -131,6 +131,12 @@ void TorControlSocket::process()
ByteArray line = readline(5120); ByteArray line = readline(5120);
if(line.empty()) // This happens when the incoming buffer isn't empty yet doesn't have a full line already.
{
std::this_thread::sleep_for(std::chrono::milliseconds(50));
continue;
}
if (!line.endsWith(ByteArray("\r\n"))) { if (!line.endsWith(ByteArray("\r\n"))) {
setError("Invalid control message syntax"); setError("Invalid control message syntax");
return; return;

View File

@ -502,6 +502,11 @@ void TorManager::threadTick()
break; break;
case TorControl::HiddenServiceReady: case TorControl::HiddenServiceReady:
if(d->control->torStatus() < TorControl::TorReady)
{
d->control->getTorInfo(); // forces TorControl to check its state.
std::this_thread::sleep_for(std::chrono::seconds(1));
}
break; break;
case TorControl::Error: case TorControl::Error: