1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

Merge pull request #1069 from majestrate/refactor-single-char-variables-2020-01-23

Refactor single char variables in dht messages
This commit is contained in:
Jeff 2020-01-23 12:12:33 -05:00 committed by GitHub
commit 0edad0a817
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 300 additions and 261 deletions

View file

@ -105,8 +105,8 @@ namespace llarp
/// local path
void
LookupIntroSetForPath(const service::Address& addr, uint64_t txid,
const llarp::PathID_t& path,
const Key_t& askpeer) override;
const llarp::PathID_t& path, const Key_t& askpeer,
uint64_t R) override;
/// send a dht message to peer, if keepalive is true then keep the session
/// with that peer alive for 10 seconds
@ -435,14 +435,29 @@ namespace llarp
new GotRouterMessage(requester, txid, {router->rc()}, false));
return;
}
Key_t next;
std::set< Key_t > excluding = {requester, ourKey};
if(_nodes->FindCloseExcluding(target, next, excluding))
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 Key_t next(rc.pubkey);
{
if(next == target)
{
// we know it, ask them directly for their own RC to keep it updated
LookupRouterRecursive(target.as_array(), requester, txid, next);
// we know the target
if(rc.ExpiresSoon(llarp::time_now_ms()))
{
// ask target for their rc to keep it updated
LookupRouterRecursive(target.as_array(), requester, txid, next);
}
else
{
// send reply with rc we know of
replies.emplace_back(
new GotRouterMessage(requester, txid, {rc}, false));
}
}
else if(recursive) // are we doing a recursive lookup?
{
@ -467,11 +482,6 @@ namespace llarp
new GotRouterMessage(requester, next, txid, false));
}
}
else
{
// we don't know it and have no closer peers to ask
replies.emplace_back(new GotRouterMessage(requester, txid, {}, false));
}
}
const llarp::service::IntroSet*
@ -565,13 +575,14 @@ namespace llarp
void
Context::LookupIntroSetForPath(const service::Address& addr, uint64_t txid,
const llarp::PathID_t& path,
const Key_t& askpeer)
const Key_t& askpeer, uint64_t R)
{
TXOwner asker(OurKey(), txid);
TXOwner peer(askpeer, ++ids);
_pendingIntrosetLookups.NewTX(
peer, asker, addr,
new LocalServiceAddressLookup(path, txid, addr, this, askpeer));
new LocalServiceAddressLookup(path, txid, addr, this, askpeer),
((R + 1) * 2000));
}
void
@ -598,7 +609,8 @@ namespace llarp
TXOwner peer(askpeer, ++ids);
_pendingIntrosetLookups.NewTX(
peer, asker, addr,
new ServiceAddressLookup(asker, addr, this, R, handler), (R * 2000));
new ServiceAddressLookup(asker, addr, this, R, handler),
((R + 1) * 2000));
}
void

View file

@ -88,7 +88,8 @@ namespace llarp
virtual void
LookupIntroSetForPath(const service::Address& addr, uint64_t txid,
const PathID_t& path, const Key_t& askpeer) = 0;
const PathID_t& path, const Key_t& askpeer,
uint64_t R) = 0;
virtual void
DHTSendTo(const RouterID& peer, IMessage* msg, bool keepalive = true) = 0;

View file

@ -2,28 +2,32 @@
#include <dht/messages/findintro.hpp>
#include <dht/messages/gotintro.hpp>
#include <routing/message.hpp>
#include <router/abstractrouter.hpp>
#include <nodedb.hpp>
namespace llarp
{
namespace dht
{
FindIntroMessage::~FindIntroMessage() = default;
/// 2 ** 12 which is 4096 nodes, after which this starts to fail "more"
const uint64_t FindIntroMessage::MaxRecursionDepth = 12;
FindIntroMessage::~FindIntroMessage() = default;
bool
FindIntroMessage::DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* val)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("N", N, read, k, val))
if(!BEncodeMaybeReadDictEntry("N", tagName, read, k, val))
return false;
if(!BEncodeMaybeReadDictInt("R", R, read, k, val))
if(!BEncodeMaybeReadDictInt("R", recursionDepth, read, k, val))
return false;
if(!BEncodeMaybeReadDictEntry("S", S, read, k, val))
if(!BEncodeMaybeReadDictEntry("S", serviceAddress, read, k, val))
return false;
if(!BEncodeMaybeReadDictInt("T", T, read, k, val))
if(!BEncodeMaybeReadDictInt("T", txID, read, k, val))
return false;
if(!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, k,
@ -42,25 +46,25 @@ namespace llarp
// message id
if(!BEncodeWriteDictMsgType(buf, "A", "F"))
return false;
if(N.Empty())
if(tagName.Empty())
{
// recursion
if(!BEncodeWriteDictInt("R", R, buf))
if(!BEncodeWriteDictInt("R", recursionDepth, buf))
return false;
// service address
if(!BEncodeWriteDictEntry("S", S, buf))
if(!BEncodeWriteDictEntry("S", serviceAddress, buf))
return false;
}
else
{
if(!BEncodeWriteDictEntry("N", N, buf))
if(!BEncodeWriteDictEntry("N", tagName, buf))
return false;
// recursion
if(!BEncodeWriteDictInt("R", R, buf))
if(!BEncodeWriteDictInt("R", recursionDepth, buf))
return false;
}
// txid
if(!BEncodeWriteDictInt("T", T, buf))
if(!BEncodeWriteDictInt("T", txID, buf))
return false;
// protocol version
if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf))
@ -73,71 +77,73 @@ namespace llarp
FindIntroMessage::HandleMessage(
llarp_dht_context* ctx, std::vector< IMessage::Ptr_t >& replies) const
{
if(R > 5)
if(recursionDepth > MaxRecursionDepth)
{
llarp::LogError("R value too big, ", R, "> 5");
llarp::LogError("recursion depth big, ", recursionDepth, "> ",
MaxRecursionDepth);
return false;
}
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;
}
Key_t peer;
std::set< Key_t > exclude = {dht.OurKey(), From};
if(N.Empty())
if(tagName.Empty())
{
llarp::LogInfo("lookup ", S.ToString());
const auto introset = dht.GetIntroSetByServiceAddress(S);
if(serviceAddress.IsZero())
{
// we dont got it
replies.emplace_back(new GotIntroMessage({}, txID));
return true;
}
llarp::LogInfo("lookup ", serviceAddress.ToString());
const auto introset = dht.GetIntroSetByServiceAddress(serviceAddress);
if(introset)
{
service::IntroSet i = *introset;
replies.emplace_back(new GotIntroMessage({i}, T));
replies.emplace_back(new GotIntroMessage({*introset}, txID));
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
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));
replies.emplace_back(new GotIntroMessage(From, closer, txID));
return true;
}
Key_t us = dht.OurKey();
Key_t target = S.ToKey();
// we are recursive
if(dht.Nodes()->FindCloseExcluding(target, peer, exclude))
const auto rc = dht.GetRouter()->nodedb()->FindClosestTo(target);
peer = Key_t(rc.pubkey);
if((us ^ target) < (peer ^ target) || peer == us)
{
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;
}
if(R > 0)
dht.LookupIntroSetRecursive(S, From, T, peer, R - 1);
else
dht.LookupIntroSetIterative(S, From, T, peer);
}
// we are not closer than our peer to the target so don't
// recurse farther
replies.emplace_back(new GotIntroMessage({}, txID));
return true;
}
// no more closer peers
replies.emplace_back(new GotIntroMessage({}, T));
if(relayed)
{
dht.LookupIntroSetForPath(serviceAddress, txID, pathID, peer,
recursionDepth - 1);
}
else
{
dht.LookupIntroSetRecursive(serviceAddress, From, txID, peer,
recursionDepth - 1);
}
return true;
}
@ -146,45 +152,47 @@ namespace llarp
// tag lookup
if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude))
{
dht.LookupTagForPath(N, T, pathID, peer);
dht.LookupTagForPath(tagName, txID, pathID, peer);
}
else
{
// no more closer peers
replies.emplace_back(new GotIntroMessage({}, T));
replies.emplace_back(new GotIntroMessage({}, txID));
return true;
}
}
else
{
if(R == 0)
if(recursionDepth == 0)
{
// base case
auto introsets = dht.FindRandomIntroSetsWithTagExcluding(N, 2, {});
auto introsets =
dht.FindRandomIntroSetsWithTagExcluding(tagName, 2, {});
std::vector< service::IntroSet > reply;
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;
}
if(R < 5)
if(recursionDepth < MaxRecursionDepth)
{
// tag lookup
if(dht.Nodes()->GetRandomNodeExcluding(peer, exclude))
{
dht.LookupTagRecursive(N, From, T, peer, R - 1);
dht.LookupTagRecursive(tagName, From, txID, peer,
recursionDepth - 1);
}
else
{
replies.emplace_back(new GotIntroMessage({}, T));
replies.emplace_back(new GotIntroMessage({}, txID));
}
}
else
{
// too big R value
replies.emplace_back(new GotIntroMessage({}, T));
// too big recursion depth
replies.emplace_back(new GotIntroMessage({}, txID));
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -10,7 +10,8 @@ namespace llarp
{
namespace dht
{
PublishIntroMessage::~PublishIntroMessage() = default;
const uint64_t PublishIntroMessage::MaxPropagationDepth = 5;
PublishIntroMessage::~PublishIntroMessage() = default;
bool
PublishIntroMessage::DecodeKey(const llarp_buffer_t &key,
@ -19,19 +20,12 @@ namespace llarp
bool read = false;
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;
if(!BEncodeMaybeReadDictInt("R", R, read, key, val))
if(!BEncodeMaybeReadDictInt("S", depth, read, key, val))
return false;
if(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))
@ -45,21 +39,23 @@ namespace llarp
std::vector< std::unique_ptr< IMessage > > &replies) const
{
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;
}
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
replies.emplace_back(new GotIntroMessage({}, txID));
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");
// don't propogate or store
@ -67,7 +63,7 @@ namespace llarp
return true;
}
llarp::dht::Key_t addr;
if(!I.A.CalculateAddress(addr.as_array()))
if(not introset.A.CalculateAddress(addr.as_array()))
{
llarp::LogWarn(
"failed to calculate hidden service address for PubIntro message");
@ -75,23 +71,25 @@ namespace llarp
}
now += llarp::service::MAX_INTROSET_TIME_DELTA;
if(I.IsExpired(now))
if(introset.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));
dht.services()->PutNode(introset);
replies.emplace_back(new GotIntroMessage({introset}, 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))
std::set< Key_t > exclude_propagate;
for(const auto &e : exclude)
exclude_propagate.insert(e);
exclude_propagate.insert(From);
exclude_propagate.insert(dht.OurKey());
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;
}
@ -103,13 +101,11 @@ namespace llarp
return false;
if(!BEncodeWriteDictMsgType(buf, "A", "I"))
return false;
if(!BEncodeWriteDictList("E", E, buf))
if(!BEncodeWriteDictList("E", exclude, buf))
return false;
if(!BEncodeWriteDictEntry("I", I, buf))
if(!BEncodeWriteDictEntry("I", introset, buf))
return false;
if(!BEncodeWriteDictInt("R", R, buf))
return false;
if(!BEncodeWriteDictInt("S", S, buf))
if(!BEncodeWriteDictInt("S", depth, buf))
return false;
if(!BEncodeWriteDictInt("T", txID, buf))
return false;

