ControlConnection.h

Go to the documentation of this file.
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 

Generated on Mon Aug 30 19:14:02 2010 for Vidalia by  doxygen 1.5.9