diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 318db953..0768b838 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -111,6 +111,9 @@ namespace data case eI2NPDatabaseLookup: HandleDatabaseLookupMsg (msg); break; + case eI2NPDeliveryStatus: + HandleDeliveryStatusMsg (msg); + break; case eI2NPDummyMsg: // plain RouterInfo from NTCP2 with flags for now HandleNTCP2RouterInfoMsg (msg); @@ -148,10 +151,12 @@ namespace data lastDestinationCleanup = ts; } - if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL) // update timestamp and publish + if (!m_HiddenMode && i2p::transport::transports.IsOnline () && + ((m_PublishReplyToken && ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) || + ts - lastPublish >= NETDB_PUBLISH_INTERVAL)) // update timestamp and publish { i2p::context.UpdateTimestamp (ts); - if (!m_HiddenMode) Publish (); + Publish (); lastPublish = ts; } if (ts - lastExploratory >= 30) // exploratory every 30 seconds @@ -992,6 +997,16 @@ namespace data } } + void NetDb::HandleDeliveryStatusMsg (std::shared_ptr msg) + { + if (m_PublishReplyToken == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) + { + LogPrint (eLogInfo, "NetDb: Publishing confirmed. reply token=", m_PublishReplyToken); + m_PublishExcluded.clear (); + m_PublishReplyToken = 0; + } + } + void NetDb::Explore (int numDestinations) { // new requests @@ -1045,18 +1060,22 @@ namespace data void NetDb::Publish () { i2p::context.UpdateStats (); // for floodfill - std::set excluded; // TODO: fill up later - for (int i = 0; i < 2; i++) + + if (m_PublishExcluded.size () > NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS) { - auto floodfill = GetClosestFloodfill (i2p::context.GetRouterInfo ().GetIdentHash (), excluded); - if (floodfill) - { - uint32_t replyToken; - RAND_bytes ((uint8_t *)&replyToken, 4); - LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); - transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); - excluded.insert (floodfill->GetIdentHash ()); - } + LogPrint (eLogError, "NetDb: Couldn't publish our RouterInfo to ", NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again"); + m_PublishExcluded.clear (); + } + + auto floodfill = GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded); + if (floodfill) + { + uint32_t replyToken; + RAND_bytes ((uint8_t *)&replyToken, 4); + LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); + m_PublishExcluded.insert (floodfill->GetIdentHash ()); + m_PublishReplyToken = replyToken; + transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); } } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index f9a57ccd..afd1f562 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -41,6 +41,8 @@ namespace data 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_PUBLISH_INTERVAL = 60 * 40; + const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds + const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 /** function for visiting a leaseset stored in a floodfill */ @@ -77,6 +79,7 @@ namespace data void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); void HandleDatabaseLookupMsg (std::shared_ptr msg); void HandleNTCP2RouterInfoMsg (std::shared_ptr m); + void HandleDeliveryStatusMsg (std::shared_ptr msg); std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith) const; @@ -115,6 +118,8 @@ namespace data void ClearRouterInfos () { m_RouterInfos.clear (); }; + uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; }; + private: void Load (); @@ -162,9 +167,11 @@ namespace data /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ std::shared_ptr m_FloodfillBootstrap; - /** true if in hidden mode */ bool m_HiddenMode; + + std::set m_PublishExcluded; + uint32_t m_PublishReplyToken = 0; }; extern NetDb netdb; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 74f8ad34..375e0b9a 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -670,8 +670,13 @@ namespace i2p void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - std::unique_lock l(m_GarlicMutex); - i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); + if (i2p::data::netdb.GetPublishReplyToken () == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) + i2p::data::netdb.PostI2NPMsg (msg); + else + { + std::unique_lock l(m_GarlicMutex); + i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); + } } void RouterContext::CleanupDestination ()