From ea1481beef19cfd1166126dc4425b661755257ab Mon Sep 17 00:00:00 2001
From: sledgehammer999
Date: Fri, 14 Feb 2020 22:07:19 +0200
Subject: [PATCH] Use IP geolocation database by DB-IP instead of MaxMind
Closes #11792
---
README.md | 3 +-
src/base/net/geoipmanager.cpp | 49 ++++++++++++-------
src/base/net/private/geoipdatabase.cpp | 11 ++---
src/base/net/private/geoipdatabase.h | 1 +
src/gui/aboutdialog.cpp | 12 ++++-
src/gui/aboutdialog.ui | 22 +++++++--
src/gui/advancedsettings.cpp | 2 +-
src/webui/www/private/views/about.html | 3 +-
src/webui/www/private/views/aboutToolbar.html | 6 +--
src/webui/www/private/views/preferences.html | 2 +-
10 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/README.md b/README.md
index a2c75ef52..8c0d32e72 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,7 @@ It aims to be a good alternative to all other bittorrent clients
out there. qBittorrent is fast, stable and provides unicode
support as well as many features.
-This product includes GeoLite data created by MaxMind, available from
-https://www.maxmind.com/
+The free [IP to Country Lite database](https://db-ip.com/db/download/ip-to-country-lite) by [DB-IP](https://db-ip.com/) is used for resolving the countries of peers. The database is licensed under the [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/).
### Installation:
For installation, follow the instructions from INSTALL file, but simple:
diff --git a/src/base/net/geoipmanager.cpp b/src/base/net/geoipmanager.cpp
index d5a6e8067..49f30cfb1 100644
--- a/src/base/net/geoipmanager.cpp
+++ b/src/base/net/geoipmanager.cpp
@@ -42,10 +42,9 @@
#include "downloadmanager.h"
#include "private/geoipdatabase.h"
-static const char DATABASE_URL[] = "https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz";
-static const char GEOIP_FOLDER[] = "GeoIP";
-static const char GEOIP_FILENAME[] = "GeoLite2-Country.mmdb";
-static const int UPDATE_INTERVAL = 30; // Days between database updates
+static const QString DATABASE_URL = QStringLiteral("https://download.db-ip.com/free/dbip-country-lite-%1.mmdb.gz");
+static const char GEODB_FOLDER[] = "GeoDB";
+static const char GEODB_FILENAME[] = "dbip-country-lite.mmdb";
using namespace Net;
@@ -89,29 +88,45 @@ void GeoIPManager::loadDatabase()
m_geoIPDatabase = nullptr;
const QString filepath = Utils::Fs::expandPathAbs(
- QString("%1%2/%3").arg(specialFolderLocation(SpecialFolder::Data), GEOIP_FOLDER, GEOIP_FILENAME));
+ QString("%1%2/%3").arg(specialFolderLocation(SpecialFolder::Data), GEODB_FOLDER, GEODB_FILENAME));
QString error;
m_geoIPDatabase = GeoIPDatabase::load(filepath, error);
if (m_geoIPDatabase)
- Logger::instance()->addMessage(tr("GeoIP database loaded. Type: %1. Build time: %2.")
+ Logger::instance()->addMessage(tr("IP geolocation database loaded. Type: %1. Build time: %2.")
.arg(m_geoIPDatabase->type(), m_geoIPDatabase->buildEpoch().toString()),
Log::INFO);
else
- Logger::instance()->addMessage(tr("Couldn't load GeoIP database. Reason: %1").arg(error), Log::WARNING);
+ Logger::instance()->addMessage(tr("Couldn't load IP geolocation database. Reason: %1").arg(error), Log::WARNING);
manageDatabaseUpdate();
}
void GeoIPManager::manageDatabaseUpdate()
{
- if (!m_geoIPDatabase || (m_geoIPDatabase->buildEpoch().daysTo(QDateTime::currentDateTimeUtc()) >= UPDATE_INTERVAL))
+ const auto expired = [](const QDateTime &testDateTime)
+ {
+ const QDate testDate = testDateTime.date();
+ const QDate curDate = QDateTime::currentDateTimeUtc().date();
+
+ if ((testDate.year() < curDate.year()) && (curDate.day() > 1))
+ return true;
+
+ if ((testDate.month() < curDate.month()) && (curDate.day() > 1))
+ return true;
+
+ return false;
+ };
+
+ if (!m_geoIPDatabase || expired(m_geoIPDatabase->buildEpoch()))
downloadDatabaseFile();
}
void GeoIPManager::downloadDatabaseFile()
{
- DownloadManager::instance()->download({DATABASE_URL}, this, &GeoIPManager::downloadFinished);
+ const QDate curDate = QDateTime::currentDateTimeUtc().date();
+ const QString curUrl = DATABASE_URL.arg(curDate.toString("yyyy-MM"));
+ DownloadManager::instance()->download({curUrl}, this, &GeoIPManager::downloadFinished);
}
QString GeoIPManager::lookup(const QHostAddress &hostAddr) const
@@ -403,14 +418,14 @@ void GeoIPManager::configure()
void GeoIPManager::downloadFinished(const DownloadResult &result)
{
if (result.status != DownloadStatus::Success) {
- LogMsg(tr("Couldn't download GeoIP database file. Reason: %1").arg(result.errorString), Log::WARNING);
+ LogMsg(tr("Couldn't download IP geolocation database file. Reason: %1").arg(result.errorString), Log::WARNING);
return;
}
bool ok = false;
const QByteArray data = Utils::Gzip::decompress(result.data, &ok);
if (!ok) {
- LogMsg(tr("Could not decompress GeoIP database file."), Log::WARNING);
+ LogMsg(tr("Could not decompress IP geolocation database file."), Log::WARNING);
return;
}
@@ -420,24 +435,24 @@ void GeoIPManager::downloadFinished(const DownloadResult &result)
if (!m_geoIPDatabase || (geoIPDatabase->buildEpoch() > m_geoIPDatabase->buildEpoch())) {
delete m_geoIPDatabase;
m_geoIPDatabase = geoIPDatabase;
- LogMsg(tr("GeoIP database loaded. Type: %1. Build time: %2.")
+ LogMsg(tr("IP geolocation database loaded. Type: %1. Build time: %2.")
.arg(m_geoIPDatabase->type(), m_geoIPDatabase->buildEpoch().toString()),
Log::INFO);
const QString targetPath = Utils::Fs::expandPathAbs(
- specialFolderLocation(SpecialFolder::Data) + GEOIP_FOLDER);
+ specialFolderLocation(SpecialFolder::Data) + GEODB_FOLDER);
if (!QDir(targetPath).exists())
QDir().mkpath(targetPath);
- QFile targetFile(QString("%1/%2").arg(targetPath, GEOIP_FILENAME));
+ QFile targetFile(QString("%1/%2").arg(targetPath, GEODB_FILENAME));
if (!targetFile.open(QFile::WriteOnly) || (targetFile.write(data) == -1))
- LogMsg(tr("Couldn't save downloaded GeoIP database file."), Log::WARNING);
+ LogMsg(tr("Couldn't save downloaded IP geolocation database file."), Log::WARNING);
else
- LogMsg(tr("Successfully updated GeoIP database."), Log::INFO);
+ LogMsg(tr("Successfully updated IP geolocation database."), Log::INFO);
}
else {
delete geoIPDatabase;
}
}
else {
- LogMsg(tr("Couldn't load GeoIP database. Reason: %1").arg(error), Log::WARNING);
+ LogMsg(tr("Couldn't load IP geolocation database. Reason: %1").arg(error), Log::WARNING);
}
}
diff --git a/src/base/net/private/geoipdatabase.cpp b/src/base/net/private/geoipdatabase.cpp
index f50538684..f191e882b 100644
--- a/src/base/net/private/geoipdatabase.cpp
+++ b/src/base/net/private/geoipdatabase.cpp
@@ -37,7 +37,6 @@
namespace
{
const qint32 MAX_FILE_SIZE = 67108864; // 64MB
- const char DB_TYPE[] = "GeoLite2-Country";
const quint32 MAX_METADATA_SIZE = 131072; // 128KB
const char METADATA_BEGIN_MARK[] = "\xab\xcd\xefMaxMind.com";
const char DATA_SECTION_SEPARATOR[16] = {0};
@@ -143,7 +142,7 @@ GeoIPDatabase::~GeoIPDatabase()
QString GeoIPDatabase::type() const
{
- return DB_TYPE;
+ return m_dbType;
}
quint16 GeoIPDatabase::ipVersion() const
@@ -253,11 +252,7 @@ bool GeoIPDatabase::parseMetadata(const QVariantHash &metadata, QString &error)
m_indexSize = m_nodeCount * m_nodeSize;
CHECK_METADATA_REQ(database_type, QString);
- const QString dbType = metadata.value("database_type").toString();
- if (dbType != DB_TYPE) {
- error = tr("Invalid database type: %1").arg(dbType);
- return false;
- }
+ m_dbType = metadata.value("database_type").toString();
CHECK_METADATA_REQ(build_epoch, ULongLong);
m_buildEpoch = QDateTime::fromSecsSinceEpoch(metadata.value("build_epoch").toULongLong());
@@ -270,7 +265,7 @@ bool GeoIPDatabase::parseMetadata(const QVariantHash &metadata, QString &error)
bool GeoIPDatabase::loadDB(QString &error) const
{
- qDebug() << "Parsing MaxMindDB index tree...";
+ qDebug() << "Parsing IP geolocation database index tree...";
const int nodeSize = m_recordSize / 4; // in bytes
const int indexSize = m_nodeCount * nodeSize;
diff --git a/src/base/net/private/geoipdatabase.h b/src/base/net/private/geoipdatabase.h
index 5ba3d0196..313ee0346 100644
--- a/src/base/net/private/geoipdatabase.h
+++ b/src/base/net/private/geoipdatabase.h
@@ -93,6 +93,7 @@ private:
int m_indexSize;
int m_recordBytes;
QDateTime m_buildEpoch;
+ QString m_dbType;
// Search data
mutable QHash m_countries;
quint32 m_size;
diff --git a/src/gui/aboutdialog.cpp b/src/gui/aboutdialog.cpp
index d070abef2..76640cc9f 100644
--- a/src/gui/aboutdialog.cpp
+++ b/src/gui/aboutdialog.cpp
@@ -48,7 +48,7 @@ AboutDialog::AboutDialog(QWidget *parent)
m_ui->logo->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/skin/qbittorrent-tray.svg", this, 32));
// About
- QString aboutText = QString(
+ const QString aboutText = QString(
""
"%1\n\n"
"%2\n\n"
@@ -88,13 +88,21 @@ AboutDialog::AboutDialog(QWidget *parent)
licensefile.close();
}
- // Libraries
+ // Software Used
m_ui->labelQtVer->setText(QT_VERSION_STR);
m_ui->labelLibtVer->setText(Utils::Misc::libtorrentVersionString());
m_ui->labelBoostVer->setText(Utils::Misc::boostVersionString());
m_ui->labelOpensslVer->setText(Utils::Misc::opensslVersionString());
m_ui->labelZlibVer->setText(Utils::Misc::zlibVersionString());
+ const QString DBIPText = QString(
+ "
"
+ "%1"
+ " (https://db-ip.com/ )
")
+ .arg(tr("The free IP to Country Lite database by DB-IP is used for resolving the countries of peers. "
+ "The database is licensed under the Creative Commons Attribution 4.0 International License"));
+ m_ui->labelDBIP->setText(DBIPText);
+
Utils::Gui::resize(this);
show();
}
diff --git a/src/gui/aboutdialog.ui b/src/gui/aboutdialog.ui
index fa27a9818..13ac0eb7b 100644
--- a/src/gui/aboutdialog.ui
+++ b/src/gui/aboutdialog.ui
@@ -314,11 +314,11 @@
-
+
- Libraries
+ Software Used
-
+
-
@@ -470,6 +470,22 @@
+ -
+
+
+ DB-IP license text
+
+
+ true
+
+
+ true
+
+
+ Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse
+
+
+
-
diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp
index 04cadf491..a6e91fa9f 100644
--- a/src/gui/advancedsettings.cpp
+++ b/src/gui/advancedsettings.cpp
@@ -496,7 +496,7 @@ void AdvancedSettings::loadAdvancedSettings()
addRow(LIST_REFRESH, tr("Transfer list refresh interval"), &m_spinBoxListRefresh);
// Resolve Peer countries
m_checkBoxResolveCountries.setChecked(pref->resolvePeerCountries());
- addRow(RESOLVE_COUNTRIES, tr("Resolve peer countries (GeoIP)"), &m_checkBoxResolveCountries);
+ addRow(RESOLVE_COUNTRIES, tr("Resolve peer countries"), &m_checkBoxResolveCountries);
// Resolve peer hosts
m_checkBoxResolveHosts.setChecked(pref->resolvePeerHostNames());
addRow(RESOLVE_HOSTS, tr("Resolve peer host names"), &m_checkBoxResolveHosts);
diff --git a/src/webui/www/private/views/about.html b/src/webui/www/private/views/about.html
index b7455b6b7..55483857f 100644
--- a/src/webui/www/private/views/about.html
+++ b/src/webui/www/private/views/about.html
@@ -652,7 +652,7 @@
-
+
QBT_TR(qBittorrent was built with the following libraries:)QBT_TR[CONTEXT=AboutDialog]
+
QBT_TR(The free IP to Country Lite database by DB-IP is used for resolving the countries of peers. The database is licensed under the Creative Commons Attribution 4.0 International License)QBT_TR[CONTEXT=AboutDialog] (https://db-ip.com/ )
diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html
index 8f5e1cc8a..bafce04cb 100644
--- a/src/webui/www/private/views/preferences.html
+++ b/src/webui/www/private/views/preferences.html
@@ -868,7 +868,7 @@
- QBT_TR(Resolve peer countries (GeoIP):)QBT_TR[CONTEXT=OptionsDialog]
+ QBT_TR(Resolve peer countries:)QBT_TR[CONTEXT=OptionsDialog]