diff --git a/CMakeLists.txt b/CMakeLists.txt index 47fb3d2c8..b30585fee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -504,21 +504,15 @@ set(LIB_SRC llarp/dht/decode.cpp llarp/dht/dht_immediate.cpp llarp/dht/dht.cpp - llarp/dht/find_intro.cpp - llarp/dht/find_router.cpp - llarp/dht/got_intro.cpp - llarp/dht/got_router.cpp llarp/dht/kademlia.cpp llarp/dht/key.cpp llarp/dht/message.cpp - llarp/dht/messages/all.cpp llarp/dht/messages/findintro.cpp llarp/dht/messages/findrouter.cpp llarp/dht/messages/gotintro.cpp llarp/dht/messages/gotrouter.cpp llarp/dht/messages/pubintro.cpp llarp/dht/node.cpp - llarp/dht/publish_intro.cpp llarp/dns.cpp llarp/dnsc.cpp llarp/dnsd.cpp diff --git a/llarp/dht/context.cpp b/llarp/dht/context.cpp index 62a1bfa77..3cf79359c 100644 --- a/llarp/dht/context.cpp +++ b/llarp/dht/context.cpp @@ -1,6 +1,9 @@ #include +#include +#include #include +#include #include #include #include @@ -270,7 +273,7 @@ namespace llarp ourKey = us; nodes = new Bucket< RCNode >(ourKey); services = new Bucket< ISNode >(ourKey); - llarp::LogDebug("intialize dht with key ", ourKey); + llarp::LogDebug("initialize dht with key ", ourKey); // start exploring r->logic->call_later( @@ -452,7 +455,7 @@ namespace llarp if(I.A != introset.A) { llarp::LogWarn( - "publish introset acknoledgement acked a different service"); + "publish introset acknowledgement acked a different service"); return false; } return true; diff --git a/llarp/dht/decode.cpp b/llarp/dht/decode.cpp index 6f83f9987..dd822cd76 100644 --- a/llarp/dht/decode.cpp +++ b/llarp/dht/decode.cpp @@ -1,5 +1,10 @@ #include -#include + +#include +#include +#include +#include +#include namespace llarp { diff --git a/llarp/dht/find_intro.cpp b/llarp/dht/find_intro.cpp deleted file mode 100644 index 441b3e466..000000000 --- a/llarp/dht/find_intro.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include -#include -#include - -namespace llarp -{ - namespace dht - { - /* - struct IntroSetLookupInformer - { - llarp::Router* router; - service::Address target; - - void - SendReply(const llarp::routing::IMessage* msg) - { - } - }; - */ - - FindIntroMessage::~FindIntroMessage() - { - } - - bool - FindIntroMessage::DecodeKey(llarp_buffer_t k, llarp_buffer_t* val) - { - bool read = false; - - if(!BEncodeMaybeReadDictEntry("N", N, read, k, val)) - return false; - - if(!BEncodeMaybeReadDictInt("R", R, read, k, val)) - return false; - - if(!BEncodeMaybeReadDictEntry("S", S, read, k, val)) - return false; - - if(!BEncodeMaybeReadDictInt("T", T, read, k, val)) - return false; - - if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, k, - val)) - return false; - - return read; - } - - bool - FindIntroMessage::BEncode(llarp_buffer_t* buf) const - { - if(!bencode_start_dict(buf)) - return false; - - // message id - if(!BEncodeWriteDictMsgType(buf, "A", "F")) - return false; - if(N.Empty()) - { - // recursion - if(!BEncodeWriteDictInt("R", R, buf)) - return false; - // service address - if(!BEncodeWriteDictEntry("S", S, buf)) - return false; - } - else - { - if(!BEncodeWriteDictEntry("N", N, buf)) - return false; - // recursion - if(!BEncodeWriteDictInt("R", R, buf)) - return false; - } - // txid - if(!BEncodeWriteDictInt("T", T, buf)) - return false; - // protocol version - if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf)) - return false; - - return bencode_end(buf); - } - - bool - FindIntroMessage::HandleMessage( - llarp_dht_context* ctx, - std::vector< std::unique_ptr< IMessage > >& replies) const - { - if(R > 5) - { - llarp::LogError("R value too big, ", R, "> 5"); - return false; - } - auto& dht = ctx->impl; - if(dht.pendingIntrosetLookups.HasPendingLookupFrom(TXOwner{From, T})) - { - llarp::LogWarn("duplicate FIM from ", From, " txid=", T); - return false; - } - Key_t peer; - std::set< Key_t > exclude = {dht.OurKey(), From}; - if(N.Empty()) - { - llarp::LogInfo("lookup ", S.ToString()); - const auto introset = dht.GetIntroSetByServiceAddress(S); - if(introset) - { - service::IntroSet i = *introset; - replies.emplace_back(new GotIntroMessage({i}, T)); - return true; - } - else - { - if(R == 0) - { - // we don't have it - Key_t target = S.ToKey(); - Key_t closer; - // find closer peer - if(!dht.nodes->FindClosest(target, closer)) - return false; - if(relayed) - dht.LookupIntroSetForPath(S, T, pathID, closer); - else - replies.emplace_back(new GotIntroMessage(From, closer, T)); - return true; - } - else - { - Key_t us = dht.OurKey(); - Key_t target = S.ToKey(); - // we are recursive - if(dht.nodes->FindCloseExcluding(target, peer, exclude)) - { - if(relayed) - dht.LookupIntroSetForPath(S, T, pathID, peer); - else - { - if((us ^ target) < (peer ^ target)) - { - // we are not closer than our peer to the target so don't - // recurse farther - replies.emplace_back(new GotIntroMessage({}, T)); - return true; - } - else if(R > 0) - dht.LookupIntroSetRecursive(S, From, T, peer, R - 1); - else - dht.LookupIntroSetIterative(S, From, T, peer); - } - return true; - } - else - { - // no more closer peers - replies.emplace_back(new GotIntroMessage({}, T)); - return true; - } - } - } - } - else - { - if(relayed) - { - // tag lookup - if(dht.nodes->GetRandomNodeExcluding(peer, exclude)) - { - dht.LookupTagForPath(N, T, pathID, peer); - } - else - { - // no more closer peers - replies.emplace_back(new GotIntroMessage({}, T)); - return true; - } - } - else - { - if(R == 0) - { - // base case - auto introsets = dht.FindRandomIntroSetsWithTagExcluding(N, 2, {}); - std::vector< service::IntroSet > reply; - for(const auto& introset : introsets) - { - reply.push_back(introset); - } - replies.emplace_back(new GotIntroMessage(reply, T)); - return true; - } - else if(R < 5) - { - // tag lookup - if(dht.nodes->GetRandomNodeExcluding(peer, exclude)) - { - dht.LookupTagRecursive(N, From, T, peer, R - 1); - } - else - { - replies.emplace_back(new GotIntroMessage({}, T)); - } - } - else - { - // too big R value - replies.emplace_back(new GotIntroMessage({}, T)); - } - } - } - return true; - } - } // namespace dht -} // namespace llarp diff --git a/llarp/dht/find_router.cpp b/llarp/dht/find_router.cpp deleted file mode 100644 index 88643d664..000000000 --- a/llarp/dht/find_router.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include - -#include -#include -#include -#include - -namespace llarp -{ - namespace dht - { - bool - RelayedFindRouterMessage::HandleMessage( - llarp_dht_context *ctx, - std::vector< std::unique_ptr< IMessage > > &replies) const - { - auto &dht = ctx->impl; - /// lookup for us, send an immeidate reply - Key_t us = dht.OurKey(); - Key_t k{K}; - if(K == us) - { - auto path = dht.router->paths.GetByUpstream(K, pathID); - if(path) - { - replies.emplace_back( - new GotRouterMessage(k, txid, {dht.router->rc()}, false)); - return true; - } - return false; - } - - Key_t peer; - // check if we know this in our nodedb first - RouterContact found; - if(dht.router->nodedb->Get(K, found)) - { - replies.emplace_back(new GotRouterMessage(k, txid, {found}, false)); - return true; - } - // lookup if we don't have it in our nodedb - if(dht.nodes->FindClosest(k, peer)) - dht.LookupRouterForPath(K, txid, pathID, peer); - return true; - } - - FindRouterMessage::~FindRouterMessage() - { - } - - bool - FindRouterMessage::BEncode(llarp_buffer_t *buf) const - { - if(!bencode_start_dict(buf)) - return false; - - // message type - if(!bencode_write_bytestring(buf, "A", 1)) - return false; - if(!bencode_write_bytestring(buf, "R", 1)) - return false; - - // exploritory or not? - if(!bencode_write_bytestring(buf, "E", 1)) - return false; - if(!bencode_write_uint64(buf, exploritory ? 1 : 0)) - return false; - - // iterative or not? - if(!bencode_write_bytestring(buf, "I", 1)) - return false; - if(!bencode_write_uint64(buf, iterative ? 1 : 0)) - return false; - - // key - if(!bencode_write_bytestring(buf, "K", 1)) - return false; - if(!bencode_write_bytestring(buf, K.data(), K.size())) - return false; - - // txid - if(!bencode_write_bytestring(buf, "T", 1)) - return false; - if(!bencode_write_uint64(buf, txid)) - return false; - - // version - if(!bencode_write_bytestring(buf, "V", 1)) - return false; - if(!bencode_write_uint64(buf, version)) - return false; - - return bencode_end(buf); - } - - bool - FindRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val) - { - llarp_buffer_t strbuf; - - if(llarp_buffer_eq(key, "E")) - { - uint64_t result; - if(!bencode_read_integer(val, &result)) - return false; - - exploritory = result != 0; - return true; - } - - if(llarp_buffer_eq(key, "I")) - { - uint64_t result; - if(!bencode_read_integer(val, &result)) - return false; - - iterative = result != 0; - return true; - } - if(llarp_buffer_eq(key, "K")) - { - if(!bencode_read_string(val, &strbuf)) - return false; - if(strbuf.sz != K.size()) - return false; - - std::copy(strbuf.base, strbuf.base + K.SIZE, K.begin()); - return true; - } - if(llarp_buffer_eq(key, "T")) - { - return bencode_read_integer(val, &txid); - } - if(llarp_buffer_eq(key, "V")) - { - return bencode_read_integer(val, &version); - } - return false; - } - - bool - FindRouterMessage::HandleMessage( - llarp_dht_context *ctx, - std::vector< std::unique_ptr< IMessage > > &replies) const - { - auto &dht = ctx->impl; - if(!dht.allowTransit) - { - llarp::LogWarn("Got DHT lookup from ", From, - " when we are not allowing dht transit"); - return false; - } - if(dht.pendingRouterLookups.HasPendingLookupFrom({From, txid})) - { - llarp::LogWarn("Duplicate FRM from ", From, " txid=", txid); - return false; - } - RouterContact found; - Key_t k{K}; - if(exploritory) - return dht.HandleExploritoryRouterLookup(From, txid, K, replies); - else if(dht.router->nodedb->Get(K, found)) - { - replies.emplace_back(new GotRouterMessage(k, txid, {found}, false)); - return true; - } - else - dht.LookupRouterRelayed(From, txid, k, !iterative, replies); - return true; - } - } // namespace dht -} // namespace llarp diff --git a/llarp/dht/got_intro.cpp b/llarp/dht/got_intro.cpp deleted file mode 100644 index c60a4d28c..000000000 --- a/llarp/dht/got_intro.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include - -namespace llarp -{ - namespace dht - { - GotIntroMessage::GotIntroMessage( - const std::vector< llarp::service::IntroSet > &results, uint64_t tx) - : IMessage({}), I(results), T(tx) - { - } - - GotIntroMessage::~GotIntroMessage() - { - } - - bool - GotIntroMessage::HandleMessage( - llarp_dht_context *ctx, - __attribute__((unused)) - std::vector< std::unique_ptr< IMessage > > &replies) const - { - auto &dht = ctx->impl; - auto crypto = &dht.router->crypto; - - for(const auto &introset : I) - { - if(!introset.Verify(crypto, dht.Now())) - { - llarp::LogWarn( - "Invalid introset while handling direct GotIntro " - "from ", - From); - return false; - } - } - TXOwner owner(From, T); - auto tagLookup = dht.pendingTagLookups.GetPendingLookupFrom(owner); - if(tagLookup) - { - dht.pendingTagLookups.Found(owner, tagLookup->target, I); - return true; - } - auto serviceLookup = - dht.pendingIntrosetLookups.GetPendingLookupFrom(owner); - if(serviceLookup) - { - if(I.size()) - { - dht.pendingIntrosetLookups.Found(owner, serviceLookup->target, I); - } - else - { - dht.pendingIntrosetLookups.NotFound(owner, K); - } - return true; - } - llarp::LogError("no pending TX for GIM from ", From, " txid=", T); - return false; - } - - bool - RelayedGotIntroMessage::HandleMessage( - llarp_dht_context *ctx, - __attribute__((unused)) - std::vector< std::unique_ptr< IMessage > > &replies) const - { - // TODO: implement me better? - auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID); - if(pathset) - { - return pathset->HandleGotIntroMessage(this); - } - llarp::LogWarn("No path for got intro message pathid=", pathID); - return false; - } - - bool - GotIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf) - { - if(llarp_buffer_eq(key, "I")) - { - return BEncodeReadList(I, buf); - } - if(llarp_buffer_eq(key, "K")) - { - if(K) // duplicate key? - return false; - K.reset(new dht::Key_t()); - return K->BDecode(buf); - } - bool read = false; - if(!BEncodeMaybeReadDictInt("T", T, read, key, buf)) - return false; - if(!BEncodeMaybeReadDictInt("V", version, read, key, buf)) - return false; - return read; - } - - bool - GotIntroMessage::BEncode(llarp_buffer_t *buf) const - { - if(!bencode_start_dict(buf)) - return false; - if(!BEncodeWriteDictMsgType(buf, "A", "G")) - return false; - if(!BEncodeWriteDictList("I", I, buf)) - return false; - if(K) - { - if(!BEncodeWriteDictEntry("K", *K.get(), buf)) - return false; - } - if(!BEncodeWriteDictInt("T", T, buf)) - return false; - if(!BEncodeWriteDictInt("V", version, buf)) - return false; - return bencode_end(buf); - } - } // namespace dht -} // namespace llarp diff --git a/llarp/dht/got_router.cpp b/llarp/dht/got_router.cpp deleted file mode 100644 index 60fa5d1f7..000000000 --- a/llarp/dht/got_router.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include -#include - -#include - -namespace llarp -{ - namespace dht - { - GotRouterMessage::~GotRouterMessage() - { - } - - bool - GotRouterMessage::BEncode(llarp_buffer_t *buf) const - { - if(!bencode_start_dict(buf)) - return false; - - // message type - if(!BEncodeWriteDictMsgType(buf, "A", "S")) - return false; - - if(K) - { - if(!BEncodeWriteDictEntry("K", *K.get(), buf)) - return false; - } - - // near - if(N.size()) - { - if(!BEncodeWriteDictList("N", N, buf)) - return false; - } - - if(!BEncodeWriteDictList("R", R, buf)) - return false; - - // txid - if(!BEncodeWriteDictInt("T", txid, buf)) - return false; - - // version - if(!BEncodeWriteDictInt("V", version, buf)) - return false; - - return bencode_end(buf); - } - - bool - GotRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val) - { - if(llarp_buffer_eq(key, "K")) - { - if(K) // duplicate key? - return false; - K.reset(new dht::Key_t()); - return K->BDecode(val); - } - if(llarp_buffer_eq(key, "N")) - { - return BEncodeReadList(N, val); - } - if(llarp_buffer_eq(key, "R")) - { - return BEncodeReadList(R, val); - } - if(llarp_buffer_eq(key, "T")) - { - return bencode_read_integer(val, &txid); - } - bool read = false; - if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, key, - val)) - return false; - - return read; - } - - bool - GotRouterMessage::HandleMessage( - llarp_dht_context *ctx, - __attribute__((unused)) - std::vector< std::unique_ptr< IMessage > > &replies) const - { - auto &dht = ctx->impl; - if(relayed) - { - auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID); - return pathset && pathset->HandleGotRouterMessage(this); - } - // not relayed - TXOwner owner(From, txid); - - if(dht.pendingExploreLookups.HasPendingLookupFrom(owner)) - { - if(N.size() == 0) - dht.pendingExploreLookups.NotFound(owner, K); - else - { - dht.pendingExploreLookups.Found(owner, From.as_array(), N); - } - return true; - } - // not explore lookup - - if(!dht.pendingRouterLookups.HasPendingLookupFrom(owner)) - { - llarp::LogWarn("Unwarrented GRM from ", From, " txid=", txid); - return false; - } - // no pending lookup - - llarp::LogInfo("DHT no pending lookup"); - if(R.size() == 1) - dht.pendingRouterLookups.Found(owner, R[0].pubkey, {R[0]}); - else - dht.pendingRouterLookups.NotFound(owner, K); - return true; - } - } // namespace dht -} // namespace llarp diff --git a/llarp/dht/messages/all.cpp b/llarp/dht/messages/all.cpp deleted file mode 100644 index ea40fc3f8..000000000 --- a/llarp/dht/messages/all.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/llarp/dht/messages/all.hpp b/llarp/dht/messages/all.hpp deleted file mode 100644 index f8ac315ff..000000000 --- a/llarp/dht/messages/all.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef LLARP_DHT_MESSAGES_ALL_HPP -#define LLARP_DHT_MESSAGES_ALL_HPP -#include -#include -#include -#include -#include -#endif diff --git a/llarp/dht/messages/findintro.cpp b/llarp/dht/messages/findintro.cpp index 5c1805e09..441b3e466 100644 --- a/llarp/dht/messages/findintro.cpp +++ b/llarp/dht/messages/findintro.cpp @@ -1 +1,217 @@ +#include #include +#include +#include + +namespace llarp +{ + namespace dht + { + /* + struct IntroSetLookupInformer + { + llarp::Router* router; + service::Address target; + + void + SendReply(const llarp::routing::IMessage* msg) + { + } + }; + */ + + FindIntroMessage::~FindIntroMessage() + { + } + + bool + FindIntroMessage::DecodeKey(llarp_buffer_t k, llarp_buffer_t* val) + { + bool read = false; + + if(!BEncodeMaybeReadDictEntry("N", N, read, k, val)) + return false; + + if(!BEncodeMaybeReadDictInt("R", R, read, k, val)) + return false; + + if(!BEncodeMaybeReadDictEntry("S", S, read, k, val)) + return false; + + if(!BEncodeMaybeReadDictInt("T", T, read, k, val)) + return false; + + if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, k, + val)) + return false; + + return read; + } + + bool + FindIntroMessage::BEncode(llarp_buffer_t* buf) const + { + if(!bencode_start_dict(buf)) + return false; + + // message id + if(!BEncodeWriteDictMsgType(buf, "A", "F")) + return false; + if(N.Empty()) + { + // recursion + if(!BEncodeWriteDictInt("R", R, buf)) + return false; + // service address + if(!BEncodeWriteDictEntry("S", S, buf)) + return false; + } + else + { + if(!BEncodeWriteDictEntry("N", N, buf)) + return false; + // recursion + if(!BEncodeWriteDictInt("R", R, buf)) + return false; + } + // txid + if(!BEncodeWriteDictInt("T", T, buf)) + return false; + // protocol version + if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf)) + return false; + + return bencode_end(buf); + } + + bool + FindIntroMessage::HandleMessage( + llarp_dht_context* ctx, + std::vector< std::unique_ptr< IMessage > >& replies) const + { + if(R > 5) + { + llarp::LogError("R value too big, ", R, "> 5"); + return false; + } + auto& dht = ctx->impl; + if(dht.pendingIntrosetLookups.HasPendingLookupFrom(TXOwner{From, T})) + { + llarp::LogWarn("duplicate FIM from ", From, " txid=", T); + return false; + } + Key_t peer; + std::set< Key_t > exclude = {dht.OurKey(), From}; + if(N.Empty()) + { + llarp::LogInfo("lookup ", S.ToString()); + const auto introset = dht.GetIntroSetByServiceAddress(S); + if(introset) + { + service::IntroSet i = *introset; + replies.emplace_back(new GotIntroMessage({i}, T)); + return true; + } + else + { + if(R == 0) + { + // we don't have it + Key_t target = S.ToKey(); + Key_t closer; + // find closer peer + if(!dht.nodes->FindClosest(target, closer)) + return false; + if(relayed) + dht.LookupIntroSetForPath(S, T, pathID, closer); + else + replies.emplace_back(new GotIntroMessage(From, closer, T)); + return true; + } + else + { + Key_t us = dht.OurKey(); + Key_t target = S.ToKey(); + // we are recursive + if(dht.nodes->FindCloseExcluding(target, peer, exclude)) + { + if(relayed) + dht.LookupIntroSetForPath(S, T, pathID, peer); + else + { + if((us ^ target) < (peer ^ target)) + { + // we are not closer than our peer to the target so don't + // recurse farther + replies.emplace_back(new GotIntroMessage({}, T)); + return true; + } + else if(R > 0) + dht.LookupIntroSetRecursive(S, From, T, peer, R - 1); + else + dht.LookupIntroSetIterative(S, From, T, peer); + } + return true; + } + else + { + // no more closer peers + replies.emplace_back(new GotIntroMessage({}, T)); + return true; + } + } + } + } + else + { + if(relayed) + { + // tag lookup + if(dht.nodes->GetRandomNodeExcluding(peer, exclude)) + { + dht.LookupTagForPath(N, T, pathID, peer); + } + else + { + // no more closer peers + replies.emplace_back(new GotIntroMessage({}, T)); + return true; + } + } + else + { + if(R == 0) + { + // base case + auto introsets = dht.FindRandomIntroSetsWithTagExcluding(N, 2, {}); + std::vector< service::IntroSet > reply; + for(const auto& introset : introsets) + { + reply.push_back(introset); + } + replies.emplace_back(new GotIntroMessage(reply, T)); + return true; + } + else if(R < 5) + { + // tag lookup + if(dht.nodes->GetRandomNodeExcluding(peer, exclude)) + { + dht.LookupTagRecursive(N, From, T, peer, R - 1); + } + else + { + replies.emplace_back(new GotIntroMessage({}, T)); + } + } + else + { + // too big R value + replies.emplace_back(new GotIntroMessage({}, T)); + } + } + } + return true; + } + } // namespace dht +} // namespace llarp diff --git a/llarp/dht/messages/findrouter.cpp b/llarp/dht/messages/findrouter.cpp index f9019d2bd..88643d664 100644 --- a/llarp/dht/messages/findrouter.cpp +++ b/llarp/dht/messages/findrouter.cpp @@ -1 +1,172 @@ #include + +#include +#include +#include +#include + +namespace llarp +{ + namespace dht + { + bool + RelayedFindRouterMessage::HandleMessage( + llarp_dht_context *ctx, + std::vector< std::unique_ptr< IMessage > > &replies) const + { + auto &dht = ctx->impl; + /// lookup for us, send an immeidate reply + Key_t us = dht.OurKey(); + Key_t k{K}; + if(K == us) + { + auto path = dht.router->paths.GetByUpstream(K, pathID); + if(path) + { + replies.emplace_back( + new GotRouterMessage(k, txid, {dht.router->rc()}, false)); + return true; + } + return false; + } + + Key_t peer; + // check if we know this in our nodedb first + RouterContact found; + if(dht.router->nodedb->Get(K, found)) + { + replies.emplace_back(new GotRouterMessage(k, txid, {found}, false)); + return true; + } + // lookup if we don't have it in our nodedb + if(dht.nodes->FindClosest(k, peer)) + dht.LookupRouterForPath(K, txid, pathID, peer); + return true; + } + + FindRouterMessage::~FindRouterMessage() + { + } + + bool + FindRouterMessage::BEncode(llarp_buffer_t *buf) const + { + if(!bencode_start_dict(buf)) + return false; + + // message type + if(!bencode_write_bytestring(buf, "A", 1)) + return false; + if(!bencode_write_bytestring(buf, "R", 1)) + return false; + + // exploritory or not? + if(!bencode_write_bytestring(buf, "E", 1)) + return false; + if(!bencode_write_uint64(buf, exploritory ? 1 : 0)) + return false; + + // iterative or not? + if(!bencode_write_bytestring(buf, "I", 1)) + return false; + if(!bencode_write_uint64(buf, iterative ? 1 : 0)) + return false; + + // key + if(!bencode_write_bytestring(buf, "K", 1)) + return false; + if(!bencode_write_bytestring(buf, K.data(), K.size())) + return false; + + // txid + if(!bencode_write_bytestring(buf, "T", 1)) + return false; + if(!bencode_write_uint64(buf, txid)) + return false; + + // version + if(!bencode_write_bytestring(buf, "V", 1)) + return false; + if(!bencode_write_uint64(buf, version)) + return false; + + return bencode_end(buf); + } + + bool + FindRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val) + { + llarp_buffer_t strbuf; + + if(llarp_buffer_eq(key, "E")) + { + uint64_t result; + if(!bencode_read_integer(val, &result)) + return false; + + exploritory = result != 0; + return true; + } + + if(llarp_buffer_eq(key, "I")) + { + uint64_t result; + if(!bencode_read_integer(val, &result)) + return false; + + iterative = result != 0; + return true; + } + if(llarp_buffer_eq(key, "K")) + { + if(!bencode_read_string(val, &strbuf)) + return false; + if(strbuf.sz != K.size()) + return false; + + std::copy(strbuf.base, strbuf.base + K.SIZE, K.begin()); + return true; + } + if(llarp_buffer_eq(key, "T")) + { + return bencode_read_integer(val, &txid); + } + if(llarp_buffer_eq(key, "V")) + { + return bencode_read_integer(val, &version); + } + return false; + } + + bool + FindRouterMessage::HandleMessage( + llarp_dht_context *ctx, + std::vector< std::unique_ptr< IMessage > > &replies) const + { + auto &dht = ctx->impl; + if(!dht.allowTransit) + { + llarp::LogWarn("Got DHT lookup from ", From, + " when we are not allowing dht transit"); + return false; + } + if(dht.pendingRouterLookups.HasPendingLookupFrom({From, txid})) + { + llarp::LogWarn("Duplicate FRM from ", From, " txid=", txid); + return false; + } + RouterContact found; + Key_t k{K}; + if(exploritory) + return dht.HandleExploritoryRouterLookup(From, txid, K, replies); + else if(dht.router->nodedb->Get(K, found)) + { + replies.emplace_back(new GotRouterMessage(k, txid, {found}, false)); + return true; + } + else + dht.LookupRouterRelayed(From, txid, k, !iterative, replies); + return true; + } + } // namespace dht +} // namespace llarp diff --git a/llarp/dht/messages/gotintro.cpp b/llarp/dht/messages/gotintro.cpp index 3024f84a8..d32653a7f 100644 --- a/llarp/dht/messages/gotintro.cpp +++ b/llarp/dht/messages/gotintro.cpp @@ -1 +1,125 @@ #include + +#include +#include +#include + +namespace llarp +{ + namespace dht + { + GotIntroMessage::GotIntroMessage( + const std::vector< llarp::service::IntroSet > &results, uint64_t tx) + : IMessage({}), I(results), T(tx) + { + } + + GotIntroMessage::~GotIntroMessage() + { + } + + bool + GotIntroMessage::HandleMessage( + llarp_dht_context *ctx, + __attribute__((unused)) + std::vector< std::unique_ptr< IMessage > > &replies) const + { + auto &dht = ctx->impl; + auto crypto = &dht.router->crypto; + + for(const auto &introset : I) + { + if(!introset.Verify(crypto, dht.Now())) + { + llarp::LogWarn( + "Invalid introset while handling direct GotIntro " + "from ", + From); + return false; + } + } + TXOwner owner(From, T); + auto tagLookup = dht.pendingTagLookups.GetPendingLookupFrom(owner); + if(tagLookup) + { + dht.pendingTagLookups.Found(owner, tagLookup->target, I); + return true; + } + auto serviceLookup = + dht.pendingIntrosetLookups.GetPendingLookupFrom(owner); + if(serviceLookup) + { + if(I.size()) + { + dht.pendingIntrosetLookups.Found(owner, serviceLookup->target, I); + } + else + { + dht.pendingIntrosetLookups.NotFound(owner, K); + } + return true; + } + llarp::LogError("no pending TX for GIM from ", From, " txid=", T); + return false; + } + + bool + RelayedGotIntroMessage::HandleMessage( + llarp_dht_context *ctx, + __attribute__((unused)) + std::vector< std::unique_ptr< IMessage > > &replies) const + { + // TODO: implement me better? + auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID); + if(pathset) + { + return pathset->HandleGotIntroMessage(this); + } + llarp::LogWarn("No path for got intro message pathid=", pathID); + return false; + } + + bool + GotIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf) + { + if(llarp_buffer_eq(key, "I")) + { + return BEncodeReadList(I, buf); + } + if(llarp_buffer_eq(key, "K")) + { + if(K) // duplicate key? + return false; + K.reset(new dht::Key_t()); + return K->BDecode(buf); + } + bool read = false; + if(!BEncodeMaybeReadDictInt("T", T, read, key, buf)) + return false; + if(!BEncodeMaybeReadDictInt("V", version, read, key, buf)) + return false; + return read; + } + + bool + GotIntroMessage::BEncode(llarp_buffer_t *buf) const + { + if(!bencode_start_dict(buf)) + return false; + if(!BEncodeWriteDictMsgType(buf, "A", "G")) + return false; + if(!BEncodeWriteDictList("I", I, buf)) + return false; + if(K) + { + if(!BEncodeWriteDictEntry("K", *K.get(), buf)) + return false; + } + if(!BEncodeWriteDictInt("T", T, buf)) + return false; + if(!BEncodeWriteDictInt("V", version, buf)) + return false; + return bencode_end(buf); + } + } // namespace dht +} // namespace llarp diff --git a/llarp/dht/messages/gotrouter.cpp b/llarp/dht/messages/gotrouter.cpp index 6632ef521..60fa5d1f7 100644 --- a/llarp/dht/messages/gotrouter.cpp +++ b/llarp/dht/messages/gotrouter.cpp @@ -1 +1,123 @@ +#include #include + +#include + +namespace llarp +{ + namespace dht + { + GotRouterMessage::~GotRouterMessage() + { + } + + bool + GotRouterMessage::BEncode(llarp_buffer_t *buf) const + { + if(!bencode_start_dict(buf)) + return false; + + // message type + if(!BEncodeWriteDictMsgType(buf, "A", "S")) + return false; + + if(K) + { + if(!BEncodeWriteDictEntry("K", *K.get(), buf)) + return false; + } + + // near + if(N.size()) + { + if(!BEncodeWriteDictList("N", N, buf)) + return false; + } + + if(!BEncodeWriteDictList("R", R, buf)) + return false; + + // txid + if(!BEncodeWriteDictInt("T", txid, buf)) + return false; + + // version + if(!BEncodeWriteDictInt("V", version, buf)) + return false; + + return bencode_end(buf); + } + + bool + GotRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val) + { + if(llarp_buffer_eq(key, "K")) + { + if(K) // duplicate key? + return false; + K.reset(new dht::Key_t()); + return K->BDecode(val); + } + if(llarp_buffer_eq(key, "N")) + { + return BEncodeReadList(N, val); + } + if(llarp_buffer_eq(key, "R")) + { + return BEncodeReadList(R, val); + } + if(llarp_buffer_eq(key, "T")) + { + return bencode_read_integer(val, &txid); + } + bool read = false; + if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, key, + val)) + return false; + + return read; + } + + bool + GotRouterMessage::HandleMessage( + llarp_dht_context *ctx, + __attribute__((unused)) + std::vector< std::unique_ptr< IMessage > > &replies) const + { + auto &dht = ctx->impl; + if(relayed) + { + auto pathset = ctx->impl.router->paths.GetLocalPathSet(pathID); + return pathset && pathset->HandleGotRouterMessage(this); + } + // not relayed + TXOwner owner(From, txid); + + if(dht.pendingExploreLookups.HasPendingLookupFrom(owner)) + { + if(N.size() == 0) + dht.pendingExploreLookups.NotFound(owner, K); + else + { + dht.pendingExploreLookups.Found(owner, From.as_array(), N); + } + return true; + } + // not explore lookup + + if(!dht.pendingRouterLookups.HasPendingLookupFrom(owner)) + { + llarp::LogWarn("Unwarrented GRM from ", From, " txid=", txid); + return false; + } + // no pending lookup + + llarp::LogInfo("DHT no pending lookup"); + if(R.size() == 1) + dht.pendingRouterLookups.Found(owner, R[0].pubkey, {R[0]}); + else + dht.pendingRouterLookups.NotFound(owner, K); + return true; + } + } // namespace dht +} // namespace llarp diff --git a/llarp/dht/messages/pubintro.cpp b/llarp/dht/messages/pubintro.cpp index cf561872d..d78f184f5 100644 --- a/llarp/dht/messages/pubintro.cpp +++ b/llarp/dht/messages/pubintro.cpp @@ -1 +1,121 @@ #include + +#include +#include +#include +#include +#include + +namespace llarp +{ + namespace dht + { + PublishIntroMessage::~PublishIntroMessage() + { + } + + bool + PublishIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val) + { + bool read = false; + if(llarp_buffer_eq(key, "E")) + { + return BEncodeReadList(E, val); + } + if(!BEncodeMaybeReadDictEntry("I", I, read, key, val)) + return false; + if(!BEncodeMaybeReadDictInt("R", R, read, key, val)) + return false; + if(llarp_buffer_eq(key, "S")) + { + read = true; + hasS = true; + if(!bencode_read_integer(val, &S)) + return false; + } + if(!BEncodeMaybeReadDictInt("T", txID, read, key, val)) + return false; + if(!BEncodeMaybeReadDictInt("V", version, read, key, val)) + return false; + return read; + } + + bool + PublishIntroMessage::HandleMessage( + llarp_dht_context *ctx, + std::vector< std::unique_ptr< IMessage > > &replies) const + { + auto now = ctx->impl.Now(); + if(S > 5) + { + llarp::LogWarn("invalid S value ", S, " > 5"); + return false; + } + auto &dht = ctx->impl; + if(!I.Verify(&dht.router->crypto, now)) + { + llarp::LogWarn("invalid introset: ", I); + // don't propogate or store + replies.emplace_back(new GotIntroMessage({}, txID)); + return true; + } + if(I.W && !I.W->IsValid(dht.router->crypto.shorthash, now)) + { + llarp::LogWarn("proof of work not good enough for IntroSet"); + // don't propogate or store + replies.emplace_back(new GotIntroMessage({}, txID)); + return true; + } + llarp::dht::Key_t addr; + if(!I.A.CalculateAddress(addr.as_array())) + { + llarp::LogWarn( + "failed to calculate hidden service address for PubIntro message"); + return false; + } + + now += llarp::service::MAX_INTROSET_TIME_DELTA; + if(I.IsExpired(now)) + { + // don't propogate or store + replies.emplace_back(new GotIntroMessage({}, txID)); + return true; + } + dht.services->PutNode(I); + replies.emplace_back(new GotIntroMessage({I}, txID)); + Key_t peer; + std::set< Key_t > exclude; + for(const auto &e : E) + exclude.insert(e); + exclude.insert(From); + exclude.insert(dht.OurKey()); + if(S && dht.nodes->FindCloseExcluding(addr, peer, exclude)) + { + dht.PropagateIntroSetTo(From, txID, I, peer, S - 1, exclude); + } + return true; + } + + bool + PublishIntroMessage::BEncode(llarp_buffer_t *buf) const + { + if(!bencode_start_dict(buf)) + return false; + if(!BEncodeWriteDictMsgType(buf, "A", "I")) + return false; + if(!BEncodeWriteDictList("E", E, buf)) + return false; + if(!BEncodeWriteDictEntry("I", I, buf)) + return false; + if(!BEncodeWriteDictInt("R", R, buf)) + return false; + if(!BEncodeWriteDictInt("S", S, buf)) + return false; + if(!BEncodeWriteDictInt("T", txID, buf)) + return false; + if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf)) + return false; + return bencode_end(buf); + } + } // namespace dht +} // namespace llarp diff --git a/llarp/dht/publish_intro.cpp b/llarp/dht/publish_intro.cpp deleted file mode 100644 index e49a12e60..000000000 --- a/llarp/dht/publish_intro.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include -#include - -namespace llarp -{ - namespace dht - { - PublishIntroMessage::~PublishIntroMessage() - { - } - - bool - PublishIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val) - { - bool read = false; - if(llarp_buffer_eq(key, "E")) - { - return BEncodeReadList(E, val); - } - if(!BEncodeMaybeReadDictEntry("I", I, read, key, val)) - return false; - if(!BEncodeMaybeReadDictInt("R", R, read, key, val)) - return false; - if(llarp_buffer_eq(key, "S")) - { - read = true; - hasS = true; - if(!bencode_read_integer(val, &S)) - return false; - } - if(!BEncodeMaybeReadDictInt("T", txID, read, key, val)) - return false; - if(!BEncodeMaybeReadDictInt("V", version, read, key, val)) - return false; - return read; - } - - bool - PublishIntroMessage::HandleMessage( - llarp_dht_context *ctx, - std::vector< std::unique_ptr< IMessage > > &replies) const - { - auto now = ctx->impl.Now(); - if(S > 5) - { - llarp::LogWarn("invalid S value ", S, " > 5"); - return false; - } - auto &dht = ctx->impl; - if(!I.Verify(&dht.router->crypto, now)) - { - llarp::LogWarn("invalid introset: ", I); - // don't propogate or store - replies.emplace_back(new GotIntroMessage({}, txID)); - return true; - } - if(I.W && !I.W->IsValid(dht.router->crypto.shorthash, now)) - { - llarp::LogWarn("proof of work not good enough for IntroSet"); - // don't propogate or store - replies.emplace_back(new GotIntroMessage({}, txID)); - return true; - } - llarp::dht::Key_t addr; - if(!I.A.CalculateAddress(addr.as_array())) - { - llarp::LogWarn( - "failed to calculate hidden service address for PubIntro message"); - return false; - } - - now += llarp::service::MAX_INTROSET_TIME_DELTA; - if(I.IsExpired(now)) - { - // don't propogate or store - replies.emplace_back(new GotIntroMessage({}, txID)); - return true; - } - dht.services->PutNode(I); - replies.emplace_back(new GotIntroMessage({I}, txID)); - Key_t peer; - std::set< Key_t > exclude; - for(const auto &e : E) - exclude.insert(e); - exclude.insert(From); - exclude.insert(dht.OurKey()); - if(S && dht.nodes->FindCloseExcluding(addr, peer, exclude)) - { - dht.PropagateIntroSetTo(From, txID, I, peer, S - 1, exclude); - } - return true; - } - - bool - PublishIntroMessage::BEncode(llarp_buffer_t *buf) const - { - if(!bencode_start_dict(buf)) - return false; - if(!BEncodeWriteDictMsgType(buf, "A", "I")) - return false; - if(!BEncodeWriteDictList("E", E, buf)) - return false; - if(!BEncodeWriteDictEntry("I", I, buf)) - return false; - if(!BEncodeWriteDictInt("R", R, buf)) - return false; - if(!BEncodeWriteDictInt("S", S, buf)) - return false; - if(!BEncodeWriteDictInt("T", txID, buf)) - return false; - if(!BEncodeWriteDictInt("V", LLARP_PROTO_VERSION, buf)) - return false; - return bencode_end(buf); - } - } // namespace dht -} // namespace llarp diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 1dc30ead0..5430f9e2d 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -1,4 +1,5 @@ #include + #include #include @@ -85,7 +86,7 @@ namespace llarp if(p->SendExitRequest(&obtain, router)) llarp::LogInfo("asking ", m_ExitRouter, " for exit"); else - llarp::LogError("faild to send exit request"); + llarp::LogError("failed to send exit request"); } bool diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index 2e31a4012..281fcd966 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -4,6 +4,8 @@ #include #include +struct llarp_dht_context; + namespace llarp { namespace path @@ -25,7 +27,7 @@ namespace llarp } llarp::Router* router; - struct llarp_dht_context* dht; + llarp_dht_context* dht; llarp::SecretKey enckey; size_t numHops; llarp_time_t lastBuild = 0; @@ -35,7 +37,7 @@ namespace llarp std::atomic< uint8_t > keygens; /// construct - Builder(llarp::Router* p_router, struct llarp_dht_context* p_dht, + Builder(llarp::Router* p_router, llarp_dht_context* p_dht, size_t numPaths, size_t numHops); virtual ~Builder(); diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index 13fe42a20..de6b216f8 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -1,7 +1,6 @@ #ifndef LLARP_PATHSET_HPP #define LLARP_PATHSET_HPP -#include #include #include #include @@ -18,10 +17,13 @@ struct llarp_nodedb; namespace llarp { + struct RouterContact; + namespace dht { struct GotIntroMessage; - } + struct GotRouterMessage; + } // namespace dht namespace path { @@ -34,12 +36,12 @@ namespace llarp ePathExpired }; - /// the role of this path can fuffill + /// the role of this path can fulfill using PathRole = int; /// capable of any role constexpr PathRole ePathRoleAny = 0; - /// outbound hs traffic capabale + /// outbound hs traffic capable constexpr PathRole ePathRoleOutboundHS = (1 << 0); /// inbound hs traffic capable constexpr PathRole ePathRoleInboundHS = (1 << 1); diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 2eb0dbdbd..ff780700c 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1,6 +1,10 @@ #include #include +#include +#include +#include +#include #include #include #include @@ -1688,7 +1692,7 @@ namespace llarp if(markedBad) return false; bool should = path::Builder::ShouldBuildMore(now); - // determinte newest intro + // determine newest intro Introduction intro; if(!GetNewestIntro(intro)) return should;