refactor single char variables in DHT (mostly)

pull/1069/head
Jeff Becker 4 years ago
parent ae8bb3751b
commit 2c0dc12f39
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -435,13 +435,29 @@ namespace llarp
new GotRouterMessage(requester, txid, {router->rc()}, false)); new GotRouterMessage(requester, txid, {router->rc()}, false));
return; return;
} }
if(not GetRouter()->ConnectionToRouterAllowed(target.as_array()))
{
// explicitly not allowed
replies.emplace_back(new GotRouterMessage(requester, txid, {}, false));
return;
}
const auto rc = GetRouter()->nodedb()->FindClosestTo(target); const auto rc = GetRouter()->nodedb()->FindClosestTo(target);
Key_t next(rc.pubkey); const Key_t next(rc.pubkey);
{ {
if(next == target) if(next == target)
{ {
// we know it, ask them directly for their own RC to keep it updated // we know the target
LookupRouterRecursive(target.as_array(), requester, txid, next); if(rc.ExpiresSoon(llarp::time_now_ms()))
{
// ask target for their rc to keep it updated
LookupRouterRecursive(target.as_array(), requester, txid, next);
}
else
{
// send reply with rc we know of
replies.emplace_back(
new GotRouterMessage(requester, txid, {rc}, false));
}
} }
else if(recursive) // are we doing a recursive lookup? else if(recursive) // are we doing a recursive lookup?
{ {

@ -16,16 +16,16 @@ namespace llarp
{ {
bool read = false; bool read = false;
if(!BEncodeMaybeReadDictEntry("N", N, read, k, val)) if(!BEncodeMaybeReadDictEntry("N", tagName, read, k, val))
return false; return false;
if(!BEncodeMaybeReadDictInt("R", R, read, k, val)) if(!BEncodeMaybeReadDictInt("R", recursionDepth, read, k, val))
return false; return false;
if(!BEncodeMaybeReadDictEntry("S", S, read, k, val)) if(!BEncodeMaybeReadDictEntry("S", serviceAddress, read, k, val))
return false; return false;
if(!BEncodeMaybeReadDictInt("T", T, read, k, val)) if(!BEncodeMaybeReadDictInt("T", txID, read, k, val))
return false; return false;
if(!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, k, if(!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, k,
@ -44,25 +44,25 @@ namespace llarp
// message id // message id
if(!BEncodeWriteDictMsgType(buf, "A", "F")) if(!BEncodeWriteDictMsgType(buf, "A", "F"))
return false; return false;
if(N.Empty()) if(tagName.Empty())
{ {
// recursion // recursion
if(!BEncodeWriteDictInt("R", R, buf)) if(!BEncodeWriteDictInt("R", recursionDepth, buf))
return false; return false;
// service address // service address
if(!BEncodeWriteDictEntry("S", S, buf)) if(!BEncodeWriteDictEntry("S", serviceAddress, buf))
return false; return false;
} }
else else
{ {
if(!BEncodeWriteDictEntry("N", N, buf)) if(!BEncodeWriteDictEntry("N", tagName, buf))
return false; return false;
// recursion // recursion
if(!BEncodeWriteDictInt("R", R, buf)) if(!BEncodeWriteDictInt("R", recursionDepth, buf))
return false; return false;
} }
// txid // txid
if(!BEncodeWriteDictInt("T", T, buf)) if(!BEncodeWriteDictInt("T", txID, buf))
return false; return false;
// protocol version // protocol version
if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf)) if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf))
@ -75,74 +75,73 @@ namespace llarp
FindIntroMessage::HandleMessage( FindIntroMessage::HandleMessage(
llarp_dht_context* ctx, std::vector< IMessage::Ptr_t >& replies) const llarp_dht_context* ctx, std::vector< IMessage::Ptr_t >& replies) const
{ {
if(R > 5) static constexpr uint64_t MaxRecursionAllowed = 8;
if(recursionDepth > MaxRecursionAllowed)
{ {
llarp::LogError("R value too big, ", R, "> 5"); llarp::LogError("recursion depth big, ", recursionDepth, "> ",
MaxRecursionAllowed);
return false; return false;
} }
auto& dht = *ctx->impl; auto& dht = *ctx->impl;
if(dht.pendingIntrosetLookups().HasPendingLookupFrom(TXOwner{From, T})) if(dht.pendingIntrosetLookups().HasPendingLookupFrom(TXOwner{From, txID}))
{ {
llarp::LogWarn("duplicate FIM from ", From, " txid=", T); llarp::LogWarn("duplicate FIM from ", From, " txid=", txID);
return false; return false;
} }
Key_t peer; Key_t peer;
std::set< Key_t > exclude = {dht.OurKey(), From}; std::set< Key_t > exclude = {dht.OurKey(), From};
if(N.Empty()) if(tagName.Empty())
{ {
llarp::LogInfo("lookup ", S.ToString()); if(serviceAddress.IsZero())
const auto introset = dht.GetIntroSetByServiceAddress(S); {
// we dont got it
replies.emplace_back(new GotIntroMessage({}, txID));
}
llarp::LogInfo("lookup ", serviceAddress.ToString());
const auto introset = dht.GetIntroSetByServiceAddress(serviceAddress);
if(introset) if(introset)
{ {
service::IntroSet i = *introset; replies.emplace_back(new GotIntroMessage({*introset}, txID));
replies.emplace_back(new GotIntroMessage({i}, T));
return true; return true;
} }
if(R == 0) const Key_t target = serviceAddress.ToKey();
const Key_t us = dht.OurKey();
if(recursionDepth == 0)
{ {
// we don't have it // we don't have it
Key_t target = S.ToKey();
Key_t closer; Key_t closer;
// find closer peer // find closer peer
if(!dht.Nodes()->FindClosest(target, closer)) if(!dht.Nodes()->FindClosest(target, closer))
return false; return false;
replies.emplace_back(new GotIntroMessage(From, closer, T)); replies.emplace_back(new GotIntroMessage(From, closer, txID));
return true; return true;
} }
Key_t us = dht.OurKey();
Key_t target = S.ToKey();
// we are recursive // we are recursive
const auto rc = dht.GetRouter()->nodedb()->FindClosestTo(target); const auto rc = dht.GetRouter()->nodedb()->FindClosestTo(target);
peer = Key_t(rc.pubkey);
if((us ^ target) < (peer ^ target) || peer == us)
{ {
peer = Key_t(rc.pubkey); // we are not closer than our peer to the target so don't
if(peer == us) // recurse farther
{ replies.emplace_back(new GotIntroMessage({}, txID));
replies.emplace_back(new GotIntroMessage({}, T));
return true;
}
if(relayed)
dht.LookupIntroSetForPath(S, T, pathID, peer, R - 1);
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;
}
if(R > 0)
dht.LookupIntroSetRecursive(S, From, T, peer, R - 1);
else
dht.LookupIntroSetIterative(S, From, T, peer);
}
return true; return true;
} }
if(relayed)
// no more closer peers {
replies.emplace_back(new GotIntroMessage({}, T)); dht.LookupIntroSetForPath(serviceAddress, txID, pathID, peer,
recursionDepth - 1);
}
else
{
dht.LookupIntroSetRecursive(serviceAddress, From, txID, peer,
recursionDepth - 1);
}
return true; return true;
} }
@ -151,45 +150,47 @@ namespace llarp
// tag lookup // tag lookup
if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude)) if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude))
{ {
dht.LookupTagForPath(N, T, pathID, peer); dht.LookupTagForPath(tagName, txID, pathID, peer);
} }
else else
{ {
// no more closer peers // no more closer peers
replies.emplace_back(new GotIntroMessage({}, T)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
} }
} }
else else
{ {
if(R == 0) if(recursionDepth == 0)
{ {
// base case // base case
auto introsets = dht.FindRandomIntroSetsWithTagExcluding(N, 2, {}); auto introsets =
dht.FindRandomIntroSetsWithTagExcluding(tagName, 2, {});
std::vector< service::IntroSet > reply; std::vector< service::IntroSet > reply;
for(const auto& introset : introsets) for(const auto& introset : introsets)
{ {
reply.push_back(introset); reply.emplace_back(introset);
} }
replies.emplace_back(new GotIntroMessage(reply, T)); replies.emplace_back(new GotIntroMessage(reply, txID));
return true; return true;
} }
if(R < 5) if(recursionDepth < MaxRecursionAllowed)
{ {
// tag lookup // tag lookup
if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude)) if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude))
{ {
dht.LookupTagRecursive(N, From, T, peer, R - 1); dht.LookupTagRecursive(tagName, From, txID, peer,
recursionDepth - 1);
} }
else else
{ {
replies.emplace_back(new GotIntroMessage({}, T)); replies.emplace_back(new GotIntroMessage({}, txID));
} }
} }
else else
{ {
// too big R value // too big recursion depth
replies.emplace_back(new GotIntroMessage({}, T)); replies.emplace_back(new GotIntroMessage({}, txID));
} }
} }

@ -12,11 +12,11 @@ namespace llarp
{ {
struct FindIntroMessage final : public IMessage struct FindIntroMessage final : public IMessage
{ {
uint64_t R = 0; uint64_t recursionDepth = 0;
llarp::service::Address S; llarp::service::Address serviceAddress;
llarp::service::Tag N; llarp::service::Tag tagName;
uint64_t T = 0; uint64_t txID = 0;
bool relayed = false; bool relayed = false;
FindIntroMessage(const Key_t& from, bool relay) : IMessage(from) FindIntroMessage(const Key_t& from, bool relay) : IMessage(from)
{ {
@ -25,24 +25,23 @@ namespace llarp
FindIntroMessage(const llarp::service::Tag& tag, uint64_t txid, FindIntroMessage(const llarp::service::Tag& tag, uint64_t txid,
bool iterate = true) bool iterate = true)
: IMessage({}), N(tag), T(txid) : IMessage({}), tagName(tag), txID(txid)
{ {
S.Zero(); serviceAddress.Zero();
if(iterate) if(iterate)
R = 0; recursionDepth = 0;
else else
R = 1; recursionDepth = 1;
} }
FindIntroMessage(uint64_t txid, const llarp::service::Address& addr, FindIntroMessage(uint64_t txid, const llarp::service::Address& addr,
bool iterate = false) uint64_t maxRecursionDepth)
: IMessage({}), S(addr), T(txid) : IMessage({})
, recursionDepth(maxRecursionDepth)
, serviceAddress(addr)
, txID(txid)
{ {
N.Zero(); tagName.Zero();
if(iterate)
R = 0;
else
R = 3;
} }
~FindIntroMessage() override; ~FindIntroMessage() override;

@ -18,11 +18,12 @@ namespace llarp
{ {
auto &dht = *ctx->impl; auto &dht = *ctx->impl;
/// lookup for us, send an immeidate reply /// lookup for us, send an immeidate reply
Key_t us = dht.OurKey(); const Key_t us = dht.OurKey();
Key_t k{K}; const Key_t k{targetKey};
if(K == us) if(k == us)
{ {
auto path = dht.GetRouter()->pathContext().GetByUpstream(K, pathID); auto path =
dht.GetRouter()->pathContext().GetByUpstream(targetKey, pathID);
if(path) if(path)
{ {
replies.emplace_back( replies.emplace_back(
@ -34,26 +35,22 @@ namespace llarp
Key_t peer; Key_t peer;
// check if we know this in our nodedb first // check if we know this in our nodedb first
RouterContact found; if(not dht.GetRouter()->ConnectionToRouterAllowed(targetKey))
if(!dht.GetRouter()->ConnectionToRouterAllowed(K))
{ {
// explicitly disallowed by network // explicitly disallowed by network
replies.emplace_back(new GotRouterMessage(k, txid, {}, false)); replies.emplace_back(new GotRouterMessage(k, txid, {}, false));
return true; return true;
} }
if(dht.GetRouter()->nodedb()->Get(K, found)) // check netdb
const auto rc = dht.GetRouter()->nodedb()->FindClosestTo(k);
if(rc.pubkey == targetKey)
{ {
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false)); replies.emplace_back(new GotRouterMessage(k, txid, {rc}, false));
return true;
}
if((!dht.Nodes()->FindClosest(k, peer)) || peer == us)
{
// can't find any peers closer
replies.emplace_back(new GotRouterMessage(k, txid, {}, false));
return true; return true;
} }
peer = Key_t(rc.pubkey);
// lookup if we don't have it in our nodedb // lookup if we don't have it in our nodedb
dht.LookupRouterForPath(K, txid, pathID, peer); dht.LookupRouterForPath(targetKey, txid, pathID, peer);
return true; return true;
} }
@ -86,7 +83,7 @@ namespace llarp
// key // key
if(!bencode_write_bytestring(buf, "K", 1)) if(!bencode_write_bytestring(buf, "K", 1))
return false; return false;
if(!bencode_write_bytestring(buf, K.data(), K.size())) if(!bencode_write_bytestring(buf, targetKey.data(), targetKey.size()))
return false; return false;
// txid // txid
@ -132,10 +129,10 @@ namespace llarp
{ {
if(!bencode_read_string(val, &strbuf)) if(!bencode_read_string(val, &strbuf))
return false; return false;
if(strbuf.sz != K.size()) if(strbuf.sz != targetKey.size())
return false; return false;
std::copy(strbuf.base, strbuf.base + K.SIZE, K.begin()); std::copy(strbuf.base, strbuf.base + targetKey.SIZE, targetKey.begin());
return true; return true;
} }
if(key == "T") if(key == "T")
@ -167,26 +164,15 @@ namespace llarp
return false; return false;
} }
RouterContact found; RouterContact found;
if(K.IsZero()) if(targetKey.IsZero())
{ {
llarp::LogError("invalid FRM from ", From, "K is zero"); llarp::LogError("invalid FRM from ", From, " key is zero");
return false; return false;
} }
const Key_t k(K); const Key_t k(targetKey);
if(exploritory) if(exploritory)
return dht.HandleExploritoryRouterLookup(From, txid, K, replies); return dht.HandleExploritoryRouterLookup(From, txid, targetKey,
if(!dht.GetRouter()->ConnectionToRouterAllowed(K)) replies);
{
// explicitly disallowed by network
replies.emplace_back(new GotRouterMessage(k, txid, {}, false));
return true;
}
if(dht.GetRCFromNodeDB(k, found))
{
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;
}
dht.LookupRouterRelayed(From, txid, k, !iterative, replies); dht.LookupRouterRelayed(From, txid, k, !iterative, replies);
return true; return true;
} }

@ -15,14 +15,14 @@ namespace llarp
// find by routerid // find by routerid
FindRouterMessage(uint64_t id, const RouterID& target) FindRouterMessage(uint64_t id, const RouterID& target)
: IMessage({}), K(target), txid(id) : IMessage({}), targetKey(target), txid(id)
{ {
} }
// exploritory // exploritory
FindRouterMessage(uint64_t id) : IMessage({}), exploritory(true), txid(id) FindRouterMessage(uint64_t id) : IMessage({}), exploritory(true), txid(id)
{ {
K.Randomize(); targetKey.Randomize();
} }
~FindRouterMessage() override; ~FindRouterMessage() override;
@ -38,7 +38,7 @@ namespace llarp
llarp_dht_context* ctx, llarp_dht_context* ctx,
std::vector< std::unique_ptr< IMessage > >& replies) const override; std::vector< std::unique_ptr< IMessage > >& replies) const override;
RouterID K; RouterID targetKey;
bool iterative = false; bool iterative = false;
bool exploritory = false; bool exploritory = false;
uint64_t txid = 0; uint64_t txid = 0;

@ -13,7 +13,7 @@ namespace llarp
{ {
GotIntroMessage::GotIntroMessage(std::vector< service::IntroSet > results, GotIntroMessage::GotIntroMessage(std::vector< service::IntroSet > results,
uint64_t tx) uint64_t tx)
: IMessage({}), I(std::move(results)), T(tx) : IMessage({}), found(std::move(results)), txid(tx)
{ {
} }
@ -25,7 +25,7 @@ namespace llarp
{ {
auto &dht = *ctx->impl; auto &dht = *ctx->impl;
for(const auto &introset : I) for(const auto &introset : found)
{ {
if(!introset.Verify(dht.Now())) if(!introset.Verify(dht.Now()))
{ {
@ -36,28 +36,29 @@ namespace llarp
return false; return false;
} }
} }
TXOwner owner(From, T); TXOwner owner(From, txid);
auto tagLookup = dht.pendingTagLookups().GetPendingLookupFrom(owner); auto tagLookup = dht.pendingTagLookups().GetPendingLookupFrom(owner);
if(tagLookup) if(tagLookup)
{ {
dht.pendingTagLookups().Found(owner, tagLookup->target, I); dht.pendingTagLookups().Found(owner, tagLookup->target, found);
return true; return true;
} }
auto serviceLookup = auto serviceLookup =
dht.pendingIntrosetLookups().GetPendingLookupFrom(owner); dht.pendingIntrosetLookups().GetPendingLookupFrom(owner);
if(serviceLookup) if(serviceLookup)
{ {
if(I.size()) if(not found.empty())
{ {
dht.pendingIntrosetLookups().Found(owner, serviceLookup->target, I); dht.pendingIntrosetLookups().Found(owner, serviceLookup->target,
found);
} }
else else
{ {
dht.pendingIntrosetLookups().NotFound(owner, K); dht.pendingIntrosetLookups().NotFound(owner, nullptr);
} }
return true; return true;
} }
LogError("no pending TX for GIM from ", From, " txid=", T); LogError("no pending TX for GIM from ", From, " txid=", txid);
return false; return false;
} }
@ -84,17 +85,20 @@ namespace llarp
{ {
if(key == "I") if(key == "I")
{ {
return BEncodeReadList(I, buf); return BEncodeReadList(found, buf);
} }
if(key == "K") if(key == "K")
{ {
if(K) // duplicate key? if(closer.has_value()) // duplicate key?
return false; return false;
K = std::make_unique< dht::Key_t >(); dht::Key_t K;
return K->BDecode(buf); if(not K.BDecode(buf))
return false;
closer = K;
return true;
} }
bool read = false; bool read = false;
if(!BEncodeMaybeReadDictInt("T", T, read, key, buf)) if(!BEncodeMaybeReadDictInt("T", txid, read, key, buf))
return false; return false;
if(!BEncodeMaybeReadDictInt("V", version, read, key, buf)) if(!BEncodeMaybeReadDictInt("V", version, read, key, buf))
return false; return false;
@ -108,14 +112,14 @@ namespace llarp
return false; return false;
if(!BEncodeWriteDictMsgType(buf, "A", "G")) if(!BEncodeWriteDictMsgType(buf, "A", "G"))
return false; return false;
if(!BEncodeWriteDictList("I", I, buf)) if(!BEncodeWriteDictList("I", found, buf))
return false; return false;
if(K) if(closer.has_value())
{ {
if(!BEncodeWriteDictEntry("K", *K.get(), buf)) if(!BEncodeWriteDictEntry("K", closer.value(), buf))
return false; return false;
} }
if(!BEncodeWriteDictInt("T", T, buf)) if(!BEncodeWriteDictInt("T", txid, buf))
return false; return false;
if(!BEncodeWriteDictInt("V", version, buf)) if(!BEncodeWriteDictInt("V", version, buf))
return false; return false;

@ -6,6 +6,7 @@
#include <util/copy_or_nullptr.hpp> #include <util/copy_or_nullptr.hpp>
#include <vector> #include <vector>
#include <absl/types/optional.h>
namespace llarp namespace llarp
{ {
@ -15,11 +16,11 @@ namespace llarp
struct GotIntroMessage : public IMessage struct GotIntroMessage : public IMessage
{ {
/// the found introsets /// the found introsets
std::vector< service::IntroSet > I; std::vector< service::IntroSet > found;
/// txid /// txid
uint64_t T = 0; uint64_t txid = 0;
/// the key of a router closer in keyspace if iterative lookup /// the key of a router closer in keyspace if iterative lookup
std::unique_ptr< Key_t > K; absl::optional< Key_t > closer;
GotIntroMessage(const Key_t& from) : IMessage(from) GotIntroMessage(const Key_t& from) : IMessage(from)
{ {
@ -27,16 +28,16 @@ namespace llarp
GotIntroMessage(const GotIntroMessage& other) GotIntroMessage(const GotIntroMessage& other)
: IMessage(other.From) : IMessage(other.From)
, I(other.I) , found(other.found)
, T(other.T) , txid(other.txid)
, K(copy_or_nullptr(other.K)) , closer(other.closer)
{ {
version = other.version; version = other.version;
} }
/// for iterative reply /// for iterative reply
GotIntroMessage(const Key_t& from, const Key_t& closer, uint64_t txid) GotIntroMessage(const Key_t& from, const Key_t& _closer, uint64_t _txid)
: IMessage(from), T(txid), K(new Key_t(closer)) : IMessage(from), txid(_txid), closer(_closer)
{ {
} }

@ -15,35 +15,35 @@ namespace llarp
bool bool
GotRouterMessage::BEncode(llarp_buffer_t *buf) const GotRouterMessage::BEncode(llarp_buffer_t *buf) const
{ {
if(!bencode_start_dict(buf)) if(not bencode_start_dict(buf))
return false; return false;
// message type // message type
if(!BEncodeWriteDictMsgType(buf, "A", "S")) if(not BEncodeWriteDictMsgType(buf, "A", "S"))
return false; return false;
if(K) if(closerTarget)
{ {
if(!BEncodeWriteDictEntry("K", *K.get(), buf)) if(not BEncodeWriteDictEntry("K", *closerTarget, buf))
return false; return false;
} }
// near // near
if(N.size()) if(not nearKeys.empty())
{ {
if(!BEncodeWriteDictList("N", N, buf)) if(not BEncodeWriteDictList("N", nearKeys, buf))
return false; return false;
} }
if(!BEncodeWriteDictList("R", R, buf)) if(not BEncodeWriteDictList("R", foundRCs, buf))
return false; return false;
// txid // txid
if(!BEncodeWriteDictInt("T", txid, buf)) if(not BEncodeWriteDictInt("T", txid, buf))
return false; return false;
// version // version
if(!BEncodeWriteDictInt("V", version, buf)) if(not BEncodeWriteDictInt("V", version, buf))
return false; return false;
return bencode_end(buf); return bencode_end(buf);
@ -54,18 +54,18 @@ namespace llarp
{ {
if(key == "K") if(key == "K")
{ {
if(K) // duplicate key? if(closerTarget) // duplicate key?
return false; return false;
K = std::make_unique< dht::Key_t >(); closerTarget = std::make_unique< dht::Key_t >();
return K->BDecode(val); return closerTarget->BDecode(val);
} }
if(key == "N") if(key == "N")
{ {
return BEncodeReadList(N, val); return BEncodeReadList(nearKeys, val);
} }
if(key == "R") if(key == "R")
{ {
return BEncodeReadList(R, val); return BEncodeReadList(foundRCs, val);
} }
if(key == "T") if(key == "T")
{ {
@ -98,29 +98,29 @@ namespace llarp
if(dht.pendingExploreLookups().HasPendingLookupFrom(owner)) if(dht.pendingExploreLookups().HasPendingLookupFrom(owner))
{ {
LogDebug("got ", N.size(), " results in GRM for explore"); LogDebug("got ", nearKeys.size(), " results in GRM for explore");
if(N.size() == 0) if(nearKeys.empty())
dht.pendingExploreLookups().NotFound(owner, K); dht.pendingExploreLookups().NotFound(owner, closerTarget);
else else
{ {
dht.pendingExploreLookups().Found(owner, From.as_array(), N); dht.pendingExploreLookups().Found(owner, From.as_array(), nearKeys);
} }
return true; return true;
} }
// not explore lookup // not explore lookup
if(dht.pendingRouterLookups().HasPendingLookupFrom(owner)) if(dht.pendingRouterLookups().HasPendingLookupFrom(owner))
{ {
LogDebug("got ", R.size(), " results in GRM for lookup"); LogDebug("got ", foundRCs.size(), " results in GRM for lookup");
if(R.size() == 0) if(foundRCs.empty())
dht.pendingRouterLookups().NotFound(owner, K); dht.pendingRouterLookups().NotFound(owner, closerTarget);
else if(R[0].pubkey.IsZero()) else if(foundRCs[0].pubkey.IsZero())
return false; return false;
else else
dht.pendingRouterLookups().Found(owner, R[0].pubkey, R); dht.pendingRouterLookups().Found(owner, foundRCs[0].pubkey, foundRCs);
return true; return true;
} }
// store if valid // store if valid
for(const auto &rc : R) for(const auto &rc : foundRCs)
{ {
if(not dht.GetRouter()->rcLookupHandler().CheckRC(rc)) if(not dht.GetRouter()->rcLookupHandler().CheckRC(rc))
return false; return false;

@ -20,27 +20,33 @@ namespace llarp
GotRouterMessage(const Key_t& from, uint64_t id, GotRouterMessage(const Key_t& from, uint64_t id,
const std::vector< RouterContact >& results, const std::vector< RouterContact >& results,
bool tunneled) bool tunneled)
: IMessage(from), R(results), txid(id), relayed(tunneled) : IMessage(from), foundRCs(results), txid(id), relayed(tunneled)
{ {
} }
GotRouterMessage(const Key_t& from, const Key_t& closer, uint64_t id, GotRouterMessage(const Key_t& from, const Key_t& closer, uint64_t id,
bool tunneled) bool tunneled)
: IMessage(from), K(new Key_t(closer)), txid(id), relayed(tunneled) : IMessage(from)
, closerTarget(new Key_t(closer))
, txid(id)
, relayed(tunneled)
{ {
} }
GotRouterMessage(uint64_t id, std::vector< RouterID > _near, GotRouterMessage(uint64_t id, std::vector< RouterID > _near,
bool tunneled) bool tunneled)
: IMessage({}), N(std::move(_near)), txid(id), relayed(tunneled) : IMessage({})
, nearKeys(std::move(_near))
, txid(id)
, relayed(tunneled)
{ {
} }
GotRouterMessage(const GotRouterMessage& other) GotRouterMessage(const GotRouterMessage& other)
: IMessage(other.From) : IMessage(other.From)
, R(other.R) , foundRCs(other.foundRCs)
, N(other.N) , nearKeys(other.nearKeys)
, K(copy_or_nullptr(other.K)) , closerTarget(copy_or_nullptr(other.closerTarget))
, txid(other.txid) , txid(other.txid)
, relayed(other.relayed) , relayed(other.relayed)
{ {
@ -60,9 +66,9 @@ namespace llarp
llarp_dht_context* ctx, llarp_dht_context* ctx,
std::vector< std::unique_ptr< IMessage > >& replies) const override; std::vector< std::unique_ptr< IMessage > >& replies) const override;
std::vector< RouterContact > R; std::vector< RouterContact > foundRCs;
std::vector< RouterID > N; std::vector< RouterID > nearKeys;
std::unique_ptr< Key_t > K; std::unique_ptr< Key_t > closerTarget;
uint64_t txid = 0; uint64_t txid = 0;
bool relayed = false; bool relayed = false;
}; };

@ -10,7 +10,8 @@ namespace llarp
{ {
namespace dht namespace dht
{ {
PublishIntroMessage::~PublishIntroMessage() = default; const uint64_t PublishIntroMessage::MaxPropagationDepth = 5;
PublishIntroMessage::~PublishIntroMessage() = default;
bool bool
PublishIntroMessage::DecodeKey(const llarp_buffer_t &key, PublishIntroMessage::DecodeKey(const llarp_buffer_t &key,
@ -19,19 +20,12 @@ namespace llarp
bool read = false; bool read = false;
if(key == "E") if(key == "E")
{ {
return BEncodeReadList(E, val); return BEncodeReadList(exclude, val);
} }
if(!BEncodeMaybeReadDictEntry("I", I, read, key, val)) if(!BEncodeMaybeReadDictEntry("I", introset, read, key, val))
return false; return false;
if(!BEncodeMaybeReadDictInt("R", R, read, key, val)) if(!BEncodeMaybeReadDictInt("S", depth, read, key, val))
return false; return false;
if(key == "S")
{
read = true;
hasS = true;
if(!bencode_read_integer(val, &S))
return false;
}
if(!BEncodeMaybeReadDictInt("T", txID, read, key, val)) if(!BEncodeMaybeReadDictInt("T", txID, read, key, val))
return false; return false;
if(!BEncodeMaybeReadDictInt("V", version, read, key, val)) if(!BEncodeMaybeReadDictInt("V", version, read, key, val))
@ -45,21 +39,23 @@ namespace llarp
std::vector< std::unique_ptr< IMessage > > &replies) const std::vector< std::unique_ptr< IMessage > > &replies) const
{ {
auto now = ctx->impl->Now(); auto now = ctx->impl->Now();
if(S > 5)
if(depth > MaxPropagationDepth)
{ {
llarp::LogWarn("invalid S value ", S, " > 5"); llarp::LogWarn("invalid propgagation depth value ", depth, " > ",
MaxPropagationDepth);
return false; return false;
} }
auto &dht = *ctx->impl; auto &dht = *ctx->impl;
if(!I.Verify(now)) if(!introset.Verify(now))
{ {
llarp::LogWarn("invalid introset: ", I); llarp::LogWarn("invalid introset: ", introset);
// don't propogate or store // don't propogate or store
replies.emplace_back(new GotIntroMessage({}, txID)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
} }
if(I.W && !I.W->IsValid(now)) if(introset.W && !introset.W->IsValid(now))
{ {
llarp::LogWarn("proof of work not good enough for IntroSet"); llarp::LogWarn("proof of work not good enough for IntroSet");
// don't propogate or store // don't propogate or store
@ -67,7 +63,7 @@ namespace llarp
return true; return true;
} }
llarp::dht::Key_t addr; llarp::dht::Key_t addr;
if(!I.A.CalculateAddress(addr.as_array())) if(not introset.A.CalculateAddress(addr.as_array()))
{ {
llarp::LogWarn( llarp::LogWarn(
"failed to calculate hidden service address for PubIntro message"); "failed to calculate hidden service address for PubIntro message");
@ -75,23 +71,25 @@ namespace llarp
} }
now += llarp::service::MAX_INTROSET_TIME_DELTA; now += llarp::service::MAX_INTROSET_TIME_DELTA;
if(I.IsExpired(now)) if(introset.IsExpired(now))
{ {
// don't propogate or store // don't propogate or store
replies.emplace_back(new GotIntroMessage({}, txID)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
} }
dht.services()->PutNode(I); dht.services()->PutNode(introset);
replies.emplace_back(new GotIntroMessage({I}, txID)); replies.emplace_back(new GotIntroMessage({introset}, txID));
Key_t peer; Key_t peer;
std::set< Key_t > exclude; std::set< Key_t > exclude_propagate;
for(const auto &e : E) for(const auto &e : exclude)
exclude.insert(e); exclude_propagate.insert(e);
exclude.insert(From); exclude_propagate.insert(From);
exclude.insert(dht.OurKey()); exclude_propagate.insert(dht.OurKey());
if(S && dht.Nodes()->FindCloseExcluding(addr, peer, exclude)) if(depth > 0
&& dht.Nodes()->FindCloseExcluding(addr, peer, exclude_propagate))
{ {
dht.PropagateIntroSetTo(From, txID, I, peer, S - 1, exclude); dht.PropagateIntroSetTo(From, txID, introset, peer, depth - 1,
exclude_propagate);
} }
return true; return true;
} }
@ -103,13 +101,11 @@ namespace llarp
return false; return false;
if(!BEncodeWriteDictMsgType(buf, "A", "I")) if(!BEncodeWriteDictMsgType(buf, "A", "I"))
return false; return false;
if(!BEncodeWriteDictList("E", E, buf)) if(!BEncodeWriteDictList("E", exclude, buf))
return false;
if(!BEncodeWriteDictEntry("I", I, buf))
return false; return false;
if(!BEncodeWriteDictInt("R", R, buf)) if(!BEncodeWriteDictEntry("I", introset, buf))
return false; return false;
if(!BEncodeWriteDictInt("S", S, buf)) if(!BEncodeWriteDictInt("S", depth, buf))
return false; return false;
if(!BEncodeWriteDictInt("T", txID, buf)) if(!BEncodeWriteDictInt("T", txID, buf))
return false; return false;

@ -12,22 +12,23 @@ namespace llarp
{ {
struct PublishIntroMessage final : public IMessage struct PublishIntroMessage final : public IMessage
{ {
llarp::service::IntroSet I; static const uint64_t MaxPropagationDepth;
std::vector< Key_t > E; llarp::service::IntroSet introset;
uint64_t R = 0; std::vector< Key_t > exclude;
uint64_t S = 0; uint64_t depth = 0;
uint64_t txID = 0; uint64_t txID = 0;
bool hasS = false;
PublishIntroMessage() : IMessage({}) PublishIntroMessage() : IMessage({})
{ {
} }
PublishIntroMessage(const llarp::service::IntroSet& i, uint64_t tx, PublishIntroMessage(const llarp::service::IntroSet& i, uint64_t tx,
uint64_t s, std::vector< Key_t > exclude = {}) uint64_t s, std::vector< Key_t > _exclude = {})
: IMessage({}), E(std::move(exclude)), txID(tx) : IMessage({})
, introset(i)
, exclude(std::move(_exclude))
, depth(s)
, txID(tx)
{ {
I = i;
S = s;
} }
~PublishIntroMessage() override; ~PublishIntroMessage() override;

@ -296,15 +296,15 @@ namespace llarp
{ {
std::set< IntroSet > remote; std::set< IntroSet > remote;
auto currentPub = m_state->m_CurrentPublishTX; auto currentPub = m_state->m_CurrentPublishTX;
for(const auto& introset : msg->I) for(const auto& introset : msg->found)
{ {
if(!introset.Verify(Now())) if(!introset.Verify(Now()))
{ {
if(m_Identity.pub == introset.A && currentPub == msg->T) if(m_Identity.pub == introset.A && currentPub == msg->txid)
IntroSetPublishFail(); IntroSetPublishFail();
return true; return true;
} }
if(m_Identity.pub == introset.A && currentPub == msg->T) if(m_Identity.pub == introset.A && currentPub == msg->txid)
{ {
LogInfo( LogInfo(
"got introset publish confirmation for hidden service endpoint ", "got introset publish confirmation for hidden service endpoint ",
@ -316,11 +316,11 @@ namespace llarp
remote.insert(introset); remote.insert(introset);
} }
auto& lookups = m_state->m_PendingLookups; auto& lookups = m_state->m_PendingLookups;
auto itr = lookups.find(msg->T); auto itr = lookups.find(msg->txid);
if(itr == lookups.end()) if(itr == lookups.end())
{ {
LogWarn("invalid lookup response for hidden service endpoint ", Name(), LogWarn("invalid lookup response for hidden service endpoint ", Name(),
" txid=", msg->T); " txid=", msg->txid);
return true; return true;
} }
std::unique_ptr< IServiceLookup > lookup = std::move(itr->second); std::unique_ptr< IServiceLookup > lookup = std::move(itr->second);
@ -716,11 +716,11 @@ namespace llarp
llarp_async_verify_rc* j) llarp_async_verify_rc* j)
{ {
auto& pendingRouters = m_state->m_PendingRouters; auto& pendingRouters = m_state->m_PendingRouters;
auto itr = pendingRouters.find(msg->R[0].pubkey); auto itr = pendingRouters.find(j->rc.pubkey);
if(itr != pendingRouters.end()) if(itr != pendingRouters.end())
{ {
if(j->valid) if(j->valid)
itr->second.InformResult(msg->R); itr->second.InformResult(msg->foundRCs);
else else
itr->second.InformResult({}); itr->second.InformResult({});
pendingRouters.erase(itr); pendingRouters.erase(itr);
@ -731,17 +731,20 @@ namespace llarp
bool bool
Endpoint::HandleGotRouterMessage(dht::GotRouterMessage_constptr msg) Endpoint::HandleGotRouterMessage(dht::GotRouterMessage_constptr msg)
{ {
if(msg->R.size()) if(not msg->foundRCs.empty())
{ {
llarp_async_verify_rc* job = new llarp_async_verify_rc(); for(const auto& rc : msg->foundRCs)
job->nodedb = Router()->nodedb(); {
job->cryptoworker = Router()->threadpool(); llarp_async_verify_rc* job = new llarp_async_verify_rc();
job->diskworker = Router()->diskworker(); job->nodedb = Router()->nodedb();
job->logic = Router()->logic(); job->cryptoworker = Router()->threadpool();
job->hook = std::bind(&Endpoint::HandleVerifyGotRouter, this, msg, job->diskworker = Router()->diskworker();
std::placeholders::_1); job->logic = Router()->logic();
job->rc = msg->R[0]; job->hook = std::bind(&Endpoint::HandleVerifyGotRouter, this, msg,
llarp_nodedb_async_verify(job); std::placeholders::_1);
job->rc = rc;
llarp_nodedb_async_verify(job);
}
} }
else else
{ {

@ -181,7 +181,7 @@ TEST_F(TestDhtServiceAddressLookup, send_reply)
WhenDynamicCastTo<dht::GotIntroMessage *>( WhenDynamicCastTo<dht::GotIntroMessage *>(
AllOf( AllOf(
NotNull(), NotNull(),
Field(&dht::GotIntroMessage::I, SizeIs(1)) Field(&dht::GotIntroMessage::found, SizeIs(1))
) )
), ),
true true
@ -206,7 +206,7 @@ TEST_F(TestDhtServiceAddressLookup, send_reply)
WhenDynamicCastTo<dht::GotIntroMessage *>( WhenDynamicCastTo<dht::GotIntroMessage *>(
AllOf( AllOf(
NotNull(), NotNull(),
Field(&dht::GotIntroMessage::I, SizeIs(1)) Field(&dht::GotIntroMessage::found, SizeIs(1))
) )
), ),
true true

@ -139,7 +139,7 @@ TEST_F(TestDhtTagLookup, send_reply)
WhenDynamicCastTo<dht::GotIntroMessage *>( WhenDynamicCastTo<dht::GotIntroMessage *>(
AllOf( AllOf(
NotNull(), NotNull(),
Field(&dht::GotIntroMessage::I, IsEmpty()) Field(&dht::GotIntroMessage::found, IsEmpty())
) )
), ),
true true
@ -164,7 +164,7 @@ TEST_F(TestDhtTagLookup, send_reply)
WhenDynamicCastTo<dht::GotIntroMessage *>( WhenDynamicCastTo<dht::GotIntroMessage *>(
AllOf( AllOf(
NotNull(), NotNull(),
Field(&dht::GotIntroMessage::I, SizeIs(1)) Field(&dht::GotIntroMessage::found, SizeIs(1))
) )
), ),
true true
@ -188,7 +188,7 @@ TEST_F(TestDhtTagLookup, send_reply)
WhenDynamicCastTo<dht::GotIntroMessage *>( WhenDynamicCastTo<dht::GotIntroMessage *>(
AllOf( AllOf(
NotNull(), NotNull(),
Field(&dht::GotIntroMessage::I, SizeIs(1)) Field(&dht::GotIntroMessage::found, SizeIs(1))
) )
), ),
true true
@ -218,7 +218,7 @@ TEST_F(TestDhtTagLookup, send_reply)
WhenDynamicCastTo<dht::GotIntroMessage *>( WhenDynamicCastTo<dht::GotIntroMessage *>(
AllOf( AllOf(
NotNull(), NotNull(),
Field(&dht::GotIntroMessage::I, SizeIs(2)) Field(&dht::GotIntroMessage::found, SizeIs(2))
) )
), ),
true true

Loading…
Cancel
Save