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 2838 2008-07-06 22:43:48Z 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 <QThread> 00022 #include <QMutex> 00023 #include <QQueue> 00024 #include <QWaitCondition> 00025 #include <QTimer> 00026 #include <QHostAddress> 00027 00028 #include "eventtype.h" 00029 #include "controlsocket.h" 00030 #include "torevents.h" 00031 #include "sendcommandevent.h" 00032 00033 00034 class ControlConnection : public QThread 00035 { 00036 Q_OBJECT 00037 00038 public: 00039 /** Control connection status */ 00040 enum Status { 00041 Unset, /**< Control connection status is not yet set. */ 00042 Disconnected, /**< Control connection disconnected. */ 00043 Disconnecting, /**< Control connection is disconnecting. */ 00044 Connecting, /**< Control connection attempt pending. */ 00045 Connected /**< Control connection established. */ 00046 }; 00047 00048 /** Default constructor. */ 00049 ControlConnection(TorEvents *events = 0); 00050 /** Destructor. */ 00051 ~ControlConnection(); 00052 00053 /** Connect to the specified Tor control interface. */ 00054 void connect(const QHostAddress &addr, quint16 port); 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 TorEvents* _events; /**< Dispatches asynchronous events from Tor. */ 00098 Status _status; /**< Status of the control connection. */ 00099 QHostAddress _addr; /**< Address of Tor's control interface. */ 00100 quint16 _port; /**< Port of Tor's control interface. */ 00101 QMutex _connMutex; /**< Mutex around the control socket. */ 00102 QMutex _recvMutex; /**< Mutex around the queue of ReceiveWaiters. */ 00103 QMutex _statusMutex; /**< Mutex around the connection status value. */ 00104 int _connectAttempt; /**< How many times we've tried to connect to Tor while 00105 waiting for Tor to start. */ 00106 QTimer* _connectTimer; /**< Timer used to delay connect attempts. */ 00107 00108 /** Private class used to wait for a response to a control command. */ 00109 class ReceiveWaiter { 00110 public: 00111 /** Default constructor. */ 00112 ReceiveWaiter() { _status = Waiting; } 00113 /** Waits for and gets the reply from a control command. */ 00114 bool getResult(ControlReply *reply, QString *errmsg = 0); 00115 /** Sets the result and reply from a control command. */ 00116 void setResult(bool success, const ControlReply &reply, 00117 const QString &errmsg = QString()); 00118 private: 00119 /** Status of the receive waiter. */ 00120 enum ReceiveStatus { Waiting, Failed, Success } _status; 00121 ControlReply _reply; /**< Reply to a previous command. */ 00122 QMutex _mutex; /**< Mutex around the wait condition. */ 00123 QWaitCondition _waitCond; /**< Waits for a control rpely. */ 00124 QString _errmsg; /**< Error message if the reply fails. */ 00125 }; 00126 QQueue<ReceiveWaiter *> _recvQueue; /**< Objects waiting for a reply. */ 00127 SendCommandEvent::SendWaiter* _sendWaiter; 00128 }; 00129 00130 #endif 00131