Fully define interface for dht::Context

pull/339/head
Michael 5 years ago
parent c6e6bdb90f
commit 13a9f65520
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -467,8 +467,9 @@ extern "C"
// llarp::Info("checkOnline - DHT nodes ",
// request->ptr->ctx->router->dht->impl.nodes->nodes.size());
request->online = false;
request->nodes = request->ptr->ctx->router->dht()->impl.nodes->nodes.size();
if(request->ptr->ctx->router->dht()->impl.nodes->nodes.size())
request->nodes =
request->ptr->ctx->router->dht()->impl->Nodes()->nodes.size();
if(request->ptr->ctx->router->dht()->impl->Nodes()->nodes.size())
{
// llarp::Info("checkOnline - Going to say we're online");
request->online = true;

@ -29,9 +29,264 @@ namespace llarp
{
}
struct Context final : public AbstractContext
{
Context();
~Context()
{
}
util::StatusObject
ExtractStatus() const override;
llarp::Crypto*
Crypto() const override;
/// on behalf of whoasked request introset for target from dht router with
/// key askpeer
void
LookupIntroSetRecursive(
const service::Address& target, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer, uint64_t R,
service::IntroSetLookupHandler result = nullptr) override;
void
LookupIntroSetIterative(
const service::Address& target, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer,
service::IntroSetLookupHandler result = nullptr) override;
/// on behalf of whoasked request router with public key target from dht
/// router with key askpeer
void
LookupRouterRecursive(const RouterID& target, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer,
RouterLookupHandler result = nullptr);
bool
LookupRouter(const RouterID& target, RouterLookupHandler result) override
{
Key_t askpeer;
if(!nodes->FindClosest(Key_t(target), askpeer))
{
return false;
}
LookupRouterRecursive(target, OurKey(), 0, askpeer, result);
return true;
}
bool
HasRouterLookup(const RouterID& target) const override
{
return pendingRouterLookups().HasLookupFor(target);
}
/// on behalf of whoasked request introsets with tag from dht router with
/// key askpeer with Recursion depth R
void
LookupTagRecursive(const service::Tag& tag, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer,
uint64_t R) override;
/// issue dht lookup for tag via askpeer and send reply to local path
void
LookupTagForPath(const service::Tag& tag, uint64_t txid,
const llarp::PathID_t& path,
const Key_t& askpeer) override;
/// issue dht lookup for router via askpeer and send reply to local path
void
LookupRouterForPath(const RouterID& target, uint64_t txid,
const PathID_t& path, const Key_t& askpeer) override;
/// issue dht lookup for introset for addr via askpeer and send reply to
/// local path
void
LookupIntroSetForPath(const service::Address& addr, uint64_t txid,
const llarp::PathID_t& path,
const Key_t& askpeer) override;
/// send a dht message to peer, if keepalive is true then keep the session
/// with that peer alive for 10 seconds
void
DHTSendTo(const RouterID& peer, IMessage* msg,
bool keepalive = true) override;
/// get routers closest to target excluding requester
bool
HandleExploritoryRouterLookup(
const Key_t& requester, uint64_t txid, const RouterID& target,
std::vector< std::unique_ptr< IMessage > >& reply) override;
std::set< service::IntroSet >
FindRandomIntroSetsWithTagExcluding(
const service::Tag& tag, size_t max = 2,
const std::set< service::IntroSet >& excludes = {}) override;
/// handle rc lookup from requester for target
void
LookupRouterRelayed(
const Key_t& requester, uint64_t txid, const Key_t& target,
bool recursive,
std::vector< std::unique_ptr< IMessage > >& replies) override;
/// relay a dht message from a local path to the main network
bool
RelayRequestForPath(const llarp::PathID_t& localPath,
const IMessage* msg) override;
/// send introset to peer from source with S counter and excluding peers
void
PropagateIntroSetTo(const Key_t& source, uint64_t sourceTX,
const service::IntroSet& introset, const Key_t& peer,
uint64_t S,
const std::set< Key_t >& exclude) override;
/// initialize dht context and explore every exploreInterval milliseconds
void
Init(const Key_t& us, AbstractRouter* router,
llarp_time_t exploreInterval) override;
/// get localally stored introset by service address
const llarp::service::IntroSet*
GetIntroSetByServiceAddress(
const llarp::service::Address& addr) const override;
static void
handle_cleaner_timer(void* user, uint64_t orig, uint64_t left);
static void
handle_explore_timer(void* user, uint64_t orig, uint64_t left);
/// explore dht for new routers
void
Explore(size_t N = 3);
llarp::AbstractRouter* router;
// for router contacts
std::unique_ptr< Bucket< RCNode > > nodes;
// for introduction sets
std::unique_ptr< Bucket< ISNode > > _services;
Bucket< ISNode >*
services() override
{
return _services.get();
}
bool allowTransit;
bool&
AllowTransit() override
{
return allowTransit;
}
const bool&
AllowTransit() const override
{
return allowTransit;
}
Bucket< RCNode >*
Nodes() const override
{
return nodes.get();
}
const Key_t&
OurKey() const override
{
return ourKey;
}
llarp::AbstractRouter*
GetRouter() const override
{
return router;
}
PendingIntrosetLookups _pendingIntrosetLookups;
PendingTagLookups _pendingTagLookups;
PendingRouterLookups _pendingRouterLookups;
PendingExploreLookups _pendingExploreLookups;
PendingIntrosetLookups&
pendingIntrosetLookups() override
{
return _pendingIntrosetLookups;
}
const PendingIntrosetLookups&
pendingIntrosetLookups() const override
{
return _pendingIntrosetLookups;
}
PendingTagLookups&
pendingTagLookups() override
{
return _pendingTagLookups;
}
const PendingTagLookups&
pendingTagLookups() const override
{
return _pendingTagLookups;
}
PendingRouterLookups&
pendingRouterLookups() override
{
return _pendingRouterLookups;
}
const PendingRouterLookups&
pendingRouterLookups() const override
{
return _pendingRouterLookups;
}
PendingExploreLookups&
pendingExploreLookups() override
{
return _pendingExploreLookups;
}
const PendingExploreLookups&
pendingExploreLookups() const override
{
return _pendingExploreLookups;
}
uint64_t
NextID()
{
return ++ids;
}
llarp_time_t
Now() const override;
void
ExploreNetworkVia(const Key_t& peer) override;
private:
void
ScheduleCleanupTimer();
void
CleanupTX();
uint64_t ids;
Key_t ourKey;
};
Context::Context() : router(nullptr), allowTransit(false)
{
randombytes((byte_t *)&ids, sizeof(uint64_t));
randombytes((byte_t*)&ids, sizeof(uint64_t));
}
void
@ -43,7 +298,7 @@ namespace llarp
if(nodes->GetManyRandom(peers, N))
{
for(const auto &peer : peers)
for(const auto& peer : peers)
ExploreNetworkVia(peer);
}
else
@ -51,42 +306,42 @@ namespace llarp
}
void
Context::ExploreNetworkVia(const Key_t &askpeer)
Context::ExploreNetworkVia(const Key_t& askpeer)
{
uint64_t txid = ++ids;
TXOwner peer(askpeer, txid);
TXOwner whoasked(OurKey(), txid);
pendingExploreLookups.NewTX(
pendingExploreLookups().NewTX(
peer, whoasked, askpeer.as_array(),
new ExploreNetworkJob(askpeer.as_array(), this));
}
void
Context::handle_explore_timer(void *u, uint64_t orig, uint64_t left)
Context::handle_explore_timer(void* u, uint64_t orig, uint64_t left)
{
if(left)
return;
Context *ctx = static_cast< Context * >(u);
Context* ctx = static_cast< Context* >(u);
ctx->Explore(1);
ctx->router->logic()->call_later({orig, ctx, &handle_explore_timer});
}
void
Context::handle_cleaner_timer(void *u,
Context::handle_cleaner_timer(void* u,
__attribute__((unused)) uint64_t orig,
uint64_t left)
{
if(left)
return;
Context *ctx = static_cast< Context * >(u);
Context* ctx = static_cast< Context* >(u);
// clean up transactions
ctx->CleanupTX();
if(ctx->services)
if(ctx->_services)
{
// expire intro sets
auto now = ctx->Now();
auto &nodes = ctx->services->nodes;
auto& nodes = ctx->_services->nodes;
auto itr = nodes.begin();
while(itr != nodes.end())
{
@ -104,11 +359,11 @@ namespace llarp
std::set< service::IntroSet >
Context::FindRandomIntroSetsWithTagExcluding(
const service::Tag &tag, size_t max,
const std::set< service::IntroSet > &exclude)
const service::Tag& tag, size_t max,
const std::set< service::IntroSet >& exclude)
{
std::set< service::IntroSet > found;
auto &nodes = services->nodes;
auto& nodes = _services->nodes;
if(nodes.size() == 0)
{
return found;
@ -151,8 +406,8 @@ namespace llarp
void
Context::LookupRouterRelayed(
const Key_t &requester, uint64_t txid, const Key_t &target,
bool recursive, std::vector< std::unique_ptr< IMessage > > &replies)
const Key_t& requester, uint64_t txid, const Key_t& target,
bool recursive, std::vector< std::unique_ptr< IMessage > >& replies)
{
if(target == ourKey)
{
@ -201,13 +456,13 @@ namespace llarp
}
}
const llarp::service::IntroSet *
const llarp::service::IntroSet*
Context::GetIntroSetByServiceAddress(
const llarp::service::Address &addr) const
const llarp::service::Address& addr) const
{
auto key = addr.ToKey();
auto itr = services->nodes.find(key);
if(itr == services->nodes.end())
auto itr = _services->nodes.find(key);
if(itr == _services->nodes.end())
return nullptr;
return &itr->second.introset;
}
@ -218,34 +473,34 @@ namespace llarp
auto now = Now();
llarp::LogDebug("DHT tick");
pendingRouterLookups.Expire(now);
pendingIntrosetLookups.Expire(now);
pendingTagLookups.Expire(now);
pendingExploreLookups.Expire(now);
pendingRouterLookups().Expire(now);
_pendingIntrosetLookups.Expire(now);
pendingTagLookups().Expire(now);
pendingExploreLookups().Expire(now);
}
util::StatusObject
Context::ExtractStatus() const
{
util::StatusObject obj{
{"pendingRouterLookups", pendingRouterLookups.ExtractStatus()},
{"pendingIntrosetLookups", pendingIntrosetLookups.ExtractStatus()},
{"pendingTagLookups", pendingTagLookups.ExtractStatus()},
{"pendingExploreLookups", pendingExploreLookups.ExtractStatus()},
{"pendingRouterLookups", pendingRouterLookups().ExtractStatus()},
{"pendingIntrosetLookups", _pendingIntrosetLookups.ExtractStatus()},
{"pendingTagLookups", pendingTagLookups().ExtractStatus()},
{"pendingExploreLookups", pendingExploreLookups().ExtractStatus()},
{"nodes", nodes->ExtractStatus()},
{"services", services->ExtractStatus()},
{"services", _services->ExtractStatus()},
{"ourKey", ourKey.ToHex()}};
return obj;
}
void
Context::Init(const Key_t &us, AbstractRouter *r,
Context::Init(const Key_t& us, AbstractRouter* r,
llarp_time_t exploreInterval)
{
router = r;
ourKey = us;
nodes = std::make_unique< Bucket< RCNode > >(ourKey, llarp::randint);
services = std::make_unique< Bucket< ISNode > >(ourKey, llarp::randint);
router = r;
ourKey = us;
nodes = std::make_unique< Bucket< RCNode > >(ourKey, llarp::randint);
_services = std::make_unique< Bucket< ISNode > >(ourKey, llarp::randint);
llarp::LogDebug("initialize dht with key ", ourKey);
// start exploring
@ -262,7 +517,7 @@ namespace llarp
}
void
Context::DHTSendTo(const RouterID &peer, IMessage *msg, bool keepalive)
Context::DHTSendTo(const RouterID& peer, IMessage* msg, bool keepalive)
{
llarp::DHTImmediateMessage m;
m.msgs.emplace_back(msg);
@ -275,7 +530,7 @@ namespace llarp
}
bool
Context::RelayRequestForPath(const llarp::PathID_t &id, const IMessage *msg)
Context::RelayRequestForPath(const llarp::PathID_t& id, const IMessage* msg)
{
llarp::routing::DHTMessage reply;
if(!msg->HandleMessage(router->dht(), reply.M))
@ -289,84 +544,84 @@ namespace llarp
}
void
Context::LookupIntroSetForPath(const service::Address &addr, uint64_t txid,
const llarp::PathID_t &path,
const Key_t &askpeer)
Context::LookupIntroSetForPath(const service::Address& addr, uint64_t txid,
const llarp::PathID_t& path,
const Key_t& askpeer)
{
TXOwner asker(OurKey(), txid);
TXOwner peer(askpeer, ++ids);
pendingIntrosetLookups.NewTX(
_pendingIntrosetLookups.NewTX(
peer, asker, addr,
new LocalServiceAddressLookup(path, txid, addr, this, askpeer));
}
void
Context::PropagateIntroSetTo(const Key_t &from, uint64_t txid,
const service::IntroSet &introset,
const Key_t &tellpeer, uint64_t S,
const std::set< Key_t > &exclude)
Context::PropagateIntroSetTo(const Key_t& from, uint64_t txid,
const service::IntroSet& introset,
const Key_t& tellpeer, uint64_t S,
const std::set< Key_t >& exclude)
{
TXOwner asker(from, txid);
TXOwner peer(tellpeer, ++ids);
service::Address addr = introset.A.Addr();
pendingIntrosetLookups.NewTX(
_pendingIntrosetLookups.NewTX(
peer, asker, addr,
new PublishServiceJob(asker, introset, this, S, exclude));
}
void
Context::LookupIntroSetRecursive(const service::Address &addr,
const Key_t &whoasked, uint64_t txid,
const Key_t &askpeer, uint64_t R,
Context::LookupIntroSetRecursive(const service::Address& addr,
const Key_t& whoasked, uint64_t txid,
const Key_t& askpeer, uint64_t R,
service::IntroSetLookupHandler handler)
{
TXOwner asker(whoasked, txid);
TXOwner peer(askpeer, ++ids);
pendingIntrosetLookups.NewTX(
_pendingIntrosetLookups.NewTX(
peer, asker, addr,
new ServiceAddressLookup(asker, addr, this, R, handler));
}
void
Context::LookupIntroSetIterative(const service::Address &addr,
const Key_t &whoasked, uint64_t txid,
const Key_t &askpeer,
Context::LookupIntroSetIterative(const service::Address& addr,
const Key_t& whoasked, uint64_t txid,
const Key_t& askpeer,
service::IntroSetLookupHandler handler)
{
TXOwner asker(whoasked, txid);
TXOwner peer(askpeer, ++ids);
pendingIntrosetLookups.NewTX(
_pendingIntrosetLookups.NewTX(
peer, asker, addr,
new ServiceAddressLookup(asker, addr, this, 0, handler));
}
void
Context::LookupTagRecursive(const service::Tag &tag, const Key_t &whoasked,
uint64_t whoaskedTX, const Key_t &askpeer,
Context::LookupTagRecursive(const service::Tag& tag, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer,
uint64_t R)
{
TXOwner asker(whoasked, whoaskedTX);
TXOwner peer(askpeer, ++ids);
pendingTagLookups.NewTX(peer, asker, tag,
new TagLookup(asker, tag, this, R));
_pendingTagLookups.NewTX(peer, asker, tag,
new TagLookup(asker, tag, this, R));
llarp::LogInfo("ask ", askpeer, " for ", tag, " on behalf of ", whoasked,
" R=", R);
}
void
Context::LookupTagForPath(const service::Tag &tag, uint64_t txid,
const llarp::PathID_t &path, const Key_t &askpeer)
Context::LookupTagForPath(const service::Tag& tag, uint64_t txid,
const llarp::PathID_t& path, const Key_t& askpeer)
{
TXOwner peer(askpeer, ++ids);
TXOwner whoasked(OurKey(), txid);
pendingTagLookups.NewTX(peer, whoasked, tag,
new LocalTagLookup(path, txid, tag, this));
_pendingTagLookups.NewTX(peer, whoasked, tag,
new LocalTagLookup(path, txid, tag, this));
}
bool
Context::HandleExploritoryRouterLookup(
const Key_t &requester, uint64_t txid, const RouterID &target,
std::vector< std::unique_ptr< IMessage > > &reply)
const Key_t& requester, uint64_t txid, const RouterID& target,
std::vector< std::unique_ptr< IMessage > >& reply)
{
std::vector< RouterID > closer;
Key_t t(target.as_array());
@ -397,42 +652,42 @@ namespace llarp
want, " dht peers");
return false;
}
for(const auto &f : found)
for(const auto& f : found)
closer.emplace_back(f.as_array());
reply.emplace_back(new GotRouterMessage(txid, closer, false));
return true;
}
void
Context::LookupRouterForPath(const RouterID &target, uint64_t txid,
const llarp::PathID_t &path,
const Key_t &askpeer)
Context::LookupRouterForPath(const RouterID& target, uint64_t txid,
const llarp::PathID_t& path,
const Key_t& askpeer)
{
TXOwner peer(askpeer, ++ids);
TXOwner whoasked(OurKey(), txid);
pendingRouterLookups.NewTX(
_pendingRouterLookups.NewTX(
peer, whoasked, target,
new LocalRouterLookup(path, txid, target, this));
}
void
Context::LookupRouterRecursive(const RouterID &target,
const Key_t &whoasked, uint64_t txid,
const Key_t &askpeer,
Context::LookupRouterRecursive(const RouterID& target,
const Key_t& whoasked, uint64_t txid,
const Key_t& askpeer,
RouterLookupHandler handler)
{
TXOwner asker(whoasked, txid);
TXOwner peer(askpeer, ++ids);
if(target != askpeer)
{
pendingRouterLookups.NewTX(
_pendingRouterLookups.NewTX(
peer, asker, target,
new RecursiveRouterLookup(asker, target, this, handler));
}
}
llarp::Crypto *
llarp::Crypto*
Context::Crypto() const
{
return router->crypto();

@ -14,6 +14,7 @@
#include <util/time.hpp>
#include <util/status.hpp>
#include <memory>
#include <set>
namespace llarp
@ -22,8 +23,18 @@ namespace llarp
namespace dht
{
struct AbstractContext
struct AbstractContext : public util::IStateful
{
using PendingIntrosetLookups =
TXHolder< service::Address, service::IntroSet,
service::Address::Hash >;
using PendingTagLookups =
TXHolder< service::Tag, service::IntroSet, service::Tag::Hash >;
using PendingRouterLookups =
TXHolder< RouterID, RouterContact, RouterID::Hash >;
using PendingExploreLookups =
TXHolder< RouterID, RouterID, RouterID::Hash >;
virtual ~AbstractContext() = 0;
virtual bool
@ -50,218 +61,122 @@ namespace llarp
const service::Tag& tag, size_t max = 2,
const std::set< service::IntroSet >& excludes = {}) = 0;
virtual void
DHTSendTo(const RouterID& peer, IMessage* msg, bool keepalive = true) = 0;
virtual llarp_time_t
Now() const = 0;
virtual llarp::Crypto*
Crypto() const = 0;
virtual llarp::AbstractRouter*
GetRouter() const = 0;
virtual const Key_t&
OurKey() const = 0;
virtual Bucket< RCNode >*
Nodes() const = 0;
};
struct Context final : public AbstractContext, public util::IStateful
{
Context();
~Context()
{
}
util::StatusObject
ExtractStatus() const override;
llarp::Crypto*
Crypto() const override;
/// on behalf of whoasked request introset for target from dht router with
/// key askpeer
void
LookupIntroSetRecursive(
const service::Address& target, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer, uint64_t R,
service::IntroSetLookupHandler result = nullptr) override;
void
LookupIntroSetIterative(
const service::Address& target, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer,
service::IntroSetLookupHandler result = nullptr) override;
/// on behalf of whoasked request router with public key target from dht
/// router with key askpeer
void
LookupRouterRecursive(const RouterID& target, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer,
RouterLookupHandler result = nullptr);
bool
LookupRouter(const RouterID& target, RouterLookupHandler result) override
{
Key_t askpeer;
if(!nodes->FindClosest(Key_t(target), askpeer))
{
return false;
}
LookupRouterRecursive(target, OurKey(), 0, askpeer, result);
return true;
}
bool
HasRouterLookup(const RouterID& target) const
{
return pendingRouterLookups.HasLookupFor(target);
}
virtual bool
HasRouterLookup(const RouterID& target) const = 0;
/// on behalf of whoasked request introsets with tag from dht router with
/// key askpeer with Recursion depth R
void
virtual void
LookupTagRecursive(const service::Tag& tag, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer, uint64_t R);
uint64_t whoaskedTX, const Key_t& askpeer,
uint64_t R) = 0;
/// issue dht lookup for tag via askpeer and send reply to local path
void
virtual void
LookupTagForPath(const service::Tag& tag, uint64_t txid,
const llarp::PathID_t& path, const Key_t& askpeer);
const PathID_t& path, const Key_t& askpeer) = 0;
/// issue dht lookup for router via askpeer and send reply to local path
void
virtual void
LookupRouterForPath(const RouterID& target, uint64_t txid,
const llarp::PathID_t& path, const Key_t& askpeer);
const PathID_t& path, const Key_t& askpeer) = 0;
/// issue dht lookup for introset for addr via askpeer and send reply to
/// local path
void
virtual void
LookupIntroSetForPath(const service::Address& addr, uint64_t txid,
const llarp::PathID_t& path, const Key_t& askpeer);
const PathID_t& path, const Key_t& askpeer) = 0;
/// send a dht message to peer, if keepalive is true then keep the session
/// with that peer alive for 10 seconds
void
DHTSendTo(const RouterID& peer, IMessage* msg,
bool keepalive = true) override;
virtual void
DHTSendTo(const RouterID& peer, IMessage* msg, bool keepalive = true) = 0;
/// get routers closest to target excluding requester
bool
virtual bool
HandleExploritoryRouterLookup(
const Key_t& requester, uint64_t txid, const RouterID& target,
std::vector< std::unique_ptr< IMessage > >& reply);
std::set< service::IntroSet >
FindRandomIntroSetsWithTagExcluding(
const service::Tag& tag, size_t max = 2,
const std::set< service::IntroSet >& excludes = {}) override;
std::vector< std::unique_ptr< IMessage > >& reply) = 0;
/// handle rc lookup from requester for target
void
LookupRouterRelayed(const Key_t& requester, uint64_t txid,
const Key_t& target, bool recursive,
std::vector< std::unique_ptr< IMessage > >& replies);
virtual void
LookupRouterRelayed(
const Key_t& requester, uint64_t txid, const Key_t& target,
bool recursive,
std::vector< std::unique_ptr< IMessage > >& replies) = 0;
/// relay a dht message from a local path to the main network
bool
RelayRequestForPath(const llarp::PathID_t& localPath,
const IMessage* msg);
virtual bool
RelayRequestForPath(const PathID_t& localPath, const IMessage* msg) = 0;
/// send introset to peer from source with S counter and excluding peers
void
virtual void
PropagateIntroSetTo(const Key_t& source, uint64_t sourceTX,
const service::IntroSet& introset, const Key_t& peer,
uint64_t S, const std::set< Key_t >& exclude);
uint64_t S, const std::set< Key_t >& exclude) = 0;
/// initialize dht context and explore every exploreInterval milliseconds
void
virtual void
Init(const Key_t& us, AbstractRouter* router,
llarp_time_t exploreInterval);
llarp_time_t exploreInterval) = 0;
/// get localally stored introset by service address
const llarp::service::IntroSet*
GetIntroSetByServiceAddress(const llarp::service::Address& addr) const;
virtual const llarp::service::IntroSet*
GetIntroSetByServiceAddress(
const llarp::service::Address& addr) const = 0;
static void
handle_cleaner_timer(void* user, uint64_t orig, uint64_t left);
static void
handle_explore_timer(void* user, uint64_t orig, uint64_t left);
/// explore dht for new routers
void
Explore(size_t N = 3);
virtual llarp_time_t
Now() const = 0;
llarp::AbstractRouter* router;
// for router contacts
std::unique_ptr< Bucket< RCNode > > nodes;
virtual void
ExploreNetworkVia(const Key_t& peer) = 0;
// for introduction sets
std::unique_ptr< Bucket< ISNode > > services;
bool allowTransit;
virtual llarp::Crypto*
Crypto() const = 0;
Bucket< RCNode >*
Nodes() const override
{
return nodes.get();
}
virtual llarp::AbstractRouter*
GetRouter() const = 0;
const Key_t&
OurKey() const override
{
return ourKey;
}
virtual const Key_t&
OurKey() const = 0;
llarp::AbstractRouter*
GetRouter() const override
{
return router;
}
virtual PendingIntrosetLookups&
pendingIntrosetLookups() = 0;
TXHolder< service::Address, service::IntroSet, service::Address::Hash >
pendingIntrosetLookups;
virtual const PendingIntrosetLookups&
pendingIntrosetLookups() const = 0;
TXHolder< service::Tag, service::IntroSet, service::Tag::Hash >
pendingTagLookups;
virtual PendingTagLookups&
pendingTagLookups() = 0;
TXHolder< RouterID, RouterContact, RouterID::Hash > pendingRouterLookups;
virtual const PendingTagLookups&
pendingTagLookups() const = 0;
TXHolder< RouterID, RouterID, RouterID::Hash > pendingExploreLookups;
virtual PendingRouterLookups&
pendingRouterLookups() = 0;
uint64_t
NextID()
{
return ++ids;
}
virtual const PendingRouterLookups&
pendingRouterLookups() const = 0;
llarp_time_t
Now() const override;
virtual PendingExploreLookups&
pendingExploreLookups() = 0;
void
ExploreNetworkVia(const Key_t& peer);
virtual const PendingExploreLookups&
pendingExploreLookups() const = 0;
private:
void
ScheduleCleanupTimer();
virtual Bucket< ISNode >*
services() = 0;
void
CleanupTX();
virtual bool&
AllowTransit() = 0;
virtual const bool&
AllowTransit() const = 0;
uint64_t ids;
virtual Bucket< RCNode >*
Nodes() const = 0;
};
Key_t ourKey;
}; // namespace llarp
} // namespace dht
std::unique_ptr< AbstractContext >
makeContext();
} // namespace dht
} // namespace llarp
struct llarp_dht_context
{
llarp::dht::Context impl;
std::unique_ptr< llarp::dht::AbstractContext > impl;
llarp::AbstractRouter* parent;
llarp_dht_context(llarp::AbstractRouter* router);
};

@ -22,19 +22,19 @@ llarp_dht_context_free(struct llarp_dht_context *ctx)
void
__llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id)
{
ctx->impl.nodes->DelNode(llarp::dht::Key_t(id));
ctx->impl->Nodes()->DelNode(llarp::dht::Key_t(id));
}
void
llarp_dht_allow_transit(llarp_dht_context *ctx)
{
ctx->impl.allowTransit = true;
ctx->impl->AllowTransit() = true;
}
void
llarp_dht_context_start(struct llarp_dht_context *ctx, const byte_t *key)
{
ctx->impl.Init(llarp::dht::Key_t(key), ctx->parent, 20000);
ctx->impl->Init(llarp::dht::Key_t(key), ctx->parent, 20000);
}
void

