diff --git a/llarp/handlers/session.cpp b/llarp/handlers/session.cpp index 1ae18d223b..b92f2b6456 100644 --- a/llarp/handlers/session.cpp +++ b/llarp/handlers/session.cpp @@ -140,7 +140,7 @@ namespace llarp::handlers update_and_publish_localcc(get_current_client_intros(), _srv_records); } - static std::atomic testnet_trigger = false; + // static std::atomic testnet_trigger = false; void SessionEndpoint::start_tickers() { @@ -155,24 +155,25 @@ namespace llarp::handlers }, true); - if (not testnet_trigger) - { - testnet_trigger = true; - - _router.loop()->call_later(10s, [this]() { - try - { - RouterID cpk{oxenc::from_base32z("o53kmmkwbmqrh5pmrg8irptixqdt5xwafgmwuxa7u7gigxic58ro")}; - log::info(logcat, "Beginning session init to client: {}", cpk.to_network_address(false)); - _initiate_session( - NetworkAddress::from_pubkey(cpk, true), [](ip_v) { log::critical(logcat, "FUCK YEAH"); }); - } - catch (const std::exception& e) - { - log::critical(logcat, "Failed to parse client netaddr: {}", e.what()); - } - }); - } + // if (not testnet_trigger) + // { + // testnet_trigger = true; + + // _router.loop()->call_later(10s, [this]() { + // try + // { + // RouterID cpk{oxenc::from_base32z("6e9wdnd4cj3j3rgc9ze8ctxqj4z976tmu8osbzwgabruabb4u1ky")}; + // log::info(logcat, "Beginning session init to client: {}", cpk.to_network_address(false)); + // _initiate_session( + // NetworkAddress::from_pubkey(cpk, true), [](ip_v) { log::critical(logcat, "FUCK YEAH"); + // }); + // } + // catch (const std::exception& e) + // { + // log::critical(logcat, "Failed to parse client netaddr: {}", e.what()); + // } + // }); + // } } else log::info(logcat, "SessionEndpoint configured to NOT publish ClientContact..."); @@ -594,14 +595,24 @@ namespace llarp::handlers path->send_path_control_message( "path_control", std::move(intermediate_payload), - [this, remote, tag, path, hook = std::move(cb), session_keys = std::move(kx_data)]( - oxen::quic::message m) mutable { + [this, + remote, + tag, + path, + hook = std::move(cb), + session_keys = std::move(kx_data), + remote_intro = std::move(remote_intro)](oxen::quic::message m) mutable { if (m) { log::critical(logcat, "Call to InitiateSession succeeded!"); auto outbound = std::make_shared( - remote, *this, std::move(path), std::move(tag), std::move(session_keys)); + remote, + *this, + std::move(path), + std::move(tag), + std::move(session_keys), + std::move(remote_intro)); auto [session, _] = _sessions.insert_or_assign(std::move(remote), std::move(outbound)); diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 15185d3728..64cd66d397 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -1440,15 +1440,18 @@ namespace llarp hop->to_string(), buffer_printer{*inner_body}); - auto hop_is_rx = hop->rxid() == hop_id; + auto next_ids = hop->next_id(hop_id); - const auto& next_id = hop_is_rx ? hop->txid() : hop->rxid(); - const auto& next_router = hop_is_rx ? hop->upstream() : hop->downstream(); + if (not next_ids) + { + log::error(logcat, "Failed to query hop ({}) for next ids (input: {})", hop->to_string(), hop_id); + return m.respond(messages::ERROR_RESPONSE, true); + } - std::string new_payload = ONION::serialize_hop(next_id.to_view(), onion_nonce, std::move(payload)); + std::string new_payload = ONION::serialize_hop(next_ids->second.to_view(), onion_nonce, std::move(payload)); send_control_message( - next_router, + next_ids->first, "path_control", std::move(new_payload), [hop_weak = hop->weak_from_this(), hop_id, prev_message = std::move(m)]( @@ -1535,7 +1538,7 @@ namespace llarp nonce, hop.kx.xor_nonce); - log::trace(logcat, "xchacha20 -> {}", buffer_printer{payload}); + log::debug(logcat, "xchacha20 -> {}", buffer_printer{payload}); } NetworkAddress sender; @@ -1557,7 +1560,7 @@ namespace llarp } catch (const std::exception& e) { - log::warning(logcat, "Exception: {}", e.what()); + log::warning(logcat, "Exception: {}: {}", e.what(), buffer_printer{data}); } return; } @@ -1581,8 +1584,8 @@ namespace llarp onion_nonce, hop->kx.xor_nonce); - RouterID next_router; - std::string new_payload; + std::optional> next_ids = std::nullopt; + std::string next_payload; // if terminal hop, pass to the correct path expecting to receive this message if (hop->terminal_hop) @@ -1590,12 +1593,13 @@ namespace llarp log::debug( logcat, "We are terminal hop for path data: {}: {}", hop->to_string(), buffer_printer{payload}); - // HopID ihid; - // std::string intermediate; + HopID ihid; + std::string intermediate; try { - std::tie(hop_id, payload) = PATH::DATA::deserialize_intermediate(oxenc::bt_dict_consumer{payload}); + std::tie(ihid, intermediate) = + PATH::DATA::deserialize_intermediate(oxenc::bt_dict_consumer{payload}); } catch (const std::exception& e) { @@ -1604,29 +1608,52 @@ namespace llarp return; } - // log::debug(logcat, "Inbound path rxid:{}, outbound path txid:{}", hop_id, ihid); + log::debug(logcat, "Inbound path rxid:{}, outbound path txid:{}", hop_id, ihid); - hop = _router.path_context()->get_transit_hop(hop_id); + auto next_hop = _router.path_context()->get_transit_hop(ihid); - if (not hop) + if (not next_hop) { - log::warning(logcat, "We are bridge node for path data message with unknown txID: {}", hop_id); + log::warning(logcat, "We are bridge node for path data message with unknown txID: {}", ihid); return; } - // payload = std::move(intermediate); - log::debug(logcat, "Bridging path data message on hop: {}", hop->to_string()); - } + log::debug(logcat, "Bridging path data message on hop: {}", next_hop->to_string()); - // if not terminal hop, relay datagram onwards - auto hop_is_rx = hop->rxid() == hop_id; + next_ids = next_hop->next_id(ihid); - const auto& next_id = hop_is_rx ? hop->txid() : hop->rxid(); - next_router = hop_is_rx ? hop->upstream() : hop->downstream(); + onion_nonce ^= next_hop->kx.xor_nonce; - new_payload = ONION::serialize_hop(next_id.to_view(), onion_nonce, std::move(payload)); + crypto::onion( + reinterpret_cast(intermediate.data()), + intermediate.size(), + next_hop->kx.shared_secret, + onion_nonce, + next_hop->kx.xor_nonce); + + if (not next_ids) + { + log::error( + logcat, "Failed to query hop ({}) for next ids (input: {})", next_hop->to_string(), hop_id); + return; + } + + next_payload = ONION::serialize_hop(next_ids->second.to_view(), onion_nonce, std::move(intermediate)); + } + else + { + next_ids = hop->next_id(hop_id); + + if (not next_ids) + { + log::error(logcat, "Failed to query hop ({}) for next ids (input: {})", hop->to_string(), hop_id); + return; + } + + next_payload = ONION::serialize_hop(next_ids->second.to_view(), onion_nonce, std::move(payload)); + } - send_data_message(next_router, std::move(new_payload)); + send_data_message(next_ids->first, std::move(next_payload)); }); } diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 38a2db76b8..9f7879e1e3 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -57,6 +57,18 @@ namespace llarp::path return std::move(btdp).str(); } + std::optional> TransitHop::next_id(const HopID& h) const + { + std::optional> ret = std::nullopt; + + if (h == _rxid) + ret = {_upstream, _txid}; + else if (h == _txid) + ret = {_downstream, _rxid}; + + return ret; + } + nlohmann::json TransitHop::ExtractStatus() const { return { diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 54a13cacfe..07d82b24a5 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -51,6 +51,8 @@ namespace llarp HopID txid() { return _txid; } const HopID& txid() const { return _txid; } + std::optional> next_id(const HopID& h) const; + bool operator<(const TransitHop& other) const { return std::tie(_txid, _rxid, _upstream, _downstream) diff --git a/llarp/session/session.cpp b/llarp/session/session.cpp index 43f1200fe0..02d6b1864d 100644 --- a/llarp/session/session.cpp +++ b/llarp/session/session.cpp @@ -22,7 +22,8 @@ namespace llarp::session SessionTag _t, bool use_tun, bool is_outbound, - std::optional kx_data) + std::optional kx_data, + std::optional _remote_intro) : _r{r}, _parent{parent}, _tag{std::move(_t)}, @@ -33,6 +34,8 @@ namespace llarp::session { if (kx_data.has_value()) session_keys = std::move(*kx_data); + if (_remote_intro.has_value()) + remote_intro = std::move(*_remote_intro); set_new_current_path(std::move(_p)); } @@ -48,7 +51,7 @@ namespace llarp::session // session_keys.encrypt(to_uspan(data)); auto inner_payload = PATH::DATA::serialize(std::move(data), _r.local_rid()); auto intermediate_payload = - PATH::DATA::serialize_intermediate(std::move(inner_payload), _current_path->intro.pivot_txid); + PATH::DATA::serialize_intermediate(std::move(inner_payload), remote_intro.pivot_txid); return _r.send_data_message( _current_path->upstream_rid(), _current_path->make_path_message(std::move(intermediate_payload))); } @@ -163,7 +166,8 @@ namespace llarp::session handlers::SessionEndpoint& parent, std::shared_ptr path, SessionTag _t, - std::optional kx_data) + std::optional kx_data, + std::optional remote_intro) : PathHandler{parent._router, path::DEFAULT_PATHS_HELD}, BaseSession{ _router, @@ -173,7 +177,8 @@ namespace llarp::session std::move(_t), _router.using_tun_if(), true, - std::move(kx_data)}, + std::move(kx_data), + std::move(remote_intro)}, _is_snode_session{not _remote.is_client()}, _last_use{_router.now()} { diff --git a/llarp/session/session.hpp b/llarp/session/session.hpp index 24263a63bb..71eac6c511 100644 --- a/llarp/session/session.hpp +++ b/llarp/session/session.hpp @@ -49,6 +49,8 @@ namespace llarp shared_kx_data session_keys{}; + ClientIntro remote_intro; + bool _use_tun; bool _is_outbound; @@ -80,7 +82,8 @@ namespace llarp SessionTag _t, bool use_tun, bool is_outbound, - std::optional kx_data = std::nullopt); + std::optional kx_data = std::nullopt, + std::optional remote_intro = std::nullopt); virtual ~BaseSession() = default; @@ -122,7 +125,8 @@ namespace llarp handlers::SessionEndpoint& parent, std::shared_ptr path, SessionTag _t, - std::optional kx_data = std::nullopt); + std::optional kx_data = std::nullopt, + std::optional remote_intro = std::nullopt); ~OutboundSession() override;