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/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/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/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 <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/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