more attempts to find good peer

This commit is contained in:
orignal 2023-02-01 16:04:09 -05:00
parent 09a1a78bd6
commit bf8eecf407
2 changed files with 92 additions and 9 deletions

View File

@ -815,20 +815,100 @@ namespace transport
} }
} }
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const template<typename Filter>
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer (Filter filter) const
{ {
if (m_Peers.empty ()) return nullptr; if (m_Peers.empty()) return nullptr;
bool found = false;
i2p::data::IdentHash ident; i2p::data::IdentHash ident;
{ {
uint16_t inds[3];
RAND_bytes ((uint8_t *)inds, sizeof (inds));
std::unique_lock<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
inds[0] %= m_Peers.size ();
auto it = m_Peers.begin (); auto it = m_Peers.begin ();
std::advance (it, rand () % m_Peers.size ()); std::advance (it, inds[0]);
if (it == m_Peers.end () || it->second.router || it->second.sessions.empty () || // try random peer
it->second.sessions.front ()->GetSendQueueSize () > PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE) if (it != m_Peers.end () && filter (it->second))
return nullptr; // not connected or overloaded {
ident = it->first; ident = it->first;
} found = true;
return i2p::data::netdb.FindRouter (ident); }
else
{
// try some peers around
auto it1 = m_Peers.begin ();
if (inds[0])
{
// before
inds[1] %= inds[0];
std::advance (it1, (inds[1] + inds[0])/2);
}
else
it1 = it;
auto it2 = it;
if (inds[0] < m_Peers.size () - 1)
{
// after
inds[2] %= (m_Peers.size () - 1 - inds[0]); inds[2] /= 2;
std::advance (it2, inds[2]);
}
// it1 - from, it2 - to
it = it1;
while (it != it2 && it != m_Peers.end ())
{
if (filter (it->second))
{
ident = it->first;
found = true;
break;
}
it++;
}
if (!found)
{
// still not found, try from the beginning
it = m_Peers.begin ();
while (it != it1 && it != m_Peers.end ())
{
if (filter (it->second))
{
ident = it->first;
found = true;
break;
}
it++;
}
if (!found)
{
// still not found, try to the beginning
it = it2;
while (it != m_Peers.end ())
{
if (filter (it->second))
{
ident = it->first;
found = true;
break;
}
it++;
}
}
}
}
}
return found ? i2p::data::netdb.FindRouter (ident) : nullptr;
}
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const
{
return GetRandomPeer (
[](const Peer& peer)->bool
{
// connected and not overloaded
return !peer.router && !peer.sessions.empty () &&
peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE;
});
} }
void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families) void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families)

View File

@ -163,6 +163,9 @@ namespace transport
void DetectExternalIP (); void DetectExternalIP ();
template<typename Filter>
std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer (Filter filter) const;
private: private:
volatile bool m_IsOnline; volatile bool m_IsOnline;