Show
Ignore:
Timestamp:
01/15/06 17:36:23 (3 years ago)
Author:
edmanm
Message:

Check in a bulk of the asynchronous event handling code. Some work remains.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/control/torcontrol.cpp

    r84 r90  
    2121 *  Boston, MA  02110-1301, USA. 
    2222 ****************************************************************/ 
    23                       
     23                    
    2424#include <QHostAddress> 
    2525 
     
    3030TorControl::TorControl() 
    3131{ 
     32  /* Construct the message pump and give it a control connection and TorEvents 
     33   * object, used to translate and dispatch event messages sent by Tor */ 
     34  _messages = new MessagePump(&_controlConn, &_events); 
     35 
     36  /* Plumb the signal relays between the TorEvents object and The Outside */ 
     37  QObject::connect(&_events, SIGNAL(bandwidth(quint64, quint64)), 
     38                   this, SLOT(onBandwidthUpdate(quint64, quit64)), 
     39                   Qt::DirectConnection); 
     40  QObject::connect(&_events, SIGNAL(log(TorEvents::LogSeverity, QString)), 
     41                   this, SLOT(onLogMessage(TorEvents::LogSeverity, QString)), 
     42                   Qt::DirectConnection); 
     43  QObject::connect(&_events, SIGNAL(circuit(quint64, TorEvents::CircuitStatus, 
     44                                            QString)), 
     45                   this, SLOT(onCircuitStatus(quint64, TorEvents::CircuitStatus, 
     46                                              QString)), 
     47                   Qt::DirectConnection); 
     48  QObject::connect(&_events, SIGNAL(stream(quint64, TorEvents::StreamStatus, 
     49                                           quint64, QString)), 
     50                   this, SLOT(onStreamStatus(quint64, TorEvents::StreamStatus, 
     51                                             quint64, QString)), 
     52                   Qt::DirectConnection); 
     53   
    3254  /* Plumb the process signals */ 
    3355  QObject::connect(&_torProcess, SIGNAL(started()), 
     
    4668TorControl::~TorControl() 
    4769{ 
     70  if (isConnected()) { 
     71    disconnect(); 
     72  } 
     73  if (isRunning()) { 
     74    stop(); 
     75  } 
     76  if (_messages) { 
     77    delete _messages; 
     78  } 
    4879} 
    4980 
     
    69100TorControl::stop(QString *errmsg) 
    70101{ 
     102  if (isConnected()) { 
     103    disconnect(); 
     104  } 
    71105  return _torProcess.stop(errmsg); 
    72106} 
     
    92126{ 
    93127  VidaliaSettings settings; 
    94   return _controlConn.connect(settings.getControlAddress(), 
    95                               settings.getControlPort(), errmsg); 
     128  if ( _controlConn.connect(settings.getControlAddress(), 
     129                            settings.getControlPort(), errmsg) 
     130     ) { 
     131    _messages->start(); 
     132    return true; 
     133  } 
     134  return false; 
    96135} 
    97136 
     
    108147TorControl::disconnect() 
    109148{ 
     149  _messages->stop(); 
     150  send(ControlCommand("QUIT"), 0); 
    110151  _controlConn.disconnect(); 
    111152} 
     
    123164{ 
    124165  return _controlConn.isValid(); 
     166} 
     167 
     168/** Sends a message to Tor and discards the response */ 
     169bool 
     170TorControl::send(ControlCommand cmd, QString *errmsg) 
     171{ 
     172  ControlReply reply; 
     173  return send(cmd, reply, errmsg); 
     174} 
     175 
     176/** Send a message to Tor and read the response */ 
     177bool 
     178TorControl::send(ControlCommand cmd, ControlReply &reply, QString *errmsg) 
     179{ 
     180  return _messages->send(cmd, reply, errmsg); 
    125181} 
    126182 
     
    137193  ControlReply reply; 
    138194 
    139   if (_controlConn.send(cmd, reply, errmsg)) { 
     195  if (send(cmd, reply, errmsg)) { 
    140196    ReplyLine line = reply.getLine(); 
    141197    if (line.getStatus() != "250") { 
     
    166222  
    167223  /* Ask Tor for the specified info values */ 
    168   if (_controlConn.send(cmd, reply, errmsg)) { 
     224  if (send(cmd, reply, errmsg)) { 
    169225   
    170226    /* Parse the response for the returned values */ 
     
    214270  /* Convert the signal to the correct string */ 
    215271  switch (sig) { 
    216     case Reload:   sigtype = "RELOAD"; break; 
    217     case Shutdown: sigtype = "SHUTDOWN"; break; 
    218     case Dump:     sigtype = "DUMP"; break; 
    219     case Debug:    sigtype = "DEBUG"; break; 
    220     case Halt:     sigtype = "HALT"; break; 
    221     default: return false; break; 
     272    case SignalReload:   sigtype = "RELOAD"; break; 
     273    case SignalShutdown: sigtype = "SHUTDOWN"; break; 
     274    case SignalDump:     sigtype = "DUMP"; break; 
     275    case SignalDebug:    sigtype = "DEBUG"; break; 
     276    case SignalHalt:     sigtype = "HALT"; break; 
     277    default: return false; 
    222278  } 
    223279   
    224280  /* Send and check the response */ 
    225   if (_controlConn.send(cmd, reply, errmsg)) { 
     281  if (!send(cmd, reply, errmsg)) { 
     282    return false; 
     283  } else { 
    226284    ReplyLine line = reply.getLine(); 
    227285    if (line.getStatus() != "250") { 
     
    246304} 
    247305 
     306/** Adds an event to the event list and registers it with Tor. If registration 
     307 * fails, then the event is NOT added to the event list. */ 
     308bool 
     309TorControl::addEvent(TorEvents::Event e, QString *errmsg) 
     310{ 
     311  QString event = TorEvents::toString(e); 
     312  _eventList << event; 
     313  if (!registerEvents(errmsg)) { 
     314    /* Registering the event failed, so remove it from the list */ 
     315    _eventList.removeAt(_eventList.indexOf(event)); 
     316    return false; 
     317  } 
     318  return true; 
     319} 
     320 
     321/** Removes an event from the event list and unregisters it from Tor. If 
     322 * unregistration fails, then the event is NOT removed from the event list. */ 
     323bool 
     324TorControl::removeEvent(TorEvents::Event e, QString *errmsg) 
     325{ 
     326  QString event = TorEvents::toString(e); 
     327  if (_eventList.contains(event)) { 
     328    _eventList.removeAt(_eventList.indexOf(event)); 
     329    if (!registerEvents(errmsg)) { 
     330      /* Unregistration failed, so leave it in the list */ 
     331      _eventList << event; 
     332      return false; 
     333    } 
     334  } 
     335  return true; 
     336} 
     337 
     338/** Register for the events currently in the event list */ 
     339bool 
     340TorControl::registerEvents(QString *errmsg) 
     341{ 
     342  ControlCommand cmd("SETEVENTS", _eventList.join(" "));  
     343  ControlReply reply; 
     344  if (!send(cmd, reply, errmsg)) { 
     345    return false; 
     346  } else { 
     347    ReplyLine line = reply.getLine(); 
     348    if (line.getStatus() != "250") { 
     349      if (errmsg) { 
     350        *errmsg = line.getMessage(); 
     351      } 
     352      return false; 
     353    } 
     354  } 
     355  return true; 
     356} 
     357 
     358/** 
     359 * The methods below relay the appropriate signals from the TorEvents object. 
     360 */ 
     361void 
     362TorControl::onBandwidthUpdate(quint64 bytesIn, quint64 bytesOut) 
     363{ 
     364  emit bandwidth(bytesIn, bytesOut); 
     365} 
     366void 
     367TorControl::onLogMessage(TorEvents::LogSeverity severity, QString msg) 
     368{ 
     369  emit log(severity, msg); 
     370} 
     371void 
     372TorControl::onCircuitStatus(quint64 circId,  
     373                            TorEvents::CircuitStatus status, QString path) 
     374{ 
     375  emit circuit(circId, status, path); 
     376} 
     377void 
     378TorControl::onStreamStatus(quint64 streamId, TorEvents::StreamStatus status, 
     379                           quint64 circId, QString target) 
     380{ 
     381  emit stream(streamId, status, circId, target); 
     382} 
     383