store and show tracker error

This commit is contained in:
orignal committed 2026-08-31 12:48:02 -04:00
1 parent 719812c926
commit aafaed4734
4 files changed
+49 -14

No files matched your search

+20 -8
View File
@@ -490,9 +490,8 @@ namespace torrents
void Torrent::ParseTrackerResponse (size_t trackerID, std::string_view buf)
{
if (trackerID >= m_TrackerStats.size ())
m_TrackerStats.resize (trackerID + 1, TrackerStats{{}, MIN_TRACKER_REQUESTS_INTERVAL,
0, 0, 0, i2p::util::GetSecondsSinceEpoch ()});
CheckTrackerStatsSize (trackerID);
std::get<6>(m_TrackerStats[trackerID]) = ""; // clear error
ParseDictionary (buf, [this, trackerID](std::string_view key, std::string_view buf)->size_t
{
if (key == "interval")
@@ -524,6 +523,7 @@ namespace torrents
{
auto [reason, l] = ExtractByteString (buf);
LogPrint (eLogError, "Torrents: Tracker error: ", reason);
std::get<6>(m_TrackerStats[trackerID]) = reason;
// double interval if tracker failure
int interval = std::max (MIN_TRACKER_REQUESTS_INTERVAL, std::get<1>(m_TrackerStats[trackerID])*2);
std::get<1>(m_TrackerStats[trackerID]) = interval;
@@ -551,10 +551,9 @@ namespace torrents
void Torrent::HandleDatagramTrackerResponse (size_t trackerID, uint32_t interval,
const uint8_t * hashes, size_t hashesLen, int numSeeders, int numLeechers)
{
if (trackerID >= m_TrackerStats.size ())
m_TrackerStats.resize (trackerID + 1, TrackerStats{{}, MIN_TRACKER_REQUESTS_INTERVAL,
0, 0, 0, i2p::util::GetSecondsSinceEpoch () });
auto& [peers, trackerRequestInterval, nextRequestTime, seeders, leechers, lastUpdateTime] = m_TrackerStats[trackerID];
CheckTrackerStatsSize (trackerID);
auto& [peers, trackerRequestInterval, nextRequestTime, seeders, leechers,
lastUpdateTime, error] = m_TrackerStats[trackerID];
trackerRequestInterval = interval*1000; // milliseconds
nextRequestTime = i2p::util::GetMonotonicMilliseconds () + trackerRequestInterval;
seeders = numSeeders;
@@ -571,6 +570,19 @@ namespace torrents
}
}
void Torrent::SetTrackerError (size_t trackerID, std::string_view error)
{
CheckTrackerStatsSize (trackerID);
std::get<6>(m_TrackerStats[trackerID]) = error;
}
void Torrent::CheckTrackerStatsSize (size_t trackerID)
{
if (trackerID >= m_TrackerStats.size ())
m_TrackerStats.resize (trackerID + 1, TrackerStats{{}, MIN_TRACKER_REQUESTS_INTERVAL,
0, 0, 0, i2p::util::GetSecondsSinceEpoch (), ""});
}
std::pair<std::vector<uint8_t>, bool> Torrent::CreateBitfield () const
{
size_t numPieces = m_Pieces.size ();
@@ -816,7 +828,7 @@ namespace torrents
{
if (trackerID >= m_TrackerStats.size ())
m_TrackerStats.resize (trackerID + 1, TrackerStats{{}, MIN_TRACKER_REQUESTS_INTERVAL,
0, 0, 0, i2p::util::GetSecondsSinceEpoch ()});
0, 0, 0, i2p::util::GetSecondsSinceEpoch (), ""});
std::get<2>(m_TrackerStats[trackerID]) = ts;
}
+6 -2
View File
@@ -146,9 +146,10 @@ namespace torrents
using RequestedBlock = std::tuple<uint32_t, uint32_t, uint32_t>; // (index, offset, len)
class Torrent final
{
using TrackerStats = std::tuple<std::unordered_set<i2p::data::IdentHash>, int, uint64_t, int, int, uint64_t>;
using TrackerStats = std::tuple<std::unordered_set<i2p::data::IdentHash>,
int, uint64_t, int, int, uint64_t, std::string>;
// (peers, interval, next tracker request time in monotonic milliseconds,
// seeders, leechers, last update time in seconds since epoch)
// seeders, leechers, last update time in seconds since epoch, error)
public:
using InfoHash = std::array<uint8_t, 20>;
@@ -214,6 +215,8 @@ namespace torrents
int GetNumLeechers (size_t trackerID) const { return (trackerID < m_TrackerStats.size ()) ? std::get<4>(m_TrackerStats[trackerID]) : 0; }
int GetNumPeers (size_t trackerID) const { return (trackerID < m_TrackerStats.size ()) ? std::get<0>(m_TrackerStats[trackerID]).size () : 0; }
uint64_t GetLastTrackerUpdateTime (size_t trackerID) const { return (trackerID < m_TrackerStats.size ()) ? std::get<5>(m_TrackerStats[trackerID]) : 0; }
std::string GetTrackerError (size_t trackerID) const { return (trackerID < m_TrackerStats.size ()) ? std::get<6>(m_TrackerStats[trackerID]) : ""; }
void SetTrackerError (size_t trackerID, std::string_view error);
private:
@@ -222,6 +225,7 @@ namespace torrents
size_t ParsePeers (size_t trackerID, std::string_view buf);
size_t ParseFiles (std::string_view buf);
static bool IsSafeName (std::string_view name); // a name from a torrent file before it becomes a path
void CheckTrackerStatsSize (size_t trackerID);
private:
+11 -2
View File
@@ -443,8 +443,17 @@ namespace torrents
tracker["seederCount"] = torrent->GetNumSeeders (i);
tracker["leecherCount"] = torrent->GetNumLeechers (i);
tracker["lastAnnouncePeerCount"] = torrent->GetNumPeers (i);
tracker["lastAnnounceResult"] = "Success"; // TODO:
tracker["lastAnnounceSucceeded"] = true; // TODO:
auto trackerError = torrent->GetTrackerError (i);
if (trackerError.empty ())
{
tracker["lastAnnounceResult"] = "Success";
tracker["lastAnnounceSucceeded"] = true;
}
else
{
tracker["lastAnnounceResult"] = trackerError;
tracker["lastAnnounceSucceeded"] = false;
}
tracker["lastAnnounceTimedOut"] = false; // TODO:
tracker["nextAnnounceTime"] = (torrent->GetNextTrackerRequestTime (i) -
i2p::util::GetMonotonicMilliseconds () + i2p::util::GetMillisecondsSinceEpoch ())/1000;
+12 -2
View File
@@ -834,8 +834,18 @@ namespace torrents
{
uint32_t transactionID = bufbe32toh (buf);
LogPrint (eLogDebug, "TorrentsTunnel: Datagram tracker action error response ", transactionID);
m_DatragramTrackerTransactions.erase (transactionID);
LogPrint (eLogInfo, "TorrentsTunnel: Datagram tracker error response: ", std::string_view ((const char *)(buf + 4), len - 4));
auto it = m_DatragramTrackerTransactions.find (transactionID);
if (it == m_DatragramTrackerTransactions.end ())
{
LogPrint (eLogInfo, "TorrentsTunnel: Datagram tracker transaction ", transactionID, " not found");
return;
}
std::string_view error ((const char *)(buf + 4), len - 4);
LogPrint (eLogInfo, "TorrentsTunnel: Datagram tracker error response: ", error);
auto [trackerID, fromPort, torrent, ts] = it->second;
if (!torrent.expired ()) // response to announce
torrent.lock ()->SetTrackerError (trackerID, error);
m_DatragramTrackerTransactions.erase (it);
}
void TorrentsTunnel::ConnectToDatagramTracker (size_t trackerID, std::string_view dest, uint16_t port)