[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[vidalia-svn] r4378: Drop remote GeoIP lookups and use either a local city-level (vidalia/trunk/src/vidalia/network)
Author: edmanm
Date: 2010-08-05 16:28:54 -0400 (Thu, 05 Aug 2010)
New Revision: 4378
Added:
vidalia/trunk/src/vidalia/network/CountryInfo.cpp
vidalia/trunk/src/vidalia/network/CountryInfo.h
vidalia/trunk/src/vidalia/network/GeoIpRecord.cpp
vidalia/trunk/src/vidalia/network/GeoIpRecord.h
Removed:
vidalia/trunk/src/vidalia/network/GeoIp.cpp
vidalia/trunk/src/vidalia/network/GeoIp.h
Modified:
vidalia/trunk/src/vidalia/network/GeoIpResolver.cpp
vidalia/trunk/src/vidalia/network/GeoIpResolver.h
vidalia/trunk/src/vidalia/network/NetViewer.cpp
vidalia/trunk/src/vidalia/network/NetViewer.h
vidalia/trunk/src/vidalia/network/RouterListItem.cpp
vidalia/trunk/src/vidalia/network/RouterListItem.h
vidalia/trunk/src/vidalia/network/RouterListWidget.cpp
vidalia/trunk/src/vidalia/network/RouterListWidget.h
vidalia/trunk/src/vidalia/network/TorMapImageView.cpp
vidalia/trunk/src/vidalia/network/TorMapImageView.h
vidalia/trunk/src/vidalia/network/TorMapWidget.cpp
vidalia/trunk/src/vidalia/network/TorMapWidget.h
Log:
Drop remote GeoIP lookups and use either a local city-level database, a
local country-level database, or Tor's built-in database depending on
build and vidalia.conf optinos. This massive commit includes a number of
changes:
- Move the CountryInfo class over to src/vidalia/network since that is a
more reasonable location for it, and add the ability to parse the
built-in country coordinates CSV file.
- Rename GeoIp to GeoIpRecord to avoid conflicts with the MaxMind GeoIp
library.
Copied: vidalia/trunk/src/vidalia/network/CountryInfo.cpp (from rev 4346, vidalia/trunk/src/common/CountryInfo.cpp)
===================================================================
--- vidalia/trunk/src/vidalia/network/CountryInfo.cpp (rev 0)
+++ vidalia/trunk/src/vidalia/network/CountryInfo.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -0,0 +1,281 @@
+/*
+** This file is part of Vidalia, and is subject to the license terms in the
+** LICENSE file, found in the top level directory of this distribution. If you
+** did not receive the LICENSE file with this file, you may obtain it from the
+** Vidalia source package distributed by the Vidalia Project at
+** http://www.vidalia-project.net/. No part of Vidalia, including this file,
+** may be copied, modified, propagated, or distributed except according to the
+** terms described in the LICENSE file.
+*/
+
+/*
+** \file CountryInfo.cpp
+** \version $Id$
+** \brief Provides a method to look up a localized country name given its
+** ISO 3166 2-letter country code.
+*/
+
+#include "CountryInfo.h"
+#include "Vidalia.h"
+
+#include <QMap>
+#include <QHash>
+#include <QFile>
+#include <QStringList>
+
+#define COUNTRY_LOCATION_FILE ":/geoip/country-coordinates.csv"
+
+
+CountryInfo::CountryInfo(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QString
+CountryInfo::countryName(const QString &countryCode)
+{
+ static QMap<QString,QString> db;
+ if (db.isEmpty()) {
+ db.insert("af", QT_TR_NOOP("Afghanistan"));
+ db.insert("al", QT_TR_NOOP("Albania "));
+ db.insert("dz", QT_TR_NOOP("Algeria "));
+ db.insert("ad", QT_TR_NOOP("Andorra"));
+ db.insert("ao", QT_TR_NOOP("Angola"));
+ db.insert("ag", QT_TR_NOOP("Antigua & Barbuda"));
+ db.insert("ar", QT_TR_NOOP("Argentina"));
+ db.insert("am", QT_TR_NOOP("Armenia"));
+ db.insert("au", QT_TR_NOOP("Australia"));
+ db.insert("at", QT_TR_NOOP("Austria "));
+ db.insert("az", QT_TR_NOOP("Azerbaijan"));
+ db.insert("bs", QT_TR_NOOP("Bahamas"));
+ db.insert("bh", QT_TR_NOOP("Bahrain "));
+ db.insert("bd", QT_TR_NOOP("Bangladesh"));
+ db.insert("bb", QT_TR_NOOP("Barbados"));
+ db.insert("by", QT_TR_NOOP("Belarus"));
+ db.insert("be", QT_TR_NOOP("Belgium"));
+ db.insert("bz", QT_TR_NOOP("Belize"));
+ db.insert("bj", QT_TR_NOOP("Benin "));
+ db.insert("bt", QT_TR_NOOP("Bhutan"));
+ db.insert("bo", QT_TR_NOOP("Bolivia"));
+ db.insert("ba", QT_TR_NOOP("Bosnia & Herzegovina"));
+ db.insert("bw", QT_TR_NOOP("Botswana"));
+ db.insert("br", QT_TR_NOOP("Brazil"));
+ db.insert("bn", QT_TR_NOOP("Brunei Darussalam"));
+ db.insert("bg", QT_TR_NOOP("Bulgaria"));
+ db.insert("bf", QT_TR_NOOP("Burkina Faso"));
+ db.insert("bi", QT_TR_NOOP("Burundi"));
+ db.insert("kh", QT_TR_NOOP("Cambodia"));
+ db.insert("cm", QT_TR_NOOP("Cameroon"));
+ db.insert("ca", QT_TR_NOOP("Canada"));
+ db.insert("cv", QT_TR_NOOP("Cape Verde"));
+ db.insert("cf", QT_TR_NOOP("Central African Republic"));
+ db.insert("td", QT_TR_NOOP("Chad"));
+ db.insert("cl", QT_TR_NOOP("Chile"));
+ db.insert("cn", QT_TR_NOOP("China"));
+ db.insert("co", QT_TR_NOOP("Colombia"));
+ db.insert("km", QT_TR_NOOP("Comoros"));
+ db.insert("cd", QT_TR_NOOP("Congo, The Democratic Republic of the"));
+ db.insert("cg", QT_TR_NOOP("Congo"));
+ db.insert("cr", QT_TR_NOOP("Costa Rica"));
+ db.insert("ci", QT_TR_NOOP("Cote dâIvoire"));
+ db.insert("hr", QT_TR_NOOP("Croatia"));
+ db.insert("cu", QT_TR_NOOP("Cuba"));
+ db.insert("cy", QT_TR_NOOP("Cyprus"));
+ db.insert("cz", QT_TR_NOOP("Czech Republic"));
+ db.insert("dk", QT_TR_NOOP("Denmark"));
+ db.insert("dj", QT_TR_NOOP("Djibouti"));
+ db.insert("dm", QT_TR_NOOP("Dominica"));
+ db.insert("do", QT_TR_NOOP("Dominican Republic"));
+ db.insert("ec", QT_TR_NOOP("Ecuador"));
+ db.insert("eg", QT_TR_NOOP("Egypt"));
+ db.insert("sv", QT_TR_NOOP("El Salvador"));
+ db.insert("gq", QT_TR_NOOP("Equatorial Guinea"));
+ db.insert("er", QT_TR_NOOP("Eritrea"));
+ db.insert("ee", QT_TR_NOOP("Estonia"));
+ db.insert("et", QT_TR_NOOP("Ethiopia "));
+ db.insert("fj", QT_TR_NOOP("Fiji "));
+ db.insert("fi", QT_TR_NOOP("Finland "));
+ db.insert("fr", QT_TR_NOOP("France"));
+ db.insert("ga", QT_TR_NOOP("Gabon"));
+ db.insert("gm", QT_TR_NOOP("Gambia"));
+ db.insert("ge", QT_TR_NOOP("Georgia"));
+ db.insert("de", QT_TR_NOOP("Germany"));
+ db.insert("gh", QT_TR_NOOP("Ghana"));
+ db.insert("gr", QT_TR_NOOP("Greece "));
+ db.insert("gd", QT_TR_NOOP("Grenada"));
+ db.insert("gt", QT_TR_NOOP("Guatemala"));
+ db.insert("gu", QT_TR_NOOP("Guam "));
+ db.insert("gn", QT_TR_NOOP("Guinea"));
+ db.insert("gw", QT_TR_NOOP("Guinea-Bissau"));
+ db.insert("gy", QT_TR_NOOP("Guyana"));
+ db.insert("hk", QT_TR_NOOP("Hong Kong"));
+ db.insert("ht", QT_TR_NOOP("Haiti"));
+ db.insert("hn", QT_TR_NOOP("Honduras"));
+ db.insert("hu", QT_TR_NOOP("Hungary "));
+ db.insert("is", QT_TR_NOOP("Iceland "));
+ db.insert("in", QT_TR_NOOP("India "));
+ db.insert("id", QT_TR_NOOP("Indonesia "));
+ db.insert("ir", QT_TR_NOOP("Iran "));
+ db.insert("iq", QT_TR_NOOP("Iraq "));
+ db.insert("ie", QT_TR_NOOP("Ireland "));
+ db.insert("il", QT_TR_NOOP("Israel"));
+ db.insert("it", QT_TR_NOOP("Italy"));
+ db.insert("jm", QT_TR_NOOP("Jamaica"));
+ db.insert("jp", QT_TR_NOOP("Japan"));
+ db.insert("jo", QT_TR_NOOP("Jordan"));
+ db.insert("kz", QT_TR_NOOP("Kazakhstan"));
+ db.insert("ke", QT_TR_NOOP("Kenya"));
+ db.insert("ki", QT_TR_NOOP("Kiribati"));
+ db.insert("kp", QT_TR_NOOP("Korea, North "));
+ db.insert("kr", QT_TR_NOOP("Korea, South "));
+ db.insert("kw", QT_TR_NOOP("Kuwait"));
+ db.insert("kg", QT_TR_NOOP("Kyrgyzstan"));
+ db.insert("la", QT_TR_NOOP("Laos"));
+ db.insert("lv", QT_TR_NOOP("Latvia"));
+ db.insert("lb", QT_TR_NOOP("Lebanon"));
+ db.insert("ls", QT_TR_NOOP("Lesotho"));
+ db.insert("lr", QT_TR_NOOP("Liberia"));
+ db.insert("ly", QT_TR_NOOP("Libya "));
+ db.insert("li", QT_TR_NOOP("Liechtenstein"));
+ db.insert("lt", QT_TR_NOOP("Lithuania"));
+ db.insert("lu", QT_TR_NOOP("Luxembourg"));
+ db.insert("mk", QT_TR_NOOP("Macedonia"));
+ db.insert("mg", QT_TR_NOOP("Madagascar"));
+ db.insert("mw", QT_TR_NOOP("Malawi"));
+ db.insert("my", QT_TR_NOOP("Malaysia"));
+ db.insert("mv", QT_TR_NOOP("Maldives "));
+ db.insert("ml", QT_TR_NOOP("Mali"));
+ db.insert("mt", QT_TR_NOOP("Malta"));
+ db.insert("mh", QT_TR_NOOP("Marshall Islands"));
+ db.insert("mr", QT_TR_NOOP("Mauritania"));
+ db.insert("mu", QT_TR_NOOP("Mauritius"));
+ db.insert("mx", QT_TR_NOOP("Mexico "));
+ db.insert("fm", QT_TR_NOOP("Micronesia"));
+ db.insert("md", QT_TR_NOOP("Moldova"));
+ db.insert("mc", QT_TR_NOOP("Monaco"));
+ db.insert("mn", QT_TR_NOOP("Mongolia"));
+ db.insert("me", QT_TR_NOOP("Montenegro"));
+ db.insert("ma", QT_TR_NOOP("Morocco"));
+ db.insert("mz", QT_TR_NOOP("Mozambique"));
+ db.insert("mm", QT_TR_NOOP("Myanmar "));
+ db.insert("na", QT_TR_NOOP("Namibia"));
+ db.insert("nr", QT_TR_NOOP("Nauru"));
+ db.insert("np", QT_TR_NOOP("Nepal"));
+ db.insert("nl", QT_TR_NOOP("Netherlands"));
+ db.insert("nz", QT_TR_NOOP("New Zealand"));
+ db.insert("ni", QT_TR_NOOP("Nicaragua"));
+ db.insert("ne", QT_TR_NOOP("Niger"));
+ db.insert("ng", QT_TR_NOOP("Nigeria"));
+ db.insert("no", QT_TR_NOOP("Norway"));
+ db.insert("om", QT_TR_NOOP("Oman"));
+ db.insert("pk", QT_TR_NOOP("Pakistan"));
+ db.insert("pw", QT_TR_NOOP("Palau"));
+ db.insert("ps", QT_TR_NOOP("Palestine"));
+ db.insert("pa", QT_TR_NOOP("Panama"));
+ db.insert("pg", QT_TR_NOOP("Papua New Guinea"));
+ db.insert("py", QT_TR_NOOP("Paraguay"));
+ db.insert("pe", QT_TR_NOOP("Peru"));
+ db.insert("ph", QT_TR_NOOP("Philippines"));
+ db.insert("pl", QT_TR_NOOP("Poland"));
+ db.insert("pt", QT_TR_NOOP("Portugal"));
+ db.insert("qa", QT_TR_NOOP("Qatar"));
+ db.insert("ro", QT_TR_NOOP("Romania"));
+ db.insert("ru", QT_TR_NOOP("Russia"));
+ db.insert("rw", QT_TR_NOOP("Rwanda"));
+ db.insert("kn", QT_TR_NOOP("Saint Kitts & Nevis"));
+ db.insert("lc", QT_TR_NOOP("Saint Lucia"));
+ db.insert("vc", QT_TR_NOOP("Saint Vincent & the Grenadines"));
+ db.insert("ws", QT_TR_NOOP("Samoa"));
+ db.insert("sm", QT_TR_NOOP("San Marino"));
+ db.insert("st", QT_TR_NOOP("Sao Tome & Principe"));
+ db.insert("sa", QT_TR_NOOP("Saudi Arabia"));
+ db.insert("sn", QT_TR_NOOP("Senegal"));
+ db.insert("rs", QT_TR_NOOP("Serbia"));
+ db.insert("sc", QT_TR_NOOP("Seychelles"));
+ db.insert("sl", QT_TR_NOOP("Sierra Leone"));
+ db.insert("sg", QT_TR_NOOP("Singapore"));
+ db.insert("sk", QT_TR_NOOP("Slovakia"));
+ db.insert("si", QT_TR_NOOP("Slovenia"));
+ db.insert("sb", QT_TR_NOOP("Solomon Islands"));
+ db.insert("so", QT_TR_NOOP("Somalia"));
+ db.insert("za", QT_TR_NOOP("South Africa"));
+ db.insert("es", QT_TR_NOOP("Spain"));
+ db.insert("lk", QT_TR_NOOP("Sri Lanka"));
+ db.insert("sd", QT_TR_NOOP("Sudan"));
+ db.insert("sr", QT_TR_NOOP("Suriname"));
+ db.insert("sz", QT_TR_NOOP("Swaziland"));
+ db.insert("se", QT_TR_NOOP("Sweden"));
+ db.insert("ch", QT_TR_NOOP("Switzerland"));
+ db.insert("sy", QT_TR_NOOP("Syria"));
+ db.insert("tw", QT_TR_NOOP("Taiwan "));
+ db.insert("tj", QT_TR_NOOP("Tajikistan"));
+ db.insert("tz", QT_TR_NOOP("Tanzania"));
+ db.insert("th", QT_TR_NOOP("Thailand"));
+ db.insert("tl", QT_TR_NOOP("Timor-Leste (East Timor)"));
+ db.insert("tg", QT_TR_NOOP("Togo"));
+ db.insert("to", QT_TR_NOOP("Tonga"));
+ db.insert("tt", QT_TR_NOOP("Trinidad & Tobago"));
+ db.insert("tn", QT_TR_NOOP("Tunisia"));
+ db.insert("tr", QT_TR_NOOP("Turkey"));
+ db.insert("tm", QT_TR_NOOP("Turkmenistan"));
+ db.insert("tv", QT_TR_NOOP("Tuvalu"));
+ db.insert("ug", QT_TR_NOOP("Uganda"));
+ db.insert("ua", QT_TR_NOOP("Ukraine"));
+ db.insert("ae", QT_TR_NOOP("United Arab Emirates"));
+ db.insert("gb", QT_TR_NOOP("United Kingdom"));
+ db.insert("us", QT_TR_NOOP("United States"));
+ db.insert("uy", QT_TR_NOOP("Uruguay"));
+ db.insert("uz", QT_TR_NOOP("Uzbekistan"));
+ db.insert("vu", QT_TR_NOOP("Vanuatu"));
+ db.insert("va", QT_TR_NOOP("Vatican"));
+ db.insert("ve", QT_TR_NOOP("Venezuela"));
+ db.insert("vn", QT_TR_NOOP("Vietnam"));
+ db.insert("eh", QT_TR_NOOP("Western Sahara"));
+ db.insert("ye", QT_TR_NOOP("Yemen"));
+ db.insert("zr", QT_TR_NOOP("Zaire"));
+ db.insert("zm", QT_TR_NOOP("Zambia"));
+ db.insert("zw", QT_TR_NOOP("Zimbabwe"));
+ }
+
+ QString cc = countryCode.toLower();
+ if (db.contains(cc))
+ return tr(db.value(cc).toLocal8Bit().data());
+ return QString();
+}
+
+QPair<float,float>
+CountryInfo::countryLocation(const QString &countryCode)
+{
+ static QHash<QString,QPair<float,float> > db;
+ if (db.isEmpty()) {
+ /* Load the country coordinates database */
+ QFile infile(COUNTRY_LOCATION_FILE);
+ if (! infile.open(QIODevice::ReadOnly | QIODevice::Text))
+ return QPair<float,float>(-180.0, -180.0);
+
+ while (! infile.atEnd()) {
+ /* Read and parse a single line from the input file */
+ bool ok;
+ QString line = infile.readLine().trimmed();
+ vInfo(line);
+ QStringList parts = line.split(",");
+ if (parts.size() >= 3) {
+ float latitude = parts[1].toFloat(&ok);
+ if (! ok)
+ continue;
+ float longitude = parts[2].toFloat(&ok);
+ if (! ok)
+ continue;
+ db.insert(parts[0], QPair<float,float>(latitude, longitude));
+ }
+ }
+ vInfo("Loaded %1 country location entries from built-in database.").arg(db.size());
+ infile.close();
+ }
+
+ QString cc = countryCode.toLower();
+ if (db.contains(cc))
+ return db.value(cc);
+ return QPair<float,float>(-180.0, -180.0);
+}
+
Copied: vidalia/trunk/src/vidalia/network/CountryInfo.h (from rev 4346, vidalia/trunk/src/common/CountryInfo.h)
===================================================================
--- vidalia/trunk/src/vidalia/network/CountryInfo.h (rev 0)
+++ vidalia/trunk/src/vidalia/network/CountryInfo.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -0,0 +1,48 @@
+/*
+** This file is part of Vidalia, and is subject to the license terms in the
+** LICENSE file, found in the top level directory of this distribution. If you
+** did not receive the LICENSE file with this file, you may obtain it from the
+** Vidalia source package distributed by the Vidalia Project at
+** http://www.vidalia-project.net/. No part of Vidalia, including this file,
+** may be copied, modified, propagated, or distributed except according to the
+** terms described in the LICENSE file.
+*/
+
+/*
+** \file CountryInfo.h
+** \version $Id$
+** \brief Provides a method to look up a localized country name given its
+** ISO 3166-1 2-letter country code.
+*/
+
+#ifndef _COUNTRYINFO_H
+#define _COUNTRYINFO_H
+
+#include <QObject>
+#include <QString>
+#include <QPair>
+
+
+class CountryInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ /** Default constructor.
+ */
+ CountryInfo(QObject *parent = 0);
+
+ /** Returns the name of the country represented by <b>countryCode</b>, where
+ * <b>countryCode</b> is a 2-letter ISO 3166-1 alpha-2 two-letter country
+ * code. The name will be returned translated to the current locale if an
+ * appropriate QTranslator is currently installed.
+ */
+ static QString countryName(const QString &countryCode);
+
+ /**
+ */
+ static QPair<float,float> countryLocation(const QString &countryCode);
+};
+
+#endif
+
Deleted: vidalia/trunk/src/vidalia/network/GeoIp.cpp
Deleted: vidalia/trunk/src/vidalia/network/GeoIp.h
Copied: vidalia/trunk/src/vidalia/network/GeoIpRecord.cpp (from rev 4346, vidalia/trunk/src/vidalia/network/GeoIp.cpp)
===================================================================
--- vidalia/trunk/src/vidalia/network/GeoIpRecord.cpp (rev 0)
+++ vidalia/trunk/src/vidalia/network/GeoIpRecord.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -0,0 +1,85 @@
+/*
+** This file is part of Vidalia, and is subject to the license terms in the
+** LICENSE file, found in the top level directory of this distribution. If you
+** did not receive the LICENSE file with this file, you may obtain it from the
+** Vidalia source package distributed by the Vidalia Project at
+** http://www.vidalia-project.net/. No part of Vidalia, including this file,
+** may be copied, modified, propagated, or distributed except according to the
+** terms described in the LICENSE file.
+*/
+
+/*
+** \file GeoIpRecord.cpp
+** \version $Id$
+** \brief Associates an IP with a geographic location
+*/
+
+#include "GeoIpRecord.h"
+
+#include <QStringList>
+
+/** Verifies a latitude is between -90.0 and 90.0 degrees. */
+#define IS_VALID_LATITUDE(x) (((x) >= -90.0) && ((x) <= 90.0))
+/** Verifies a longitude is between -180.0 and 180.0 degrees. */
+#define IS_VALID_LONGITUDE(x) (((x) >= -180.0) && ((x) <= 180.0))
+
+
+GeoIpRecord::GeoIpRecord()
+{
+ _latitude = 0.0;
+ _longitude = 0.0;
+}
+
+GeoIpRecord::GeoIpRecord(const QHostAddress &ip, float latitude, float longitude,
+ const QString &country, const QString &countryCode)
+{
+ _ip = ip;
+ _latitude = latitude;
+ _longitude = longitude;
+ _country = country;
+ _countryCode = countryCode;
+}
+
+GeoIpRecord::GeoIpRecord(const QHostAddress &ip, float latitude, float longitude,
+ const QString &city, const QString ®ion,
+ const QString &country, const QString &countryCode)
+{
+ _ip = ip;
+ _latitude = latitude;
+ _longitude = longitude;
+ _city = city;
+ _region = region;
+ _country = country;
+ _countryCode = countryCode;
+}
+
+bool
+GeoIpRecord::isValid() const
+{
+ return (! _ip.isNull()
+ && IS_VALID_LATITUDE(_latitude)
+ && IS_VALID_LONGITUDE(_longitude));
+}
+
+QString
+GeoIpRecord::toString() const
+{
+ QStringList location;
+
+ /* Add the city name (if present) */
+ if (!_city.isEmpty())
+ location << _city;
+
+ /* Add the full state or region name (if present) */
+ if (!_region.isEmpty() && _region != _city)
+ location << _region;
+
+ /* Add the country name or the country code (if present) */
+ if (!_country.isEmpty())
+ location << _country;
+ else if (!_countryCode.isEmpty())
+ location << _countryCode;
+
+ return location.join(", ");
+}
+
Copied: vidalia/trunk/src/vidalia/network/GeoIpRecord.h (from rev 4346, vidalia/trunk/src/vidalia/network/GeoIp.h)
===================================================================
--- vidalia/trunk/src/vidalia/network/GeoIpRecord.h (rev 0)
+++ vidalia/trunk/src/vidalia/network/GeoIpRecord.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -0,0 +1,101 @@
+/*
+** This file is part of Vidalia, and is subject to the license terms in the
+** LICENSE file, found in the top level directory of this distribution. If you
+** did not receive the LICENSE file with this file, you may obtain it from the
+** Vidalia source package distributed by the Vidalia Project at
+** http://www.vidalia-project.net/. No part of Vidalia, including this file,
+** may be copied, modified, propagated, or distributed except according to the
+** terms described in the LICENSE file.
+*/
+
+/*
+** \file GeoIpRecord.h
+** \version $Id$
+** \brief Associates an IP with a geographic location
+*/
+
+#ifndef _GEOIPRECORD_H
+#define _GEOIPRECORD_H
+
+#include <QHash>
+#include <QString>
+#include <QHostAddress>
+
+
+class GeoIpRecord
+{
+public:
+ /** Default constructor. Creates an empty GeoIpRecord object.
+ */
+ GeoIpRecord();
+
+ /**
+ */
+ GeoIpRecord(const QHostAddress &ip, float latitude, float longitude,
+ const QString &country, const QString &countryCode);
+
+ /**
+ */
+ GeoIpRecord(const QHostAddress &ip, float latitude, float longitude,
+ const QString &city, const QString ®ion,
+ const QString &country, const QString &countryCode);
+
+ /** Returns the IP address associated with this GeoIP object.
+ */
+ QHostAddress ip() const { return _ip; }
+
+ /** Returns the latitude portion of the geographic coordinates associated
+ * with this IP address or range of IP addresses.
+ */
+ float latitude() const { return _latitude; }
+
+ /** Returns the longitude portion of the geographic coordinates associated
+ * with this IP address or range of IP addresses.
+ */
+ float longitude() const { return _longitude; }
+
+ /** Returns the name of the city associated with this IP address, if known.
+ * Otherwise, returns an empty QString.
+ */
+ QString city() const { return _city; }
+
+ /** Returns the full region name (e.g., state) in which this IP address
+ * resides, if known. Otherwise, returns an empty QString.
+ */
+ QString region() const { return _region; }
+
+ /** Returns the full name of the country associated with this IP address
+ * or range of IP addresses, if known. Otherwise, returns an empty QString.
+ */
+ QString country() const { return _country; }
+
+ /** Returns the ISO 3166-1 alpha-2 two-letter country code of the country
+ * associated with this IP address or range of IP addresses, if known.
+ * Otherwise, returns an empty QString.
+ */
+ QString countryCode() const { return _countryCode; }
+
+ /** Returns a human-readable string of city, region(state), and country.
+ * Some fields may be absent if they are not known. If no fields are known,
+ * this will return an empty QString.
+ */
+ QString toString() const;
+
+ /** Returns true if the GeoIpRecord object is valid. A valid GeoIpRecord object must
+ * have valid IP address, valid latitude and longitude coordinates and a
+ * two-letter country code.
+ */
+ bool isValid() const;
+
+private:
+ QHostAddress _ip; /**< IP address for this location. */
+ float _latitude; /**< Latitudinal coordinate for this IP's location. */
+ float _longitude; /**< Longitudinal coordinate for this IP's location. */
+ QString _city; /**< City in which this IP lives. */
+ QString _region; /**< State or district in which this IP lives. */
+ QString _country; /**< Country in which this IP lives. */
+ QString _countryCode; /**< ISO-3166-1 alpha-2 country code. */
+};
+
+#endif
+
Modified: vidalia/trunk/src/vidalia/network/GeoIpResolver.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/GeoIpResolver.cpp 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/GeoIpResolver.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -11,273 +11,77 @@
/*
** \file GeoIpResolver.cpp
** \version $Id$
-** \brief Requests GeoIP information and caches the result
+** \brief Retrieves GeoIP information either from Tor or from a local
+** database and returns the result.
*/
#include "GeoIpResolver.h"
-#include "GeoIpRequest.h"
-#include "GeoIpResponse.h"
-#include "GeoIp.h"
+#include "GeoIpRecord.h"
#include "Vidalia.h"
-#include "stringutil.h"
-#include "TorSslSocket.h"
-/** Host for the GeoIP information. */
-#define GEOIP_HOST "geoips.vidalia-project.net"
-/** The SSL GeoIP service runs on port 443. */
-#define GEOIP_SSL_PORT 443
-/** Page that we request the GeoIP information from. */
-#define GEOIP_PAGE "/cgi-bin/geoip.py"
-
-
/** Default constructor. */
GeoIpResolver::GeoIpResolver(QObject *parent)
- : QObject(parent)
+ : QObject(parent), _useLocalDatabase(false)
{
- _socksAddr = QHostAddress::LocalHost;
- _socksPort = 9050;
- _cache = new GeoIpCache(this);
}
-/** Sets the address and port of Tor, through which GeoIP requests will be
- * made. */
-void
-GeoIpResolver::setSocksHost(const QHostAddress &addr, quint16 port)
-{
- _socksAddr = addr;
- _socksPort = port;
-}
-
-/** Resolves <b>ip</b> to geographic information if it is cached. A resolved()
- * signal will be emitted and true returned if we have cached geographic
- * information for <b>ip</b>. Otherwise, this returns false. */
bool
-GeoIpResolver::resolveFromCache(const QHostAddress &ip)
+GeoIpResolver::setLocalDatabase(const QString &databaseFile)
{
- if (_cache->contains(ip)) {
- emit resolved(-1, QList<GeoIp>() << _cache->geoIpForAddress(ip));
- return true;
- }
+#if defined(USE_GEOIP)
+ return _database.open(databaseFile);
+#else
return false;
+#endif
}
-/** Resolves a list of IPs to a geographic location, but only those which are
- * cached. Returns a list of IPs that were not in the cache. */
-QList<QHostAddress>
-GeoIpResolver::resolveFromCache(const QList<QHostAddress> &ips)
-{
- QList<GeoIp> cached;
-
- /* Build a list of which IPs have cached GeoIp information */
- foreach (QHostAddress ip, ips) {
- if (_cache->contains(ip))
- cached << _cache->geoIpForAddress(ip);
- }
-
- /* If any were cached, emit their results now */
- if (cached.size() > 0) {
- vInfo("Resolved %1 GeoIP entries from cache.").arg(cached.size());
- emit resolved(-1, cached);
- }
- return ips;
-}
-
-/** Resolves a single IP to a geographic location. */
-int
-GeoIpResolver::resolve(const QHostAddress &ip)
-{
- return resolve(QList<QHostAddress>() << ip);
-}
-
-/** Called when the socket has connected to the Geo IP host. */
void
-GeoIpResolver::connected()
+GeoIpResolver::setUseLocalDatabase(bool useLocalDatabase)
{
- /* Find the socket and request for whoever called this slot */
- QAbstractSocket *socket = dynamic_cast<QAbstractSocket *>(sender());
- if (!_requestList.contains(socket)) {
- return;
- }
- GeoIpRequest *req = static_cast<GeoIpRequest *>(_requestList.value(socket));
-
- vInfo("Connected to the GeoIP host. Sending request for %1 uncached "
- "GeoIP entries. (request id %2)").arg(req->size()).arg(req->id());
-
- /* Send the request */
- socket->write(req->request());
+ _useLocalDatabase = useLocalDatabase;
}
-/** Called when the socket has disconnected from the Geo IP host. */
-void
-GeoIpResolver::disconnected()
+GeoIpRecord
+GeoIpResolver::resolveUsingTor(const QHostAddress &ip)
{
- /* Find the socket and request for whoever called this slot */
- QAbstractSocket *socket = dynamic_cast<QAbstractSocket *>(sender());
- if (!_requestList.contains(socket)) {
- return;
+ QString countryCode = Vidalia::torControl()->ipToCountry(ip);
+ if (! countryCode.isEmpty()) {
+ QPair<float,float> coords = CountryInfo::countryLocation(countryCode);
+ return GeoIpRecord(ip, coords.first, coords.second,
+ CountryInfo::countryName(countryCode),
+ countryCode);
}
- GeoIpRequest *req = static_cast<GeoIpRequest *>(_requestList.take(socket));
-
- /* Read and parse the response header */
- GeoIpResponse response = GeoIpResponse(socket->readAll());
-
- /* Check the response code and see what we got */
- if (response.statusCode() == 200) {
- /* We got a 200 OK, so get the Geo IP information from the response body
- * and cache the results. */
- parseGeoIpResponse(response.content(), req);
- } else {
- /* We failed to get the Geo IP information, so emit resolveFailed and
- * include the HTTP status message. */
- vWarn("GeoIP resolution failed (request id %1): %2").arg(req->id())
- .arg(response.statusMessage());
- emit resolveFailed(req->id(), response.statusMessage());
- }
- /* Close the socket and clean up */
- socket->close();
- delete socket;
- delete req;
+ return GeoIpRecord();
}
-void
-GeoIpResolver::parseGeoIpResponse(const QByteArray &response,
- GeoIpRequest *request)
+GeoIpRecord
+GeoIpResolver::resolveUsingLocalDatabase(const QHostAddress &ip)
{
- QList<GeoIp> geoIpList;
- QHash<QString,QString> keyvals;
- QHostAddress ip, from, to;
- QString city, region, country, cc;
- float latitude, longitude;
- GeoIp geoIp;
- int numCached = 0;
- bool ok;
-
- QStringList lines = QString(response).split("\n", QString::SkipEmptyParts);
- foreach (QString line, lines) {
- /* Split the key=value formatted GeoIP record into keys and values */
- QHash<QString,QString> keyvals = string_parse_keyvals(line.trimmed(), &ok);
- if (! ok)
- goto err;
-
- /* Extract each of the required fields from the GeoIP record */
- ip = QHostAddress(keyvals.value("IP"));
- if (ip.isNull())
- goto err;
- latitude = keyvals.value("LAT").toFloat(&ok);
- if (! ok)
- goto err;
- longitude = keyvals.value("LON").toFloat(&ok);
- if (! ok)
- goto err;
-
- /* Each of these fields is optional */
- city = keyvals.value("CITY");
- region = keyvals.value("REGION");
- country = keyvals.value("COUNTRY");
- cc = keyvals.value("CC");
-
- geoIp = GeoIp(ip, latitude, longitude, city, region, country, cc);
- if (! geoIp.isValid())
- goto err;
-
- if (request->contains(ip)) {
- if (! _cache->contains(ip)) {
- from = QHostAddress(keyvals.value("FROM"));
- to = QHostAddress(keyvals.value("TO"));
- if (! from.isNull() && ! to.isNull())
- _cache->addToCache(from, to, geoIp);
- else
- _cache->addToCache(geoIp);
- numCached++;
- }
-
- geoIpList << geoIp;
- continue;
-
-err:
- vInfo("Ignored improperly formatted GeoIP record (request id %1): %2")
- .arg(line).arg(request->id());
- } else {
- /* This item wasn't requested, so just log it and ignore. */
- vWarn("Received a GeoIP entry for IP address %1 that was not included "
- "in the initial request. (request id %2)").arg(ip)
- .arg(request->id());
+#if defined(USE_GEOIP)
+ if (_database.type() == GeoIpDatabase::CityDatabase) {
+ return _database.recordByAddr(ip);
+ } else {
+ QString countryCode = _database.countryCodeByAddr(ip);
+ if (! countryCode.isEmpty()) {
+ QPair<float,float> coords = CountryInfo::countryLocation(countryCode);
+ return GeoIpRecord(ip, coords.first, coords.second,
+ CountryInfo::countryName(countryCode),
+ countryCode);
}
}
- /* If new results were cached, save them to disk */
- if (numCached > 0)
- _cache->saveToDisk();
-
- /* Emit the results */
- vInfo("Parsed %1 entries from the GeoIP response. (request id %2)")
- .arg(geoIpList.size()).arg(request->id());
- emit resolved(request->id(), geoIpList);
+#endif
+ return GeoIpRecord();
}
-/** Called when an error has occurred requesting Geo IP information. */
-void
-GeoIpResolver::socketError(const QString &errorString)
+/** Resolves a single IP to a geographic location. */
+GeoIpRecord
+GeoIpResolver::resolve(const QHostAddress &ip)
{
- /* Find the socket and request for whoever called this slot */
- QAbstractSocket *socket = dynamic_cast<QAbstractSocket *>(sender());
- if (!_requestList.contains(socket)) {
- return;
- }
-
- /* We expect a remote host to close the socket, because that's how the HTTP
- * server tells us he's done talking to us. */
- if (socket->error() != QAbstractSocket::RemoteHostClosedError) {
- /* Emit the failure and clean up */
- GeoIpRequest *req = static_cast<GeoIpRequest *>(_requestList.take(socket));
- emit resolveFailed(req->id(), errorString);
- socket->abort();
- vWarn("GeoIP request socket error (request id %1): %2").arg(req->id())
- .arg(errorString);
- delete socket;
- delete req;
- }
+#if defined(USE_GEOIP)
+ if (_useLocalDatabase)
+ return resolveUsingLocalDatabase(ip);
+#endif
+ return resolveUsingTor(ip);
}
-/** Creates an HTTP request for Geo IP information. */
-GeoIpRequest*
-GeoIpResolver::createRequest(const QList<QHostAddress> &ips)
-{
- static int id = -1;
- GeoIpRequest *request = new GeoIpRequest(++id);
- request->setHost(GEOIP_HOST);
- request->setPage(GEOIP_PAGE);
- request->setRequest(ips);
- return request;
-}
-
-/** Resolves a list of IPs to a geographic location. */
-int
-GeoIpResolver::resolve(const QList<QHostAddress> &ips)
-{
- /* Resolve the cached IPs and get a list of IPs that still need to be
- * resolved to a lat and long. */
- QList<QHostAddress> uncached = resolveFromCache(ips);
- if (! uncached.size())
- return -1;
-
- /* Create a socket used to request the geo ip information. */
- TorSslSocket *socket = new TorSslSocket(_socksAddr, _socksPort);
- connect(socket, SIGNAL(connectedToRemoteHost()), this, SLOT(connected()),
- Qt::QueuedConnection);
- connect(socket, SIGNAL(socketError(QString)),
- this, SLOT(socketError(QString)),
- Qt::QueuedConnection);
- connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()),
- Qt::QueuedConnection);
- GeoIpRequest *request = createRequest(uncached);
- _requestList.insert(socket, request);
-
- /* Connect so we can send our request and return the request ID. */
- vInfo("Opening an SSL connection to the GeoIP host at %1:%2 (request id %3)")
- .arg(GEOIP_HOST).arg(GEOIP_SSL_PORT).arg(request->id());
- socket->connectToRemoteHost(GEOIP_HOST, GEOIP_SSL_PORT, true);
-
- return request->id();
-}
-
Modified: vidalia/trunk/src/vidalia/network/GeoIpResolver.h
===================================================================
--- vidalia/trunk/src/vidalia/network/GeoIpResolver.h 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/GeoIpResolver.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -11,24 +11,26 @@
/*
G** \file GeoIpResolver.h
** \version $Id$
-** \brief Requests GeoIP information and caches the result
+** \brief Retrieves GeoIP information either from Tor or from a local
+** database and returns the result.
*/
#ifndef _GEOIPRESOLVER_H
#define _GEOIPRESOLVER_H
-#include "GeoIpCache.h"
+#include "Vidalia.h"
+#ifdef USE_GEOIP
+#include "GeoIpDatabase.h"
+#endif
+#include "CountryInfo.h"
#include <QObject>
#include <QList>
#include <QHash>
#include <QHostAddress>
-class GeoIp;
-class GeoIpRequest;
-class GeoIpResponse;
class QString;
-class QAbstractSocket;
+class GeoIpRecord;
class GeoIpResolver : public QObject
@@ -36,50 +38,51 @@
Q_OBJECT
public:
- /** Default constructor. */
+ /** Default constructor.
+ */
GeoIpResolver(QObject *parent = 0);
-
- /** Sets the address and port of Tor, through which GeoIP requests will be
- * made. */
- void setSocksHost(const QHostAddress &addr, quint16 port);
- /** Resolves a single IP to a geographic location. */
- int resolve(const QHostAddress &ip);
- /** Resolves a list of IPs to a geographic location. */
- int resolve(const QList<QHostAddress> &ips);
- /** Resolves <b>ip</b> to geographic information only if it is cached. */
- bool resolveFromCache(const QHostAddress &ip);
- /** Resolves a list of IPs to a geographic location, but only those which
- * are cached. Returns a list of which IPs were not cached. */
- QList<QHostAddress> resolveFromCache(const QList<QHostAddress> &ips);
-signals:
- /** Emitted when a list of IPs have been resolved to lat/long. */
- void resolved(int id, const QList<GeoIp> &geoips);
- /** Emitted when a resolve has failed. */
- void resolveFailed(int id, const QString &errorString);
+ /** Sets the local database file to <b>databaseFile</b>. Returns true if
+ * <b>databaseFile</b> could be opened for reading. Otherwise, returns
+ * false.
+ * \sa setUseLocalDatabase()
+ */
+ bool setLocalDatabase(const QString &databaseFile);
-private slots:
- /** Called when the socket has connected to the Geo IP host. */
- void connected();
- /** Called when the socket has disconnected from the Geo IP host. */
- void disconnected();
- /** Called when an error has occurred getting the Geo IP information. */
- void socketError(const QString &errorString);
+ /** Enables or disables the use of a local GeoIP database, depending on
+ * the value of <b>useLocalDatabase</b>.
+ * \sa setLocalDatabase()
+ */
+ void setUseLocalDatabase(bool useLocalDatabase);
-private:
- /** Creates an HTTP request for Geo IP information. */
- GeoIpRequest* createRequest(const QList<QHostAddress> &ips);
+ /** Resolves a single IP to a geographic location and returns the
+ * result on success. On failure, this returns a default-constructed
+ * GeoIpRecord object.
+ */
+ GeoIpRecord resolve(const QHostAddress &ip);
- void parseGeoIpResponse(const QByteArray &response, GeoIpRequest *request);
+protected:
+ /** Maps <b>ip</b> to a country code using Tor, and then maps the
+ * country code to a geographic location using the built-in
+ * country-to-coordinate database.
+ */
+ GeoIpRecord resolveUsingTor(const QHostAddress &ip);
- /**< Cached GeoIp objects. */
- GeoIpCache* _cache;
- /**< List of sockets used for requests. */
- QHash<QAbstractSocket *,GeoIpRequest*> _requestList;
- /** Tor's SocksListenAddress. */
- QHostAddress _socksAddr;
- /** Tor's SocksPort. */
- quint16 _socksPort;
+ /** Maps <b>ip</b> to an approximate geographic location using a local
+ * GeoIP database and returns the result on success.
+ * \sa setLocalDatabase()
+ * \sa setUseLocalDatabase()
+ */
+ GeoIpRecord resolveUsingLocalDatabase(const QHostAddress &ip);
+
+private:
+#ifdef USE_GEOIP
+ /** Wrapper around a local database used for looking up GeoIP
+ * information.
+ */
+ GeoIpDatabase _database;
+#endif
+ bool _useLocalDatabase;
};
#endif
Modified: vidalia/trunk/src/vidalia/network/NetViewer.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/NetViewer.cpp 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/NetViewer.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -22,11 +22,13 @@
#include <QMessageBox>
#include <QHeaderView>
+#include <QCoreApplication>
#define IMG_MOVE ":/images/22x22/move-map.png"
#define IMG_ZOOMIN ":/images/22x22/zoom-in.png"
#define IMG_ZOOMOUT ":/images/22x22/zoom-out.png"
+#if 0
/** Number of milliseconds to wait after the arrival of the last descriptor whose
* IP needs to be resolved to geographic information, in case more descriptors
* arrive. Then we can simply lump the IPs into a single request. */
@@ -34,8 +36,8 @@
/** Maximum number of milliseconds to wait after the arrival of the first
* IP address into the resolve queue, before we flush the entire queue. */
#define MAX_RESOLVE_QUEUE_DELAY (30*1000)
+#endif
-
/** Constructor. Loads settings from VidaliaSettings.
* \param parent The parent widget of this NetViewer object.\
*/
@@ -109,15 +111,7 @@
* needs to be called to get rid of any descriptors that were removed. */
_refreshTimer.setInterval(60*60*1000);
connect(&_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
-
- /* Set up the timers used to group together GeoIP requests for new
- * descriptors arriving within MIN_RESOLVE_QUEUE_DELAY milliseconds, but no
- * more than MAX_RESOLVE_QUEUE_DELAY milliseconds of each other. */
- _minResolveQueueTimer.setSingleShot(true);
- connect(&_minResolveQueueTimer, SIGNAL(timeout()), this, SLOT(resolve()));
- _maxResolveQueueTimer.setSingleShot(true);
- connect(&_maxResolveQueueTimer, SIGNAL(timeout()), this, SLOT(resolve()));
-
+
/* Connect the necessary slots and signals */
connect(ui.actionHelp, SIGNAL(triggered()), this, SLOT(help()));
connect(ui.actionRefresh, SIGNAL(triggered()), this, SLOT(refresh()));
@@ -136,9 +130,7 @@
connect(ui.treeCircuitList, SIGNAL(closeStream(StreamId)),
_torControl, SLOT(closeStream(StreamId)));
- /* Connect the slot to find out when geoip information has arrived */
- connect(&_geoip, SIGNAL(resolved(int, QList<GeoIp>)),
- this, SLOT(resolved(int, QList<GeoIp>)));
+ setupGeoIpResolver();
}
/** Called when the user changes the UI translation. */
@@ -168,24 +160,31 @@
}
}
-/** Display the network map window. If there are geoip requests waiting in the
- * queue, start the queue timers now. */
void
-NetViewer::showWindow()
+NetViewer::setupGeoIpResolver()
{
- if (!_resolveQueue.isEmpty()) {
- _minResolveQueueTimer.start(MIN_RESOLVE_QUEUE_DELAY);
- _maxResolveQueueTimer.start(MAX_RESOLVE_QUEUE_DELAY);
+ VidaliaSettings settings;
+
+#if defined(USE_GEOIP)
+ if (settings.useLocalGeoIpDatabase()) {
+ QString databaseFile = settings.localGeoIpDatabase();
+ if (! databaseFile.isEmpty()) {
+ _geoip.setLocalDatabase(databaseFile);
+ _geoip.setUseLocalDatabase(true);
+ vInfo("Using local database file for relay mapping: %1")
+ .arg(databaseFile);
+ return;
+ }
}
- VidaliaWindow::showWindow();
+#endif
+ vInfo("Using Tor's GeoIP database for country-level relay mapping.");
+ _geoip.setUseLocalDatabase(false);
}
/** Loads data into map, lists and starts timer when we get connected*/
void
NetViewer::onAuthenticated()
{
- _geoip.setSocksHost(_torControl->getSocksAddress(),
- _torControl->getSocksPort());
refresh();
_refreshTimer.start();
ui.actionRefresh->setEnabled(true);
@@ -225,9 +224,6 @@
void
NetViewer::clear()
{
- /* Clear the resolve queue and map */
- _resolveMap.clear();
- _resolveQueue.clear();
/* Clear the network map */
_map->clear();
_map->update();
@@ -324,6 +320,8 @@
RouterDescriptor rd = _torControl->getRouterDescriptor(rs.id());
if (!rd.isEmpty())
addRouter(rd);
+
+ QCoreApplication::processEvents();
}
}
@@ -333,18 +331,19 @@
NetViewer::addRouter(const RouterDescriptor &rd)
{
/* Add the descriptor to the list of server */
- ui.treeRouterList->addRouter(rd);
+ RouterListItem *item = ui.treeRouterList->addRouter(rd);
+ if (! item)
+ return;
- /* Add this IP to a list of addresses whose geographic location we'd like to
- * find, but not for special purpose descriptors (e.g., bridges). This
- * check is only valid for Tor >= 0.2.0.13-alpha. */
- if (_torControl->getTorVersion() >= 0x020013) {
- DescriptorAnnotations annotations =
- _torControl->getDescriptorAnnotations(rd.id());
- if (!annotations.contains("purpose"))
- addToResolveQueue(rd.ip(), rd.id());
- } else {
- addToResolveQueue(rd.ip(), rd.id());
+ /* Attempt to map this relay to an approximate geographic location. The
+ * accuracy of the result depends on the database information currently
+ * available to the GeoIP resolver. */
+ if (! item->location().isValid() || rd.ip() != item->location().ip()) {
+ GeoIpRecord location = _geoip.resolve(rd.ip());
+ if (location.isValid()) {
+ item->setLocation(location);
+ _map->addRouter(rd, location);
+ }
}
}
@@ -361,33 +360,6 @@
}
}
-/** Adds an IP address to the resolve queue and updates the queue timers. */
-void
-NetViewer::addToResolveQueue(const QHostAddress &ip, const QString &id)
-{
- QString ipstr = ip.toString();
- if (!_resolveMap.values(ipstr).contains(id)) {
- /* Remember which server ids belong to which IP addresses */
- _resolveMap.insertMulti(ipstr, id);
- }
-
- if (!_resolveQueue.contains(ip) && !_geoip.resolveFromCache(ip)) {
- /* Add the IP to the queue of IPs waiting for geographic information */
- _resolveQueue << ip;
-
- /* Wait MIN_RESOLVE_QUEUE_DELAY after the last item inserted into the
- * queue, before sending the resolve request. */
- _minResolveQueueTimer.start(MIN_RESOLVE_QUEUE_DELAY);
-
- /* Do not wait longer than MAX_RESOLVE_QUEUE_DELAY from the time the first
- * item is inserted into the queue, before flushing and resolving the
- * queue. */
- if (_resolveQueue.size() == 1) {
- _maxResolveQueueTimer.start(MAX_RESOLVE_QUEUE_DELAY);
- }
- }
-}
-
/** Called when the user selects a circuit from the circuit and streams
* list. */
void
@@ -429,65 +401,6 @@
_map->selectRouter(routers[0].id());
}
-/** If there are any IPs in the resolve queue, do the request now. */
-void
-NetViewer::resolve()
-{
- if (!_resolveQueue.isEmpty()) {
- /* Send the request now if either the network map is visible, or the
- * request is for more than a quarter of the servers in the list. */
- if (isVisible() ||
- (_resolveQueue.size() >= ui.treeRouterList->topLevelItemCount()/4)) {
- vInfo("Sending GeoIP request for %1 IP addresses.")
- .arg(_resolveQueue.size());
- /* Flush the resolve queue and stop the timers */
- _geoip.resolve(_resolveQueue);
- _resolveQueue.clear();
- }
- }
- /* Stop the queue timers. Only one should be active since the other is what
- * called this slot, but calling stop() on a stopped timer does not hurt. */
- _minResolveQueueTimer.stop();
- _maxResolveQueueTimer.stop();
-}
-
-/** Called when a list of GeoIp information has been resolved. */
-void
-NetViewer::resolved(int id, const QList<GeoIp> &geoips)
-{
- Q_UNUSED(id);
-
- QString ip;
- RouterListItem *router;
-
- foreach (GeoIp geoip, geoips) {
- /* Find all routers that are at this IP address */
- ip = geoip.ip().toString();
- QList<QString> ids = _resolveMap.values(ip);
- _resolveMap.remove(ip);
-
- /* Update their geographic location information with the results of this
- * GeoIP query. */
- foreach (QString id, ids) {
- router = ui.treeRouterList->findRouterById(id);
- if (router) {
- /* Save the location information in the descriptor */
- router->setLocation(geoip);
- /* Plot the router on the map */
- _map->addRouter(router->descriptor(), geoip);
- }
- }
- }
-
- /* Update the circuit lines */
- foreach (Circuit circuit, ui.treeCircuitList->circuits()) {
- _map->addCircuit(circuit.id(), circuit.routerIDs());
- }
-
- /* Repaint the map */
- _map->update();
-}
-
/** Called when the user selects a router on the network map. Displays a
* dialog with detailed information for the router specified by
* <b>id</b>.*/
@@ -514,7 +427,7 @@
/* Populate the UI with information learned from a previous GeoIP request */
RouterListItem *item = ui.treeRouterList->findRouterById(id);
if (item)
- dlg.setLocation(item->location());
+ dlg.setLocation(item->location().toString());
else
dlg.setLocation(tr("Unknown"));
Modified: vidalia/trunk/src/vidalia/network/NetViewer.h
===================================================================
--- vidalia/trunk/src/vidalia/network/NetViewer.h 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/NetViewer.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -49,7 +49,7 @@
public slots:
/** Displays the network map window. */
- void showWindow();
+// void showWindow();
/** Loads a list of current circuits and streams. */
void loadConnections();
/** Adds <b>circuit</b> to the list and the map */
@@ -85,16 +85,12 @@
void refresh();
/** Called when the user selects a circuit on the circuit list */
void circuitSelected(const Circuit &circuit);
- /** Called when an IP has been resolved to geographic information. */
- void resolved(int id, const QList<GeoIp> &geoips);
/** Called when the user selects one or more routers in the list. */
void routerSelected(const QList<RouterDescriptor> &routers);
/** Handles when we get connected to Tor network */
void onAuthenticated();
/** Handles when we get disconnected from Tor network */
void onDisconnected();
- /** Resolves IP addresses in the resolve queue to geographic information. */
- void resolve();
/** Called when the user selects a router on the network map. Displays a
* dialog with detailed information for the router specified by
* <b>id</b>.*/
@@ -108,8 +104,8 @@
void toggleFullScreen();
private:
- /** Adds an IP address to the resolve queue and updates the queue timers. */
- void addToResolveQueue(const QHostAddress &ip, const QString &id);
+ /** */
+ void setupGeoIpResolver();
/** Retrieves a list of all running routers from Tor and their descriptors,
* and adds them to the RouterListWidget. */
void loadNetworkStatus();
@@ -125,19 +121,8 @@
QTimer _refreshTimer;
/** GeoIpResolver used to geolocate routers by IP address. */
GeoIpResolver _geoip;
- /** Queue for IPs pending resolution to geographic information. */
- QList<QHostAddress> _resolveQueue;
- /** Maps pending GeoIP requests to server IDs. */
- QHash<QString, QString> _resolveMap;
/** Stores a list of address mappings from Tor. */
AddressMap _addressMap;
- /** Timer used to delay GeoIP requests for MIN_RESOLVE_QUEUE_DELAY
- * milliseconds after we've inserted the last item into the queue. */
- QTimer _minResolveQueueTimer;
- /** Timer used to limit the delay of GeoIP requests to
- * MAX_RESOLVE_QUEUE_DELAY milliseconds after inserting the first item
- * into the queue. */
- QTimer _maxResolveQueueTimer;
/** Widget that displays the Tor network map. */
#if defined(USE_MARBLE)
Modified: vidalia/trunk/src/vidalia/network/RouterListItem.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/RouterListItem.cpp 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/RouterListItem.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -38,7 +38,7 @@
{
_list = list;
_rd = 0;
- _country = "~"; /* Force items with no country to the bottom */
+ _countryCode = "~"; /* Force items with no country to the bottom */
setIcon(COUNTRY_COLUMN, QIcon(IMG_FLAG_UNKNOWN));
update(rd);
}
@@ -91,17 +91,17 @@
/** Sets the location information for this item's router descriptor. */
void
-RouterListItem::setLocation(const GeoIp &geoip)
+RouterListItem::setLocation(const GeoIpRecord &geoip)
{
QPixmap flag(":/images/flags/" + geoip.countryCode().toLower() + ".png");
if (!flag.isNull()) {
setIcon(COUNTRY_COLUMN, QIcon(flag));
}
setToolTip(COUNTRY_COLUMN, geoip.toString());
-
+
if (_rd)
_rd->setLocation(geoip.toString());
- _country = geoip.countryCode();
+ _countryCode = geoip.countryCode();
}
/** Overload the comparison operator. */
@@ -125,13 +125,13 @@
return (a->_statusValue < b->_statusValue);
case RouterListWidget::CountryColumn:
/* Compare based on country code */
- if (a->_country == b->_country) {
+ if (a->_countryCode == b->_countryCode) {
if (order == Qt::AscendingOrder)
return (a->_statusValue > b->_statusValue);
else
return (a->_statusValue < b->_statusValue);
}
- return (a->_country < b->_country);
+ return (a->_countryCode < b->_countryCode);
case RouterListWidget::NameColumn:
/* Case-insensitive comparison based on router name */
if (a->name().toLower() == b->name().toLower()) {
Modified: vidalia/trunk/src/vidalia/network/RouterListItem.h
===================================================================
--- vidalia/trunk/src/vidalia/network/RouterListItem.h 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/RouterListItem.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -19,7 +19,7 @@
#include "RouterDescriptor.h"
#include "RouterListWidget.h"
-#include "GeoIp.h"
+#include "GeoIpRecord.h"
#include <QCoreApplication>
#include <QTreeWidgetItem>
@@ -47,9 +47,9 @@
/** Returns the descriptor for this router. */
RouterDescriptor descriptor() const { return *_rd; }
/** Sets the location information for this router item. */
- void setLocation(const GeoIp &geoip);
+ void setLocation(const GeoIpRecord &geoip);
/** Returns the location information set for this router item. */
- QString location() const { return _rd->location(); }
+ GeoIpRecord location() const { return _location; }
/** Overload the comparison operator. */
virtual bool operator<(const QTreeWidgetItem &other) const;
@@ -58,8 +58,8 @@
RouterDescriptor* _rd; /**< Descriptor for this router item. */
RouterListWidget* _list; /**< The list for this list item. */
qint64 _statusValue; /**< Value used to sort items by status. */
- QString _country; /**< Country in which this router is likely
- located. */
+ GeoIpRecord _location; /**< Location information for this router. */
+ QString _countryCode;
};
#endif
Modified: vidalia/trunk/src/vidalia/network/RouterListWidget.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/RouterListWidget.cpp 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/RouterListWidget.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -201,12 +201,12 @@
}
/** Adds a router descriptor to the list. */
-void
-RouterListWidget::addRouter(RouterDescriptor rd)
+RouterListItem*
+RouterListWidget::addRouter(const RouterDescriptor &rd)
{
QString id = rd.id();
if (id.isEmpty())
- return;
+ return 0;
RouterListItem *item = findRouterById(id);
if (item) {
@@ -219,6 +219,8 @@
/* Set our status tip to the number of servers in the list */
setStatusTip(tr("%1 relays online").arg(topLevelItemCount()));
+
+ return item;
}
/** Called when the selected items have changed. This emits the
Modified: vidalia/trunk/src/vidalia/network/RouterListWidget.h
===================================================================
--- vidalia/trunk/src/vidalia/network/RouterListWidget.h 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/RouterListWidget.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -47,7 +47,7 @@
RouterListWidget(QWidget *parent = 0);
/** Adds a new descriptor the list. */
- void addRouter(RouterDescriptor rd);
+ RouterListItem* addRouter(const RouterDescriptor &rd);
/** Finds the list item whose key ID matches <b>id</b>. Returns 0 if not
* found. */
RouterListItem* findRouterById(QString id);
Modified: vidalia/trunk/src/vidalia/network/TorMapImageView.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/TorMapImageView.cpp 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/TorMapImageView.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -85,7 +85,7 @@
/** Adds a router to the map. */
void
-TorMapImageView::addRouter(const RouterDescriptor &desc, const GeoIp &geoip)
+TorMapImageView::addRouter(const RouterDescriptor &desc, const GeoIpRecord &geoip)
{
QString id = desc.id();
QPointF routerCoord = toMapSpace(geoip.latitude(), geoip.longitude());
Modified: vidalia/trunk/src/vidalia/network/TorMapImageView.h
===================================================================
--- vidalia/trunk/src/vidalia/network/TorMapImageView.h 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/TorMapImageView.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -18,7 +18,7 @@
#define _TORMAPIMAGEVIEW_H
#include "ZImageView.h"
-#include "GeoIp.h"
+#include "GeoIpRecord.h"
#include "RouterDescriptor.h"
#include "Circuit.h"
@@ -40,7 +40,7 @@
~TorMapImageView();
/** Plots the given router on the map using the given coordinates. */
- void addRouter(const RouterDescriptor &desc, const GeoIp &geoip);
+ void addRouter(const RouterDescriptor &desc, const GeoIpRecord &geoip);
/** Plots the given circuit on the map. */
void addCircuit(const CircuitId &circid, const QStringList &path);
/** Selects and hightlights a router on the map. */
Modified: vidalia/trunk/src/vidalia/network/TorMapWidget.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/TorMapWidget.cpp 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/TorMapWidget.cpp 2010-08-05 20:28:54 UTC (rev 4378)
@@ -69,7 +69,7 @@
/** Adds a router to the map. */
void
-TorMapWidget::addRouter(const RouterDescriptor &desc, const GeoIp &geoip)
+TorMapWidget::addRouter(const RouterDescriptor &desc, const GeoIpRecord &geoip)
{
QString kml;
qreal lon = geoip.longitude();
Modified: vidalia/trunk/src/vidalia/network/TorMapWidget.h
===================================================================
--- vidalia/trunk/src/vidalia/network/TorMapWidget.h 2010-08-05 20:26:44 UTC (rev 4377)
+++ vidalia/trunk/src/vidalia/network/TorMapWidget.h 2010-08-05 20:28:54 UTC (rev 4378)
@@ -18,7 +18,7 @@
#define _TORMAPWIDGET_H
#include "RouterDescriptor.h"
-#include "GeoIp.h"
+#include "GeoIpRecord.h"
#include "Circuit.h"
#include "Stream.h"
@@ -46,7 +46,7 @@
~TorMapWidget();
/** Plots the given router on the map using the given coordinates. */
- void addRouter(const RouterDescriptor &desc, const GeoIp &geoip);
+ void addRouter(const RouterDescriptor &desc, const GeoIpRecord &geoip);
/** Plots the given circuit on the map. */
void addCircuit(const CircuitId &circid, const QStringList &path);
/** Selects and hightlights a router on the map. */