mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
20 Commits
8b28f3fd8e
...
240d9c7b03
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
240d9c7b03 | ||
|
|
e8f5efd156 | ||
|
|
57aa8b3de8 | ||
|
|
972b66f9a5 | ||
|
|
eadeea76e7 | ||
|
|
da7d3c55b0 | ||
|
|
60d3e4d963 | ||
|
|
adc230acde | ||
|
|
e4ba07a540 | ||
|
|
93ec5ac5c4 | ||
|
|
774c606b09 | ||
|
|
1bff42042d | ||
|
|
daeb177579 | ||
|
|
5d7a062f1b | ||
|
|
35f7bd5127 | ||
|
|
d411da451a | ||
|
|
45bab06f37 | ||
|
|
588855c6a7 | ||
|
|
c3fa0ae8cc | ||
|
|
32a70562c4 |
@@ -59,7 +59,7 @@ get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
|||||||
# function returns an empty string via _git_dir_var.
|
# function returns an empty string via _git_dir_var.
|
||||||
#
|
#
|
||||||
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
|
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
|
||||||
# neither foo nor bar contain a file/directory .git. This wil return
|
# neither foo nor bar contain a file/directory .git. This will return
|
||||||
# C:/bla/.git
|
# C:/bla/.git
|
||||||
#
|
#
|
||||||
function(_git_find_closest_git_dir _start_dir _git_dir_var)
|
function(_git_find_closest_git_dir _start_dir _git_dir_var)
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ namespace transport
|
|||||||
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
||||||
#endif
|
#endif
|
||||||
m_upnpUrlsInitialized=err!=0;
|
m_upnpUrlsInitialized=err!=0;
|
||||||
if (err == UPNP_IGD_VALID_CONNECTED)
|
if (err == UPNP_IGD_VALID_CONNECTED || err == UPNP_IGD_VALID_NOT_CONNECTED)
|
||||||
{
|
{
|
||||||
#if (MINIUPNPC_API_VERSION < 18)
|
#if (MINIUPNPC_API_VERSION < 18)
|
||||||
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
|
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ namespace config {
|
|||||||
"https://reseed.onion.im/,"
|
"https://reseed.onion.im/,"
|
||||||
"https://i2pseed.creativecowpat.net:8443/,"
|
"https://i2pseed.creativecowpat.net:8443/,"
|
||||||
"https://reseed.i2pgit.org/,"
|
"https://reseed.i2pgit.org/,"
|
||||||
"https://banana.incognet.io/,"
|
"https://coconut.incognet.io/,"
|
||||||
"https://reseed-pl.i2pd.xyz/,"
|
"https://reseed-pl.i2pd.xyz/,"
|
||||||
"https://www2.mk16.de/,"
|
"https://www2.mk16.de/,"
|
||||||
"https://i2p.ghativega.in/,"
|
"https://i2p.ghativega.in/,"
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ namespace data
|
|||||||
|
|
||||||
RouterProfile::RouterProfile ():
|
RouterProfile::RouterProfile ():
|
||||||
m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0),
|
m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0),
|
||||||
m_LastUpdateTime (i2p::util::GetSecondsSinceEpoch ()),
|
m_LastUpdateTime (i2p::util::GetSecondsSinceEpoch ()), m_LastAccessTime (0),
|
||||||
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
|
m_LastPersistTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0),
|
||||||
m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false),
|
m_NumTunnelsNonReplied (0),m_NumTimesTaken (0), m_NumTimesRejected (0),
|
||||||
m_IsDuplicated (false)
|
m_HasConnected (false), m_IsDuplicated (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +80,7 @@ namespace data
|
|||||||
|
|
||||||
void RouterProfile::Load (const IdentHash& identHash)
|
void RouterProfile::Load (const IdentHash& identHash)
|
||||||
{
|
{
|
||||||
|
m_IsUpdated = false;
|
||||||
std::string ident = identHash.ToBase64 ();
|
std::string ident = identHash.ToBase64 ();
|
||||||
std::string path = g_ProfilesStorage.Path(ident);
|
std::string path = g_ProfilesStorage.Path(ident);
|
||||||
boost::property_tree::ptree pt;
|
boost::property_tree::ptree pt;
|
||||||
@@ -257,7 +258,10 @@ namespace data
|
|||||||
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
||||||
auto it = g_Profiles.find (identHash);
|
auto it = g_Profiles.find (identHash);
|
||||||
if (it != g_Profiles.end ())
|
if (it != g_Profiles.end ())
|
||||||
|
{
|
||||||
|
it->second->SetLastAccessTime (i2p::util::GetSecondsSinceEpoch ());
|
||||||
return it->second;
|
return it->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto profile = netdb.NewRouterProfile ();
|
auto profile = netdb.NewRouterProfile ();
|
||||||
profile->Load (identHash); // if possible
|
profile->Load (identHash); // if possible
|
||||||
@@ -275,6 +279,15 @@ namespace data
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsRouterDuplicated (const IdentHash& identHash)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> l(g_ProfilesMutex);
|
||||||
|
auto it = g_Profiles.find (identHash);
|
||||||
|
if (it != g_Profiles.end ())
|
||||||
|
return it->second->IsDuplicated ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void InitProfilesStorage ()
|
void InitProfilesStorage ()
|
||||||
{
|
{
|
||||||
g_ProfilesStorage.SetPlace(i2p::fs::GetDataDir());
|
g_ProfilesStorage.SetPlace(i2p::fs::GetDataDir());
|
||||||
@@ -295,12 +308,14 @@ namespace data
|
|||||||
std::lock_guard<std::mutex> l(g_ProfilesMutex);
|
std::lock_guard<std::mutex> l(g_ProfilesMutex);
|
||||||
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
||||||
{
|
{
|
||||||
if (ts - it->second->GetLastUpdateTime () > PEER_PROFILE_PERSIST_INTERVAL)
|
if (it->second->IsUpdated () && ts > it->second->GetLastPersistTime () + PEER_PROFILE_PERSIST_INTERVAL)
|
||||||
{
|
{
|
||||||
if (it->second->IsUpdated ())
|
tmp.push_back (std::make_pair (it->first, it->second));
|
||||||
tmp.push_back (std::make_pair (it->first, it->second));
|
it->second->SetLastPersistTime (ts);
|
||||||
it = g_Profiles.erase (it);
|
it->second->SetUpdated (false);
|
||||||
}
|
}
|
||||||
|
if (!it->second->IsUpdated () && ts > std::max (it->second->GetLastUpdateTime (), it->second->GetLastAccessTime ()) + PEER_PROFILE_PERSIST_INTERVAL)
|
||||||
|
it = g_Profiles.erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,11 @@ namespace data
|
|||||||
|
|
||||||
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
|
||||||
bool IsUpdated () const { return m_IsUpdated; };
|
bool IsUpdated () const { return m_IsUpdated; };
|
||||||
|
void SetUpdated (bool updated) { m_IsUpdated = updated; }
|
||||||
|
uint64_t GetLastAccessTime () const { return m_LastAccessTime; };
|
||||||
|
void SetLastAccessTime (uint64_t ts) { m_LastAccessTime = ts; };
|
||||||
|
uint64_t GetLastPersistTime () const { return m_LastPersistTime; };
|
||||||
|
void SetLastPersistTime (uint64_t ts) { m_LastPersistTime = ts; };
|
||||||
|
|
||||||
bool IsUseful() const;
|
bool IsUseful() const;
|
||||||
bool IsDuplicated () const { return m_IsDuplicated; };
|
bool IsDuplicated () const { return m_IsDuplicated; };
|
||||||
@@ -91,7 +96,8 @@ namespace data
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsUpdated;
|
bool m_IsUpdated;
|
||||||
uint64_t m_LastDeclineTime, m_LastUnreachableTime, m_LastUpdateTime; // in seconds
|
uint64_t m_LastDeclineTime, m_LastUnreachableTime, m_LastUpdateTime,
|
||||||
|
m_LastAccessTime, m_LastPersistTime; // in seconds
|
||||||
// participation
|
// participation
|
||||||
uint32_t m_NumTunnelsAgreed;
|
uint32_t m_NumTunnelsAgreed;
|
||||||
uint32_t m_NumTunnelsDeclined;
|
uint32_t m_NumTunnelsDeclined;
|
||||||
@@ -107,6 +113,7 @@ namespace data
|
|||||||
|
|
||||||
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
|
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
|
||||||
bool IsRouterBanned (const IdentHash& identHash); // check only existing profiles
|
bool IsRouterBanned (const IdentHash& identHash); // check only existing profiles
|
||||||
|
bool IsRouterDuplicated (const IdentHash& identHash); // check only existing profiles
|
||||||
void InitProfilesStorage ();
|
void InitProfilesStorage ();
|
||||||
std::future<void> DeleteObsoleteProfiles ();
|
std::future<void> DeleteObsoleteProfiles ();
|
||||||
void SaveProfiles ();
|
void SaveProfiles ();
|
||||||
|
|||||||
@@ -33,13 +33,14 @@ namespace i2p
|
|||||||
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
||||||
m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone),
|
m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone),
|
||||||
m_Testing (false), m_TestingV6 (false), m_NetID (I2PD_NET_ID),
|
m_Testing (false), m_TestingV6 (false), m_NetID (I2PD_NET_ID),
|
||||||
m_PublishReplyToken (0), m_IsHiddenMode (false)
|
m_PublishReplyToken (0), m_IsHiddenMode (false),
|
||||||
|
m_Rng(i2p::util::GetMonotonicMicroseconds () % 1000000LL), m_IsSaving (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterContext::Init ()
|
void RouterContext::Init ()
|
||||||
{
|
{
|
||||||
srand (i2p::util::GetMillisecondsSinceEpoch () % 1000);
|
srand (m_Rng () % 1000);
|
||||||
m_StartupTime = i2p::util::GetMonotonicSeconds ();
|
m_StartupTime = i2p::util::GetMonotonicSeconds ();
|
||||||
|
|
||||||
if (!Load ())
|
if (!Load ())
|
||||||
@@ -253,11 +254,36 @@ namespace i2p
|
|||||||
|
|
||||||
void RouterContext::UpdateRouterInfo ()
|
void RouterContext::UpdateRouterInfo ()
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<i2p::data::RouterInfo::Buffer> buffer;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l(m_RouterInfoMutex);
|
std::lock_guard<std::mutex> l(m_RouterInfoMutex);
|
||||||
m_RouterInfo.CreateBuffer (m_Keys);
|
m_RouterInfo.CreateBuffer (m_Keys);
|
||||||
|
buffer = m_RouterInfo.CopyBuffer ();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// update save buffer to latest
|
||||||
|
std::lock_guard<std::mutex> l(m_SaveBufferMutex);
|
||||||
|
m_SaveBuffer = buffer;
|
||||||
|
}
|
||||||
|
bool isSaving = false;
|
||||||
|
if (m_IsSaving.compare_exchange_strong (isSaving, true)) // try to save only if not being saved
|
||||||
|
{
|
||||||
|
auto savingRouterInfo = std::async (std::launch::async, [this]()
|
||||||
|
{
|
||||||
|
std::shared_ptr<i2p::data::RouterInfo::Buffer> buffer;
|
||||||
|
while (m_SaveBuffer)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> l(m_SaveBufferMutex);
|
||||||
|
buffer = m_SaveBuffer;
|
||||||
|
m_SaveBuffer = nullptr;
|
||||||
|
}
|
||||||
|
if (buffer)
|
||||||
|
i2p::data::RouterInfo::SaveToFile (i2p::fs::DataDirPath (ROUTER_INFO), buffer);
|
||||||
|
}
|
||||||
|
m_IsSaving = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
m_RouterInfo.SaveToFile (i2p::fs::DataDirPath (ROUTER_INFO));
|
|
||||||
m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch ();
|
m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1359,7 +1385,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
m_PublishTimer->cancel ();
|
m_PublishTimer->cancel ();
|
||||||
m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_PUBLISH_INTERVAL +
|
m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_PUBLISH_INTERVAL +
|
||||||
rand () % ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE));
|
m_Rng () % ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE));
|
||||||
m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishTimer,
|
m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishTimer,
|
||||||
this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
@@ -1471,7 +1497,8 @@ namespace i2p
|
|||||||
if (m_CongestionUpdateTimer)
|
if (m_CongestionUpdateTimer)
|
||||||
{
|
{
|
||||||
m_CongestionUpdateTimer->cancel ();
|
m_CongestionUpdateTimer->cancel ();
|
||||||
m_CongestionUpdateTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONGESTION_UPDATE_INTERVAL));
|
m_CongestionUpdateTimer->expires_from_now (boost::posix_time::seconds(
|
||||||
|
ROUTER_INFO_CONGESTION_UPDATE_INTERVAL + m_Rng () % ROUTER_INFO_CONGESTION_UPDATE_INTERVAL_VARIANCE));
|
||||||
m_CongestionUpdateTimer->async_wait (std::bind (&RouterContext::HandleCongestionUpdateTimer,
|
m_CongestionUpdateTimer->async_wait (std::bind (&RouterContext::HandleCongestionUpdateTimer,
|
||||||
this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
@@ -36,7 +37,8 @@ namespace garlic
|
|||||||
const int ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE = 105;// in seconds
|
const int ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE = 105;// in seconds
|
||||||
const int ROUTER_INFO_CONFIRMATION_TIMEOUT = 1600; // in milliseconds
|
const int ROUTER_INFO_CONFIRMATION_TIMEOUT = 1600; // in milliseconds
|
||||||
const int ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15;
|
const int ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15;
|
||||||
const int ROUTER_INFO_CONGESTION_UPDATE_INTERVAL = 12*60; // in seconds
|
const int ROUTER_INFO_CONGESTION_UPDATE_INTERVAL = 11*60; // in seconds
|
||||||
|
const int ROUTER_INFO_CONGESTION_UPDATE_INTERVAL_VARIANCE = 130; // in seconds
|
||||||
const int ROUTER_INFO_CLEANUP_INTERVAL = 102; // in seconds
|
const int ROUTER_INFO_CLEANUP_INTERVAL = 102; // in seconds
|
||||||
|
|
||||||
enum RouterStatus
|
enum RouterStatus
|
||||||
@@ -263,6 +265,10 @@ namespace garlic
|
|||||||
uint32_t m_PublishReplyToken;
|
uint32_t m_PublishReplyToken;
|
||||||
bool m_IsHiddenMode; // not publish
|
bool m_IsHiddenMode; // not publish
|
||||||
mutable std::mutex m_RouterInfoMutex;
|
mutable std::mutex m_RouterInfoMutex;
|
||||||
|
std::mt19937 m_Rng;
|
||||||
|
std::shared_ptr<i2p::data::RouterInfo::Buffer> m_SaveBuffer;
|
||||||
|
std::mutex m_SaveBufferMutex; // TODO: make m_SaveBuffer atomic
|
||||||
|
std::atomic<bool> m_IsSaving;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RouterContext context;
|
extern RouterContext context;
|
||||||
|
|||||||
@@ -623,7 +623,8 @@ namespace transport
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t packetNum = SendData (it->second->payload, it->second->payloadSize);
|
uint32_t packetNum = SendData (it->second->payload, it->second->payloadSize,
|
||||||
|
it->second->numResends > 1 ? SSU2_FLAG_IMMEDIATE_ACK_REQUESTED : 0);
|
||||||
it->second->numResends++;
|
it->second->numResends++;
|
||||||
it->second->sendTime = ts;
|
it->second->sendTime = ts;
|
||||||
resentPackets.emplace (packetNum, it->second);
|
resentPackets.emplace (packetNum, it->second);
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
|
|
||||||
TransitTunnels::TransitTunnels ():
|
TransitTunnels::TransitTunnels ():
|
||||||
m_IsRunning (false)
|
m_IsRunning (false), m_Rng(i2p::util::GetMonotonicMicroseconds ()%1000000LL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,19 +328,44 @@ namespace tunnel
|
|||||||
// check if we accept this tunnel
|
// check if we accept this tunnel
|
||||||
std::shared_ptr<i2p::tunnel::TransitTunnel> transitTunnel;
|
std::shared_ptr<i2p::tunnel::TransitTunnel> transitTunnel;
|
||||||
uint8_t retCode = 0;
|
uint8_t retCode = 0;
|
||||||
if (!i2p::context.AcceptsTunnels () || i2p::context.GetCongestionLevel (false) >= CONGESTION_LEVEL_FULL)
|
if (i2p::context.AcceptsTunnels ())
|
||||||
|
{
|
||||||
|
auto congestionLevel = i2p::context.GetCongestionLevel (false);
|
||||||
|
if (congestionLevel < CONGESTION_LEVEL_FULL)
|
||||||
|
{
|
||||||
|
if (congestionLevel >= CONGESTION_LEVEL_MEDIUM)
|
||||||
|
{
|
||||||
|
// random reject depending on congestion level
|
||||||
|
int level = m_Rng () % (CONGESTION_LEVEL_FULL - CONGESTION_LEVEL_MEDIUM) + CONGESTION_LEVEL_MEDIUM;
|
||||||
|
if (congestionLevel > level)
|
||||||
|
retCode = 30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retCode = 30;
|
||||||
|
}
|
||||||
|
else
|
||||||
retCode = 30;
|
retCode = 30;
|
||||||
|
|
||||||
if (!retCode)
|
if (!retCode)
|
||||||
{
|
{
|
||||||
// create new transit tunnel
|
i2p::data::IdentHash nextIdent(clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET);
|
||||||
transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
bool isEndpoint = clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG;
|
||||||
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
if (isEndpoint || !i2p::data::IsRouterDuplicated (nextIdent))
|
||||||
clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
{
|
||||||
bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
// create new transit tunnel
|
||||||
layerKey, ivKey,
|
transitTunnel = CreateTransitTunnel (
|
||||||
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||||
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
|
nextIdent,
|
||||||
if (!AddTransitTunnel (transitTunnel))
|
bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
|
layerKey, ivKey,
|
||||||
|
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
||||||
|
isEndpoint);
|
||||||
|
if (!AddTransitTunnel (transitTunnel))
|
||||||
|
retCode = 30;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// decline tunnel going to duplicated router
|
||||||
retCode = 30;
|
retCode = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,7 +477,7 @@ namespace tunnel
|
|||||||
if (congestionLevel < CONGESTION_LEVEL_FULL)
|
if (congestionLevel < CONGESTION_LEVEL_FULL)
|
||||||
{
|
{
|
||||||
// random reject depending on congestion level
|
// random reject depending on congestion level
|
||||||
int level = i2p::tunnel::tunnels.GetRng ()() % (CONGESTION_LEVEL_FULL - CONGESTION_LEVEL_MEDIUM) + CONGESTION_LEVEL_MEDIUM;
|
int level = m_Rng () % (CONGESTION_LEVEL_FULL - CONGESTION_LEVEL_MEDIUM) + CONGESTION_LEVEL_MEDIUM;
|
||||||
if (congestionLevel > level)
|
if (congestionLevel > level)
|
||||||
accept = false;
|
accept = false;
|
||||||
}
|
}
|
||||||
@@ -460,23 +485,32 @@ namespace tunnel
|
|||||||
accept = false;
|
accept = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// replace record to reply
|
|
||||||
if (accept)
|
if (accept)
|
||||||
{
|
{
|
||||||
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
i2p::data::IdentHash nextIdent(clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET);
|
||||||
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
bool isEndpoint = clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG;
|
||||||
clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
if (isEndpoint || !i2p::data::IsRouterDuplicated (nextIdent))
|
||||||
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
{
|
||||||
clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
auto transitTunnel = CreateTransitTunnel (
|
||||||
clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||||
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
nextIdent,
|
||||||
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
|
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
if (!AddTransitTunnel (transitTunnel))
|
clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
||||||
|
clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
||||||
|
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
||||||
|
isEndpoint);
|
||||||
|
if (!AddTransitTunnel (transitTunnel))
|
||||||
|
retCode = 30;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// decline tunnel going to duplicated router
|
||||||
retCode = 30;
|
retCode = 30;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
retCode = 30; // always reject with bandwidth reason (30)
|
retCode = 30; // always reject with bandwidth reason (30)
|
||||||
|
|
||||||
|
// replace record to reply
|
||||||
memset (record + ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options
|
memset (record + ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options
|
||||||
record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode;
|
record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode;
|
||||||
// encrypt reply
|
// encrypt reply
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ namespace tunnel
|
|||||||
std::unique_ptr<std::thread> m_Thread;
|
std::unique_ptr<std::thread> m_Thread;
|
||||||
std::list<std::shared_ptr<TransitTunnel> > m_TransitTunnels;
|
std::list<std::shared_ptr<TransitTunnel> > m_TransitTunnels;
|
||||||
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_TunnelBuildMsgQueue;
|
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_TunnelBuildMsgQueue;
|
||||||
|
std::mt19937 m_Rng;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -1042,7 +1042,7 @@ namespace transport
|
|||||||
// if still testing or unknown, repeat peer test
|
// if still testing or unknown, repeat peer test
|
||||||
if (ipv4Testing || ipv6Testing)
|
if (ipv4Testing || ipv6Testing)
|
||||||
PeerTest (ipv4Testing, ipv6Testing);
|
PeerTest (ipv4Testing, ipv6Testing);
|
||||||
m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(3 * SESSION_CREATION_TIMEOUT));
|
m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(2 * SESSION_CREATION_TIMEOUT + m_Rng() % SESSION_CREATION_TIMEOUT));
|
||||||
m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
|
m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2024, The PurpleI2P Project
|
* Copyright (c) 2013-2025, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
* This file is part of Purple i2pd project and licensed under BSD3
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@@ -246,8 +246,6 @@ namespace tunnel
|
|||||||
uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; };
|
uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; };
|
||||||
int GetCongestionLevel() const { return m_MaxNumTransitTunnels ? CONGESTION_LEVEL_FULL * m_TransitTunnels.GetNumTransitTunnels () / m_MaxNumTransitTunnels : CONGESTION_LEVEL_FULL; }
|
int GetCongestionLevel() const { return m_MaxNumTransitTunnels ? CONGESTION_LEVEL_FULL * m_TransitTunnels.GetNumTransitTunnels () / m_MaxNumTransitTunnels : CONGESTION_LEVEL_FULL; }
|
||||||
|
|
||||||
std::mt19937& GetRng () { return m_Rng; };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<class TTunnel>
|
template<class TTunnel>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "Timestamp.h"
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
@@ -49,9 +50,10 @@ namespace client
|
|||||||
if (m_IsPersist)
|
if (m_IsPersist)
|
||||||
i2p::config::GetOption("addressbook.hostsfile", m_HostsFile);
|
i2p::config::GetOption("addressbook.hostsfile", m_HostsFile);
|
||||||
}
|
}
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const override;
|
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) override;
|
||||||
void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) override;
|
void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) override;
|
||||||
void RemoveAddress (const i2p::data::IdentHash& ident) override;
|
void RemoveAddress (const i2p::data::IdentHash& ident) override;
|
||||||
|
void CleanUpCache () override;
|
||||||
|
|
||||||
bool Init () override;
|
bool Init () override;
|
||||||
int Load (Addresses& addresses) override;
|
int Load (Addresses& addresses) override;
|
||||||
@@ -72,6 +74,8 @@ namespace client
|
|||||||
std::string etagsPath, indexPath, localPath;
|
std::string etagsPath, indexPath, localPath;
|
||||||
bool m_IsPersist;
|
bool m_IsPersist;
|
||||||
std::string m_HostsFile; // file to dump hosts.txt, empty if not used
|
std::string m_HostsFile; // file to dump hosts.txt, empty if not used
|
||||||
|
std::unordered_map<i2p::data::IdentHash, std::pair<std::vector<uint8_t>, uint64_t> > m_FullAddressCache; // ident hash -> (full ident buffer, last access timestamp)
|
||||||
|
std::mutex m_FullAddressCacheMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool AddressBookFilesystemStorage::Init()
|
bool AddressBookFilesystemStorage::Init()
|
||||||
@@ -92,8 +96,19 @@ namespace client
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident) const
|
std::shared_ptr<const i2p::data::IdentityEx> AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
|
auto ts = i2p::util::GetMonotonicSeconds ();
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> l(m_FullAddressCacheMutex);
|
||||||
|
auto it = m_FullAddressCache.find (ident);
|
||||||
|
if (it != m_FullAddressCache.end ())
|
||||||
|
{
|
||||||
|
it->second.second = ts;
|
||||||
|
return std::make_shared<i2p::data::IdentityEx>(it->second.first.data (), it->second.first.size ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_IsPersist)
|
if (!m_IsPersist)
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "Addressbook: Persistence is disabled");
|
LogPrint(eLogDebug, "Addressbook: Persistence is disabled");
|
||||||
@@ -101,43 +116,67 @@ namespace client
|
|||||||
}
|
}
|
||||||
std::string filename = storage.Path(ident.ToBase32());
|
std::string filename = storage.Path(ident.ToBase32());
|
||||||
std::ifstream f(filename, std::ifstream::binary);
|
std::ifstream f(filename, std::ifstream::binary);
|
||||||
if (!f.is_open ()) {
|
if (!f.is_open ())
|
||||||
|
{
|
||||||
LogPrint(eLogDebug, "Addressbook: Requested, but not found: ", filename);
|
LogPrint(eLogDebug, "Addressbook: Requested, but not found: ", filename);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
f.seekg (0,std::ios::end);
|
f.seekg (0,std::ios::end);
|
||||||
size_t len = f.tellg ();
|
size_t len = f.tellg ();
|
||||||
if (len < i2p::data::DEFAULT_IDENTITY_SIZE) {
|
if (len < i2p::data::DEFAULT_IDENTITY_SIZE)
|
||||||
|
{
|
||||||
LogPrint (eLogError, "Addressbook: File ", filename, " is too short: ", len);
|
LogPrint (eLogError, "Addressbook: File ", filename, " is too short: ", len);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
f.seekg(0, std::ios::beg);
|
f.seekg(0, std::ios::beg);
|
||||||
uint8_t * buf = new uint8_t[len];
|
std::vector<uint8_t> buf(len);
|
||||||
f.read((char *)buf, len);
|
f.read((char *)buf.data (), len);
|
||||||
auto address = std::make_shared<i2p::data::IdentityEx>(buf, len);
|
if (!f)
|
||||||
delete[] buf;
|
{
|
||||||
return address;
|
LogPrint (eLogError, "Addressbook: Couldn't read ", filename);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> l(m_FullAddressCacheMutex);
|
||||||
|
m_FullAddressCache.try_emplace (ident, buf, ts);
|
||||||
|
}
|
||||||
|
return std::make_shared<i2p::data::IdentityEx>(buf.data (), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookFilesystemStorage::AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address)
|
void AddressBookFilesystemStorage::AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address)
|
||||||
{
|
{
|
||||||
if (!m_IsPersist) return;
|
if (!address) return;
|
||||||
std::string path = storage.Path( address->GetIdentHash().ToBase32() );
|
|
||||||
std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
|
|
||||||
if (!f.is_open ()) {
|
|
||||||
LogPrint (eLogError, "Addressbook: Can't open file ", path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
size_t len = address->GetFullLen ();
|
size_t len = address->GetFullLen ();
|
||||||
uint8_t * buf = new uint8_t[len];
|
std::vector<uint8_t> buf;
|
||||||
address->ToBuffer (buf, len);
|
if (!len) return; // invalid address
|
||||||
f.write ((char *)buf, len);
|
{
|
||||||
delete[] buf;
|
std::lock_guard<std::mutex> l(m_FullAddressCacheMutex);
|
||||||
|
auto [it, inserted] = m_FullAddressCache.try_emplace (address->GetIdentHash(), len, i2p::util::GetMonotonicSeconds ());
|
||||||
|
if (inserted)
|
||||||
|
address->ToBuffer (it->second.first.data (), len);
|
||||||
|
if (m_IsPersist)
|
||||||
|
buf = it->second.first;
|
||||||
|
}
|
||||||
|
if (m_IsPersist && !buf.empty ())
|
||||||
|
{
|
||||||
|
std::string path = storage.Path(address->GetIdentHash().ToBase32());
|
||||||
|
std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
|
||||||
|
if (!f.is_open ())
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Addressbook: Can't open file ", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
f.write ((const char *)buf.data (), len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident)
|
void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> l(m_FullAddressCacheMutex);
|
||||||
|
m_FullAddressCache.erase (ident);
|
||||||
|
}
|
||||||
if (!m_IsPersist) return;
|
if (!m_IsPersist) return;
|
||||||
storage.Remove( ident.ToBase32() );
|
storage.Remove( ident.ToBase32() );
|
||||||
}
|
}
|
||||||
@@ -281,6 +320,19 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddressBookFilesystemStorage::CleanUpCache ()
|
||||||
|
{
|
||||||
|
auto ts = i2p::util::GetMonotonicSeconds ();
|
||||||
|
std::lock_guard<std::mutex> l(m_FullAddressCacheMutex);
|
||||||
|
for (auto it = m_FullAddressCache.begin (); it != m_FullAddressCache.end ();)
|
||||||
|
{
|
||||||
|
if (ts > it->second.second + ADDRESS_CACHE_EXPIRATION_TIMEOUT)
|
||||||
|
it = m_FullAddressCache.erase (it);
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
Address::Address (std::string_view b32):
|
Address::Address (std::string_view b32):
|
||||||
@@ -327,6 +379,7 @@ namespace client
|
|||||||
LoadHosts (); /* try storage, then hosts.txt, then download */
|
LoadHosts (); /* try storage, then hosts.txt, then download */
|
||||||
StartSubscriptions ();
|
StartSubscriptions ();
|
||||||
StartLookups ();
|
StartLookups ();
|
||||||
|
ScheduleCacheUpdate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,9 +394,14 @@ namespace client
|
|||||||
StopSubscriptions ();
|
StopSubscriptions ();
|
||||||
if (m_SubscriptionsUpdateTimer)
|
if (m_SubscriptionsUpdateTimer)
|
||||||
{
|
{
|
||||||
delete m_SubscriptionsUpdateTimer;
|
m_SubscriptionsUpdateTimer->cancel ();
|
||||||
m_SubscriptionsUpdateTimer = nullptr;
|
m_SubscriptionsUpdateTimer = nullptr;
|
||||||
}
|
}
|
||||||
|
if (m_AddressCacheUpdateTimer)
|
||||||
|
{
|
||||||
|
m_AddressCacheUpdateTimer->cancel ();
|
||||||
|
m_AddressCacheUpdateTimer = nullptr;
|
||||||
|
}
|
||||||
bool isDownloading = m_Downloading.valid ();
|
bool isDownloading = m_Downloading.valid ();
|
||||||
if (isDownloading)
|
if (isDownloading)
|
||||||
{
|
{
|
||||||
@@ -682,7 +740,7 @@ namespace client
|
|||||||
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
m_SubscriptionsUpdateTimer = new boost::asio::deadline_timer (dest->GetService ());
|
m_SubscriptionsUpdateTimer = std::make_unique<boost::asio::deadline_timer>(dest->GetService ());
|
||||||
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT));
|
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT));
|
||||||
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
|
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
|
||||||
this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
@@ -833,6 +891,29 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddressBook::ScheduleCacheUpdate ()
|
||||||
|
{
|
||||||
|
if (!m_AddressCacheUpdateTimer)
|
||||||
|
{
|
||||||
|
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
||||||
|
if(dest)
|
||||||
|
m_AddressCacheUpdateTimer = std::make_unique<boost::asio::deadline_timer>(dest->GetService ());
|
||||||
|
}
|
||||||
|
if (m_AddressCacheUpdateTimer)
|
||||||
|
{
|
||||||
|
m_AddressCacheUpdateTimer->expires_from_now (boost::posix_time::seconds(ADDRESS_CACHE_UPDATE_INTERVAL ));
|
||||||
|
m_AddressCacheUpdateTimer->async_wait (
|
||||||
|
[this](const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
if (m_Storage) m_Storage->CleanUpCache ();
|
||||||
|
ScheduleCacheUpdate ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AddressBookSubscription::AddressBookSubscription (AddressBook& book, std::string_view link):
|
AddressBookSubscription::AddressBookSubscription (AddressBook& book, std::string_view link):
|
||||||
m_Book (book), m_Link (link)
|
m_Book (book), m_Link (link)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ namespace client
|
|||||||
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
||||||
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
|
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
|
||||||
const int CONTINIOUS_SUBSCRIPTION_MAX_NUM_RETRIES = 10; // then update timeout
|
const int CONTINIOUS_SUBSCRIPTION_MAX_NUM_RETRIES = 10; // then update timeout
|
||||||
const int SUBSCRIPTION_REQUEST_TIMEOUT = 120; //in second
|
const int SUBSCRIPTION_REQUEST_TIMEOUT = 120; //in seconds
|
||||||
|
const int ADDRESS_CACHE_EXPIRATION_TIMEOUT = 710; // in seconds
|
||||||
|
const int ADDRESS_CACHE_UPDATE_INTERVAL = 76; // in seconds
|
||||||
|
|
||||||
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
|
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
|
||||||
const uint16_t ADDRESS_RESPONSE_DATAGRAM_PORT = 54;
|
const uint16_t ADDRESS_RESPONSE_DATAGRAM_PORT = 54;
|
||||||
@@ -62,9 +64,10 @@ namespace client
|
|||||||
typedef std::map<std::string, std::shared_ptr<Address>, std::less<> > Addresses;
|
typedef std::map<std::string, std::shared_ptr<Address>, std::less<> > Addresses;
|
||||||
|
|
||||||
virtual ~AddressBookStorage () {};
|
virtual ~AddressBookStorage () {};
|
||||||
virtual std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const = 0;
|
virtual std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) = 0;
|
||||||
virtual void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) = 0;
|
virtual void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) = 0;
|
||||||
virtual void RemoveAddress (const i2p::data::IdentHash& ident) = 0;
|
virtual void RemoveAddress (const i2p::data::IdentHash& ident) = 0;
|
||||||
|
virtual void CleanUpCache () = 0;
|
||||||
|
|
||||||
virtual bool Init () = 0;
|
virtual bool Init () = 0;
|
||||||
virtual int Load (Addresses& addresses) = 0;
|
virtual int Load (Addresses& addresses) = 0;
|
||||||
@@ -120,6 +123,8 @@ namespace client
|
|||||||
void StopLookups ();
|
void StopLookups ();
|
||||||
void HandleLookupResponse (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
void HandleLookupResponse (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
|
void ScheduleCacheUpdate ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::mutex m_AddressBookMutex;
|
std::mutex m_AddressBookMutex;
|
||||||
@@ -133,7 +138,7 @@ namespace client
|
|||||||
int m_NumRetries;
|
int m_NumRetries;
|
||||||
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
||||||
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||||
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
std::unique_ptr<boost::asio::deadline_timer> m_SubscriptionsUpdateTimer, m_AddressCacheUpdateTimer;
|
||||||
bool m_IsEnabled;
|
bool m_IsEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user