00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <QMutexLocker>
00030 #include <util/string.h>
00031 #include <vidalia.h>
00032
00033 #include "controlconnection.h"
00034
00035
00036 #define MAX_CONNECT_ATTEMPTS 6
00037
00038 #define CONNECT_RETRY_DELAY 500*1000
00039
00040
00041
00042 ControlConnection::ControlConnection(TorEvents *events)
00043 {
00044 _events = events;
00045 _sock = 0;
00046 }
00047
00048
00049 ControlConnection::~ControlConnection()
00050 {
00051
00052 exit();
00053
00054 wait();
00055 }
00056
00057
00058 void
00059 ControlConnection::connect(QHostAddress addr, quint16 port)
00060 {
00061
00062 _addr = addr;
00063 _port = port;
00064
00065 QThread::start();
00066 }
00067
00068
00069
00070
00071 bool
00072 ControlConnection::connect()
00073 {
00074 QString errmsg;
00075 bool result;
00076
00077 setStatus(Connecting);
00078 for (int i = 0; i < MAX_CONNECT_ATTEMPTS; i++) {
00079
00080 if (status() != Connecting) {
00081 vNotice("Cancelling attempt to connect to Tor's control port.");
00082 return false;
00083 }
00084
00085
00086 _connMutex.lock();
00087 vDebug("Control connection attempt %1 of %2").arg(i+1)
00088 .arg(MAX_CONNECT_ATTEMPTS);
00089 result = _sock->connect(_addr, _port, &errmsg);
00090 _connMutex.unlock();
00091 if (result) {
00092 vInfo("Connected to Tor's control port.");
00093 setStatus(Connected);
00094 emit connected();
00095 return true;
00096 }
00097 QThread::usleep(CONNECT_RETRY_DELAY);
00098 }
00099 setStatus(Disconnected);
00100 vWarn("Failed to connect to Tor's control port after %1 attempts: %2")
00101 .arg(MAX_CONNECT_ATTEMPTS)
00102 .arg(errmsg);
00103 emit connectFailed(errmsg);
00104 return false;
00105 }
00106
00107
00108 void
00109 ControlConnection::disconnect()
00110 {
00111
00112 exit(0);
00113 }
00114
00115
00116 void
00117 ControlConnection::cancelConnect()
00118 {
00119 QMutexLocker locker(&_connMutex);
00120 _status = Disconnected;
00121 }
00122
00123
00124 ControlConnection::Status
00125 ControlConnection::status()
00126 {
00127 QMutexLocker locker(&_connMutex);
00128 return _status;
00129 }
00130
00131
00132 void
00133 ControlConnection::setStatus(Status status)
00134 {
00135 QMutexLocker locker(&_connMutex);
00136 _status = status;
00137 }
00138
00139
00140 bool
00141 ControlConnection::send(ControlCommand cmd, ControlReply &reply, QString *errmsg)
00142 {
00143 bool result = false;
00144 QString errstr;
00145
00146 _recvMutex.lock();
00147 if (send(cmd, &errstr)) {
00148
00149 ReceiveWaiter *w = new ReceiveWaiter();
00150 _recvQueue.enqueue(w);
00151 _recvMutex.unlock();
00152
00153
00154 result = w->getResult(&reply, &errstr);
00155 if (!result)
00156 vWarn("Failed to receive control reply: %1").arg(errstr);
00157 delete w;
00158 } else {
00159 vWarn("Failed to send control command (%1): %2")
00160 .arg(cmd.keyword()).arg(errstr);
00161 _recvMutex.unlock();
00162 }
00163
00164 if (!result && errmsg)
00165 *errmsg = errstr;
00166 return result;
00167 }
00168
00169
00170
00171
00172 bool
00173 ControlConnection::send(ControlCommand cmd, QString *errmsg)
00174 {
00175 QThread *socketThread;
00176 bool result;
00177
00178
00179 _connMutex.lock();
00180 if (!_sock || _status != Connected) {
00181 _connMutex.unlock();
00182 return err(errmsg, tr("Control socket is not connected."));
00183 }
00184 socketThread = _sock->thread();
00185 _connMutex.unlock();
00186
00187 if (socketThread != QThread::currentThread()) {
00188
00189 SendWaiter *w = new SendWaiter();
00190 Vidalia::postEvent(_sock, new SendCommandEvent(cmd, w));
00191
00192
00193 result = w->getResult(errmsg);
00194 delete w;
00195 } else {
00196
00197 _connMutex.lock();
00198 result = _sock->sendCommand(cmd, errmsg);
00199 _connMutex.unlock();
00200 }
00201 return result;
00202 }
00203
00204
00205 void
00206 ControlConnection::onReadyRead()
00207 {
00208 QMutexLocker locker(&_connMutex);
00209 ReceiveWaiter *waiter;
00210 QString errmsg;
00211
00212 while (_sock->canReadLine()) {
00213 ControlReply reply;
00214 if (_sock->readReply(reply, &errmsg)) {
00215 if (reply.getStatus() == "650") {
00216
00217 vDebug("Control Event: %1").arg(reply.toString());
00218
00219 if (_events) {
00220 _events->handleEvent(reply);
00221 }
00222 } else {
00223
00224 vInfo("Control Reply: %1").arg(reply.toString());
00225
00226 _recvMutex.lock();
00227 if (!_recvQueue.isEmpty()) {
00228 waiter = _recvQueue.dequeue();
00229 waiter->setResult(true, reply);
00230 }
00231 _recvMutex.unlock();
00232 }
00233 } else {
00234 vWarn("Unable to read control reply: %1").arg(errmsg);
00235 }
00236 }
00237 }
00238
00239
00240 bool
00241 ControlConnection::eventFilter(QObject *obj, QEvent *event)
00242 {
00243 if (event->type() == CustomEventType::SendCommandEvent) {
00244
00245 SendCommandEvent *sce = (SendCommandEvent *)event;
00246 SendWaiter *w = sce->waiter();
00247 QString errmsg;
00248 bool result;
00249
00250
00251 _connMutex.lock();
00252 if (_sock) {
00253 result = _sock->sendCommand(sce->command(), &errmsg);
00254 } else {
00255 result = false;
00256 errmsg = tr("Control socket is not connected");
00257 }
00258 _connMutex.unlock();
00259
00260
00261 if (w) {
00262 w->setResult(result, errmsg);
00263 }
00264
00265
00266 sce->accept();
00267 return true;
00268 }
00269
00270 return QObject::eventFilter(obj, event);
00271 }
00272
00273
00274
00275 void
00276 ControlConnection::run()
00277 {
00278
00279 _connMutex.lock();
00280 _sock = new ControlSocket();
00281 QObject::connect(_sock, SIGNAL(readyRead()), this, SLOT(onReadyRead()),
00282 Qt::DirectConnection);
00283 QObject::connect(_sock, SIGNAL(disconnected()), this, SLOT(quit()),
00284 Qt::DirectConnection);
00285 _sock->installEventFilter(this);
00286 _connMutex.unlock();
00287
00288
00289 if (connect()) {
00290 vDebug("Starting control connection event loop.");
00291
00292 exec();
00293 vDebug("Exited control connection event loop.");
00294 }
00295
00296
00297 setStatus(Disconnected);
00298 emit disconnected();
00299
00300
00301 _connMutex.lock();
00302 QObject::disconnect(_sock, 0, 0, 0);
00303 delete _sock;
00304 _sock = 0;
00305 _connMutex.unlock();
00306
00307
00308 _recvMutex.lock();
00309 foreach (ReceiveWaiter *w, _recvQueue) {
00310 w->setResult(false, ControlReply(),
00311 tr("Control socket is not connected."));
00312 }
00313 _recvMutex.unlock();
00314 }
00315
00316
00317
00318
00319
00320
00321 bool
00322 ControlConnection::ReceiveWaiter::getResult(ControlReply *reply,
00323 QString *errmsg)
00324 {
00325 forever {
00326 _mutex.lock();
00327 if (_status == Waiting) {
00328 _waitCond.wait(&_mutex);
00329 _mutex.unlock();
00330 } else {
00331 _mutex.unlock();
00332 break;
00333 }
00334 }
00335 if (errmsg) {
00336 *errmsg = _errmsg;
00337 }
00338 *reply = _reply;
00339 return (_status == Success);
00340 }
00341
00342
00343 void
00344 ControlConnection::ReceiveWaiter::setResult(bool success,
00345 ControlReply reply,
00346 QString errmsg)
00347 {
00348 _mutex.lock();
00349 _status = (success ? Success : Failed);
00350 _reply = reply;
00351 _errmsg = errmsg;
00352 _mutex.unlock();
00353 _waitCond.wakeAll();
00354 }
00355
00356
00357
00358
00359
00360
00361 void
00362 ControlConnection::SendWaiter::setResult(bool success, QString errmsg)
00363 {
00364 _mutex.lock();
00365 _status = (success ? Success : Failed);
00366 _errmsg = errmsg;
00367 _mutex.unlock();
00368 _waitCond.wakeAll();
00369 }
00370
00371
00372 bool
00373 ControlConnection::SendWaiter::getResult(QString *errmsg)
00374 {
00375 forever {
00376 _mutex.lock();
00377 if (_status == Waiting) {
00378 _waitCond.wait(&_mutex);
00379 _mutex.unlock();
00380 } else {
00381 _mutex.unlock();
00382 break;
00383 }
00384 }
00385 if (errmsg) {
00386 *errmsg = _errmsg;
00387 }
00388 return (_status == Success);
00389 }
00390