diff --git a/llarp/bootstrap.cpp b/llarp/bootstrap.cpp index 51d88a810b..f2ebfde023 100644 --- a/llarp/bootstrap.cpp +++ b/llarp/bootstrap.cpp @@ -156,7 +156,7 @@ namespace llarp if (not fs::exists(fpath)) { - log::critical(logcat, "Bootstrap RC file non-existant at path:{}", fpath); + log::critical(logcat, "Bootstrap RC file non-existent at path:{}", fpath); return result; } diff --git a/llarp/contact/client_contact.hpp b/llarp/contact/client_contact.hpp index 98e90515c8..0d2175d604 100644 --- a/llarp/contact/client_contact.hpp +++ b/llarp/contact/client_contact.hpp @@ -47,7 +47,7 @@ namespace llarp }; // TESTNET: - inline static constexpr auto CC_PUBLISH_INTERVAL{1min}; + inline static constexpr auto CC_PUBLISH_INTERVAL{30s}; /** ClientContact On the wire we encode the data as a dict containing: diff --git a/llarp/handlers/session.cpp b/llarp/handlers/session.cpp index 29c06354a4..c31adc53db 100644 --- a/llarp/handlers/session.cpp +++ b/llarp/handlers/session.cpp @@ -236,9 +236,9 @@ namespace llarp::handlers if (auto s = btdc.maybe(messages::STATUS_KEY)) status = s; } - catch (...) + catch (const std::exception& e) { - log::warning(logcat, "Exception caught parsing 'find_name' response!"); + log::warning(logcat, "Exception caught parsing 'find_name' response: {}", e.what()); } log::warning(logcat, "Call to endpoint 'lookup_name' failed -- status:{}", status.value_or("")); @@ -414,7 +414,25 @@ namespace llarp::handlers { log::debug(logcat, "Publishing ClientContact to pivot {}", path->pivot_rid()); - ret &= path->publish_client_contact(ecc, true); + ret &= path->publish_client_contact(ecc, true, 0, [](std::string response) { + log::info(logcat, "Received response to PublishClientContact..."); + + std::optional status = std::nullopt; + try + { + oxenc::bt_dict_consumer btdc{response}; + + if (auto s = btdc.maybe(messages::STATUS_KEY)) + status = s; + } + catch (const std::exception& e) + { + log::warning(logcat, "Exception: {}", e.what()); + } + + log::warning( + logcat, "Call to PublishClientContact failed -- status:{}", status.value_or("")); + }); } } diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 895927baa9..e7a278f4dc 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -382,7 +382,7 @@ namespace llarp::handlers auto pkt_hook = [this]() { for (auto pkt = _net_if->read_next_packet(); not pkt.empty(); pkt = _net_if->read_next_packet()) { - log::debug(logcat, "packet router receiving {}", pkt.info_line()); + log::trace(logcat, "packet router receiving {}", pkt.info_line()); _packet_router->handle_ip_packet(std::move(pkt)); } }; diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 8152bf4b8c..bf6517d86a 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -1292,6 +1292,8 @@ namespace llarp void LinkManager::handle_path_control(oxen::quic::message m, const RouterID& /* from */) { + log::debug(logcat, "{} called", __PRETTY_FUNCTION__); + HopID hop_id; std::string payload; SymmNonce nonce; @@ -1313,12 +1315,20 @@ namespace llarp // bidirectional, will need to check if we have a Path with path_id. if (not hop) { + // if (auto path = _router.path_context()->get_path(hop_id)) + // { + // log::info(logcat, "Received path control corresponding to known path!"); + // // + // } + log::warning(logcat, "Received path control with unknown next hop (ID: {})", hop_id); return m.respond(messages::ERROR_RESPONSE, true); } - nonce = crypto::onion( - reinterpret_cast(payload.data()), payload.size(), hop->shared, nonce, hop->nonceXOR); + auto onion_nonce = nonce ^ hop->nonceXOR; + + crypto::onion( + reinterpret_cast(payload.data()), payload.size(), hop->shared, onion_nonce, hop->nonceXOR); // if terminal hop, payload should contain a request (e.g. "ons_resolve"); handle and respond. if (hop->terminal_hop) @@ -1332,7 +1342,7 @@ namespace llarp const auto& next_id = hop_is_rx ? hop->txid() : hop->rxid(); const auto& next_router = hop_is_rx ? hop->upstream() : hop->downstream(); - std::string new_payload = ONION::serialize_hop(next_id.to_view(), nonce, std::move(payload)); + std::string new_payload = ONION::serialize_hop(next_id.to_view(), onion_nonce, std::move(payload)); send_control_message( next_router, @@ -1344,7 +1354,7 @@ namespace llarp if (not hop) { - log::warning(logcat, "Received response to path control message with non-existant TransitHop!"); + log::warning(logcat, "Received response to path control message with non-existent TransitHop!"); return prev_message.respond(messages::ERROR_RESPONSE, true); } @@ -1366,7 +1376,6 @@ namespace llarp { log::warning(logcat, "Exception: {}", e.what()); return prev_message.respond(messages::ERROR_RESPONSE, true); - ; } auto resp_payload = ONION::serialize_hop(hop_id.to_view(), nonce, std::move(payload)); @@ -1451,8 +1460,8 @@ namespace llarp } catch (const std::exception& e) { - log::warning(logcat, "Exception: {}", e.what()); - return; + log::warning(logcat, "Exception: {}; Payload: {}", e.what(), buffer_printer{payload}); + return m.respond(messages::serialize_response({{messages::STATUS_KEY, e.what()}}), true); } // If a handler exists for "method", call it; else drop request on the floor. diff --git a/llarp/messages/path.hpp b/llarp/messages/path.hpp index b9d73af87d..e1ad9ef63f 100644 --- a/llarp/messages/path.hpp +++ b/llarp/messages/path.hpp @@ -51,29 +51,12 @@ namespace llarp } catch (const std::exception& e) { - throw std::runtime_error{"Exception caught deserializing onion data:{}"_format(e.what())}; + throw std::runtime_error{"Exception caught deserializing onion data: {}"_format(e.what())}; } return {std::move(hop_id), std::move(nonce), std::move(payload)}; } - inline static std::tuple deserialize_hop(oxenc::bt_dict_consumer& btdc) - { - ustring hopid, nonce, payload; - - try - { - hopid = btdc.require("k"); - nonce = btdc.require("n"); - payload = btdc.require("x"); - } - catch (const std::exception& e) - { - throw std::runtime_error{"Exception caught deserializing onion data:{}"_format(e.what())}; - } - - return {std::move(hopid), std::move(nonce), std::move(payload)}; - } } // namespace ONION namespace PATH @@ -170,7 +153,7 @@ namespace llarp } catch (const std::exception& e) { - log::warning(logcat, "Exception caught deserializing hop dict:{}", e.what()); + log::warning(logcat, "Exception caught deserializing hop dict: {}", e.what()); throw; } @@ -227,7 +210,7 @@ namespace llarp } catch (const std::exception& e) { - throw std::runtime_error{"Exception caught deserializing path control:{}"_format(e.what())}; + throw std::runtime_error{"Exception caught deserializing path control: {}"_format(e.what())}; } return {std::move(endpoint), std::move(payload)}; diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index bc02746b32..d4e9e7a803 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -7,6 +7,8 @@ #include #include +#include + namespace llarp::path { static auto logcat = log::Cat("path"); @@ -19,31 +21,34 @@ namespace llarp::path bool is_client) : handler{std::move(_handler)}, _router{rtr}, _is_session_path{is_session}, _is_client{is_client} { - hops.resize(_hops.size()); - size_t hsz = _hops.size(); + size_t n_hops = _hops.size(); + // transit_hops.resize(n_hops); + hops.resize(n_hops); - for (size_t idx = 0; idx < hsz; ++idx) + for (size_t idx = 0; idx < n_hops; ++idx) { + // transit_hops[idx] hops[idx].rc = _hops[idx]; - do - { - hops[idx].txID.Randomize(); - } while (hops[idx].txID.is_zero()); - - do - { - hops[idx].rxID.Randomize(); - } while (hops[idx].rxID.is_zero()); + hops[idx].txID = HopID::make_random(); + // transit_hops[idx]._txid = HopID::make_random(); + hops[idx].rxID = HopID::make_random(); + // transit_hops[idx]._rxid = HopID::make_random(); } - for (size_t idx = 0; idx < hsz - 1; ++idx) + for (size_t idx = 0; idx < n_hops - 1; ++idx) { + // transit_hops[idx]._txid = transit_hops[idx + 1]._rxid; hops[idx].txID = hops[idx + 1].rxID; } // initialize parts of the clientintro - intro.pivot_rid = hops[hsz - 1].rc.router_id(); - intro.pivot_hid = hops[hsz - 1].txID; + // intro.pivot_rid = transit_hops.back().rc.router_id(); + // intro.pivot_hid = transit_hops.back()._txid; + intro.pivot_rid = hops.back().rc.router_id(); + intro.pivot_hid = hops.back().txID; + + log::info( + logcat, "Path client intro holding pivot_rid ({}) and pivot_hid ({})", intro.pivot_rid, intro.pivot_hid); } void Path::link_session(recv_session_dgram_cb cb) @@ -75,8 +80,8 @@ namespace llarp::path bool Path::operator<(const Path& other) const { - auto& first_hop = hops[0]; - auto& other_first = other.hops[0]; + auto& first_hop = hops.front(); + auto& other_first = other.hops.front(); return std::tie(first_hop.txID, first_hop.rxID, first_hop.upstream) < std::tie(other_first.txID, other_first.rxID, other_first.upstream); } @@ -148,14 +153,14 @@ namespace llarp::path { auto nonce = SymmNonce::make_random(); - for (const auto& hop : hops) + for (const auto& hop : std::ranges::reverse_view(hops)) { nonce = crypto::onion( reinterpret_cast(inner_payload.data()), inner_payload.size(), hop.shared, - hop.nonce, - hop.nonce); + nonce, + hop.nonceXOR); } return ONION::serialize_hop(upstream_txid().to_view(), nonce, std::move(inner_payload)); @@ -182,7 +187,7 @@ namespace llarp::path auto self = weak.lock(); if (not self) { - log::warning(logcat, "Received response to path control message with non-existant path!"); + log::warning(logcat, "Received response to path control message with non-existent path!"); return; } @@ -193,12 +198,12 @@ namespace llarp::path return; } - log::debug(logcat, "Received response to path control message..."); + log::debug(logcat, "Received response to path control message: {}", buffer_printer{m.body()}); - if (m.timed_out) + if (not m) { - log::info(logcat, "Path control message returned as time out!"); - return response_cb(messages::TIMEOUT_RESPONSE); + log::warning(logcat, "Path control message returned error!"); + return response_cb(m.body_str()); } HopID hop_id; @@ -211,7 +216,7 @@ namespace llarp::path } catch (const std::exception& e) { - log::warning(logcat, "Error parsing path control message response: {}", e.what()); + log::warning(logcat, "Exception parsing path control message response: {}", e.what()); return response_cb(messages::ERROR_RESPONSE); } @@ -227,43 +232,48 @@ namespace llarp::path // TODO: DISCUSS: // Parsing and handling of the contents (errors, etc.) is the currently responsibility of the callback - response_cb(std::string{reinterpret_cast(payload.data()), payload.size()}); + response_cb(std::move(payload)); }); } bool Path::is_ready(std::chrono::milliseconds now) const { - return _established ? is_expired(now) : false; + return _established ? !is_expired(now) : false; + } + + PathHopConfig Path::upstream() + { + return hops.front(); } RouterID Path::upstream_rid() { - return hops[0].rc.router_id(); + return hops.front().rc.router_id(); } const RouterID& Path::upstream_rid() const { - return hops[0].rc.router_id(); + return hops.front().rc.router_id(); } HopID Path::upstream_txid() { - return hops[0].txID; + return hops.front().txID; } const HopID& Path::upstream_txid() const { - return hops[0].txID; + return hops.front().txID; } HopID Path::upstream_rxid() { - return hops[0].rxID; + return hops.front().rxID; } const HopID& Path::upstream_rxid() const { - return hops[0].rxID; + return hops.front().rxID; } RouterID Path::pivot_rid() diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index 1222534cf6..51a85aa9f5 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -42,6 +42,8 @@ namespace llarp { std::vector hops; + // std::vector transit_hops; + std::weak_ptr handler; ClientIntro intro{}; @@ -128,6 +130,8 @@ namespace llarp bool is_ready(std::chrono::milliseconds now = llarp::time_now_ms()) const; + PathHopConfig upstream(); + RouterID upstream_rid(); const RouterID& upstream_rid() const; @@ -178,9 +182,9 @@ namespace llarp recv_session_dgram_cb _recv_dgram; - std::chrono::milliseconds last_recv_msg = 0s; - std::chrono::milliseconds last_latency_test = 0s; - uint64_t last_latency_test_id = 0; + std::chrono::milliseconds last_recv_msg{0s}; + std::chrono::milliseconds last_latency_test{0s}; + uint64_t last_latency_test_id{}; }; } // namespace path } // namespace llarp diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp index 86cf03108f..5e027ff940 100644 --- a/llarp/path/path_context.cpp +++ b/llarp/path/path_context.cpp @@ -39,6 +39,9 @@ namespace llarp::path { Lock_t l{paths_mutex}; + // TESTNET: TODO: once PathHopConfig -> TransitHop, remove this association + put_transit_hop(TransitHop::from_hop_config(path->upstream())); + _path_map.emplace(path->upstream_rxid(), path); _path_map.emplace(path->upstream_txid(), path); diff --git a/llarp/path/path_handler.cpp b/llarp/path/path_handler.cpp index 10166002f4..84f2f37e10 100644 --- a/llarp/path/path_handler.cpp +++ b/llarp/path/path_handler.cpp @@ -166,19 +166,6 @@ namespace llarp::path return selected; } - size_t PathHandler::paths_at_time(std::chrono::milliseconds futureTime) const - { - size_t num = 0; - Lock_t l{paths_mutex}; - - for (const auto& item : _paths) - { - if (item.second->is_ready() && !item.second->is_expired(futureTime)) - ++num; - } - return num; - } - void PathHandler::reset_path_state() { build_interval_limit = PATH_BUILD_RATE; @@ -424,7 +411,6 @@ namespace llarp::path } RemoteRC remote_rc; - to_exclude.insert(remote_rc.router_id()); // we will manually add this last if (const auto maybe = _router.node_db()->get_rc(pivot)) { @@ -433,6 +419,8 @@ namespace llarp::path else return std::nullopt; + to_exclude.insert(remote_rc.router_id()); // we will manually add this last + // leave one extra spot for the terminal node auto hops_needed = num_hops - hops.size() - 1; @@ -508,7 +496,7 @@ namespace llarp::path last_build = llarp::time_now_ms(); const auto& edge = hops[0].router_id(); - const auto& terminus = hops.back().router_id(); + const auto& pivot = hops.back().router_id(); if (not _router.pathbuild_limiter().Attempt(edge)) { @@ -519,9 +507,9 @@ namespace llarp::path { Lock_t l{paths_mutex}; - if (auto [it, b] = _paths.try_emplace(terminus, nullptr); not b) + if (auto [it, b] = _paths.try_emplace(pivot, nullptr); not b) { - log::warning(logcat, "Pending build to {} already underway... aborting...", terminus); + log::warning(logcat, "Pending build to {} already underway... aborting...", pivot); return false; } } diff --git a/llarp/path/path_handler.hpp b/llarp/path/path_handler.hpp index aca8398578..52ca9fd25a 100644 --- a/llarp/path/path_handler.hpp +++ b/llarp/path/path_handler.hpp @@ -184,9 +184,6 @@ namespace llarp std::optional>> get_n_random_paths_conditional( size_t n, std::function)> filter, bool exact = false); - /// count the number of paths that will exist at this timestamp in future - size_t paths_at_time(std::chrono::milliseconds futureTime) const; - virtual void reset_path_state(); /// return true if we hit our soft limit for building paths too fast diff --git a/llarp/path/path_types.hpp b/llarp/path/path_types.hpp index 3f17d63b41..5a267a7481 100644 --- a/llarp/path/path_types.hpp +++ b/llarp/path/path_types.hpp @@ -11,6 +11,13 @@ namespace llarp struct HopID final : public AlignedBuffer { using AlignedBuffer::AlignedBuffer; + + static HopID make_random() + { + HopID h; + h.Randomize(); + return h; + } }; namespace path diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 407808bd71..39d5d10420 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -9,6 +9,20 @@ namespace llarp::path { static auto logcat = log::Cat("transit-hop"); + std::shared_ptr TransitHop::from_hop_config(PathHopConfig hop_config) + { + auto hop = std::make_shared(); + + hop->_txid = {hop_config.txID}; + hop->_rxid = {hop_config.rxID}; + hop->_upstream = {hop_config.upstream}; + hop->shared = {hop_config.shared}; + hop->nonce = {hop_config.nonce}; + hop->nonceXOR = {hop_config.nonceXOR}; + + return hop; + } + std::shared_ptr TransitHop::deserialize_hop( oxenc::bt_dict_consumer&& btdc, const RouterID& src, Router& r, SharedSecret secret) { @@ -33,7 +47,7 @@ namespace llarp::path if (hop->lifetime > path::DEFAULT_LIFETIME) throw std::runtime_error{PATH::BUILD::BAD_LIFETIME}; - hop->downstream() = src; + hop->_downstream = src; hop->shared = std::move(secret); if (r.path_context()->has_transit_hop(hop)) diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index d651c0903d..eef2945878 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -10,18 +10,22 @@ namespace llarp { struct Router; + /** TODO: combine PathHopConfig into TransitHop + - Add RelayContact + */ + namespace path { struct TransitHop : std::enable_shared_from_this { - private: HopID _txid, _rxid; RouterID _upstream; RouterID _downstream; - public: TransitHop() = default; + static std::shared_ptr from_hop_config(PathHopConfig hop_config); + TransitHop(Router& r, const RouterID& src, ustring symmkey, ustring symmnonce); // This static factory function is used in path-build logic. The exceptions thrown are the exact response @@ -30,6 +34,7 @@ namespace llarp oxenc::bt_dict_consumer&& btdc, const RouterID& src, Router& r, SharedSecret secret); SharedSecret shared; + SymmNonce nonce; SymmNonce nonceXOR; std::chrono::milliseconds started{0s}; // 10 minutes default