mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
29 Commits
8b28f3fd8e
...
build-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d0dad5fd4 | ||
|
|
b17087ba4a | ||
|
|
f466be3b5c | ||
|
|
24f167141d | ||
|
|
8a7c4040b6 | ||
|
|
ea279ef45a | ||
|
|
8aa18add4b | ||
|
|
5ff52e6c93 | ||
|
|
ef19a85fc0 | ||
|
|
2ce3145195 | ||
|
|
b8d74dab47 | ||
|
|
e8f5efd156 | ||
|
|
57aa8b3de8 | ||
|
|
972b66f9a5 | ||
|
|
eadeea76e7 | ||
|
|
da7d3c55b0 | ||
|
|
60d3e4d963 | ||
|
|
adc230acde | ||
|
|
e4ba07a540 | ||
|
|
93ec5ac5c4 | ||
|
|
774c606b09 | ||
|
|
1bff42042d | ||
|
|
daeb177579 | ||
|
|
5d7a062f1b | ||
|
|
35f7bd5127 | ||
|
|
d411da451a | ||
|
|
45bab06f37 | ||
|
|
588855c6a7 | ||
|
|
c3fa0ae8cc |
23
ChangeLog
23
ChangeLog
@@ -1,6 +1,29 @@
|
|||||||
# for this file format description,
|
# for this file format description,
|
||||||
# see https://github.com/olivierlacan/keep-a-changelog
|
# see https://github.com/olivierlacan/keep-a-changelog
|
||||||
|
|
||||||
|
## [2.56.0] - 2025-02-10
|
||||||
|
### Added
|
||||||
|
- Config params for shared local destination
|
||||||
|
- AddressBook full addresses cache
|
||||||
|
- Decline transit tunnel to duplicated router
|
||||||
|
- Recreate tunnels in random order
|
||||||
|
### Changed
|
||||||
|
- Exclude disk operations from SSU2 and NTCP2 threads
|
||||||
|
- Set minimal version for peer test to 0.9.62
|
||||||
|
- Send ack requested flag after second SSU2 resend attempt
|
||||||
|
- Shorter ECIESx25519 ack request interval for datagram and I2CP sessions
|
||||||
|
- Don't change datagram routing path too often if unidirectional data stream
|
||||||
|
- Reduce LeaseSet and local RouterInfo publishing confimation intervals
|
||||||
|
- Don't delete buffer of connected routers or if an update received
|
||||||
|
- Smaller RouterInfo request timeout if sent directly
|
||||||
|
- Persist local RouterInfo in separate thread
|
||||||
|
- Don't recalculate and process ranges for every SSU2 Ack block
|
||||||
|
- Reseeds list
|
||||||
|
### Fixed
|
||||||
|
- Termination deadlock if SAM session is active
|
||||||
|
- Race condition at tunnel endpoint
|
||||||
|
- Inbound tunnel build encryption
|
||||||
|
|
||||||
## [2.55.0] - 2024-12-30
|
## [2.55.0] - 2024-12-30
|
||||||
### Added
|
### Added
|
||||||
- Support boost 1.87
|
- Support boost 1.87
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misl
|
|||||||
DEFINES = -D_GLIBCXX_USE_NANOSLEEP=1
|
DEFINES = -D_GLIBCXX_USE_NANOSLEEP=1
|
||||||
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
||||||
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||||
LDLIBS = -lcrypto -lssl -lz -lpthread -lboost_system -lboost_program_options
|
LDLIBS = -lssl -lcrypto -lz -lpthread -lboost_system -lboost_program_options
|
||||||
|
|
||||||
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
|
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
|
||||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ CXX = g++
|
|||||||
CXXFLAGS := -Wall -std=c++17
|
CXXFLAGS := -Wall -std=c++17
|
||||||
INCFLAGS = -I/system/develop/headers
|
INCFLAGS = -I/system/develop/headers
|
||||||
DEFINES = -D_DEFAULT_SOURCE -D_GNU_SOURCE
|
DEFINES = -D_DEFAULT_SOURCE -D_GNU_SOURCE
|
||||||
LDLIBS = -lbe -lbsd -lnetwork -lz -lcrypto -lssl -lboost_system -lboost_program_options -lpthread
|
LDLIBS = -lbe -lbsd -lnetwork -lz -lssl -lcrypto -lboost_system -lboost_program_options -lpthread
|
||||||
|
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
DEFINES += -DUSE_UPNP
|
DEFINES += -DUSE_UPNP
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ endif
|
|||||||
LDLIBS += -lpthread -ldl
|
LDLIBS += -lpthread -ldl
|
||||||
else
|
else
|
||||||
LDFLAGS += -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
LDFLAGS += -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
||||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lz -lssl -lcrypto -lboost_system -lboost_filesystem -lboost_program_options -lpthread
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDFLAGS += -L${UPNPROOT}/lib
|
LDFLAGS += -L${UPNPROOT}/lib
|
||||||
LDLIBS += -lminiupnpc
|
LDLIBS += -lminiupnpc
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ ifeq ($(USE_UPNP),yes)
|
|||||||
endif
|
endif
|
||||||
LDLIBS += -lpthread -ldl
|
LDLIBS += -lpthread -ldl
|
||||||
else
|
else
|
||||||
LDLIBS += -lcrypto -lssl -lz -lboost_program_options -lpthread -latomic
|
LDLIBS += -lssl -lcrypto -lz -lboost_program_options -lpthread -latomic
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDLIBS += -lminiupnpc
|
LDLIBS += -lminiupnpc
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ LDFLAGS += -Wl,-dead_strip
|
|||||||
LDFLAGS += -Wl,-dead_strip_dylibs
|
LDFLAGS += -Wl,-dead_strip_dylibs
|
||||||
|
|
||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
LDLIBS = -lz /usr/local/lib/libssl.a /usr/local/lib/libcrypto.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
||||||
else
|
else
|
||||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lz -lssl -lcrypto -lboost_system -lboost_filesystem -lboost_program_options -lpthread
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ verify = true
|
|||||||
## Default: reg.i2p at "mainline" I2P Network
|
## Default: reg.i2p at "mainline" I2P Network
|
||||||
# defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt
|
# defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt
|
||||||
## Optional subscriptions URLs, separated by comma
|
## Optional subscriptions URLs, separated by comma
|
||||||
# subscriptions = http://reg.i2p/hosts.txt,http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
|
# subscriptions = http://reg.i2p/hosts.txt,http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt
|
||||||
|
|
||||||
[limits]
|
[limits]
|
||||||
## Maximum active transit sessions (default: 5000)
|
## Maximum active transit sessions (default: 5000)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
||||||
|
|
||||||
Name: i2pd-git
|
Name: i2pd-git
|
||||||
Version: 2.55.0
|
Version: 2.56.0
|
||||||
Release: git%{git_hash}%{?dist}
|
Release: git%{git_hash}%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd
|
Conflicts: i2pd
|
||||||
@@ -148,6 +148,9 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sun Feb 09 2025 orignal <orignal@i2pmail.org> - 2.56.0
|
||||||
|
- update to 2.56.0
|
||||||
|
|
||||||
* Mon Dec 30 2024 orignal <orignal@i2pmail.org> - 2.55.0
|
* Mon Dec 30 2024 orignal <orignal@i2pmail.org> - 2.55.0
|
||||||
- update to 2.55.0
|
- update to 2.55.0
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.55.0
|
Version: 2.56.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd-git
|
Conflicts: i2pd-git
|
||||||
@@ -146,6 +146,9 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sun Feb 09 2025 orignal <orignal@i2pmail.org> - 2.56.0
|
||||||
|
- update to 2.56.0
|
||||||
|
|
||||||
* Mon Dec 30 2024 orignal <orignal@i2pmail.org> - 2.55.0
|
* Mon Dec 30 2024 orignal <orignal@i2pmail.org> - 2.55.0
|
||||||
- update to 2.55.0
|
- update to 2.55.0
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ port = 6668
|
|||||||
destination = irc.ilita.i2p
|
destination = irc.ilita.i2p
|
||||||
destinationport = 6667
|
destinationport = 6667
|
||||||
keys = irc-keys.dat
|
keys = irc-keys.dat
|
||||||
|
i2p.streaming.profile=2
|
||||||
|
|
||||||
#[IRC-IRC2P]
|
#[IRC-IRC2P]
|
||||||
#type = client
|
#type = client
|
||||||
|
|||||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
|||||||
|
i2pd (2.56.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.56.0/0.9.65
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Sun, 09 Feb 2025 16:00:00 +0000
|
||||||
|
|
||||||
i2pd (2.55.0-1) unstable; urgency=medium
|
i2pd (2.55.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* updated to version 2.55.0
|
* updated to version 2.55.0
|
||||||
|
|||||||
@@ -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,8 +258,11 @@ 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
|
||||||
std::lock_guard<std::mutex> l(g_ProfilesMutex);
|
std::lock_guard<std::mutex> l(g_ProfilesMutex);
|
||||||
@@ -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 = g_Profiles.erase (it);
|
it->second->SetLastPersistTime (ts);
|
||||||
|
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,21 +328,46 @@ 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;
|
retCode = 30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retCode = 30;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retCode = 30;
|
||||||
|
|
||||||
if (!retCode)
|
if (!retCode)
|
||||||
|
{
|
||||||
|
i2p::data::IdentHash nextIdent(clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET);
|
||||||
|
bool isEndpoint = clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG;
|
||||||
|
if (isEndpoint || !i2p::data::IsRouterDuplicated (nextIdent))
|
||||||
{
|
{
|
||||||
// create new transit tunnel
|
// create new transit tunnel
|
||||||
transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
transitTunnel = CreateTransitTunnel (
|
||||||
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||||
clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
nextIdent,
|
||||||
bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
layerKey, ivKey,
|
layerKey, ivKey,
|
||||||
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
||||||
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
|
isEndpoint);
|
||||||
if (!AddTransitTunnel (transitTunnel))
|
if (!AddTransitTunnel (transitTunnel))
|
||||||
retCode = 30;
|
retCode = 30;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
// decline tunnel going to duplicated router
|
||||||
|
retCode = 30;
|
||||||
|
}
|
||||||
|
|
||||||
// encrypt reply
|
// encrypt reply
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
@@ -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);
|
||||||
|
bool isEndpoint = clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG;
|
||||||
|
if (isEndpoint || !i2p::data::IsRouterDuplicated (nextIdent))
|
||||||
|
{
|
||||||
|
auto transitTunnel = CreateTransitTunnel (
|
||||||
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||||
clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
nextIdent,
|
||||||
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
||||||
clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
||||||
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
|
||||||
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
|
isEndpoint);
|
||||||
if (!AddTransitTunnel (transitTunnel))
|
if (!AddTransitTunnel (transitTunnel))
|
||||||
retCode = 30;
|
retCode = 30;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
// decline tunnel going to duplicated router
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ namespace tunnel
|
|||||||
if (m_Config->IsShort ())
|
if (m_Config->IsShort ())
|
||||||
{
|
{
|
||||||
auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr;
|
auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr;
|
||||||
if (ident && ident->GetIdentHash () != outboundTunnel->GetNextIdentHash ()) // don't encrypt if IBGW = OBEP
|
if (ident && ident->GetIdentHash () != outboundTunnel->GetEndpointIdentHash ()) // don't encrypt if IBGW = OBEP
|
||||||
{
|
{
|
||||||
auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ());
|
auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ());
|
||||||
if (msg1) msg = msg1;
|
if (msg1) msg = msg1;
|
||||||
@@ -281,6 +281,21 @@ namespace tunnel
|
|||||||
m_Endpoint.HandleDecryptedTunnelDataMsg (msg);
|
m_Endpoint.HandleDecryptedTunnelDataMsg (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InboundTunnel::Recreate ()
|
||||||
|
{
|
||||||
|
if (!IsRecreated ())
|
||||||
|
{
|
||||||
|
auto pool = GetTunnelPool ();
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
SetRecreated (true);
|
||||||
|
pool->RecreateInboundTunnel (std::static_pointer_cast<InboundTunnel>(shared_from_this ()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
|
ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
|
||||||
InboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
InboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
||||||
m_NumReceivedBytes (0)
|
m_NumReceivedBytes (0)
|
||||||
@@ -331,6 +346,21 @@ namespace tunnel
|
|||||||
LogPrint (eLogError, "Tunnel: Incoming message for outbound tunnel ", GetTunnelID ());
|
LogPrint (eLogError, "Tunnel: Incoming message for outbound tunnel ", GetTunnelID ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OutboundTunnel::Recreate ()
|
||||||
|
{
|
||||||
|
if (!IsRecreated ())
|
||||||
|
{
|
||||||
|
auto pool = GetTunnelPool ();
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
SetRecreated (true);
|
||||||
|
pool->RecreateOutboundTunnel (std::static_pointer_cast<OutboundTunnel>(shared_from_this ()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel ():
|
ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel ():
|
||||||
OutboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
OutboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
|
||||||
m_NumSentBytes (0)
|
m_NumSentBytes (0)
|
||||||
@@ -437,7 +467,7 @@ namespace tunnel
|
|||||||
std::shared_ptr<OutboundTunnel> Tunnels::GetNextOutboundTunnel ()
|
std::shared_ptr<OutboundTunnel> Tunnels::GetNextOutboundTunnel ()
|
||||||
{
|
{
|
||||||
if (m_OutboundTunnels.empty ()) return nullptr;
|
if (m_OutboundTunnels.empty ()) return nullptr;
|
||||||
uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0;
|
uint32_t ind = m_Rng () % m_OutboundTunnels.size (), i = 0;
|
||||||
std::shared_ptr<OutboundTunnel> tunnel;
|
std::shared_ptr<OutboundTunnel> tunnel;
|
||||||
for (const auto& it: m_OutboundTunnels)
|
for (const auto& it: m_OutboundTunnels)
|
||||||
{
|
{
|
||||||
@@ -714,8 +744,17 @@ namespace tunnel
|
|||||||
void Tunnels::ManageTunnels (uint64_t ts)
|
void Tunnels::ManageTunnels (uint64_t ts)
|
||||||
{
|
{
|
||||||
ManagePendingTunnels (ts);
|
ManagePendingTunnels (ts);
|
||||||
ManageInboundTunnels (ts);
|
std::vector<std::shared_ptr<Tunnel> > tunnelsToRecreate;
|
||||||
ManageOutboundTunnels (ts);
|
ManageInboundTunnels (ts, tunnelsToRecreate);
|
||||||
|
ManageOutboundTunnels (ts, tunnelsToRecreate);
|
||||||
|
// rec-create in random order
|
||||||
|
if (!tunnelsToRecreate.empty ())
|
||||||
|
{
|
||||||
|
if (tunnelsToRecreate.size () > 1)
|
||||||
|
std::shuffle (tunnelsToRecreate.begin(), tunnelsToRecreate.end(), m_Rng);
|
||||||
|
for (auto& it: tunnelsToRecreate)
|
||||||
|
it->Recreate ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tunnels::ManagePendingTunnels (uint64_t ts)
|
void Tunnels::ManagePendingTunnels (uint64_t ts)
|
||||||
@@ -778,7 +817,7 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tunnels::ManageOutboundTunnels (uint64_t ts)
|
void Tunnels::ManageOutboundTunnels (uint64_t ts, std::vector<std::shared_ptr<Tunnel> >& toRecreate)
|
||||||
{
|
{
|
||||||
for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();)
|
for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();)
|
||||||
{
|
{
|
||||||
@@ -802,10 +841,7 @@ namespace tunnel
|
|||||||
auto pool = tunnel->GetTunnelPool ();
|
auto pool = tunnel->GetTunnelPool ();
|
||||||
// let it die if the tunnel pool has been reconfigured and this is old
|
// let it die if the tunnel pool has been reconfigured and this is old
|
||||||
if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops())
|
if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops())
|
||||||
{
|
toRecreate.push_back (tunnel);
|
||||||
tunnel->SetRecreated (true);
|
|
||||||
pool->RecreateOutboundTunnel (tunnel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
tunnel->SetState (eTunnelStateExpiring);
|
tunnel->SetState (eTunnelStateExpiring);
|
||||||
@@ -830,7 +866,7 @@ namespace tunnel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tunnels::ManageInboundTunnels (uint64_t ts)
|
void Tunnels::ManageInboundTunnels (uint64_t ts, std::vector<std::shared_ptr<Tunnel> >& toRecreate)
|
||||||
{
|
{
|
||||||
for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();)
|
for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();)
|
||||||
{
|
{
|
||||||
@@ -854,10 +890,7 @@ namespace tunnel
|
|||||||
auto pool = tunnel->GetTunnelPool ();
|
auto pool = tunnel->GetTunnelPool ();
|
||||||
// let it die if the tunnel pool was reconfigured and has different number of hops
|
// let it die if the tunnel pool was reconfigured and has different number of hops
|
||||||
if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops())
|
if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops())
|
||||||
{
|
toRecreate.push_back (tunnel);
|
||||||
tunnel->SetRecreated (true);
|
|
||||||
pool->RecreateInboundTunnel (tunnel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
@@ -99,6 +99,7 @@ namespace tunnel
|
|||||||
void SetRecreated (bool recreated) { m_IsRecreated = recreated; };
|
void SetRecreated (bool recreated) { m_IsRecreated = recreated; };
|
||||||
int GetNumHops () const { return m_Hops.size (); };
|
int GetNumHops () const { return m_Hops.size (); };
|
||||||
virtual bool IsInbound() const = 0;
|
virtual bool IsInbound() const = 0;
|
||||||
|
virtual bool Recreate () = 0;
|
||||||
|
|
||||||
std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
|
std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
|
||||||
void SetTunnelPool (std::shared_ptr<TunnelPool> pool) { m_Pool = pool; };
|
void SetTunnelPool (std::shared_ptr<TunnelPool> pool) { m_Pool = pool; };
|
||||||
@@ -150,6 +151,7 @@ namespace tunnel
|
|||||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||||
|
|
||||||
bool IsInbound() const override { return false; }
|
bool IsInbound() const override { return false; }
|
||||||
|
bool Recreate () override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -166,6 +168,7 @@ namespace tunnel
|
|||||||
void HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg) override;
|
void HandleTunnelDataMsg (std::shared_ptr<I2NPMessage>&& msg) override;
|
||||||
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
||||||
bool IsInbound() const override { return true; }
|
bool IsInbound() const override { return true; }
|
||||||
|
bool Recreate () override;
|
||||||
|
|
||||||
// override TunnelBase
|
// override TunnelBase
|
||||||
void Cleanup () override { m_Endpoint.Cleanup (); };
|
void Cleanup () override { m_Endpoint.Cleanup (); };
|
||||||
@@ -246,8 +249,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>
|
||||||
@@ -264,8 +265,8 @@ namespace tunnel
|
|||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
void ManageTunnels (uint64_t ts);
|
void ManageTunnels (uint64_t ts);
|
||||||
void ManageOutboundTunnels (uint64_t ts);
|
void ManageOutboundTunnels (uint64_t ts, std::vector<std::shared_ptr<Tunnel> >& toRecreate);
|
||||||
void ManageInboundTunnels (uint64_t ts);
|
void ManageInboundTunnels (uint64_t ts, std::vector<std::shared_ptr<Tunnel> >& toRecreate);
|
||||||
void ManagePendingTunnels (uint64_t ts);
|
void ManagePendingTunnels (uint64_t ts);
|
||||||
template<class PendingTunnels>
|
template<class PendingTunnels>
|
||||||
void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts);
|
void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace tunnel
|
|||||||
void HandleDecryptedTunnelDataMsg (std::shared_ptr<I2NPMessage> msg);
|
void HandleDecryptedTunnelDataMsg (std::shared_ptr<I2NPMessage> msg);
|
||||||
void FlushI2NPMsgs ();
|
void FlushI2NPMsgs ();
|
||||||
|
|
||||||
const i2p::data::IdentHash * GetCurrentHash () const; // return null if not avaiable
|
const i2p::data::IdentHash * GetCurrentHash () const; // return null if not available
|
||||||
const std::unique_ptr<TunnelTransportSender>& GetSender () const { return m_Sender; };
|
const std::unique_ptr<TunnelTransportSender>& GetSender () const { return m_Sender; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c)
|
#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c)
|
||||||
|
|
||||||
#define I2PD_VERSION_MAJOR 2
|
#define I2PD_VERSION_MAJOR 2
|
||||||
#define I2PD_VERSION_MINOR 55
|
#define I2PD_VERSION_MINOR 56
|
||||||
#define I2PD_VERSION_MICRO 0
|
#define I2PD_VERSION_MICRO 0
|
||||||
#define I2PD_VERSION_PATCH 0
|
#define I2PD_VERSION_PATCH 0
|
||||||
#ifdef GITVER
|
#ifdef GITVER
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#define I2P_VERSION_MAJOR 0
|
#define I2P_VERSION_MAJOR 0
|
||||||
#define I2P_VERSION_MINOR 9
|
#define I2P_VERSION_MINOR 9
|
||||||
#define I2P_VERSION_MICRO 64
|
#define I2P_VERSION_MICRO 65
|
||||||
#define I2P_VERSION_PATCH 0
|
#define I2P_VERSION_PATCH 0
|
||||||
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
||||||
#define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
#define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)
|
||||||
|
|||||||
@@ -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() );
|
size_t len = address->GetFullLen ();
|
||||||
|
std::vector<uint8_t> buf;
|
||||||
|
if (!len) return; // invalid address
|
||||||
|
{
|
||||||
|
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);
|
std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
|
||||||
if (!f.is_open ()) {
|
if (!f.is_open ())
|
||||||
|
{
|
||||||
LogPrint (eLogError, "Addressbook: Can't open file ", path);
|
LogPrint (eLogError, "Addressbook: Can't open file ", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t len = address->GetFullLen ();
|
f.write ((const char *)buf.data (), len);
|
||||||
uint8_t * buf = new uint8_t[len];
|
}
|
||||||
address->ToBuffer (buf, len);
|
|
||||||
f.write ((char *)buf, len);
|
|
||||||
delete[] buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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