From 9ab8203c8adae9b6065bb05f2a19d70c77d35a6b Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Wed, 23 Aug 2023 12:38:18 +0300 Subject: [PATCH] Don't overwrite tracker entry of unrelated protocol PR #19493. --- src/base/bittorrent/sessionimpl.cpp | 11 ++- src/base/bittorrent/sessionimpl.h | 6 +- src/base/bittorrent/torrentimpl.cpp | 100 +++++++++++++++------------- src/base/bittorrent/torrentimpl.h | 2 +- 4 files changed, 64 insertions(+), 55 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index bb2a0a6d4..aa67d6d61 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -5920,12 +5920,17 @@ void SessionImpl::handleTrackerAlert(const lt::tracker_alert *a) if (!torrent) return; - QHash &updateInfo = m_updatedTrackerEntries[torrent->nativeHandle()][std::string(a->tracker_url())]; + QMap &updateInfo = m_updatedTrackerEntries[torrent->nativeHandle()][std::string(a->tracker_url())][a->local_endpoint]; if (a->type() == lt::tracker_reply_alert::alert_type) { const int numPeers = static_cast(a)->num_peers; - updateInfo.insert(a->local_endpoint, numPeers); +#ifdef QBT_USES_LIBTORRENT2 + const int protocolVersionNum = (static_cast(a)->version == lt::protocol_version::V1) ? 1 : 2; +#else + const int protocolVersionNum = 1; +#endif + updateInfo.insert(protocolVersionNum, numPeers); } } @@ -6004,7 +6009,7 @@ void SessionImpl::processTrackerStatuses() if (updatedTrackersIter == updatedTrackers.end()) continue; - const QHash &updateInfo = updatedTrackersIter.value(); + const auto &updateInfo = updatedTrackersIter.value(); TrackerEntry trackerEntry = torrent->updateTrackerEntry(announceEntry, updateInfo); const QString url = trackerEntry.url; updatedTrackerEntries.emplace(url, std::move(trackerEntry)); diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 686abd054..bd6f730ca 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -40,13 +40,13 @@ #include #include #include +#include #include #include #include #include "base/path.h" #include "base/settingvalue.h" -#include "base/types.h" #include "base/utils/thread.h" #include "addtorrentparams.h" #include "cachestatus.h" @@ -745,8 +745,8 @@ namespace BitTorrent QSet m_tags; // This field holds amounts of peers reported by trackers in their responses to announces - // (torrent.tracker_name.tracker_local_endpoint.num_peers) - QHash>> m_updatedTrackerEntries; + // (torrent.tracker_name.tracker_local_endpoint.protocol_version.num_peers) + QHash>>> m_updatedTrackerEntries; // I/O errored torrents QSet m_recentErroredTorrents; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 47e99be5f..62a5811be 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -54,9 +54,9 @@ #include "base/global.h" #include "base/logger.h" #include "base/preferences.h" +#include "base/types.h" #include "base/utils/fs.h" #include "base/utils/io.h" -#include "base/utils/string.h" #include "common.h" #include "downloadpriority.h" #include "extensiondata.h" @@ -80,10 +80,10 @@ namespace #ifdef QBT_USES_LIBTORRENT2 void updateTrackerEntry(TrackerEntry &trackerEntry, const lt::announce_entry &nativeEntry - , const lt::info_hash_t &hashes, const QHash &updateInfo) + , const lt::info_hash_t &hashes, const QHash> &updateInfo) #else void updateTrackerEntry(TrackerEntry &trackerEntry, const lt::announce_entry &nativeEntry - , const QHash &updateInfo) + , const QHash> &updateInfo) #endif { Q_ASSERT(trackerEntry.url == QString::fromStdString(nativeEntry.url)); @@ -113,50 +113,52 @@ namespace for (const auto protocolVersion : {lt::protocol_version::V1, lt::protocol_version::V2}) { - if (hashes.has(protocolVersion)) + if (!hashes.has(protocolVersion)) + continue; + + const lt::announce_infohash &infoHash = endpoint.info_hashes[protocolVersion]; + + const int protocolVersionNum = (protocolVersion == lt::protocol_version::V1) ? 1 : 2; + const QMap &endpointUpdateInfo = updateInfo[endpoint.local_endpoint]; + TrackerEntry::EndpointStats &trackerEndpoint = trackerEntry.stats[endpoint.local_endpoint][protocolVersionNum]; + + trackerEndpoint.name = endpointName; + trackerEndpoint.numPeers = endpointUpdateInfo.value(protocolVersionNum, trackerEndpoint.numPeers); + trackerEndpoint.numSeeds = infoHash.scrape_complete; + trackerEndpoint.numLeeches = infoHash.scrape_incomplete; + trackerEndpoint.numDownloaded = infoHash.scrape_downloaded; + + if (infoHash.updating) { - const lt::announce_infohash &infoHash = endpoint.info_hashes[protocolVersion]; + trackerEndpoint.status = TrackerEntry::Updating; + ++numUpdating; + } + else if (infoHash.fails > 0) + { + trackerEndpoint.status = TrackerEntry::NotWorking; + ++numNotWorking; + } + else if (nativeEntry.verified) + { + trackerEndpoint.status = TrackerEntry::Working; + ++numWorking; + } + else + { + trackerEndpoint.status = TrackerEntry::NotContacted; + } - TrackerEntry::EndpointStats &trackerEndpoint = trackerEntry.stats[endpoint.local_endpoint][(protocolVersion == lt::protocol_version::V1) ? 1 : 2]; - - trackerEndpoint.name = endpointName; - trackerEndpoint.numPeers = updateInfo.value(endpoint.local_endpoint, trackerEndpoint.numPeers); - trackerEndpoint.numSeeds = infoHash.scrape_complete; - trackerEndpoint.numLeeches = infoHash.scrape_incomplete; - trackerEndpoint.numDownloaded = infoHash.scrape_downloaded; - - if (infoHash.updating) - { - trackerEndpoint.status = TrackerEntry::Updating; - ++numUpdating; - } - else if (infoHash.fails > 0) - { - trackerEndpoint.status = TrackerEntry::NotWorking; - ++numNotWorking; - } - else if (nativeEntry.verified) - { - trackerEndpoint.status = TrackerEntry::Working; - ++numWorking; - } - else - { - trackerEndpoint.status = TrackerEntry::NotContacted; - } - - if (!infoHash.message.empty()) - { - trackerEndpoint.message = QString::fromStdString(infoHash.message); - if (firstTrackerMessage.isEmpty()) - firstTrackerMessage = trackerEndpoint.message; - } - else if (infoHash.last_error) - { - trackerEndpoint.message = QString::fromLocal8Bit(infoHash.last_error.message()); - if (firstErrorMessage.isEmpty()) - firstErrorMessage = trackerEndpoint.message; - } + if (!infoHash.message.empty()) + { + trackerEndpoint.message = QString::fromStdString(infoHash.message); + if (firstTrackerMessage.isEmpty()) + firstTrackerMessage = trackerEndpoint.message; + } + else if (infoHash.last_error) + { + trackerEndpoint.message = QString::fromLocal8Bit(infoHash.last_error.message()); + if (firstErrorMessage.isEmpty()) + firstErrorMessage = trackerEndpoint.message; } } } @@ -164,10 +166,12 @@ namespace const auto numEndpoints = static_cast(nativeEntry.endpoints.size()); for (const lt::announce_endpoint &endpoint : nativeEntry.endpoints) { - TrackerEntry::EndpointStats &trackerEndpoint = trackerEntry.stats[endpoint.local_endpoint][1]; + const int protocolVersionNum = 1; + const QMap &endpointUpdateInfo = updateInfo[endpoint.local_endpoint]; + TrackerEntry::EndpointStats &trackerEndpoint = trackerEntry.stats[endpoint.local_endpoint][protocolVersionNum]; trackerEndpoint.name = QString::fromStdString((std::stringstream() << endpoint.local_endpoint).str()); - trackerEndpoint.numPeers = updateInfo.value(endpoint.local_endpoint, trackerEndpoint.numPeers); + trackerEndpoint.numPeers = endpointUpdateInfo.value(protocolVersionNum, trackerEndpoint.numPeers); trackerEndpoint.numSeeds = endpoint.scrape_complete; trackerEndpoint.numLeeches = endpoint.scrape_incomplete; trackerEndpoint.numDownloaded = endpoint.scrape_downloaded; @@ -1615,7 +1619,7 @@ void TorrentImpl::fileSearchFinished(const Path &savePath, const PathList &fileN endReceivedMetadataHandling(savePath, fileNames); } -TrackerEntry TorrentImpl::updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash &updateInfo) +TrackerEntry TorrentImpl::updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash> &updateInfo) { const auto it = std::find_if(m_trackerEntries.begin(), m_trackerEntries.end() , [&announceEntry](const TrackerEntry &trackerEntry) diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index f01a63e3e..fae5b94a6 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -264,7 +264,7 @@ namespace BitTorrent void saveResumeData(lt::resume_data_flags_t flags = {}); void handleMoveStorageJobFinished(const Path &path, MoveStorageContext context, bool hasOutstandingJob); void fileSearchFinished(const Path &savePath, const PathList &fileNames); - TrackerEntry updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash &updateInfo); + TrackerEntry updateTrackerEntry(const lt::announce_entry &announceEntry, const QHash > &updateInfo); private: using EventTrigger = std::function;