* implement path transfer message

* update dht docs
* update other docs
* start working on dht for hidden services
* fix up unit tests for dht
* update makefile and other build files
pull/5/head
Jeff Becker 6 years ago
parent 7d9bffdf9c
commit 18b50f4a74
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -170,9 +170,11 @@ set(LIB_SRC
llarp/api/client.cpp
llarp/api/message.cpp
llarp/api/parser.cpp
llarp/routing/dht_message.cpp
llarp/routing/message_parser.cpp
llarp/routing/path_confirm.cpp
llarp/routing/path_latency.cpp
llarp/routing/path_transfer.cpp
vendor/cppbackport-master/lib/fs/rename.cpp
vendor/cppbackport-master/lib/fs/filestatus.cpp
vendor/cppbackport-master/lib/fs/filetype.cpp

@ -70,7 +70,7 @@ testnet-build: testnet-configure
testnet: testnet-build
mkdir -p $(TESTNET_ROOT)
python3 contrib/testnet/genconf.py --bin=$(REPO)/llarpd --svc=10 --clients=1 --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF)
python3 contrib/testnet/genconf.py --bin=$(REPO)/llarpd --svc=30 --clients=100 --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF)
supervisord -n -d $(TESTNET_ROOT) -l $(TESTNET_LOG) -c $(TESTNET_CONF)
test: debug-configure

@ -2,13 +2,12 @@ DHT messages
these messages can be either wrapped in a LIDM message or sent anonymously over a path
This document is currently out of date (probably)
find introduction message (FIM)
recursively find an IS.
variant 1, by SA
recursively find an IS by SA
{
A: "F",
@ -18,16 +17,6 @@ variant 1, by SA
V: 0
}
variant 2, by claimed name
{
A: "F",
N: "service.name.tld",
R: r_counter,
T: transaction_id_uin64,
V: 0
}
Transactions will persist until replied to by a GIM or 60 seconds, whichever
is reached first.
@ -80,9 +69,9 @@ got introduction message (GIM)
{
A: "G",
I: [IS],
T: transaction_id_uint64,
V: 0,
X: [ IS, IS, IS, ... ]
}
if we have a transaction with id T:
@ -95,115 +84,36 @@ when a linked transaction gets a GIM:
* set T to the current transaction id
* foward the GIM to the requester of T
publish introduction message (PIM)
publish one or many IM into the dht at once.
each IS will be placed in the dht
publish one IS to the DHT.
version 0 uses the SA of each IS as the keyspace location.
version 0 uses the SA of the IS as the keyspace location.
in the future the location will be determined by the dht kdf
which uses a shared random source to obfuscate keyspace location.
R is currently set to 3 +/- 2 by the sender.
R is currently set to 0 by the sender.
{
A: "P",
A: "I",
I: IS,
R: r_counter,
V: 0,
X: [ IS, IS, IS, ... ]
S: optional member 0 for immediate store otherwise non zero,
V: 0
}
The following steps happen in order:
first stage: reduction
if X's length is divisble by 2:
* split X in half as J and K
* generate 2 new PIM with the same values as the parent with empty X
* put J and K into the new PIM's X values
* associate the 2 new PIM with the current PIM batch
if X's length is not divisible by 2 and greater than 1:
* pop off an IS from X as A
* generate a new PIM with the same values as the parent with an X value of A
* associate the new PIM with the current PIM batch
* associate the old PIM having A removed from X with the current PIM batch
if X's length is 1:
* associate the PIM with the current PIM batch
any other cases for X are ignored.
for each PIM in the current batch:
if R is greater than 0:
* decrement R by 1
* queue the PIM for shuffle (second stage)
if R is 0:
* queue the PIM for distribution (third stage)
if R is greater than 0, do a random walk, otherwise if we are
closer to the SA of the IS than anyone else we know in the DHT
store the IS for later lookup.
if R is less than 0:
If S is provided store the IS for later lookup unconditionally,
decrement S by 1 and forward to dht peer who is next closest to
the SA of the IS. If S is greater than 3, don't store and discard
this message.
* drop the message entirely
second stage: shuffle
* The dht node waits until we have collected 10 or more PIM or for 5 seconds,
which ever comes first.
* shuffle the list of IS randomly
* re-combine the IS into new PIMs
* queue each newly shuffled PIM for distribution (third stage)
if we collected 10 or more PIM:
* X holds 5 IS at most
if we collected less than 10 but more than 1 PIM:
* X holds 2 IS at most
if we only collected 1 PIM:
* the single PIM is unmodified
third stage: distribution
if R is less than 0:
* drop message and terminate current transaction, this should never happen but
this case is left here in the event of implementation bugs.
if R is greater than 0:
* pick a random dht capable router, N
* forward the PIM to N
if R is equal to 0:
for each IS in X as A:
* find the router closest to the SA in A, N
if N is our router:
* create dht positon S from SA in A
* store A for lookup at S
if N is not our router:
* send a PIM with X value containing just A to N
In the future post random walk keyspace batching may be done here.
As of version 0, none is done.
find router contact message (FRCM)
@ -254,8 +164,3 @@ sent in reply to FRCM only
* send a GRCM with R to requesters in all linked transactions
* terminate transaction with id T
notes:
if we get a GRCM with empty R on one Tx and then one with a filled R on another
with the same K, the request is terminated by the first message as not found.
A backtrack case is needed.

