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 return false;
00082 }
00083
00084
00085 _connMutex.lock();
00086 result = _sock->connect(_addr, _port, &errmsg);
00087 _connMutex.unlock();
00088 if (result) {
00089 setStatus(Connected);
00090 emit connected();
00091 return true;
00092 }
00093 QThread::usleep(CONNECT_RETRY_DELAY);
00094 }
00095 setStatus(Disconnected);
00096 emit connectFailed(errmsg);
00097 return false;
00098 }
00099
00100
00101 void
00102 ControlConnection::disconnect()
00103 {
00104
00105 exit(0);
00106 }
00107
00108
00109 void
00110 ControlConnection::cancelConnect()
00111 {
00112 QMutexLocker locker(&_connMutex);
00113 _status = Disconnected;
00114 }
00115
00116
00117 ControlConnection::Status
00118 ControlConnection::status()
00119 {
00120 QMutexLocker locker(&_connMutex);
00121 return _status;
00122 }
00123
00124
00125 void
00126 ControlConnection::setStatus(Status status)
00127 {
00128 QMutexLocker locker(&_connMutex);
00129 _status = status;
00130 }
00131
00132
00133 bool
00134 ControlConnection::send(ControlCommand cmd, ControlReply &reply, QString *errmsg)
00135 {
00136 _recvMutex.lock();
00137 if (send(cmd, errmsg)) {
00138
00139 ReceiveWaiter *w = new ReceiveWaiter();
00140 _recvQueue.enqueue(w);
00141 _recvMutex.unlock();
00142
00143
00144 bool result = w->getResult(&reply, errmsg);
00145 delete w;
00146 return result;
00147 }
00148 _recvMutex.unlock();
00149 return false;
00150 }
00151
00152
00153
00154
00155 bool
00156 ControlConnection::send(ControlCommand cmd, QString *errmsg)
00157 {
00158 QThread *socketThread;
00159 bool result;
00160
00161
00162 _connMutex.lock();
00163 if (!_sock || _status != Connected) {
00164 _connMutex.unlock();
00165 return err(errmsg, tr("Control socket is not connected."));
00166 }
00167 socketThread = _sock->thread();
00168 _connMutex.unlock();
00169
00170 if (socketThread != QThread::currentThread()) {
00171
00172 SendWaiter *w = new SendWaiter();
00173 Vidalia::postEvent(_sock, new SendCommandEvent(cmd, w));
00174
00175
00176 result = w->getResult(errmsg);
00177 delete w;
00178 } else {
00179
00180 _connMutex.lock();
00181 result = _sock->sendCommand(cmd, errmsg);
00182 _connMutex.unlock();
00183 }
00184 return result;
00185 }
00186
00187
00188 void
00189 ControlConnection::onReadyRead()
00190 {
00191 QMutexLocker locker(&_connMutex);
00192 ReceiveWaiter *waiter;
00193
00194 while (_sock->canReadLine()) {
00195 ControlReply reply;
00196 if (_sock->readReply(reply)) {
00197 if (reply.getStatus() == "650") {
00198
00199 if (_events) {
00200 _events->handleEvent(reply);
00201 }
00202 } else {
00203
00204 _recvMutex.lock();
00205 if (!_recvQueue.isEmpty()) {
00206 waiter = _recvQueue.dequeue();
00207 waiter->setResult(true, reply);
00208 }
00209 _recvMutex.unlock();
00210 }
00211 }
00212 }
00213 }
00214
00215
00216 bool
00217 ControlConnection::eventFilter(QObject *obj, QEvent *event)
00218 {
00219 if (event->type() == CustomEventType::SendCommandEvent) {
00220
00221 SendCommandEvent *sce = (SendCommandEvent *)event;
00222 SendWaiter *w = sce->waiter();
00223 QString errmsg;
00224 bool result;
00225
00226
00227 _connMutex.lock();
00228 if (_sock) {
00229 result = _sock->sendCommand(sce->command(), &errmsg);
00230 } else {
00231 result = false;
00232 errmsg = tr("Control socket is not connected");
00233 }
00234 _connMutex.unlock();
00235
00236
00237 if (w) {
00238 w->setResult(result, errmsg);
00239 }
00240
00241
00242 sce->accept();
00243 return true;
00244 }
00245
00246 return QObject::eventFilter(obj, event);
00247 }
00248
00249
00250
00251 void
00252 ControlConnection::run()
00253 {
00254
00255 _connMutex.lock();
00256 _sock = new ControlSocket();
00257 QObject::connect(_sock, SIGNAL(readyRead()), this, SLOT(onReadyRead()),
00258 Qt::DirectConnection);
00259 _sock->installEventFilter(this);
00260 _connMutex.unlock();
00261
00262
00263 if (connect()) {
00264
00265 exec();
00266 }
00267
00268
00269 setStatus(Disconnected);
00270 emit disconnected();
00271
00272
00273 _connMutex.lock();
00274 QObject::disconnect(_sock, 0, 0, 0);
00275 delete _sock;
00276 _sock = 0;
00277 _connMutex.unlock();
00278
00279
00280 _recvMutex.lock();
00281 foreach (ReceiveWaiter *w, _recvQueue) {
00282 w->setResult(false, ControlReply(),
00283 tr("Control socket is not connected."));
00284 }
00285 _recvMutex.unlock();
00286 }
00287
00288
00289
00290
00291
00292
00293 bool
00294 ControlConnection::ReceiveWaiter::getResult(ControlReply *reply,
00295 QString *errmsg)
00296 {
00297 forever {
00298 _mutex.lock();
00299 if (_status == Waiting) {
00300 _waitCond.wait(&_mutex);
00301 _mutex.unlock();
00302 } else {
00303 _mutex.unlock();
00304 break;
00305 }
00306 }
00307 if (errmsg) {
00308 *errmsg = _errmsg;
00309 }
00310 *reply = _reply;
00311 return (_status == Success);
00312 }
00313
00314
00315 void
00316 ControlConnection::ReceiveWaiter::setResult(bool success,
00317 ControlReply reply,
00318 QString errmsg)
00319 {
00320 _status = (success ? Success : Failed);
00321 _reply = reply;
00322 _errmsg = errmsg;
00323 _waitCond.wakeAll();
00324
00325 }
00326
00327
00328
00329
00330
00331
00332 void
00333 ControlConnection::SendWaiter::setResult(bool success, QString errmsg)
00334 {
00335 _mutex.lock();
00336 _status = (success ? Success : Failed);
00337 _errmsg = errmsg;
00338 _mutex.unlock();
00339 _waitCond.wakeAll();
00340 }
00341
00342
00343 bool
00344 ControlConnection::SendWaiter::getResult(QString *errmsg)
00345 {
00346 forever {
00347 _mutex.lock();
00348 if (_status == Waiting) {
00349 _waitCond.wait(&_mutex);
00350 _mutex.unlock();
00351 } else {
00352 _mutex.unlock();
00353 break;
00354 }
00355 }
00356 if (errmsg) {
00357 *errmsg = _errmsg;
00358 }
00359 return (_status == Success);
00360 }
00361