diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 8105b5c10..3d6f09d94 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -139,7 +139,7 @@ namespace llarp LinkManager::register_commands(std::shared_ptr& s) { assert(ep.connid_map.count(s->conn_id())); - RouterID rid = ep.connid_map[s->conn_id()]; + const RouterID& rid = ep.connid_map[s->conn_id()]; s->register_command("path_build"s, [this, rid](oxen::quic::message m) { _router.loop()->call( @@ -611,7 +611,8 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - respond(serialize_response({{messages::STATUS_KEY, FindRouterMessage::EXCEPTION}, {"TARGET", ""}})); + respond(serialize_response( + {{messages::STATUS_KEY, FindRouterMessage::EXCEPTION}, {"TARGET", ""}})); return; } @@ -641,8 +642,8 @@ namespace llarp neighbors += rid.bt_encode(); } - respond( - serialize_response({{messages::STATUS_KEY, FindRouterMessage::RETRY_EXP}, {"TARGET", neighbors}})); + respond(serialize_response( + {{messages::STATUS_KEY, FindRouterMessage::RETRY_EXP}, {"TARGET", neighbors}})); } else { @@ -1144,7 +1145,8 @@ namespace llarp shared.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data())) { log::info(link_cat, "DH server initialization failed during path build"); - m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); + m.respond( + serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } @@ -1157,14 +1159,16 @@ namespace llarp shared)) { log::error(link_cat, "HMAC failed on path build request"); - m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); + m.respond( + serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } if (!std::equal( digest.begin(), digest.end(), reinterpret_cast(hash.data()))) { log::info(link_cat, "HMAC mismatch on path build request"); - m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); + m.respond( + serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } @@ -1176,7 +1180,8 @@ namespace llarp outer_nonce.data())) { log::info(link_cat, "Decrypt failed on path build request"); - m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); + m.respond( + serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } @@ -1237,7 +1242,7 @@ namespace llarp // generate hash of hop key for nonce mutation ShortHash xor_hash; crypto::shorthash(xor_hash, hop->pathKey.data(), hop->pathKey.size()); - hop->nonceXOR = xor_hash.data(); // nonceXOR is 24 bytes, ShortHash is 32; this will truncate + hop->nonceXOR = xor_hash.data(); // nonceXOR is 24 bytes, ShortHash is 32; this will truncate // set and check path lifetime hop->lifetime = 1ms * lifetime; @@ -1245,7 +1250,8 @@ namespace llarp if (hop->lifetime >= path::DEFAULT_LIFETIME) { log::warning(link_cat, "Path build attempt with too long of a lifetime."); - m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_LIFETIME}}), true); + m.respond( + serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_LIFETIME}}), true); return; } @@ -1501,7 +1507,9 @@ namespace llarp { (exit_ep->UpdateLocalPath(transit_hop->info.rxID)) ? m.respond(UpdateExitMessage::sign_and_serialize_response(_router.identity(), tx_id)) - : m.respond(serialize_response({{messages::STATUS_KEY, UpdateExitMessage::UPDATE_FAILED}}), true); + : m.respond( + serialize_response({{messages::STATUS_KEY, UpdateExitMessage::UPDATE_FAILED}}), + true); } // If we fail to verify the message, no-op } @@ -1588,7 +1596,8 @@ namespace llarp } } - m.respond(serialize_response({{messages::STATUS_KEY, CloseExitMessage::UPDATE_FAILED}}), true); + m.respond( + serialize_response({{messages::STATUS_KEY, CloseExitMessage::UPDATE_FAILED}}), true); } catch (const std::exception& e) { diff --git a/llarp/messages/common.hpp b/llarp/messages/common.hpp index da08cd60f..ee9a336b7 100644 --- a/llarp/messages/common.hpp +++ b/llarp/messages/common.hpp @@ -28,13 +28,10 @@ namespace llarp } // ideally STATUS is the first key in a bt-dict, so use a single, early ascii char - inline auto STATUS_KEY = "!"s; - inline auto STATUS_OK = "OK"sv; - inline auto STATUS_TIMEOUT = "TIMEOUT"sv; - inline auto STATUS_ERROR = "ERROR"sv; // generic, unknown error (e.g. onion decrypt throw) - inline auto TIMEOUT_BT_DICT = serialize_response({{STATUS_KEY, STATUS_TIMEOUT}}); - inline auto ERROR_BT_DICT = serialize_response({{STATUS_KEY, STATUS_ERROR}}); - } // namespace llarp::messages + inline const auto STATUS_KEY = "!"s; + inline const auto TIMEOUT_BT_DICT = serialize_response({{STATUS_KEY, "TIMEOUT"}}); + inline const auto ERROR_BT_DICT = serialize_response({{STATUS_KEY, "ERROR"}}); + } // namespace messages /// abstract base class for serialized messages struct AbstractSerializable diff --git a/llarp/messages/path.hpp b/llarp/messages/path.hpp index ff0bccc04..65e6f7d00 100644 --- a/llarp/messages/path.hpp +++ b/llarp/messages/path.hpp @@ -31,7 +31,7 @@ namespace llarp // generate nonceXOR value self->hop->pathKey ShortHash hash; crypto::shorthash(hash, hop.shared.data(), hop.shared.size()); - hop.nonceXOR = hash.data(); // nonceXOR is 24 bytes, ShortHash is 32; this will truncate + hop.nonceXOR = hash.data(); // nonceXOR is 24 bytes, ShortHash is 32; this will truncate hop.upstream = nextHop; } diff --git a/llarp/path/abstracthophandler.hpp b/llarp/path/abstracthophandler.hpp index cf380955e..82f99ce15 100644 --- a/llarp/path/abstracthophandler.hpp +++ b/llarp/path/abstracthophandler.hpp @@ -1,6 +1,7 @@ #pragma once #include "path_types.hpp" + #include #include #include diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 8379646e5..fc07f02ee 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -231,7 +231,8 @@ namespace llarp::path void Path::EnterState(PathStatus st, llarp_time_t now) { - if (now == 0s) now = router.now(); + if (now == 0s) + now = router.now(); if (st == ePathFailed) { diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index 180ac95fb..3be47b7f9 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -31,8 +31,6 @@ namespace llarp struct TransitHopInfo; struct PathHopConfig; - using TransitHop_ptr = std::shared_ptr; - struct Ptr_hash; struct Endpoint_Hash; @@ -189,8 +187,7 @@ namespace llarp std::function func = nullptr); bool - close_exit( - SecretKey sk, std::string tx_id, std::function func = nullptr); + close_exit(SecretKey sk, std::string tx_id, std::function func = nullptr); bool obtain_exit( diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp index 1f717862e..a8e30a5a9 100644 --- a/llarp/path/path_context.cpp +++ b/llarp/path/path_context.cpp @@ -72,14 +72,23 @@ namespace llarp::path return _router->pubkey() == k; } - PathContext::EndpointPathPtrSet + std::vector> PathContext::FindOwnedPathsWithEndpoint(const RouterID& r) { - EndpointPathPtrSet found; + std::vector> found; for (const auto& [pathid, path] : own_paths) { + // each path is stored in this map twice, once for each pathid at the first hop + // This will make the output deduplicated without needing a std::set + // TODO: we should only need to map one pathid; as the path owner we only send/receive + // packets with the first hop's RXID; its TXID is for packets between it and hop 2. + // TODO: Also, perhaps we want a bit of data duplication here, e.g. a map from + // RouterID (terminal hop) to shared_ptr. + if (path->TXID() == pathid) + continue; + if (path->Endpoint() == r && path->IsReady()) - found.insert(path); + found.push_back(path); } return found; } @@ -147,7 +156,7 @@ namespace llarp::path return _router->pubkey(); } - TransitHop_ptr + std::shared_ptr PathContext::GetPathForTransfer(const PathID_t& id) { if (auto itr = transit_hops.find({OurRouterID(), id}); itr != transit_hops.end()) diff --git a/llarp/path/path_context.hpp b/llarp/path/path_context.hpp index 8d2242a23..3f6b4485c 100644 --- a/llarp/path/path_context.hpp +++ b/llarp/path/path_context.hpp @@ -40,12 +40,6 @@ namespace llarp namespace std { - inline bool - operator==(const llarp::path::TransitHopID& lhs, const llarp::path::TransitHopID& rhs) - { - return lhs.operator==(rhs); - } - template <> struct hash { @@ -59,8 +53,6 @@ namespace std namespace llarp::path { - using TransitHop_ptr = std::shared_ptr; - struct PathContext { explicit PathContext(Router* router); @@ -96,7 +88,7 @@ namespace llarp::path bool TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r); - TransitHop_ptr + std::shared_ptr GetPathForTransfer(const PathID_t& topath); std::shared_ptr @@ -105,9 +97,8 @@ namespace llarp::path PathSet_ptr GetLocalPathSet(const PathID_t& id); - using EndpointPathPtrSet = std::set>; /// get a set of all paths that we own who's endpoint is r - EndpointPathPtrSet + std::vector> FindOwnedPathsWithEndpoint(const RouterID& r); bool @@ -145,7 +136,7 @@ namespace llarp::path private: Router* _router; - std::unordered_map transit_hops; + std::unordered_map> transit_hops; std::unordered_map own_paths; bool m_AllowTransit; util::DecayingHashSet path_limits; diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index a3570a0ec..fc1697549 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -1,6 +1,5 @@ #include "pathbuilder.hpp" -#include "llarp/path/pathset.hpp" #include "path.hpp" #include "path_context.hpp" @@ -8,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -95,7 +95,7 @@ namespace llarp // generate nonceXOR value self->hop->pathKey ShortHash hash; crypto::shorthash(hash, hop.shared.data(), hop.shared.size()); - hop.nonceXOR = hash.data(); // nonceXOR is 24 bytes, ShortHash is 32; this will truncate + hop.nonceXOR = hash.data(); // nonceXOR is 24 bytes, ShortHash is 32; this will truncate hop.upstream = nextHop; } diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index 5f5ce26f7..1b1012448 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -1,4 +1,5 @@ #include "pathset.hpp" + #include "path.hpp" #include diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 603b163d7..42b8867ff 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -12,10 +12,8 @@ namespace llarp::path "[TransitHopInfo tx={} rx={} upstream={} downstream={}]", txID, rxID, upstream, downstream); } - TransitHop::TransitHop() - : AbstractHopHandler{} - { - } + TransitHop::TransitHop() : AbstractHopHandler{} + {} void TransitHop::onion(ustring& data, SymmNonce& nonce, bool randomize) const @@ -46,9 +44,11 @@ namespace llarp::path } bool - TransitHop::send_path_control_message( - std::string, std::string, std::function) + TransitHop::send_path_control_message(std::string, std::string, std::function) { + // TODO: if we want terminal/pivot hops to be able to *initiate* a request rather than + // simply responding/reacting to the client end's requests, this will need + // an implementation. return true; } diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 907cac76e..21422359a 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -138,9 +138,7 @@ namespace llarp /// a timeout flag (if set, response string will be empty) bool send_path_control_message( - std::string method, - std::string body, - std::function func) override; + std::string method, std::string body, std::function func) override; void QueueDestroySelf(Router* r); diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index a7f3c1231..6c0d7f181 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -172,11 +172,9 @@ namespace llarp::service if (poker) poker->put_up(); - - result_handler(true, result); } - result_handler(false, result); + result_handler(success, result); }; ctx->send_auth_async(apply_result); @@ -202,7 +200,9 @@ namespace llarp::service // If we fail along the way (e.g. it's a .snode, we can't build a path, or whatever else) then // we invoke the resultHandler with an empty vector. lookup_name( - name, [this, resultHandler, service = std::move(service)](std::string name_result, bool success) mutable { + name, + [this, resultHandler, service = std::move(service)]( + std::string name_result, bool success) mutable { if (!success) return resultHandler({}); @@ -823,20 +823,20 @@ namespace llarp::service { oxenc::bt_dict_consumer btdc{resp}; auto status = btdc.require(messages::STATUS_KEY); - if (status != messages::STATUS_OK) + if (status != "OK"sv) { log::info(link_cat, "Error on ONS lookup: {}", status); - func(""s, false); + func(std::string{status}, false); } name = btdc.require("NAME"); } catch (...) { log::warning(link_cat, "Failed to parse find name response!"); - func(""s, false); + func("ERROR"s, false); } - func(name, true); + func(std::move(name), true); }; for (const auto& path : chosenpaths) @@ -1357,40 +1357,39 @@ namespace llarp::service // TODO: if all requests fail, call callback with failure? for (const auto& path : paths) { - path->find_intro( - location, false, 0, [this, hook, got_it](std::string resp) mutable { - // asking many, use only first successful - if (*got_it) - return; + path->find_intro(location, false, 0, [this, hook, got_it](std::string resp) mutable { + // asking many, use only first successful + if (*got_it) + return; - std::string introset; + std::string introset; - try - { - oxenc::bt_dict_consumer btdc{resp}; - auto status = btdc.require(messages::STATUS_KEY); - if (status != messages::STATUS_OK) - { - log::info(link_cat, "Error in find intro set response: {}", status); - return; - } - introset = btdc.require("INTROSET"); - } - catch (...) - { - log::warning(link_cat, "Failed to parse find name response!"); - throw; - } + try + { + oxenc::bt_dict_consumer btdc{resp}; + auto status = btdc.require(messages::STATUS_KEY); + if (status != "OK"sv) + { + log::info(link_cat, "Error in find intro set response: {}", status); + return; + } + introset = btdc.require("INTROSET"); + } + catch (...) + { + log::warning(link_cat, "Failed to parse find name response!"); + throw; + } - service::EncryptedIntroSet enc{introset}; - router()->contacts()->services()->PutNode(std::move(enc)); + service::EncryptedIntroSet enc{introset}; + router()->contacts()->services()->PutNode(std::move(enc)); - // TODO: finish this - /* - if (good) - *got_it = true; - */ - }); + // TODO: finish this + /* + if (good) + *got_it = true; + */ + }); } return hookAdded; } diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index d05f5115c..9fbcfb476 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -189,7 +189,7 @@ namespace llarp::service { oxenc::bt_dict_consumer btdc{resp}; auto status = btdc.require(messages::STATUS_KEY); - if (status != messages::STATUS_OK) + if (status != "OK"sv) { log::info(link_cat, "Error in find intro set response: {}", status); return; diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index e6e49c413..0d9acf49c 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -302,7 +302,11 @@ namespace llarp::service // PKE (A, B, N) SharedSecret shared_secret; - if (!crypto::dh_server(shared_secret, self->msg->sender.EncryptionPublicKey(), self->m_LocalIdentity.enckey, self->frame.nonce)) + if (!crypto::dh_server( + shared_secret, + self->msg->sender.EncryptionPublicKey(), + self->m_LocalIdentity.enckey, + self->frame.nonce)) { LogError("x25519 key exchange failed"); Dump(self->frame);