@ -81,8 +81,8 @@ namespace llarp
llarp::LogError("R value too big, ", R, "> 5");
return false;
}
auto& dht = ctx->impl;
if(dht.pendingIntrosetLookups.HasPendingLookupFrom(TXOwner{From, T}))
auto& dht = *ctx->impl;
if(dht.pendingIntrosetLookups().HasPendingLookupFrom(TXOwner{From, T}))
{
llarp::LogWarn("duplicate FIM from ", From, " txid=", T);
return false;
@ -107,7 +107,7 @@ namespace llarp
Key_t target = S.ToKey();
Key_t closer;
// find closer peer
if(!dht.nodes->FindClosest(target, closer))
if(!dht.Nodes()->FindClosest(target, closer))
return false;
if(relayed)
dht.LookupIntroSetForPath(S, T, pathID, closer);
@ -120,7 +120,7 @@ namespace llarp
Key_t us = dht.OurKey();
Key_t target = S.ToKey();
// we are recursive
if(dht.nodes->FindCloseExcluding(target, peer, exclude))
if(dht.Nodes()->FindCloseExcluding(target, peer, exclude))
{
if(relayed)
dht.LookupIntroSetForPath(S, T, pathID, peer);
@ -154,7 +154,7 @@ namespace llarp
if(relayed)
{
// tag lookup
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude))
{
dht.LookupTagForPath(N, T, pathID, peer);
}
@ -182,7 +182,7 @@ namespace llarp
else if(R < 5)
{
// tag lookup
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude))
{
dht.LookupTagRecursive(N, From, T, peer, R - 1);
}

