|
|
@ -55,7 +55,7 @@ namespace data |
|
|
|
Load (); |
|
|
|
Load (); |
|
|
|
|
|
|
|
|
|
|
|
uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold); |
|
|
|
uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold); |
|
|
|
if (m_RouterInfos.size () < threshold || m_Floodfills.size () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils
|
|
|
|
if (m_RouterInfos.size () < threshold || m_Floodfills.GetSize () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils
|
|
|
|
{ |
|
|
|
{ |
|
|
|
Reseed (); |
|
|
|
Reseed (); |
|
|
|
} |
|
|
|
} |
|
|
@ -66,13 +66,13 @@ namespace data |
|
|
|
if (it != m_RouterInfos.end ()) |
|
|
|
if (it != m_RouterInfos.end ()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// remove own router
|
|
|
|
// remove own router
|
|
|
|
m_Floodfills.remove (it->second); |
|
|
|
m_Floodfills.Remove (it->second->GetIdentHash ()); |
|
|
|
m_RouterInfos.erase (it); |
|
|
|
m_RouterInfos.erase (it); |
|
|
|
} |
|
|
|
} |
|
|
|
// insert own router
|
|
|
|
// insert own router
|
|
|
|
m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ()); |
|
|
|
m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ()); |
|
|
|
if (i2p::context.IsFloodfill ()) |
|
|
|
if (i2p::context.IsFloodfill ()) |
|
|
|
m_Floodfills.push_back (i2p::context.GetSharedRouterInfo ()); |
|
|
|
m_Floodfills.Insert (i2p::context.GetSharedRouterInfo ()); |
|
|
|
|
|
|
|
|
|
|
|
i2p::config::GetOption("persist.profiles", m_PersistProfiles); |
|
|
|
i2p::config::GetOption("persist.profiles", m_PersistProfiles); |
|
|
|
|
|
|
|
|
|
|
@ -88,7 +88,7 @@ namespace data |
|
|
|
SaveProfiles (); |
|
|
|
SaveProfiles (); |
|
|
|
DeleteObsoleteProfiles (); |
|
|
|
DeleteObsoleteProfiles (); |
|
|
|
m_RouterInfos.clear (); |
|
|
|
m_RouterInfos.clear (); |
|
|
|
m_Floodfills.clear (); |
|
|
|
m_Floodfills.Clear (); |
|
|
|
if (m_Thread) |
|
|
|
if (m_Thread) |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_IsRunning = false; |
|
|
|
m_IsRunning = false; |
|
|
@ -289,7 +289,7 @@ namespace data |
|
|
|
if (wasFloodfill) |
|
|
|
if (wasFloodfill) |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
m_Floodfills.remove (r); |
|
|
|
m_Floodfills.Remove (r->GetIdentHash ()); |
|
|
|
} |
|
|
|
} |
|
|
|
m_Requests.RequestComplete (ident, nullptr); |
|
|
|
m_Requests.RequestComplete (ident, nullptr); |
|
|
|
return nullptr; |
|
|
|
return nullptr; |
|
|
@ -301,9 +301,9 @@ namespace data |
|
|
|
LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); |
|
|
|
LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
if (wasFloodfill) |
|
|
|
if (wasFloodfill) |
|
|
|
m_Floodfills.remove (r); |
|
|
|
m_Floodfills.Remove (r->GetIdentHash ()); |
|
|
|
else if (r->IsEligibleFloodfill ()) |
|
|
|
else if (r->IsEligibleFloodfill ()) |
|
|
|
m_Floodfills.push_back (r); |
|
|
|
m_Floodfills.Insert (r); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
@ -329,7 +329,7 @@ namespace data |
|
|
|
if (r->IsFloodfill () && r->IsEligibleFloodfill ()) |
|
|
|
if (r->IsFloodfill () && r->IsEligibleFloodfill ()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
m_Floodfills.push_back (r); |
|
|
|
m_Floodfills.Insert (r); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
@ -530,7 +530,7 @@ namespace data |
|
|
|
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second) |
|
|
|
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (r->IsFloodfill () && r->IsEligibleFloodfill ()) |
|
|
|
if (r->IsFloodfill () && r->IsEligibleFloodfill ()) |
|
|
|
m_Floodfills.push_back (r); |
|
|
|
m_Floodfills.Insert (r); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
@ -614,7 +614,7 @@ namespace data |
|
|
|
{ |
|
|
|
{ |
|
|
|
// make sure we cleanup netDb from previous attempts
|
|
|
|
// make sure we cleanup netDb from previous attempts
|
|
|
|
m_RouterInfos.clear (); |
|
|
|
m_RouterInfos.clear (); |
|
|
|
m_Floodfills.clear (); |
|
|
|
m_Floodfills.Clear (); |
|
|
|
|
|
|
|
|
|
|
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); |
|
|
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); |
|
|
|
std::vector<std::string> files; |
|
|
|
std::vector<std::string> files; |
|
|
@ -622,14 +622,14 @@ namespace data |
|
|
|
for (const auto& path : files) |
|
|
|
for (const auto& path : files) |
|
|
|
LoadRouterInfo (path, ts); |
|
|
|
LoadRouterInfo (path, ts); |
|
|
|
|
|
|
|
|
|
|
|
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)"); |
|
|
|
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.GetSize (), " floodfils)"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void NetDb::SaveUpdated () |
|
|
|
void NetDb::SaveUpdated () |
|
|
|
{ |
|
|
|
{ |
|
|
|
int updatedCount = 0, deletedCount = 0, deletedFloodfillsCount = 0; |
|
|
|
int updatedCount = 0, deletedCount = 0, deletedFloodfillsCount = 0; |
|
|
|
auto total = m_RouterInfos.size (); |
|
|
|
auto total = m_RouterInfos.size (); |
|
|
|
auto totalFloodfills = m_Floodfills.size (); |
|
|
|
auto totalFloodfills = m_Floodfills.GetSize (); |
|
|
|
uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; |
|
|
|
uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; |
|
|
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); |
|
|
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); |
|
|
|
auto uptime = i2p::context.GetUptime (); |
|
|
|
auto uptime = i2p::context.GetUptime (); |
|
|
@ -721,11 +721,10 @@ namespace data |
|
|
|
// clean up expired floodfills or not floodfills anymore
|
|
|
|
// clean up expired floodfills or not floodfills anymore
|
|
|
|
{ |
|
|
|
{ |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
for (auto it = m_Floodfills.begin (); it != m_Floodfills.end ();) |
|
|
|
m_Floodfills.Cleanup ([](const std::shared_ptr<RouterInfo>& r)->bool |
|
|
|
if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ()) |
|
|
|
{ |
|
|
|
it = m_Floodfills.erase (it); |
|
|
|
return r && r->IsFloodfill () && !r->IsUnreachable (); |
|
|
|
else |
|
|
|
}); |
|
|
|
it++; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1362,75 +1361,38 @@ namespace data |
|
|
|
std::shared_ptr<const RouterInfo> NetDb::GetClosestFloodfill (const IdentHash& destination, |
|
|
|
std::shared_ptr<const RouterInfo> NetDb::GetClosestFloodfill (const IdentHash& destination, |
|
|
|
const std::set<IdentHash>& excluded) const |
|
|
|
const std::set<IdentHash>& excluded) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::shared_ptr<const RouterInfo> r; |
|
|
|
|
|
|
|
XORMetric minMetric; |
|
|
|
|
|
|
|
IdentHash destKey = CreateRoutingKey (destination); |
|
|
|
IdentHash destKey = CreateRoutingKey (destination); |
|
|
|
minMetric.SetMax (); |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
for (const auto& it: m_Floodfills) |
|
|
|
return m_Floodfills.FindClosest (destKey, [&excluded](const std::shared_ptr<RouterInfo>& r)->bool |
|
|
|
{ |
|
|
|
|
|
|
|
if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ()) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
XORMetric m = destKey ^ it->GetIdentHash (); |
|
|
|
return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && |
|
|
|
if (m < minMetric && !excluded.count (it->GetIdentHash ())) |
|
|
|
!excluded.count (r->GetIdentHash ()); |
|
|
|
{ |
|
|
|
}); |
|
|
|
minMetric = m; |
|
|
|
|
|
|
|
r = it; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num, |
|
|
|
std::vector<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num, |
|
|
|
std::set<IdentHash>& excluded, bool closeThanUsOnly) const |
|
|
|
std::set<IdentHash>& excluded, bool closeThanUsOnly) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct Sorted |
|
|
|
std::vector<IdentHash> res; |
|
|
|
{ |
|
|
|
|
|
|
|
std::shared_ptr<const RouterInfo> r; |
|
|
|
|
|
|
|
XORMetric metric; |
|
|
|
|
|
|
|
bool operator< (const Sorted& other) const { return metric < other.metric; }; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::set<Sorted> sorted; |
|
|
|
|
|
|
|
IdentHash destKey = CreateRoutingKey (destination); |
|
|
|
IdentHash destKey = CreateRoutingKey (destination); |
|
|
|
XORMetric ourMetric; |
|
|
|
std::vector<std::shared_ptr<RouterInfo> > v; |
|
|
|
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex); |
|
|
|
for (const auto& it: m_Floodfills) |
|
|
|
v = m_Floodfills.FindClosest (destKey, num, [&excluded](const std::shared_ptr<RouterInfo>& r)->bool |
|
|
|
{ |
|
|
|
|
|
|
|
if (!it->IsUnreachable () && !it->GetProfile ()->IsUnreachable ()) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
XORMetric m = destKey ^ it->GetIdentHash (); |
|
|
|
return r && !r->IsUnreachable () && !r->GetProfile ()->IsUnreachable () && |
|
|
|
if (closeThanUsOnly && ourMetric < m) continue; |
|
|
|
!excluded.count (r->GetIdentHash ()); |
|
|
|
if (sorted.size () < num) |
|
|
|
}); |
|
|
|
sorted.insert ({it, m}); |
|
|
|
} |
|
|
|
else if (m < sorted.rbegin ()->metric) |
|
|
|
if (v.empty ()) return res; |
|
|
|
{ |
|
|
|
|
|
|
|
sorted.insert ({it, m}); |
|
|
|
XORMetric ourMetric; |
|
|
|
sorted.erase (std::prev (sorted.end ())); |
|
|
|
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); |
|
|
|
} |
|
|
|
for (auto& it: v) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<IdentHash> res; |
|
|
|
|
|
|
|
size_t i = 0; |
|
|
|
|
|
|
|
for (const auto& it: sorted) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
if (i < num) |
|
|
|
if (closeThanUsOnly && ourMetric < (destKey ^ it->GetIdentHash ())) break; |
|
|
|
{ |
|
|
|
res.push_back (it->GetIdentHash ()); |
|
|
|
const auto& ident = it.r->GetIdentHash (); |
|
|
|
} |
|
|
|
if (!excluded.count (ident)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
res.push_back (ident); |
|
|
|
|
|
|
|
i++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return res; |
|
|
|
return res; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|