mirror of https://github.com/oxen-io/lokinet
Tidy dht code
parent
9f436174d4
commit
7296ebcbe8
@ -1,217 +0,0 @@
|
|||||||
#include <dht/context.hpp>
|
|
||||||
#include <dht/messages/findintro.hpp>
|
|
||||||
#include <dht/messages/gotintro.hpp>
|
|
||||||
#include <routing/message.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
struct IntroSetLookupInformer
|
|
||||||
{
|
|
||||||
llarp::Router* router;
|
|
||||||
service::Address target;
|
|
||||||
|
|
||||||
void
|
|
||||||
SendReply(const llarp::routing::IMessage* msg)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
FindIntroMessage::~FindIntroMessage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindIntroMessage::DecodeKey(llarp_buffer_t k, llarp_buffer_t* val)
|
|
||||||
{
|
|
||||||
bool read = false;
|
|
||||||
|
|
||||||
if(!BEncodeMaybeReadDictEntry("N", N, read, k, val))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!BEncodeMaybeReadDictInt("R", R, read, k, val))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!BEncodeMaybeReadDictEntry("S", S, read, k, val))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!BEncodeMaybeReadDictInt("T", T, read, k, val))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, k,
|
|
||||||
val))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindIntroMessage::BEncode(llarp_buffer_t* buf) const
|
|
||||||
{
|
|
||||||
if(!bencode_start_dict(buf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// message id
|
|
||||||
if(!BEncodeWriteDictMsgType(buf, "A", "F"))
|
|
||||||
return false;
|
|
||||||
if(N.Empty())
|
|
||||||
{
|
|
||||||
// recursion
|
|
||||||
if(!BEncodeWriteDictInt("R", R, buf))
|
|
||||||
return false;
|
|
||||||
// service address
|
|
||||||
if(!BEncodeWriteDictEntry("S", S, buf))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!BEncodeWriteDictEntry("N", N, buf))
|
|
||||||
return false;
|
|
||||||
// recursion
|
|
||||||
if(!BEncodeWriteDictInt("R", R, buf))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// txid
|
|
||||||
if(!BEncodeWriteDictInt("T", T, buf))
|
|
||||||
return false;
|
|
||||||
// protocol version
|
|
||||||
if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return bencode_end(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindIntroMessage::HandleMessage(
|
|
||||||
llarp_dht_context* ctx,
|
|
||||||
std::vector< std::unique_ptr< IMessage > >& replies) const
|
|
||||||
{
|
|
||||||
if(R > 5)
|
|
||||||
{
|
|
||||||
llarp::LogError("R value too big, ", R, "> 5");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto& dht = ctx->impl;
|
|
||||||
if(dht.pendingIntrosetLookups.HasPendingLookupFrom(TXOwner{From, T}))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("duplicate FIM from ", From, " txid=", T);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Key_t peer;
|
|
||||||
std::set< Key_t > exclude = {dht.OurKey(), From};
|
|
||||||
if(N.Empty())
|
|
||||||
{
|
|
||||||
llarp::LogInfo("lookup ", S.ToString());
|
|
||||||
const auto introset = dht.GetIntroSetByServiceAddress(S);
|
|
||||||
if(introset)
|
|
||||||
{
|
|
||||||
service::IntroSet i = *introset;
|
|
||||||
replies.emplace_back(new GotIntroMessage({i}, T));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(R == 0)
|
|
||||||
{
|
|
||||||
// we don't have it
|
|
||||||
Key_t target = S.ToKey();
|
|
||||||
Key_t closer;
|
|
||||||
// find closer peer
|
|
||||||
if(!dht.nodes->FindClosest(target, closer))
|
|
||||||
return false;
|
|
||||||
if(relayed)
|
|
||||||
dht.LookupIntroSetForPath(S, T, pathID, closer);
|
|
||||||
else
|
|
||||||
replies.emplace_back(new GotIntroMessage(From, closer, T));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Key_t us = dht.OurKey();
|
|
||||||
Key_t target = S.ToKey();
|
|
||||||
// we are recursive
|
|
||||||
if(dht.nodes->FindCloseExcluding(target, peer, exclude))
|
|
||||||
{
|
|
||||||
if(relayed)
|
|
||||||
dht.LookupIntroSetForPath(S, T, pathID, peer);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if((us ^ target) < (peer ^ target))
|
|
||||||
{
|
|
||||||
// we are not closer than our peer to the target so don't
|
|
||||||
// recurse farther
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, T));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if(R > 0)
|
|
||||||
dht.LookupIntroSetRecursive(S, From, T, peer, R - 1);
|
|
||||||
else
|
|
||||||
dht.LookupIntroSetIterative(S, From, T, peer);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no more closer peers
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, T));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(relayed)
|
|
||||||
{
|
|
||||||
// tag lookup
|
|
||||||
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
|
|
||||||
{
|
|
||||||
dht.LookupTagForPath(N, T, pathID, peer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no more closer peers
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, T));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(R == 0)
|
|
||||||
{
|
|
||||||
// base case
|
|
||||||
auto introsets = dht.FindRandomIntroSetsWithTagExcluding(N, 2, {});
|
|
||||||
std::vector< service::IntroSet > reply;
|
|
||||||
for(const auto& introset : introsets)
|
|
||||||
{
|
|
||||||
reply.push_back(introset);
|
|
||||||
}
|
|
||||||
replies.emplace_back(new GotIntroMessage(reply, T));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if(R < 5)
|
|
||||||
{
|
|
||||||
// tag lookup
|
|
||||||
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
|
|
||||||
{
|
|
||||||
dht.LookupTagRecursive(N, From, T, peer, R - 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, T));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// too big R value
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, T));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
@ -1,172 +0,0 @@
|
|||||||
#include <dht/messages/findrouter.hpp>
|
|
||||||
|
|
||||||
#include <dht/context.hpp>
|
|
||||||
#include <dht/messages/gotrouter.hpp>
|
|
||||||
#include <messages/dht.hpp>
|
|
||||||
#include <router/router.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
bool
|
|
||||||
RelayedFindRouterMessage::HandleMessage(
|
|
||||||
llarp_dht_context *ctx,
|
|
||||||
std::vector< std::unique_ptr< IMessage > > &replies) const
|
|
||||||
{
|
|
||||||
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->paths.GetByUpstream(K, pathID);
|
|
||||||
if(path)
|
|
||||||
{
|
|
||||||
replies.emplace_back(
|
|
||||||
new GotRouterMessage(k, txid, {dht.router->rc()}, false));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Key_t peer;
|
|
||||||
// check if we know this in our nodedb first
|
|
||||||
RouterContact found;
|
|
||||||
if(dht.router->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))
|
|
||||||
dht.LookupRouterForPath(K, txid, pathID, peer);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FindRouterMessage::~FindRouterMessage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindRouterMessage::BEncode(llarp_buffer_t *buf) const
|
|
||||||
{
|
|
||||||
if(!bencode_start_dict(buf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// message type
|
|
||||||
if(!bencode_write_bytestring(buf, "A", 1))
|
|
||||||
return false;
|
|
||||||
if(!bencode_write_bytestring(buf, "R", 1))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// exploritory or not?
|
|
||||||
if(!bencode_write_bytestring(buf, "E", 1))
|
|
||||||
return false;
|
|
||||||
if(!bencode_write_uint64(buf, exploritory ? 1 : 0))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// iterative or not?
|
|
||||||
if(!bencode_write_bytestring(buf, "I", 1))
|
|
||||||
return false;
|
|
||||||
if(!bencode_write_uint64(buf, iterative ? 1 : 0))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// key
|
|
||||||
if(!bencode_write_bytestring(buf, "K", 1))
|
|
||||||
return false;
|
|
||||||
if(!bencode_write_bytestring(buf, K.data(), K.size()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// txid
|
|
||||||
if(!bencode_write_bytestring(buf, "T", 1))
|
|
||||||
return false;
|
|
||||||
if(!bencode_write_uint64(buf, txid))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// version
|
|
||||||
if(!bencode_write_bytestring(buf, "V", 1))
|
|
||||||
return false;
|
|
||||||
if(!bencode_write_uint64(buf, version))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return bencode_end(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
|
||||||
{
|
|
||||||
llarp_buffer_t strbuf;
|
|
||||||
|
|
||||||
if(llarp_buffer_eq(key, "E"))
|
|
||||||
{
|
|
||||||
uint64_t result;
|
|
||||||
if(!bencode_read_integer(val, &result))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
exploritory = result != 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(llarp_buffer_eq(key, "I"))
|
|
||||||
{
|
|
||||||
uint64_t result;
|
|
||||||
if(!bencode_read_integer(val, &result))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
iterative = result != 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(llarp_buffer_eq(key, "K"))
|
|
||||||
{
|
|
||||||
if(!bencode_read_string(val, &strbuf))
|
|
||||||
return false;
|
|
||||||
if(strbuf.sz != K.size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::copy(strbuf.base, strbuf.base + K.SIZE, K.begin());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(llarp_buffer_eq(key, "T"))
|
|
||||||
{
|
|
||||||
return bencode_read_integer(val, &txid);
|
|
||||||
}
|
|
||||||
if(llarp_buffer_eq(key, "V"))
|
|
||||||
{
|
|
||||||
return bencode_read_integer(val, &version);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FindRouterMessage::HandleMessage(
|
|
||||||
llarp_dht_context *ctx,
|
|
||||||
std::vector< std::unique_ptr< IMessage > > &replies) const
|
|
||||||
{
|
|
||||||
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}))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("Duplicate FRM from ", From, " txid=", txid);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
RouterContact found;
|
|
||||||
Key_t k{K};
|
|
||||||
if(exploritory)
|
|
||||||
return dht.HandleExploritoryRouterLookup(From, txid, K, replies);
|
|
||||||
else if(dht.router->nodedb->Get(K, found))
|
|
||||||
{
|
|
||||||
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dht.LookupRouterRelayed(From, txid, k, !iterative, replies);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
@ -1,124 +0,0 @@
|
|||||||
#include <dht/context.hpp>
|
|
||||||
#include <dht/messages/gotintro.hpp>
|
|
||||||
#include <messages/dht.hpp>
|
|
||||||
#include <router/router.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
GotIntroMessage::GotIntroMessage(
|
|
||||||
const std::vector< llarp::service::IntroSet > &results, uint64_t tx)
|
|
||||||
: IMessage({}), I(results), T(tx)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GotIntroMessage::~GotIntroMessage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GotIntroMessage::HandleMessage(
|
|
||||||
llarp_dht_context *ctx,
|
|
||||||
__attribute__((unused))
|
|
||||||
std::vector< std::unique_ptr< IMessage > > &replies) const
|
|
||||||
{
|
|
||||||
auto &dht = ctx->impl;
|
|
||||||
auto crypto = &dht.router->crypto;
|
|
||||||
|
|
||||||
for(const auto &introset : I)
|
|
||||||
{
|
|
||||||
if(!introset.Verify(crypto, dht.Now()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"Invalid introset while handling direct GotIntro "
|
|
||||||
"from ",
|
|
||||||
From);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TXOwner owner(From, T);
|
|
||||||
auto tagLookup = dht.pendingTagLookups.GetPendingLookupFrom(owner);
|
|
||||||
if(tagLookup)
|
|
||||||
{
|
|
||||||
dht.pendingTagLookups.Found(owner, tagLookup->target, I);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
auto serviceLookup =
|
|
||||||
dht.pendingIntrosetLookups.GetPendingLookupFrom(owner);
|
|
||||||
if(serviceLookup)
|
|
||||||
{
|
|
||||||
if(I.size())
|
|
||||||
{
|
|
||||||
dht.pendingIntrosetLookups.Found(owner, serviceLookup->target, I);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dht.pendingIntrosetLookups.NotFound(owner, K);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
llarp::LogError("no pending TX for GIM from ", From, " txid=", T);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RelayedGotIntroMessage::HandleMessage(
|
|
||||||
llarp_dht_context *ctx,
|
|
||||||
__attribute__((unused))
|
|
||||||
std::vector< std::unique_ptr< IMessage > > &replies) const
|
|
||||||
{
|
|
||||||
// TODO: implement me better?
|
|
||||||
auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID);
|
|
||||||
if(pathset)
|
|
||||||
{
|
|
||||||
return pathset->HandleGotIntroMessage(this);
|
|
||||||
}
|
|
||||||
llarp::LogWarn("No path for got intro message pathid=", pathID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GotIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
|
||||||
{
|
|
||||||
if(llarp_buffer_eq(key, "I"))
|
|
||||||
{
|
|
||||||
return BEncodeReadList(I, buf);
|
|
||||||
}
|
|
||||||
if(llarp_buffer_eq(key, "K"))
|
|
||||||
{
|
|
||||||
if(K) // duplicate key?
|
|
||||||
return false;
|
|
||||||
K.reset(new dht::Key_t());
|
|
||||||
return K->BDecode(buf);
|
|
||||||
}
|
|
||||||
bool read = false;
|
|
||||||
if(!BEncodeMaybeReadDictInt("T", T, read, key, buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeMaybeReadDictInt("V", version, read, key, buf))
|
|
||||||
return false;
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GotIntroMessage::BEncode(llarp_buffer_t *buf) const
|
|
||||||
{
|
|
||||||
if(!bencode_start_dict(buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictMsgType(buf, "A", "G"))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictList("I", I, buf))
|
|
||||||
return false;
|
|
||||||
if(K)
|
|
||||||
{
|
|
||||||
if(!BEncodeWriteDictEntry("K", *K.get(), buf))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!BEncodeWriteDictInt("T", T, buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictInt("V", version, buf))
|
|
||||||
return false;
|
|
||||||
return bencode_end(buf);
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
@ -1,123 +0,0 @@
|
|||||||
#include <dht/context.hpp>
|
|
||||||
#include <dht/messages/gotrouter.hpp>
|
|
||||||
|
|
||||||
#include <router/router.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
GotRouterMessage::~GotRouterMessage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GotRouterMessage::BEncode(llarp_buffer_t *buf) const
|
|
||||||
{
|
|
||||||
if(!bencode_start_dict(buf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// message type
|
|
||||||
if(!BEncodeWriteDictMsgType(buf, "A", "S"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(K)
|
|
||||||
{
|
|
||||||
if(!BEncodeWriteDictEntry("K", *K.get(), buf))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// near
|
|
||||||
if(N.size())
|
|
||||||
{
|
|
||||||
if(!BEncodeWriteDictList("N", N, buf))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!BEncodeWriteDictList("R", R, buf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// txid
|
|
||||||
if(!BEncodeWriteDictInt("T", txid, buf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// version
|
|
||||||
if(!BEncodeWriteDictInt("V", version, buf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return bencode_end(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GotRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
|
||||||
{
|
|
||||||
if(llarp_buffer_eq(key, "K"))
|
|
||||||
{
|
|
||||||
if(K) // duplicate key?
|
|
||||||
return false;
|
|
||||||
K.reset(new dht::Key_t());
|
|
||||||
return K->BDecode(val);
|
|
||||||
}
|
|
||||||
if(llarp_buffer_eq(key, "N"))
|
|
||||||
{
|
|
||||||
return BEncodeReadList(N, val);
|
|
||||||
}
|
|
||||||
if(llarp_buffer_eq(key, "R"))
|
|
||||||
{
|
|
||||||
return BEncodeReadList(R, val);
|
|
||||||
}
|
|
||||||
if(llarp_buffer_eq(key, "T"))
|
|
||||||
{
|
|
||||||
return bencode_read_integer(val, &txid);
|
|
||||||
}
|
|
||||||
bool read = false;
|
|
||||||
if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, key,
|
|
||||||
val))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
GotRouterMessage::HandleMessage(
|
|
||||||
llarp_dht_context *ctx,
|
|
||||||
__attribute__((unused))
|
|
||||||
std::vector< std::unique_ptr< IMessage > > &replies) const
|
|
||||||
{
|
|
||||||
auto &dht = ctx->impl;
|
|
||||||
if(relayed)
|
|
||||||
{
|
|
||||||
auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID);
|
|
||||||
return pathset && pathset->HandleGotRouterMessage(this);
|
|
||||||
}
|
|
||||||
// not relayed
|
|
||||||
TXOwner owner(From, txid);
|
|
||||||
|
|
||||||
if(dht.pendingExploreLookups.HasPendingLookupFrom(owner))
|
|
||||||
{
|
|
||||||
if(N.size() == 0)
|
|
||||||
dht.pendingExploreLookups.NotFound(owner, K);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dht.pendingExploreLookups.Found(owner, From.as_array(), N);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// not explore lookup
|
|
||||||
|
|
||||||
if(!dht.pendingRouterLookups.HasPendingLookupFrom(owner))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("Unwarrented GRM from ", From, " txid=", txid);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// no pending lookup
|
|
||||||
|
|
||||||
llarp::LogInfo("DHT no pending lookup");
|
|
||||||
if(R.size() == 1)
|
|
||||||
dht.pendingRouterLookups.Found(owner, R[0].pubkey, {R[0]});
|
|
||||||
else
|
|
||||||
dht.pendingRouterLookups.NotFound(owner, K);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
@ -1 +0,0 @@
|
|||||||
#include <dht/messages/all.hpp>
|
|
@ -1,8 +0,0 @@
|
|||||||
#ifndef LLARP_DHT_MESSAGES_ALL_HPP
|
|
||||||
#define LLARP_DHT_MESSAGES_ALL_HPP
|
|
||||||
#include <dht/messages/findintro.hpp>
|
|
||||||
#include <dht/messages/findrouter.hpp>
|
|
||||||
#include <dht/messages/gotintro.hpp>
|
|
||||||
#include <dht/messages/gotrouter.hpp>
|
|
||||||
#include <dht/messages/pubintro.hpp>
|
|
||||||
#endif
|
|
@ -1 +1,217 @@
|
|||||||
|
#include <dht/context.hpp>
|
||||||
#include <dht/messages/findintro.hpp>
|
#include <dht/messages/findintro.hpp>
|
||||||
|
#include <dht/messages/gotintro.hpp>
|
||||||
|
#include <routing/message.hpp>
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
namespace dht
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
struct IntroSetLookupInformer
|
||||||
|
{
|
||||||
|
llarp::Router* router;
|
||||||
|
service::Address target;
|
||||||
|
|
||||||
|
void
|
||||||
|
SendReply(const llarp::routing::IMessage* msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
FindIntroMessage::~FindIntroMessage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindIntroMessage::DecodeKey(llarp_buffer_t k, llarp_buffer_t* val)
|
||||||
|
{
|
||||||
|
bool read = false;
|
||||||
|
|
||||||
|
if(!BEncodeMaybeReadDictEntry("N", N, read, k, val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!BEncodeMaybeReadDictInt("R", R, read, k, val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!BEncodeMaybeReadDictEntry("S", S, read, k, val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!BEncodeMaybeReadDictInt("T", T, read, k, val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, k,
|
||||||
|
val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindIntroMessage::BEncode(llarp_buffer_t* buf) const
|
||||||
|
{
|
||||||
|
if(!bencode_start_dict(buf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// message id
|
||||||
|
if(!BEncodeWriteDictMsgType(buf, "A", "F"))
|
||||||
|
return false;
|
||||||
|
if(N.Empty())
|
||||||
|
{
|
||||||
|
// recursion
|
||||||
|
if(!BEncodeWriteDictInt("R", R, buf))
|
||||||
|
return false;
|
||||||
|
// service address
|
||||||
|
if(!BEncodeWriteDictEntry("S", S, buf))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!BEncodeWriteDictEntry("N", N, buf))
|
||||||
|
return false;
|
||||||
|
// recursion
|
||||||
|
if(!BEncodeWriteDictInt("R", R, buf))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// txid
|
||||||
|
if(!BEncodeWriteDictInt("T", T, buf))
|
||||||
|
return false;
|
||||||
|
// protocol version
|
||||||
|
if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bencode_end(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindIntroMessage::HandleMessage(
|
||||||
|
llarp_dht_context* ctx,
|
||||||
|
std::vector< std::unique_ptr< IMessage > >& replies) const
|
||||||
|
{
|
||||||
|
if(R > 5)
|
||||||
|
{
|
||||||
|
llarp::LogError("R value too big, ", R, "> 5");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto& dht = ctx->impl;
|
||||||
|
if(dht.pendingIntrosetLookups.HasPendingLookupFrom(TXOwner{From, T}))
|
||||||
|
{
|
||||||
|
llarp::LogWarn("duplicate FIM from ", From, " txid=", T);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Key_t peer;
|
||||||
|
std::set< Key_t > exclude = {dht.OurKey(), From};
|
||||||
|
if(N.Empty())
|
||||||
|
{
|
||||||
|
llarp::LogInfo("lookup ", S.ToString());
|
||||||
|
const auto introset = dht.GetIntroSetByServiceAddress(S);
|
||||||
|
if(introset)
|
||||||
|
{
|
||||||
|
service::IntroSet i = *introset;
|
||||||
|
replies.emplace_back(new GotIntroMessage({i}, T));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(R == 0)
|
||||||
|
{
|
||||||
|
// we don't have it
|
||||||
|
Key_t target = S.ToKey();
|
||||||
|
Key_t closer;
|
||||||
|
// find closer peer
|
||||||
|
if(!dht.nodes->FindClosest(target, closer))
|
||||||
|
return false;
|
||||||
|
if(relayed)
|
||||||
|
dht.LookupIntroSetForPath(S, T, pathID, closer);
|
||||||
|
else
|
||||||
|
replies.emplace_back(new GotIntroMessage(From, closer, T));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Key_t us = dht.OurKey();
|
||||||
|
Key_t target = S.ToKey();
|
||||||
|
// we are recursive
|
||||||
|
if(dht.nodes->FindCloseExcluding(target, peer, exclude))
|
||||||
|
{
|
||||||
|
if(relayed)
|
||||||
|
dht.LookupIntroSetForPath(S, T, pathID, peer);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((us ^ target) < (peer ^ target))
|
||||||
|
{
|
||||||
|
// we are not closer than our peer to the target so don't
|
||||||
|
// recurse farther
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, T));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(R > 0)
|
||||||
|
dht.LookupIntroSetRecursive(S, From, T, peer, R - 1);
|
||||||
|
else
|
||||||
|
dht.LookupIntroSetIterative(S, From, T, peer);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no more closer peers
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, T));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(relayed)
|
||||||
|
{
|
||||||
|
// tag lookup
|
||||||
|
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
|
||||||
|
{
|
||||||
|
dht.LookupTagForPath(N, T, pathID, peer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no more closer peers
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, T));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(R == 0)
|
||||||
|
{
|
||||||
|
// base case
|
||||||
|
auto introsets = dht.FindRandomIntroSetsWithTagExcluding(N, 2, {});
|
||||||
|
std::vector< service::IntroSet > reply;
|
||||||
|
for(const auto& introset : introsets)
|
||||||
|
{
|
||||||
|
reply.push_back(introset);
|
||||||
|
}
|
||||||
|
replies.emplace_back(new GotIntroMessage(reply, T));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(R < 5)
|
||||||
|
{
|
||||||
|
// tag lookup
|
||||||
|
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
|
||||||
|
{
|
||||||
|
dht.LookupTagRecursive(N, From, T, peer, R - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// too big R value
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace dht
|
||||||
|
} // namespace llarp
|
||||||
|
@ -1 +1,172 @@
|
|||||||
#include <dht/messages/findrouter.hpp>
|
#include <dht/messages/findrouter.hpp>
|
||||||
|
|
||||||
|
#include <dht/context.hpp>
|
||||||
|
#include <dht/messages/gotrouter.hpp>
|
||||||
|
#include <messages/dht.hpp>
|
||||||
|
#include <router/router.hpp>
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
namespace dht
|
||||||
|
{
|
||||||
|
bool
|
||||||
|
RelayedFindRouterMessage::HandleMessage(
|
||||||
|
llarp_dht_context *ctx,
|
||||||
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
||||||
|
{
|
||||||
|
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->paths.GetByUpstream(K, pathID);
|
||||||
|
if(path)
|
||||||
|
{
|
||||||
|
replies.emplace_back(
|
||||||
|
new GotRouterMessage(k, txid, {dht.router->rc()}, false));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Key_t peer;
|
||||||
|
// check if we know this in our nodedb first
|
||||||
|
RouterContact found;
|
||||||
|
if(dht.router->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))
|
||||||
|
dht.LookupRouterForPath(K, txid, pathID, peer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindRouterMessage::~FindRouterMessage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindRouterMessage::BEncode(llarp_buffer_t *buf) const
|
||||||
|
{
|
||||||
|
if(!bencode_start_dict(buf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// message type
|
||||||
|
if(!bencode_write_bytestring(buf, "A", 1))
|
||||||
|
return false;
|
||||||
|
if(!bencode_write_bytestring(buf, "R", 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// exploritory or not?
|
||||||
|
if(!bencode_write_bytestring(buf, "E", 1))
|
||||||
|
return false;
|
||||||
|
if(!bencode_write_uint64(buf, exploritory ? 1 : 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// iterative or not?
|
||||||
|
if(!bencode_write_bytestring(buf, "I", 1))
|
||||||
|
return false;
|
||||||
|
if(!bencode_write_uint64(buf, iterative ? 1 : 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// key
|
||||||
|
if(!bencode_write_bytestring(buf, "K", 1))
|
||||||
|
return false;
|
||||||
|
if(!bencode_write_bytestring(buf, K.data(), K.size()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// txid
|
||||||
|
if(!bencode_write_bytestring(buf, "T", 1))
|
||||||
|
return false;
|
||||||
|
if(!bencode_write_uint64(buf, txid))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// version
|
||||||
|
if(!bencode_write_bytestring(buf, "V", 1))
|
||||||
|
return false;
|
||||||
|
if(!bencode_write_uint64(buf, version))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bencode_end(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
||||||
|
{
|
||||||
|
llarp_buffer_t strbuf;
|
||||||
|
|
||||||
|
if(llarp_buffer_eq(key, "E"))
|
||||||
|
{
|
||||||
|
uint64_t result;
|
||||||
|
if(!bencode_read_integer(val, &result))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
exploritory = result != 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(llarp_buffer_eq(key, "I"))
|
||||||
|
{
|
||||||
|
uint64_t result;
|
||||||
|
if(!bencode_read_integer(val, &result))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
iterative = result != 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(llarp_buffer_eq(key, "K"))
|
||||||
|
{
|
||||||
|
if(!bencode_read_string(val, &strbuf))
|
||||||
|
return false;
|
||||||
|
if(strbuf.sz != K.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::copy(strbuf.base, strbuf.base + K.SIZE, K.begin());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(llarp_buffer_eq(key, "T"))
|
||||||
|
{
|
||||||
|
return bencode_read_integer(val, &txid);
|
||||||
|
}
|
||||||
|
if(llarp_buffer_eq(key, "V"))
|
||||||
|
{
|
||||||
|
return bencode_read_integer(val, &version);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FindRouterMessage::HandleMessage(
|
||||||
|
llarp_dht_context *ctx,
|
||||||
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
||||||
|
{
|
||||||
|
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}))
|
||||||
|
{
|
||||||
|
llarp::LogWarn("Duplicate FRM from ", From, " txid=", txid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RouterContact found;
|
||||||
|
Key_t k{K};
|
||||||
|
if(exploritory)
|
||||||
|
return dht.HandleExploritoryRouterLookup(From, txid, K, replies);
|
||||||
|
else if(dht.router->nodedb->Get(K, found))
|
||||||
|
{
|
||||||
|
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dht.LookupRouterRelayed(From, txid, k, !iterative, replies);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace dht
|
||||||
|
} // namespace llarp
|
||||||
|
@ -1 +1,125 @@
|
|||||||
#include <dht/messages/gotintro.hpp>
|
#include <dht/messages/gotintro.hpp>
|
||||||
|
|
||||||
|
#include <dht/context.hpp>
|
||||||
|
#include <messages/dht.hpp>
|
||||||
|
#include <router/router.hpp>
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
namespace dht
|
||||||
|
{
|
||||||
|
GotIntroMessage::GotIntroMessage(
|
||||||
|
const std::vector< llarp::service::IntroSet > &results, uint64_t tx)
|
||||||
|
: IMessage({}), I(results), T(tx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GotIntroMessage::~GotIntroMessage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GotIntroMessage::HandleMessage(
|
||||||
|
llarp_dht_context *ctx,
|
||||||
|
__attribute__((unused))
|
||||||
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
||||||
|
{
|
||||||
|
auto &dht = ctx->impl;
|
||||||
|
auto crypto = &dht.router->crypto;
|
||||||
|
|
||||||
|
for(const auto &introset : I)
|
||||||
|
{
|
||||||
|
if(!introset.Verify(crypto, dht.Now()))
|
||||||
|
{
|
||||||
|
llarp::LogWarn(
|
||||||
|
"Invalid introset while handling direct GotIntro "
|
||||||
|
"from ",
|
||||||
|
From);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TXOwner owner(From, T);
|
||||||
|
auto tagLookup = dht.pendingTagLookups.GetPendingLookupFrom(owner);
|
||||||
|
if(tagLookup)
|
||||||
|
{
|
||||||
|
dht.pendingTagLookups.Found(owner, tagLookup->target, I);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto serviceLookup =
|
||||||
|
dht.pendingIntrosetLookups.GetPendingLookupFrom(owner);
|
||||||
|
if(serviceLookup)
|
||||||
|
{
|
||||||
|
if(I.size())
|
||||||
|
{
|
||||||
|
dht.pendingIntrosetLookups.Found(owner, serviceLookup->target, I);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dht.pendingIntrosetLookups.NotFound(owner, K);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
llarp::LogError("no pending TX for GIM from ", From, " txid=", T);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RelayedGotIntroMessage::HandleMessage(
|
||||||
|
llarp_dht_context *ctx,
|
||||||
|
__attribute__((unused))
|
||||||
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
||||||
|
{
|
||||||
|
// TODO: implement me better?
|
||||||
|
auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID);
|
||||||
|
if(pathset)
|
||||||
|
{
|
||||||
|
return pathset->HandleGotIntroMessage(this);
|
||||||
|
}
|
||||||
|
llarp::LogWarn("No path for got intro message pathid=", pathID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GotIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||||
|
{
|
||||||
|
if(llarp_buffer_eq(key, "I"))
|
||||||
|
{
|
||||||
|
return BEncodeReadList(I, buf);
|
||||||
|
}
|
||||||
|
if(llarp_buffer_eq(key, "K"))
|
||||||
|
{
|
||||||
|
if(K) // duplicate key?
|
||||||
|
return false;
|
||||||
|
K.reset(new dht::Key_t());
|
||||||
|
return K->BDecode(buf);
|
||||||
|
}
|
||||||
|
bool read = false;
|
||||||
|
if(!BEncodeMaybeReadDictInt("T", T, read, key, buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeMaybeReadDictInt("V", version, read, key, buf))
|
||||||
|
return false;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GotIntroMessage::BEncode(llarp_buffer_t *buf) const
|
||||||
|
{
|
||||||
|
if(!bencode_start_dict(buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictMsgType(buf, "A", "G"))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictList("I", I, buf))
|
||||||
|
return false;
|
||||||
|
if(K)
|
||||||
|
{
|
||||||
|
if(!BEncodeWriteDictEntry("K", *K.get(), buf))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!BEncodeWriteDictInt("T", T, buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictInt("V", version, buf))
|
||||||
|
return false;
|
||||||
|
return bencode_end(buf);
|
||||||
|
}
|
||||||
|
} // namespace dht
|
||||||
|
} // namespace llarp
|
||||||
|
@ -1 +1,123 @@
|
|||||||
|
#include <dht/context.hpp>
|
||||||
#include <dht/messages/gotrouter.hpp>
|
#include <dht/messages/gotrouter.hpp>
|
||||||
|
|
||||||
|
#include <router/router.hpp>
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
namespace dht
|
||||||
|
{
|
||||||
|
GotRouterMessage::~GotRouterMessage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GotRouterMessage::BEncode(llarp_buffer_t *buf) const
|
||||||
|
{
|
||||||
|
if(!bencode_start_dict(buf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// message type
|
||||||
|
if(!BEncodeWriteDictMsgType(buf, "A", "S"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(K)
|
||||||
|
{
|
||||||
|
if(!BEncodeWriteDictEntry("K", *K.get(), buf))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// near
|
||||||
|
if(N.size())
|
||||||
|
{
|
||||||
|
if(!BEncodeWriteDictList("N", N, buf))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!BEncodeWriteDictList("R", R, buf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// txid
|
||||||
|
if(!BEncodeWriteDictInt("T", txid, buf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// version
|
||||||
|
if(!BEncodeWriteDictInt("V", version, buf))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bencode_end(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GotRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
||||||
|
{
|
||||||
|
if(llarp_buffer_eq(key, "K"))
|
||||||
|
{
|
||||||
|
if(K) // duplicate key?
|
||||||
|
return false;
|
||||||
|
K.reset(new dht::Key_t());
|
||||||
|
return K->BDecode(val);
|
||||||
|
}
|
||||||
|
if(llarp_buffer_eq(key, "N"))
|
||||||
|
{
|
||||||
|
return BEncodeReadList(N, val);
|
||||||
|
}
|
||||||
|
if(llarp_buffer_eq(key, "R"))
|
||||||
|
{
|
||||||
|
return BEncodeReadList(R, val);
|
||||||
|
}
|
||||||
|
if(llarp_buffer_eq(key, "T"))
|
||||||
|
{
|
||||||
|
return bencode_read_integer(val, &txid);
|
||||||
|
}
|
||||||
|
bool read = false;
|
||||||
|
if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, key,
|
||||||
|
val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GotRouterMessage::HandleMessage(
|
||||||
|
llarp_dht_context *ctx,
|
||||||
|
__attribute__((unused))
|
||||||
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
||||||
|
{
|
||||||
|
auto &dht = ctx->impl;
|
||||||
|
if(relayed)
|
||||||
|
{
|
||||||
|
auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID);
|
||||||
|
return pathset && pathset->HandleGotRouterMessage(this);
|
||||||
|
}
|
||||||
|
// not relayed
|
||||||
|
TXOwner owner(From, txid);
|
||||||
|
|
||||||
|
if(dht.pendingExploreLookups.HasPendingLookupFrom(owner))
|
||||||
|
{
|
||||||
|
if(N.size() == 0)
|
||||||
|
dht.pendingExploreLookups.NotFound(owner, K);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dht.pendingExploreLookups.Found(owner, From.as_array(), N);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// not explore lookup
|
||||||
|
|
||||||
|
if(!dht.pendingRouterLookups.HasPendingLookupFrom(owner))
|
||||||
|
{
|
||||||
|
llarp::LogWarn("Unwarrented GRM from ", From, " txid=", txid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// no pending lookup
|
||||||
|
|
||||||
|
llarp::LogInfo("DHT no pending lookup");
|
||||||
|
if(R.size() == 1)
|
||||||
|
dht.pendingRouterLookups.Found(owner, R[0].pubkey, {R[0]});
|
||||||
|
else
|
||||||
|
dht.pendingRouterLookups.NotFound(owner, K);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace dht
|
||||||
|
} // namespace llarp
|
||||||
|
@ -1 +1,121 @@
|
|||||||
#include <dht/messages/pubintro.hpp>
|
#include <dht/messages/pubintro.hpp>
|
||||||
|
|
||||||
|
#include <dht/context.hpp>
|
||||||
|
#include <dht/messages/gotintro.hpp>
|
||||||
|
#include <messages/dht.hpp>
|
||||||
|
#include <messages/dht_immediate.hpp>
|
||||||
|
#include <router/router.hpp>
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
namespace dht
|
||||||
|
{
|
||||||
|
PublishIntroMessage::~PublishIntroMessage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PublishIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
||||||
|
{
|
||||||
|
bool read = false;
|
||||||
|
if(llarp_buffer_eq(key, "E"))
|
||||||
|
{
|
||||||
|
return BEncodeReadList(E, val);
|
||||||
|
}
|
||||||
|
if(!BEncodeMaybeReadDictEntry("I", I, read, key, val))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeMaybeReadDictInt("R", R, read, key, val))
|
||||||
|
return false;
|
||||||
|
if(llarp_buffer_eq(key, "S"))
|
||||||
|
{
|
||||||
|
read = true;
|
||||||
|
hasS = true;
|
||||||
|
if(!bencode_read_integer(val, &S))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!BEncodeMaybeReadDictInt("T", txID, read, key, val))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeMaybeReadDictInt("V", version, read, key, val))
|
||||||
|
return false;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PublishIntroMessage::HandleMessage(
|
||||||
|
llarp_dht_context *ctx,
|
||||||
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
llarp::LogWarn("invalid introset: ", I);
|
||||||
|
// don't propogate or store
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, txID));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(I.W && !I.W->IsValid(dht.router->crypto.shorthash, now))
|
||||||
|
{
|
||||||
|
llarp::LogWarn("proof of work not good enough for IntroSet");
|
||||||
|
// don't propogate or store
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, txID));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
llarp::dht::Key_t addr;
|
||||||
|
if(!I.A.CalculateAddress(addr.as_array()))
|
||||||
|
{
|
||||||
|
llarp::LogWarn(
|
||||||
|
"failed to calculate hidden service address for PubIntro message");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
now += llarp::service::MAX_INTROSET_TIME_DELTA;
|
||||||
|
if(I.IsExpired(now))
|
||||||
|
{
|
||||||
|
// don't propogate or store
|
||||||
|
replies.emplace_back(new GotIntroMessage({}, txID));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
dht.services->PutNode(I);
|
||||||
|
replies.emplace_back(new GotIntroMessage({I}, txID));
|
||||||
|
Key_t peer;
|
||||||
|
std::set< Key_t > exclude;
|
||||||
|
for(const auto &e : E)
|
||||||
|
exclude.insert(e);
|
||||||
|
exclude.insert(From);
|
||||||
|
exclude.insert(dht.OurKey());
|
||||||
|
if(S && dht.nodes->FindCloseExcluding(addr, peer, exclude))
|
||||||
|
{
|
||||||
|
dht.PropagateIntroSetTo(From, txID, I, peer, S - 1, exclude);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PublishIntroMessage::BEncode(llarp_buffer_t *buf) const
|
||||||
|
{
|
||||||
|
if(!bencode_start_dict(buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictMsgType(buf, "A", "I"))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictList("E", E, buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictEntry("I", I, buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictInt("R", R, buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictInt("S", S, buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictInt("T", txID, buf))
|
||||||
|
return false;
|
||||||
|
if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf))
|
||||||
|
return false;
|
||||||
|
return bencode_end(buf);
|
||||||
|
}
|
||||||
|
} // namespace dht
|
||||||
|
} // namespace llarp
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
#include <dht/context.hpp>
|
|
||||||
#include <dht/messages/pubintro.hpp>
|
|
||||||
#include <messages/dht.hpp>
|
|
||||||
#include <messages/dht_immediate.hpp>
|
|
||||||
#include <router/router.hpp>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
namespace dht
|
|
||||||
{
|
|
||||||
PublishIntroMessage::~PublishIntroMessage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
PublishIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
|
||||||
{
|
|
||||||
bool read = false;
|
|
||||||
if(llarp_buffer_eq(key, "E"))
|
|
||||||
{
|
|
||||||
return BEncodeReadList(E, val);
|
|
||||||
}
|
|
||||||
if(!BEncodeMaybeReadDictEntry("I", I, read, key, val))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeMaybeReadDictInt("R", R, read, key, val))
|
|
||||||
return false;
|
|
||||||
if(llarp_buffer_eq(key, "S"))
|
|
||||||
{
|
|
||||||
read = true;
|
|
||||||
hasS = true;
|
|
||||||
if(!bencode_read_integer(val, &S))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!BEncodeMaybeReadDictInt("T", txID, read, key, val))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeMaybeReadDictInt("V", version, read, key, val))
|
|
||||||
return false;
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
PublishIntroMessage::HandleMessage(
|
|
||||||
llarp_dht_context *ctx,
|
|
||||||
std::vector< std::unique_ptr< IMessage > > &replies) const
|
|
||||||
{
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("invalid introset: ", I);
|
|
||||||
// don't propogate or store
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, txID));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(I.W && !I.W->IsValid(dht.router->crypto.shorthash, now))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("proof of work not good enough for IntroSet");
|
|
||||||
// don't propogate or store
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, txID));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
llarp::dht::Key_t addr;
|
|
||||||
if(!I.A.CalculateAddress(addr.as_array()))
|
|
||||||
{
|
|
||||||
llarp::LogWarn(
|
|
||||||
"failed to calculate hidden service address for PubIntro message");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
now += llarp::service::MAX_INTROSET_TIME_DELTA;
|
|
||||||
if(I.IsExpired(now))
|
|
||||||
{
|
|
||||||
// don't propogate or store
|
|
||||||
replies.emplace_back(new GotIntroMessage({}, txID));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
dht.services->PutNode(I);
|
|
||||||
replies.emplace_back(new GotIntroMessage({I}, txID));
|
|
||||||
Key_t peer;
|
|
||||||
std::set< Key_t > exclude;
|
|
||||||
for(const auto &e : E)
|
|
||||||
exclude.insert(e);
|
|
||||||
exclude.insert(From);
|
|
||||||
exclude.insert(dht.OurKey());
|
|
||||||
if(S && dht.nodes->FindCloseExcluding(addr, peer, exclude))
|
|
||||||
{
|
|
||||||
dht.PropagateIntroSetTo(From, txID, I, peer, S - 1, exclude);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
PublishIntroMessage::BEncode(llarp_buffer_t *buf) const
|
|
||||||
{
|
|
||||||
if(!bencode_start_dict(buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictMsgType(buf, "A", "I"))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictList("E", E, buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictEntry("I", I, buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictInt("R", R, buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictInt("S", S, buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictInt("T", txID, buf))
|
|
||||||
return false;
|
|
||||||
if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf))
|
|
||||||
return false;
|
|
||||||
return bencode_end(buf);
|
|
||||||
}
|
|
||||||
} // namespace dht
|
|
||||||
} // namespace llarp
|
|
Loading…
Reference in New Issue