@ -153,14 +153,14 @@ the "network address" of a hidden service, which is computed as the blake2b
HS(BE(SI))
introducer (I)
introduction (I)
a descriptor annoucing a path to a hidden service
k is the rc.k value of the router to contact
p is the path id on the router that is owned by the service
v is the protocol version
x is the timestamp seconds since epoch that this introducer expires at
x is the timestamp seconds since epoch that this introduction expires at
{
k: "<32 bytes public identity key of router>",
@ -169,12 +169,13 @@ x is the timestamp seconds since epoch that this introducer expires at
x: time_expires_seconds_since_epoch_uint64
}
introducer set (IS)
introduction set (IS)
a signed set of introducers for a hidden service
a signed set of introductions for a hidden service
a is the service info
i is the list of introducers that this service is advertising with
i is the list of introductions that this service is advertising with
v is the protocol version
w is an optinal proof of work for DoS protection (slot for future)
z is the signature of the entire IS where z is set to zero signed by the hidden
service's signing key.
@ -182,6 +183,7 @@ service's signing key.
a: SI,
i: [ I, I, I, ... ],
v: 0,
w: optional proof of work,
z: "<64 bytes signature using service info signing key>"
}
@ -190,10 +192,6 @@ service's signing key.
Encrypted frames:
{
v: 0,
w: "<32+32+32+N bytes payload>"
}
Encrypted frames are encrypted containers for link message records like LRCR.
@ -502,7 +500,7 @@ sent in response to an OXAM to indicate that exit traffic is not allowed or
was denied.
{
A: "R",
A: "J",
B: backoff_milliseconds_uint64,
I: "<32 bytes signing public key of requester>",
R: "<optional reject metadata>",
@ -596,3 +594,13 @@ The address used in exit MAY be reused later.
Y: "<16 bytes nounce>",
Z: "<64 bytes signagure using previously provided signing key>"
}
DHT message holder message:
wrapper message for sending many dht messages down a path.
{
A: "M",
M: [many, dht, messages, here],
V: 0
}

