return up to 16 hash in expolatory reply

gha
orignal 1 month ago
parent 5ed76b997c
commit ec59308fad

@ -9,6 +9,8 @@
#include <string.h> #include <string.h>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <map>
#include <random>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <stdexcept> #include <stdexcept>
@ -992,7 +994,7 @@ namespace data
char key[48]; char key[48];
int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48); int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48);
key[l] = 0; key[l] = 0;
int num = buf[32]; // num size_t num = buf[32]; // num
LogPrint (eLogDebug, "NetDb: DatabaseSearchReply for ", key, " num=", num); LogPrint (eLogDebug, "NetDb: DatabaseSearchReply for ", key, " num=", num);
IdentHash ident (buf); IdentHash ident (buf);
auto dest = m_Requests.FindRequest (ident); auto dest = m_Requests.FindRequest (ident);
@ -1012,7 +1014,12 @@ namespace data
} }
// try responses // try responses
for (int i = 0; i < num; i++) if (num > NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES)
{
LogPrint (eLogWarning, "NetDb: Too many peer hashes ", num, " in database search reply, Reduced to ", NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES);
num = NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES;
}
for (size_t i = 0; i < num; i++)
{ {
const uint8_t * router = buf + 33 + i*32; const uint8_t * router = buf + 33 + i*32;
char peerHash[48]; char peerHash[48];
@ -1087,17 +1094,8 @@ namespace data
excludedRouters.insert (excluded_ident); excludedRouters.insert (excluded_ident);
excluded_ident += 32; excluded_ident += 32;
} }
std::vector<IdentHash> routers; replyMsg = CreateDatabaseSearchReply (ident, GetClosestNonFloodfill (ident,
for (int i = 0; i < 3; i++) NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES, excludedRouters));
{
auto r = GetClosestNonFloodfill (ident, excludedRouters);
if (r)
{
routers.push_back (r->GetIdentHash ());
excludedRouters.insert (r->GetIdentHash ());
}
}
replyMsg = CreateDatabaseSearchReply (ident, routers);
} }
else else
{ {
@ -1453,29 +1451,39 @@ namespace data
}); });
} }
std::shared_ptr<const RouterInfo> NetDb::GetClosestNonFloodfill (const IdentHash& destination, std::vector<IdentHash> NetDb::GetClosestNonFloodfill (const IdentHash& destination,
const std::set<IdentHash>& excluded) const size_t num, const std::set<IdentHash>& excluded) const
{ {
std::shared_ptr<const RouterInfo> r; std::vector<IdentHash> ret;
XORMetric minMetric; if (!num) return ret; // empty list
IdentHash destKey = CreateRoutingKey (destination); // collect eligible
minMetric.SetMax (); std::vector<std::shared_ptr<const RouterInfo> > eligible;
// must be called from NetDb thread only eligible.reserve (NETDB_NUM_ROUTERS_THRESHOLD);
bool checkIsReal = i2p::tunnel::tunnels.GetPreciseTunnelCreationSuccessRate () < NETDB_TUNNEL_CREATION_RATE_THRESHOLD; // too low rate
std::lock_guard<std::mutex> l(m_RouterInfosMutex);
for (const auto& it: m_RouterInfos)
{ {
if (!it.second->IsDeclaredFloodfill () && (!checkIsReal || (it.second->HasProfile () && it.second->GetProfile ()->IsReal ()))) bool checkIsReal = i2p::tunnel::tunnels.GetPreciseTunnelCreationSuccessRate () < NETDB_TUNNEL_CREATION_RATE_THRESHOLD; // too low rate
{ std::lock_guard<std::mutex> l(m_RouterInfosMutex);
XORMetric m = destKey ^ it.first; for (const auto& it: m_RouterInfos)
if (m < minMetric && !excluded.count (it.first)) if (!it.second->IsDeclaredFloodfill () && (!checkIsReal || (it.second->HasProfile () && it.second->GetProfile ()->IsReal ())))
{ eligible.push_back (it.second);
minMetric = m;
r = it.second;
}
}
} }
return r; // reduce number of eligible routers if too many
if (eligible.size () > NETDB_NUM_ROUTERS_THRESHOLD)
{
std::shuffle (eligible.begin(), eligible.end(), std::mt19937(std::random_device()()));
eligible.resize (NETDB_NUM_ROUTERS_THRESHOLD);
}
// sort by distance
IdentHash destKey = CreateRoutingKey (destination);
std::map<XORMetric, std::shared_ptr<const RouterInfo> > sorted;
for (const auto& it: eligible)
sorted.emplace (destKey ^ it->GetIdentHash (), it);
// return first num closest routers
for (const auto& it: sorted)
{
ret.push_back (it.second->GetIdentHash ());
if (ret.size () >= num) break;
}
return ret;
} }
void NetDb::ManageRouterInfos () void NetDb::ManageRouterInfos ()

@ -53,6 +53,7 @@ namespace data
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
const size_t NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES = 16;
/** function for visiting a leaseset stored in a floodfill */ /** function for visiting a leaseset stored in a floodfill */
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor; typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;
@ -97,7 +98,7 @@ namespace data
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const; std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num, std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const; std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const; std::vector<IdentHash> GetClosestNonFloodfill (const IdentHash& destination, size_t num, const std::set<IdentHash>& excluded) const;
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily (FamilyID fam) const; std::shared_ptr<const RouterInfo> GetRandomRouterInFamily (FamilyID fam) const;
void SetUnreachable (const IdentHash& ident, bool unreachable); void SetUnreachable (const IdentHash& ident, bool unreachable);
void ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports); void ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports);

Loading…
Cancel
Save