00001 /**************************************************************** 00002 * Vidalia is distributed under the following license: 00003 * 00004 * Copyright (C) 2006, Matt Edman, Justin Hipple 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 ****************************************************************/ 00021 00022 /** 00023 * \file controlconnection.h 00024 * \version $Id: controlconnection.h 1563 2006-12-26 06:06:04Z edmanm $ 00025 * \brief A connection to Tor's control interface, responsible for sending and 00026 * receiving commands and events 00027 */ 00028 00029 #ifndef _CONTROLCONNECTION_H 00030 #define _CONTROLCONNECTION_H 00031 00032 #include <QThread> 00033 #include <QMutex> 00034 #include <QQueue> 00035 #include <QWaitCondition> 00036 00037 #include "eventtype.h" 00038 #include "controlsocket.h" 00039 #include "torevents.h" 00040 00041 00042 class ControlConnection : public QThread 00043 { 00044 Q_OBJECT 00045 00046 public: 00047 /** Control connection status */ 00048 enum Status { 00049 Disconnected, /**< Control connection disconnected. */ 00050 Connecting, /**< Control connection attempt pending. */ 00051 Connected /**< Control connection established. */ 00052 }; 00053 00054 /** Default constructor. */ 00055 ControlConnection(TorEvents *events = 0); 00056 /** Destructor. */ 00057 ~ControlConnection(); 00058 00059 /** Connect to the specified Tor control interface. */ 00060 void connect(QHostAddress addr, quint16 port); 00061 /** Cancels a pending control connection to Tor. */ 00062 void cancelConnect(); 00063 /** Disconnect from Tor's control interface. */ 00064 void disconnect(); 00065 /** Returns the status of the control connection. */ 00066 Status status(); 00067 /** Sends a control command to Tor and waits for the reply. */ 00068 bool send(ControlCommand cmd, ControlReply &reply, QString *errmsg = 0); 00069 /** Sends a control command to Tor and does not wait for a reply. */ 00070 bool send(ControlCommand cmd, QString *errmsg = 0); 00071 00072 signals: 00073 /** Emitted when a control connection has been established. */ 00074 void connected(); 00075 /** Emitted when a control connection has been closed. */ 00076 void disconnected(); 00077 /** Emitted when a control connection fails. */ 00078 void connectFailed(QString errmsg); 00079 00080 protected: 00081 /** Catches events for the control socket. */ 00082 bool eventFilter(QObject *obj, QEvent *event); 00083 00084 private slots: 00085 /** Called when there is data on the control socket. */ 00086 void onReadyRead(); 00087 00088 private: 00089 /** Sets the control connection status. */ 00090 void setStatus(Status status); 00091 /** Connects to Tor's control interface. */ 00092 bool connect(); 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 00104 /** Private class used to wait for a response to a control command. */ 00105 class ReceiveWaiter { 00106 public: 00107 /** Default constructor. */ 00108 ReceiveWaiter() { _status = Waiting; } 00109 /** Waits for and gets the reply from a control command. */ 00110 bool getResult(ControlReply *reply, QString *errmsg = 0); 00111 /** Sets the result and reply from a control command. */ 00112 void setResult(bool success, ControlReply reply, 00113 QString errmsg = QString()); 00114 private: 00115 /** Status of the receive waiter. */ 00116 enum ReceiveStatus { Waiting, Failed, Success } _status; 00117 ControlReply _reply; /**< Reply to a previous command. */ 00118 QMutex _mutex; /**< Mutex around the wait condition. */ 00119 QWaitCondition _waitCond; /**< Waits for a control rpely. */ 00120 QString _errmsg; /**< Error message if the reply fails. */ 00121 }; 00122 QQueue<ReceiveWaiter *> _recvQueue; /**< Objects waiting for a reply. */ 00123 00124 /** Object used to wait for the result of a send operation. */ 00125 class SendWaiter { 00126 public: 00127 /** Default constructor. */ 00128 SendWaiter() { _status = Waiting; } 00129 /** Sets the result of the send operation. */ 00130 void setResult(bool success, QString errmsg = QString()); 00131 /** Waits for and gets the result of the send operation. */ 00132 bool getResult(QString *errmsg = 0); 00133 private: 00134 /** Status of the send waiter. */ 00135 enum SenderStatus { Waiting, Failed, Success } _status; 00136 QMutex _mutex; /**< Mutex around the wait condition. */ 00137 QWaitCondition _waitCond; /**< Waits for the send to complete. */ 00138 QString _errmsg; /**< Error message if the send fails. */ 00139 }; 00140 00141 /** Private event used to push a control command to the socket's thread */ 00142 class SendCommandEvent : public QEvent { 00143 public: 00144 /** Constructor. */ 00145 SendCommandEvent(ControlCommand cmd, SendWaiter *waiter = 0) 00146 : QEvent((QEvent::Type)CustomEventType::SendCommandEvent) 00147 { _cmd = cmd; _waiter = waiter; } 00148 /** Returns the control command to send to Tor. */ 00149 ControlCommand command() { return _cmd; } 00150 /** Returns a waiter (if any) for the result of this send. */ 00151 SendWaiter* waiter() { return _waiter; } 00152 private: 00153 ControlCommand _cmd; /**< Command to send to Tor. */ 00154 SendWaiter* _waiter; /**< Waiter for the result of this event. */ 00155 }; 00156 }; 00157 00158 #endif 00159