From abb2f63ec649ff6054d4ce5381dac471a0dfcff4 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Mon, 6 Nov 2023 12:46:42 -0500 Subject: [PATCH] path control message response status changes change path control message inner message response to take just a string, which will be a bt-encoded response with an early key for status. If there is a timeout we pass a bt dict that only has that as the status, else the response we de-onioned should have either an OK status or some other error. change messages to use new status key correctly call Path::EnterState on path build response --- llarp/link/link_manager.cpp | 90 +++++++++++++++--------------- llarp/link/link_manager.hpp | 7 +-- llarp/messages/common.hpp | 18 ++++++ llarp/path/abstracthophandler.hpp | 2 +- llarp/path/path.cpp | 27 +++++---- llarp/path/path.hpp | 14 ++--- llarp/path/pathbuilder.cpp | 37 ++++++------ llarp/path/transit_hop.cpp | 2 +- llarp/path/transit_hop.hpp | 2 +- llarp/service/endpoint.cpp | 30 ++++++---- llarp/service/outbound_context.cpp | 15 +++-- 11 files changed, 140 insertions(+), 104 deletions(-) diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index f2a2f8e3e..b69fb7bde 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -124,6 +124,8 @@ namespace llarp } // namespace link + using messages::serialize_response; + void LinkManager::for_each_connection(std::function func) { @@ -534,7 +536,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - respond(serialize_response({{"STATUS", FindNameMessage::EXCEPTION}})); + respond(serialize_response({{messages::STATUS_KEY, FindNameMessage::EXCEPTION}})); } _router.rpc_client()->lookup_ons_hash( @@ -544,7 +546,7 @@ namespace llarp if (maybe) respond(serialize_response({{"NAME", maybe->ciphertext}})); else - respond(serialize_response({{"STATUS", FindNameMessage::NOT_FOUND}})); + respond(serialize_response({{messages::STATUS_KEY, FindNameMessage::NOT_FOUND}})); }); } @@ -562,7 +564,7 @@ namespace llarp try { oxenc::bt_dict_consumer btdc{m.body()}; - payload = btdc.require(m ? "NAME" : "STATUS"); + payload = btdc.require(m ? "NAME" : messages::STATUS_KEY); } catch (const std::exception& e) { @@ -609,7 +611,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - respond(serialize_response({{"STATUS", FindRouterMessage::EXCEPTION}, {"TARGET", ""}})); + respond(serialize_response({{messages::STATUS_KEY, FindRouterMessage::EXCEPTION}, {"TARGET", ""}})); return; } @@ -640,7 +642,7 @@ namespace llarp } respond( - serialize_response({{"STATUS", FindRouterMessage::RETRY_EXP}, {"TARGET", neighbors}})); + serialize_response({{messages::STATUS_KEY, FindRouterMessage::RETRY_EXP}, {"TARGET", neighbors}})); } else { @@ -680,14 +682,14 @@ namespace llarp else { respond(serialize_response( - {{"STATUS", FindRouterMessage::RETRY_ITER}, + {{messages::STATUS_KEY, FindRouterMessage::RETRY_ITER}, {"TARGET", reinterpret_cast(target_addr.data())}})); } } else { respond(serialize_response( - {{"STATUS", FindRouterMessage::RETRY_NEW}, + {{messages::STATUS_KEY, FindRouterMessage::RETRY_NEW}, {"TARGET", reinterpret_cast(closest_rid.data())}})); } } @@ -837,7 +839,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - respond(serialize_response({{"STATUS", PublishIntroMessage::EXCEPTION}})); + respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::EXCEPTION}})); return; } @@ -848,14 +850,14 @@ namespace llarp if (not service::EncryptedIntroSet::verify(introset, derived_signing_key, sig)) { log::error(link_cat, "Received PublishIntroMessage with invalid introset: {}", introset); - respond(serialize_response({{"STATUS", PublishIntroMessage::INVALID_INTROSET}})); + respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::INVALID_INTROSET}})); return; } if (now + service::MAX_INTROSET_TIME_DELTA > signed_at + path::DEFAULT_LIFETIME) { log::error(link_cat, "Received PublishIntroMessage with expired introset: {}", introset); - respond(serialize_response({{"STATUS", PublishIntroMessage::EXPIRED}})); + respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::EXPIRED}})); return; } @@ -865,7 +867,7 @@ namespace llarp { log::error( link_cat, "Received PublishIntroMessage but only know {} nodes", closest_rcs.size()); - respond(serialize_response({{"STATUS", PublishIntroMessage::INSUFFICIENT}})); + respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::INSUFFICIENT}})); return; } @@ -877,7 +879,7 @@ namespace llarp { log::error( link_cat, "Received PublishIntroMessage with invalide relay order: {}", relay_order); - respond(serialize_response({{"STATUS", PublishIntroMessage::INVALID_ORDER}})); + respond(serialize_response({{messages::STATUS_KEY, PublishIntroMessage::INVALID_ORDER}})); return; } @@ -894,7 +896,7 @@ namespace llarp relay_order); _router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)}); - respond(serialize_response({{"STATUS", ""}})); + respond(serialize_response({{messages::STATUS_KEY, ""}})); } else { @@ -932,7 +934,7 @@ namespace llarp log::info(link_cat, "Received PublishIntroMessage for {} (TXID: {}); we are candidate {}"); _router.contacts()->services()->PutNode(dht::ISNode{std::move(enc)}); - respond(serialize_response({{"STATUS", ""}})); + respond(serialize_response({{messages::STATUS_KEY, ""}})); } else log::warning( @@ -955,7 +957,7 @@ namespace llarp try { oxenc::bt_dict_consumer btdc{m.body()}; - payload = btdc.require("STATUS"); + payload = btdc.require(messages::STATUS_KEY); } catch (const std::exception& e) { @@ -1006,7 +1008,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - respond(serialize_response({{"STATUS", FindIntroMessage::EXCEPTION}})); + respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::EXCEPTION}})); return; } @@ -1018,7 +1020,7 @@ namespace llarp { log::warning( link_cat, "Received FindIntroMessage with invalid relay order: {}", relay_order); - respond(serialize_response({{"STATUS", FindIntroMessage::INVALID_ORDER}})); + respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::INVALID_ORDER}})); return; } @@ -1028,7 +1030,7 @@ namespace llarp { log::error( link_cat, "Received FindIntroMessage but only know {} nodes", closest_rcs.size()); - respond(serialize_response({{"STATUS", FindIntroMessage::INSUFFICIENT_NODES}})); + respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::INSUFFICIENT_NODES}})); return; } @@ -1066,7 +1068,7 @@ namespace llarp log::warning( link_cat, "Received FindIntroMessage with relayed == false and no local introset entry"); - respond(serialize_response({{"STATUS", FindIntroMessage::NOT_FOUND}})); + respond(serialize_response({{messages::STATUS_KEY, FindIntroMessage::NOT_FOUND}})); } } } @@ -1085,7 +1087,7 @@ namespace llarp try { oxenc::bt_dict_consumer btdc{m.body()}; - payload = btdc.require((m) ? "INTROSET" : "STATUS"); + payload = btdc.require((m) ? "INTROSET" : messages::STATUS_KEY); } catch (const std::exception& e) { @@ -1112,7 +1114,7 @@ namespace llarp if (!_router.path_context().AllowingTransit()) { log::warning(link_cat, "got path build request when not permitting transit"); - m.respond(serialize_response({{"STATUS", PathBuildMessage::NO_TRANSIT}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::NO_TRANSIT}}), true); return; } try @@ -1142,7 +1144,7 @@ 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({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } @@ -1155,14 +1157,14 @@ namespace llarp shared)) { log::error(link_cat, "HMAC failed on path build request"); - m.respond(serialize_response({{"STATUS", 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({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } @@ -1174,7 +1176,7 @@ namespace llarp outer_nonce.data())) { log::info(link_cat, "Decrypt failed on path build request"); - m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } @@ -1195,7 +1197,7 @@ namespace llarp if (frame.empty()) { log::info(link_cat, "Path build request received invalid frame"); - m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_FRAMES}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_FRAMES}}), true); return; } @@ -1212,7 +1214,7 @@ namespace llarp if (hop_info.txID.IsZero() || hop_info.rxID.IsZero()) { log::warning(link_cat, "Invalid PathID; PathIDs must be non-zero"); - m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_PATHID}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_PATHID}}), true); return; } @@ -1221,7 +1223,7 @@ namespace llarp if (_router.path_context().HasTransitHop(hop_info)) { log::warning(link_cat, "Invalid PathID; PathIDs must be unique"); - m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_PATHID}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_PATHID}}), true); return; } @@ -1229,7 +1231,7 @@ namespace llarp hop->pathKey.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data())) { log::warning(link_cat, "DH failed during path build."); - m.respond(serialize_response({{"STATUS", PathBuildMessage::BAD_CRYPTO}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_CRYPTO}}), true); return; } // generate hash of hop key for nonce mutation @@ -1241,7 +1243,7 @@ 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({{"STATUS", PathBuildMessage::BAD_LIFETIME}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::BAD_LIFETIME}}), true); return; } @@ -1253,7 +1255,7 @@ namespace llarp hop->terminal_hop = true; // we are terminal hop and everything is okay _router.path_context().PutTransitHop(hop); - m.respond(serialize_response({{"STATUS", PathBuildMessage::OK}}), false); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::OK}}), false); return; } @@ -1285,7 +1287,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", PathBuildMessage::EXCEPTION}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, PathBuildMessage::EXCEPTION}}), true); return; } } @@ -1300,7 +1302,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - // m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); + // m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true); return; } } @@ -1315,7 +1317,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true); return; } } @@ -1330,7 +1332,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - // m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); + // m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true); return; } } @@ -1345,7 +1347,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true); return; } } @@ -1360,7 +1362,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - // m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); + // m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true); return; } } @@ -1375,7 +1377,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true); return; } } @@ -1390,7 +1392,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", "EXCEPTION"}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, "EXCEPTION"}}), true); return; } } @@ -1429,7 +1431,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", ObtainExitMessage::EXCEPTION}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, ObtainExitMessage::EXCEPTION}}), true); throw; } } @@ -1497,7 +1499,7 @@ namespace llarp { (exit_ep->UpdateLocalPath(transit_hop->info.rxID)) ? m.respond(UpdateExitMessage::sign_and_serialize_response(_router.identity(), tx_id)) - : m.respond(serialize_response({{"STATUS", UpdateExitMessage::UPDATE_FAILED}}), true); + : m.respond(serialize_response({{messages::STATUS_KEY, UpdateExitMessage::UPDATE_FAILED}}), true); } // If we fail to verify the message, no-op } @@ -1505,7 +1507,7 @@ namespace llarp catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", UpdateExitMessage::EXCEPTION}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, UpdateExitMessage::EXCEPTION}}), true); return; } } @@ -1584,12 +1586,12 @@ namespace llarp } } - m.respond(serialize_response({{"STATUS", CloseExitMessage::UPDATE_FAILED}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, CloseExitMessage::UPDATE_FAILED}}), true); } catch (const std::exception& e) { log::warning(link_cat, "Exception: {}", e.what()); - m.respond(serialize_response({{"STATUS", CloseExitMessage::EXCEPTION}}), true); + m.respond(serialize_response({{messages::STATUS_KEY, CloseExitMessage::EXCEPTION}}), true); return; } } diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index b544cc62e..40d24ee40 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -27,12 +28,6 @@ namespace llarp { struct LinkManager; - inline std::string - serialize_response(oxenc::bt_dict supplement = {}) - { - return oxenc::bt_serialize(supplement); - } - namespace link { struct Connection; diff --git a/llarp/messages/common.hpp b/llarp/messages/common.hpp index e230b4a89..da08cd60f 100644 --- a/llarp/messages/common.hpp +++ b/llarp/messages/common.hpp @@ -18,6 +18,24 @@ namespace namespace llarp { + namespace messages + { + + inline std::string + serialize_response(oxenc::bt_dict supplement = {}) + { + return oxenc::bt_serialize(supplement); + } + + // 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 + /// abstract base class for serialized messages struct AbstractSerializable { diff --git a/llarp/path/abstracthophandler.hpp b/llarp/path/abstracthophandler.hpp index 0991488b7..8d6086586 100644 --- a/llarp/path/abstracthophandler.hpp +++ b/llarp/path/abstracthophandler.hpp @@ -59,7 +59,7 @@ namespace llarp /// a timeout flag (if set, response string will be empty) virtual bool send_path_control_message( - std::string method, std::string body, std::function func) = 0; + std::string method, std::string body, std::function func) = 0; /// send routing message and increment sequence number virtual bool diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index fe4cc315e..ca8b7b0ee 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -49,7 +49,7 @@ namespace llarp::path bool Path::obtain_exit( - SecretKey sk, uint64_t flag, std::string tx_id, std::function func) + SecretKey sk, uint64_t flag, std::string tx_id, std::function func) { return send_path_control_message( "obtain_exit", @@ -58,7 +58,7 @@ namespace llarp::path } bool - Path::close_exit(SecretKey sk, std::string tx_id, std::function func) + Path::close_exit(SecretKey sk, std::string tx_id, std::function func) { return send_path_control_message( "close_exit", CloseExitMessage::sign_and_serialize(sk, std::move(tx_id)), std::move(func)); @@ -69,21 +69,21 @@ namespace llarp::path const dht::Key_t& location, bool is_relayed, uint64_t order, - std::function func) + std::function func) { return send_path_control_message( "find_intro", FindIntroMessage::serialize(location, is_relayed, order), std::move(func)); } bool - Path::find_name(std::string name, std::function func) + Path::find_name(std::string name, std::function func) { return send_path_control_message( "find_name", FindNameMessage::serialize(std::move(name)), std::move(func)); } bool - Path::find_router(std::string rid, std::function func) + Path::find_router(std::string rid, std::function func) { return send_path_control_message( "find_router", FindRouterMessage::serialize(std::move(rid), false, false), std::move(func)); @@ -91,7 +91,7 @@ namespace llarp::path bool Path::send_path_control_message( - std::string method, std::string body, std::function func) + std::string method, std::string body, std::function func) { oxenc::bt_dict_producer btdp; btdp.append("BODY", body); @@ -121,13 +121,16 @@ namespace llarp::path std::move(outer_payload), [response_cb = std::move(func), weak = weak_from_this()](oxen::quic::message m) { auto self = weak.lock(); - if (not self) + // TODO: do we want to allow empty callback here? + if ((not self) or (not response_cb)) return; + if (m.timed_out) { - response_cb(""s, true); + response_cb(messages::TIMEOUT_BT_DICT); return; } + TunnelNonce nonce{}; std::string payload; try @@ -139,9 +142,11 @@ namespace llarp::path } catch (const std::exception& e) { - log::warning(path_cat, "Error parsing onion response: {}", e.what()); + log::warning(path_cat, "Error parsing path control message response: {}", e.what()); + response_cb(messages::ERROR_BT_DICT); return; } + for (const auto& hop : self->hops) { nonce = crypto::onion( @@ -155,7 +160,7 @@ namespace llarp::path // TODO: should we do anything (even really simple) here to check if the decrypted // response is sensible (e.g. is a bt dict)? Parsing and handling of the // contents (errors or otherwise) is the currently responsibility of the callback. - response_cb(payload, false); + response_cb(payload); }); } @@ -242,6 +247,8 @@ namespace llarp::path void Path::EnterState(PathStatus st, llarp_time_t now) { + if (now == 0s) now = router.now(); + if (st == ePathFailed) { _status = st; diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index e4fdc2107..5035fcd62 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -143,7 +143,7 @@ namespace llarp } void - EnterState(PathStatus st, llarp_time_t now); + EnterState(PathStatus st, llarp_time_t now = 0s); llarp_time_t ExpireTime() const @@ -186,28 +186,28 @@ namespace llarp Tick(llarp_time_t now, Router* r); bool - find_name(std::string name, std::function func = nullptr); + find_name(std::string name, std::function func = nullptr); bool - find_router(std::string rid, std::function func = nullptr); + find_router(std::string rid, std::function func = nullptr); bool find_intro( const dht::Key_t& location, bool is_relayed = false, uint64_t order = 0, - std::function func = nullptr); + std::function func = nullptr); bool close_exit( - SecretKey sk, std::string tx_id, std::function func = nullptr); + SecretKey sk, std::string tx_id, std::function func = nullptr); bool obtain_exit( SecretKey sk, uint64_t flag, std::string tx_id, - std::function func = nullptr); + std::function func = nullptr); /// sends a control request along a path /// @@ -221,7 +221,7 @@ namespace llarp send_path_control_message( std::string method, std::string body, - std::function func = nullptr) override; + std::function func = nullptr) override; bool SendRoutingMessage(std::string payload, Router* r) override; diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index dd284d270..d90428de2 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -1,5 +1,6 @@ #include "pathbuilder.hpp" +#include "llarp/path/pathset.hpp" #include "path.hpp" #include "path_context.hpp" @@ -462,8 +463,7 @@ namespace llarp frames.append(dummy); } - auto self = GetSelf(); - router->path_context().AddOwnPath(self, path); + router->path_context().AddOwnPath(GetSelf(), path); PathBuildStarted(path); // TODO: @@ -471,32 +471,33 @@ namespace llarp // handle these responses as well as how we store and use Paths as a whole might // be worth doing sooner rather than later. Leaving some TODOs below where fail // and success live. - auto response_cb = [self](oxen::quic::message m) { + auto response_cb = [path](oxen::quic::message m) { try { - if (not m) + if (m) { - 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) + // TODO: inform success (what this means needs revisiting, badly) + path->EnterState(path::ePathEstablished); return; } - - // TODO: inform success (what this means needs revisiting, badly) + if (m.timed_out) + { + log::warning(path_cat, "Path build timed out"); + } + else + { + oxenc::bt_dict_consumer d{m.body()}; + auto status = d.require(messages::STATUS_KEY); + log::warning(path_cat, "Path build returned failure status: {}", status); + } } catch (const std::exception& e) { log::warning(path_cat, "Failed parsing path build response."); - // TODO: inform failure (what this means needs revisiting, badly) } + + // TODO: inform failure (what this means needs revisiting, badly) + path->EnterState(path::ePathFailed); }; if (not router->send_control_message( diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index fbc4d584c..bf355c935 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -53,7 +53,7 @@ namespace llarp::path bool TransitHop::send_path_control_message( - std::string, std::string, std::function) + std::string, std::string, std::function) { return true; } diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 70d2345aa..0f2f6a517 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -140,7 +140,7 @@ namespace llarp send_path_control_message( std::string method, std::string body, - std::function func) override; + std::function func) override; // send routing message when end of path bool diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index e1d93f347..a5f0c60ad 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -202,20 +202,20 @@ 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)](oxen::quic::message m) mutable { - if (!m) + name, [this, resultHandler, service = std::move(service)](std::string name_result, bool success) mutable { + if (!success) return resultHandler({}); std::string name; try { - oxenc::bt_dict_consumer btdc{m.body()}; + oxenc::bt_dict_consumer btdc{name_result}; name = btdc.require("NAME"); } catch (...) { log::warning(link_cat, "Failed to parse find name response!"); - throw; + return resultHandler({}); } auto saddr = service::Address(); @@ -816,14 +816,18 @@ namespace llarp::service std::shuffle(chosenpaths.begin(), chosenpaths.end(), llarp::csrng); chosenpaths.resize(std::min(paths.size(), MAX_ONS_LOOKUP_ENDPOINTS)); - auto response_cb = [func = std::move(func)](std::string resp, bool timeout) { - if (timeout) - func(""s, false); - + // TODO: only want one successful response to call the callback, or failed if all fail + auto response_cb = [func = std::move(func)](std::string resp) { std::string name{}; try { oxenc::bt_dict_consumer btdc{resp}; + auto status = btdc.require(messages::STATUS_KEY); + if (status != messages::STATUS_OK) + { + log::info(link_cat, "Error on ONS lookup: {}", status); + func(""s, false); + } name = btdc.require("NAME"); } catch (...) @@ -1354,9 +1358,9 @@ namespace llarp::service for (const auto& path : paths) { path->find_intro( - location, false, 0, [this, hook, got_it](std::string resp, bool timeout) mutable { + location, false, 0, [this, hook, got_it](std::string resp) mutable { // asking many, use only first successful - if (timeout or *got_it) + if (*got_it) return; std::string introset; @@ -1364,6 +1368,12 @@ namespace llarp::service 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 (...) diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 52462d226..d05f5115c 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -157,6 +157,7 @@ namespace llarp::service return "OBContext:" + current_intro.address_keys.Addr().ToString(); } + // TODO: it seems a lot of this logic is duplicated in service/endpoint void OutboundContext::UpdateIntroSet() { @@ -173,7 +174,7 @@ namespace llarp::service for (const auto& path : paths) { - path->find_intro(location, false, relayOrder, [this](std::string resp, bool timeout) mutable { + path->find_intro(location, false, relayOrder, [this](std::string resp) mutable { if (marked_bad) { log::info(link_cat, "Outbound context has been marked bad (whatever that means)"); @@ -182,14 +183,17 @@ namespace llarp::service updatingIntroSet = false; - if (timeout) - return; - // TODO: this parsing is probably elsewhere, may need DRYed 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 (...) @@ -539,10 +543,9 @@ namespace llarp::service ex->msg.proto = ProtocolType::Auth; ex->hook = [this, path, cb = std::move(func)](auto frame) mutable { - auto hook = [&, frame, path](std::string resp, bool timeout) { + auto hook = [&, frame, path](std::string resp) { // TODO: revisit this (void)resp; - (void)timeout; ep.HandleHiddenServiceFrame(path, *frame.get()); };