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