@ -6,6 +6,8 @@
#include <llarp/router_contact.h>
#include <llarp/time.h>
#include <llarp/aligned.hpp>
#include <llarp/path_types.hpp>
#include <llarp/service.hpp>
#include <array>
#include <functional>
@ -46,23 +48,40 @@ namespace llarp
}
};
struct Node
struct RCNode
{
llarp_rc* rc;
Key_t ID;
Node() : rc(nullptr)
RCNode() : rc(nullptr)
{
ID.Zero();
}
Node(llarp_rc* other) : rc(other)
RCNode(llarp_rc* other) : rc(other)
{
ID = other->pubkey;
}
};
struct ISNode
{
llarp::service::IntroSet* introset;
Key_t ID;
ISNode() : introset(nullptr)
{
ID.Zero();
}
ISNode(llarp::service::IntroSet* other) : introset(other)
{
other->A.CalculateAddress(ID);
}
};
struct SearchJob
{
const static uint64_t JobTimeout = 30000;
@ -128,24 +147,65 @@ namespace llarp
DecodeMesssageList(const Key_t& from, llarp_buffer_t* buf,
std::vector< IMessage* >& dst);
template < typename Val_t >
struct Bucket
{
typedef std::map< Key_t, Node, XorMetric > BucketStorage_t;
typedef std::map< Key_t, Val_t, XorMetric > BucketStorage_t;
Bucket(const Key_t& us) : nodes(XorMetric(us)){};
bool
FindClosest(const Key_t& target, Key_t& result) const;
FindClosest(const Key_t& target, Key_t& result) const
{
Key_t mindist;
mindist.Fill(0xff);
for(const auto& item : nodes)
{
auto curDist = item.first ^ target;
if(curDist < mindist)
{
mindist = curDist;
result = item.first;
}
}
return nodes.size() > 0;
}
bool
FindCloseExcluding(const Key_t& target, Key_t& result,
const std::set< Key_t >& exclude) const;
const std::set< Key_t >& exclude) const
{
Key_t maxdist;
maxdist.Fill(0xff);
Key_t mindist;
mindist.Fill(0xff);
for(const auto& item : nodes)
{
if(exclude.find(item.first) != exclude.end())
continue;
auto curDist = item.first ^ target;
if(curDist < mindist)
{
mindist = curDist;
result = item.first;
}
}
return mindist < maxdist;
}
void
PutNode(const Node& val);
PutNode(const Val_t& val)
{
nodes[val.ID] = val;
}
void
DelNode(const Key_t& key);
DelNode(const Key_t& key)
{
auto itr = nodes.find(key);
if(itr != nodes.end())
nodes.erase(itr);
}
BucketStorage_t nodes;
};
@ -177,6 +237,10 @@ namespace llarp
const Key_t& target, bool recursive,
std::vector< IMessage* >& replies);
bool
RelayRequestForPath(const llarp::PathID_t& localPath,
const IMessage* msg);
void
Init(const Key_t& us, llarp_router* router);
@ -190,8 +254,12 @@ namespace llarp
queue_router_lookup(void* user);
llarp_router* router = nullptr;
Bucket* nodes = nullptr;
bool allowTransit = false;
// for router contacts
Bucket< RCNode >* nodes = nullptr;
// for introduction sets
Bucket< ISNode >* services = nullptr;
bool allowTransit = false;
const Key_t&
OurKey() const

@ -0,0 +1,31 @@
#ifndef LLARP_MESSAGES_DHT_HPP
#define LLARP_MESSAGES_DHT_HPP
#include <llarp/dht.hpp>
#include <llarp/routing/message.hpp>
#include <vector>
namespace llarp
{
namespace routing
{
struct DHTMessage : public IMessage
{
std::vector< llarp::dht::IMessage* > M;
uint64_t V = 0;
~DHTMessage();
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* val);
bool
BEncode(llarp_buffer_t* buf) const;
bool
HandleMessage(IMessageHandler* h, llarp_router* r) const;
};
} // namespace routing
} // namespace llarp
#endif

@ -25,6 +25,6 @@ namespace llarp
bool
HandleMessage(llarp_router* router) const;
};
}
} // namespace llarp
#endif

@ -13,7 +13,20 @@ namespace llarp
{
PathID_t P;
Encrypted T;
uint64_t V = 0;
TunnelNonce Y;
PathTransferMessage();
~PathTransferMessage();
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* val);
bool
BEncode(llarp_buffer_t* buf) const;
bool
HandleMessage(IMessageHandler*, llarp_router* r) const;
};
} // namespace routing

@ -23,8 +23,9 @@ namespace llarp
TunnelNonce tunnelNonce;
PathID_t txid, rxid;
PoW *work = nullptr;
uint64_t version = 0;
PoW *work = nullptr;
uint64_t version = 0;
uint64_t lifetime = 0;
bool
BDecode(llarp_buffer_t *buf);

@ -3,6 +3,9 @@
#include <llarp/aligned.hpp>
#include <llarp/bencode.hpp>
#include <llarp/crypto.hpp>
#include <llarp/path_types.hpp>
#include <set>
namespace llarp
{
@ -22,7 +25,7 @@ namespace llarp
/// calculate our address
void
CalculateAddress(llarp_crypto* c, Address& addr) const;
CalculateAddress(Address& addr) const;
bool
BEncode(llarp_buffer_t* buf) const;
@ -49,6 +52,33 @@ namespace llarp
// load from file
bool
LoadFromFile(const std::string& fpath);
bool
BEncode(llarp_buffer_t* buf) const;
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
};
struct Introduction : public llarp::IBEncodeMessage
{
llarp::PubKey router;
llarp::PathID_t pathID;
uint64_t version = 0;
uint64_t expiresAt;
bool
BEncode(llarp_buffer_t* buf) const;
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
};
struct IntroSet : public llarp::IBEncodeMessage
{
Info A;
std::set< Introduction > I;
llarp::Signature Z;
};
}; // namespace service

