diff --git a/src/dbmanager.cpp b/src/dbmanager.cpp index 58c8638..f451625 100644 --- a/src/dbmanager.cpp +++ b/src/dbmanager.cpp @@ -84,7 +84,7 @@ TopDestinationList DBManager::totalTop() const TopDestinationList result; - if (not query.exec("SELECT * FROM total_history ORDER BY request_counter DESC LIMIT " + QString::number(g::c::LAST_AND_TOP_LIST_SIZE))) + if (not query.exec("SELECT * FROM total_history ORDER BY request_counter DESC LIMIT " + QString::number(g::p::LAST_AND_TOP_LIST_SIZE))) { qCritical() << "Db query failed:" << query.lastError().text(); } @@ -105,7 +105,7 @@ TopDestinationList DBManager::dailyTop() const TopDestinationList result; - if (not query.exec("SELECT * FROM daily_history ORDER BY request_counter DESC LIMIT " + QString::number(g::c::LAST_AND_TOP_LIST_SIZE))) + if (not query.exec("SELECT * FROM daily_history ORDER BY request_counter DESC LIMIT " + QString::number(g::p::LAST_AND_TOP_LIST_SIZE))) { qCritical() << "Db query failed:" << query.lastError().text(); } diff --git a/src/g.cpp b/src/g.cpp index 2e2b254..f2d8e46 100644 --- a/src/g.cpp +++ b/src/g.cpp @@ -33,7 +33,6 @@ namespace c { const QString SOFTWARE_NAME = "3proxy-eagle"; const QString SOFTWARE_VERSION = "0.0.1a"; const QString COPYRIGHT = "GPLv3 (c) acetone, 2022"; - const int LAST_AND_TOP_LIST_SIZE = 10; const qint64 DB_DAILY_TOP_TABLE_ACTUALIZE_MINIMAL_INTERVAL_MS = 300000; // 5 min const qint64 CACHE_ACTUALIZE_TOP_LISTS_FROM_DB_MINIMAL_INTERVAL_MS = 5000; // 5 sec const QString HA_PAGE_TITLE = "{{PAGE_TITLE}}"; @@ -60,6 +59,7 @@ namespace p { QString SERVICE_TITLE = "3proxy-eagle"; QString BIND_TO_ADDRESS = "127.0.0.1"; quint16 BIND_TO_PORT = 8161; + bool IGNORE_IP_ADDRS_IN_STATISTCS = false; } // namespace p std::list< std::pair > instanses; diff --git a/src/g.h b/src/g.h index bbcd7c9..9f9dd31 100644 --- a/src/g.h +++ b/src/g.h @@ -35,7 +35,6 @@ namespace c /* for Constants */ { extern const QString SOFTWARE_NAME; extern const QString SOFTWARE_VERSION; extern const QString COPYRIGHT; - extern const int LAST_AND_TOP_LIST_SIZE; extern const qint64 DB_DAILY_TOP_TABLE_ACTUALIZE_MINIMAL_INTERVAL_MS; extern const qint64 CACHE_ACTUALIZE_TOP_LISTS_FROM_DB_MINIMAL_INTERVAL_MS; extern const QString HA_PAGE_TITLE; @@ -56,11 +55,13 @@ namespace c /* for Constants */ { } // namespace c namespace p /* for Parameters */ { + extern uint LAST_AND_TOP_LIST_SIZE; extern QString WORKING_DIR; extern QStringList IGNORED_DESTINATIONS; extern QString SERVICE_TITLE; extern QString BIND_TO_ADDRESS; extern quint16 BIND_TO_PORT; + extern bool IGNORE_IP_ADDRS_IN_STATISTCS; } // namespace p extern std::list< std::pair > instanses; diff --git a/src/main.cpp b/src/main.cpp index 620f1e1..0d0dfc2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,13 +46,15 @@ void usage() << "Accumulate ethical 3proxy statistics with web interface\n\n" "U S A G E:\n" - " -i --instanse <3proxy>,<3proxy.cfg>\n" - " -w --working-directory \n" - " -t --service-title <3proxy-eagle>\n" - " -I --ignored-destinations <[0.0.0.0],127.0.0.1>\n" - " -a --bind-to-address <127.0.0.1>\n" - " -p --bind-to-port <8161>\n" - " -l --log-level (off, error, warn, info, debug)\n\n" + " -i --instanse <3proxy>,<3proxy.cfg>\n" + " -w --working-directory \n" + " -t --service-title <3proxy-eagle>\n" + " -I --ignored-destinations <[0.0.0.0],127.0.0.1>\n" + " -a --bind-to-address <127.0.0.1>\n" + " -p --bind-to-port <8161>\n" + " -l --log-level (off, error, warn, info, debug)\n" + " -s --top-lists-size <5>\n" + " -D --reject-ip-from-statistics\n\n" "N O T E S:\n" "* Multi instanses supported. Just pass new one --instanse value!\n" @@ -174,6 +176,23 @@ int main(int argc, char *argv[]) g::p::SERVICE_TITLE = value; } + else if ((key == "-s" or key == "--top-lists-size") and not value.isEmpty()) + { + bool ok = false; + value.toUInt(&ok); + if (not ok) + { + qWarning() << "--top-lists-size parsing failed, incorrect unsigned integer" << value; + continue; + } + g::p::LAST_AND_TOP_LIST_SIZE = value.toUInt(); + } + + else if (key == "-D" or key == "--reject-ip-from-statistics") + { + g::p::IGNORE_IP_ADDRS_IN_STATISTCS = true; + } + else if (key == "-h" or key == "--help") { usage(); @@ -203,6 +222,8 @@ int main(int argc, char *argv[]) qInfo().noquote() << "Instanses count:" << g::instanses.size(); qInfo().noquote() << "Working directory:" << g::p::WORKING_DIR; qInfo().noquote() << "Ignored destinations:" << g::p::IGNORED_DESTINATIONS; + qInfo().noquote() << "Top lists size:" << g::p::LAST_AND_TOP_LIST_SIZE; + qInfo() << "Reject IP addresses from statistics:" << g::p::IGNORE_IP_ADDRS_IN_STATISTCS; (new HttpServer)/*->killTheCapitalism()*/; diff --git a/src/statistics.cpp b/src/statistics.cpp index 62fabf4..7dbbb5e 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -21,11 +21,13 @@ along with this program. If not, see . #include "dbmanager.h" #include "g.h" +#include #include #include #include #include +QMutex Statistics::m_lastDestinationsMtx; QStringList Statistics::m_lastDestinations; std::atomic Statistics::m_dailyUpload {0}; @@ -33,6 +35,7 @@ std::atomic Statistics::m_dailyDownload {0}; std::atomic Statistics::m_totalUpload {0}; std::atomic Statistics::m_totalDownload {0}; +QMutex Statistics::m_topDestinationsMtx; TopDestinationList Statistics::m_dailyTopDestinations; TopDestinationList Statistics::m_totalTopDestinations; @@ -47,6 +50,23 @@ void Statistics::report(const LogEvent& event) return; } + m_lastDestinationsMtx.lock(); + if (not lastDestinations().contains(event.dest)) + { + if (lastDestinations().size() >= static_cast(g::p::LAST_AND_TOP_LIST_SIZE)) + { + m_lastDestinations.pop_back(); + } + m_lastDestinations.push_front(event.dest); + } + m_lastDestinationsMtx.unlock(); + + if (g::p::IGNORE_IP_ADDRS_IN_STATISTCS and isIpAddress(event.dest)) + { + qDebug() << event.dest << "rejected from statistics"; + return; + } + DBManager db; m_dailyDownload = db.incrementDailyDownloadTraffic(event.from); @@ -57,21 +77,12 @@ void Statistics::report(const LogEvent& event) db.incrementTotalTopCount(event.dest); db.incrementDailyTopCount(event.dest); - // editing without mutex because DBManager() already lock this place - if (not lastDestinations().contains(event.dest)) - { - if (lastDestinations().size() >= g::c::LAST_AND_TOP_LIST_SIZE) - { - m_lastDestinations.pop_back(); - } - m_lastDestinations.push_front(event.dest); - } - m_cacheUpdatedAfterLastReport = false; } const QStringList Statistics::lastDestinations() { + QMutexLocker lock (&m_lastDestinationsMtx); return m_lastDestinations; } @@ -81,18 +92,19 @@ const TopDestinationList Statistics::dailyTopDestinations() { actualizeTopLists(); } + QMutexLocker lock (&m_topDestinationsMtx); return m_dailyTopDestinations; } const TopDestinationList Statistics::totalTopDestinations() { + QMutexLocker lock (&m_topDestinationsMtx); return m_totalTopDestinations; } void Statistics::actualizeTopLists() { - static QMutex mutex; - QMutexLocker lock (&mutex); + QMutexLocker lock (&m_topDestinationsMtx); qint64 started = QDateTime::currentMSecsSinceEpoch(); if (started - m_actualizeTopListsLastTimestamp < g::c::CACHE_ACTUALIZE_TOP_LISTS_FROM_DB_MINIMAL_INTERVAL_MS) @@ -109,3 +121,20 @@ void Statistics::actualizeTopLists() m_actualizeTopListsLastTimestamp = QDateTime::currentMSecsSinceEpoch(); qDebug() << "Cache actualized in" << m_actualizeTopListsLastTimestamp-started << "ms"; } + +bool Statistics::isIpAddress(const QString& dest) +{ + static QRegularExpression ipv4("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$"); + if (ipv4.match(dest).hasMatch()) + { + return true; + } + + static QRegularExpression ipv6("^\\[[a-f0-9:]*\\]$"); + if (ipv6.match(dest).hasMatch()) + { + return true; + } + + return false; +} diff --git a/src/statistics.h b/src/statistics.h index a9a15d1..548e58e 100644 --- a/src/statistics.h +++ b/src/statistics.h @@ -22,6 +22,7 @@ along with this program. If not, see . #include "g.h" #include +#include struct LogEvent { @@ -49,7 +50,9 @@ public: private: static void actualizeTopLists(); + static bool isIpAddress(const QString& dest); + static QMutex m_lastDestinationsMtx; static QStringList m_lastDestinations; static bool m_cacheUpdatedAfterLastReport; @@ -60,6 +63,7 @@ private: static std::atomic m_totalUpload; static std::atomic m_totalDownload; + static QMutex m_topDestinationsMtx; static TopDestinationList m_dailyTopDestinations; static TopDestinationList m_totalTopDestinations; };