mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-05 14:29:13 +00:00
remove expired nodes from routing table
This commit is contained in:
@@ -153,6 +153,34 @@ namespace torrents
|
||||
}
|
||||
}
|
||||
|
||||
std::list<NodeID> RoutingTable::DeleteExpiredNodes ()
|
||||
{
|
||||
auto ts = i2p::util::GetMonotonicSeconds ();
|
||||
auto bucket = m_Buckets;
|
||||
std::list<NodeID> deleted;
|
||||
while (bucket)
|
||||
{
|
||||
if (ts > bucket->lastUpdateTime + DHT_BUCKET_EXPIRATION_THRESHOLD)
|
||||
{
|
||||
auto it = bucket->nodes.begin ();
|
||||
while (it != bucket->nodes.end ())
|
||||
{
|
||||
if (ts > it->second + DHT_NODE_EXPIRATION_TIME)
|
||||
{
|
||||
deleted.push_back (it->first);
|
||||
it = bucket->nodes.erase (it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
bucket = bucket->next;
|
||||
}
|
||||
if (!deleted.empty ())
|
||||
RemoveEmptyBuckets ();
|
||||
return deleted;
|
||||
}
|
||||
|
||||
bool RoutingTable::AddNode (const NodeID& id)
|
||||
{
|
||||
if (id == m_OurNode) return false;
|
||||
@@ -174,7 +202,11 @@ namespace torrents
|
||||
while (bucket->IsFull ());
|
||||
}
|
||||
if (bucket)
|
||||
bucket->nodes.emplace (id, i2p::util::GetMonotonicSeconds ());
|
||||
{
|
||||
auto ts = i2p::util::GetMonotonicSeconds ();
|
||||
bucket->nodes.emplace (id, ts);
|
||||
bucket->lastUpdateTime = ts;
|
||||
}
|
||||
RemoveEmptyBuckets ();
|
||||
return true;
|
||||
}
|
||||
@@ -268,7 +300,8 @@ namespace torrents
|
||||
}
|
||||
|
||||
TorrentsDHT::TorrentsDHT (TorrentsTunnel& tunnel, uint16_t port):
|
||||
m_Tunnel (tunnel), m_DHTUpdateCheckTimer (tunnel.GetService ()), m_Port (port),
|
||||
m_Tunnel (tunnel), m_DHTUpdateCheckTimer (tunnel.GetService ()),
|
||||
m_DHTExpirationCheckTimer (tunnel.GetService ()), m_Port (port),
|
||||
m_NextDHTExploratoryTime (i2p::util::GetMonotonicSeconds () + DHT_INITIAL_EXPLORATORY_INTERVAL)
|
||||
{
|
||||
auto dest = tunnel.GetLocalDestination ();
|
||||
@@ -297,11 +330,13 @@ namespace torrents
|
||||
}
|
||||
Load (GetDHTFilePath (filename));
|
||||
ScheduleDHTUpdateCheck ();
|
||||
ScheduleDHTExpirationCheck ();
|
||||
}
|
||||
|
||||
void TorrentsDHT::Stop ()
|
||||
{
|
||||
m_DHTUpdateCheckTimer.cancel ();
|
||||
m_DHTExpirationCheckTimer.cancel ();
|
||||
std::string filename ("nodest");
|
||||
auto dest = m_Tunnel.GetLocalDestination ();
|
||||
if (dest)
|
||||
@@ -698,8 +733,8 @@ namespace torrents
|
||||
{
|
||||
auto node = std::make_shared<Node>(nodeInfo);
|
||||
LogPrint (eLogDebug, "TorrentsDHT: find_node response received ", node->peer.ToBase64 ());
|
||||
if (m_Nodes.emplace (node->id, node).second && m_RoutingTable)
|
||||
m_RoutingTable->AddNode (node->id);
|
||||
m_Nodes.emplace (node->id, node);
|
||||
if (m_RoutingTable) m_RoutingTable->AddNode (node->id);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogInfo, "TorrentsDHT: Response to unknown query ", query);
|
||||
@@ -868,6 +903,27 @@ namespace torrents
|
||||
ScheduleDHTUpdateCheck ();
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentsDHT::ScheduleDHTExpirationCheck ()
|
||||
{
|
||||
m_DHTExpirationCheckTimer.cancel ();
|
||||
m_DHTExpirationCheckTimer.expires_after (std::chrono::seconds (DHT_EXPIRATION_CHECK_INTERVAL));
|
||||
m_DHTExpirationCheckTimer.async_wait (std::bind_front(&TorrentsDHT::HandleDHTExpirationCheckTimer, this));
|
||||
}
|
||||
|
||||
void TorrentsDHT::HandleDHTExpirationCheckTimer (const boost::system::error_code& ecode)
|
||||
{
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
{
|
||||
if (m_RoutingTable)
|
||||
{
|
||||
auto deleted = m_RoutingTable->DeleteExpiredNodes ();
|
||||
for (auto it: deleted)
|
||||
m_Nodes.erase (it);
|
||||
}
|
||||
ScheduleDHTExpirationCheck ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,9 +36,12 @@ namespace i2p
|
||||
namespace torrents
|
||||
{
|
||||
constexpr int DHT_UPDATE_CHECK_INTERVAL = 24; // in seconds
|
||||
constexpr int DHT_EXPIRATION_CHECK_INTERVAL = 73; // in seconds
|
||||
constexpr int DHT_EXPLORATORY_INTERVAL = 4*60; // in seconds
|
||||
constexpr int DHT_EXPLORATORY_INTERVAL_VARIANCE = 40; // in seconds
|
||||
constexpr int DHT_INITIAL_EXPLORATORY_INTERVAL = 90; // in seconds
|
||||
constexpr int DHT_NODE_EXPIRATION_TIME = 855; // in seconds
|
||||
constexpr int DHT_BUCKET_EXPIRATION_THRESHOLD = 290; // in seconds
|
||||
|
||||
using Distance = Torrent::InfoHash;
|
||||
struct NodeID: public Torrent::InfoHash
|
||||
@@ -87,6 +90,7 @@ namespace torrents
|
||||
Bucket * next;
|
||||
std::map<NodeID, uint64_t> nodes; // nodeID->update time in monotonic seconds
|
||||
NodeID start;
|
||||
uint64_t lastUpdateTime = 0; // monotonic seconds
|
||||
|
||||
Bucket (): next (nullptr), start{} {}
|
||||
Bucket (const NodeID& start1): next (nullptr), start (start1) {}
|
||||
@@ -112,6 +116,7 @@ namespace torrents
|
||||
std::optional<NodeID> FindClosestNode (const Torrent::InfoHash& infoHash) const;
|
||||
std::list<std::pair<NodeID, NodeID> > GetExploratoryTargets () const; // (target, node to send find_node to)
|
||||
NodeID FindClosestNodeInBucket (const NodeID& target) const;
|
||||
std::list<NodeID> DeleteExpiredNodes ();
|
||||
|
||||
private:
|
||||
|
||||
@@ -197,10 +202,13 @@ namespace torrents
|
||||
void ScheduleDHTUpdateCheck ();
|
||||
void HandleDHTUpdateCheckTimer (const boost::system::error_code& ecode);
|
||||
|
||||
void ScheduleDHTExpirationCheck ();
|
||||
void HandleDHTExpirationCheckTimer (const boost::system::error_code& ecode);
|
||||
|
||||
private:
|
||||
|
||||
TorrentsTunnel& m_Tunnel;
|
||||
boost::asio::steady_timer m_DHTUpdateCheckTimer;
|
||||
boost::asio::steady_timer m_DHTUpdateCheckTimer, m_DHTExpirationCheckTimer;
|
||||
uint16_t m_Port;
|
||||
NodeID m_NodeID;
|
||||
std::unique_ptr<RoutingTable> m_RoutingTable;
|
||||
|
||||
Reference in New Issue
Block a user