@ -426,59 +426,6 @@ namespace llarp
return now - started >= JobTimeout;
}
bool
Bucket::FindClosest(const Key_t &target, Key_t &result) const
{
Key_t mindist;
mindist.Fill(0xff);
for(const auto &item : nodes)
{
auto curDist = item.first ^ target;
if(curDist < mindist)
{
mindist = curDist;
result = item.first;
}
}
return nodes.size() > 0;
}
bool
Bucket::FindCloseExcluding(const Key_t &target, Key_t &result,
const std::set< Key_t > &exclude) const
{
Key_t maxdist;
maxdist.Fill(0xff);
Key_t mindist;
mindist.Fill(0xff);
for(const auto &item : nodes)
{
if(exclude.find(item.first) != exclude.end())
continue;
auto curDist = item.first ^ target;
if(curDist < mindist)
{
mindist = curDist;
result = item.first;
}
}
return mindist < maxdist;
}
void
Bucket::PutNode(const Node &v)
{
nodes[v.ID] = v;
}
void
Bucket::DelNode(const Key_t &k)
{
auto itr = nodes.find(k);
if(itr != nodes.end())
nodes.erase(itr);
}
Context::Context()
{
randombytes((byte_t *)&ids, sizeof(uint64_t));
@ -488,6 +435,8 @@ namespace llarp
{
if(nodes)
delete nodes;
if(services)
delete services;
}
void
@ -603,9 +552,10 @@ namespace llarp
void
Context::Init(const Key_t &us, llarp_router *r)
{
router = r;
ourKey = us;
nodes = new Bucket(ourKey);
router = r;
ourKey = us;
nodes = new Bucket< RCNode >(ourKey);
services = new Bucket< ISNode >(ourKey);
llarp::Debug("intialize dht with key ", ourKey);
}
@ -616,6 +566,13 @@ namespace llarp
{1000, this, &handle_cleaner_timer});
}
bool
Context::RelayRequestForPath(const llarp::PathID_t &id, const IMessage *msg)
{
// TODO: implement me
return false;
}
void
Context::LookupRouter(const Key_t &target, const Key_t &whoasked,
uint64_t txid, const Key_t &askpeer,
@ -673,60 +630,61 @@ llarp_dht_context::llarp_dht_context(llarp_router *router)
parent = router;
}
extern "C" {
struct llarp_dht_context *
llarp_dht_context_new(struct llarp_router *router)
extern "C"
{
return new llarp_dht_context(router);
}
struct llarp_dht_context *
llarp_dht_context_new(struct llarp_router *router)
{
return new llarp_dht_context(router);
}
void
llarp_dht_context_free(struct llarp_dht_context *ctx)
{
delete ctx;
}
void
llarp_dht_context_free(struct llarp_dht_context *ctx)
{
delete ctx;
}
void
llarp_dht_put_peer(struct llarp_dht_context *ctx, struct llarp_rc *rc)
void
llarp_dht_put_peer(struct llarp_dht_context *ctx, struct llarp_rc *rc)
{
llarp::dht::Node n(rc);
ctx->impl.nodes->PutNode(n);
}
{
llarp::dht::RCNode n(rc);
ctx->impl.nodes->PutNode(n);
}
void
llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id)
{
llarp::dht::Key_t k = id;
ctx->impl.nodes->DelNode(k);
}
void
llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id)
{
llarp::dht::Key_t k = id;
ctx->impl.nodes->DelNode(k);
}
void
llarp_dht_set_msg_handler(struct llarp_dht_context *ctx,
llarp_dht_msg_handler handler)
{
ctx->impl.custom_handler = handler;
}
void
llarp_dht_set_msg_handler(struct llarp_dht_context *ctx,
llarp_dht_msg_handler handler)
{
ctx->impl.custom_handler = handler;
}
void
llarp_dht_allow_transit(llarp_dht_context *ctx)
{
ctx->impl.allowTransit = true;
}
void
llarp_dht_allow_transit(llarp_dht_context *ctx)
{
ctx->impl.allowTransit = true;
}
void
llarp_dht_context_start(struct llarp_dht_context *ctx, const byte_t *key)
{
ctx->impl.Init(key, ctx->parent);
}
void
llarp_dht_context_start(struct llarp_dht_context *ctx, const byte_t *key)
{
ctx->impl.Init(key, ctx->parent);
}
void
llarp_dht_lookup_router(struct llarp_dht_context *ctx,
struct llarp_router_lookup_job *job)
{
job->dht = ctx;
job->found = false;
llarp_logic_queue_job(ctx->parent->logic,
{job, &llarp::dht::Context::queue_router_lookup});
}
void
llarp_dht_lookup_router(struct llarp_dht_context *ctx,
struct llarp_router_lookup_job *job)
{
job->dht = ctx;
job->found = false;
llarp_logic_queue_job(ctx->parent->logic,
{job, &llarp::dht::Context::queue_router_lookup});
}
}

