handshake receive timeout

This commit is contained in:
orignal
2026-08-10 15:42:13 -04:00
parent 2333d39851
commit 4156005c49
2 changed files with 41 additions and 6 deletions
+38 -5
View File
@@ -604,9 +604,33 @@ namespace torrents
m_Stream->Close ();
m_Stream = nullptr;
}
if (m_HandshakeReceiveTimer)
{
m_HandshakeReceiveTimer->cancel ();
m_HandshakeReceiveTimer = nullptr;
}
Done(shared_from_this ());
}
void PeerConnection::ScheduleHandshakeReceiveTimer ()
{
if (m_HandshakeReceiveTimer)
m_HandshakeReceiveTimer->cancel ();
else
m_HandshakeReceiveTimer = std::make_unique<boost::asio::steady_timer>(GetTorrentsTunnel ()->GetService ());
m_HandshakeReceiveTimer->expires_after (std::chrono::seconds(HANDSHAKE_RECEIVE_TIMEOUT));
m_HandshakeReceiveTimer->async_wait ([s = shared_from_this ()](const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
LogPrint (eLogInfo, "Torrents: Handshake was not received after ", HANDSHAKE_RECEIVE_TIMEOUT, " seconds");
s->Terminate ();
}
else
s->m_HandshakeReceiveTimer = nullptr;
});
}
TorrentsTunnel * PeerConnection::GetTorrentsTunnel () const
{
return static_cast<TorrentsTunnel *>(GetOwner ());
@@ -632,6 +656,7 @@ namespace torrents
void PeerConnection::Connect ()
{
SendHandshakeMsg ();
ScheduleHandshakeReceiveTimer ();
StreamReceive ();
}
@@ -639,6 +664,7 @@ namespace torrents
{
LogPrint (eLogDebug, "Torrents: Incoming connection from ", m_Stream->GetRemoteIdentity () ?
(m_Stream->GetRemoteIdentity ()->GetIdentHash ().ToBase32 () + ".b32.i2p") : "");
ScheduleHandshakeReceiveTimer ();
StreamReceive ();
}
@@ -803,6 +829,11 @@ namespace torrents
{
LogPrint (eLogDebug, "Torrents: Handshake received");
if (m_ReceiveBufferOffset < HANDSHAKE_MSG_LENGTH) return 0;
if (m_HandshakeReceiveTimer)
{
m_HandshakeReceiveTimer->cancel ();
m_HandshakeReceiveTimer = nullptr;
}
if (m_ReceiveBuffer[0] != 19 || std::string_view ((const char *)(m_ReceiveBuffer + 1), 19) != "BitTorrent protocol")
{
LogPrint (eLogError, "Torrents: Unexpected handshake protocol string");
@@ -1151,9 +1182,9 @@ namespace torrents
TorrentsTunnel::TorrentsTunnel (std::string_view name, std::shared_ptr<i2p::client::ClientDestination> localDestination,
std::string_view torrentsDir, std::string_view trackers):
i2p::client::I2PService (localDestination), m_Name (name), m_TorrentsDir (torrentsDir),
m_PeerID ("-I2PD-"), m_Rng(i2p::util::GetMonotonicMicroseconds ()%1000000LL),
m_TrackerRequestsCheckTimer (GetService ()), m_KeepAliveCheckTimer (GetService ()),
m_ReconnectCheckTimer (GetService ()), m_TorrentsStatusUpdateTimer (GetService ())
m_PeerID ("-I2PD-"), m_TrackerRequestsCheckTimer (GetService ()),
m_KeepAliveCheckTimer (GetService ()), m_ReconnectCheckTimer (GetService ()),
m_TorrentsStatusUpdateTimer (GetService ())
{
if (localDestination)
m_PeerID += localDestination->GetIdentHash ().ToBase64 ();
@@ -1282,7 +1313,8 @@ namespace torrents
if (i2p::fs::Rename (partFilePath, filePath))
{
torrent->SetComplete ();
i2p::fs::Remove (resumeFilePath);
if (!i2p::fs::Remove (resumeFilePath))
LogPrint (eLogError, "Torrents: Can't delete resume file ", resumeFilePath);
LogPrint (eLogInfo, "Torrents: Download complete ", filePath);
}
else
@@ -1452,7 +1484,8 @@ namespace torrents
for (auto it: m_Torrents)
if (ts > it.second->GetNextTrackerRequestTime ())
{
it.second->SetNextTrackerRequestTime (ts + it.second->GetInterval () + m_Rng () % TRACKER_REQUESTS_INTERVAL_VARIANCE);
auto nextInterval = it.second->GetInterval () + GetLocalDestination ()->GetRng()() % TRACKER_REQUESTS_INTERVAL_VARIANCE;
it.second->SetNextTrackerRequestTime (ts + nextInterval);
RequestTracker (it.second);
}
ScheduleTrackerRequestsCheck ();
+3 -1
View File
@@ -50,6 +50,7 @@ namespace torrents
constexpr size_t MAX_NUM_PIECES = 6;
constexpr int PIECE_INACTIVITY_TIMEOUT = 60; // in seconds
constexpr int TORRENTS_STATUS_UPDATE_INTERVAL = 25; // in seconds
constexpr int HANDSHAKE_RECEIVE_TIMEOUT = 20; // in seconds
constexpr size_t HANDSHAKE_MSG_LENGTH = 68;
constexpr size_t INTERESTED_MSG_LENGTH = 5;
@@ -210,6 +211,7 @@ namespace torrents
private:
void Terminate ();
void ScheduleHandshakeReceiveTimer ();
TorrentsTunnel * GetTorrentsTunnel () const;
void WriteToStream (const uint8_t * buf, size_t len);
@@ -254,6 +256,7 @@ namespace torrents
size_t m_NumRequests, m_NumPieces; // outgoing
std::list<RequestedBlock> m_IncomingRequestsQueue;
int m_LastRequestedPieceIndex;
std::unique_ptr<boost::asio::steady_timer> m_HandshakeReceiveTimer;
};
class TorrentsTunnel final: public i2p::client::I2PService
@@ -319,7 +322,6 @@ namespace torrents
std::string m_Name, 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,
m_ReconnectCheckTimer, m_TorrentsStatusUpdateTimer;
DiskIOService m_DiskIOService;