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