@ -59,7 +59,6 @@ namespace llarp
" when we are not allowing transit");
return false;
}
llarp::Info("Got LRCM from ", remote);
return AsyncDecrypt(&router->paths);
}
@ -73,6 +72,11 @@ namespace llarp
return false;
if(!BEncodeWriteDictEntry("i", nextHop, buf))
return false;
if(lifetime > 10 && lifetime < 600)
{
if(!BEncodeWriteDictInt(buf, "i", lifetime))
return false;
}
if(!BEncodeWriteDictEntry("n", tunnelNonce, buf))
return false;
if(!BEncodeWriteDictEntry("r", rxid, buf))
@ -107,6 +111,8 @@ namespace llarp
return false;
if(!BEncodeMaybeReadDictEntry("i", self->nextHop, read, *key, r->buffer))
return false;
if(!BEncodeMaybeReadDictInt("l", self->lifetime, read, *key, r->buffer))
return false;
if(!BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key,
r->buffer))
return false;
@ -247,6 +253,12 @@ namespace llarp
self->record.work->extendedLifetime, " seconds for ", info);
self->hop->lifetime += 1000 * self->record.work->extendedLifetime;
}
else if(self->record.lifetime < 600 && self->record.lifetime > 10)
{
self->hop->lifetime = self->record.lifetime;
llarp::Info("LRCM short lifespan set to ", self->hop->lifetime,
" seconds for ", info);
}
// TODO: check if we really want to accept it
self->hop->started = llarp_time_now_ms();

@ -0,0 +1,61 @@
#include <llarp/messages/dht.hpp>
#include "../router.hpp"
namespace llarp
{
namespace routing
{
DHTMessage::~DHTMessage()
{
for(auto& msg : M)
delete msg;
}
bool
DHTMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* val)
{
llarp::dht::Key_t from;
from.Zero();
if(llarp_buffer_eq(key, "M"))
{
return llarp::dht::DecodeMesssageList(from, val, M);
}
else if(llarp_buffer_eq(key, "V"))
{
return bencode_read_integer(val, &V);
}
return false;
}
bool
DHTMessage::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictMsgType(buf, "A", "M"))
return false;
if(!BEncodeWriteDictBEncodeList("M", M, buf))
return false;
if(!BEncodeWriteDictInt(buf, "V", LLARP_PROTO_VERSION))
return false;
return bencode_end(buf);
}
bool
DHTMessage::HandleMessage(IMessageHandler* h, llarp_router* r) const
{
// set source as us
llarp::dht::Key_t us = r->pubkey();
for(auto& msg : M)
{
msg->From = us;
if(!r->dht->impl.RelayRequestForPath(from, msg))
return false;
}
return true;
}
} // namespace routing
} // namespace llarp

@ -1,5 +1,7 @@
#include <llarp/messages/dht.hpp>
#include <llarp/messages/path_confirm.hpp>
#include <llarp/messages/path_latency.hpp>
#include <llarp/messages/path_transfer.hpp>
#include <llarp/routing/message.hpp>
namespace llarp
@ -40,9 +42,15 @@ namespace llarp
case 'L':
self->msg = new PathLatencyMessage;
break;
case 'M':
self->msg = new DHTMessage;
break;
case 'P':
self->msg = new PathConfirmMessage;
break;
case 'T':
self->msg = new PathTransferMessage;
break;
default:
llarp::Error("invalid routing message id: ", *strbuf.cur);
}

