From dfcb8a8043c0c689e5681c5ae5da89df5643347e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 14 Aug 2026 15:21:44 -0400 Subject: [PATCH] handle interested flag --- libi2pd_client/Torrents.cpp | 57 +++++++++++++++++++++++++++---------- libi2pd_client/Torrents.h | 4 ++- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index bee0efbe..ca46d426 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -596,6 +596,17 @@ namespace torrents } } + bool Torrent::HasIncompletePieces (const boost::dynamic_bitset<>& peerRemoteBitfield) const + { + size_t ind = peerRemoteBitfield.find_first(); + while (ind != boost::dynamic_bitset<>::npos) + { + if (!m_Pieces[ind].IsComplete ()) return true; + ind = peerRemoteBitfield.find_next(ind); + } + return false; + } + std::vector Torrent::GetPieceFileFragments (int index) const { if (index < 0 || index >= (int)m_Pieces.size ()) return {}; @@ -650,8 +661,8 @@ namespace torrents PeerConnection::PeerConnection (i2p::client::I2PService * owner, std::shared_ptr stream): i2p::client::I2PServiceHandler (owner), m_Stream (stream), m_ReceiveBufferOffset (0), m_IsHandshakeSent (false), m_IsEstablished (false), m_IsChoked (true), m_IsRemoteChoked (true), - m_LastReceiveTime (0), m_LastSendTime (0), m_NumRequests (0), m_NumPieces (0), - m_LastRequestedPieceIndex (-1) + m_IsInterested (false), m_IsRemoteInterested (false), m_LastReceiveTime (0), m_LastSendTime (0), + m_NumRequests (0), m_NumPieces (0), m_LastRequestedPieceIndex (-1) { } @@ -765,7 +776,19 @@ namespace torrents else if (ts > m_LastSendTime + PEER_KEEP_SEND_INTERVAL) { m_NumRequests = 0; // if we need to send keep-alive, all pending requests are invalid now - if (m_Torrent->IsComplete () || !RequestNextBlocks ()) // try to request if we still have blocks to request + bool requested = false; + if (!m_Torrent->IsComplete () && m_Torrent->HasIncompletePieces (m_RemoteBitfield)) + { + // try to request if we still have blocks to request + if (!m_IsChoked) + requested = RequestNextBlocks (); + else if (!m_IsInterested) + { + m_IsInterested = true; + SendInterestedMsg (); + } + } + if (!requested) { // send keep-alive uint32_t len = 0; @@ -884,6 +907,7 @@ namespace torrents RequestNextBlocks (); break; case eMessageTypeInterested: + m_IsRemoteInterested = true; if (m_IsRemoteChoked) { m_IsRemoteChoked = false; @@ -891,11 +915,7 @@ namespace torrents } break; case eMessageTypeNotInterested: - if (!m_IsRemoteChoked) - { - m_IsRemoteChoked = true; - SendChokeMsg (); - } + m_IsRemoteInterested = false; break; case eMessageTypeHave: HandleHaveMsg (m_ReceiveBuffer + offset + 1, msgLen - 1); @@ -988,9 +1008,12 @@ namespace torrents if (!piece.IsComplete ()) { // new piece - if (m_IsChoked) + if (!m_IsInterested) + { + m_IsInterested = true; SendInterestedMsg (); - else if (m_LastRequestedPieceIndex < 0) + } + if (m_LastRequestedPieceIndex < 0 && !m_IsChoked) RequestNextBlocks (); } } @@ -1012,7 +1035,7 @@ namespace torrents void PeerConnection::HandleBitfieldMsg (const uint8_t * buf, size_t len) { if (!m_Torrent) return; - bool isInterested = false; + m_IsInterested = false; size_t numPieces = m_Torrent->GetNumPieces (); m_RemoteBitfield.resize (numPieces); size_t idx = 0; @@ -1025,14 +1048,14 @@ namespace torrents if (buf[i] & bit) { m_RemoteBitfield.set (idx); - if (!isInterested && !m_Torrent->GetPiece (idx).IsComplete ()) - isInterested = true; + if (!m_IsInterested && !m_Torrent->GetPiece (idx).IsComplete ()) + m_IsInterested = true; } bit >>= 1; idx++; } } - if (isInterested) + if (m_IsInterested) SendInterestedMsg (); else if (m_RemoteBitfield.all ()) // remote is seeding Terminate (); // we don't need this connection @@ -1304,7 +1327,11 @@ namespace torrents else if (m_LastRequestedPieceIndex >= 0) { m_LastRequestedPieceIndex = -1; // no request - SendNotinterestedMsg (); + if (m_IsInterested) + { + m_IsInterested = false; + SendNotinterestedMsg (); + } } } return len > 0; diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index 421ab7c7..2fda2f40 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -181,6 +181,7 @@ namespace torrents void StartCountingPeers (); void ApplyPeerRemoteBitfield (const boost::dynamic_bitset<>& peerRemoteBitfield); + bool HasIncompletePieces (const boost::dynamic_bitset<>& peerRemoteBitfield) const; // if remote bitfie;d has incomplete pieces private: @@ -278,7 +279,8 @@ namespace torrents std::shared_ptr m_Torrent; std::string m_RemotePeerID; boost::dynamic_bitset<> m_RemoteBitfield; - bool m_IsHandshakeSent, m_IsEstablished, m_IsChoked, m_IsRemoteChoked; + bool m_IsHandshakeSent, m_IsEstablished, m_IsChoked, m_IsRemoteChoked, + m_IsInterested, m_IsRemoteInterested; uint64_t m_LastReceiveTime, m_LastSendTime; // monotonic seconds size_t m_NumRequests, m_NumPieces; // outgoing std::list m_IncomingRequestsQueue;