diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index dd4739304..347d8b1c7 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -38,6 +38,7 @@ enum class RsTorManagerEventCode: uint8_t TOR_CONNECTIVITY_CHANGED = 0x03, TOR_MANAGER_ERROR = 0x04, CONFIGURATION_NEEDED = 0x05, + TOR_MANAGER_STOPPED = 0x06, }; // Status of the Tor hidden service setup/loaded by RS diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 86d857980..c4e012de8 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -328,7 +328,7 @@ std::string TorManager::errorMessage() const return d->errorMessage; } -bool TorManager::start() +bool TorManager::startTorManager() { if (!d->errorMessage.empty()) { d->errorMessage.clear(); @@ -432,11 +432,39 @@ bool TorManager::start() d->process->setExecutable(executable); d->process->setDataDir(d->dataDir); d->process->setDefaultTorrc(defaultTorrc); - d->process->start(); } + + std::cerr << "Starting Tor manager thread:" << std::endl; + RsThread::start("TorManager"); return true ; } +void TorManager::run() +{ + d->process->start(); + + while(!shouldStop()) + { + threadTick(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + d->control->shutdown(); + d->process->stop(); + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_MANAGER_STOPPED; + rsEvents->sendEvent(ev); + } +} + +void TorManager::threadTick() +{ + d->process->tick(); +} + bool TorManager::getProxyServerInfo(std::string& proxy_server_adress,uint16_t& proxy_server_port) { proxy_server_adress = control()->socksAddress(); @@ -743,7 +771,7 @@ void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_po bool RsTor::start() { - return instance()->start(); + return instance()->startTorManager(); } void RsTor::setTorDataDirectory(const std::string& dir) diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index e146a6819..555192852 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -47,7 +47,7 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public HiddenServiceClient, public RsTor +class TorManager : public HiddenServiceClient, public RsThread, public RsTor { // Q_OBJECT @@ -65,7 +65,6 @@ public: TorProcess *process(); TorControl *control(); - std::string torDataDirectory() const; void setTorDataDirectory(const std::string &path); @@ -87,7 +86,7 @@ public: bool getProxyServerInfo(std::string &proxy_server_adress, uint16_t& proxy_server_port); //public slots: - bool start(); + bool startTorManager(); //private slots: virtual void hiddenServiceOnline() override {} // do nothing here. @@ -95,9 +94,10 @@ public: virtual void hiddenServiceHostnameChanged() override; virtual void hiddenServiceStatusChanged(int old_status,int new_status) override; -//signals: -// void configurationNeededChanged(); -// void errorChanged(); + // Thread stuff + + virtual void run() override; + void threadTick() ; private: explicit TorManager(); diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 809afdbe9..3142e9488 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -216,12 +216,7 @@ void TorProcess::start() mControlPort = 0; mControlHost.clear(); - RsThread::start("TorControl"); -} - -void TorProcess::run() -{ - // We're inside the process control thread: launch the process, + // Launch the process std::vector args; @@ -278,51 +273,44 @@ void TorProcess::run() flags = fcntl(fd[STDOUT_FILENO], F_GETFL); fcntl(fd[STDOUT_FILENO], F_SETFL, flags | O_NONBLOCK); flags = fcntl(fd[STDERR_FILENO], F_GETFL); fcntl(fd[STDERR_FILENO], F_SETFL, flags | O_NONBLOCK); - RsFdBinInterface stdout_FD(fd[STDOUT_FILENO]); - RsFdBinInterface stderr_FD(fd[STDERR_FILENO]); + mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO]); + mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO]); +} + +void TorProcess::tick() +{ + mStdOutFD->tick(); + mStdErrFD->tick(); unsigned char buff[1024]; + int s; - while(!shouldStop()) + if((s=mStdOutFD->readline(buff,1024))) logMessage(std::string((char*)buff,s)); + if((s=mStdErrFD->readline(buff,1024))) logMessage(std::string((char*)buff,s)); + + if(!mStdOutFD->isactive() && !mStdErrFD->isactive()) { - stdout_FD.tick(); - stderr_FD.tick(); - int s; + RsErr() << "Tor process died. Exiting TorControl process." ; + stop(); + return; + } + time_t now = time(nullptr); - if((s=stdout_FD.readline(buff,1024))) logMessage(std::string((char*)buff,s)); - if((s=stderr_FD.readline(buff,1024))) logMessage(std::string((char*)buff,s)); + if(mControlPortReadNbTries <= 10 && (mControlPort==0 || mControlHost.empty()) && mLastTryReadControlPort + INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES < now) + { + mLastTryReadControlPort = now; - if(!stdout_FD.isactive() && !stderr_FD.isactive()) + if(tryReadControlPort()) { - RsErr() << "Tor process died. Exiting TorControl process." ; - return; + mState = Ready; + // stateChanged(mState); } - time_t now = time(nullptr); - - if(mControlPortReadNbTries <= 10 && (mControlPort==0 || mControlHost.empty()) && mLastTryReadControlPort + INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES < now) + else if(mControlPortReadNbTries > 10) { - mLastTryReadControlPort = now; - - if(tryReadControlPort()) - { - mState = Ready; - // stateChanged(mState); - } - else if(mControlPortReadNbTries > 10) - { - //errorMessageChanged(errorMessage); - //stateChanged(state); - } + //errorMessageChanged(errorMessage); + //stateChanged(state); } } - - // Kill the Tor process since we've been asked to stop. - - kill(mTorProcessId,SIGTERM); - int status=0; - wait(&status); - - RsInfo() << "Tor process has been normally terminated. Exiting."; } void TorProcess::stop() @@ -333,7 +321,9 @@ void TorProcess::stop() while(mState == Starting) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - fullstop(); + kill(mTorProcessId,SIGTERM); + + RsInfo() << "Tor process has been normally terminated. Exiting."; mState = NotStarted; @@ -431,7 +421,7 @@ bool TorProcess::tryReadControlPort() if (!mControlHost.empty() && mControlPort > 0) { - std::cerr << "Read control port = " << mControlPort << std::endl; + std::cerr << "Got control host/port = " << mControlHost << ":" << mControlPort << std::endl; return true; } } diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index 7b7868417..77f3bb60b 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -36,6 +36,8 @@ #include "bytearray.h" #include "util/rsthreads.h" +class RsFdBinInterface ; + namespace Tor { @@ -53,14 +55,8 @@ public: /* Launches and controls a Tor instance with behavior suitable for bundling * an instance with the application. */ -class TorProcess: public RsThread +class TorProcess { - //Q_OBJECT - //Q_ENUMS(State) - - //Q_PROPERTY(State state READ state NOTIFY stateChanged) - //Q_PROPERTY(std::string errorMessage READ errorMessage NOTIFY errorMessageChanged) - public: enum State { Failed = -1, @@ -91,20 +87,14 @@ public: unsigned short controlPort(); ByteArray controlPassword(); -//signals: void stateChanged(int newState); void errorMessageChanged(const std::string &errorMessage); void logMessage(const std::string &message); -//public slots: void start(); void stop(); + void tick(); - // Implements RsThread - void run() override ; - - // Keeps reading the output of the tor process and so on. - void threadTick(); private: TorProcessClient *m_client; @@ -127,12 +117,15 @@ private: pid_t mTorProcessId; time_t mLastTryReadControlPort ; int mControlPortReadNbTries ; -//public slots: + void processStarted(); void processFinished(); void processError(std::string error); void processReadable(); bool tryReadControlPort(); + + RsFdBinInterface *mStdOutFD; + RsFdBinInterface *mStdErrFD; }; }