maintain connections list per torrent

This commit is contained in:
orignal
2026-09-08 20:53:22 -04:00
parent 0a8a96e60b
commit 7d93ac0f02
5 changed files with 39 additions and 27 deletions
+29 -2
View File
@@ -725,6 +725,7 @@ namespace torrents
bool Torrent::UpdateStatus (uint64_t ts)
{
GetConnections (); // cleanup expired connections
if (!m_Length) return false; // non ready magnet
bool complete = true;
for (auto& it: m_Pieces)
@@ -902,6 +903,29 @@ namespace torrents
return eTorrentStatusDownloading;
}
void Torrent::AddConnection (std::shared_ptr<PeerConnection> conn)
{
m_Connections.emplace_back (conn);
}
std::list<std::shared_ptr<PeerConnection> > Torrent::GetConnections ()
{
std::list<std::shared_ptr<PeerConnection> > ret;
auto it = m_Connections.begin ();
while (it != m_Connections.end ())
{
auto conn = it->lock ();
if (conn)
{
ret.emplace_back (conn);
it++;
}
else
it = m_Connections.erase (it);
}
return ret;
}
PeerConnection::PeerConnection (std::shared_ptr<i2p::client::I2PService> owner,
std::shared_ptr<i2p::stream::Stream> stream): i2p::client::I2PServiceHandler (owner),
m_Stream (stream), m_ReceiveBufferOffset (0), m_NextMsgLength (0), m_MaxNumRequests (MIN_NUM_REQUESTS),
@@ -1268,6 +1292,9 @@ namespace torrents
// BEP6
if (m_ReceiveBuffer[20 + 7] & 0x04) // bit 61 of reserved
m_IsFast = true;
// established
m_IsEstablished = true;
m_Torrent->AddConnection (shared_from_this ());
// send bitfield, have all or have none
auto [bitfield, empty] = m_Torrent->CreateBitfield ();
if (!empty)
@@ -1279,7 +1306,7 @@ namespace torrents
}
else if (m_IsFast)
SendHaveNoneMsg ();
m_IsEstablished = true;
return HANDSHAKE_MSG_LENGTH;
}
@@ -1444,7 +1471,7 @@ namespace torrents
torrent->SaveTorrentResumeFile (resumeFilePath);
});
// send have
auto conns = GetTorrentsTunnel ()->GetTorrentConnections (m_Torrent);
auto conns = m_Torrent->GetConnections ();
for (auto it: conns)
it->SendHaveMsg (index);
}
+4
View File
@@ -161,6 +161,7 @@ namespace torrents
};
using RequestedBlock = std::tuple<uint32_t, uint32_t, uint32_t>; // (index, offset, len)
class PeerConnection;
class Torrent final
{
using TrackerStats = std::tuple<std::unordered_set<i2p::data::IdentHash>,
@@ -210,6 +211,8 @@ namespace torrents
std::vector<PieceFileFragment> GetPieceFileFragments (int index) const;
std::vector<size_t> GetFilesCompleted () const; // completed size per file
bool UpdateStatus (uint64_t ts); // return true if complete
void AddConnection (std::shared_ptr<PeerConnection> conn);
std::list<std::shared_ptr<PeerConnection> > GetConnections ();
uint64_t GetNextTrackerRequestTime (size_t trackerID) const;
void SetNextTrackerRequestTime (size_t trackerID, uint64_t ts);
@@ -259,6 +262,7 @@ namespace torrents
InfoHash m_InfoHash; // SHA1
std::vector<Piece> m_Pieces;
std::vector<TrackerStats> m_TrackerStats;
std::list<std::weak_ptr<PeerConnection> > m_Connections;
bool m_IsComplete, m_IsStopped;
std::list<std::pair<std::filesystem::path, size_t> > m_Files; // list of (path, length)
size_t m_Uploaded, m_Downloaded;
+4 -4
View File
@@ -370,9 +370,9 @@ namespace torrents
boost::json::array peers;
std::list<std::shared_ptr<PeerConnection> > conns;
boost::asio::post (m_Tunnel->GetService (),
boost::asio::use_future ([tunnel = m_Tunnel, torrent, &conns]()
boost::asio::use_future ([torrent, &conns]()
{
conns = tunnel->GetTorrentConnections (torrent);
conns = torrent->GetConnections ();
})).wait ();
for (const auto& it: conns)
{
@@ -410,9 +410,9 @@ namespace torrents
{
std::list<std::shared_ptr<PeerConnection> > conns;
boost::asio::post (m_Tunnel->GetService (),
boost::asio::use_future ([tunnel = m_Tunnel, torrent, &conns]()
boost::asio::use_future ([torrent, &conns]()
{
conns = tunnel->GetTorrentConnections (torrent);
conns = torrent->GetConnections ();
})).wait ();
return boost::json::value(conns.size ());
}
+2 -20
View File
@@ -277,7 +277,7 @@ namespace torrents
// inform trackers that we are done
RequestTorrentTrackers (torrent, eTrackerAnnounceEventCompleted);
// close connections with seeds and reset stats for remaining
auto conns = GetTorrentConnections (torrent);
auto conns = torrent->GetConnections ();
for (auto it: conns)
{
if (it->GetRemoteBitfield ().all ()) // seed
@@ -508,7 +508,7 @@ namespace torrents
// inform trackers that we stopped
RequestTorrentTrackers (torrent, eTrackerAnnounceEventStopped);
// close connections
auto connections = GetTorrentConnections (torrent);
auto connections = torrent->GetConnections ();
for (auto it: connections)
it->Close ();
}
@@ -827,24 +827,6 @@ namespace torrents
}
}
std::list<std::shared_ptr<PeerConnection> > TorrentsTunnel::GetTorrentConnections (std::shared_ptr<Torrent> torrent)
{
std::list<std::shared_ptr<PeerConnection> > ret;
if (torrent)
{
IterateHandlers ([&ret, torrent](std::shared_ptr<i2p::client::I2PServiceHandler> handler)
{
if (handler)
{
auto conn = std::static_pointer_cast<PeerConnection>(handler);
if (conn->GetTorrent () == torrent && conn->GetStream ())
ret.emplace_back (conn);
}
});
}
return ret;
}
std::unordered_set<i2p::data::IdentHash> TorrentsTunnel::GetNonConnectedPeers (std::shared_ptr<Torrent> torrent)
{
std::unordered_set<i2p::data::IdentHash> ret;
-1
View File
@@ -105,7 +105,6 @@ namespace torrents
bool RemoveTorrent (int id, bool deleteFiles);
bool StopTorrent (int id);
bool StartTorrent (int id);
std::list<std::shared_ptr<PeerConnection> > GetTorrentConnections (std::shared_ptr<Torrent> torrent);
const char* GetName() const override { return m_Name.c_str (); }