redunant lookups for lns.

* request lns from all endpoints we have on our pathset
* make sure all snodes agree on the lns name being looked up
pull/1541/head
Jeff Becker 3 years ago
parent ec242447a0
commit 7a11f3b1e3
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -201,6 +201,7 @@ add_library(liblokinet
service/info.cpp
service/intro_set.cpp
service/intro.cpp
service/lns_tracker.cpp
service/lookup.cpp
service/name.cpp
service/outbound_context.cpp

@ -808,12 +808,39 @@ namespace llarp
handler(maybe);
return true;
}
auto path = PickRandomEstablishedPath();
if (path == nullptr)
return false;
LogInfo(Name(), " looking up LNS name: ", name);
auto job = new LookupNameJob(this, GenTXID(), name, handler);
return job->SendRequestViaPath(path, m_router);
path::Path::UniqueEndpointSet_t paths;
ForEachPath([&](auto path) {
if (path->IsReady())
{
paths.insert(path);
}
});
// not enough paths
if (paths.size() < 3)
{
handler(std::nullopt);
return true;
}
auto maybeInvalidateCache = [handler, &cache, name](auto result) {
if (not result)
{
cache.Remove(name);
}
handler(result);
};
auto resultHandler =
m_state->lnsTracker.MakeResultHandler(name, paths.size(), maybeInvalidateCache);
for (const auto& path : paths)
{
LogInfo(Name(), " lookup ", name, " from ", path->Endpoint());
auto job = new LookupNameJob(this, GenTXID(), name, resultHandler);
job->SendRequestViaPath(path, m_router);
}
return true;
}
bool
@ -826,12 +853,6 @@ namespace llarp
// decrypt entry
const auto maybe = msg->result.Decrypt(itr->second->name);
if (maybe.has_value())
{
// put cache entry for result
m_state->nameCache.Put(itr->second->name, *maybe);
}
// inform result
itr->second->HandleNameResponse(maybe);
lookups.erase(itr);

@ -10,6 +10,7 @@
#include <llarp/util/compare_ptr.hpp>
#include <llarp/util/decaying_hashtable.hpp>
#include <llarp/util/status.hpp>
#include "lns_tracker.hpp"
#include <memory>
#include <queue>
@ -66,6 +67,8 @@ namespace llarp
util::DecayingHashTable<std::string, Address, std::hash<std::string>> nameCache;
LNSLookupTracker lnsTracker;
bool
Configure(const NetworkConfig& conf);

@ -0,0 +1,41 @@
#include "lns_tracker.hpp"
namespace llarp::service
{
std::function<void(std::optional<Address>)>
LNSLookupTracker::MakeResultHandler(
std::string name,
std::size_t numPeers,
std::function<void(std::optional<Address>)> resultHandler)
{
auto itr = m_PendingLookups.emplace(name, LookupInfo{numPeers, resultHandler}).first;
auto& request = itr->second;
return [&, name](std::optional<Address> found) {
if (request.HandleOneResult(found))
m_PendingLookups.erase(name);
};
}
bool
LNSLookupTracker::LookupInfo::HandleOneResult(std::optional<Address> result)
{
if (result)
{
m_CurrentValues.insert(*result);
}
m_ResultsGotten++;
if (m_ResultsGotten == m_ResultsNeeded)
{
if (m_CurrentValues.size() == 1)
{
m_HandleResult(*m_CurrentValues.begin());
}
else
{
m_HandleResult(std::nullopt);
}
return true;
}
return false;
}
} // namespace llarp::service

@ -0,0 +1,45 @@
#pragma once
#include <functional>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include "address.hpp"
namespace llarp::service
{
/// tracks and manages consensus of lns names we fetch from the network
class LNSLookupTracker
{
struct LookupInfo
{
std::unordered_set<Address> m_CurrentValues;
std::function<void(std::optional<Address>)> m_HandleResult;
std::size_t m_ResultsGotten = 0;
std::size_t m_ResultsNeeded;
LookupInfo(std::size_t wantResults, std::function<void(std::optional<Address>)> resultHandler)
: m_HandleResult{std::move(resultHandler)}, m_ResultsNeeded{wantResults}
{}
/// return true to remove self
bool
HandleOneResult(std::optional<Address> result);
};
std::unordered_map<std::string, LookupInfo> m_PendingLookups;
public:
/// make a function that will handle consensus of an lns request
/// name is the name we are requesting
/// numPeers is the number of peers we asked
/// resultHandler is a function that we are wrapping that will handle the final result
std::function<void(std::optional<Address>)>
MakeResultHandler(
std::string name,
std::size_t numPeers,
std::function<void(std::optional<Address>)> resultHandler);
};
} // namespace llarp::service

@ -17,6 +17,7 @@ namespace llarp::util
EraseIf([&](const auto& item) { return item.second.second + m_CacheInterval <= now; });
}
/// return if we have this value by key
bool
Has(const Key_t& k) const
{
@ -33,6 +34,7 @@ namespace llarp::util
return m_Values.try_emplace(std::move(key), std::make_pair(std::move(value), now)).second;
}
/// get value by key
std::optional<Value_t>
Get(Key_t k) const
{
@ -42,6 +44,13 @@ namespace llarp::util
return itr->second.first;
}
/// explicit remove an item from the cache by key
void
Remove(const Key_t& key)
{
m_Values.erase(key);
}
private:
template <typename Predicate_t>
void

Loading…
Cancel
Save