Vidalia 0.2.10
|
00001 /* 00002 ** This file is part of Vidalia, and is subject to the license terms in the 00003 ** LICENSE file, found in the top level directory of this distribution. If 00004 ** you did not receive the LICENSE file with this file, you may obtain it 00005 ** from the Vidalia source package distributed by the Vidalia Project at 00006 ** http://www.vidalia-project.net/. No part of Vidalia, including this file, 00007 ** may be copied, modified, propagated, or distributed except according to 00008 ** the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file ControlConnection.h 00013 ** \version $Id: ControlConnection.h 4054 2009-08-17 02:25:08Z edmanm $ 00014 ** \brief A connection to Tor's control interface, responsible for sending and 00015 ** receiving commands and events 00016 **/ 00017 00018 #ifndef _CONTROLCONNECTION_H 00019 #define _CONTROLCONNECTION_H 00020 00021 #include "ControlSocket.h" 00022 #include "TorEvents.h" 00023 #include "SendCommandEvent.h" 00024 00025 #include <QThread> 00026 #include <QMutex> 00027 #include <QQueue> 00028 #include <QWaitCondition> 00029 #include <QTimer> 00030 #include <QHostAddress> 00031 00032 00033 class ControlConnection : public QThread 00034 { 00035 Q_OBJECT 00036 00037 public: 00038 /** Control connection status */ 00039 enum Status { 00040 Unset, /**< Control connection status is not yet set. */ 00041 Disconnected, /**< Control connection disconnected. */ 00042 Disconnecting, /**< Control connection is disconnecting. */ 00043 Connecting, /**< Control connection attempt pending. */ 00044 Connected /**< Control connection established. */ 00045 }; 00046 00047 /** Default constructor. */ 00048 ControlConnection(TorEvents *events = 0); 00049 /** Destructor. */ 00050 ~ControlConnection(); 00051 00052 /** Connect to the specified Tor control interface. */ 00053 void connect(const QHostAddress &addr, quint16 port); 00054 /** Cancels a pending control connection to Tor. */ 00055 void cancelConnect(); 00056 /** Disconnect from Tor's control interface. */ 00057 void disconnect(); 00058 /** Returns true if the control socket is connected to Tor. */ 00059 bool isConnected(); 00060 /** Returns the status of the control connection. */ 00061 Status status(); 00062 /** Sends a control command to Tor and waits for the reply. */ 00063 bool send(const ControlCommand &cmd, ControlReply &reply, QString *errmsg = 0); 00064 /** Sends a control command to Tor and does not wait for a reply. */ 00065 bool send(const ControlCommand &cmd, QString *errmsg = 0); 00066 00067 signals: 00068 /** Emitted when a control connection has been established. */ 00069 void connected(); 00070 /** Emitted when a control connection has been closed. */ 00071 void disconnected(); 00072 /** Emitted when a control connection fails. */ 00073 void connectFailed(QString errmsg); 00074 00075 private slots: 00076 /** Connects to Tor's control interface. */ 00077 void connect(); 00078 /** Called when there is data on the control socket. */ 00079 void onReadyRead(); 00080 /** Called when the control socket is connected. */ 00081 void onConnected(); 00082 /** Called when the control socket is disconnected. */ 00083 void onDisconnected(); 00084 /** Called when the control socket encounters an error. */ 00085 void onError(QAbstractSocket::SocketError error); 00086 00087 private: 00088 /** Sets the control connection status. */ 00089 void setStatus(Status status); 00090 /** Returns the string description of <b>status</b>. */ 00091 QString statusString(Status status); 00092 /** Main thread implementation. */ 00093 void run(); 00094 00095 ControlSocket* _sock; /**< Socket used to communicate with Tor. */ 00096 TorEvents* _events; /**< Dispatches asynchronous events from Tor. */ 00097 Status _status; /**< Status of the control connection. */ 00098 QHostAddress _addr; /**< Address of Tor's control interface. */ 00099 quint16 _port; /**< Port of Tor's control interface. */ 00100 QMutex _connMutex; /**< Mutex around the control socket. */ 00101 QMutex _recvMutex; /**< Mutex around the queue of ReceiveWaiters. */ 00102 QMutex _statusMutex; /**< Mutex around the connection status value. */ 00103 int _connectAttempt; /**< How many times we've tried to connect to Tor while 00104 waiting for Tor to start. */ 00105 QTimer* _connectTimer; /**< Timer used to delay connect attempts. */ 00106 00107 /** Private class used to wait for a response to a control command. */ 00108 class ReceiveWaiter { 00109 public: 00110 /** Default constructor. */ 00111 ReceiveWaiter() { _status = Waiting; } 00112 /** Waits for and gets the reply from a control command. */ 00113 bool getResult(ControlReply *reply, QString *errmsg = 0); 00114 /** Sets the result and reply from a control command. */ 00115 void setResult(bool success, const ControlReply &reply, 00116 const QString &errmsg = QString()); 00117 private: 00118 /** Status of the receive waiter. */ 00119 enum ReceiveStatus { Waiting, Failed, Success } _status; 00120 ControlReply _reply; /**< Reply to a previous command. */ 00121 QMutex _mutex; /**< Mutex around the wait condition. */ 00122 QWaitCondition _waitCond; /**< Waits for a control rpely. */ 00123 QString _errmsg; /**< Error message if the reply fails. */ 00124 }; 00125 QQueue<ReceiveWaiter *> _recvQueue; /**< Objects waiting for a reply. */ 00126 SendCommandEvent::SendWaiter* _sendWaiter; 00127 }; 00128 00129 #endif 00130