Compare commits

...

4 Commits

@ -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
@ -1457,12 +1457,18 @@ namespace data
size_t num, const std::set<IdentHash>& excluded)
{
std::vector<IdentHash> ret;
if (!num) return ret; // empty list
if (!num || m_RouterInfos.empty ()) return ret; // empty list
auto ts = i2p::util::GetMonotonicSeconds ();
if (ts > m_LastExploratorySelectionUpdateTime + NETDB_EXPLORATORY_SELECTION_UPDATE_INTERVAL)
{
// update selection
m_ExploratorySelection.clear ();
#if (__cplusplus >= 201703L) // C++ 17 or higher
std::vector<std::shared_ptr<const RouterInfo> > eligible;
eligible.reserve (m_RouterInfos.size ());
#else
auto& eligible = m_ExploratorySelection;
#endif
{
// collect eligible from current netdb
bool checkIsReal = i2p::tunnel::tunnels.GetPreciseTunnelCreationSuccessRate () < NETDB_TUNNEL_CREATION_RATE_THRESHOLD; // too low rate
@ -1470,14 +1476,24 @@ namespace data
for (const auto& it: m_RouterInfos)
if (!it.second->IsDeclaredFloodfill () &&
(!checkIsReal || (it.second->HasProfile () && it.second->GetProfile ()->IsReal ())))
m_ExploratorySelection.push_back (it.second);
eligible.push_back (it.second);
}
#if (__cplusplus >= 201703L) // C++ 17 or higher
if (eligible.size () > NETDB_MAX_EXPLORATORY_SELECTION_SIZE)
{
std::sample (eligible.begin(), eligible.end(), std::back_inserter(m_ExploratorySelection),
NETDB_MAX_EXPLORATORY_SELECTION_SIZE, std::mt19937(std::random_device()()));
}
else
std::swap (m_ExploratorySelection, eligible);
#else
if (m_ExploratorySelection.size () > NETDB_MAX_EXPLORATORY_SELECTION_SIZE)
{
// reduce number of eligible to max selection size
std::shuffle (m_ExploratorySelection.begin(), m_ExploratorySelection.end(), std::mt19937(std::random_device()()));
m_ExploratorySelection.resize (NETDB_MAX_EXPLORATORY_SELECTION_SIZE);
}
#endif
m_LastExploratorySelectionUpdateTime = ts;
}

@ -81,22 +81,28 @@ namespace data
void RequestedDestination::Success (std::shared_ptr<RouterInfo> 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 ()
@ -121,22 +127,20 @@ namespace data
if (!ret.second) // not inserted
{
dest->SetRequestComplete (nullptr); // don't call requestComplete in destructor
if (requestComplete)
dest = ret.first->second; // existing one
if (requestComplete && dest->IsActive ())
{
auto prev = ret.first->second->GetRequestComplete ();
auto prev = dest->GetRequestComplete ();
if (prev) // if already set
ret.first->second->SetRequestComplete (
dest->SetRequestComplete (
[requestComplete, prev](std::shared_ptr<RouterInfo> r)
{
prev (r); // call previous
requestComplete (r); // then new
});
else
ret.first->second->SetRequestComplete (requestComplete);
dest->SetRequestComplete (requestComplete);
}
if (i2p::util::GetSecondsSinceEpoch () > ret.first->second->GetLastRequestTime () + MIN_REQUEST_TIME)
if (!SendNextRequest (ret.first->second)) // try next floodfill
m_RequestedDestinations.erase (ret.first); // delete request if failed
return nullptr;
}
}
@ -152,7 +156,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,30 +186,43 @@ 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);
}
}
bool NetDbRequests::SendNextRequest (std::shared_ptr<RequestedDestination> dest)
{
if (!dest) return false;
if (!dest || !dest->IsActive ()) return false;
bool ret = true;
auto count = dest->GetNumExcludedPeers ();
if (!dest->IsExploratory () && count < MAX_NUM_REQUEST_ATTEMPTS)

@ -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
{

@ -328,7 +328,6 @@ namespace transport
{
if (m_PeerCleanupTimer) m_PeerCleanupTimer->cancel ();
if (m_PeerTestTimer) m_PeerTestTimer->cancel ();
m_Peers.clear ();
if (m_SSU2Server)
{
@ -353,6 +352,7 @@ namespace transport
delete m_Thread;
m_Thread = nullptr;
}
m_Peers.clear ();
}
void Transports::Run ()

Loading…
Cancel
Save