diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index b244b52f..7cae9bca 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -780,7 +780,7 @@ namespace data auto dest = m_Requests.CreateRequest (destination, false, direct, requestComplete); // non-exploratory if (!dest) { - LogPrint (eLogWarning, "NetDb: Destination ", destination.ToBase64(), " is requested already"); + LogPrint (eLogWarning, "NetDb: Destination ", destination.ToBase64(), " is requested already or cached"); return; } @@ -1000,7 +1000,7 @@ namespace data LogPrint (eLogDebug, "NetDb: DatabaseSearchReply for ", key, " num=", num); IdentHash ident (buf); auto dest = m_Requests.FindRequest (ident); - if (dest) + if (dest && dest->IsActive ()) { if (!dest->IsExploratory () && (num > 0 || dest->GetNumExcludedPeers () < 3)) // before 3-rd attempt might be just bad luck // try to send next requests diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 0bce4a1f..67b8d1ee 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -81,22 +81,28 @@ namespace data void RequestedDestination::Success (std::shared_ptr r) { - m_IsActive = false; - if (m_RequestComplete) - { - m_RequestComplete (r); - m_RequestComplete = nullptr; - } + if (m_IsActive) + { + m_IsActive = false; + if (m_RequestComplete) + { + m_RequestComplete (r); + m_RequestComplete = nullptr; + } + } } void RequestedDestination::Fail () { - m_IsActive = false; - if (m_RequestComplete) - { - m_RequestComplete (nullptr); - m_RequestComplete = nullptr; - } + if (m_IsActive) + { + m_IsActive = false; + if (m_RequestComplete) + { + m_RequestComplete (nullptr); + m_RequestComplete = nullptr; + } + } } void NetDbRequests::Start () @@ -152,7 +158,9 @@ namespace data if (it != m_RequestedDestinations.end ()) { request = it->second; - m_RequestedDestinations.erase (it); + if (request->IsExploratory ()) + m_RequestedDestinations.erase (it); + // otherwise cache for a while } } if (request) @@ -180,24 +188,37 @@ namespace data for (auto it = m_RequestedDestinations.begin (); it != m_RequestedDestinations.end ();) { auto& dest = it->second; - bool done = false; - if (!dest->IsExploratory ()) + if (dest->IsActive () || ts < dest->GetCreationTime () + REQUEST_CACHE_TIME) { - if (ts < dest->GetCreationTime () + MAX_REQUEST_TIME) // request becomes worthless - { - if (ts > dest->GetLastRequestTime () + MIN_REQUEST_TIME) // try next floodfill if no response after min interval - done = !SendNextRequest (dest); - } - else // delete obsolete request - done = true; + if (!dest->IsExploratory ()) + { + // regular request + bool done = false; + if (ts < dest->GetCreationTime () + MAX_REQUEST_TIME) + { + if (ts > dest->GetLastRequestTime () + MIN_REQUEST_TIME) // try next floodfill if no response after min interval + done = !SendNextRequest (dest); + } + else // request is expired + done = true; + if (done) + dest->Fail (); + it++; + } + else + { + // exploratory + if (ts >= dest->GetCreationTime () + MAX_EXPLORATORY_REQUEST_TIME) + { + dest->Fail (); + it = m_RequestedDestinations.erase (it); // delete expired exploratory request right a way + } + else + it++; + } } - else if (ts >= dest->GetCreationTime () + MAX_EXPLORATORY_REQUEST_TIME) - done = true; - - if (done) - it = m_RequestedDestinations.erase (it); else - ++it; + it = m_RequestedDestinations.erase (it); } } diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index 01cc8153..fb54d0fc 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -25,6 +25,7 @@ namespace data 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_EXPLORATORY_REQUEST_TIME = 30; // in seconds + const uint64_t REQUEST_CACHE_TIME = MAX_REQUEST_TIME + 40; // in seconds class RequestedDestination {