From 265bb8b7797b6313ac181ee562683f99e570249f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 May 2024 22:19:42 -0400 Subject: [PATCH] handle DatabaseSearchReply in netdb requests thread --- libi2pd/I2NPProtocol.cpp | 6 ++-- libi2pd/NetDb.cpp | 70 ++++----------------------------------- libi2pd/NetDb.hpp | 10 +++--- libi2pd/NetDbRequests.cpp | 68 +++++++++++++++++++++++++++++++++++++ libi2pd/NetDbRequests.h | 3 ++ 5 files changed, 87 insertions(+), 70 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index e968daf9..4cceda8f 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -862,12 +862,14 @@ namespace i2p break; } case eI2NPDatabaseStore: - case eI2NPDatabaseSearchReply: // forward to netDb if came directly or through exploratory tunnel as response to our request if (!msg->from || !msg->from->GetTunnelPool () || msg->from->GetTunnelPool ()->IsExploratory ()) i2p::data::netdb.PostI2NPMsg (msg); break; - + case eI2NPDatabaseSearchReply: + if (!msg->from || !msg->from->GetTunnelPool () || msg->from->GetTunnelPool ()->IsExploratory ()) + i2p::data::netdb.PostDatabaseSearchReplyMsg (msg); + break; case eI2NPDatabaseLookup: // forward to netDb if floodfill and came directly if (!msg->from && i2p::context.IsFloodfill ()) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index b9d32a70..2ec8097c 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -138,9 +138,6 @@ namespace data case eI2NPDatabaseStore: HandleDatabaseStoreMsg (msg); break; - case eI2NPDatabaseSearchReply: - HandleDatabaseSearchReplyMsg (msg); - break; case eI2NPDatabaseLookup: HandleDatabaseLookupMsg (msg); break; @@ -982,66 +979,7 @@ namespace data LogPrint (eLogError, "NetDb: Database store message is too long ", floodMsg->len); } } - - void NetDb::HandleDatabaseSearchReplyMsg (std::shared_ptr msg) - { - const uint8_t * buf = msg->GetPayload (); - char key[48]; - int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48); - key[l] = 0; - size_t num = buf[32]; // num - LogPrint (eLogDebug, "NetDb: DatabaseSearchReply for ", key, " num=", num); - IdentHash ident (buf); - auto dest = m_Requests->FindRequest (ident); - if (dest && dest->IsActive ()) - { - if (!dest->IsExploratory () && (num > 0 || dest->GetNumAttempts () < 3)) // before 3-rd attempt might be just bad luck - { - // try to send next requests - if (!m_Requests->SendNextRequest (dest)) - m_Requests->RequestComplete (ident, nullptr); - } - else - // no more requests for destination possible. delete it - m_Requests->RequestComplete (ident, nullptr); - } - else if (!m_FloodfillBootstrap) - { - LogPrint (eLogInfo, "NetDb: Unsolicited or late database search reply for ", key); - return; - } - - // try responses - if (num > NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES) - { - LogPrint (eLogWarning, "NetDb: Too many peer hashes ", num, " in database search reply, Reduced to ", NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES); - num = NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES; - } - for (size_t i = 0; i < num; i++) - { - const uint8_t * router = buf + 33 + i*32; - char peerHash[48]; - int l1 = i2p::data::ByteStreamToBase64 (router, 32, peerHash, 48); - peerHash[l1] = 0; - LogPrint (eLogDebug, "NetDb: ", i, ": ", peerHash); - - auto r = FindRouter (router); - if (!r || i2p::util::GetMillisecondsSinceEpoch () > r->GetTimestamp () + 3600*1000LL) - { - // router with ident not found or too old (1 hour) - LogPrint (eLogDebug, "NetDb: Found new/outdated router. Requesting RouterInfo..."); - if(m_FloodfillBootstrap) - RequestDestinationFrom(router, m_FloodfillBootstrap->GetIdentHash(), true); - else if (!IsRouterBanned (router)) - RequestDestination (router); - else - LogPrint (eLogDebug, "NetDb: Router ", peerHash, " is banned. Skipped"); - } - else - LogPrint (eLogDebug, "NetDb: [:|||:]"); - } - } - + void NetDb::HandleDatabaseLookupMsg (std::shared_ptr msg) { const uint8_t * buf = msg->GetPayload (); @@ -1402,6 +1340,12 @@ namespace data if (msg) m_Queue.Put (msg); } + void NetDb::PostDatabaseSearchReplyMsg (std::shared_ptr msg) + { + if (msg && m_Requests) + m_Requests->PostDatabaseSearchReplyMsg (msg); + } + std::shared_ptr NetDb::GetClosestFloodfill (const IdentHash& destination, const std::unordered_set& excluded) const { diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 1a6c357f..099b6272 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -87,11 +87,6 @@ namespace data void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr, bool direct = true); void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr); - void HandleDatabaseStoreMsg (std::shared_ptr msg); - void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); - void HandleDatabaseLookupMsg (std::shared_ptr msg); - void HandleNTCP2RouterInfoMsg (std::shared_ptr m); - std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith, bool reverse, bool endpoint) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse, bool endpoint) const; @@ -106,6 +101,7 @@ namespace data void ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports); void PostI2NPMsg (std::shared_ptr msg); + void PostDatabaseSearchReplyMsg (std::shared_ptr msg); // to NetdbReq thread void Reseed (); Families& GetFamilies () { return m_Families; }; @@ -161,6 +157,10 @@ namespace data template std::shared_ptr GetRandomRouter (Filter filter) const; + void HandleDatabaseStoreMsg (std::shared_ptr msg); + void HandleDatabaseLookupMsg (std::shared_ptr msg); + void HandleNTCP2RouterInfoMsg (std::shared_ptr m); + private: mutable std::mutex m_LeaseSetsMutex; diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 105e9a9f..4c6ed3fc 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -7,6 +7,7 @@ */ #include "Log.h" +#include "Base.h" #include "I2NPProtocol.h" #include "Transports.h" #include "NetDb.hpp" @@ -333,5 +334,72 @@ namespace data ScheduleManageRequests (); } } + + void NetDbRequests::PostDatabaseSearchReplyMsg (std::shared_ptr msg) + { + GetIOService ().post ([this, msg]() + { + HandleDatabaseSearchReplyMsg (msg); + }); + } + + void NetDbRequests::HandleDatabaseSearchReplyMsg (std::shared_ptr msg) + { + const uint8_t * buf = msg->GetPayload (); + char key[48]; + int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48); + key[l] = 0; + size_t num = buf[32]; // num + LogPrint (eLogDebug, "NetDbReq: DatabaseSearchReply for ", key, " num=", num); + IdentHash ident (buf); + auto dest = FindRequest (ident); + if (dest && dest->IsActive ()) + { + if (!dest->IsExploratory () && (num > 0 || dest->GetNumAttempts () < 3)) // before 3-rd attempt might be just bad luck + { + // try to send next requests + if (!SendNextRequest (dest)) + RequestComplete (ident, nullptr); + } + else + // no more requests for destination possible. delete it + RequestComplete (ident, nullptr); + } + else /*if (!m_FloodfillBootstrap)*/ + { + LogPrint (eLogInfo, "NetDbReq: Unsolicited or late database search reply for ", key); + return; + } + + // try responses + if (num > NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES) + { + LogPrint (eLogWarning, "NetDbReq: Too many peer hashes ", num, " in database search reply, Reduced to ", NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES); + num = NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES; + } + for (size_t i = 0; i < num; i++) + { + const uint8_t * router = buf + 33 + i*32; + char peerHash[48]; + int l1 = i2p::data::ByteStreamToBase64 (router, 32, peerHash, 48); + peerHash[l1] = 0; + LogPrint (eLogDebug, "NetDbReq: ", i, ": ", peerHash); + + auto r = netdb.FindRouter (router); + if (!r || i2p::util::GetMillisecondsSinceEpoch () > r->GetTimestamp () + 3600*1000LL) + { + // router with ident not found or too old (1 hour) + LogPrint (eLogDebug, "NetDbReq: Found new/outdated router. Requesting RouterInfo..."); + /* if(m_FloodfillBootstrap) + RequestDestinationFrom(router, m_FloodfillBootstrap->GetIdentHash(), true); + else */if (!IsRouterBanned (router)) + netdb.RequestDestination (router); + else + LogPrint (eLogDebug, "NetDbReq: Router ", peerHash, " is banned. Skipped"); + } + else + LogPrint (eLogDebug, "NetDbReq: [:|||:]"); + } + } } } diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index e9dd99af..c18c5cd3 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -85,8 +85,11 @@ namespace data std::shared_ptr FindRequest (const IdentHash& ident) const; bool SendNextRequest (std::shared_ptr dest); + void PostDatabaseSearchReplyMsg (std::shared_ptr msg); + private: + void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); void ManageRequests (); // timer void ScheduleManageRequests ();