only one peer connection with destination per torrent

This commit is contained in:
orignal
2026-09-12 11:03:33 -04:00
parent d5a6c93d3d
commit 95f251fdcb
2 changed files with 27 additions and 7 deletions
+25 -5
View File
@@ -915,9 +915,23 @@ namespace torrents
return eTorrentStatusDownloading;
}
void Torrent::AddConnection (std::shared_ptr<PeerConnection> conn)
bool Torrent::AddConnection (std::shared_ptr<PeerConnection> conn)
{
m_Connections.emplace_back (conn);
if (!conn) return false;
auto remoteIdentHash = conn->GetRemoteIdentHash ();
if (!remoteIdentHash) return false;
auto [it, inserted] = m_Connections.emplace (*remoteIdentHash, conn);
if (!inserted)
{
if (it->second.expired ())
{
m_Connections.erase (it); // delete not longer existing
return m_Connections.emplace (*remoteIdentHash, conn).second; // try again
}
else
return false;
}
return true;
}
std::list<std::shared_ptr<PeerConnection> > Torrent::GetConnections ()
@@ -926,7 +940,7 @@ namespace torrents
auto it = m_Connections.begin ();
while (it != m_Connections.end ())
{
auto conn = it->lock ();
auto conn = it->second.lock ();
if (conn)
{
ret.emplace_back (conn);
@@ -1262,7 +1276,7 @@ namespace torrents
size_t PeerConnection::HandleHandshakeMsg ()
{
LogPrint (eLogDebug, "Torrents: Handshake received");
if (m_ReceiveBufferOffset < HANDSHAKE_MSG_LENGTH) return 0;
if (!m_Stream || m_ReceiveBufferOffset < HANDSHAKE_MSG_LENGTH) return 0;
if (m_HandshakeReceiveTimer)
{
m_HandshakeReceiveTimer->cancel ();
@@ -1312,7 +1326,13 @@ namespace torrents
m_IsFast = true;
// established
m_IsEstablished = true;
m_Torrent->AddConnection (shared_from_this ());
if (!m_Torrent->AddConnection (shared_from_this ()))
{
LogPrint (eLogWarning, "Torrents: Connection with peer ",
i2p::data::GetIdentHashAbbreviation (m_Stream->GetRemoteIdentity ()->GetIdentHash ()), " already exists");
Terminate ();
return 0;
}
// send bitfield, have all or have none
auto [bitfield, empty] = m_Torrent->CreateBitfield ();
if (!empty)
+2 -2
View File
@@ -218,7 +218,7 @@ namespace torrents
bool UpdateStatus (uint64_t ts); // return true if complete
uint64_t GetNextUpdateStatusTime () { return m_NextUpdateStatusTime; }
void SetNextUpdateStatusTime (uint64_t nextUpdateStatusTime) { m_NextUpdateStatusTime = nextUpdateStatusTime; }
void AddConnection (std::shared_ptr<PeerConnection> conn);
bool AddConnection (std::shared_ptr<PeerConnection> conn);
std::list<std::shared_ptr<PeerConnection> > GetConnections ();
uint64_t GetNextTrackerRequestTime (size_t trackerID) const;
@@ -269,7 +269,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;
std::unordered_map<i2p::data::IdentHash, std::weak_ptr<PeerConnection> > m_Connections; // remote ident hash -> connection
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;