implement GetNonConnectedPeers. Reconnect timer

This commit is contained in:
orignal
2026-08-04 18:18:46 -04:00
parent 3ae36ee350
commit c39ce4d87c
2 changed files with 66 additions and 15 deletions
+57 -12
View File
@@ -367,14 +367,6 @@ namespace torrents
return len;
}
std::list<i2p::data::IdentHash> Torrent::GetNonConnectedPeers () const
{
std::list<i2p::data::IdentHash> nonConnectedPeers;
for (auto& it: m_Peers)
nonConnectedPeers.push_back (it);
return nonConnectedPeers;
}
std::pair<std::vector<uint8_t>, bool> Torrent::CreateBitfield () const
{
size_t numPieces = m_Pieces.size ();
@@ -878,7 +870,8 @@ namespace torrents
std::string_view torrentsDir, std::string_view trackers):
i2p::client::I2PService (localDestination), m_TorrentsDir (torrentsDir),
m_PeerID ("-I2PD-"), m_Rng(i2p::util::GetMonotonicMicroseconds ()%1000000LL),
m_TrackerRequestsCheckTimer (GetService ()), m_KeepAliveCheckTimer (GetService ())
m_TrackerRequestsCheckTimer (GetService ()), m_KeepAliveCheckTimer (GetService ()),
m_ReconnectCheckTimer (GetService ())
{
if (localDestination)
m_PeerID += localDestination->GetIdentHash ().ToBase64 ();
@@ -917,6 +910,7 @@ namespace torrents
{
m_TrackerRequestsCheckTimer.cancel ();
m_KeepAliveCheckTimer.cancel ();
m_ReconnectCheckTimer.cancel ();
m_Torrents.clear ();
for (auto it: m_Torrents)
boost::asio::post (m_DiskIOService.GetService (), std::bind (&TorrentsTunnel::SaveTorrentResumeFile, this, it.second));
@@ -1049,9 +1043,8 @@ namespace torrents
if (res->result () == boost::beast::http::status::ok)
{
torrent->ParseTrackerResponse (res->body ());
auto peersToConnect = torrent->GetNonConnectedPeers ();
for (const auto& it: peersToConnect)
ConnectToPeer (torrent, it);
ConnectToPeers (torrent);
ScheduleReconnectCheck ();
}
else
LogPrint (eLogWarning, "Torrents: Tracker response code ", res->result_int());
@@ -1078,6 +1071,17 @@ namespace torrents
}, std::make_shared<i2p::client::Address>(peer), TORRENT_PORT);
}
void TorrentsTunnel::ConnectToPeers (std::shared_ptr<Torrent> torrent)
{
if (!torrent) return;
auto peersToConnect = GetNonConnectedPeers (torrent);
if (!peersToConnect.empty ())
{
for (const auto& it: peersToConnect)
ConnectToPeer (torrent, it);
}
}
std::string TorrentsTunnel::GetTorrentFilePath (const std::string& filename) const
{
std::stringstream s("");
@@ -1129,6 +1133,24 @@ namespace torrents
}
}
void TorrentsTunnel::ScheduleReconnectCheck ()
{
m_ReconnectCheckTimer.cancel ();
m_ReconnectCheckTimer.expires_after (std::chrono::seconds(RECONNECT_CHECK_INTERVAL));
m_ReconnectCheckTimer.async_wait (std::bind (&TorrentsTunnel::HandleReconnectCheckTimer,
this, std::placeholders::_1));
}
void TorrentsTunnel::HandleReconnectCheckTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
for (auto it: m_Torrents)
ConnectToPeers (it.second);
ScheduleReconnectCheck ();
}
}
std::list<std::shared_ptr<PeerConnection> > TorrentsTunnel::GetTorrentConnections (std::shared_ptr<Torrent> torrent)
{
std::list<std::shared_ptr<PeerConnection> > ret;
@@ -1151,5 +1173,28 @@ namespace torrents
}
return ret;
}
std::list<i2p::data::IdentHash> TorrentsTunnel::GetNonConnectedPeers (std::shared_ptr<Torrent> torrent)
{
std::list<i2p::data::IdentHash> ret;
if (torrent)
{
ret = torrent->GetPeers ();
if(!ret.empty ())
{
IterateHandlers ([&ret](std::shared_ptr<i2p::client::I2PServiceHandler> handler)
{
if (handler)
{
auto conn = std::static_pointer_cast<PeerConnection>(handler);
auto ident = conn->GetStream ()->GetRemoteIdentity ();
if (ident)
std::remove (ret.begin (), ret.end (), ident->GetIdentHash ());
}
});
}
}
return ret;
}
}
}
+9 -3
View File
@@ -38,6 +38,7 @@ namespace torrents
constexpr uint16_t TORRENT_PORT = 6881; // not used by required by protocol
constexpr int TRACKER_RESPONSE_TIMEOUT = 8; // in seconds
constexpr int TRACKER_REQUESTS_CHECK_TIMEOUT = 1900; // in milliseconds
constexpr int RECONNECT_CHECK_INTERVAL = 70; // in seconds
constexpr int MIN_TRACKER_REQUESTS_INTERVAL = 15000; // in milliseconds
constexpr int TRACKER_REQUESTS_INTERVAL_VARIANCE = 3000; // in milliseconds
constexpr size_t PEER_CONNECTION_RECEIVE_BUFFER_SIZE = 65535;
@@ -124,7 +125,6 @@ namespace torrents
size_t GetNumPieces () const { return m_Pieces.size (); }
Piece& GetPiece (int index) { return m_Pieces[index]; }
std::pair<std::vector<uint8_t>, bool> CreateBitfield () const; // (bitfield, empty)
std::list<i2p::data::IdentHash> GetNonConnectedPeers () const;
const std::list<i2p::data::IdentHash>& GetPeers () const { return m_Peers; }
std::tuple<uint32_t, uint32_t, uint32_t> GetNextBlockToRequest (std::shared_ptr<PeerConnection> conn); // return (index, offset, len)
void ClearAllRequests ();
@@ -234,7 +234,6 @@ namespace torrents
const std::string& GetPeerID () const { return m_PeerID; }
std::string GetTorrentFilePath (const std::string& filename) const;
std::shared_ptr<Torrent> FindTorrent (const Torrent::InfoHash& infoHash) const;
void ConnectToPeer (std::shared_ptr<Torrent> torrent, const i2p::data::IdentHash& peer);
std::list<std::shared_ptr<PeerConnection> > GetTorrentConnections (std::shared_ptr<Torrent> torrent);
const char* GetName() const override { return "Torrents"; }
@@ -257,13 +256,20 @@ namespace torrents
void ScheduleKeepAliveCheck ();
void HandleKeepAliveCheckTimer (const boost::system::error_code& ecode);
void ScheduleReconnectCheck ();
void HandleReconnectCheckTimer (const boost::system::error_code& ecode);
std::list<i2p::data::IdentHash> GetNonConnectedPeers (std::shared_ptr<Torrent> torrent);
void ConnectToPeer (std::shared_ptr<Torrent> torrent, const i2p::data::IdentHash& peer);
void ConnectToPeers (std::shared_ptr<Torrent> torrent);
private:
std::string m_TorrentsDir, m_PeerID; // 20 characters
std::vector<std::string> m_Trackers;
std::map<Torrent::InfoHash, std::shared_ptr<Torrent> > m_Torrents;
std::mt19937 m_Rng;
boost::asio::steady_timer m_TrackerRequestsCheckTimer, m_KeepAliveCheckTimer;
boost::asio::steady_timer m_TrackerRequestsCheckTimer, m_KeepAliveCheckTimer, m_ReconnectCheckTimer;
DiskIOService m_DiskIOService;
};
}