Vidalia 0.3.1
ServerPage.cpp
Go to the documentation of this file.
1/*
2** This file is part of Vidalia, and is subject to the license terms in the
3** LICENSE file, found in the top level directory of this distribution. If you
4** did not receive the LICENSE file with this file, you may obtain it from the
5** Vidalia source package distributed by the Vidalia Project at
6** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7** including this file, may be copied, modified, propagated, or distributed
8** except according to the terms described in the LICENSE file.
9*/
10
11/*
12** \file ServerPage.cpp
13** \brief Tor server configuration options
14*/
15
16#include "config.h"
17#include "ServerPage.h"
18#include "Vidalia.h"
19#include "VMessageBox.h"
20#include "ConfigDialog.h"
21#include "IpValidator.h"
22#include "PortValidator.h"
23#include "DomainValidator.h"
24#include "NicknameValidator.h"
25#include "BridgeUsageDialog.h"
26
27#include "html.h"
28#include "stringutil.h"
29
30#if defined(USE_MINIUPNPC)
31#include "UPNPTestDialog.h"
32#endif
33
34
35#include <QClipboard>
36#include <QMessageBox>
37
38/* These are completely made up values (in bytes/sec). */
39#define CABLE256_AVG_RATE (32*1024)
40#define CABLE256_MAX_RATE (64*1024)
41#define CABLE512_AVG_RATE (64*1024)
42#define CABLE512_MAX_RATE (128*1024)
43#define CABLE768_AVG_RATE (96*1024)
44#define CABLE768_MAX_RATE (192*1024)
45#define T1_AVG_RATE (192*1024)
46#define T1_MAX_RATE (384*1024)
47#define HIGHBW_AVG_RATE (5120*1024)
48#define HIGHBW_MAX_RATE (10240*1024)
49/** Minimum allowed bandwidth rate (20KB) */
50#define MIN_BANDWIDTH_RATE 20
51/** Maximum bandwidth rate. This is limited to 2147483646 bytes,
52 * or 2097151 kilobytes. (2147483646/1024) */
53#define MAX_BANDWIDTH_RATE 2097151
54
55/** Ports represented by the "Websites" checkbox. (80) */
56#define PORTS_HTTP (QStringList() << "80")
57/** Ports represented by the "Secure Websites" checkbox. (443) */
58#define PORTS_HTTPS (QStringList() << "443")
59/** Ports represented by the "Retrieve Mail" checkbox. (110,143,993,995) */
60#define PORTS_MAIL (QStringList() << "110" << "143" << "993" << "995")
61/** Ports represented by the "Instant Messaging" checkbox.
62 * (703,1863,5050,5190,5222,8300,8888) */
63#define PORTS_IM (QStringList() << "706" << "1863" << "5050" << "5190" \
64 << "5222" << "5223" << "8300" << "8888")
65/** Ports represented by the "Internet Relay Chat" checkbox.
66 * (6660-6669,6697,7000-7001) */
67#define PORTS_IRC (QStringList() << "6660-6669" << "6697" << "7000-7001")
68
69
70/** Constructor */
71ServerPage::ServerPage(QWidget *parent)
72: ConfigPage(parent, "Server")
73{
74 /* Invoke the Qt Designer generated object setup routine */
75 ui.setupUi(this);
76
77 /* Create ServerSettings object */
79
80 /* Bind events to actions */
81 connect(ui.btnRateHelp, SIGNAL(clicked()), this, SLOT(bandwidthHelp()));
82 connect(ui.btnExitHelp, SIGNAL(clicked()), this, SLOT(exitPolicyHelp()));
83 connect(ui.btnUpnpHelp, SIGNAL(clicked()), this, SLOT(upnpHelp()));
84 connect(ui.cmboRate, SIGNAL(currentIndexChanged(int)),
85 this, SLOT(rateChanged(int)));
86 connect(ui.lineAvgRateLimit, SIGNAL(editingFinished()),
87 this, SLOT(customRateChanged()));
88 connect(ui.lineMaxRateLimit, SIGNAL(editingFinished()),
89 this, SLOT(customRateChanged()));
90 connect(ui.rdoClientMode, SIGNAL(toggled(bool)),
91 this, SLOT(serverModeChanged(bool)));
92 connect(ui.rdoNonExitMode, SIGNAL(toggled(bool)),
93 this, SLOT(serverModeChanged(bool)));
94 connect(ui.rdoServerMode, SIGNAL(toggled(bool)),
95 this, SLOT(serverModeChanged(bool)));
96 connect(ui.rdoBridgeMode, SIGNAL(toggled(bool)),
97 this, SLOT(serverModeChanged(bool)));
98 connect(Vidalia::torControl(), SIGNAL(authenticated()),
99 this, SLOT(onAuthenticated()));
100 connect(Vidalia::torControl(), SIGNAL(disconnected()),
101 this, SLOT(onDisconnected()));
102 connect(ui.btnCopyBridgeIdentity, SIGNAL(clicked()),
103 this, SLOT(copyBridgeIdentity()));
104 connect(ui.lblBridgeUsage, SIGNAL(linkActivated(QString)),
105 this, SLOT(linkActivated(QString)));
106 connect(ui.lblWhatsThis, SIGNAL(linkActivated(QString)),
107 this, SLOT(linkActivated(QString)));
108
109 /* Set validators for address, mask and various port number fields */
110 ui.lineServerNickname->setValidator(new NicknameValidator(this));
111 ui.lineServerPort->setValidator(new QIntValidator(1, 65535, this));
112 ui.lineDirPort->setValidator(new QIntValidator(1, 65535, this));
113 ui.lineAvgRateLimit->setValidator(
114 new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this));
115 ui.lineMaxRateLimit->setValidator(
116 new QIntValidator(MIN_BANDWIDTH_RATE, MAX_BANDWIDTH_RATE, this));
117
118#if defined(USE_MINIUPNPC)
119 connect(ui.btnTestUpnp, SIGNAL(clicked()), this, SLOT(testUpnp()));
120#else
121 ui.chkEnableUpnp->setVisible(false);
122 ui.btnTestUpnp->setVisible(false);
123#endif
124
125 _tmpDirPort = "9030";
126 _tmpMirror = true;
127}
128
129/** Destructor */
131{
132 delete _settings;
133}
134
135/** Called when the user changes the UI translation. */
136void
138{
139 ui.retranslateUi(this);
140}
141
142/** Called when Vidalia has authenticated to Tor. If the user's Tor is not
143 * recent enough, this disables the bridge server option and displays a
144 * warning if the user had previously configured Tor as a bridge. */
145void
147{
148 quint32 torVersion = Vidalia::torControl()->getTorVersion();
149 if (torVersion < 0x020008) {
150 ui.rdoBridgeMode->setEnabled(false);
151 if (ui.rdoBridgeMode->isChecked()) {
152 int ret = VMessageBox::warning(this,
153 tr("Bridge Support Unavailable"),
154 p(tr("You have configured Tor to act as a bridge relay "
155 "for censored users, but your version of Tor does not "
156 "support bridges.")) +
157 p(tr("Please upgrade your Tor software or configure Tor to "
158 "act as a normal Tor relay.")),
159 VMessageBox::ShowSettings|VMessageBox::Default,
161 if (ret == VMessageBox::ShowSettings) {
162 ConfigDialog *dialog = dynamic_cast<ConfigDialog *>(window());
163 if (dialog)
165 }
166 }
167 }
168}
169
170/** Called when Vidalia disconnects from Tor. This method reenables the bridge
171 * server option. */
172void
174{
175 ui.rdoBridgeMode->setEnabled(true);
176}
177
178/** Copies the user's bridge relay identity to the clipboard. */
179void
181{
182 QString bridge = ui.lblBridgeIdentity->text();
183 if (!bridge.isEmpty())
184 vApp->clipboard()->setText(bridge);
185}
186
187/** Loads the user's bridge relay identity into the appropriate widgets. If
188 * the user's bridge is not running, then "Not Running" will be displayed.
189 * Otherwise, either the bridge's "address:port", "fingerprint", or
190 * "address:port fingerprint" will be displayed, depending on whether our
191 * GETCONF and GETINFO commands are successful. */
192void
194{
196 QString bridge, address, orPort, fingerprint;
197
198 if (tc->isConnected()) {
199 tc->getInfo("address", address);
200 tc->getInfo("fingerprint", fingerprint);
201 tc->getConf("ORPort", orPort);
202
203 if (!address.isEmpty() && !orPort.isEmpty() && orPort != "0")
204 bridge = address + ":" + orPort + " ";
205 if (!fingerprint.isEmpty())
206 bridge += fingerprint;
207 bridge = bridge.trimmed();
208 }
209
210 ui.lblBridgeIdentity->setText(bridge.isEmpty()
211 ? tr("Your bridge relay is not running.")
212 : bridge);
213 ui.lblYourBridgeRelayIs->setEnabled(!bridge.isEmpty());
214 ui.lblBridgeIdentity->setEnabled(!bridge.isEmpty());
215 ui.btnCopyBridgeIdentity->setEnabled(!bridge.isEmpty());
216}
217
218/** Called when the user toggles any one of the server mode radio buttons
219 * and hides or displays the server configuration tabs appropriately. */
220void
222{
223 Q_UNUSED(enabled);
224 bool bridgeEnabled = ui.rdoBridgeMode->isChecked();
225 bool relayEnabled = ui.rdoServerMode->isChecked() ||
226 ui.rdoNonExitMode->isChecked();
227
228 /* Show the tab menu only if the user is running a normal relay or a bridge
229 * relay. */
230 ui.tabsMenu->setVisible(relayEnabled || bridgeEnabled);
231
232 /* Display the widgets that show the user their bridge identity if bridge
233 * relay mode is selected. */
234 ui.lblYourBridgeRelayIs->setVisible(bridgeEnabled);
235 ui.lblBridgeIdentity->setVisible(bridgeEnabled);
236 ui.btnCopyBridgeIdentity->setVisible(bridgeEnabled);
237 ui.chkPublishBridgeAddress->setVisible(bridgeEnabled);
238 ui.lblBridgeUsage->setVisible(bridgeEnabled
240
241 if(bridgeEnabled) {
242 if(ui.lineDirPort->text().length() != 0) {
243 _tmpDirPort = ui.lineDirPort->text();
244 _tmpMirror = ui.chkMirrorDirectory->isChecked();
245 }
246 ui.lineDirPort->clear();
247 ui.chkMirrorDirectory->setChecked(false);
248 } else {
249 ui.lineDirPort->setText(_tmpDirPort);
250 ui.chkMirrorDirectory->setChecked(_tmpMirror);
251 }
252
253 ui.lineDirPort->setEnabled(!bridgeEnabled);
254 ui.lblDirPort->setEnabled(!bridgeEnabled);
255
256 ui.chkMirrorDirectory->setEnabled(!bridgeEnabled);
257
258 /* Disable the Exit Policies tab when bridge or non-exit relay mode is
259 * selected */
260 ui.tabsMenu->setTabEnabled(2, !bridgeEnabled and !ui.rdoNonExitMode->isChecked());
261
262 if(ui.chkMirrorDirectory->isChecked()) {
263 ui.lblDirPort->setEnabled(!bridgeEnabled);
264 ui.lineDirPort->setEnabled(!bridgeEnabled);
265 }
266}
267
268/** Returns true if the user has changed their server settings since the
269 * last time they were applied to Tor. */
270bool
272{
274}
275
276/** Applies the server configuration settings to Tor. Returns true if the
277 * settings were applied successfully. Otherwise, <b>errmsg</b> is
278 * set and false is returned. */
279bool
280ServerPage::apply(QString &errmsg)
281{
282 return _settings->apply(&errmsg);
283}
284
285/** Returns true if the user has changed their server settings since the
286 * last time they were applied to Tor. */
287void
289{
290 _settings->revert();
291}
292
293/** Saves changes made to settings on the Server settings page. */
294bool
295ServerPage::save(QString &errmsg)
296{
297 /* Force the bandwidth rate limits to validate */
299
300 if (ui.rdoServerMode->isChecked() ||
301 ui.rdoNonExitMode->isChecked() ||
302 ui.rdoBridgeMode->isChecked()) {
303 /* A server must have an ORPort and a nickname */
304 if (ui.lineServerPort->text().isEmpty() ||
305 ui.lineServerNickname->text().isEmpty()) {
306 errmsg = tr("You must specify at least a relay nickname and port.");
307 return false;
308 }
309 /* If the bandwidth rates aren't set, use some defaults before saving */
310 if (ui.lineAvgRateLimit->text().isEmpty()) {
311 ui.lineAvgRateLimit->setText(QString::number(2097152/1024) /* 2MB */);
312 }
313 if (ui.lineMaxRateLimit->text().isEmpty()) {
314 ui.lineMaxRateLimit->setText(QString::number(5242880/1024) /* 5MB */);
315 }
316 }
317
318 /* "Server" is enabled whether we're a bridge or normal relay. "Bridge" is
319 * only enabled if we're a bridge (obviously). */
320 _settings->setServerEnabled(ui.rdoServerMode->isChecked()
321 || ui.rdoNonExitMode->isChecked()
322 || ui.rdoBridgeMode->isChecked());
323 _settings->setNonExitEnabled(ui.rdoNonExitMode->isChecked());
324 _settings->setBridgeEnabled(ui.rdoBridgeMode->isChecked());
325 if (ui.rdoBridgeMode->isChecked())
326 _settings->setPublishServerDescriptor(ui.chkPublishBridgeAddress->isChecked());
327
328 /* Save the rest of the server settings. */
329 _settings->setNickname(ui.lineServerNickname->text());
330 _settings->setORPort(ui.lineServerPort->text().toUInt());
331 if (!ui.rdoBridgeMode->isChecked()) {
332 _settings->setDirPort(ui.lineDirPort->text().toUInt());
333 _settings->setDirectoryMirror(ui.chkMirrorDirectory->isChecked());
334 } else {
336 }
337 _settings->setContactInfo(ui.lineServerContact->text());
340
341#if defined(USE_MINIUPNPC)
342 _settings->setUpnpEnabled(ui.chkEnableUpnp->isChecked());
343#endif
344
345 return true;
346}
347
348/** Loads previously saved settings */
349void
351{
353 ui.rdoBridgeMode->setChecked(true);
354 else if (_settings->isNonExitEnabled()) {
355 if(_settings->getExitPolicy().toString() != "reject *:*")
356 ui.rdoServerMode->setChecked(true);
357 else
358 ui.rdoNonExitMode->setChecked(true);
359 } else if (_settings->isServerEnabled()) {
360 if(_settings->getExitPolicy().toString() == "reject *:*")
361 ui.rdoNonExitMode->setChecked(true);
362 else
363 ui.rdoServerMode->setChecked(true);
364 } else
365 ui.rdoClientMode->setChecked(true);
366
367 ui.lineServerNickname->setText(_settings->getNickname());
368 ui.lineServerPort->setText(QString::number(_settings->getORPort()));
369 ui.lineDirPort->setText(QString::number(_settings->getDirPort()));
370 ui.lineServerContact->setText(_settings->getContactInfo());
371 ui.chkMirrorDirectory->setChecked(_settings->isDirectoryMirror());
372 ui.lblBridgeUsage->setVisible(_settings->isBridgeEnabled()
374 ui.chkPublishBridgeAddress->setChecked(_settings->publishServerDescriptor());
375
379
380#if defined(USE_MINIUPNPC)
381 ui.chkEnableUpnp->setChecked(_settings->isUpnpEnabled());
382#endif
383}
384
385/** Shows exit policy related help information */
386void
388{
389 emit helpRequested("server.exitpolicy");
390}
391
392/** Shows the bandwidth rate limiting help information */
393void
395{
396 emit helpRequested("server.bandwidth");
397}
398
399/** Loads the server's bandwidth average and burst limits. */
400void
402{
405
406 if (avgRate == CABLE256_AVG_RATE &&
407 maxRate == CABLE256_MAX_RATE) {
408 /* Cable/DSL 256 Kbps */
409 ui.cmboRate->setCurrentIndex(CableDsl256);
410 } else if (avgRate == CABLE512_AVG_RATE &&
411 maxRate == CABLE512_MAX_RATE) {
412 /* Cable/DSL 512 Kbps */
413 ui.cmboRate->setCurrentIndex(CableDsl512);
414 } else if (avgRate == CABLE768_AVG_RATE &&
415 maxRate == CABLE768_MAX_RATE) {
416 /* Cable/DSL 768 Kbps */
417 ui.cmboRate->setCurrentIndex(CableDsl768);
418 } else if (avgRate == T1_AVG_RATE &&
419 maxRate == T1_MAX_RATE) {
420 /* T1/Cable/DSL 1.5 Mbps */
421 ui.cmboRate->setCurrentIndex(T1CableDsl1500);
422 } else if (avgRate == HIGHBW_AVG_RATE &&
423 maxRate == HIGHBW_MAX_RATE) {
424 /* > 1.5 Mbps */
425 ui.cmboRate->setCurrentIndex(GreaterThan1500);
426 } else {
427 /* Custom bandwidth limits */
428 ui.cmboRate->setCurrentIndex(CustomBwLimits);
429 }
430 /* Fill in the custom bandwidth limit boxes */
431 ui.lineAvgRateLimit->setText(QString::number(avgRate/1024));
432 ui.lineMaxRateLimit->setText(QString::number(maxRate/1024));
433}
434
435/** Saves the server's bandwidth average and burst limits. */
436void
438{
439 quint32 avgRate, maxRate;
440
441 switch (ui.cmboRate->currentIndex()) {
442 case CableDsl256: /* Cable/DSL 256 Kbps */
443 avgRate = CABLE256_AVG_RATE;
444 maxRate = CABLE256_MAX_RATE;
445 break;
446 case CableDsl512: /* Cable/DSL 512 Kbps */
447 avgRate = CABLE512_AVG_RATE;
448 maxRate = CABLE512_MAX_RATE;
449 break;
450 case CableDsl768: /* Cable/DSL 768 Kbps */
451 avgRate = CABLE768_AVG_RATE;
452 maxRate = CABLE768_MAX_RATE;
453 break;
454 case T1CableDsl1500: /* T1/Cable/DSL 1.5 Mbps */
455 avgRate = T1_AVG_RATE;
456 maxRate = T1_MAX_RATE;
457 break;
458 case GreaterThan1500: /* > 1.5 Mbps */
459 avgRate = HIGHBW_AVG_RATE;
460 maxRate = HIGHBW_MAX_RATE;
461 break;
462 default: /* Custom bandwidth limits */
463 avgRate = (quint32)(ui.lineAvgRateLimit->text().toUInt()*1024);
464 maxRate = (quint32)(ui.lineMaxRateLimit->text().toUInt()*1024);
465 break;
466 }
469}
470
471/** */
472void
474{
475 ExitPolicy exitPolicy = _settings->getExitPolicy();
476
477 if (exitPolicy.contains(Policy(Policy::RejectAll))) {
478 /* If the policy ends with reject *:*, check if the policy explicitly
479 * accepts these ports */
480 ui.chkWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTP));
481 ui.chkSecWebsites->setChecked(exitPolicy.acceptsPorts(PORTS_HTTPS));
482 ui.chkMail->setChecked(exitPolicy.acceptsPorts(PORTS_MAIL));
483 ui.chkIRC->setChecked(exitPolicy.acceptsPorts(PORTS_IRC));
484 ui.chkIM->setChecked(exitPolicy.acceptsPorts(PORTS_IM));
485 ui.chkMisc->setChecked(false);
486 } else {
487 /* If the exit policy ends with accept *:*, check if the policy explicitly
488 * rejects these ports */
489 ui.chkWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTP));
490 ui.chkSecWebsites->setChecked(!exitPolicy.rejectsPorts(PORTS_HTTPS));
491 ui.chkMail->setChecked(!exitPolicy.rejectsPorts(PORTS_MAIL));
492 ui.chkIRC->setChecked(!exitPolicy.rejectsPorts(PORTS_IRC));
493 ui.chkIM->setChecked(!exitPolicy.rejectsPorts(PORTS_IM));
494 ui.chkMisc->setChecked(true);
495 }
496}
497
498/** */
499void
501{
502 ExitPolicy *exitPolicy;
503 if(ui.rdoNonExitMode->isChecked()) {
504 exitPolicy = new ExitPolicy(ExitPolicy::Middleman);
505 } else {
506 exitPolicy = new ExitPolicy();
507 bool rejectUnchecked = ui.chkMisc->isChecked();
508
509 /* If misc is checked, then reject unchecked items and leave the default exit
510 * policy alone. Else, accept only checked items and end with reject *:*,
511 * replacing the default exit policy. */
512 if (ui.chkWebsites->isChecked() && !rejectUnchecked) {
513 exitPolicy->addAcceptedPorts(PORTS_HTTP);
514 } else if (!ui.chkWebsites->isChecked() && rejectUnchecked) {
515 exitPolicy->addRejectedPorts(PORTS_HTTP);
516 }
517 if (ui.chkSecWebsites->isChecked() && !rejectUnchecked) {
518 exitPolicy->addAcceptedPorts(PORTS_HTTPS);
519 } else if (!ui.chkSecWebsites->isChecked() && rejectUnchecked) {
520 exitPolicy->addRejectedPorts(PORTS_HTTPS);
521 }
522 if (ui.chkMail->isChecked() && !rejectUnchecked) {
523 exitPolicy->addAcceptedPorts(PORTS_MAIL);
524 } else if (!ui.chkMail->isChecked() && rejectUnchecked) {
525 exitPolicy->addRejectedPorts(PORTS_MAIL);
526 }
527 if (ui.chkIRC->isChecked() && !rejectUnchecked) {
528 exitPolicy->addAcceptedPorts(PORTS_IRC);
529 } else if (!ui.chkIRC->isChecked() && rejectUnchecked) {
530 exitPolicy->addRejectedPorts(PORTS_IRC);
531 }
532 if (ui.chkIM->isChecked() && !rejectUnchecked) {
533 exitPolicy->addAcceptedPorts(PORTS_IM);
534 } else if (!ui.chkIM->isChecked() && rejectUnchecked) {
535 exitPolicy->addRejectedPorts(PORTS_IM);
536 }
537 if (!ui.chkMisc->isChecked()) {
538 exitPolicy->addPolicy(Policy(Policy::RejectAll));
539 }
540 }
541 _settings->setExitPolicy(*exitPolicy);
542}
543
544/** Called when the user selects a new value from the rate combo box. */
545void
547{
548 /* If the "Custom" option is selected, show the custom bandwidth
549 * limits form. */
550 ui.frmCustomRate->setVisible(index == CustomBwLimits);
551}
552
553/** Called when the user edits the long-term average or maximum bandwidth limit.
554 * This ensures that the average bandwidth rate is greater than MIN_RATE
555 * (20KB/s) and that the max rate is greater than the average rate. */
556void
558{
559 /* Make sure the average rate isn't too low or too high */
560 quint32 avgRate = (quint32)ui.lineAvgRateLimit->text().toUInt();
561 if (avgRate < MIN_BANDWIDTH_RATE) {
562 ui.lineAvgRateLimit->setText(QString::number(MIN_BANDWIDTH_RATE));
563 }
564 if (avgRate > MAX_BANDWIDTH_RATE) {
565 ui.lineAvgRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE));
566 }
567 /* Ensure the max burst rate is greater than the average rate but less than
568 * the maximum allowed rate. */
569 quint32 burstRate = (quint32)ui.lineMaxRateLimit->text().toUInt();
570 if (avgRate > burstRate) {
571 ui.lineMaxRateLimit->setText(QString::number(avgRate));
572 }
573 if (burstRate > MAX_BANDWIDTH_RATE) {
574 ui.lineMaxRateLimit->setText(QString::number(MAX_BANDWIDTH_RATE));
575 }
576}
577
578/** Tests automatic port forwarding using UPnP. */
579void
581{
582#if defined(USE_MINIUPNPC)
583 UPNPTestDialog dlg(ui.lineServerPort->text().toUInt(),
584 ui.lineDirPort->text().toUInt(), this);
585
586 connect(&dlg, SIGNAL(help()), this, SLOT(upnpHelp()));
587
588 dlg.exec();
589#endif
590}
591
592/** Called when the user clicks the UPnP test dialog's help button. */
593void
595{
596 emit helpRequested("server.upnp");
597}
598
599/** Called when the user clicks on a QLabel containing a hyperlink. */
600void
601ServerPage::linkActivated(const QString &url)
602{
603 if (!url.compare("#bridgeUsage"))
605 else if(!url.compare("#bridgeHelp"))
606 emit helpRequested("bridges.about");
607}
608
609/** Retrieves bridge usage history from Tor, parses and validates it, and
610 * then displays it in a new dialog. */
611void
613{
614 QString info;
615 QMessageBox dlg(this);
616
617 info = Vidalia::torControl()->getInfo("status/clients-seen").toString();
618 if (info.isEmpty()) {
619 goto none;
620 } else {
621 QDateTime timeStarted;
622 QHash<QString,int> countrySummary;
623 QHash<QString,QString> keyvals;
624 BridgeUsageDialog dlg(this);
625 bool ok;
626
627 keyvals = string_parse_keyvals(info, &ok);
628 if (!ok || !keyvals.contains("TimeStarted")
629 || !keyvals.contains("CountrySummary"))
630 goto err;
631
632 timeStarted = QDateTime::fromString(keyvals.value("TimeStarted"),
633 "yyyy-MM-dd HH:mm:ss");
634 if (!timeStarted.isValid())
635 goto err;
636
637 // Default is LocalTime, force UTC
638 timeStarted.setTimeSpec(Qt::UTC);
639
640 QStringList summary = keyvals.value("CountrySummary")
641 .split(",", QString::SkipEmptyParts);
642 if (summary.isEmpty()) {
643 goto none;
644 } else {
645 foreach (QString pair, summary) {
646 QStringList parts = pair.split("=");
647 if (parts.size() != 2)
648 goto err;
649
650 countrySummary.insert(parts.at(0).toUpper(), parts.at(1).toInt(&ok));
651 if (!ok)
652 goto err;
653 }
654
655 dlg.update(timeStarted, countrySummary);
656 dlg.exec();
657 }
658 }
659 return;
660
661none:
662 dlg.setIcon(QMessageBox::Information);
663 dlg.setWindowTitle(tr("No Recent Usage"));
664 dlg.setText(tr("No clients have used your relay recently."));
665 dlg.setInformativeText(tr("Leave your relay running so clients have "
666 "a better chance of finding and using it."));
667 dlg.setStandardButtons(QMessageBox::Ok);
668 dlg.exec();
669 return;
670
671err:
672 dlg.setIcon(QMessageBox::Warning);
673 dlg.setWindowTitle(tr("Bridge History"));
674 dlg.setText(tr("Vidalia was unable to retrieve your bridge's usage "
675 "history."));
676 dlg.setInformativeText(tr("Tor returned an improperly formatted "
677 "response when Vidalia requested your "
678 "bridge's usage history."));
679 dlg.setDetailedText(tr("The returned response was: %1").arg(info));
680 dlg.setStandardButtons(QMessageBox::Ok);
681 dlg.exec();
682}
683
#define CABLE256_AVG_RATE
Definition: ServerPage.cpp:39
#define T1_AVG_RATE
Definition: ServerPage.cpp:45
#define PORTS_MAIL
Definition: ServerPage.cpp:60
#define T1_MAX_RATE
Definition: ServerPage.cpp:46
#define PORTS_IRC
Definition: ServerPage.cpp:67
#define CABLE512_AVG_RATE
Definition: ServerPage.cpp:41
#define PORTS_IM
Definition: ServerPage.cpp:63
#define PORTS_HTTP
Definition: ServerPage.cpp:56
#define HIGHBW_AVG_RATE
Definition: ServerPage.cpp:47
#define MAX_BANDWIDTH_RATE
Definition: ServerPage.cpp:53
#define MIN_BANDWIDTH_RATE
Definition: ServerPage.cpp:50
#define CABLE768_AVG_RATE
Definition: ServerPage.cpp:43
#define CABLE256_MAX_RATE
Definition: ServerPage.cpp:40
#define PORTS_HTTPS
Definition: ServerPage.cpp:58
#define CABLE512_MAX_RATE
Definition: ServerPage.cpp:42
#define CABLE768_MAX_RATE
Definition: ServerPage.cpp:44
#define HIGHBW_MAX_RATE
Definition: ServerPage.cpp:48
stop errmsg connect(const QHostAddress &address, quint16 port)
stop errmsg isConnected()
#define vApp
Definition: Vidalia.h:37
virtual bool changedSinceLastApply() const
void update(const QDateTime &timeStarted, const QHash< QString, int > &countrySummary)
void showWindow(Page page=General)
void helpRequested(const QString &topic)
bool contains(Policy policy)
Definition: ExitPolicy.cpp:130
void addRejectedPorts(QStringList portList)
Definition: ExitPolicy.cpp:107
void addPolicy(Policy policy)
Definition: ExitPolicy.cpp:61
bool rejectsPorts(QStringList portList)
Definition: ExitPolicy.cpp:118
bool acceptsPorts(QStringList portList)
Definition: ExitPolicy.cpp:94
QString toString()
Definition: ExitPolicy.cpp:156
void addAcceptedPorts(QStringList portList)
Definition: ExitPolicy.cpp:83
Definition: Policy.h:25
@ RejectAll
Definition: Policy.h:37
void loadBandwidthLimits()
Definition: ServerPage.cpp:401
bool _tmpMirror
Definition: ServerPage.h:128
bool changedSinceLastApply()
Definition: ServerPage.cpp:271
void displayBridgeUsage()
Definition: ServerPage.cpp:612
void loadExitPolicies()
Definition: ServerPage.cpp:473
bool apply(QString &errmsg)
Definition: ServerPage.cpp:280
void upnpHelp()
Definition: ServerPage.cpp:594
ServerSettings * _settings
Definition: ServerPage.h:119
virtual void retranslateUi()
Definition: ServerPage.cpp:137
void onDisconnected()
Definition: ServerPage.cpp:173
Ui::ServerPage ui
Definition: ServerPage.h:122
void load()
Definition: ServerPage.cpp:350
void customRateChanged()
Definition: ServerPage.cpp:557
void loadBridgeIdentity()
Definition: ServerPage.cpp:193
void copyBridgeIdentity()
Definition: ServerPage.cpp:180
@ CustomBwLimits
Definition: ServerPage.h:93
@ GreaterThan1500
Definition: ServerPage.h:92
@ T1CableDsl1500
Definition: ServerPage.h:91
void exitPolicyHelp()
Definition: ServerPage.cpp:387
void linkActivated(const QString &url)
Definition: ServerPage.cpp:601
void bandwidthHelp()
Definition: ServerPage.cpp:394
void rateChanged(int rate)
Definition: ServerPage.cpp:546
void onAuthenticated()
Definition: ServerPage.cpp:146
void serverModeChanged(bool enabled)
Definition: ServerPage.cpp:221
QString _tmpDirPort
Definition: ServerPage.h:127
ServerPage(QWidget *parent=0)
Definition: ServerPage.cpp:71
void saveExitPolicies()
Definition: ServerPage.cpp:500
void saveBandwidthLimits()
Definition: ServerPage.cpp:437
bool save(QString &errmsg)
Definition: ServerPage.cpp:295
void testUpnp()
Definition: ServerPage.cpp:580
void revert()
Definition: ServerPage.cpp:288
QString getContactInfo()
bool apply(QString *errmsg=0)
void setBridgeEnabled(bool enable)
void setORPort(quint16 orPort)
void setNonExitEnabled(bool enable)
quint16 getDirPort()
void setPublishServerDescriptor(bool publish)
quint32 getBandwidthBurstRate()
bool publishServerDescriptor() const
void setUpnpEnabled(bool enabled)
quint32 getBandwidthAvgRate()
void setNickname(QString nickname)
QString getNickname()
void setDirectoryMirror(bool mirror)
ExitPolicy getExitPolicy()
void setBandwidthBurstRate(quint32 rate)
void setServerEnabled(bool enable)
void setExitPolicy(ExitPolicy &policy)
void setContactInfo(QString info)
void setDirPort(quint16 dirPort)
void setBandwidthAvgRate(quint32 rate)
bool isConnected()
Definition: TorControl.cpp:262
bool getInfo(QHash< QString, QString > &map, QString *errmsg=0)
Definition: TorControl.cpp:450
quint32 getTorVersion()
Definition: TorControl.cpp:667
static int warning(QWidget *parent, QString caption, QString text, int button0, int button1=NoButton, int button2=NoButton)
static TorControl * torControl()
Definition: Vidalia.h:76
QString p(QString str)
Definition: html.cpp:22
Definition: tcglobal.cpp:19
bool err(QString *str, const QString &errmsg)
Definition: stringutil.cpp:37
QHash< QString, QString > string_parse_keyvals(const QString &str, bool *ok)
Definition: stringutil.cpp:244