1
0
mirror of https://github.com/PurpleI2P/i2pd.git synced 2025-01-11 21:47:52 +00:00

update introducers. cleanup unreachable routers

This commit is contained in:
orignal 2023-04-05 21:30:36 -04:00
parent e3fb9d8483
commit 9475a22728
5 changed files with 69 additions and 29 deletions

View File

@ -106,7 +106,7 @@ namespace data
{ {
i2p::util::SetThreadName("NetDB"); i2p::util::SetThreadName("NetDB");
uint64_t lastSave = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; uint64_t lastManage = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch (); uint64_t lastProfilesCleanup = i2p::util::GetSecondsSinceEpoch ();
int16_t profilesCleanupVariance = 0; int16_t profilesCleanupVariance = 0;
@ -155,14 +155,14 @@ namespace data
lastManageRequest = ts; lastManageRequest = ts;
} }
if (ts - lastSave >= 60 || ts + 60 < lastSave) // save routers, manage leasesets and validate subscriptions every minute if (ts - lastManage >= 60 || ts + 60 < lastManage) // manage routers and leasesets every minute
{ {
if (lastSave) if (lastManage)
{ {
SaveUpdated (); ManageRouterInfos ();
ManageLeaseSets (); ManageLeaseSets ();
} }
lastSave = ts; lastManage = ts;
} }
if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT || if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT ||
@ -631,13 +631,8 @@ namespace data
if (!it.second->IsUnreachable ()) if (!it.second->IsUnreachable ())
{ {
// find & mark expired routers // find & mark expired routers
if (!it.second->IsReachable () && (it.second->GetCompatibleTransports (true) & RouterInfo::eSSU2V4)) if (it.second->GetCompatibleTransports (true)) // non reachable by any transport
// non-reachable router, but reachable by ipv4 SSU2 means introducers
{
if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)
// RouterInfo expires after 1 hour if uses introducer
it.second->SetUnreachable (true); it.second->SetUnreachable (true);
}
else if (checkForExpiration && ts > it.second->GetTimestamp () + expirationTimeout) else if (checkForExpiration && ts > it.second->GetTimestamp () + expirationTimeout)
it.second->SetUnreachable (true); it.second->SetUnreachable (true);
else if (ts + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < it.second->GetTimestamp ()) else if (ts + NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < it.second->GetTimestamp ())
@ -1348,6 +1343,17 @@ namespace data
return r; return r;
} }
void NetDb::ManageRouterInfos ()
{
auto ts = i2p::util::GetSecondsSinceEpoch ();
{
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
for (auto& it: m_RouterInfos)
it.second->UpdateIntroducers (ts);
}
SaveUpdated ();
}
void NetDb::ManageLeaseSets () void NetDb::ManageLeaseSets ()
{ {
auto ts = i2p::util::GetMillisecondsSinceEpoch (); auto ts = i2p::util::GetMillisecondsSinceEpoch ();

View File

@ -40,7 +40,6 @@ namespace data
const int NETDB_MIN_FLOODFILLS = 5; const int NETDB_MIN_FLOODFILLS = 5;
const int NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE = 8; // in percents const int NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE = 8; // in percents
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60;
const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours
const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days
@ -139,6 +138,7 @@ namespace data
void Run (); // exploratory thread void Run (); // exploratory thread
void Explore (int numDestinations); void Explore (int numDestinations);
void Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg); void Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg);
void ManageRouterInfos ();
void ManageLeaseSets (); void ManageLeaseSets ();
void ManageRequests (); void ManageRequests ();

View File