@ -0,0 +1,65 @@
#include <llarp/messages/path_transfer.hpp>
#include "../router.hpp"
namespace llarp
{
namespace routing
{
PathTransferMessage::PathTransferMessage() : IMessage()
{
}
PathTransferMessage::~PathTransferMessage()
{
}
bool
PathTransferMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* val)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("P", P, read, key, val))
return false;
if(!BEncodeMaybeReadDictEntry("T", T, read, key, val))
return false;
if(!BEncodeMaybeReadDictInt("V", V, read, key, val))
return false;
if(!BEncodeMaybeReadDictEntry("Y", Y, read, key, val))
return false;
return false;
}
bool
PathTransferMessage::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictMsgType(buf, "A", "T"))
return false;
if(!BEncodeWriteDictEntry("P", P, buf))
return false;
if(!BEncodeWriteDictEntry("T", T, buf))
return false;
if(!BEncodeWriteDictInt(buf, "V", LLARP_PROTO_VERSION))
return false;
if(!BEncodeWriteDictEntry("Y", Y, buf))
return false;
return bencode_end(buf);
}
bool
PathTransferMessage::HandleMessage(IMessageHandler* h,
llarp_router* r) const
{
auto path = r->paths.GetByUpstream(r->pubkey(), P);
if(path)
{
return path->HandleDownstream(T.Buffer(), Y, r);
}
llarp::Warn("No such local path for path transfer src=", from,
" dst=", P);
return false;
}
} // namespace routing
} // namespace llarp

@ -72,8 +72,8 @@ namespace llarp
r->crypto.xchacha20(buf, pathKey, Y);
msg->X = buf;
llarp::Info("relay ", msg->X.size(), " bytes downstream from ",
info.upstream, " to ", info.downstream);
llarp::Debug("relay ", msg->X.size(), " bytes downstream from ",
info.upstream, " to ", info.downstream);
return r->SendToOrQueue(info.downstream, msg);
}
@ -93,8 +93,8 @@ namespace llarp
msg->Y = Y;
msg->X = buf;
llarp::Info("relay ", msg->X.size(), " bytes upstream from ",
info.downstream, " to ", info.upstream);
llarp::Debug("relay ", msg->X.size(), " bytes upstream from ",
info.downstream, " to ", info.upstream);
return r->SendToOrQueue(info.upstream, msg);
}
}
@ -113,7 +113,6 @@ namespace llarp
{
llarp::routing::PathLatencyMessage reply;
reply.L = msg->T;
llarp::Info("got latency message ", msg->T);
return SendRoutingMessage(&reply, r);
}

@ -1,9 +1,7 @@
#include <gtest/gtest.h>
#include <llarp/dht.hpp>
using Node = llarp::dht::Node;
using Key_t = llarp::dht::Key_t;
using Bucket = llarp::dht::Bucket;
using Key_t = llarp::dht::Key_t;
class KademliaDHTTest : public ::testing::Test
{
@ -19,12 +17,12 @@ class KademliaDHTTest : public ::testing::Test
SetUp()
{
us.Fill(16);
nodes = new Bucket(us);
nodes = new llarp::dht::Bucket< llarp::dht::RCNode >(us);
size_t numNodes = 10;
byte_t fill = 1;
while(numNodes)
{
Node n;
llarp::dht::RCNode n;
n.ID.Fill(fill);
nodes->PutNode(n);
--numNodes;
@ -38,15 +36,15 @@ class KademliaDHTTest : public ::testing::Test
delete nodes;
}
Bucket* nodes = nullptr;
Key_t us;
llarp::dht::Bucket< llarp::dht::RCNode >* nodes = nullptr;
llarp::dht::Key_t us;
};
TEST_F(KademliaDHTTest, TestBucketFindClosest)
{
Key_t result;
Key_t target;
Key_t oldResult;
llarp::dht::Key_t result;
llarp::dht::Key_t target;
llarp::dht::Key_t oldResult;
target.Fill(5);
ASSERT_TRUE(nodes->FindClosest(target, result));
ASSERT_TRUE(target == result);
@ -61,13 +59,13 @@ TEST_F(KademliaDHTTest, TestBucketRandomzied)
size_t moreNodes = 100;
while(moreNodes--)
{
Node n;
llarp::dht::RCNode n;
n.ID.Randomize();
nodes->PutNode(n);
}
Key_t result;
Key_t target;
Key_t oldResult;
llarp::dht::Key_t result;
llarp::dht::Key_t target;
llarp::dht::Key_t oldResult;
target.Randomize();
ASSERT_TRUE(nodes->FindClosest(target, result));
};

Loading…
Cancel
Save