| | 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 | |
| | 166 | } |
| | 167 | |
| | 168 | /** Sends a message to Tor and discards the response */ |
| | 169 | bool |
| | 170 | TorControl::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 */ |
| | 177 | bool |
| | 178 | TorControl::send(ControlCommand cmd, ControlReply &reply, QString *errmsg) |
| | 179 | { |
| | 180 | return _messages->send(cmd, reply, errmsg); |
| 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; |
| | 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. */ |
| | 308 | bool |
| | 309 | TorControl::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. */ |
| | 323 | bool |
| | 324 | TorControl::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 */ |
| | 339 | bool |
| | 340 | TorControl::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 | */ |
| | 361 | void |
| | 362 | TorControl::onBandwidthUpdate(quint64 bytesIn, quint64 bytesOut) |
| | 363 | { |
| | 364 | emit bandwidth(bytesIn, bytesOut); |
| | 365 | } |
| | 366 | void |
| | 367 | TorControl::onLogMessage(TorEvents::LogSeverity severity, QString msg) |
| | 368 | { |
| | 369 | emit log(severity, msg); |
| | 370 | } |
| | 371 | void |
| | 372 | TorControl::onCircuitStatus(quint64 circId, |
| | 373 | TorEvents::CircuitStatus status, QString path) |
| | 374 | { |
| | 375 | emit circuit(circId, status, path); |
| | 376 | } |
| | 377 | void |
| | 378 | TorControl::onStreamStatus(quint64 streamId, TorEvents::StreamStatus status, |
| | 379 | quint64 circId, QString target) |
| | 380 | { |
| | 381 | emit stream(streamId, status, circId, target); |
| | 382 | } |
| | 383 | |