mirror of https://github.com/oxen-io/lokinet
Compare commits
31 Commits
f173186696
...
42337388f9
Author | SHA1 | Date |
---|---|---|
dr7ana | 42337388f9 | 8 months ago |
Jason Rhinelander | f7c18de0d4 | 8 months ago |
Jason Rhinelander | 4f364f5e59 | 8 months ago |
Jason Rhinelander | a7a18868c7 | 8 months ago |
Jason Rhinelander | 6ebc812cda | 8 months ago |
Jason Rhinelander | 1ca81713ab | 8 months ago |
Jason Rhinelander | e237d5ad6e | 8 months ago |
dr7ana | 8cbae70369 | 8 months ago |
Jason Rhinelander | b4a1ed9b85 | 8 months ago |
dr7ana | 7d713323f0 | 8 months ago |
dr7ana | aae677814d | 8 months ago |
Jason Rhinelander | 6f2825c922 | 8 months ago |
Jason Rhinelander | 16506b6d8b | 8 months ago |
Jason Rhinelander | d2667cfb89 | 8 months ago |
dr7ana | 7ac88616f7 | 8 months ago |
dr7ana | b7e21becf0 | 8 months ago |
dr7ana | 7314c2a22a | 8 months ago |
Jason Rhinelander | c18ad4c618 | 8 months ago |
dr7ana | 2abe2d9363 | 8 months ago |
Jason Rhinelander | 5c3467ecb0 | 8 months ago |
Jason Rhinelander | 18effaa76f | 8 months ago |
Jason Rhinelander | c3242e4092 | 8 months ago |
dr7ana | 46ad8d4058 | 8 months ago |
dr7ana | bda8b211dd | 8 months ago |
Jason Rhinelander | f4f5ab0109 | 8 months ago |
dr7ana | e710cfea47 | 8 months ago |
dr7ana | 0e451db77f | 8 months ago |
dr7ana | 3ae8fce77d | 8 months ago |
dr7ana | 41312abab0 | 8 months ago |
dr7ana | 6955f3fae0 | 8 months ago |
Thomas Winget | 4755269458 | 8 months ago |
@ -0,0 +1,4 @@
|
|||||||
|
set(GRAPHVIZ_GRAPH_NAME "graph.dot" CACHE STRING "")
|
||||||
|
set(GRAPHVIZ_GENERATE_PER_TARGET FALSE CACHE BOOL "")
|
||||||
|
set(GRAPHVIZ_GENERATE_DEPENDERS FALSE CACHE BOOL "")
|
||||||
|
set(GRAPHVIZ_OBJECT_LIBS OFF CACHE BOOL "")
|
@ -1,7 +0,0 @@
|
|||||||
if(STATIC_LINK)
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
||||||
link_libraries( -static-libstdc++ )
|
|
||||||
else()
|
|
||||||
link_libraries( -static-libstdc++ -static-libgcc )
|
|
||||||
endif()
|
|
||||||
endif()
|
|
@ -0,0 +1 @@
|
|||||||
|
Subproject commit a7de63756dcc5c31cb899a4b810e6434b1a7c01c
|
@ -1 +1 @@
|
|||||||
Subproject commit 33982d24a380268933ebea33976ad806e5c4e4bb
|
Subproject commit 6ee6ed398d00043d862466a56279b5c502513bff
|
@ -1 +1 @@
|
|||||||
Subproject commit 68b3420bad5f0384f06d378b89ccdc06aba07465
|
Subproject commit a27961d787c9065f2bf6da9d60d01dca2e125739
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "lokinet/lokinet_addr.h"
|
||||||
#include "lokinet/lokinet_context.h"
|
#include "lokinet/lokinet_context.h"
|
||||||
#include "lokinet/lokinet_srv.h"
|
|
||||||
#include "lokinet/lokinet_misc.h"
|
#include "lokinet/lokinet_misc.h"
|
||||||
#include "lokinet/lokinet_addr.h"
|
#include "lokinet/lokinet_srv.h"
|
||||||
#include "lokinet/lokinet_stream.h"
|
#include "lokinet/lokinet_stream.h"
|
||||||
#include "lokinet/lokinet_udp.h"
|
#include "lokinet/lokinet_udp.h"
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
#include <llarp/bootstrap.hpp>
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, BootstrapList>
|
||||||
|
load_bootstrap_fallbacks()
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, BootstrapList> fallbacks;
|
||||||
|
using init_list = std::initializer_list<std::pair<std::string, std::string_view>>;
|
||||||
|
// clang-format off
|
||||||
|
for (const auto& [network, bootstrap] : init_list{
|
||||||
|
//
|
||||||
|
})
|
||||||
|
// clang-format on
|
||||||
|
{
|
||||||
|
llarp_buffer_t buf{bootstrap.data(), bootstrap.size()};
|
||||||
|
auto& bsl = fallbacks[network];
|
||||||
|
bsl.BDecode(&buf);
|
||||||
|
}
|
||||||
|
return fallbacks;
|
||||||
|
}
|
||||||
|
} // namespace llarp
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
/// default queue length for logic jobs
|
|
||||||
constexpr std::size_t event_loop_queue_size = 1024;
|
|
||||||
} // namespace llarp
|
|
@ -1,669 +0,0 @@
|
|||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
#include "explorenetworkjob.hpp"
|
|
||||||
#include "localrouterlookup.hpp"
|
|
||||||
#include "localserviceaddresslookup.hpp"
|
|
||||||
#include "localtaglookup.hpp"
|
|
||||||
#include <llarp/dht/messages/findrouter.hpp>
|
|
||||||
#include <llarp/dht/messages/gotintro.hpp>
|
|
||||||
#include <llarp/dht/messages/gotrouter.hpp>
|
|
||||||
#include <llarp/dht/messages/pubintro.hpp>
|
|
||||||
#include "node.hpp"
|
|
||||||
#include "publishservicejob.hpp"
|
|
||||||
#include "recursiverouterlookup.hpp"
|
|
||||||
#include "serviceaddresslookup.hpp"
|
|
||||||
#include "taglookup.hpp"
|
|
||||||
#include <llarp/messages/dht_immediate.hpp>
|
|
||||||
#include <llarp/path/path_context.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
|
||||||
#include <llarp/routing/path_dht_message.hpp>
|
|
||||||
#include <llarp/nodedb.hpp>
|
|
||||||
#include <llarp/profiling.hpp>
|
|
||||||
#include <llarp/router/rc_lookup_handler.hpp>
|
|
||||||
#include <llarp/util/decaying_hashset.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
AbstractDHTMessageHandler::~AbstractDHTMessageHandler() = default;
|
|
||||||
|
|
||||||
struct DHTMessageHandler final : public AbstractDHTMessageHandler
|
|
||||||
{
|
|
||||||
DHTMessageHandler();
|
|
||||||
|
|
||||||
~DHTMessageHandler() override = default;
|
|
||||||
|
|
||||||
util::StatusObject
|
|
||||||
ExtractStatus() const override;
|
|
||||||
|
|
||||||
void
|
|
||||||
StoreRC(const RouterContact rc) const override
|
|
||||||
{
|
|
||||||
GetRouter()->rc_lookup_handler().check_rc(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// void
|
|
||||||
// LookupIntroSetRelayed(
|
|
||||||
// const Key_t& target,
|
|
||||||
// const Key_t& whoasked,
|
|
||||||
// uint64_t whoaskedTX,
|
|
||||||
// const Key_t& askpeer,
|
|
||||||
// uint64_t relayOrder,
|
|
||||||
// service::EncryptedIntroSetLookupHandler result = nullptr) override;
|
|
||||||
|
|
||||||
// void
|
|
||||||
// LookupIntroSetDirect(
|
|
||||||
// const Key_t& target,
|
|
||||||
// const Key_t& whoasked,
|
|
||||||
// uint64_t whoaskedTX,
|
|
||||||
// const Key_t& askpeer,
|
|
||||||
// service::EncryptedIntroSetLookupHandler 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) override;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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 Key_t& addr,
|
|
||||||
uint64_t txid,
|
|
||||||
const llarp::PathID_t& path,
|
|
||||||
const Key_t& askpeer,
|
|
||||||
uint64_t relayOrder) 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, AbstractDHTMessage* 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<AbstractDHTMessage>>& reply) 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<AbstractDHTMessage>>& replies) override;
|
|
||||||
|
|
||||||
/// relay a dht message from a local path to the main network
|
|
||||||
bool
|
|
||||||
RelayRequestForPath(const llarp::PathID_t& localPath, const AbstractDHTMessage& msg) override;
|
|
||||||
|
|
||||||
/// send introset to peer as R/S
|
|
||||||
void
|
|
||||||
PropagateLocalIntroSet(
|
|
||||||
const PathID_t& from,
|
|
||||||
uint64_t txid,
|
|
||||||
const service::EncryptedIntroSet& introset,
|
|
||||||
const Key_t& tellpeer,
|
|
||||||
uint64_t relayOrder) override;
|
|
||||||
|
|
||||||
/// send introset to peer from source with S counter and excluding peers
|
|
||||||
void
|
|
||||||
PropagateIntroSetTo(
|
|
||||||
const Key_t& from,
|
|
||||||
uint64_t txid,
|
|
||||||
const service::EncryptedIntroSet& introset,
|
|
||||||
const Key_t& tellpeer,
|
|
||||||
uint64_t relayOrder) override;
|
|
||||||
|
|
||||||
/// initialize dht context and explore every exploreInterval milliseconds
|
|
||||||
void
|
|
||||||
Init(const Key_t& us, Router* router) override;
|
|
||||||
|
|
||||||
/// get localally stored introset by service address
|
|
||||||
std::optional<llarp::service::EncryptedIntroSet>
|
|
||||||
GetIntroSetByLocation(const Key_t& location) const override;
|
|
||||||
|
|
||||||
void
|
|
||||||
handle_cleaner_timer();
|
|
||||||
|
|
||||||
/// explore dht for new routers
|
|
||||||
void
|
|
||||||
Explore(size_t N = 3);
|
|
||||||
|
|
||||||
llarp::Router* router{nullptr};
|
|
||||||
// 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{false};
|
|
||||||
|
|
||||||
bool&
|
|
||||||
AllowTransit() override
|
|
||||||
{
|
|
||||||
return allowTransit;
|
|
||||||
}
|
|
||||||
const bool&
|
|
||||||
AllowTransit() const override
|
|
||||||
{
|
|
||||||
return allowTransit;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bucket<RCNode>*
|
|
||||||
Nodes() const override
|
|
||||||
{
|
|
||||||
return _nodes.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PutRCNodeAsync(const RCNode& val) override
|
|
||||||
{
|
|
||||||
router->loop()->call([nodes = Nodes(), val] { nodes->PutNode(val); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DelRCNodeAsync(const Key_t& val) override
|
|
||||||
{
|
|
||||||
router->loop()->call([nodes = Nodes(), val] { nodes->DelNode(val); });
|
|
||||||
}
|
|
||||||
|
|
||||||
const Key_t&
|
|
||||||
OurKey() const override
|
|
||||||
{
|
|
||||||
return ourKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
llarp::Router*
|
|
||||||
GetRouter() const override
|
|
||||||
{
|
|
||||||
return router;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GetRCFromNodeDB(const Key_t& k, llarp::RouterContact& rc) const override
|
|
||||||
{
|
|
||||||
if (const auto maybe = router->node_db()->Get(k.as_array()); maybe.has_value())
|
|
||||||
{
|
|
||||||
rc = *maybe;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PendingIntrosetLookups _pendingIntrosetLookups;
|
|
||||||
PendingRouterLookups _pendingRouterLookups;
|
|
||||||
PendingExploreLookups _pendingExploreLookups;
|
|
||||||
|
|
||||||
PendingIntrosetLookups&
|
|
||||||
pendingIntrosetLookups() override
|
|
||||||
{
|
|
||||||
return _pendingIntrosetLookups;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PendingIntrosetLookups&
|
|
||||||
pendingIntrosetLookups() const override
|
|
||||||
{
|
|
||||||
return _pendingIntrosetLookups;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
bool
|
|
||||||
handle_message(
|
|
||||||
const AbstractDHTMessage&, std::vector<std::unique_ptr<dht::AbstractDHTMessage>>&) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<int> _timer_keepalive;
|
|
||||||
|
|
||||||
void
|
|
||||||
CleanupTX();
|
|
||||||
|
|
||||||
uint64_t ids;
|
|
||||||
|
|
||||||
Key_t ourKey;
|
|
||||||
};
|
|
||||||
|
|
||||||
DHTMessageHandler::DHTMessageHandler()
|
|
||||||
{
|
|
||||||
randombytes((byte_t*)&ids, sizeof(uint64_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::Explore(size_t N)
|
|
||||||
{
|
|
||||||
// ask N random peers for new routers
|
|
||||||
llarp::LogDebug("Exploring network via ", N, " peers");
|
|
||||||
std::set<Key_t> peers;
|
|
||||||
|
|
||||||
if (_nodes->GetManyRandom(peers, N))
|
|
||||||
{
|
|
||||||
for (const auto& peer : peers)
|
|
||||||
ExploreNetworkVia(peer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
llarp::LogError("failed to select ", N, " random nodes for exploration");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::ExploreNetworkVia(const Key_t& askpeer)
|
|
||||||
{
|
|
||||||
uint64_t txid = ++ids;
|
|
||||||
const TXOwner peer(askpeer, txid);
|
|
||||||
const TXOwner whoasked(OurKey(), txid);
|
|
||||||
const RouterID K(askpeer.as_array());
|
|
||||||
pendingExploreLookups().NewTX(
|
|
||||||
peer, whoasked, K, new ExploreNetworkJob(askpeer.as_array(), this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::handle_cleaner_timer()
|
|
||||||
{
|
|
||||||
// clean up transactions
|
|
||||||
CleanupTX();
|
|
||||||
const llarp_time_t now = Now();
|
|
||||||
|
|
||||||
if (_nodes)
|
|
||||||
{
|
|
||||||
// expire router contacts in memory
|
|
||||||
auto& nodes = _nodes->nodes;
|
|
||||||
auto itr = nodes.begin();
|
|
||||||
while (itr != nodes.end())
|
|
||||||
{
|
|
||||||
if (itr->second.rc.IsExpired(now))
|
|
||||||
{
|
|
||||||
itr = nodes.erase(itr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_services)
|
|
||||||
{
|
|
||||||
// expire intro sets
|
|
||||||
auto& nodes = _services->nodes;
|
|
||||||
auto itr = nodes.begin();
|
|
||||||
while (itr != nodes.end())
|
|
||||||
{
|
|
||||||
if (itr->second.introset.IsExpired(now))
|
|
||||||
{
|
|
||||||
itr = nodes.erase(itr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::LookupRouterRelayed(
|
|
||||||
const Key_t& requester,
|
|
||||||
uint64_t txid,
|
|
||||||
const Key_t& target,
|
|
||||||
bool recursive,
|
|
||||||
std::vector<std::unique_ptr<AbstractDHTMessage>>& replies)
|
|
||||||
{
|
|
||||||
if (target == ourKey)
|
|
||||||
{
|
|
||||||
// we are the target, give them our RC
|
|
||||||
replies.emplace_back(new GotRouterMessage(requester, txid, {router->rc()}, false));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (not GetRouter()->SessionToRouterAllowed(target.as_array()))
|
|
||||||
{
|
|
||||||
// explicitly not allowed
|
|
||||||
replies.emplace_back(new GotRouterMessage(requester, txid, {}, false));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto rc = GetRouter()->node_db()->FindClosestTo(target);
|
|
||||||
const Key_t next(rc.pubkey);
|
|
||||||
{
|
|
||||||
if (next == target)
|
|
||||||
{
|
|
||||||
// we know the target
|
|
||||||
if (rc.ExpiresSoon(llarp::time_now_ms()))
|
|
||||||
{
|
|
||||||
// ask target for their rc to keep it updated
|
|
||||||
LookupRouterRecursive(target.as_array(), requester, txid, next);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// send reply with rc we know of
|
|
||||||
replies.emplace_back(new GotRouterMessage(requester, txid, {rc}, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (recursive) // are we doing a recursive lookup?
|
|
||||||
{
|
|
||||||
// is the next peer we ask closer to the target than us?
|
|
||||||
if ((next ^ target) < (ourKey ^ target))
|
|
||||||
{
|
|
||||||
// yes it is closer, ask neighbour recursively
|
|
||||||
LookupRouterRecursive(target.as_array(), requester, txid, next);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no we are closer to the target so tell requester it's not there
|
|
||||||
// so they switch to iterative lookup
|
|
||||||
replies.emplace_back(new GotRouterMessage(requester, txid, {}, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// iterative lookup and we don't have it tell them who is closer
|
|
||||||
replies.emplace_back(new GotRouterMessage(requester, next, txid, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<llarp::service::EncryptedIntroSet>
|
|
||||||
DHTMessageHandler::GetIntroSetByLocation(const Key_t& key) const
|
|
||||||
{
|
|
||||||
auto itr = _services->nodes.find(key);
|
|
||||||
if (itr == _services->nodes.end())
|
|
||||||
return {};
|
|
||||||
return itr->second.introset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::CleanupTX()
|
|
||||||
{
|
|
||||||
auto now = Now();
|
|
||||||
llarp::LogTrace("DHT tick");
|
|
||||||
|
|
||||||
pendingRouterLookups().Expire(now);
|
|
||||||
_pendingIntrosetLookups.Expire(now);
|
|
||||||
pendingExploreLookups().Expire(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
util::StatusObject
|
|
||||||
DHTMessageHandler::ExtractStatus() const
|
|
||||||
{
|
|
||||||
util::StatusObject obj{
|
|
||||||
{"pendingRouterLookups", pendingRouterLookups().ExtractStatus()},
|
|
||||||
{"pendingIntrosetLookups", _pendingIntrosetLookups.ExtractStatus()},
|
|
||||||
{"pendingExploreLookups", pendingExploreLookups().ExtractStatus()},
|
|
||||||
{"nodes", _nodes->ExtractStatus()},
|
|
||||||
{"services", _services->ExtractStatus()},
|
|
||||||
{"ourKey", ourKey.ToHex()}};
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DHTMessageHandler::handle_message(
|
|
||||||
const AbstractDHTMessage& msg, std::vector<std::unique_ptr<dht::AbstractDHTMessage>>& replies)
|
|
||||||
{
|
|
||||||
return msg.handle_message(*this, replies);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::Init(const Key_t& us, Router* r)
|
|
||||||
{
|
|
||||||
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 cleanup timer
|
|
||||||
_timer_keepalive = std::make_shared<int>(0);
|
|
||||||
router->loop()->call_every(1s, _timer_keepalive, [this] { handle_cleaner_timer(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::DHTSendTo(const RouterID& peer, AbstractDHTMessage* msg, bool)
|
|
||||||
{
|
|
||||||
router->SendToOrQueue(peer, msg);
|
|
||||||
auto now = Now();
|
|
||||||
router->PersistSessionUntil(peer, now + 1min);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this function handles incoming DHT messages sent down a path by a client
|
|
||||||
// note that IMessage here is different than that found in the routing
|
|
||||||
// namespace. by the time this is called, we are inside
|
|
||||||
// llarp::routing::DHTMessage::HandleMessage()
|
|
||||||
bool
|
|
||||||
DHTMessageHandler::RelayRequestForPath(const llarp::PathID_t& id, const AbstractDHTMessage& msg)
|
|
||||||
{
|
|
||||||
routing::PathDHTMessage reply;
|
|
||||||
if (not handle_message(msg, reply.dht_msgs))
|
|
||||||
return false;
|
|
||||||
if (not reply.dht_msgs.empty())
|
|
||||||
{
|
|
||||||
auto path = router->path_context().GetByUpstream(router->pubkey(), id);
|
|
||||||
return path && path->SendRoutingMessage(reply, router);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::LookupIntroSetForPath(
|
|
||||||
const Key_t& addr,
|
|
||||||
uint64_t txid,
|
|
||||||
const llarp::PathID_t& path,
|
|
||||||
const Key_t& askpeer,
|
|
||||||
uint64_t relayOrder)
|
|
||||||
{
|
|
||||||
const TXOwner asker(OurKey(), txid);
|
|
||||||
const TXOwner peer(askpeer, ++ids);
|
|
||||||
_pendingIntrosetLookups.NewTX(
|
|
||||||
peer,
|
|
||||||
asker,
|
|
||||||
asker,
|
|
||||||
new LocalServiceAddressLookup(path, txid, relayOrder, addr, this, askpeer));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::PropagateIntroSetTo(
|
|
||||||
const Key_t& from,
|
|
||||||
uint64_t txid,
|
|
||||||
const service::EncryptedIntroSet& introset,
|
|
||||||
const Key_t& tellpeer,
|
|
||||||
uint64_t relayOrder)
|
|
||||||
{
|
|
||||||
const TXOwner asker(from, txid);
|
|
||||||
const TXOwner peer(tellpeer, ++ids);
|
|
||||||
_pendingIntrosetLookups.NewTX(
|
|
||||||
peer, asker, asker, new PublishServiceJob(asker, introset, this, relayOrder));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::PropagateLocalIntroSet(
|
|
||||||
const PathID_t& from,
|
|
||||||
uint64_t txid,
|
|
||||||
const service::EncryptedIntroSet& introset,
|
|
||||||
const Key_t& tellpeer,
|
|
||||||
uint64_t relayOrder)
|
|
||||||
{
|
|
||||||
const TXOwner asker(OurKey(), txid);
|
|
||||||
const TXOwner peer(tellpeer, ++ids);
|
|
||||||
_pendingIntrosetLookups.NewTX(
|
|
||||||
peer,
|
|
||||||
asker,
|
|
||||||
peer,
|
|
||||||
new LocalPublishServiceJob(peer, from, txid, introset, this, relayOrder));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::LookupIntroSetRelayed(
|
|
||||||
const Key_t& addr,
|
|
||||||
const Key_t& whoasked,
|
|
||||||
uint64_t txid,
|
|
||||||
const Key_t& askpeer,
|
|
||||||
uint64_t relayOrder,
|
|
||||||
service::EncryptedIntroSetLookupHandler handler)
|
|
||||||
{
|
|
||||||
const TXOwner asker(whoasked, txid);
|
|
||||||
const TXOwner peer(askpeer, ++ids);
|
|
||||||
_pendingIntrosetLookups.NewTX(
|
|
||||||
peer, asker, asker, new ServiceAddressLookup(asker, addr, this, relayOrder, handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::LookupIntroSetDirect(
|
|
||||||
const Key_t& addr,
|
|
||||||
const Key_t& whoasked,
|
|
||||||
uint64_t txid,
|
|
||||||
const Key_t& askpeer,
|
|
||||||
service::EncryptedIntroSetLookupHandler handler)
|
|
||||||
{
|
|
||||||
const TXOwner asker(whoasked, txid);
|
|
||||||
const TXOwner peer(askpeer, ++ids);
|
|
||||||
_pendingIntrosetLookups.NewTX(
|
|
||||||
peer, asker, asker, new ServiceAddressLookup(asker, addr, this, 0, handler), 1s);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DHTMessageHandler::HandleExploritoryRouterLookup(
|
|
||||||
const Key_t& requester,
|
|
||||||
uint64_t txid,
|
|
||||||
const RouterID& target,
|
|
||||||
std::vector<std::unique_ptr<AbstractDHTMessage>>& reply)
|
|
||||||
{
|
|
||||||
std::vector<RouterID> closer;
|
|
||||||
const Key_t t(target.as_array());
|
|
||||||
std::set<Key_t> foundRouters;
|
|
||||||
if (!_nodes)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const size_t nodeCount = _nodes->size();
|
|
||||||
if (nodeCount == 0)
|
|
||||||
{
|
|
||||||
llarp::LogError("cannot handle exploritory router lookup, no dht peers");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
llarp::LogDebug("We have ", _nodes->size(), " connected nodes into the DHT");
|
|
||||||
// ourKey should never be in the connected list
|
|
||||||
// requester is likely in the connected list
|
|
||||||
// 4 or connection nodes (minus a potential requestor), whatever is less
|
|
||||||
if (!_nodes->GetManyNearExcluding(
|
|
||||||
t, foundRouters, std::min(nodeCount, size_t{4}), std::set<Key_t>{ourKey, requester}))
|
|
||||||
{
|
|
||||||
llarp::LogError(
|
|
||||||
"not enough dht nodes to handle exploritory router lookup, "
|
|
||||||
"have ",
|
|
||||||
nodeCount,
|
|
||||||
" dht peers");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const auto& f : foundRouters)
|
|
||||||
{
|
|
||||||
const RouterID id = f.as_array();
|
|
||||||
// discard shit routers
|
|
||||||
if (router->router_profiling().IsBadForConnect(id))
|
|
||||||
continue;
|
|
||||||
closer.emplace_back(id);
|
|
||||||
}
|
|
||||||
llarp::LogDebug("Gave ", closer.size(), " routers for exploration");
|
|
||||||
reply.emplace_back(new GotRouterMessage(txid, closer, false));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::LookupRouterForPath(
|
|
||||||
const RouterID& target, uint64_t txid, const llarp::PathID_t& path, const Key_t& askpeer)
|
|
||||||
|
|
||||||
{
|
|
||||||
const TXOwner peer(askpeer, ++ids);
|
|
||||||
const TXOwner whoasked(OurKey(), txid);
|
|
||||||
_pendingRouterLookups.NewTX(
|
|
||||||
peer, whoasked, target, new LocalRouterLookup(path, txid, target, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DHTMessageHandler::LookupRouterRecursive(
|
|
||||||
const RouterID& target,
|
|
||||||
const Key_t& whoasked,
|
|
||||||
uint64_t txid,
|
|
||||||
const Key_t& askpeer,
|
|
||||||
RouterLookupHandler handler)
|
|
||||||
{
|
|
||||||
const TXOwner asker(whoasked, txid);
|
|
||||||
const TXOwner peer(askpeer, ++ids);
|
|
||||||
_pendingRouterLookups.NewTX(
|
|
||||||
peer, asker, target, new RecursiveRouterLookup(asker, target, this, handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
llarp_time_t
|
|
||||||
DHTMessageHandler::Now() const
|
|
||||||
{
|
|
||||||
return router->now();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<AbstractDHTMessageHandler>
|
|
||||||
make_handler()
|
|
||||||
{
|
|
||||||
return std::make_unique<DHTMessageHandler>();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace llarp::dht
|
|
@ -1,53 +0,0 @@
|
|||||||
#include "context.hpp"
|
|
||||||
#include "dht.h"
|
|
||||||
#include <llarp/router_contact.hpp>
|
|
||||||
|
|
||||||
llarp_dht_context::llarp_dht_context(llarp::Router* router)
|
|
||||||
{
|
|
||||||
parent = router;
|
|
||||||
impl = llarp::dht::make_handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct llarp_dht_context*
|
|
||||||
llarp_dht_context_new(llarp::Router* router)
|
|
||||||
{
|
|
||||||
return new llarp_dht_context(router);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
llarp_dht_context_free(struct llarp_dht_context* ctx)
|
|
||||||
{
|
|
||||||
delete ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
__llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id)
|
|
||||||
{
|
|
||||||
ctx->impl->Nodes()->DelNode(llarp::dht::Key_t(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
llarp_dht_allow_transit(llarp_dht_context* ctx)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
llarp_dht_lookup_router(struct llarp_dht_context* ctx, struct llarp_router_lookup_job* job)
|
|
||||||
{
|
|
||||||
job->dht = ctx;
|
|
||||||
job->found = false;
|
|
||||||
job->result.Clear();
|
|
||||||
// llarp_rc_clear(&job->result);
|
|
||||||
llarp::LogError("implement me llarp_dht_lookup_router");
|
|
||||||
/*
|
|
||||||
ctx->parent->logic->queue_job(
|
|
||||||
{job, &llarp::dht::Context::queue_router_lookup});
|
|
||||||
*/
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <llarp/crypto/crypto.hpp>
|
|
||||||
#include <llarp/router_contact.hpp>
|
|
||||||
#include <llarp/util/buffer.hpp>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dht.h
|
|
||||||
*
|
|
||||||
* DHT functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct llarp_dht_context;
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
struct Router;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// allocator
|
|
||||||
struct llarp_dht_context*
|
|
||||||
llarp_dht_context_new(llarp::Router* parent);
|
|
||||||
|
|
||||||
/// deallocator
|
|
||||||
void
|
|
||||||
llarp_dht_context_free(struct llarp_dht_context* dht);
|
|
||||||
|
|
||||||
/// start dht context with our location in keyspace
|
|
||||||
void
|
|
||||||
llarp_dht_context_start(struct llarp_dht_context* ctx, const byte_t* key);
|
|
||||||
|
|
||||||
// remove this? dns needs it atm
|
|
||||||
struct llarp_router_lookup_job;
|
|
||||||
|
|
||||||
using llarp_router_lookup_handler = void (*)(struct llarp_router_lookup_job*);
|
|
||||||
|
|
||||||
struct llarp_router_lookup_job
|
|
||||||
{
|
|
||||||
/// can be anything but usually a class context for hook
|
|
||||||
void* user;
|
|
||||||
llarp_router_lookup_handler hook;
|
|
||||||
struct llarp_dht_context* dht;
|
|
||||||
llarp::PubKey target;
|
|
||||||
bool found;
|
|
||||||
// make sure you initialize addr and exits
|
|
||||||
llarp::RouterContact result;
|
|
||||||
bool iterative;
|
|
||||||
};
|
|
||||||
// end dns requirement
|
|
||||||
|
|
||||||
/// start allowing dht participation on a context
|
|
||||||
void
|
|
||||||
llarp_dht_allow_transit(struct llarp_dht_context* ctx);
|
|
||||||
|
|
||||||
/// remove router from tracked dht peer list
|
|
||||||
/// internal function do not use
|
|
||||||
void
|
|
||||||
__llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id);
|
|
||||||
|
|
||||||
void
|
|
||||||
llarp_dht_lookup_router(struct llarp_dht_context* ctx, struct llarp_router_lookup_job* job);
|
|
@ -1,39 +0,0 @@
|
|||||||
#include "explorenetworkjob.hpp"
|
|
||||||
|
|
||||||
#include <llarp/dht/messages/findrouter.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
|
||||||
|
|
||||||
#include <llarp/nodedb.hpp>
|
|
||||||
|
|
||||||
#include <llarp/tooling/dht_event.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
void
|
|
||||||
ExploreNetworkJob::Start(const TXOwner& peer)
|
|
||||||
{
|
|
||||||
auto msg = new FindRouterMessage(peer.txid);
|
|
||||||
auto router = parent->GetRouter();
|
|
||||||
if (router)
|
|
||||||
{
|
|
||||||
router->notify_router_event<tooling::FindRouterSentEvent>(router->pubkey(), *msg);
|
|
||||||
}
|
|
||||||
parent->DHTSendTo(peer.node.as_array(), msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ExploreNetworkJob::SendReply()
|
|
||||||
{
|
|
||||||
llarp::LogDebug("got ", valuesFound.size(), " routers from exploration");
|
|
||||||
|
|
||||||
auto router = parent->GetRouter();
|
|
||||||
for (const auto& pk : valuesFound)
|
|
||||||
{
|
|
||||||
// lookup router
|
|
||||||
if (router and router->node_db()->Has(pk))
|
|
||||||
continue;
|
|
||||||
parent->LookupRouter(
|
|
||||||
pk, [router, pk](const auto& res) { router->HandleDHTLookupForExplore(pk, res); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace llarp::dht
|
|
@ -1,30 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_EXPLORENETWORKJOB
|
|
||||||
#define LLARP_DHT_EXPLORENETWORKJOB
|
|
||||||
|
|
||||||
#include "tx.hpp"
|
|
||||||
#include <llarp/router_id.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
struct ExploreNetworkJob : public TX<RouterID, RouterID>
|
|
||||||
{
|
|
||||||
ExploreNetworkJob(const RouterID& peer, AbstractDHTMessageHandler* ctx)
|
|
||||||
: TX<RouterID, RouterID>(TXOwner{}, peer, ctx)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Validate(const RouterID&) const override
|
|
||||||
{
|
|
||||||
// TODO: check with lokid
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Start(const TXOwner& peer) override;
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
} // namespace llarp::dht
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,61 +0,0 @@
|
|||||||
#include "localrouterlookup.hpp"
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include <llarp/dht/messages/gotrouter.hpp>
|
|
||||||
|
|
||||||
#include <llarp/path/path_context.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
|
||||||
#include <llarp/routing/path_dht_message.hpp>
|
|
||||||
#include <llarp/util/logging.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
LocalRouterLookup::LocalRouterLookup(
|
|
||||||
const PathID_t& path, uint64_t txid, const RouterID& _target, AbstractDHTMessageHandler* ctx)
|
|
||||||
: RecursiveRouterLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx, nullptr), localPath(path)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void
|
|
||||||
LocalRouterLookup::SendReply()
|
|
||||||
{
|
|
||||||
auto path =
|
|
||||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"did not send reply for relayed dht request, no such local path "
|
|
||||||
"for pathid=",
|
|
||||||
localPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (valuesFound.size())
|
|
||||||
{
|
|
||||||
RouterContact found;
|
|
||||||
for (const auto& rc : valuesFound)
|
|
||||||
{
|
|
||||||
if (rc.OtherIsNewer(found))
|
|
||||||
found = rc;
|
|
||||||
}
|
|
||||||
valuesFound.clear();
|
|
||||||
if (not found.pubkey.IsZero())
|
|
||||||
{
|
|
||||||
valuesFound.resize(1);
|
|
||||||
valuesFound[0] = found;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
llarp::LogWarn("We found a null RC for dht request, dropping it");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
routing::PathDHTMessage msg;
|
|
||||||
msg.dht_msgs.emplace_back(
|
|
||||||
new GotRouterMessage(parent->OurKey(), whoasked.txid, valuesFound, true));
|
|
||||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"failed to send routing message when informing result of dht "
|
|
||||||
"request, pathid=",
|
|
||||||
localPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace llarp::dht
|
|
@ -1,27 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_LOCALROUTERLOOKUP
|
|
||||||
#define LLARP_DHT_LOCALROUTERLOOKUP
|
|
||||||
|
|
||||||
#include "recursiverouterlookup.hpp"
|
|
||||||
|
|
||||||
#include <llarp/path/path_types.hpp>
|
|
||||||
#include <llarp/router_contact.hpp>
|
|
||||||
#include <llarp/router_id.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
struct LocalRouterLookup : public RecursiveRouterLookup
|
|
||||||
{
|
|
||||||
PathID_t localPath;
|
|
||||||
|
|
||||||
LocalRouterLookup(
|
|
||||||
const PathID_t& path,
|
|
||||||
uint64_t txid,
|
|
||||||
const RouterID& target,
|
|
||||||
AbstractDHTMessageHandler* ctx);
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
} // namespace llarp::dht
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||||||
#include "localserviceaddresslookup.hpp"
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include <llarp/dht/messages/gotintro.hpp>
|
|
||||||
#include <llarp/path/path_context.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
|
||||||
#include <llarp/routing/path_dht_message.hpp>
|
|
||||||
#include <llarp/util/logging.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
LocalServiceAddressLookup::LocalServiceAddressLookup(
|
|
||||||
const PathID_t& pathid,
|
|
||||||
uint64_t txid,
|
|
||||||
uint64_t relayOrder,
|
|
||||||
const Key_t& addr,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
[[maybe_unused]] const Key_t& askpeer)
|
|
||||||
: ServiceAddressLookup(TXOwner{ctx->OurKey(), txid}, addr, ctx, relayOrder, nullptr)
|
|
||||||
, localPath(pathid)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void
|
|
||||||
LocalServiceAddressLookup::SendReply()
|
|
||||||
{
|
|
||||||
auto path =
|
|
||||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"did not send reply for relayed dht request, no such local path "
|
|
||||||
"for pathid=",
|
|
||||||
localPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// pick newest if we have more than 1 result
|
|
||||||
if (valuesFound.size())
|
|
||||||
{
|
|
||||||
service::EncryptedIntroSet found;
|
|
||||||
for (const auto& introset : valuesFound)
|
|
||||||
{
|
|
||||||
if (found.OtherIsNewer(introset))
|
|
||||||
found = introset;
|
|
||||||
}
|
|
||||||
valuesFound.clear();
|
|
||||||
valuesFound.emplace_back(found);
|
|
||||||
}
|
|
||||||
routing::PathDHTMessage msg;
|
|
||||||
msg.dht_msgs.emplace_back(new GotIntroMessage(valuesFound, whoasked.txid));
|
|
||||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"failed to send routing message when informing result of dht "
|
|
||||||
"request, pathid=",
|
|
||||||
localPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace llarp::dht
|
|
@ -1,28 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_LOCALSERVICEADDRESSLOOKUP
|
|
||||||
#define LLARP_DHT_LOCALSERVICEADDRESSLOOKUP
|
|
||||||
|
|
||||||
#include "serviceaddresslookup.hpp"
|
|
||||||
|
|
||||||
#include <llarp/path/path_types.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
struct LocalServiceAddressLookup : public ServiceAddressLookup
|
|
||||||
{
|
|
||||||
PathID_t localPath;
|
|
||||||
|
|
||||||
LocalServiceAddressLookup(
|
|
||||||
const PathID_t& pathid,
|
|
||||||
uint64_t txid,
|
|
||||||
uint64_t relayOrder,
|
|
||||||
const Key_t& addr,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
[[maybe_unused]] const Key_t& askpeer);
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace llarp::dht
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||||||
#include "localtaglookup.hpp"
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include <llarp/dht/messages/gotintro.hpp>
|
|
||||||
#include <llarp/path/path_context.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
|
||||||
#include <llarp/routing/path_dht_message.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
LocalTagLookup::LocalTagLookup(
|
|
||||||
const PathID_t& path,
|
|
||||||
uint64_t txid,
|
|
||||||
const service::Tag& _target,
|
|
||||||
AbstractDHTMessageHandler* ctx)
|
|
||||||
: TagLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx, 0), localPath(path)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void
|
|
||||||
LocalTagLookup::SendReply()
|
|
||||||
{
|
|
||||||
auto path =
|
|
||||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"did not send reply for relayed dht request, no such local path "
|
|
||||||
"for pathid=",
|
|
||||||
localPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
routing::PathDHTMessage msg;
|
|
||||||
msg.dht_msgs.emplace_back(new GotIntroMessage(valuesFound, whoasked.txid));
|
|
||||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"failed to send routing message when informing result of dht "
|
|
||||||
"request, pathid=",
|
|
||||||
localPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace llarp::dht
|
|
@ -1,23 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_LOOKUPTAGLOOKUP
|
|
||||||
#define LLARP_DHT_LOOKUPTAGLOOKUP
|
|
||||||
|
|
||||||
#include "taglookup.hpp"
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
struct LocalTagLookup : public TagLookup
|
|
||||||
{
|
|
||||||
PathID_t localPath;
|
|
||||||
|
|
||||||
LocalTagLookup(
|
|
||||||
const PathID_t& path,
|
|
||||||
uint64_t txid,
|
|
||||||
const service::Tag& target,
|
|
||||||
AbstractDHTMessageHandler* ctx);
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
} // namespace llarp::dht
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,138 +0,0 @@
|
|||||||
#include "context.hpp"
|
|
||||||
#include "oxenc/bt_serialize.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <llarp/util/bencode.hpp>
|
|
||||||
#include <llarp/dht/messages/findintro.hpp>
|
|
||||||
#include <llarp/dht/messages/findrouter.hpp>
|
|
||||||
#include <llarp/dht/messages/gotintro.hpp>
|
|
||||||
#include <llarp/dht/messages/gotrouter.hpp>
|
|
||||||
#include <llarp/dht/messages/pubintro.hpp>
|
|
||||||
#include <llarp/dht/messages/findname.hpp>
|
|
||||||
#include <llarp/dht/messages/gotname.hpp>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
struct MessageDecoder
|
|
||||||
{
|
|
||||||
const Key_t& From;
|
|
||||||
std::unique_ptr<AbstractDHTMessage> msg;
|
|
||||||
bool firstKey = true;
|
|
||||||
bool relayed = false;
|
|
||||||
|
|
||||||
MessageDecoder(const Key_t& from, bool wasRelayed) : From(from), relayed(wasRelayed)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator()(llarp_buffer_t* buffer, llarp_buffer_t* key)
|
|
||||||
{
|
|
||||||
llarp_buffer_t strbuf;
|
|
||||||
// check for empty dict
|
|
||||||
if (!key)
|
|
||||||
return !firstKey;
|
|
||||||
// first key
|
|
||||||
if (firstKey)
|
|
||||||
{
|
|
||||||
if (!(key->startswith("A")))
|
|
||||||
return false;
|
|
||||||
if (!bencode_read_string(buffer, &strbuf))
|
|
||||||
return false;
|
|
||||||
// bad msg size?
|
|
||||||
if (strbuf.sz != 1)
|
|
||||||
return false;
|
|
||||||
llarp::LogDebug("Handle DHT message ", *strbuf.base, " relayed=", relayed);
|
|
||||||
switch (*strbuf.base)
|
|
||||||
{
|
|
||||||
case 'N':
|
|
||||||
msg = std::make_unique<FindNameMessage>(From, Key_t{}, 0);
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
msg = std::make_unique<GotNameMessage>(From, 0, service::EncryptedName{});
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
msg = std::make_unique<FindIntroMessage>(From, relayed, 0);
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
if (relayed)
|
|
||||||
msg = std::make_unique<RelayedFindRouterMessage>(From);
|
|
||||||
else
|
|
||||||
msg = std::make_unique<FindRouterMessage>(From);
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
msg = std::make_unique<GotRouterMessage>(From, relayed);
|
|
||||||
break;
|
|
||||||
case 'I':
|
|
||||||
msg = std::make_unique<PublishIntroMessage>(From, relayed);
|
|
||||||
break;
|
|
||||||
case 'G':
|
|
||||||
if (relayed)
|
|
||||||
{
|
|
||||||
msg = std::make_unique<RelayedGotIntroMessage>();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg = std::make_unique<GotIntroMessage>(From);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
llarp::LogWarn("unknown dht message type: ", (char)*strbuf.base);
|
|
||||||
// bad msg type
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
firstKey = false;
|
|
||||||
return msg != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return msg->decode_key(*key, buffer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<AbstractDHTMessage>
|
|
||||||
DecodeMessage(const Key_t& from, llarp_buffer_t* buf, bool relayed)
|
|
||||||
{
|
|
||||||
MessageDecoder dec(from, relayed);
|
|
||||||
if (!bencode_read_dict(dec, buf))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return std::move(dec.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ListDecoder
|
|
||||||
{
|
|
||||||
ListDecoder(
|
|
||||||
bool hasRelayed, const Key_t& from, std::vector<std::unique_ptr<AbstractDHTMessage>>& list)
|
|
||||||
: relayed(hasRelayed), From(from), l(list)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool relayed;
|
|
||||||
const Key_t& From;
|
|
||||||
std::vector<std::unique_ptr<AbstractDHTMessage>>& l;
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator()(llarp_buffer_t* buffer, bool has)
|
|
||||||
{
|
|
||||||
if (!has)
|
|
||||||
return true;
|
|
||||||
auto msg = DecodeMessage(From, buffer, relayed);
|
|
||||||
if (msg)
|
|
||||||
{
|
|
||||||
l.emplace_back(std::move(msg));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool
|
|
||||||
DecodeMessageList(
|
|
||||||
Key_t from,
|
|
||||||
llarp_buffer_t* buf,
|
|
||||||
std::vector<std::unique_ptr<AbstractDHTMessage>>& list,
|
|
||||||
bool relayed)
|
|
||||||
{
|
|
||||||
ListDecoder dec(relayed, from, list);
|
|
||||||
return bencode_read_list(dec, buf);
|
|
||||||
}
|
|
||||||
} // namespace llarp::dht
|
|
@ -1,81 +0,0 @@
|
|||||||
#include "publishservicejob.hpp"
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include <llarp/dht/messages/pubintro.hpp>
|
|
||||||
#include <llarp/dht/messages/gotintro.hpp>
|
|
||||||
#include <llarp/path/path_context.hpp>
|
|
||||||
#include <llarp/routing/path_dht_message.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
PublishServiceJob::PublishServiceJob(
|
|
||||||
const TXOwner& asker,
|
|
||||||
const service::EncryptedIntroSet& introset_,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
uint64_t relayOrder_)
|
|
||||||
: TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx)
|
|
||||||
, relayOrder(relayOrder_)
|
|
||||||
, introset(introset_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool
|
|
||||||
PublishServiceJob::Validate(const service::EncryptedIntroSet& value) const
|
|
||||||
{
|
|
||||||
if (value.derivedSigningKey != introset.derivedSigningKey)
|
|
||||||
{
|
|
||||||
llarp::LogWarn("publish introset acknowledgement acked a different service");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const llarp_time_t now = llarp::time_now_ms();
|
|
||||||
return value.verify(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PublishServiceJob::Start(const TXOwner& peer)
|
|
||||||
{
|
|
||||||
parent->DHTSendTo(
|
|
||||||
peer.node.as_array(), new PublishIntroMessage(introset, peer.txid, false, relayOrder));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PublishServiceJob::SendReply()
|
|
||||||
{
|
|
||||||
parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage({introset}, whoasked.txid));
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPublishServiceJob::LocalPublishServiceJob(
|
|
||||||
const TXOwner& peer,
|
|
||||||
const PathID_t& fromID,
|
|
||||||
uint64_t _txid,
|
|
||||||
const service::EncryptedIntroSet& introset,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
uint64_t relayOrder)
|
|
||||||
: PublishServiceJob(peer, introset, ctx, relayOrder), localPath(fromID), txid(_txid)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void
|
|
||||||
LocalPublishServiceJob::SendReply()
|
|
||||||
{
|
|
||||||
auto path =
|
|
||||||
parent->GetRouter()->path_context().GetByUpstream(parent->OurKey().as_array(), localPath);
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"did not send reply for relayed dht request, no such local path "
|
|
||||||
"for pathid=",
|
|
||||||
localPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
routing::PathDHTMessage msg;
|
|
||||||
msg.dht_msgs.emplace_back(new GotIntroMessage({introset}, txid));
|
|
||||||
if (!path->SendRoutingMessage(msg, parent->GetRouter()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"failed to send routing message when informing result of dht "
|
|
||||||
"request, pathid=",
|
|
||||||
localPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace llarp::dht
|
|
@ -1,51 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_PUBLISHSERVICEJOB
|
|
||||||
#define LLARP_DHT_PUBLISHSERVICEJOB
|
|
||||||
|
|
||||||
#include "tx.hpp"
|
|
||||||
#include "txowner.hpp"
|
|
||||||
#include <llarp/service/address.hpp>
|
|
||||||
#include <llarp/service/intro_set.hpp>
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
struct PublishServiceJob : public TX<TXOwner, service::EncryptedIntroSet>
|
|
||||||
{
|
|
||||||
uint64_t relayOrder;
|
|
||||||
service::EncryptedIntroSet introset;
|
|
||||||
|
|
||||||
PublishServiceJob(
|
|
||||||
const TXOwner& asker,
|
|
||||||
const service::EncryptedIntroSet& introset,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
uint64_t relayOrder);
|
|
||||||
|
|
||||||
bool
|
|
||||||
Validate(const service::EncryptedIntroSet& introset) const override;
|
|
||||||
|
|
||||||
void
|
|
||||||
Start(const TXOwner& peer) override;
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LocalPublishServiceJob : public PublishServiceJob
|
|
||||||
{
|
|
||||||
PathID_t localPath;
|
|
||||||
uint64_t txid;
|
|
||||||
LocalPublishServiceJob(
|
|
||||||
const TXOwner& peer,
|
|
||||||
const PathID_t& fromID,
|
|
||||||
uint64_t txid,
|
|
||||||
const service::EncryptedIntroSet& introset,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
uint64_t relayOrder);
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
} // namespace llarp::dht
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||||||
#include "recursiverouterlookup.hpp"
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include <llarp/dht/messages/findrouter.hpp>
|
|
||||||
#include <llarp/dht/messages/gotrouter.hpp>
|
|
||||||
|
|
||||||
#include <llarp/router/router.hpp>
|
|
||||||
#include <llarp/router/rc_lookup_handler.hpp>
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
RecursiveRouterLookup::RecursiveRouterLookup(
|
|
||||||
const TXOwner& _whoasked,
|
|
||||||
const RouterID& _target,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
RouterLookupHandler result)
|
|
||||||
: TX<RouterID, RouterContact>(_whoasked, _target, ctx), resultHandler(std::move(result))
|
|
||||||
|
|
||||||
{
|
|
||||||
peersAsked.insert(ctx->OurKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RecursiveRouterLookup::Validate(const RouterContact& rc) const
|
|
||||||
{
|
|
||||||
if (!rc.Verify(parent->Now()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("rc from lookup result is invalid");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RecursiveRouterLookup::Start(const TXOwner& peer)
|
|
||||||
{
|
|
||||||
parent->DHTSendTo(peer.node.as_array(), new FindRouterMessage(peer.txid, target));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RecursiveRouterLookup::SendReply()
|
|
||||||
{
|
|
||||||
if (valuesFound.size())
|
|
||||||
{
|
|
||||||
RouterContact found;
|
|
||||||
for (const auto& rc : valuesFound)
|
|
||||||
{
|
|
||||||
if (found.OtherIsNewer(rc) && parent->GetRouter()->rc_lookup_handler().check_rc(rc))
|
|
||||||
found = rc;
|
|
||||||
}
|
|
||||||
valuesFound.clear();
|
|
||||||
valuesFound.emplace_back(found);
|
|
||||||
}
|
|
||||||
if (resultHandler)
|
|
||||||
{
|
|
||||||
resultHandler(valuesFound);
|
|
||||||
}
|
|
||||||
if (whoasked.node != parent->OurKey())
|
|
||||||
{
|
|
||||||
parent->DHTSendTo(
|
|
||||||
whoasked.node.as_array(),
|
|
||||||
new GotRouterMessage({}, whoasked.txid, valuesFound, false),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
@ -1,34 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_RECURSIVEROUTERLOOKUP
|
|
||||||
#define LLARP_DHT_RECURSIVEROUTERLOOKUP
|
|
||||||
|
|
||||||
#include "tx.hpp"
|
|
||||||
|
|
||||||
#include <llarp/router_contact.hpp>
|
|
||||||
#include <llarp/router_id.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
struct RecursiveRouterLookup : public TX<RouterID, RouterContact>
|
|
||||||
{
|
|
||||||
RouterLookupHandler resultHandler;
|
|
||||||
RecursiveRouterLookup(
|
|
||||||
const TXOwner& whoasked,
|
|
||||||
const RouterID& target,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
RouterLookupHandler result);
|
|
||||||
|
|
||||||
bool
|
|
||||||
Validate(const RouterContact& rc) const override;
|
|
||||||
|
|
||||||
void
|
|
||||||
Start(const TXOwner& peer) override;
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||||||
#include "serviceaddresslookup.hpp"
|
|
||||||
|
|
||||||
#include <llarp/dht/messages/findintro.hpp>
|
|
||||||
#include <llarp/dht/messages/gotintro.hpp>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
ServiceAddressLookup::ServiceAddressLookup(
|
|
||||||
const TXOwner& asker,
|
|
||||||
const Key_t& addr,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
uint32_t order,
|
|
||||||
service::EncryptedIntroSetLookupHandler handler)
|
|
||||||
: TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx)
|
|
||||||
, location(addr)
|
|
||||||
, handleResult(std::move(handler))
|
|
||||||
, relayOrder(order)
|
|
||||||
{
|
|
||||||
peersAsked.insert(ctx->OurKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ServiceAddressLookup::Validate(const service::EncryptedIntroSet& value) const
|
|
||||||
{
|
|
||||||
if (!value.verify(parent->Now()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("Got invalid introset from service lookup");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (value.derivedSigningKey != location)
|
|
||||||
{
|
|
||||||
llarp::LogWarn("got introset with wrong target from service lookup");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ServiceAddressLookup::Start(const TXOwner& peer)
|
|
||||||
{
|
|
||||||
parent->DHTSendTo(
|
|
||||||
peer.node.as_array(), new FindIntroMessage(peer.txid, location, relayOrder));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ServiceAddressLookup::SendReply()
|
|
||||||
{
|
|
||||||
// get newest introset
|
|
||||||
if (valuesFound.size())
|
|
||||||
{
|
|
||||||
llarp::service::EncryptedIntroSet found;
|
|
||||||
for (const auto& introset : valuesFound)
|
|
||||||
{
|
|
||||||
if (found.OtherIsNewer(introset))
|
|
||||||
found = introset;
|
|
||||||
}
|
|
||||||
valuesFound.clear();
|
|
||||||
valuesFound.emplace_back(found);
|
|
||||||
}
|
|
||||||
if (handleResult)
|
|
||||||
{
|
|
||||||
handleResult(valuesFound);
|
|
||||||
}
|
|
||||||
parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage(valuesFound, whoasked.txid));
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
@ -1,41 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_SERVICEADDRESSLOOKUP
|
|
||||||
#define LLARP_DHT_SERVICEADDRESSLOOKUP
|
|
||||||
|
|
||||||
#include "key.hpp"
|
|
||||||
#include "tx.hpp"
|
|
||||||
#include <llarp/service/address.hpp>
|
|
||||||
#include <llarp/service/intro_set.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
struct TXOwner;
|
|
||||||
|
|
||||||
struct ServiceAddressLookup : public TX<TXOwner, service::EncryptedIntroSet>
|
|
||||||
{
|
|
||||||
Key_t location;
|
|
||||||
service::EncryptedIntroSetLookupHandler handleResult;
|
|
||||||
uint32_t relayOrder;
|
|
||||||
|
|
||||||
ServiceAddressLookup(
|
|
||||||
const TXOwner& asker,
|
|
||||||
const Key_t& addr,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
uint32_t relayOrder,
|
|
||||||
service::EncryptedIntroSetLookupHandler handler);
|
|
||||||
|
|
||||||
bool
|
|
||||||
Validate(const service::EncryptedIntroSet& value) const override;
|
|
||||||
|
|
||||||
void
|
|
||||||
Start(const TXOwner& peer) override;
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
} // namespace dht
|
|
||||||
|
|
||||||
} // namespace llarp
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||||||
#include "taglookup.hpp"
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include <llarp/dht/messages/gotintro.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
bool
|
|
||||||
TagLookup::Validate(const service::EncryptedIntroSet& introset) const
|
|
||||||
{
|
|
||||||
if (!introset.verify(parent->Now()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("got invalid introset from tag lookup");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (not introset.topic)
|
|
||||||
return false;
|
|
||||||
if (*introset.topic != target)
|
|
||||||
{
|
|
||||||
llarp::LogWarn("got introset with mismatched topic in tag lookup");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TagLookup::Start(const TXOwner& peer)
|
|
||||||
{
|
|
||||||
parent->DHTSendTo(peer.node.as_array(), new FindIntroMessage(target, peer.txid));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TagLookup::SendReply()
|
|
||||||
{
|
|
||||||
parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage({}, whoasked.txid));
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
@ -1,35 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_TAGLOOKUP
|
|
||||||
#define LLARP_DHT_TAGLOOKUP
|
|
||||||
|
|
||||||
#include "tx.hpp"
|
|
||||||
#include <llarp/service/intro_set.hpp>
|
|
||||||
#include <llarp/service/tag.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
struct TagLookup : public TX<service::Tag, service::EncryptedIntroSet>
|
|
||||||
{
|
|
||||||
uint64_t recursionDepth;
|
|
||||||
TagLookup(
|
|
||||||
const TXOwner& asker,
|
|
||||||
const service::Tag& tag,
|
|
||||||
AbstractDHTMessageHandler* ctx,
|
|
||||||
uint64_t recursion)
|
|
||||||
: TX<service::Tag, service::EncryptedIntroSet>(asker, tag, ctx), recursionDepth(recursion)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Validate(const service::EncryptedIntroSet& introset) const override;
|
|
||||||
|
|
||||||
void
|
|
||||||
Start(const TXOwner& peer) override;
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply() override;
|
|
||||||
};
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,79 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_TX
|
|
||||||
#define LLARP_DHT_TX
|
|
||||||
|
|
||||||
#include "key.hpp"
|
|
||||||
#include "txowner.hpp"
|
|
||||||
#include <llarp/util/logging.hpp>
|
|
||||||
#include <llarp/util/status.hpp>
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace llarp::dht
|
|
||||||
{
|
|
||||||
struct AbstractDHTMessageHandler;
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
struct TX
|
|
||||||
{
|
|
||||||
K target;
|
|
||||||
AbstractDHTMessageHandler* parent;
|
|
||||||
std::set<Key_t> peersAsked;
|
|
||||||
std::vector<V> valuesFound;
|
|
||||||
TXOwner whoasked;
|
|
||||||
|
|
||||||
TX(const TXOwner& asker, const K& k, AbstractDHTMessageHandler* p)
|
|
||||||
: target(k), parent(p), whoasked(asker)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual ~TX() = default;
|
|
||||||
|
|
||||||
void
|
|
||||||
OnFound(const Key_t& askedPeer, const V& value);
|
|
||||||
|
|
||||||
util::StatusObject
|
|
||||||
ExtractStatus() const
|
|
||||||
{
|
|
||||||
util::StatusObject obj{
|
|
||||||
{"whoasked", whoasked.ExtractStatus()}, {"target", target.ExtractStatus()}};
|
|
||||||
std::vector<util::StatusObject> foundObjs;
|
|
||||||
std::transform(
|
|
||||||
valuesFound.begin(),
|
|
||||||
valuesFound.end(),
|
|
||||||
std::back_inserter(foundObjs),
|
|
||||||
[](const auto& item) -> util::StatusObject { return item.ExtractStatus(); });
|
|
||||||
|
|
||||||
obj["found"] = foundObjs;
|
|
||||||
std::vector<std::string> asked;
|
|
||||||
std::transform(
|
|
||||||
peersAsked.begin(),
|
|
||||||
peersAsked.end(),
|
|
||||||
std::back_inserter(asked),
|
|
||||||
[](const auto& item) -> std::string { return item.ToString(); });
|
|
||||||
obj["asked"] = asked;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool
|
|
||||||
Validate(const V& value) const = 0;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
Start(const TXOwner& peer) = 0;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
SendReply() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline void
|
|
||||||
TX<K, V>::OnFound(const Key_t& askedPeer, const V& value)
|
|
||||||
{
|
|
||||||
peersAsked.insert(askedPeer);
|
|
||||||
if (Validate(value))
|
|
||||||
{
|
|
||||||
valuesFound.push_back(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace llarp::dht
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,216 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_TXHOLDER
|
|
||||||
#define LLARP_DHT_TXHOLDER
|
|
||||||
|
|
||||||
#include "tx.hpp"
|
|
||||||
#include "txowner.hpp"
|
|
||||||
#include <llarp/util/time.hpp>
|
|
||||||
#include <llarp/util/status.hpp>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
template <typename K, typename V>
|
|
||||||
struct TXHolder
|
|
||||||
{
|
|
||||||
using TXPtr = std::unique_ptr<TX<K, V>>;
|
|
||||||
// tx who are waiting for a reply for each key
|
|
||||||
std::unordered_multimap<K, TXOwner> waiting;
|
|
||||||
// tx timesouts by key
|
|
||||||
std::unordered_map<K, llarp_time_t> timeouts;
|
|
||||||
// maps remote peer with tx to handle reply from them
|
|
||||||
std::unordered_map<TXOwner, TXPtr> tx;
|
|
||||||
|
|
||||||
const TX<K, V>*
|
|
||||||
GetPendingLookupFrom(const TXOwner& owner) const;
|
|
||||||
|
|
||||||
util::StatusObject
|
|
||||||
ExtractStatus() const
|
|
||||||
{
|
|
||||||
util::StatusObject obj{};
|
|
||||||
std::vector<util::StatusObject> txObjs, timeoutsObjs, waitingObjs;
|
|
||||||
std::transform(
|
|
||||||
tx.begin(),
|
|
||||||
tx.end(),
|
|
||||||
std::back_inserter(txObjs),
|
|
||||||
[](const auto& item) -> util::StatusObject {
|
|
||||||
return util::StatusObject{
|
|
||||||
{"owner", item.first.ExtractStatus()}, {"tx", item.second->ExtractStatus()}};
|
|
||||||
});
|
|
||||||
obj["tx"] = txObjs;
|
|
||||||
std::transform(
|
|
||||||
timeouts.begin(),
|
|
||||||
timeouts.end(),
|
|
||||||
std::back_inserter(timeoutsObjs),
|
|
||||||
[](const auto& item) -> util::StatusObject {
|
|
||||||
return util::StatusObject{
|
|
||||||
{"time", to_json(item.second)}, {"target", item.first.ExtractStatus()}};
|
|
||||||
});
|
|
||||||
obj["timeouts"] = timeoutsObjs;
|
|
||||||
std::transform(
|
|
||||||
waiting.begin(),
|
|
||||||
waiting.end(),
|
|
||||||
std::back_inserter(waitingObjs),
|
|
||||||
[](const auto& item) -> util::StatusObject {
|
|
||||||
return util::StatusObject{
|
|
||||||
{"target", item.first.ExtractStatus()},
|
|
||||||
{"whoasked", item.second.ExtractStatus()}};
|
|
||||||
});
|
|
||||||
obj["waiting"] = waitingObjs;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
HasLookupFor(const K& target) const
|
|
||||||
{
|
|
||||||
return timeouts.find(target) != timeouts.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
HasPendingLookupFrom(const TXOwner& owner) const
|
|
||||||
{
|
|
||||||
return GetPendingLookupFrom(owner) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
NewTX(
|
|
||||||
const TXOwner& askpeer,
|
|
||||||
const TXOwner& whoasked,
|
|
||||||
const K& k,
|
|
||||||
TX<K, V>* t,
|
|
||||||
llarp_time_t requestTimeoutMS = 15s);
|
|
||||||
|
|
||||||
/// mark tx as not fond
|
|
||||||
void
|
|
||||||
NotFound(const TXOwner& from, const std::unique_ptr<Key_t>& next);
|
|
||||||
|
|
||||||
void
|
|
||||||
Found(const TXOwner& from, const K& k, const std::vector<V>& values)
|
|
||||||
{
|
|
||||||
Inform(from, k, values, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// inform all watches for key of values found
|
|
||||||
void
|
|
||||||
Inform(
|
|
||||||
TXOwner from,
|
|
||||||
K key,
|
|
||||||
std::vector<V> values,
|
|
||||||
bool sendreply = false,
|
|
||||||
bool removeTimeouts = true);
|
|
||||||
|
|
||||||
void
|
|
||||||
Expire(llarp_time_t now);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
const TX<K, V>*
|
|
||||||
TXHolder<K, V>::GetPendingLookupFrom(const TXOwner& owner) const
|
|
||||||
{
|
|
||||||
auto itr = tx.find(owner);
|
|
||||||
if (itr == tx.end())
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return itr->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
void
|
|
||||||
TXHolder<K, V>::NewTX(
|
|
||||||
const TXOwner& askpeer,
|
|
||||||
const TXOwner& whoasked,
|
|
||||||
const K& k,
|
|
||||||
TX<K, V>* t,
|
|
||||||
llarp_time_t requestTimeoutMS)
|
|
||||||
{
|
|
||||||
(void)whoasked;
|
|
||||||
tx.emplace(askpeer, std::unique_ptr<TX<K, V>>(t));
|
|
||||||
auto count = waiting.count(k);
|
|
||||||
waiting.emplace(k, askpeer);
|
|
||||||
|
|
||||||
auto itr = timeouts.find(k);
|
|
||||||
if (itr == timeouts.end())
|
|
||||||
{
|
|
||||||
timeouts.emplace(k, time_now_ms() + requestTimeoutMS);
|
|
||||||
}
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
t->Start(askpeer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
void
|
|
||||||
TXHolder<K, V>::NotFound(const TXOwner& from, const std::unique_ptr<Key_t>&)
|
|
||||||
{
|
|
||||||
auto txitr = tx.find(from);
|
|
||||||
if (txitr == tx.end())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Inform(from, txitr->second->target, {}, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
void
|
|
||||||
TXHolder<K, V>::Inform(
|
|
||||||
TXOwner from, K key, std::vector<V> values, bool sendreply, bool removeTimeouts)
|
|
||||||
{
|
|
||||||
auto range = waiting.equal_range(key);
|
|
||||||
auto itr = range.first;
|
|
||||||
while (itr != range.second)
|
|
||||||
{
|
|
||||||
auto txitr = tx.find(itr->second);
|
|
||||||
if (txitr != tx.end())
|
|
||||||
{
|
|
||||||
for (const auto& value : values)
|
|
||||||
{
|
|
||||||
txitr->second->OnFound(from.node, value);
|
|
||||||
}
|
|
||||||
if (sendreply)
|
|
||||||
{
|
|
||||||
txitr->second->SendReply();
|
|
||||||
tx.erase(txitr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sendreply)
|
|
||||||
{
|
|
||||||
waiting.erase(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeTimeouts)
|
|
||||||
{
|
|
||||||
timeouts.erase(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
void
|
|
||||||
TXHolder<K, V>::Expire(llarp_time_t now)
|
|
||||||
{
|
|
||||||
auto itr = timeouts.begin();
|
|
||||||
while (itr != timeouts.end())
|
|
||||||
{
|
|
||||||
if (now >= itr->second)
|
|
||||||
{
|
|
||||||
Inform(TXOwner{}, itr->first, {}, true, false);
|
|
||||||
itr = timeouts.erase(itr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "key.hpp"
|
|
||||||
#include <llarp/util/status.hpp>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
struct TXOwner
|
|
||||||
{
|
|
||||||
Key_t node;
|
|
||||||
uint64_t txid = 0;
|
|
||||||
|
|
||||||
TXOwner() = default;
|
|
||||||
TXOwner(const TXOwner&) = default;
|
|
||||||
TXOwner(TXOwner&&) = default;
|
|
||||||
|
|
||||||
TXOwner&
|
|
||||||
operator=(const TXOwner&) = default;
|
|
||||||
|
|
||||||
TXOwner(const Key_t& k, uint64_t id) : node(k), txid(id)
|
|
||||||
{}
|
|
||||||
|
|
||||||
util::StatusObject
|
|
||||||
ExtractStatus() const
|
|
||||||
{
|
|
||||||
util::StatusObject obj{
|
|
||||||
{"txid", txid},
|
|
||||||
{"node", node.ToHex()},
|
|
||||||
};
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const TXOwner& other) const
|
|
||||||
{
|
|
||||||
return std::tie(txid, node) == std::tie(other.txid, other.node);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator<(const TXOwner& other) const
|
|
||||||
{
|
|
||||||
return std::tie(txid, node) < std::tie(other.txid, other.node);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template <>
|
|
||||||
struct hash<llarp::dht::TXOwner>
|
|
||||||
{
|
|
||||||
std::size_t
|
|
||||||
operator()(const llarp::dht::TXOwner& o) const noexcept
|
|
||||||
{
|
|
||||||
std::size_t sz2;
|
|
||||||
memcpy(&sz2, o.node.data(), sizeof(std::size_t));
|
|
||||||
return o.txid ^ (sz2 << 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue