From c25ced50a3c5b2563843f69ace304ae7a6e4c5c4 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Mon, 16 Oct 2023 22:04:47 -0400 Subject: [PATCH] path build message handling mostly finished there are a few TODOs which merit further discussion --- llarp/link/link_manager.cpp | 40 ++++++++++++++++++++++--------------- llarp/link/link_manager.hpp | 16 ++------------- llarp/path/path.cpp | 1 + llarp/path/pathbuilder.cpp | 39 +++++++++++++++++++++--------------- 4 files changed, 50 insertions(+), 46 deletions(-) diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index caa004a4e..4663c60e6 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -135,14 +135,21 @@ namespace llarp void LinkManager::register_commands(std::shared_ptr& s) { + assert(ep.connid_map.count(s->conn_id())); + RouterID rid = ep.connid_map[s->conn_id()]; for (const auto& [name, func] : rpc_commands) { - s->register_command(name, [this, f = func](oxen::quic::message m) { - _router.loop()->call([this, func = f, msg = std::move(m)]() mutable { + s->register_command(name, [this, func=func](oxen::quic::message m) { + _router.loop()->call([this, func, msg = std::move(m)]() mutable { std::invoke(func, this, std::move(msg)); }); }); } + + s->register_command("path_build"s, [this, rid](oxen::quic::message m) { + _router.loop()->call( + [this, &rid, msg = std::move(m)]() mutable { handle_path_build(std::move(msg), rid); }); + }); } std::shared_ptr @@ -971,13 +978,17 @@ namespace llarp log::info(link_cat, "PublishIntroMessage failed with error code: {}", payload); if (payload == PublishIntroMessage::INVALID_INTROSET) - {} + { + } else if (payload == PublishIntroMessage::EXPIRED) - {} + { + } else if (payload == PublishIntroMessage::INSUFFICIENT) - {} + { + } else if (payload == PublishIntroMessage::INVALID_ORDER) - {} + { + } } } @@ -1099,7 +1110,7 @@ namespace llarp } void - LinkManager::handle_path_build(oxen::quic::message m) + LinkManager::handle_path_build(oxen::quic::message m, const RouterID& from) { if (!_router.path_context().AllowingTransit()) { @@ -1192,12 +1203,9 @@ namespace llarp } // populate transit hop object with hop info - // TODO: how to get downstream hop RouterID from here (all we have is oxen::quic::message) - // could do message->btstream->stream->connection_interface->connectionid - // and check our mapping, but that feels ugly as sin (and message->stream is private) - // TODO: also need downstream for IP / path build limiting clients + // TODO: IP / path build limiting clients auto hop = std::make_shared(); - // hop->info.downstream = m.from(); // TODO: RouterID m.from() or similar + hop->info.downstream = from; // extract pathIDs and check if zero or used auto& hop_info = hop->info; @@ -1213,12 +1221,11 @@ namespace llarp hop_info.upstream.from_string(upstream); - // TODO: need downstream (above), and also the whole transit hop container is garbage. + // TODO: the whole transit hop container is garbage. // namely the PathID uniqueness checking uses the PathIDs and upstream/downstream // but if someone made a path with txid, rxid, and downstream the same but // a different upstream, that would be "unique" but we wouldn't know where - // to route messages (nevermind that messages don't currently know the RouterID - // they came from). + // to route messages. if (_router.path_context().HasTransitHop(hop_info)) { log::warning(link_cat, "Invalid PathID; PathIDs must be unique"); @@ -1547,7 +1554,8 @@ namespace llarp // see Path::HandleUpdateExitVerifyMessage } else - {} + { + } } } catch (const std::exception& e) diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index d99e2face..ef92f079c 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -293,12 +293,10 @@ namespace llarp void handle_find_router(oxen::quic::message); // relay + path // Path messages - void handle_path_build(oxen::quic::message); // relay + void handle_path_build(oxen::quic::message, const RouterID& from); // relay void handle_path_confirm(oxen::quic::message); // relay void handle_path_latency(oxen::quic::message); // relay void handle_path_transfer(oxen::quic::message); // relay - void handle_relay_commit(oxen::quic::message); // relay - void handle_relay_status(oxen::quic::message); // relay // Exit messages void handle_obtain_exit(oxen::quic::message); // relay @@ -309,17 +307,7 @@ namespace llarp void handle_convo_intro(oxen::quic::message); std::unordered_map rpc_commands = { - {"find_name", &LinkManager::handle_find_name}, - {"find_router", &LinkManager::handle_find_router}, - {"publish_intro", &LinkManager::handle_publish_intro}, - {"find_intro", &LinkManager::handle_find_intro}, - {"path_build", &LinkManager::handle_path_build}, - {"path_confirm", &LinkManager::handle_path_confirm}, - {"path_latency", &LinkManager::handle_path_latency}, - {"update_exit", &LinkManager::handle_update_exit}, - {"obtain_exit", &LinkManager::handle_obtain_exit}, - {"close_exit", &LinkManager::handle_close_exit}, - {"convo_intro", &LinkManager::handle_convo_intro}}; + {"path_control", &LinkManager::handle_path_control}}; // Path relaying void handle_path_control(oxen::quic::message); diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 3fb7ad8fa..a6b6652bf 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -104,6 +104,7 @@ namespace llarp::path payload = std::move(btdp).str(); } + // TODO: old impl padded messages if smaller than a certain size; do we still want to? TunnelNonce nonce; nonce.Randomize(); diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 2f831bf06..062ffc0a9 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -1,4 +1,6 @@ #include "pathbuilder.hpp" +#include "path.hpp" +#include "path_context.hpp" #include "path.hpp" #include "path_context.hpp" @@ -6,12 +8,15 @@ #include #include #include + #include #include #include #include #include +#include + namespace llarp { namespace @@ -470,28 +475,30 @@ namespace llarp // be worth doing sooner rather than later. Leaving some TODOs below where fail // and success live. auto response_cb = [self](oxen::quic::message m) { - if (m) + try { - std::string status; - - try + if (not m) { - oxenc::bt_dict_consumer btdc{m.body()}; - status = btdc.require("STATUS"); - } - catch (...) - { - log::warning(path_cat, "Error: Failed to parse path build response!", status); - m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); - throw; + if (m.timed_out) + { + log::warning(path_cat, "Path build timed out"); + } + else + { + oxenc::bt_dict_consumer d{m.body()}; + auto status = d.require("STATUS"); + log::warning(path_cat, "Path build returned failure status: {}", status); + } + // TODO: inform failure (what this means needs revisiting, badly) + return; } - // TODO: success logic + // TODO: inform success (what this means needs revisiting, badly) } - else + catch (const std::exception& e) { - log::warning(path_cat, "Path build request returned failure {}"); - // TODO: failure logic + log::warning(path_cat, "Failed parsing path build response."); + // TODO: inform failure (what this means needs revisiting, badly) } };