View file

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

View file

@ -46,7 +46,6 @@ namespace llarp
void
RecursiveRouterLookup::DoNextRequest(const Key_t &peer)
{
peersAsked.emplace(peer);
parent->LookupRouterRecursive(target, whoasked.node, whoasked.txid, peer,
resultHandler);
}
@ -54,7 +53,6 @@ namespace llarp
void
RecursiveRouterLookup::Start(const TXOwner &peer)
{
peersAsked.emplace(peer.node);
parent->DHTSendTo(peer.node.as_array(),
new FindRouterMessage(peer.txid, target));
}
@ -78,7 +76,7 @@ namespace llarp
{
resultHandler(valuesFound);
}
else if(whoasked.node != parent->OurKey())
if(whoasked.node != parent->OurKey())
{
parent->DHTSendTo(
whoasked.node.as_array(),

View file

@ -9,6 +9,7 @@
#include <util/mem.hpp>
#include <util/thread/logic.hpp>
#include <util/thread/thread_pool.hpp>
#include <dht/kademlia.hpp>
#include <fstream>
#include <unordered_map>
@ -92,6 +93,25 @@ llarp_nodedb::Has(const llarp::RouterID &pk)
return entries.find(pk) != entries.end();
}
llarp::RouterContact
llarp_nodedb::FindClosestTo(const llarp::dht::Key_t &location)
{
llarp::RouterContact rc;
const llarp::dht::XorMetric compare(location);
visit([&rc, compare](const auto &otherRC) -> bool {
if(rc.pubkey.IsZero())
{
rc = otherRC;
return true;
}
if(compare(llarp::dht::Key_t{otherRC.pubkey.as_array()},
llarp::dht::Key_t{rc.pubkey.as_array()}))
rc = otherRC;
return true;
});
return rc;
}
/// skiplist directory is hex encoded first nibble
/// skiplist filename is <base32encoded>.snode.signed
std::string

View file

@ -6,6 +6,7 @@
#include <util/common.hpp>
#include <util/fs.hpp>
#include <util/thread/threading.hpp>
#include <dht/key.hpp>
#include <absl/base/thread_annotations.h>
@ -73,6 +74,9 @@ struct llarp_nodedb
NetDBMap_t entries GUARDED_BY(access);
fs::path nodePath;
llarp::RouterContact
FindClosestTo(const llarp::dht::Key_t &location);
/// return true if we should save our nodedb to disk
bool
ShouldSaveToDisk(llarp_time_t now = 0) const;

View file

@ -1,2 +1 @@
#include <router/abstractrouter.hpp>

View file

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

View file

@ -38,8 +38,8 @@ namespace llarp
HiddenServiceAddressLookup::BuildRequestMessage()
{
auto msg = std::make_shared< routing::DHTMessage >();
msg->M.emplace_back(
std::make_unique< dht::FindIntroMessage >(txid, remote, true));
msg->M.emplace_back(std::make_unique< dht::FindIntroMessage >(
txid, remote, dht::FindIntroMessage::MaxRecursionDepth));
return msg;
}

View file

@ -11,7 +11,6 @@ namespace llarp
{
struct MockContext final : public dht::AbstractContext
{
MOCK_CONST_METHOD1(StoreRC, void(const RouterContact));
MOCK_METHOD2(LookupRouter, bool(const RouterID&, RouterLookupHandler));
@ -48,9 +47,9 @@ namespace llarp
void(const RouterID& target, uint64_t txid,
const PathID_t& path, const dht::Key_t& askpeer));
MOCK_METHOD4(LookupIntroSetForPath,
MOCK_METHOD5(LookupIntroSetForPath,
void(const service::Address&, uint64_t, const PathID_t&,
const dht::Key_t&));
const dht::Key_t&, uint64_t));
MOCK_METHOD3(DHTSendTo, void(const RouterID&, dht::IMessage*, bool));

View file

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

View file

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