From d72ae7a3dc4f3400c3b59f4b54eaa34f2ab1ad88 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 13 Sep 2026 11:33:03 -0400 Subject: [PATCH] remove peer from torrent on termination. Always run reconnect timer --- libi2pd_client/Torrents.cpp | 39 +++++++++++++++++++++++-------- libi2pd_client/Torrents.h | 2 ++ libi2pd_client/TorrentsTunnel.cpp | 16 +++++++++++-- libi2pd_client/TorrentsTunnel.h | 1 + 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index 686f9dda..d843bac2 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -899,13 +899,21 @@ namespace torrents std::unordered_set Torrent::GetNonConnectedPeers () { std::unordered_set ret; - for (const auto& it: m_TrackerStats) + for (size_t i = 0; i < m_TrackerStats.size (); i++) + ret.merge (GetNonConnectedPeers (i)); + return ret; + } + + std::unordered_set Torrent::GetNonConnectedPeers (size_t trackerID) + { + std::unordered_set ret; + if (trackerID < m_TrackerStats.size ()) { - const auto& peers = std::get<0>(it); - for (const auto& it1: peers) + const auto& peers = std::get<0>(m_TrackerStats[trackerID]); + for (const auto& it: peers) { - if (!IsConnectedToPeer (it1)) - ret.emplace (it1); + if (!IsConnectedToPeer (it)) + ret.emplace (it); } } return ret; @@ -951,6 +959,14 @@ namespace torrents return true; } + void Torrent::RemoveConnection (std::shared_ptr conn) + { + if (!conn) return; + auto remoteIdentHash = conn->GetRemoteIdentHash (); + if (!remoteIdentHash) return; + m_Connections.erase (*remoteIdentHash); + } + std::list > Torrent::GetConnections () { std::list > ret; @@ -1006,11 +1022,15 @@ namespace torrents void PeerConnection::Terminate () { if (Kill()) return; - if (m_Torrent && m_LastRequestedPieceIndex >= 0) // pending requests by us + if (m_Torrent) { - auto& piece = m_Torrent->GetPiece (m_LastRequestedPieceIndex); - if (piece.IsRequested ()) - piece.ClearAllRequests (); // piece can be requested by other connections + if (m_LastRequestedPieceIndex >= 0) // pending requests by us + { + auto& piece = m_Torrent->GetPiece (m_LastRequestedPieceIndex); + if (piece.IsRequested ()) + piece.ClearAllRequests (); // piece can be requested by other connections + } + m_Torrent->RemoveConnection (shared_from_this ()); } if (m_Stream) { @@ -1022,7 +1042,6 @@ namespace torrents m_HandshakeReceiveTimer->cancel (); m_HandshakeReceiveTimer = nullptr; } - Done(shared_from_this ()); } void PeerConnection::ResetStats () diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index f6c7abc3..347d36e1 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -213,6 +213,7 @@ namespace torrents std::pair, boost::logic::tribool> CreateBitfield () const; // (bitfield, true - all false - none) bool ApplyBitfield (const std::vector& bitfield); // return true if complete std::unordered_set GetNonConnectedPeers (); + std::unordered_set GetNonConnectedPeers (size_t trackerID); RequestedBlock GetNextBlockToRequest (std::shared_ptr conn, bool skipRequested = true); std::vector GetPieceFileFragments (int index) const; std::vector GetFilesCompleted () const; // completed size per file @@ -220,6 +221,7 @@ namespace torrents uint64_t GetNextUpdateStatusTime () { return m_NextUpdateStatusTime; } void SetNextUpdateStatusTime (uint64_t nextUpdateStatusTime) { m_NextUpdateStatusTime = nextUpdateStatusTime; } bool AddConnection (std::shared_ptr conn); + void RemoveConnection (std::shared_ptr conn); std::list > GetConnections (); bool IsConnectedToPeer (const i2p::data::IdentHash& peer); diff --git a/libi2pd_client/TorrentsTunnel.cpp b/libi2pd_client/TorrentsTunnel.cpp index e565a2c8..fd3042ec 100644 --- a/libi2pd_client/TorrentsTunnel.cpp +++ b/libi2pd_client/TorrentsTunnel.cpp @@ -66,6 +66,7 @@ namespace torrents } ScheduleTrackerRequestsCheck (); + ScheduleReconnectCheck (); ScheduleKeepAliveCheck (); ScheduleStatusUpdate (); } @@ -651,8 +652,7 @@ namespace torrents if (res->result () == boost::beast::http::status::ok) { torrent->ParseTrackerResponse (trackerID, res->body ()); - ConnectToPeers (torrent); - ScheduleReconnectCheck (); + ConnectToPeers (torrent, trackerID); } else LogPrint (eLogWarning, "TorrentsTunnel: Tracker ", trackerID, " response code ", res->result_int()); @@ -696,6 +696,18 @@ namespace torrents return peersToConnect.size (); } + size_t TorrentsTunnel::ConnectToPeers (std::shared_ptr torrent, size_t trackerID) + { + if (!torrent) return 0; + auto peersToConnect = torrent->GetNonConnectedPeers (trackerID); + if (!peersToConnect.empty ()) + { + for (const auto& it: peersToConnect) + ConnectToPeer (torrent, it); + } + return peersToConnect.size (); + } + void TorrentsTunnel::ConnectToNewPeers (std::shared_ptr torrent, std::unordered_set& newPeers) { if (!torrent) return; diff --git a/libi2pd_client/TorrentsTunnel.h b/libi2pd_client/TorrentsTunnel.h index 7cf0d067..69e93821 100644 --- a/libi2pd_client/TorrentsTunnel.h +++ b/libi2pd_client/TorrentsTunnel.h @@ -143,6 +143,7 @@ namespace torrents void ConnectToPeer (std::shared_ptr torrent, const i2p::data::IdentHash& peer); size_t ConnectToPeers (std::shared_ptr torrent); + size_t ConnectToPeers (std::shared_ptr torrent, size_t trackerID); void UpdatePeersPerPiece (std::shared_ptr torrent); void UpdateStats ();