@ -16,17 +16,17 @@ namespace llarp
llarp_dht_context *ctx,
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto &dht = ctx->impl;
auto &dht = *ctx->impl;
/// lookup for us, send an immeidate reply
Key_t us = dht.OurKey();
Key_t k{K};
if(K == us)
{
auto path = dht.router->pathContext().GetByUpstream(K, pathID);
auto path = dht.GetRouter()->pathContext().GetByUpstream(K, pathID);
if(path)
{
replies.emplace_back(
new GotRouterMessage(k, txid, {dht.router->rc()}, false));
new GotRouterMessage(k, txid, {dht.GetRouter()->rc()}, false));
return true;
}
return false;
@ -35,13 +35,13 @@ namespace llarp
Key_t peer;
// check if we know this in our nodedb first
RouterContact found;
if(dht.router->nodedb()->Get(K, found))
if(dht.GetRouter()->nodedb()->Get(K, found))
{
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;
}
// lookup if we don't have it in our nodedb
if(dht.nodes->FindClosest(k, peer))
if(dht.Nodes()->FindClosest(k, peer))
dht.LookupRouterForPath(K, txid, pathID, peer);
return true;
}
@ -145,14 +145,14 @@ namespace llarp
llarp_dht_context *ctx,
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto &dht = ctx->impl;
if(!dht.allowTransit)
auto &dht = *ctx->impl;
if(!dht.AllowTransit())
{
llarp::LogWarn("Got DHT lookup from ", From,
" when we are not allowing dht transit");
return false;
}
if(dht.pendingRouterLookups.HasPendingLookupFrom({From, txid}))
if(dht.pendingRouterLookups().HasPendingLookupFrom({From, txid}))
{
llarp::LogWarn("Duplicate FRM from ", From, " txid=", txid);
return false;
@ -161,7 +161,7 @@ namespace llarp
Key_t k{K};
if(exploritory)
return dht.HandleExploritoryRouterLookup(From, txid, K, replies);
else if(dht.router->nodedb()->Get(K, found))
else if(dht.GetRouter()->nodedb()->Get(K, found))
{
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;

@ -25,8 +25,8 @@ namespace llarp
__attribute__((unused))
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto &dht = ctx->impl;
auto crypto = dht.router->crypto();
auto &dht = *ctx->impl;
auto crypto = dht.GetRouter()->crypto();
for(const auto &introset : I)
{
@ -40,23 +40,23 @@ namespace llarp
}
}
TXOwner owner(From, T);
auto tagLookup = dht.pendingTagLookups.GetPendingLookupFrom(owner);
auto tagLookup = dht.pendingTagLookups().GetPendingLookupFrom(owner);
if(tagLookup)
{
dht.pendingTagLookups.Found(owner, tagLookup->target, I);
dht.pendingTagLookups().Found(owner, tagLookup->target, I);
return true;
}
auto serviceLookup =
dht.pendingIntrosetLookups.GetPendingLookupFrom(owner);
dht.pendingIntrosetLookups().GetPendingLookupFrom(owner);
if(serviceLookup)
{
if(I.size())
{
dht.pendingIntrosetLookups.Found(owner, serviceLookup->target, I);
dht.pendingIntrosetLookups().Found(owner, serviceLookup->target, I);
}
else
{
dht.pendingIntrosetLookups.NotFound(owner, K);
dht.pendingIntrosetLookups().NotFound(owner, K);
}
return true;
}
@ -71,7 +71,8 @@ namespace llarp
std::vector< std::unique_ptr< IMessage > > &replies) const
{
// TODO: implement me better?
auto pathset = ctx->impl.router->pathContext().GetLocalPathSet(pathID);
auto pathset =
ctx->impl->GetRouter()->pathContext().GetLocalPathSet(pathID);
if(pathset)
{
return pathset->HandleGotIntroMessage(this);

@ -85,28 +85,29 @@ namespace llarp
__attribute__((unused))
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto &dht = ctx->impl;
auto &dht = *ctx->impl;
if(relayed)
{
auto pathset = ctx->impl.router->pathContext().GetLocalPathSet(pathID);
auto pathset =
ctx->impl->GetRouter()->pathContext().GetLocalPathSet(pathID);
return pathset && pathset->HandleGotRouterMessage(this);
}
// not relayed
TXOwner owner(From, txid);
if(dht.pendingExploreLookups.HasPendingLookupFrom(owner))
if(dht.pendingExploreLookups().HasPendingLookupFrom(owner))
{
if(N.size() == 0)
dht.pendingExploreLookups.NotFound(owner, K);
dht.pendingExploreLookups().NotFound(owner, K);
else
{
dht.pendingExploreLookups.Found(owner, From.as_array(), N);
dht.pendingExploreLookups().Found(owner, From.as_array(), N);
}
return true;
}
// not explore lookup
if(!dht.pendingRouterLookups.HasPendingLookupFrom(owner))
if(!dht.pendingRouterLookups().HasPendingLookupFrom(owner))
{
llarp::LogWarn("Unwarranted GRM from ", From, " txid=", txid);
return false;
@ -115,9 +116,9 @@ namespace llarp
llarp::LogInfo("DHT no pending lookup");
if(R.size() == 1)
dht.pendingRouterLookups.Found(owner, R[0].pubkey, {R[0]});
dht.pendingRouterLookups().Found(owner, R[0].pubkey, {R[0]});
else
dht.pendingRouterLookups.NotFound(owner, K);
dht.pendingRouterLookups().NotFound(owner, K);
return true;
}
} // namespace dht

@ -46,14 +46,14 @@ namespace llarp
llarp_dht_context *ctx,
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto now = ctx->impl.Now();
auto now = ctx->impl->Now();
if(S > 5)
{
llarp::LogWarn("invalid S value ", S, " > 5");
return false;
}
auto &dht = ctx->impl;
if(!I.Verify(dht.router->crypto(), now))
auto &dht = *ctx->impl;
if(!I.Verify(dht.Crypto(), now))
{
llarp::LogWarn("invalid introset: ", I);
// don't propogate or store
@ -63,7 +63,7 @@ namespace llarp
using namespace std::placeholders;
shorthash_func shorthash =
std::bind(&Crypto::shorthash, dht.router->crypto(), _1, _2);
std::bind(&Crypto::shorthash, dht.Crypto(), _1, _2);
if(I.W && !I.W->IsValid(shorthash, now))
{
llarp::LogWarn("proof of work not good enough for IntroSet");
@ -86,7 +86,7 @@ namespace llarp
replies.emplace_back(new GotIntroMessage({}, txID));
return true;
}
dht.services->PutNode(I);
dht.services()->PutNode(I);
replies.emplace_back(new GotIntroMessage({I}, txID));
Key_t peer;
std::set< Key_t > exclude;
@ -94,7 +94,7 @@ namespace llarp
exclude.insert(e);
exclude.insert(From);
exclude.insert(dht.OurKey());
if(S && dht.nodes->FindCloseExcluding(addr, peer, exclude))
if(S && dht.Nodes()->FindCloseExcluding(addr, peer, exclude))
{
dht.PropagateIntroSetTo(From, txID, I, peer, S - 1, exclude);
}

@ -129,7 +129,7 @@ namespace llarp
TransitHop::HandleDHTMessage(const llarp::dht::IMessage* msg,
AbstractRouter* r)
{
return r->dht()->impl.RelayRequestForPath(info.rxID, msg);
return r->dht()->impl->RelayRequestForPath(info.rxID, msg);
}
bool

@ -233,7 +233,7 @@ namespace llarp
util::StatusObject
Router::ExtractStatus() const
{
util::StatusObject obj{{"dht", _dht->impl.ExtractStatus()},
util::StatusObject obj{{"dht", _dht->impl->ExtractStatus()},
{"services", hiddenServiceContext.ExtractStatus()},
{"exit", _exitContext.ExtractStatus()}};
std::vector< util::StatusObject > ob_links, ib_links;
@ -345,9 +345,9 @@ namespace llarp
}
// we don't have the RC locally so do a dht lookup
_dht->impl.LookupRouter(remote,
std::bind(&Router::HandleDHTLookupForSendTo, this,
remote, std::placeholders::_1));
_dht->impl->LookupRouter(remote,
std::bind(&Router::HandleDHTLookupForSendTo, this,
remote, std::placeholders::_1));
return true;
}
@ -549,7 +549,7 @@ namespace llarp
router->validRouters.emplace(pk, rc);
// track valid router in dht
router->dht()->impl.nodes->PutNode(rc);
router->dht()->impl->Nodes()->PutNode(rc);
// mark success in profile
router->routerProfiling().MarkSuccess(pk);
@ -631,11 +631,11 @@ namespace llarp
}
else if(IsServiceNode() || !routerProfiling().IsBad(remote))
{
if(dht()->impl.HasRouterLookup(remote))
if(dht()->impl->HasRouterLookup(remote))
return;
LogInfo("looking up router ", remote);
// dht lookup as we don't know it
dht()->impl.LookupRouter(
dht()->impl->LookupRouter(
remote,
std::bind(&Router::HandleDHTLookupForTryEstablishTo, this, remote,
std::placeholders::_1));
@ -990,9 +990,9 @@ namespace llarp
// store it in nodedb async
async_verify_RC(newrc, nullptr);
// update dht if required
if(dht()->impl.nodes->HasNode(dht::Key_t{newrc.pubkey}))
if(dht()->impl->Nodes()->HasNode(dht::Key_t{newrc.pubkey}))
{
dht()->impl.nodes->PutNode(newrc);
dht()->impl->Nodes()->PutNode(newrc);
}
// update valid routers
{
@ -1009,9 +1009,9 @@ namespace llarp
void
Router::ServiceNodeLookupRouterWhenExpired(RouterID router)
{
dht()->impl.LookupRouter(router,
std::bind(&Router::HandleDHTLookupForExplore, this,
router, std::placeholders::_1));
dht()->impl->LookupRouter(router,
std::bind(&Router::HandleDHTLookupForExplore,
this, router, std::placeholders::_1));
}
void
@ -1077,7 +1077,7 @@ namespace llarp
for(const auto &rc : bootstrapRCList)
{
TryConnectAsync(rc, 4);
dht()->impl.ExploreNetworkVia(dht::Key_t{rc.pubkey});
dht()->impl->ExploreNetworkVia(dht::Key_t{rc.pubkey});
}
}
else

@ -27,16 +27,87 @@ namespace llarp
std::set< service::IntroSet >(const service::Tag&, size_t,
const std::set< service::IntroSet >&));
MOCK_CONST_METHOD1(HasRouterLookup, bool(const RouterID& target));
MOCK_METHOD5(LookupTagRecursive,
void(const service::Tag&, const dht::Key_t&, uint64_t,
const dht::Key_t&, uint64_t));
MOCK_METHOD4(LookupTagForPath,
void(const service::Tag&, uint64_t, const PathID_t&,
const dht::Key_t&));
MOCK_METHOD4(LookupRouterForPath,
void(const RouterID& target, uint64_t txid,
const PathID_t& path, const dht::Key_t& askpeer));
MOCK_METHOD4(LookupIntroSetForPath,
void(const service::Address&, uint64_t, const PathID_t&,
const dht::Key_t&));
MOCK_METHOD3(DHTSendTo, void(const RouterID&, dht::IMessage*, bool));
MOCK_METHOD4(
HandleExploritoryRouterLookup,
bool(const dht::Key_t& requester, uint64_t txid,
const RouterID& target,
std::vector< std::unique_ptr< dht::IMessage > >& reply));
MOCK_METHOD5(
LookupRouterRelayed,
void(const dht::Key_t& requester, uint64_t txid,
const dht::Key_t& target, bool recursive,
std::vector< std::unique_ptr< dht::IMessage > >& replies));
MOCK_METHOD2(RelayRequestForPath,
bool(const PathID_t& localPath, const dht::IMessage* msg));
MOCK_METHOD6(PropagateIntroSetTo,
void(const dht::Key_t& source, uint64_t sourceTX,
const service::IntroSet& introset,
const dht::Key_t& peer, uint64_t S,
const std::set< dht::Key_t >& exclude));
MOCK_METHOD3(Init,
void(const dht::Key_t&, AbstractRouter*, llarp_time_t));
MOCK_CONST_METHOD1(
GetIntroSetByServiceAddress,
const llarp::service::IntroSet*(const llarp::service::Address&));
MOCK_CONST_METHOD0(ExtractStatus, util::StatusObject());
MOCK_CONST_METHOD0(Now, llarp_time_t());
MOCK_METHOD1(ExploreNetworkVia, void(const dht::Key_t& peer));
MOCK_CONST_METHOD0(Crypto, llarp::Crypto*());
MOCK_CONST_METHOD0(GetRouter, llarp::AbstractRouter*());
MOCK_CONST_METHOD0(OurKey, const dht::Key_t&());
MOCK_CONST_METHOD0(pendingIntrosetLookups,
const PendingIntrosetLookups&());
MOCK_METHOD0(pendingIntrosetLookups, PendingIntrosetLookups&());
MOCK_METHOD0(pendingTagLookups, PendingTagLookups&());
MOCK_CONST_METHOD0(pendingTagLookups, const PendingTagLookups&());
MOCK_METHOD0(pendingRouterLookups, PendingRouterLookups&());
MOCK_CONST_METHOD0(pendingRouterLookups, const PendingRouterLookups&());
MOCK_METHOD0(pendingExploreLookups, PendingExploreLookups&());
MOCK_CONST_METHOD0(pendingExploreLookups, const PendingExploreLookups&());
MOCK_METHOD0(services, dht::Bucket< dht::ISNode >*());
MOCK_CONST_METHOD0(AllowTransit, const bool&());
MOCK_METHOD0(AllowTransit, bool&());
MOCK_CONST_METHOD0(Nodes, dht::Bucket< dht::RCNode >*());
};

Loading…
Cancel
Save