diff --git a/CMakeLists.txt b/CMakeLists.txt index 2daed749b..1b14d8b50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/Makefile b/Makefile index ce19e1e7d..a38b9c481 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/doc/dht_v0.txt b/doc/dht_v0.txt index 2a696b71a..20025ea3a 100644 --- a/doc/dht_v0.txt +++ b/doc/dht_v0.txt @@ -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. diff --git a/doc/proto_v0.txt b/doc/proto_v0.txt index 4fde18ae5..900c39ee8 100644 --- a/doc/proto_v0.txt +++ b/doc/proto_v0.txt @@ -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: "", @@ -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 +} \ No newline at end of file diff --git a/include/llarp/dht.hpp b/include/llarp/dht.hpp index 0bae9eeee..a65c8547f 100644 --- a/include/llarp/dht.hpp +++ b/include/llarp/dht.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include @@ -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 diff --git a/include/llarp/messages/dht.hpp b/include/llarp/messages/dht.hpp new file mode 100644 index 000000000..a70ca27c1 --- /dev/null +++ b/include/llarp/messages/dht.hpp @@ -0,0 +1,31 @@ +#ifndef LLARP_MESSAGES_DHT_HPP +#define LLARP_MESSAGES_DHT_HPP +#include +#include + +#include + +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 \ No newline at end of file diff --git a/include/llarp/messages/dht_immediate.hpp b/include/llarp/messages/dht_immediate.hpp index 37e004cb6..552f99628 100644 --- a/include/llarp/messages/dht_immediate.hpp +++ b/include/llarp/messages/dht_immediate.hpp @@ -25,6 +25,6 @@ namespace llarp bool HandleMessage(llarp_router* router) const; }; -} +} // namespace llarp #endif diff --git a/include/llarp/messages/path_transfer.hpp b/include/llarp/messages/path_transfer.hpp index a7a99b861..e2594f4ab 100644 --- a/include/llarp/messages/path_transfer.hpp +++ b/include/llarp/messages/path_transfer.hpp @@ -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 diff --git a/include/llarp/messages/relay_commit.hpp b/include/llarp/messages/relay_commit.hpp index 7e48c69d0..acf70dd85 100644 --- a/include/llarp/messages/relay_commit.hpp +++ b/include/llarp/messages/relay_commit.hpp @@ -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); diff --git a/include/llarp/service.hpp b/include/llarp/service.hpp index 88fed137a..9ae47d8e2 100644 --- a/include/llarp/service.hpp +++ b/include/llarp/service.hpp @@ -3,6 +3,9 @@ #include #include #include +#include + +#include 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 diff --git a/llarp/dht.cpp b/llarp/dht.cpp index d5bd009a2..d4b3d0b07 100644 --- a/llarp/dht.cpp +++ b/llarp/dht.cpp @@ -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}); + } } diff --git a/llarp/relay_commit.cpp b/llarp/relay_commit.cpp index 2d63a9c7e..e0c1f6c66 100644 --- a/llarp/relay_commit.cpp +++ b/llarp/relay_commit.cpp @@ -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(); diff --git a/llarp/routing/dht_message.cpp b/llarp/routing/dht_message.cpp new file mode 100644 index 000000000..9d7533857 --- /dev/null +++ b/llarp/routing/dht_message.cpp @@ -0,0 +1,61 @@ +#include +#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 \ No newline at end of file diff --git a/llarp/routing/message_parser.cpp b/llarp/routing/message_parser.cpp index 4b6ee7b0b..8dc16a92b 100644 --- a/llarp/routing/message_parser.cpp +++ b/llarp/routing/message_parser.cpp @@ -1,5 +1,7 @@ +#include #include #include +#include #include 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); } diff --git a/llarp/routing/path_transfer.cpp b/llarp/routing/path_transfer.cpp new file mode 100644 index 000000000..3c3b47887 --- /dev/null +++ b/llarp/routing/path_transfer.cpp @@ -0,0 +1,65 @@ +#include +#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 \ No newline at end of file diff --git a/llarp/transit_hop.cpp b/llarp/transit_hop.cpp index 1db2d6db1..4b45b3161 100644 --- a/llarp/transit_hop.cpp +++ b/llarp/transit_hop.cpp @@ -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); } diff --git a/test/dht_unittest.cpp b/test/dht_unittest.cpp index 043c76548..74a92472b 100644 --- a/test/dht_unittest.cpp +++ b/test/dht_unittest.cpp @@ -1,9 +1,7 @@ #include #include -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)); };