@ -400,18 +400,9 @@ namespace data
{ {
// exclude invalid introducers // exclude invalid introducers
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
int numValid = 0; UpdateIntroducers (address, ts);
for (auto& it: address->ssu->introducers) if (!address->ssu->introducers.empty ()) // still has something
{
if (it.iTag && ts < it.iExp)
numValid++;
else
it.iTag = 0;
}
if (numValid)
m_ReachableTransports |= supportedTransports; m_ReachableTransports |= supportedTransports;
else
address->ssu->introducers.resize (0);
} }
} }
if (supportedTransports) if (supportedTransports)
@ -576,6 +567,21 @@ namespace data
return caps; return caps;
} }
void RouterInfo::UpdateIntroducers (std::shared_ptr<Address> address, uint64_t ts)
{
if (!address || !address->ssu) return;
int numValid = 0;
for (auto& it: address->ssu->introducers)
{
if (it.iTag && ts < it.iExp)
numValid++;
else
it.iTag = 0;
}
if (!numValid)
address->ssu->introducers.resize (0);
}
bool RouterInfo::IsNewer (const uint8_t * buf, size_t len) const bool RouterInfo::IsNewer (const uint8_t * buf, size_t len) const
{ {
if (!m_RouterIdentity) return false; if (!m_RouterIdentity) return false;
@ -1036,6 +1042,31 @@ namespace data
} }
} }
void RouterInfo::UpdateIntroducers (uint64_t ts)
{
if (ts*1000 < m_Timestamp + INTRODUCER_UPDATE_INTERVAL) return;
if (m_ReachableTransports & eSSU2V4)
{
auto addr = (*GetAddresses ())[eSSU2V4Idx];
if (addr && addr->UsesIntroducer ())
{
UpdateIntroducers (addr, ts);
if (!addr->UsesIntroducer ()) // no more valid introducers
m_ReachableTransports &= ~eSSU2V4;
}
}
if (m_ReachableTransports & eSSU2V6)
{
auto addr = (*GetAddresses ())[eSSU2V6Idx];
if (addr && addr->UsesIntroducer ())
{
UpdateIntroducers (addr, ts);
if (!addr->UsesIntroducer ()) // no more valid introducers
m_ReachableTransports &= ~eSSU2V6;
}
}
}
void RouterInfo::UpdateBuffer (const uint8_t * buf, size_t len) void RouterInfo::UpdateBuffer (const uint8_t * buf, size_t len)
{ {
if (!m_Buffer) if (!m_Buffer)

View File

@ -61,6 +61,7 @@ namespace data
const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
const int HIGH_CONGESTION_INTERVAL = 15*60; // in seconds, 15 minutes const int HIGH_CONGESTION_INTERVAL = 15*60; // in seconds, 15 minutes
const int INTRODUCER_UPDATE_INTERVAL = 20*60*1000; // in milliseconds, 20 minutes
class RouterInfo: public RoutingDestination class RouterInfo: public RoutingDestination
{ {
@ -221,8 +222,8 @@ namespace data
void RemoveSSU2Address (bool v4); void RemoveSSU2Address (bool v4);
void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps
void UpdateSupportedTransports (); void UpdateSupportedTransports ();
void UpdateIntroducers (uint64_t ts); // ts in seconds
bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; };
bool IsReachable () const { return m_Caps & Caps::eReachable; };
bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; };
bool IsNTCP2 (bool v4only = true) const; bool IsNTCP2 (bool v4only = true) const;
bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; }; bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; };
@ -302,6 +303,7 @@ namespace data
size_t ReadString (char* str, size_t len, std::istream& s) const; size_t ReadString (char* str, size_t len, std::istream& s) const;
void ExtractCaps (const char * value); void ExtractCaps (const char * value);
uint8_t ExtractAddressCaps (const char * value) const; uint8_t ExtractAddressCaps (const char * value) const;
void UpdateIntroducers (std::shared_ptr<Address> address, uint64_t ts);
template<typename Filter> template<typename Filter>
std::shared_ptr<const Address> GetAddress (Filter filter) const; std::shared_ptr<const Address> GetAddress (Filter filter) const;
virtual std::shared_ptr<Buffer> NewBuffer () const; virtual std::shared_ptr<Buffer> NewBuffer () const;
@ -315,7 +317,7 @@ namespace data
std::shared_ptr<const IdentityEx> m_RouterIdentity; std::shared_ptr<const IdentityEx> m_RouterIdentity;
std::shared_ptr<Buffer> m_Buffer; std::shared_ptr<Buffer> m_Buffer;
size_t m_BufferLen; size_t m_BufferLen;
uint64_t m_Timestamp; uint64_t m_Timestamp; // in milliseconds
boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9 boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
bool m_IsUpdated, m_IsUnreachable; bool m_IsUpdated, m_IsUnreachable;
CompatibleTransports m_SupportedTransports, m_ReachableTransports; CompatibleTransports m_SupportedTransports, m_ReachableTransports;

View File

@ -498,7 +498,8 @@ namespace tunnel
{ {
auto r = i2p::transport::transports.GetRandomPeer (!IsExploratory ()); auto r = i2p::transport::transports.GetRandomPeer (!IsExploratory ());
if (r && r->IsECIES () && !r->GetProfile ()->IsBad () && if (r && r->IsECIES () && !r->GetProfile ()->IsBad () &&
(numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable (numHops > 1 || (r->IsV4 () && (!inbound ||
r->IsReachableBy (i2p::data::RouterInfo::eNTCP2V4 | i2p::data::RouterInfo::eSSU2V4))))) // first inbound must be reachable
{ {
prevHop = r; prevHop = r;
path.Add (r); path.Add (r);
@ -520,8 +521,8 @@ namespace tunnel
LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ()); LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ());
return false; return false;
} }
if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4 if ((i == numHops - 1) && (!hop->IsV4 () || (inbound && // doesn't support ipv4
(inbound && !hop->IsReachable ()))) // IBGW is not reachable !hop->IsReachableBy (i2p::data::RouterInfo::eNTCP2V4 | i2p::data::RouterInfo::eSSU2V4)))) // IBGW is not reachable
{ {
auto hop1 = nextHop (prevHop, true); auto hop1 = nextHop (prevHop, true);
if (hop1) hop = hop1; if (hop1) hop = hop1;