00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <QMessageBox>
00018 #include <QHeaderView>
00019 #include <vidalia.h>
00020
00021 #include "netviewer.h"
00022
00023 #define IMG_MOVE ":/images/22x22/move-map.png"
00024 #define IMG_ZOOMIN ":/images/22x22/zoom-in.png"
00025 #define IMG_ZOOMOUT ":/images/22x22/zoom-out.png"
00026
00027
00028
00029
00030 #define MIN_RESOLVE_QUEUE_DELAY (10*1000)
00031
00032
00033 #define MAX_RESOLVE_QUEUE_DELAY (30*1000)
00034
00035
00036
00037
00038
00039 NetViewer::NetViewer(QWidget *parent)
00040 : VidaliaWindow("NetViewer", parent)
00041 {
00042
00043 ui.setupUi(this);
00044 #if defined(Q_WS_MAC)
00045 ui.actionHelp->setShortcut(QString("Ctrl+?"));
00046 #endif
00047
00048
00049 ui.actionClose->setShortcut(QString("Esc"));
00050 Vidalia::createShortcut("Ctrl+W", this, ui.actionClose, SLOT(trigger()));
00051
00052
00053 _torControl = Vidalia::torControl();
00054 _torControl->setEvent(TorEvents::NewDescriptor, this, true);
00055 _torControl->setEvent(TorEvents::CircuitStatus, this, true);
00056 _torControl->setEvent(TorEvents::StreamStatus, this, true);
00057 _torControl->setEvent(TorEvents::AddressMap, this, true);
00058
00059
00060 ui.treeRouterList->header()->
00061 resizeSection(RouterListWidget::StatusColumn, 25);
00062 ui.treeRouterList->header()->
00063 resizeSection(RouterListWidget::CountryColumn, 25);
00064 ui.treeCircuitList->header()->
00065 resizeSection(CircuitListWidget::ConnectionColumn, 235);
00066
00067
00068 _map = new TorMapWidget();
00069 ui.gridLayout->addWidget(_map);
00070
00071
00072 connect(ui.actionZoomIn, SIGNAL(triggered()), _map, SLOT(zoomIn()));
00073 connect(ui.actionZoomOut, SIGNAL(triggered()), _map, SLOT(zoomOut()));
00074 connect(ui.actionZoomToFit, SIGNAL(triggered()), _map, SLOT(zoomToFit()));
00075
00076
00077
00078
00079 _refreshTimer.setInterval(60*60*1000);
00080 connect(&_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
00081
00082
00083
00084
00085 _minResolveQueueTimer.setSingleShot(true);
00086 connect(&_minResolveQueueTimer, SIGNAL(timeout()), this, SLOT(resolve()));
00087 _maxResolveQueueTimer.setSingleShot(true);
00088 connect(&_maxResolveQueueTimer, SIGNAL(timeout()), this, SLOT(resolve()));
00089
00090
00091 connect(ui.actionHelp, SIGNAL(triggered()), this, SLOT(help()));
00092 connect(ui.actionRefresh, SIGNAL(triggered()), this, SLOT(refresh()));
00093 connect(ui.treeRouterList, SIGNAL(routerSelected(RouterDescriptor)),
00094 this, SLOT(routerSelected(RouterDescriptor)));
00095 connect(ui.treeRouterList, SIGNAL(zoomToRouter(QString)),
00096 _map, SLOT(zoomToRouter(QString)));
00097 connect(ui.treeCircuitList, SIGNAL(circuitSelected(Circuit)),
00098 this, SLOT(circuitSelected(Circuit)));
00099 connect(ui.treeCircuitList, SIGNAL(circuitRemoved(CircuitId)),
00100 _map, SLOT(removeCircuit(CircuitId)));
00101 connect(ui.treeCircuitList, SIGNAL(zoomToCircuit(CircuitId)),
00102 _map, SLOT(zoomToCircuit(CircuitId)));
00103 connect(ui.treeCircuitList, SIGNAL(closeCircuit(CircuitId)),
00104 _torControl, SLOT(closeCircuit(CircuitId)));
00105 connect(ui.treeCircuitList, SIGNAL(closeStream(StreamId)),
00106 _torControl, SLOT(closeStream(StreamId)));
00107
00108
00109 connect(_torControl, SIGNAL(authenticated()), this, SLOT(onAuthenticated()));
00110 connect(_torControl, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
00111
00112
00113 connect(&_geoip, SIGNAL(resolved(int, QList<GeoIp>)),
00114 this, SLOT(resolved(int, QList<GeoIp>)));
00115 }
00116
00117
00118
00119 void
00120 NetViewer::showWindow()
00121 {
00122 if (!_resolveQueue.isEmpty()) {
00123 _minResolveQueueTimer.start(MIN_RESOLVE_QUEUE_DELAY);
00124 _maxResolveQueueTimer.start(MAX_RESOLVE_QUEUE_DELAY);
00125 }
00126 VidaliaWindow::showWindow();
00127 }
00128
00129
00130 void
00131 NetViewer::onAuthenticated()
00132 {
00133 _geoip.setSocksHost(_torControl->getSocksAddress(),
00134 _torControl->getSocksPort());
00135 refresh();
00136 _refreshTimer.start();
00137 ui.actionRefresh->setEnabled(true);
00138 }
00139
00140
00141 void
00142 NetViewer::onDisconnected()
00143 {
00144 clear();
00145 _refreshTimer.stop();
00146 ui.actionRefresh->setEnabled(false);
00147 }
00148
00149
00150 void
00151 NetViewer::customEvent(QEvent *event)
00152 {
00153 int type = event->type();
00154
00155 if (type == CustomEventType::NewDescriptorEvent) {
00156
00157 NewDescriptorEvent *nde = (NewDescriptorEvent *)event;
00158 newDescriptors(nde->descriptorIDs());
00159 } else if (type == CustomEventType::CircuitEvent) {
00160
00161 CircuitEvent *ce = (CircuitEvent *)event;
00162 addCircuit(ce->circuit());
00163 } else if (type == CustomEventType::StreamEvent) {
00164
00165 StreamEvent *se = (StreamEvent *)event;
00166 addStream(se->stream());
00167 } else if (type == CustomEventType::AddressMapEvent) {
00168
00169
00170 AddressMapEvent *ae = (AddressMapEvent *)event;
00171 _addressMap.add(ae->to(), ae->from(), ae->expires());
00172 }
00173
00174
00175 _map->update();
00176 }
00177
00178
00179 void
00180 NetViewer::refresh()
00181 {
00182
00183 ui.actionRefresh->setEnabled(false);
00184
00185
00186 clear();
00187
00188
00189 loadNetworkStatus();
00190
00191 loadAddressMap();
00192
00193 loadConnections();
00194
00195
00196 ui.actionRefresh->setEnabled(true);
00197 }
00198
00199
00200 void
00201 NetViewer::clear()
00202 {
00203
00204 _resolveMap.clear();
00205 _resolveQueue.clear();
00206
00207 _map->clear();
00208 _map->update();
00209
00210 _addressMap.clear();
00211
00212 ui.treeRouterList->clearRouters();
00213 ui.treeCircuitList->clearCircuits();
00214 ui.textRouterInfo->clear();
00215 }
00216
00217
00218 void
00219 NetViewer::loadAddressMap()
00220 {
00221
00222
00223 _addressMap = _torControl->getAddressMap().reverse();
00224 }
00225
00226
00227 void
00228 NetViewer::loadConnections()
00229 {
00230
00231 CircuitList circuits = _torControl->getCircuits();
00232 foreach (Circuit circuit, circuits) {
00233 addCircuit(circuit);
00234 }
00235
00236 StreamList streams = _torControl->getStreams();
00237 foreach (Stream stream, streams) {
00238 addStream(stream);
00239 }
00240
00241
00242 _map->update();
00243 }
00244
00245
00246 void
00247 NetViewer::addCircuit(const Circuit &circuit)
00248 {
00249
00250 ui.treeCircuitList->addCircuit(circuit);
00251
00252 _map->addCircuit(circuit.id(), circuit.routerIDs());
00253 }
00254
00255
00256 void
00257 NetViewer::addStream(const Stream &stream)
00258 {
00259 QString target = stream.targetAddress();
00260 QHostAddress addr(target);
00261
00262
00263
00264 if (!addr.isNull() && _addressMap.isMapped(target)) {
00265
00266
00267 ui.treeCircuitList->addStream(
00268 Stream(stream.id(), stream.status(), stream.circuitId(),
00269 _addressMap.mappedTo(target), stream.targetPort()));
00270 } else {
00271 ui.treeCircuitList->addStream(stream);
00272 }
00273 }
00274
00275
00276 void
00277 NetViewer::help()
00278 {
00279 emit helpRequested("netview");
00280 }
00281
00282
00283
00284 void
00285 NetViewer::loadNetworkStatus()
00286 {
00287 NetworkStatus networkStatus = _torControl->getNetworkStatus();
00288 foreach (RouterStatus rs, networkStatus) {
00289 if (!rs.isRunning())
00290 continue;
00291
00292 RouterDescriptor rd = _torControl->getRouterDescriptor(rs.id());
00293 if (!rd.isEmpty())
00294 addRouter(rd);
00295 }
00296 }
00297
00298
00299
00300 void
00301 NetViewer::addRouter(const RouterDescriptor &rd)
00302 {
00303
00304 ui.treeRouterList->addRouter(rd);
00305
00306
00307
00308
00309 if (_torControl->getTorVersion() >= 0x020013) {
00310 DescriptorAnnotations annotations =
00311 _torControl->getDescriptorAnnotations(rd.id());
00312 if (!annotations.contains("purpose"))
00313 addToResolveQueue(rd.ip(), rd.id());
00314 } else {
00315 addToResolveQueue(rd.ip(), rd.id());
00316 }
00317 }
00318
00319
00320
00321
00322 void
00323 NetViewer::newDescriptors(const QStringList &ids)
00324 {
00325 foreach (QString id, ids) {
00326 RouterDescriptor rd = _torControl->getRouterDescriptor(id);
00327 if (!rd.isEmpty())
00328 addRouter(rd);
00329 }
00330 }
00331
00332
00333 void
00334 NetViewer::addToResolveQueue(const QHostAddress &ip, const QString &id)
00335 {
00336 QString ipstr = ip.toString();
00337 if (!_resolveMap.values(ipstr).contains(id)) {
00338
00339 _resolveMap.insertMulti(ipstr, id);
00340 }
00341
00342 if (!_resolveQueue.contains(ip) && !_geoip.resolveFromCache(ip)) {
00343
00344 _resolveQueue << ip;
00345
00346
00347
00348 _minResolveQueueTimer.start(MIN_RESOLVE_QUEUE_DELAY);
00349
00350
00351
00352
00353 if (_resolveQueue.size() == 1) {
00354 _maxResolveQueueTimer.start(MAX_RESOLVE_QUEUE_DELAY);
00355 }
00356 }
00357 }
00358
00359
00360
00361 void
00362 NetViewer::circuitSelected(const Circuit &circuit)
00363 {
00364
00365 ui.treeRouterList->deselectAll();
00366 ui.textRouterInfo->clear();
00367 _map->deselectAll();
00368
00369
00370 _map->selectCircuit(circuit.id());
00371
00372 QList<RouterDescriptor> routers;
00373
00374 foreach (QString id, circuit.routerIDs()) {
00375
00376 RouterListItem *item = ui.treeRouterList->findRouterById(id);
00377 if (item)
00378 routers.append(item->descriptor());
00379 }
00380
00381 ui.textRouterInfo->display(routers);
00382 }
00383
00384
00385 void
00386 NetViewer::routerSelected(const RouterDescriptor &router)
00387 {
00388 _map->deselectAll();
00389 ui.textRouterInfo->clear();
00390 ui.textRouterInfo->display(router);
00391 _map->selectRouter(router.id());
00392 }
00393
00394
00395 void
00396 NetViewer::resolve()
00397 {
00398 if (!_resolveQueue.isEmpty()) {
00399
00400
00401 if (isVisible() ||
00402 (_resolveQueue.size() >= ui.treeRouterList->topLevelItemCount()/4)) {
00403 vInfo("Sending GeoIP request for %1 IP addresses.")
00404 .arg(_resolveQueue.size());
00405
00406 _geoip.resolve(_resolveQueue);
00407 _resolveQueue.clear();
00408 }
00409 }
00410
00411
00412 _minResolveQueueTimer.stop();
00413 _maxResolveQueueTimer.stop();
00414 }
00415
00416
00417 void
00418 NetViewer::resolved(int id, const QList<GeoIp> &geoips)
00419 {
00420 Q_UNUSED(id);
00421 QString ip;
00422 RouterListItem *router;
00423
00424 foreach (GeoIp geoip, geoips) {
00425
00426 ip = geoip.ip().toString();
00427 QList<QString> ids = _resolveMap.values(ip);
00428 _resolveMap.remove(ip);
00429 if (geoip.isUnknown())
00430 continue;
00431
00432
00433
00434 foreach (QString id, ids) {
00435 router = ui.treeRouterList->findRouterById(id);
00436 if (router) {
00437
00438 router->setLocation(geoip);
00439
00440 _map->addRouter(router->id(), geoip.latitude(), geoip.longitude());
00441 }
00442 }
00443 }
00444
00445
00446 foreach (Circuit circuit, ui.treeCircuitList->circuits()) {
00447 _map->addCircuit(circuit.id(), circuit.routerIDs());
00448 }
00449
00450
00451 _map->update();
00452 }
00453