request next node after get_peers tiemout

This commit is contained in:
orignal committed 2026-10-05 21:04:15 -04:00
1 parent e002441fad
commit 8b9efd08c1
3 files changed
+60 -32

No files matched your search

+1 -1
View File
@@ -69,7 +69,7 @@ namespace torrents
constexpr uint16_t TORRENT_PORT = 6881; // not used by required by protocol
constexpr int MIN_TRACKER_REQUESTS_INTERVAL = 15*1000; // in milliseconds
constexpr int MAX_TRACKER_REQUESTS_INTERVAL = 24*3600*1000; // in milliseconds
constexpr int DHT_TORRENT_UPDATE_INTERVAL = 340; // in seconds
constexpr int DHT_TORRENT_UPDATE_INTERVAL = 440; // in seconds
constexpr int DHT_TORRENT_UPDATE_INTERVAL_VARIANCE = 70; // in seconds
constexpr int DHT_TORRENT_INITIAL_UPDATE_INTERVAL = 100; // in seconds
constexpr size_t PEER_CONNECTION_RECEIVE_BUFFER_SIZE = 65535;
+50 -28
View File
@@ -413,7 +413,8 @@ namespace torrents
TorrentsDHT::TorrentsDHT (TorrentsTunnel& tunnel, uint16_t port):
m_Tunnel (tunnel), m_DHTUpdateCheckTimer (tunnel.GetService ()),
m_DHTExpirationCheckTimer (tunnel.GetService ()),
m_DHTSendPingCheckTimer (tunnel.GetService ()), m_Port (port),
m_DHTSendPingCheckTimer (tunnel.GetService ()),
m_DHTQueryExpirationCheckTimer (tunnel.GetService ()), m_Port (port),
m_NextDHTExploratoryTime (i2p::util::GetMonotonicSeconds () + DHT_INITIAL_EXPLORATORY_INTERVAL)
{
auto dest = tunnel.GetLocalDestination ();
@@ -444,6 +445,7 @@ namespace torrents
ScheduleDHTUpdateCheck ();
ScheduleDHTExpirationCheck ();
ScheduleDHTSendPingCheck ();
ScheduleDHTQueryExpirationCheck ();
}
void TorrentsDHT::Stop ()
@@ -451,6 +453,7 @@ namespace torrents
m_DHTUpdateCheckTimer.cancel ();
m_DHTExpirationCheckTimer.cancel ();
m_DHTSendPingCheckTimer.cancel ();
m_DHTQueryExpirationCheckTimer.cancel ();
std::string filename ("nodest");
auto dest = m_Tunnel.GetLocalDestination ();
if (dest)
@@ -826,7 +829,7 @@ namespace torrents
}
case eKRPCQueryGetPeers:
{
LogPrint (eLogDebug, "TorrentsDHT: get_peers response received from peer ", ident.ToBase64 ());
LogPrint (eLogDebug, "TorrentsDHT: get_peers response received from peer ", ident.ToBase64 (), "after attempt #", info->numAttempts);
if (!values.empty () && values[0].empty ()) // nodes
HandleGetPeersResponseNode (info, nodeID, token, nodeInfo);
else //values
@@ -860,16 +863,7 @@ namespace torrents
{
info->AddNode (node);
info->token = token;
if (!info->IsDone () && m_RoutingTable)
{
auto nextNode = info->GetNextNode ();
if (nextNode)
SendGetPeersQuery (info, nextNode->peer, nextNode->port);
else
LogPrint (eLogDebug, "TorrentsDHT: No more nodes to send get_peers");
}
else
LogPrint (eLogDebug, "TorrentsDHT: Closest node not found after ", DHT_MAX_NUM_GET_PEERS_ATTEMPTS, " get_peers attempts");
SendNextGetPeersQuery (info);
}
}
@@ -970,6 +964,20 @@ namespace torrents
toIdent, toPort, false, info);
}
void TorrentsDHT::SendNextGetPeersQuery (std::shared_ptr<GetPeersRequestInfo> info)
{
if (!info) return;
if (!info->IsDone () && m_RoutingTable)
{
auto nextNode = info->GetNextNode ();
if (nextNode)
SendGetPeersQuery (info, nextNode->peer, nextNode->port);
else
LogPrint (eLogDebug, "TorrentsDHT: No more nodes to send get_peers");
}
else
LogPrint (eLogDebug, "TorrentsDHT: Closest node not found after ", DHT_MAX_NUM_GET_PEERS_ATTEMPTS, " get_peers attempts");
}
void TorrentsDHT::SendGetPeersResponse (std::string_view transactionID, std::shared_ptr<DHTTorrent> torrent,
uint64_t token, const i2p::data::IdentHash& toIdent, uint16_t toPort)
@@ -1107,16 +1115,6 @@ namespace torrents
it++;
}
}
{
auto it = m_Queries.begin ();
while (it != m_Queries.end ())
{
if (ts > std::get<4>(it->second) + DHT_QUERY_EXPIRATION_TIME)
it = m_Queries.erase (it);
else
it++;
}
}
ScheduleDHTExpirationCheck ();
}
}
@@ -1147,20 +1145,44 @@ namespace torrents
}
}
void TorrentsDHT::ScheduleDHTQueryExpirationCheck ()
{
m_DHTQueryExpirationCheckTimer.cancel ();
m_DHTQueryExpirationCheckTimer.expires_after (std::chrono::seconds (DHT_QUERY_EXPIRATION_CHECK_INTERVAL));
m_DHTQueryExpirationCheckTimer.async_wait (std::bind_front(&TorrentsDHT::DHTQueryExpirationCheckTimer, this));
}
void TorrentsDHT::DHTQueryExpirationCheckTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
auto ts = i2p::util::GetMonotonicSeconds ();
auto it = m_Queries.begin ();
while (it != m_Queries.end ())
{
if (ts > std::get<4>(it->second) + DHT_QUERY_EXPIRATION_TIME)
{
if (std::get<2>(it->second) == eKRPCQueryGetPeers)
SendNextGetPeersQuery (std::get<3>(it->second));
it = m_Queries.erase (it);
}
else
it++;
}
ScheduleDHTQueryExpirationCheck ();
}
}
void TorrentsDHT::GetPeersAndAnnounce (std::shared_ptr<Torrent> torrent)
{
if (!torrent || !m_RoutingTable) return;
auto request = std::make_shared<GetPeersRequestInfo>(torrent);
auto bucket = m_RoutingTable->FindBucket (torrent->GetInfoHash ());
if (!bucket || bucket->nodes.empty ()) return; // DHT is empty
// fill initial list of nodes to request from bucket
for (auto it: bucket->nodes)
request->AddNode (it.second);
if (!request->IsDone ())
{
auto queriedNode = request->GetNextNode ();
if (queriedNode)
SendGetPeersQuery (request, queriedNode->peer, queriedNode->port);
}
SendNextGetPeersQuery (request);
}
}
}
+9 -3
View File
@@ -41,6 +41,7 @@ namespace torrents
constexpr int DHT_UPDATE_CHECK_INTERVAL = 24; // in seconds
constexpr int DHT_EXPIRATION_CHECK_INTERVAL = 73; // in seconds
constexpr int DHT_SEND_PING_CHECK_INTERVAL = 38; // in seconds
constexpr int DHT_QUERY_EXPIRATION_CHECK_INTERVAL = 8; // in seconds
constexpr int DHT_EXPLORATORY_INTERVAL = 130; // in seconds
constexpr int DHT_EXPLORATORY_INTERVAL_VARIANCE = 40; // in seconds
constexpr int DHT_INITIAL_EXPLORATORY_INTERVAL = 90; // in seconds
@@ -51,7 +52,7 @@ namespace torrents
constexpr int DHT_TORRENT_PEER_EXPIRATION_TIME = 3*3600; // in seconds
constexpr int DHT_INCOMING_GET_PEERS_TOKEN_EXPIRATION_TIME = 600; // in seconds
constexpr int DHT_EMPTY_TORRENT_EXPIRATION_TIME = 30; // in seconds
constexpr int DHT_QUERY_EXPIRATION_TIME = 30; // in seconds
constexpr int DHT_QUERY_EXPIRATION_TIME = 20; // in seconds
constexpr int DHT_MAX_NUM_GET_PEERS_ATTEMPTS = 22;
using Distance = Torrent::InfoHash;
@@ -191,7 +192,7 @@ namespace torrents
int numAttempts;
GetPeersRequestInfo (std::shared_ptr<Torrent> t): torrent (t), token (0), numAttempts (0) { }
bool IsDone () const { return numAttempts >= DHT_MAX_NUM_GET_PEERS_ATTEMPTS || nodesToRequest.empty (); }
bool IsDone () const { return numAttempts >= DHT_MAX_NUM_GET_PEERS_ATTEMPTS; }
bool AddNode (std::shared_ptr<Node> node);
std::shared_ptr<Node> GetNextNode ();
};
@@ -237,6 +238,7 @@ namespace torrents
uint16_t toPort, bool isRaw = false, std::shared_ptr<GetPeersRequestInfo> info = nullptr);
void SendFindNodeQuery (const NodeID& target, const i2p::data::IdentHash& toIdent, uint16_t toPort);
void SendGetPeersQuery (std::shared_ptr<GetPeersRequestInfo> info, const i2p::data::IdentHash& toIdent, uint16_t toPort);
void SendNextGetPeersQuery (std::shared_ptr<GetPeersRequestInfo> info);
void SendResponseMsg (std::string_view response, std::string_view transactionID, const i2p::data::IdentHash& toIdent, uint16_t toPort);
void SendPingResponse (std::string_view transactionID, const i2p::data::IdentHash& toIdent, uint16_t toPort);
void SendGetPeersResponse (std::string_view transactionID, std::shared_ptr<DHTTorrent> torrent,
@@ -262,10 +264,14 @@ namespace torrents
void ScheduleDHTSendPingCheck ();
void HandleDHTSendPingCheckTimer (const boost::system::error_code& ecode);
void ScheduleDHTQueryExpirationCheck ();
void DHTQueryExpirationCheckTimer (const boost::system::error_code& ecode);
private:
TorrentsTunnel& m_Tunnel;
boost::asio::steady_timer m_DHTUpdateCheckTimer, m_DHTExpirationCheckTimer, m_DHTSendPingCheckTimer;
boost::asio::steady_timer m_DHTUpdateCheckTimer, m_DHTExpirationCheckTimer,
m_DHTSendPingCheckTimer, m_DHTQueryExpirationCheckTimer;
uint16_t m_Port;
NodeID m_NodeID;
std::unique_ptr<RoutingTable> m_RoutingTable;