mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
in-meory storage for router profiles
This commit is contained in:
parent
86fc12e395
commit
48a3c767e5
|
@ -85,8 +85,7 @@ namespace data
|
||||||
if (m_IsRunning)
|
if (m_IsRunning)
|
||||||
{
|
{
|
||||||
if (m_PersistProfiles)
|
if (m_PersistProfiles)
|
||||||
for (auto& it: m_RouterInfos)
|
SaveProfiles ();
|
||||||
it.second->SaveProfile ();
|
|
||||||
DeleteObsoleteProfiles ();
|
DeleteObsoleteProfiles ();
|
||||||
m_RouterInfos.clear ();
|
m_RouterInfos.clear ();
|
||||||
m_Floodfills.clear ();
|
m_Floodfills.clear ();
|
||||||
|
@ -179,6 +178,7 @@ namespace data
|
||||||
if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) ||
|
if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) ||
|
||||||
ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup)
|
ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup)
|
||||||
{
|
{
|
||||||
|
if (m_PersistProfiles) PersistProfiles ();
|
||||||
DeleteObsoleteProfiles ();
|
DeleteObsoleteProfiles ();
|
||||||
lastProfilesCleanup = ts;
|
lastProfilesCleanup = ts;
|
||||||
profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE);
|
profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE);
|
||||||
|
@ -684,12 +684,12 @@ namespace data
|
||||||
for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();)
|
for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();)
|
||||||
{
|
{
|
||||||
if (it->second->IsUnreachable ())
|
if (it->second->IsUnreachable ())
|
||||||
{
|
|
||||||
if (m_PersistProfiles) it->second->SaveProfile ();
|
|
||||||
it = m_RouterInfos.erase (it);
|
it = m_RouterInfos.erase (it);
|
||||||
continue;
|
else
|
||||||
}
|
{
|
||||||
++it;
|
it->second->DropProfile ();
|
||||||
|
it++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// clean up expired floodfills or not floodfills anymore
|
// clean up expired floodfills or not floodfills anymore
|
||||||
|
@ -699,7 +699,7 @@ namespace data
|
||||||
if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ())
|
if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ())
|
||||||
it = m_Floodfills.erase (it);
|
it = m_Floodfills.erase (it);
|
||||||
else
|
else
|
||||||
++it;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unordered_map>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
@ -19,24 +20,26 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
i2p::fs::HashedStorage m_ProfilesStorage("peerProfiles", "p", "profile-", "txt");
|
static i2p::fs::HashedStorage g_ProfilesStorage("peerProfiles", "p", "profile-", "txt");
|
||||||
|
static std::unordered_map<i2p::data::IdentHash, std::shared_ptr<RouterProfile> > g_Profiles;
|
||||||
|
|
||||||
|
static boost::posix_time::ptime GetTime ()
|
||||||
|
{
|
||||||
|
return boost::posix_time::second_clock::local_time();
|
||||||
|
}
|
||||||
|
|
||||||
RouterProfile::RouterProfile ():
|
RouterProfile::RouterProfile ():
|
||||||
m_LastUpdateTime (boost::posix_time::second_clock::local_time()),
|
m_LastUpdateTime (GetTime ()), m_IsUpdated (false),
|
||||||
m_LastDeclineTime (0), m_LastUnreachableTime (0),
|
m_LastDeclineTime (0), m_LastUnreachableTime (0),
|
||||||
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
|
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
|
||||||
m_NumTimesTaken (0), m_NumTimesRejected (0)
|
m_NumTimesTaken (0), m_NumTimesRejected (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::posix_time::ptime RouterProfile::GetTime () const
|
|
||||||
{
|
|
||||||
return boost::posix_time::second_clock::local_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RouterProfile::UpdateTime ()
|
void RouterProfile::UpdateTime ()
|
||||||
{
|
{
|
||||||
m_LastUpdateTime = GetTime ();
|
m_LastUpdateTime = GetTime ();
|
||||||
|
m_IsUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterProfile::Save (const IdentHash& identHash)
|
void RouterProfile::Save (const IdentHash& identHash)
|
||||||
|
@ -59,7 +62,7 @@ namespace data
|
||||||
|
|
||||||
// save to file
|
// save to file
|
||||||
std::string ident = identHash.ToBase64 ();
|
std::string ident = identHash.ToBase64 ();
|
||||||
std::string path = m_ProfilesStorage.Path(ident);
|
std::string path = g_ProfilesStorage.Path(ident);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boost::property_tree::write_ini (path, pt);
|
boost::property_tree::write_ini (path, pt);
|
||||||
|
@ -72,7 +75,7 @@ namespace data
|
||||||
void RouterProfile::Load (const IdentHash& identHash)
|
void RouterProfile::Load (const IdentHash& identHash)
|
||||||
{
|
{
|
||||||
std::string ident = identHash.ToBase64 ();
|
std::string ident = identHash.ToBase64 ();
|
||||||
std::string path = m_ProfilesStorage.Path(ident);
|
std::string path = g_ProfilesStorage.Path(ident);
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
|
|
||||||
if (!i2p::fs::Exists(path))
|
if (!i2p::fs::Exists(path))
|
||||||
|
@ -158,6 +161,7 @@ namespace data
|
||||||
void RouterProfile::Unreachable ()
|
void RouterProfile::Unreachable ()
|
||||||
{
|
{
|
||||||
m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch ();
|
m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
|
UpdateTime ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterProfile::IsLowPartcipationRate () const
|
bool RouterProfile::IsLowPartcipationRate () const
|
||||||
|
@ -209,30 +213,68 @@ namespace data
|
||||||
|
|
||||||
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
|
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
|
||||||
{
|
{
|
||||||
|
auto it = g_Profiles.find (identHash);
|
||||||
|
if (it != g_Profiles.end ())
|
||||||
|
return it->second;
|
||||||
auto profile = std::make_shared<RouterProfile> ();
|
auto profile = std::make_shared<RouterProfile> ();
|
||||||
profile->Load (identHash); // if possible
|
profile->Load (identHash); // if possible
|
||||||
|
g_Profiles.emplace (identHash, profile);
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitProfilesStorage ()
|
void InitProfilesStorage ()
|
||||||
{
|
{
|
||||||
m_ProfilesStorage.SetPlace(i2p::fs::GetDataDir());
|
g_ProfilesStorage.SetPlace(i2p::fs::GetDataDir());
|
||||||
m_ProfilesStorage.Init(i2p::data::GetBase64SubstitutionTable(), 64);
|
g_ProfilesStorage.Init(i2p::data::GetBase64SubstitutionTable(), 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PersistProfiles ()
|
||||||
|
{
|
||||||
|
auto ts = GetTime ();
|
||||||
|
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
||||||
|
{
|
||||||
|
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL)
|
||||||
|
{
|
||||||
|
if (it->second->IsUpdated ())
|
||||||
|
it->second->Save (it->first);
|
||||||
|
it = g_Profiles.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveProfiles ()
|
||||||
|
{
|
||||||
|
auto ts = GetTime ();
|
||||||
|
for (auto it: g_Profiles)
|
||||||
|
if (it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
|
||||||
|
it.second->Save (it.first);
|
||||||
|
g_Profiles.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
void DeleteObsoleteProfiles ()
|
void DeleteObsoleteProfiles ()
|
||||||
{
|
{
|
||||||
|
auto ts = GetTime ();
|
||||||
|
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
||||||
|
{
|
||||||
|
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
|
||||||
|
it = g_Profiles.erase (it);
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
std::time_t now = std::time(nullptr);
|
std::time_t now = std::time(nullptr);
|
||||||
|
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
m_ProfilesStorage.Traverse(files);
|
g_ProfilesStorage.Traverse(files);
|
||||||
for (const auto& path: files) {
|
for (const auto& path: files) {
|
||||||
if (stat(path.c_str(), &st) != 0) {
|
if (stat(path.c_str(), &st) != 0) {
|
||||||
LogPrint(eLogWarning, "Profiling: Can't stat(): ", path);
|
LogPrint(eLogWarning, "Profiling: Can't stat(): ", path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (((now - st.st_mtime) / 3600) >= PEER_PROFILE_EXPIRATION_TIMEOUT) {
|
if (now - st.st_mtime >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) {
|
||||||
LogPrint(eLogDebug, "Profiling: Removing expired peer profile: ", path);
|
LogPrint(eLogDebug, "Profiling: Removing expired peer profile: ", path);
|
||||||
i2p::fs::Remove(path);
|
i2p::fs::Remove(path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,11 @@ namespace data
|
||||||
const char PEER_PROFILE_USAGE_TAKEN[] = "taken";
|
const char PEER_PROFILE_USAGE_TAKEN[] = "taken";
|
||||||
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
|
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
|
||||||
|
|
||||||
const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days)
|
const int PEER_PROFILE_EXPIRATION_TIMEOUT = 36; // in hours (1.5 days)
|
||||||
const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day)
|
const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 6 * 3600; // in seconds (6 hours)
|
||||||
const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours)
|
const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3600; // in seconds (1 hour)
|
||||||
const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes)
|
const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes)
|
||||||
|
const int PEER_PROFILE_PERSIST_INTERVAL = 3300; // in seconds (55 minutes)
|
||||||
const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours)
|
const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours)
|
||||||
|
|
||||||
class RouterProfile
|
class RouterProfile
|
||||||
|
@ -53,9 +54,11 @@ namespace data
|
||||||
|
|
||||||
void Unreachable ();
|
void Unreachable ();
|
||||||
|
|
||||||
|
boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; };
|
||||||
|
bool IsUpdated () const { return m_IsUpdated; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::posix_time::ptime GetTime () const;
|
|
||||||
void UpdateTime ();
|
void UpdateTime ();
|
||||||
|
|
||||||
bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; };
|
bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; };
|
||||||
|
@ -66,6 +69,7 @@ namespace data
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono
|
boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono
|
||||||
|
bool m_IsUpdated;
|
||||||
uint64_t m_LastDeclineTime, m_LastUnreachableTime; // in seconds
|
uint64_t m_LastDeclineTime, m_LastUnreachableTime; // in seconds
|
||||||
// participation
|
// participation
|
||||||
uint32_t m_NumTunnelsAgreed;
|
uint32_t m_NumTunnelsAgreed;
|
||||||
|
@ -79,6 +83,8 @@ namespace data
|
||||||
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
|
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
|
||||||
void InitProfilesStorage ();
|
void InitProfilesStorage ();
|
||||||
void DeleteObsoleteProfiles ();
|
void DeleteObsoleteProfiles ();
|
||||||
|
void SaveProfiles ();
|
||||||
|
void PersistProfiles ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,7 +251,7 @@ namespace data
|
||||||
bool SaveToFile (const std::string& fullPath);
|
bool SaveToFile (const std::string& fullPath);
|
||||||
|
|
||||||
std::shared_ptr<RouterProfile> GetProfile () const;
|
std::shared_ptr<RouterProfile> GetProfile () const;
|
||||||
void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
|
void DropProfile () { m_Profile = nullptr; };
|
||||||
|
|
||||||
void Update (const uint8_t * buf, size_t len);
|
void Update (const uint8_t * buf, size_t len);
|
||||||
void DeleteBuffer () { m_Buffer = nullptr; };
|
void DeleteBuffer () { m_Buffer = nullptr; };
|
||||||
|
|
Loading…
Reference in a new issue