mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-06 12:08:52 +00:00
maintain connections list per torrent
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 (); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user