Browse Source

RAND_bytes from random router selection

pull/1687/head
orignal 3 years ago
parent
commit
367df4d0db
  1. 75
      libi2pd/NetDb.cpp

75
libi2pd/NetDb.cpp

@ -1223,47 +1223,54 @@ namespace data @@ -1223,47 +1223,54 @@ namespace data
{
if (m_RouterInfos.empty())
return 0;
uint16_t inds[3];
RAND_bytes ((uint8_t *)inds, sizeof (inds));
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
auto ind = rand () % m_RouterInfos.size ();
inds[0] %= m_RouterInfos.size ();
auto it = m_RouterInfos.begin ();
std::advance (it, ind);
std::advance (it, inds[0]);
// try random router
if (it != m_RouterInfos.end () && !it->second->IsUnreachable () && filter (it->second))
return it->second;
// try routers after
auto it1 = it; it1++;
while (it1 != m_RouterInfos.end ())
// try some routers around
auto it1 = m_RouterInfos.begin ();
if (inds[0])
{
if (!it1->second->IsUnreachable () && filter (it1->second))
return it1->second;
it1++;
// before
inds[1] %= inds[0];
std::advance (it1, inds[1]);
}
// still not found, try some routers before
if (ind)
{
ind = rand () % ind;
it1 = m_RouterInfos.begin ();
std::advance (it1, ind);
auto it2 = it1;
while (it2 != it && it2 != m_RouterInfos.end ())
{
if (!it2->second->IsUnreachable () && filter (it2->second))
return it2->second;
it2++;
}
if (ind)
{
// still not found, try from the begining
it2 = m_RouterInfos.begin ();
while (it2 != it1 && it2 != m_RouterInfos.end ())
{
if (!it2->second->IsUnreachable () && filter (it2->second))
return it2->second;
it2++;
}
}
}
auto it2 = it;
if (inds[0] < m_RouterInfos.size () - 1)
{
// after
inds[2] %= (m_RouterInfos.size () - 1 - inds[0]);
std::advance (it2, inds[2]);
}
// it1 - from, it2 - to
it = it1;
while (it != it2 && it != m_RouterInfos.end ())
{
if (!it->second->IsUnreachable () && filter (it->second))
return it->second;
it++;
}
// still not found, try from the begining
it = m_RouterInfos.begin ();
while (it != it1 && it != m_RouterInfos.end ())
{
if (!it->second->IsUnreachable () && filter (it->second))
return it->second;
it++;
}
// still not found, try to the begining
it = it2;
while (it != m_RouterInfos.end ())
{
if (!it->second->IsUnreachable () && filter (it->second))
return it->second;
it++;
}
return nullptr; // seems we have too few routers
}

Loading…
Cancel
Save