moved exploratory to netdb requests thread

This commit is contained in:
orignal 2024-05-22 18:29:40 -04:00
parent b75e418879
commit e74272781f
4 changed files with 95 additions and 80 deletions

View File

@ -118,9 +118,9 @@ namespace data
{ {
i2p::util::SetThreadName("NetDB"); i2p::util::SetThreadName("NetDB");
uint64_t lastManage = 0, lastExploratory = 0; uint64_t lastManage = 0;
uint64_t lastProfilesCleanup = i2p::util::GetMonotonicMilliseconds (), lastObsoleteProfilesCleanup = lastProfilesCleanup; 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) while (m_IsRunning)
{ {
@ -204,27 +204,6 @@ namespace data
lastObsoleteProfilesCleanup = mts; lastObsoleteProfilesCleanup = mts;
obsoleteProfilesCleanVariance = rand () % i2p::data::PEER_PROFILE_OBSOLETE_PROFILES_CLEAN_VARIANCE; 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) 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<i2p::tunnel::TunnelMessageBlock> 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<I2NPMessage> floodMsg) void NetDb::Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg)
{ {
std::unordered_set<IdentHash> excluded; std::unordered_set<IdentHash> excluded;

View File

@ -48,14 +48,12 @@ namespace data
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
const int NETDB_EXPIRATION_TIMEOUT_THRESHOLD = 2*60; // 2 minutes 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_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_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 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_NUM_SEARCH_REPLY_PEER_HASHES = 16;
const size_t NETDB_MAX_EXPLORATORY_SELECTION_SIZE = 500; 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 */ /** function for visiting a leaseset stored in a floodfill */
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor; typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;
@ -142,8 +140,7 @@ namespace data
void SaveUpdated (); void SaveUpdated ();
void PersistRouters (std::list<std::pair<std::string, std::shared_ptr<RouterInfo::Buffer> > >&& update, void PersistRouters (std::list<std::pair<std::string, std::shared_ptr<RouterInfo::Buffer> > >&& update,
std::list<std::string>&& remove); std::list<std::string>&& remove);
void Run (); // exploratory thread void Run ();
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 ManageRouterInfos ();
void ManageLeaseSets (); void ManageLeaseSets ();

View File

@ -107,7 +107,7 @@ namespace data
NetDbRequests::NetDbRequests (): NetDbRequests::NetDbRequests ():
RunnableServiceWithWork ("NetDbReq"), RunnableServiceWithWork ("NetDbReq"),
m_ManageRequestsTimer (GetIOService ()) m_ManageRequestsTimer (GetIOService ()), m_ExploratoryTimer (GetIOService ())
{ {
} }
@ -123,6 +123,8 @@ namespace data
{ {
StartIOService (); StartIOService ();
ScheduleManageRequests (); ScheduleManageRequests ();
if (!i2p::context.IsHidden ())
ScheduleExploratory (EXPLORATORY_REQUEST_INTERVAL);
} }
} }
@ -131,6 +133,7 @@ namespace data
if (IsRunning ()) if (IsRunning ())
{ {
m_ManageRequestsTimer.cancel (); m_ManageRequestsTimer.cancel ();
m_ExploratoryTimer.cancel ();
StopIOService (); StopIOService ();
m_RequestedDestinations.clear (); m_RequestedDestinations.clear ();
@ -434,5 +437,86 @@ namespace data
else else
LogPrint (eLogWarning, "NetDbReq: Destination ", destination.ToBase64(), " is requested already or cached"); 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<i2p::tunnel::TunnelMessageBlock> 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);
}
}
} }
} }

View File

@ -25,6 +25,8 @@ namespace data
const uint64_t MANAGE_REQUESTS_INTERVAL = 1; // in seconds const uint64_t MANAGE_REQUESTS_INTERVAL = 1; // in seconds
const uint64_t MIN_REQUEST_TIME = 5; // 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 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 MAX_EXPLORATORY_REQUEST_TIME = 30; // in seconds
const uint64_t REQUEST_CACHE_TIME = MAX_REQUEST_TIME + 40; // 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 const uint64_t REQUESTED_DESTINATIONS_POOL_CLEANUP_INTERVAL = 191; // in seconds
@ -92,10 +94,13 @@ namespace data
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg); void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
void RequestDestination (const IdentHash& destination, const RequestedDestination::RequestComplete& requestComplete, bool direct); void RequestDestination (const IdentHash& destination, const RequestedDestination::RequestComplete& requestComplete, bool direct);
void Explore (int numDestinations);
void ManageRequests (); void ManageRequests ();
// timer // timer
void ScheduleManageRequests (); void ScheduleManageRequests ();
void HandleManageRequestsTimer (const boost::system::error_code& ecode); void HandleManageRequestsTimer (const boost::system::error_code& ecode);
void ScheduleExploratory (uint64_t interval);
void HandleExploratoryTimer (const boost::system::error_code& ecode);
private: private:
@ -103,7 +108,7 @@ namespace data
std::unordered_map<IdentHash, std::shared_ptr<RequestedDestination> > m_RequestedDestinations; std::unordered_map<IdentHash, std::shared_ptr<RequestedDestination> > m_RequestedDestinations;
i2p::util::MemoryPoolMt<RequestedDestination> m_RequestedDestinationsPool; i2p::util::MemoryPoolMt<RequestedDestination> m_RequestedDestinationsPool;
uint64_t m_LastPoolCleanUpTime = 0; // in seconds uint64_t m_LastPoolCleanUpTime = 0; // in seconds
boost::asio::deadline_timer m_ManageRequestsTimer; boost::asio::deadline_timer m_ManageRequestsTimer, m_ExploratoryTimer;
}; };
} }
} }