Configurable minimum successful tunnels

This commit is contained in:
SidorKozlov 2023-05-03 15:59:35 +02:00
parent 4ce2ef1d83
commit 3b13a3f2a1
4 changed files with 35 additions and 32 deletions

View File

@ -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.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.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.ntcphard", value<uint16_t>()->default_value(0), "Ignored")
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Ignored")

View File

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

View File

@ -38,7 +38,6 @@ namespace data
{
const int NETDB_MIN_ROUTERS = 90;
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_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours

View File

@ -45,7 +45,7 @@ namespace tunnel
const int TUNNEL_MANAGE_INTERVAL = 15; // in seconds
const int TUNNEL_POOLS_MANAGE_INTERVAL = 5; // 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_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);
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:
template<class TTunnel>
@ -292,7 +292,7 @@ namespace tunnel
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_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
uint16_t m_MaxNumTransitTunnels;
uint16_t m_MaxNumTransitTunnels;
// count of tunnels for total TCSR algorithm
int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations;
double m_TunnelCreationSuccessRate;
@ -311,6 +311,7 @@ namespace tunnel
int GetQueueSize () { return m_Queue.GetSize (); };
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 totalNum = m_TotalNumSuccesiveTunnelCreations + m_TotalNumFailedTunnelCreations;