From e74272781f8ee9ccabd7356e5a3717e39681c829 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 May 2024 18:29:40 -0400 Subject: [PATCH] moved exploratory to netdb requests thread --- libi2pd/NetDb.cpp | 75 +--------------------------------- libi2pd/NetDb.hpp | 7 +--- libi2pd/NetDbRequests.cpp | 86 ++++++++++++++++++++++++++++++++++++++- libi2pd/NetDbRequests.h | 7 +++- 4 files changed, 95 insertions(+), 80 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index f29ed7aa..246d1888 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -118,9 +118,9 @@ namespace data { i2p::util::SetThreadName("NetDB"); - uint64_t lastManage = 0, lastExploratory = 0; + uint64_t lastManage = 0; uint64_t lastProfilesCleanup = i2p::util::GetMonotonicMilliseconds (), lastObsoleteProfilesCleanup = lastProfilesCleanup; - int16_t profilesCleanupVariance = 0, obsoleteProfilesCleanVariance = 0, exploratoryIntervalVariance = 0; + int16_t profilesCleanupVariance = 0, obsoleteProfilesCleanVariance = 0; while (m_IsRunning) { @@ -204,27 +204,6 @@ namespace data lastObsoleteProfilesCleanup = mts; obsoleteProfilesCleanVariance = rand () % i2p::data::PEER_PROFILE_OBSOLETE_PROFILES_CLEAN_VARIANCE; } - - if (mts >= lastExploratory + NETDB_EXPLORATORY_INTERVAL*1000LL) // check exploratory every 55 seconds - { - auto numRouters = m_RouterInfos.size (); - if (!numRouters) - throw std::runtime_error("No known routers, reseed seems to be totally failed"); - else // we have peers now - m_FloodfillBootstrap = nullptr; - if (numRouters < 2500 || mts >= lastExploratory + (NETDB_EXPLORATORY_INTERVAL + exploratoryIntervalVariance)*1000LL) - { - if(!i2p::context.IsHidden ()) - { - numRouters = 800/numRouters; - if (numRouters < 1) numRouters = 1; - if (numRouters > 9) numRouters = 9; - Explore (numRouters); - } - lastExploratory = mts; - exploratoryIntervalVariance = rand () % NETDB_EXPLORATORY_INTERVAL_VARIANCE; - } - } } catch (std::exception& ex) { @@ -1138,56 +1117,6 @@ namespace data } } - void NetDb::Explore (int numDestinations) - { - // new requests - auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; - auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr; - bool throughTunnels = outbound && inbound; - - uint8_t randomHash[32]; - std::vector msgs; - LogPrint (eLogInfo, "NetDb: Exploring new ", numDestinations, " routers ..."); - for (int i = 0; i < numDestinations; i++) - { - RAND_bytes (randomHash, 32); - auto dest = m_Requests->CreateRequest (randomHash, true, !throughTunnels); // exploratory - if (!dest) - { - LogPrint (eLogWarning, "NetDb: Exploratory destination is requested already"); - return; - } - auto floodfill = GetClosestFloodfill (randomHash, dest->GetExcludedPeers ()); - if (floodfill) - { - if (i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) - throughTunnels = false; - if (throughTunnels) - { - msgs.push_back (i2p::tunnel::TunnelMessageBlock - { - i2p::tunnel::eDeliveryTypeRouter, - floodfill->GetIdentHash (), 0, - CreateDatabaseStoreMsg () // tell floodfill about us - }); - msgs.push_back (i2p::tunnel::TunnelMessageBlock - { - i2p::tunnel::eDeliveryTypeRouter, - floodfill->GetIdentHash (), 0, - dest->CreateRequestMessage (floodfill, inbound) // explore - }); - } - else - i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); - } - else - m_Requests->RequestComplete (randomHash, nullptr); - } - if (throughTunnels && msgs.size () > 0) - outbound->SendTunnelDataMsgs (msgs); - } - void NetDb::Flood (const IdentHash& ident, std::shared_ptr floodMsg) { std::unordered_set excluded; diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 099b6272..5b017dc6 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -48,14 +48,12 @@ namespace data const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours const int NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT = 180; // in days const int NETDB_EXPIRATION_TIMEOUT_THRESHOLD = 2*60; // 2 minutes - const int NETDB_EXPLORATORY_INTERVAL = 55; // in seconds - const int NETDB_EXPLORATORY_INTERVAL_VARIANCE = 170; // in seconds const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const size_t NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES = 16; const size_t NETDB_MAX_EXPLORATORY_SELECTION_SIZE = 500; - const int NETDB_EXPLORATORY_SELECTION_UPDATE_INTERVAL = 82; // in seconds + const int NETDB_EXPLORATORY_SELECTION_UPDATE_INTERVAL = 82; // in seconds. for floodfill /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; @@ -142,8 +140,7 @@ namespace data void SaveUpdated (); void PersistRouters (std::list > >&& update, std::list&& remove); - void Run (); // exploratory thread - void Explore (int numDestinations); + void Run (); void Flood (const IdentHash& ident, std::shared_ptr floodMsg); void ManageRouterInfos (); void ManageLeaseSets (); diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 900fc6c4..9ab2411e 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -107,7 +107,7 @@ namespace data NetDbRequests::NetDbRequests (): RunnableServiceWithWork ("NetDbReq"), - m_ManageRequestsTimer (GetIOService ()) + m_ManageRequestsTimer (GetIOService ()), m_ExploratoryTimer (GetIOService ()) { } @@ -123,6 +123,8 @@ namespace data { StartIOService (); ScheduleManageRequests (); + if (!i2p::context.IsHidden ()) + ScheduleExploratory (EXPLORATORY_REQUEST_INTERVAL); } } @@ -131,6 +133,7 @@ namespace data if (IsRunning ()) { m_ManageRequestsTimer.cancel (); + m_ExploratoryTimer.cancel (); StopIOService (); m_RequestedDestinations.clear (); @@ -434,5 +437,86 @@ namespace data else LogPrint (eLogWarning, "NetDbReq: Destination ", destination.ToBase64(), " is requested already or cached"); } + + void NetDbRequests::Explore (int numDestinations) + { + // new requests + auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); + auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; + auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr; + bool throughTunnels = outbound && inbound; + + uint8_t randomHash[32]; + std::vector msgs; + LogPrint (eLogInfo, "NetDbReq: Exploring new ", numDestinations, " routers ..."); + for (int i = 0; i < numDestinations; i++) + { + RAND_bytes (randomHash, 32); + auto dest = CreateRequest (randomHash, true, !throughTunnels); // exploratory + if (!dest) + { + LogPrint (eLogWarning, "NetDbReq: Exploratory destination is requested already"); + return; + } + auto floodfill = netdb.GetClosestFloodfill (randomHash, dest->GetExcludedPeers ()); + if (floodfill) + { + if (i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) + throughTunnels = false; + if (throughTunnels) + { + msgs.push_back (i2p::tunnel::TunnelMessageBlock + { + i2p::tunnel::eDeliveryTypeRouter, + floodfill->GetIdentHash (), 0, + CreateDatabaseStoreMsg () // tell floodfill about us + }); + msgs.push_back (i2p::tunnel::TunnelMessageBlock + { + i2p::tunnel::eDeliveryTypeRouter, + floodfill->GetIdentHash (), 0, + dest->CreateRequestMessage (floodfill, inbound) // explore + }); + } + else + i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); + } + else + RequestComplete (randomHash, nullptr); + } + if (throughTunnels && msgs.size () > 0) + outbound->SendTunnelDataMsgs (msgs); + } + + void NetDbRequests::ScheduleExploratory (uint64_t interval) + { + m_ExploratoryTimer.expires_from_now (boost::posix_time::seconds(interval)); + m_ExploratoryTimer.async_wait (std::bind (&NetDbRequests::HandleExploratoryTimer, + this, std::placeholders::_1)); + } + + void NetDbRequests::HandleExploratoryTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + auto numRouters = netdb.GetNumRouters (); + auto nextExploratoryInterval = numRouters < 2500 ? (EXPLORATORY_REQUEST_INTERVAL + rand () % EXPLORATORY_REQUEST_INTERVAL)/2 : + EXPLORATORY_REQUEST_INTERVAL + rand () % EXPLORATORY_REQUEST_INTERVAL_VARIANCE; + if (numRouters) + { + if (i2p::transport::transports.IsOnline () && i2p::transport::transports.IsRunning ()) + { + // explore only if online + numRouters = 800/numRouters; + if (numRouters < 1) numRouters = 1; + if (numRouters > 9) numRouters = 9; + Explore (numRouters); + } + } + else + LogPrint (eLogError, "NetDbReq: No known routers, reseed seems to be totally failed"); + ScheduleExploratory (nextExploratoryInterval); + } + } } } diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index 47d2fafa..9901c9c7 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -25,6 +25,8 @@ namespace data const uint64_t MANAGE_REQUESTS_INTERVAL = 1; // in seconds const uint64_t MIN_REQUEST_TIME = 5; // in seconds const uint64_t MAX_REQUEST_TIME = MAX_NUM_REQUEST_ATTEMPTS * (MIN_REQUEST_TIME + MANAGE_REQUESTS_INTERVAL); + const uint64_t EXPLORATORY_REQUEST_INTERVAL = 55; // in seconds + const uint64_t EXPLORATORY_REQUEST_INTERVAL_VARIANCE = 170; // in seconds const uint64_t MAX_EXPLORATORY_REQUEST_TIME = 30; // in seconds const uint64_t REQUEST_CACHE_TIME = MAX_REQUEST_TIME + 40; // in seconds const uint64_t REQUESTED_DESTINATIONS_POOL_CLEANUP_INTERVAL = 191; // in seconds @@ -92,10 +94,13 @@ namespace data void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); void RequestDestination (const IdentHash& destination, const RequestedDestination::RequestComplete& requestComplete, bool direct); + void Explore (int numDestinations); void ManageRequests (); // timer void ScheduleManageRequests (); void HandleManageRequestsTimer (const boost::system::error_code& ecode); + void ScheduleExploratory (uint64_t interval); + void HandleExploratoryTimer (const boost::system::error_code& ecode); private: @@ -103,7 +108,7 @@ namespace data std::unordered_map > m_RequestedDestinations; i2p::util::MemoryPoolMt m_RequestedDestinationsPool; uint64_t m_LastPoolCleanUpTime = 0; // in seconds - boost::asio::deadline_timer m_ManageRequestsTimer; + boost::asio::deadline_timer m_ManageRequestsTimer, m_ExploratoryTimer; }; } }