Tidy dht code

pull/236/head
Michael 5 years ago
parent 9f436174d4
commit 7296ebcbe8
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -504,21 +504,15 @@ set(LIB_SRC
llarp/dht/decode.cpp
llarp/dht/dht_immediate.cpp
llarp/dht/dht.cpp
llarp/dht/find_intro.cpp
llarp/dht/find_router.cpp
llarp/dht/got_intro.cpp
llarp/dht/got_router.cpp
llarp/dht/kademlia.cpp
llarp/dht/key.cpp
llarp/dht/message.cpp
llarp/dht/messages/all.cpp
llarp/dht/messages/findintro.cpp
llarp/dht/messages/findrouter.cpp
llarp/dht/messages/gotintro.cpp
llarp/dht/messages/gotrouter.cpp
llarp/dht/messages/pubintro.cpp
llarp/dht/node.cpp
llarp/dht/publish_intro.cpp
llarp/dns.cpp
llarp/dnsc.cpp
llarp/dnsd.cpp

@ -1,6 +1,9 @@
#include <dht/context.hpp>
#include <dht/messages/findrouter.hpp>
#include <dht/messages/gotintro.hpp>
#include <dht/messages/gotrouter.hpp>
#include <dht/messages/pubintro.hpp>
#include <messages/dht.hpp>
#include <messages/dht_immediate.hpp>
#include <router/router.hpp>
@ -270,7 +273,7 @@ namespace llarp
ourKey = us;
nodes = new Bucket< RCNode >(ourKey);
services = new Bucket< ISNode >(ourKey);
llarp::LogDebug("intialize dht with key ", ourKey);
llarp::LogDebug("initialize dht with key ", ourKey);
// start exploring
r->logic->call_later(
@ -452,7 +455,7 @@ namespace llarp
if(I.A != introset.A)
{
llarp::LogWarn(
"publish introset acknoledgement acked a different service");
"publish introset acknowledgement acked a different service");
return false;
}
return true;

@ -1,5 +1,10 @@
#include <dht/context.hpp>
#include <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>
namespace llarp
{

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

@ -1,4 +1,5 @@
#include <exit/session.hpp>
#include <path/path.hpp>
#include <router/router.hpp>
@ -85,7 +86,7 @@ namespace llarp
if(p->SendExitRequest(&obtain, router))
llarp::LogInfo("asking ", m_ExitRouter, " for exit");
else
llarp::LogError("faild to send exit request");
llarp::LogError("failed to send exit request");
}
bool

@ -4,6 +4,8 @@
#include <path/pathset.hpp>
#include <atomic>
struct llarp_dht_context;
namespace llarp
{
namespace path
@ -25,7 +27,7 @@ namespace llarp
}
llarp::Router* router;
struct llarp_dht_context* dht;
llarp_dht_context* dht;
llarp::SecretKey enckey;
size_t numHops;
llarp_time_t lastBuild = 0;
@ -35,7 +37,7 @@ namespace llarp
std::atomic< uint8_t > keygens;
/// construct
Builder(llarp::Router* p_router, struct llarp_dht_context* p_dht,
Builder(llarp::Router* p_router, llarp_dht_context* p_dht,
size_t numPaths, size_t numHops);
virtual ~Builder();

@ -1,7 +1,6 @@
#ifndef LLARP_PATHSET_HPP
#define LLARP_PATHSET_HPP
#include <dht/messages/all.hpp>
#include <path/path_types.hpp>
#include <router_id.hpp>
#include <routing/message.hpp>
@ -18,10 +17,13 @@ struct llarp_nodedb;
namespace llarp
{
struct RouterContact;
namespace dht
{
struct GotIntroMessage;
}
struct GotRouterMessage;
} // namespace dht
namespace path
{
@ -34,12 +36,12 @@ namespace llarp
ePathExpired
};
/// the role of this path can fuffill
/// the role of this path can fulfill
using PathRole = int;
/// capable of any role
constexpr PathRole ePathRoleAny = 0;
/// outbound hs traffic capabale
/// outbound hs traffic capable
constexpr PathRole ePathRoleOutboundHS = (1 << 0);
/// inbound hs traffic capable
constexpr PathRole ePathRoleInboundHS = (1 << 1);

@ -1,6 +1,10 @@
#include <service/endpoint.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>
#include <messages/dht.hpp>
#include <router/router.hpp>
#include <service/protocol.hpp>
@ -1688,7 +1692,7 @@ namespace llarp
if(markedBad)
return false;
bool should = path::Builder::ShouldBuildMore(now);
// determinte newest intro
// determine newest intro
Introduction intro;
if(!GetNewestIntro(intro))
return should;

Loading…
Cancel
Save