controlconnection.h

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

Generated on Wed Sep 5 15:49:27 2007 for Vidalia by  doxygen 1.5.3