Browse Source

Merge pull request #1922 from SidorKozlov/zombie-config

Configurable minimum successful tunnels
pull/1925/head
orignal 2 years ago committed by GitHub
parent
commit
19471dbb90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      libi2pd/Config.cpp
  2. 56
      libi2pd/NetDb.cpp
  3. 1
      libi2pd/NetDb.hpp
  4. 9
      libi2pd/Tunnel.h

1
libi2pd/Config.cpp

@ -78,6 +78,7 @@ namespace config {
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") ("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)") ("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
("limits.transittunnels", value<uint16_t>()->default_value(5000), "Maximum active transit tunnels (default:5000)") ("limits.transittunnels", value<uint16_t>()->default_value(5000), "Maximum active transit tunnels (default:5000)")
("limits.zombies", value<double>()->default_value(0), "Minimum percentage of successfully created tunnels under which tunnel cleanup is paused (default [%]: 0.00)")
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Ignored") ("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Ignored")
("limits.ntcphard", value<uint16_t>()->default_value(0), "Ignored") ("limits.ntcphard", value<uint16_t>()->default_value(0), "Ignored")
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Ignored") ("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Ignored")

56
libi2pd/NetDb.cpp

@ -245,19 +245,19 @@ namespace data
updated = false; updated = false;
m_Requests.RequestComplete (ident, r); m_Requests.RequestComplete (ident, r);
return r; return r;
} }
if (r->IsUnreachable ()) if (r->IsUnreachable ())
{ {
// delete router as invalid after update // delete router as invalid after update
m_RouterInfos.erase (ident); m_RouterInfos.erase (ident);
if (wasFloodfill) if (wasFloodfill)
{ {
std::unique_lock<std::mutex> l(m_FloodfillsMutex); std::unique_lock<std::mutex> l(m_FloodfillsMutex);
m_Floodfills.Remove (r->GetIdentHash ()); m_Floodfills.Remove (r->GetIdentHash ());
} }
m_Requests.RequestComplete (ident, nullptr); m_Requests.RequestComplete (ident, nullptr);
return nullptr; return nullptr;
} }
} }
LogPrint (eLogInfo, "NetDb: RouterInfo updated: ", ident.ToBase64()); LogPrint (eLogInfo, "NetDb: RouterInfo updated: ", ident.ToBase64());
if (wasFloodfill != r->IsFloodfill ()) // if floodfill status updated if (wasFloodfill != r->IsFloodfill ()) // if floodfill status updated
@ -419,7 +419,7 @@ namespace data
if (profile) if (profile)
profile->Unreachable (); profile->Unreachable ();
} }
} }
} }
void NetDb::ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports) void NetDb::ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports)
@ -429,9 +429,9 @@ namespace data
{ {
std::unique_lock<std::mutex> l(m_RouterInfosMutex); std::unique_lock<std::mutex> l(m_RouterInfosMutex);
r->ExcludeReachableTransports (transports); r->ExcludeReachableTransports (transports);
} }
} }
void NetDb::Reseed () void NetDb::Reseed ()
{ {
if (!m_Reseeder) if (!m_Reseeder)
@ -607,7 +607,9 @@ namespace data
uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL;
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); uint64_t ts = i2p::util::GetMillisecondsSinceEpoch();
auto uptime = i2p::context.GetUptime (); auto uptime = i2p::context.GetUptime ();
bool isLowRate = false; // i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () < NETDB_MIN_TUNNEL_CREATION_SUCCESS_RATE; double minTunnelCreationSuccessRate;
i2p::config::GetOption("limits.zombies", minTunnelCreationSuccessRate);
bool isLowRate = i2p::tunnel::tunnels.GetPreciseTunnelCreationSuccessRate () < minTunnelCreationSuccessRate;
// routers don't expire if less than 90 or uptime is less than 1 hour // routers don't expire if less than 90 or uptime is less than 1 hour
bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes
if (checkForExpiration && uptime > 3600) // 1 hour if (checkForExpiration && uptime > 3600) // 1 hour
@ -622,12 +624,12 @@ namespace data
if (it.second->IsUpdated ()) if (it.second->IsUpdated ())
{ {
if (it.second->GetBuffer ()) if (it.second->GetBuffer ())
{ {
// we have something to save // we have something to save
it.second->SaveToFile (m_Storage.Path(ident)); it.second->SaveToFile (m_Storage.Path(ident));
it.second->SetUnreachable (false); it.second->SetUnreachable (false);
it.second->DeleteBuffer (); it.second->DeleteBuffer ();
} }
it.second->SetUpdated (false); it.second->SetUpdated (false);
updatedCount++; updatedCount++;
continue; continue;
@ -639,7 +641,7 @@ namespace data
(it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS))) (it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS)))
it.second->SetUnreachable (false); it.second->SetUnreachable (false);
if (!it.second->IsUnreachable ()) if (!it.second->IsUnreachable ())
{ {
// find & mark expired routers // find & mark expired routers
if (!it.second->GetCompatibleTransports (true)) // non reachable by any transport if (!it.second->GetCompatibleTransports (true)) // non reachable by any transport
it.second->SetUnreachable (true); it.second->SetUnreachable (true);
@ -652,7 +654,7 @@ namespace data
} }
if (it.second->IsUnreachable () && i2p::transport::transports.IsConnected (it.second->GetIdentHash ())) if (it.second->IsUnreachable () && i2p::transport::transports.IsConnected (it.second->GetIdentHash ()))
it.second->SetUnreachable (false); // don't expire connected router it.second->SetUnreachable (false); // don't expire connected router
} }
if (it.second->IsUnreachable ()) if (it.second->IsUnreachable ())
{ {
@ -667,7 +669,7 @@ namespace data
m_RouterInfoBuffersPool.CleanUpMt (); m_RouterInfoBuffersPool.CleanUpMt ();
m_RouterInfoAddressesPool.CleanUpMt (); m_RouterInfoAddressesPool.CleanUpMt ();
m_RouterInfoAddressVectorsPool.CleanUpMt (); m_RouterInfoAddressVectorsPool.CleanUpMt ();
m_IdentitiesPool.CleanUpMt (); m_IdentitiesPool.CleanUpMt ();
if (updatedCount > 0) if (updatedCount > 0)
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers"); LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
@ -682,10 +684,10 @@ namespace data
if (it->second->IsUnreachable ()) if (it->second->IsUnreachable ())
it = m_RouterInfos.erase (it); it = m_RouterInfos.erase (it);
else else
{ {
it->second->DropProfile (); it->second->DropProfile ();
it++; it++;
} }
} }
} }
// clean up expired floodfills or not floodfills anymore // clean up expired floodfills or not floodfills anymore
@ -724,9 +726,9 @@ namespace data
if (outbound && inbound) if (outbound && inbound)
{ {
auto msg = dest->CreateRequestMessage (floodfill, inbound); auto msg = dest->CreateRequestMessage (floodfill, inbound);
outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0,
i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ())); i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ()));
} }
else else
{ {
LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found"); LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found");
@ -794,7 +796,7 @@ namespace data
uint32_t tunnelID = bufbe32toh (buf + offset); uint32_t tunnelID = bufbe32toh (buf + offset);
offset += 4; offset += 4;
if (replyToken != 0xFFFFFFFFU) // if not caught on OBEP or IBGW if (replyToken != 0xFFFFFFFFU) // if not caught on OBEP or IBGW
{ {
auto deliveryStatus = CreateDeliveryStatusMsg (replyToken); auto deliveryStatus = CreateDeliveryStatusMsg (replyToken);
if (!tunnelID) // send response directly if (!tunnelID) // send response directly
transports.SendMessage (buf + offset, deliveryStatus); transports.SendMessage (buf + offset, deliveryStatus);
@ -807,7 +809,7 @@ namespace data
else else
LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found"); LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found");
} }
} }
offset += 32; offset += 32;
} }
// we must send reply back before this check // we must send reply back before this check
@ -1315,16 +1317,16 @@ namespace data
return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () &&
!excluded.count (r->GetIdentHash ()); !excluded.count (r->GetIdentHash ());
}); });
} }
if (v.empty ()) return res; if (v.empty ()) return res;
XORMetric ourMetric; XORMetric ourMetric;
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash ();
for (auto& it: v) for (auto& it: v)
{ {
if (closeThanUsOnly && ourMetric < (destKey ^ it->GetIdentHash ())) break; if (closeThanUsOnly && ourMetric < (destKey ^ it->GetIdentHash ())) break;
res.push_back (it->GetIdentHash ()); res.push_back (it->GetIdentHash ());
} }
return res; return res;
} }
@ -1367,10 +1369,10 @@ namespace data
std::unique_lock<std::mutex> l(m_RouterInfosMutex); std::unique_lock<std::mutex> l(m_RouterInfosMutex);
for (auto& it: m_RouterInfos) for (auto& it: m_RouterInfos)
it.second->UpdateIntroducers (ts); it.second->UpdateIntroducers (ts);
} }
SaveUpdated (); SaveUpdated ();
} }
void NetDb::ManageLeaseSets () void NetDb::ManageLeaseSets ()
{ {
auto ts = i2p::util::GetMillisecondsSinceEpoch (); auto ts = i2p::util::GetMillisecondsSinceEpoch ();

1
libi2pd/NetDb.hpp

@ -38,7 +38,6 @@ namespace data
{ {
const int NETDB_MIN_ROUTERS = 90; const int NETDB_MIN_ROUTERS = 90;
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_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds
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

9
libi2pd/Tunnel.h

@ -45,7 +45,7 @@ namespace tunnel
const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds
const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // in seconds
const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds const int TUNNEL_MEMORY_POOL_MANAGE_INTERVAL = 120; // in seconds
const size_t I2NP_TUNNEL_MESSAGE_SIZE = TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34; // reserved for alignment and NTCP 16 + 6 + 12 const size_t I2NP_TUNNEL_MESSAGE_SIZE = TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34; // reserved for alignment and NTCP 16 + 6 + 12
const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6 const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6
@ -232,8 +232,8 @@ namespace tunnel
void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels);
uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; uint16_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; };
bool IsTooManyTransitTunnels () const { return m_TransitTunnels.size () >= m_MaxNumTransitTunnels; }; bool IsTooManyTransitTunnels () const { return m_TransitTunnels.size () >= m_MaxNumTransitTunnels; };
private: private:
template<class TTunnel> template<class TTunnel>
@ -292,7 +292,7 @@ namespace tunnel
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_Queue; i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_Queue;
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE> > m_I2NPTunnelEndpointMessagesMemoryPool; i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE> > m_I2NPTunnelEndpointMessagesMemoryPool;
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool; i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
uint16_t m_MaxNumTransitTunnels; uint16_t m_MaxNumTransitTunnels;
// count of tunnels for total TCSR algorithm // count of tunnels for total TCSR algorithm
int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations;
double m_TunnelCreationSuccessRate; double m_TunnelCreationSuccessRate;
@ -311,6 +311,7 @@ namespace tunnel
int GetQueueSize () { return m_Queue.GetSize (); }; int GetQueueSize () { return m_Queue.GetSize (); };
int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents
double GetPreciseTunnelCreationSuccessRate () const { return m_TunnelCreationSuccessRate * 100; } // in percents
int GetTotalTunnelCreationSuccessRate () const // in percents int GetTotalTunnelCreationSuccessRate () const // in percents
{ {
int totalNum = m_TotalNumSuccesiveTunnelCreations + m_TotalNumFailedTunnelCreations; int totalNum = m_TotalNumSuccesiveTunnelCreations + m_TotalNumFailedTunnelCreations;

Loading…
Cancel
Save