mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 02:44:15 +00:00
Merge pull request #1922 from SidorKozlov/zombie-config
Configurable minimum successful tunnels
This commit is contained in:
commit
19471dbb90
@ -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")
|
||||||
|
@ -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 ();
|
||||||
|
@ -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
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user