From 41312abab0789d5d916086376959768962215d4d Mon Sep 17 00:00:00 2001 From: dr7ana Date: Tue, 17 Oct 2023 08:42:27 -0700 Subject: [PATCH] introset and message transmission underway - message handling through classes that inherit from PathSet - cleanups around link_manager - etc etc --- llarp/crypto/crypto.cpp | 4 +- llarp/crypto/crypto.hpp | 2 +- llarp/dht/explorenetworkjob.cpp | 1 - llarp/exit/session.cpp | 31 ++- llarp/exit/session.hpp | 41 +-- llarp/handlers/exit.cpp | 8 +- llarp/handlers/null.hpp | 10 +- llarp/handlers/tun.cpp | 4 +- llarp/handlers/tun.hpp | 2 +- llarp/link/link_manager.cpp | 30 +- llarp/link/link_manager.hpp | 12 +- llarp/link/tunnel.cpp | 1 - llarp/messages/path.hpp | 2 +- llarp/path/path.cpp | 34 ++- llarp/path/pathbuilder.cpp | 44 ++- llarp/path/pathbuilder.hpp | 4 - llarp/path/pathset.hpp | 4 +- llarp/router/rc_lookup_handler.cpp | 5 +- llarp/router_contact.hpp | 2 +- llarp/service/endpoint.cpp | 6 - llarp/service/endpoint.hpp | 9 - llarp/service/outbound_context.cpp | 434 ++++++++++------------------- llarp/service/outbound_context.hpp | 113 ++++---- 23 files changed, 328 insertions(+), 475 deletions(-) diff --git a/llarp/crypto/crypto.cpp b/llarp/crypto/crypto.cpp index 471fa3187..b30cd8c0e 100644 --- a/llarp/crypto/crypto.cpp +++ b/llarp/crypto/crypto.cpp @@ -457,9 +457,9 @@ namespace llarp return crypto_sign_ed25519_seed_keypair(secret.data() + 32, secret.data(), seed.data()) != -1; } void - Crypto::randomize(const llarp_buffer_t& buff) + Crypto::randomize(uint8_t* buf, size_t len) { - randombytes((unsigned char*)buff.base, buff.sz); + randombytes(buf, len); } void diff --git a/llarp/crypto/crypto.hpp b/llarp/crypto/crypto.hpp index 25d7b2705..a8f75a5f0 100644 --- a/llarp/crypto/crypto.hpp +++ b/llarp/crypto/crypto.hpp @@ -98,7 +98,7 @@ namespace llarp seed_to_secretkey(llarp::SecretKey&, const llarp::IdentitySecret&); /// randomize buffer void - randomize(const llarp_buffer_t&); + randomize(uint8_t* buf, size_t len); /// randomizer memory void randbytes(byte_t*, size_t); diff --git a/llarp/dht/explorenetworkjob.cpp b/llarp/dht/explorenetworkjob.cpp index 485228b3b..e0b96dd67 100644 --- a/llarp/dht/explorenetworkjob.cpp +++ b/llarp/dht/explorenetworkjob.cpp @@ -1,6 +1,5 @@ #include "explorenetworkjob.hpp" -#include #include #include diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index b9b5a498f..fe6b9832c 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -21,8 +21,8 @@ namespace llarp::exit : llarp::path::Builder{r, numpaths, hoplen} , exit_router{routerId} , packet_write_func{std::move(writepkt)} - , m_Counter{0} - , m_LastUse{r->now()} + , _counter{0} + , _last_use{r->now()} , m_BundleRC{false} , m_Parent{parent} { @@ -41,7 +41,7 @@ namespace llarp::exit BaseSession::ExtractStatus() const { auto obj = path::Builder::ExtractStatus(); - obj["lastExitUse"] = to_json(m_LastUse); + obj["lastExitUse"] = to_json(_last_use); auto pub = exit_key.toPublic(); obj["exitIdentity"] = pub.ToString(); obj["endpoint"] = exit_router.ToString(); @@ -80,8 +80,8 @@ namespace llarp::exit return std::vector{*maybe}; return std::nullopt; } - else - return GetHopsAlignedToForBuild(exit_router); + + return GetHopsAlignedToForBuild(exit_router); } bool @@ -204,7 +204,7 @@ namespace llarp::exit llarp::net::IPPacket pkt{buf.view_all()}; if (pkt.empty()) return false; - m_LastUse = router->now(); + _last_use = router->now(); m_Downstream.emplace(counter, pkt); return true; } @@ -231,7 +231,7 @@ namespace llarp::exit { queue.emplace_back(); queue.back().protocol = t; - return queue.back().PutBuffer(llarp_buffer_t{pkt}, m_Counter++); + return queue.back().PutBuffer(llarp_buffer_t{pkt}, _counter++); } auto& back = queue.back(); // pack to nearest N @@ -239,10 +239,10 @@ namespace llarp::exit { queue.emplace_back(); queue.back().protocol = t; - return queue.back().PutBuffer(llarp_buffer_t{pkt}, m_Counter++); + return queue.back().PutBuffer(llarp_buffer_t{pkt}, _counter++); } back.protocol = t; - return back.PutBuffer(llarp_buffer_t{pkt}, m_Counter++); + return back.PutBuffer(llarp_buffer_t{pkt}, _counter++); } bool @@ -257,7 +257,7 @@ namespace llarp::exit bool BaseSession::IsExpired(llarp_time_t now) const { - return now > m_LastUse && now - m_LastUse > LifeSpan; + return now > _last_use && now - _last_use > LifeSpan; } bool @@ -296,6 +296,7 @@ namespace llarp::exit for (auto& [i, queue] : m_Upstream) queue.clear(); m_Upstream.clear(); + if (numHops == 1) { auto r = router; @@ -374,23 +375,25 @@ namespace llarp::exit } void - SNodeSession::SendPacketToRemote(const llarp_buffer_t& buf, service::ProtocolType t) + ExitSession::send_packet_to_remote(std::string buf) { net::IPPacket pkt{buf.view_all()}; if (pkt.empty()) return; pkt.ZeroAddresses(); - QueueUpstreamTraffic(std::move(pkt), llarp::routing::EXIT_PAD_SIZE, t); + + // QueueUpstreamTraffic(std::move(pkt), llarp::routing::EXIT_PAD_SIZE, t); } void - ExitSession::SendPacketToRemote(const llarp_buffer_t& buf, service::ProtocolType t) + SNodeSession::send_packet_to_remote(std::string buf) { net::IPPacket pkt{buf.view_all()}; if (pkt.empty()) return; pkt.ZeroSourceAddress(); - QueueUpstreamTraffic(std::move(pkt), llarp::routing::EXIT_PAD_SIZE, t); + + // QueueUpstreamTraffic(std::move(pkt), llarp::routing::EXIT_PAD_SIZE, t); } } // namespace llarp::exit diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index c55b63185..1c9810b0c 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -61,12 +61,6 @@ namespace llarp util::StatusObject ExtractStatus() const; - bool - ShouldBundleRC() const override - { - return m_BundleRC; - } - void ResetInternalState() override; @@ -140,9 +134,6 @@ namespace llarp llarp::SecretKey exit_key; std::function packet_write_func; - virtual void - PopulateRequest(llarp::routing::ObtainExitMessage& msg) const = 0; - bool HandleTrafficDrop(llarp::path::Path_ptr p, const llarp::PathID_t& path, uint64_t s); @@ -159,8 +150,6 @@ namespace llarp private: std::set snode_blacklist; - std::map> m_Upstream; - PathID_t m_CurrentPath; using DownstreamPkt = std::pair; @@ -174,12 +163,8 @@ namespace llarp } }; - using DownstreamTrafficQueue_t = - std::priority_queue, DownstreamPktSorter>; - DownstreamTrafficQueue_t m_Downstream; - - uint64_t m_Counter; - llarp_time_t m_LastUse; + uint64_t _counter; + llarp_time_t _last_use; std::vector m_PendingCallbacks; const bool m_BundleRC; @@ -207,16 +192,7 @@ namespace llarp Name() const override; void - SendPacketToRemote(const llarp_buffer_t& pkt, service::ProtocolType t) override; - - protected: - void - PopulateRequest(llarp::routing::ObtainExitMessage& msg) const override - { - // TODO: set expiration time - // msg.address_lifetime = 0; - msg.flag = 1; - } + send_packet_to_remote(std::string buf) override; }; struct SNodeSession final : public BaseSession @@ -236,16 +212,7 @@ namespace llarp Name() const override; void - SendPacketToRemote(const llarp_buffer_t& pkt, service::ProtocolType t) override; - - protected: - void - PopulateRequest(llarp::routing::ObtainExitMessage& msg) const override - { - // TODO: set expiration time - // msg.address_lifetime = 0; - msg.flag = 0; - } + send_packet_to_remote(std::string buf) override; }; } // namespace exit diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index 9c8ee2cb5..0b1ec7a72 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -114,10 +114,10 @@ namespace llarp::handlers if (not router->PathToRouterAllowed(*rid)) return false; - ObtainSNodeSession(*rid, [pkt = payload.copy(), type](auto session) mutable { + ObtainSNodeSession(*rid, [pkt = std::move(payload)](auto session) mutable { if (session and session->IsReady()) { - session->SendPacketToRemote(std::move(pkt), type); + session->send_packet_to_remote(std::move(pkt)); } }); } @@ -381,7 +381,7 @@ namespace llarp::handlers maybe_pk = itr->second; } - auto buf = const_cast(top).steal(); + auto buf = const_cast(top); inet_to_network.pop(); // we have no session for public key so drop if (not maybe_pk) @@ -398,7 +398,7 @@ namespace llarp::handlers auto itr = snode_sessions.find(pk); if (itr != snode_sessions.end()) { - itr->second->SendPacketToRemote(std::move(buf), service::ProtocolType::TrafficV4); + itr->second->send_packet_to_remote(buf.to_string()); // we are in a while loop continue; } diff --git a/llarp/handlers/null.hpp b/llarp/handlers/null.hpp index 4d5202fe0..1d216456a 100644 --- a/llarp/handlers/null.hpp +++ b/llarp/handlers/null.hpp @@ -1,8 +1,8 @@ #pragma once +#include #include #include -#include #include #include #include @@ -25,7 +25,7 @@ namespace llarp::handlers r->loop()->add_ticker([this] { Pump(Now()); }); } - virtual bool + bool HandleInboundPacket( const service::ConvoTag tag, const llarp_buffer_t& buf, @@ -74,6 +74,9 @@ namespace llarp::handlers return true; } + void + send_packet_to_remote(std::string) override {}; + std::string GetIfName() const override { @@ -98,9 +101,6 @@ namespace llarp::handlers return false; } - void - SendPacketToRemote(const llarp_buffer_t&, service::ProtocolType) override{}; - huint128_t ObtainIPForAddr(std::variant) override { diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 54060d28c..c313a235e 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -1254,12 +1254,12 @@ namespace llarp::handlers EnsurePathToService( addr, - [pkt, extra_cb, this](service::Address addr, service::OutboundContext* ctx) { + [pkt, extra_cb, this](service::Address addr, service::OutboundContext* ctx) mutable { if (ctx) { if (extra_cb) extra_cb(); - ctx->SendPacketToRemote(pkt.ConstBuffer(), service::ProtocolType::Exit); + ctx->send_packet_to_remote(pkt.to_string()); router()->TriggerPump(); return; } diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 351373567..89d07f1c9 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -73,7 +73,7 @@ namespace llarp::handlers Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) override; void - SendPacketToRemote(const llarp_buffer_t&, service::ProtocolType) override{}; + send_packet_to_remote(std::string) override{}; std::string GetIfName() const override; diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 73a060816..610a24515 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -512,12 +512,6 @@ namespace llarp // TODO: this } - std::string - LinkManager::serialize_response(oxenc::bt_dict supplement) - { - return oxenc::bt_serialize(supplement); - } - void LinkManager::handle_find_name(oxen::quic::message m) { @@ -537,8 +531,7 @@ namespace llarp _router.rpc_client()->lookup_ons_hash( name_hash, - [this, - msg = std::move(m)]([[maybe_unused]] std::optional maybe) mutable { + [msg = std::move(m)]([[maybe_unused]] std::optional maybe) mutable { if (maybe) msg.respond(serialize_response({{"NAME", maybe->ciphertext}})); else @@ -1644,4 +1637,25 @@ namespace llarp return; } } + + void + LinkManager::handle_path_control(oxen::quic::message m) + { + if (m.timed_out) + { + log::info(link_cat, "Path control message timed out!"); + return; + } + + try + { + + } + catch (const std::exception& e) + { + log::warning(link_cat, "Exception: {}", e.what()); + return; + } + } + } // namespace llarp diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index 03b5aca3c..c7f11e01c 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -28,6 +28,12 @@ namespace llarp { struct LinkManager; + inline std::string + serialize_response(oxenc::bt_dict supplement = {}) + { + return oxenc::bt_serialize(supplement); + } + namespace link { struct Connection; @@ -316,6 +322,9 @@ namespace llarp {"obtain_exit", &LinkManager::handle_obtain_exit}, {"close_exit", &LinkManager::handle_close_exit}}; + // Path relaying + void handle_path_control(oxen::quic::message); + // DHT responses void handle_find_name_response(oxen::quic::message); void handle_find_intro_response(oxen::quic::message); @@ -344,9 +353,6 @@ namespace llarp {"obtain_exit", &LinkManager::handle_obtain_exit_response}, {"close_exit", &LinkManager::handle_close_exit_response}}; - std::string - serialize_response(oxenc::bt_dict supplement = {}); - public: // Public response functions and error handling functions invoked elsehwere. These take // r-value references s.t. that message is taken out of calling scope diff --git a/llarp/link/tunnel.cpp b/llarp/link/tunnel.cpp index 3e85a0836..0c5fa5bb4 100644 --- a/llarp/link/tunnel.cpp +++ b/llarp/link/tunnel.cpp @@ -2,7 +2,6 @@ #include #include #include -#include "stream.hpp" #include #include #include diff --git a/llarp/messages/path.hpp b/llarp/messages/path.hpp index f2e60c424..c12e7930a 100644 --- a/llarp/messages/path.hpp +++ b/llarp/messages/path.hpp @@ -108,8 +108,8 @@ namespace llarp oxenc::bt_dict_producer btdp; - btdp.append("HASH", hash); btdp.append("FRAME", hashed_data); + btdp.append("HASH", hash); return std::move(btdp).str(); } diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 09979af63..9884532e1 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -107,33 +107,41 @@ namespace llarp::path Path::send_path_control_message( std::string method, std::string body, std::function func) { - oxenc::bt_dict_producer btdp; - btdp.append("METHOD", method); - btdp.append("BODY", body); - auto payload = std::move(btdp).str(); - auto* payload_ptr = reinterpret_cast(payload.data()); + std::string payload; - // TODO: old impl padded messages if smaller than a certain size; do we still want to? - - auto crypto = CryptoManager::instance(); + { + oxenc::bt_dict_producer btdp; + btdp.append("BODY", body); + btdp.append("METHOD", method); + payload = std::move(btdp).str(); + } TunnelNonce nonce; - outer_nonce.Randomize(); + nonce.Randomize(); + for (const auto& hop : hops) { // do a round of chacha for each hop and mutate the nonce with that hop's nonce - CryptoManager::instance()->xchacha20(payload_ptr, hop.shared, nonce); + CryptoManager::instance()->xchacha20( + reinterpret_cast(payload.data()), payload.size(), hop.shared, nonce); + nonce ^= hop.nonceXOR; } oxenc::bt_dict_producer outer_dict; - outer_dict.append("PATHID", TXID().ToView()); outer_dict.append("NONCE", nonce.ToView()); + outer_dict.append("PATHID", TXID().ToView()); outer_dict.append("PAYLOAD", payload); - return router.send_control_message( - upstream(), "path_control", std::move(outer_dict.str()), std::move(func)); + upstream(), + "path_control", + std::move(outer_dict).str(), + [response_cb = std::move(func)](oxen::quic::message m) { + { + // do path hop logic here + } + }); } bool diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 7123ffd8f..c3243893c 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -20,7 +20,7 @@ namespace llarp { namespace { - auto log_path = log::Cat("path"); + auto path_cat = log::Cat("path"); } namespace path @@ -326,7 +326,7 @@ namespace llarp const auto maybe = SelectFirstHop(exclude); if (not maybe.has_value()) { - log::warning(log_path, "{} has no first hop candidate", Name()); + log::warning(path_cat, "{} has no first hop candidate", Name()); return std::nullopt; } hops.emplace_back(*maybe); @@ -465,22 +465,44 @@ namespace llarp router->path_context().AddOwnPath(self, path); PathBuildStarted(path); - auto response_cb = [self](oxen::quic::message) { - // TODO: this (replaces handling LRSM, which also needs replacing) - - // TODO: Talk to Tom about why are we using it as a response callback? - // Do you mean TransitHop::HandleLRSM? + // TODO: + // Path build fail and success are handled poorly at best and changing how we + // 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) { + if (m) + { + std::string status; + + try + { + 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; + } + + // TODO: success logic + } + else + { + log::warning(path_cat, "Path build request returned failure {}"); + // TODO: failure logic + } }; if (not router->send_control_message( path->upstream(), "path_build", std::move(frames).str(), std::move(response_cb))) { - log::warning(log_path, "Error sending path_build control message"); + log::warning(path_cat, "Error sending path_build control message"); + // TODO: inform failure (what this means needs revisiting, badly) path->EnterState(path::ePathFailed, router->now()); } - - // TODO: we don't use this concept anymore? - router->persist_connection_until(path->upstream(), path->ExpireTime()); } void diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index c2c8548ab..1886e57d2 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -73,10 +73,6 @@ namespace llarp::path bool ShouldBuildMore(llarp_time_t now) const override; - /// should we bundle RCs in builds? - virtual bool - ShouldBundleRC() const = 0; - void ResetInternalState() override; diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index cfd8c1c74..adb2ca112 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -140,7 +140,7 @@ namespace llarp virtual void HandlePathBuildFailedAt(Path_ptr path, RouterID hop); - virtual void + void PathBuildStarted(Path_ptr path); /// a path died now what? @@ -249,7 +249,7 @@ namespace llarp BuildOneAlignedTo(const RouterID endpoint) = 0; virtual void - SendPacketToRemote(const llarp_buffer_t& pkt, service::ProtocolType t) = 0; + send_packet_to_remote(std::string buf) = 0; virtual std::optional> GetHopsForBuild() = 0; diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index d2b6f8aa1..d40a8e59c 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -110,7 +110,7 @@ namespace llarp else { r.node_db()->put_rc_if_newer(result); - r.connect_to(result); + // r.connect_to(result); } } else @@ -306,7 +306,8 @@ namespace llarp { for (const auto& rc : bootstrap_rc_list) { - LogInfo("Doing explore via bootstrap node: ", RouterID(rc.pubkey)); + log::info(link_cat, "Doing explore via bootstrap node: {}", RouterID(rc.pubkey)); + // TODO: replace this concept // dht->ExploreNetworkVia(dht::Key_t{rc.pubkey}); } diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 677536263..a1c7e450c 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -64,7 +64,7 @@ namespace llarp { /// for unit tests static bool BlockBogons; - + static llarp_time_t Lifetime; static llarp_time_t UpdateInterval; static llarp_time_t StaleInsertionAge; diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 70faaeef9..67a9300be 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -779,12 +779,6 @@ namespace llarp::service return path::Builder::GetHopsAlignedToForBuild(endpoint, SnodeBlacklist()); } - void - Endpoint::PathBuildStarted(path::Path_ptr path) - { - path::Builder::PathBuildStarted(path); - } - constexpr auto MaxOutboundContextPerRemote = 1; void diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index c2ea6c862..9051566bf 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -304,12 +304,6 @@ namespace llarp /// this MUST be called if you want to call EnsurePathTo on the given address void MarkAddressOutbound(service::Address) override; - bool - ShouldBundleRC() const override - { - return false; - } - void BlacklistSNode(const RouterID snode) override; @@ -426,9 +420,6 @@ namespace llarp std::optional> GetHopsForBuildWithEndpoint(RouterID endpoint); - void - PathBuildStarted(path::Path_ptr path) override; - void AsyncProcessAuthMessage( std::shared_ptr msg, std::function hook); diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 18a920c1e..e9077956b 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -17,46 +17,27 @@ namespace llarp::service bool OutboundContext::Stop() { - markedBad = true; + marked_bad = true; return path::Builder::Stop(); } bool - OutboundContext::IsDone(llarp_time_t now) const + OutboundContext::IsDone(std::chrono::milliseconds now) const { (void)now; return AvailablePaths(path::ePathRoleAny) == 0 && ShouldRemove(); } - bool - OutboundContext::ShouldBundleRC() const - { - return service_endpoint->ShouldBundleRC(); - } - - bool - OutboundContext::HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t seq) - { - // pick another intro - if (dst == remoteIntro.path_id && remoteIntro.router == p->Endpoint()) - { - LogWarn(Name(), " message ", seq, " dropped by endpoint ", p->Endpoint(), " via ", dst); - markedBad = remoteIntro.IsExpired(Now()); - MarkCurrentIntroBad(Now()); - ShiftIntroRouter(p->Endpoint()); - UpdateIntroSet(); - } - return true; - } - constexpr auto OutboundContextNumPaths = 4; OutboundContext::OutboundContext(const IntroSet& introset, Endpoint* parent) : path::Builder{parent->router(), OutboundContextNumPaths, parent->numHops} - , SendContext{introset.address_keys, {}, this, parent} - , location{introset.address_keys.Addr().ToKey()} - , addr{introset.address_keys.Addr()} - , currentIntroSet{introset} + , ep{*parent} + , current_intro{introset} + , location{current_intro.address_keys.Addr().ToKey()} + , addr{current_intro.address_keys.Addr()} + , remote_identity{current_intro.address_keys} + , created_at{ep.Now()} { assert(not introset.intros.empty()); @@ -69,29 +50,29 @@ namespace llarp::service CSRNG rng{}; it += std::uniform_int_distribution{0, introset.intros.size() - 1}(rng); } - m_NextIntro = *it; - currentConvoTag.Randomize(); - lastShift = Now(); + next_intro = *it; + current_tag.Randomize(); + last_shift = Now(); // add send and connect timeouts to the parent endpoints path alignment timeout // this will make it so that there is less of a chance for timing races - sendTimeout += parent->PathAlignmentTimeout(); - connectTimeout += parent->PathAlignmentTimeout(); + send_timeout += parent->PathAlignmentTimeout(); + connect_timeout += parent->PathAlignmentTimeout(); } OutboundContext::~OutboundContext() = default; /// actually swap intros void - OutboundContext::SwapIntros() + OutboundContext::swap_intros() { - if (remoteIntro != m_NextIntro) + if (remote_intro != next_intro) { - remoteIntro = m_NextIntro; - service_endpoint->PutSenderFor(currentConvoTag, currentIntroSet.address_keys, false); - service_endpoint->PutIntroFor(currentConvoTag, remoteIntro); - ShiftIntroRouter(m_NextIntro.router); + remote_intro = next_intro; + ep.PutSenderFor(current_tag, current_intro.address_keys, false); + ep.PutIntroFor(current_tag, remote_intro); + ShiftIntroRouter(next_intro.router); // if we have not made a handshake to the remote endpoint do so - if (not IntroGenerated()) + if (not generated_intro) { KeepAlive(); } @@ -109,10 +90,10 @@ namespace llarp::service const Address&, std::optional foundIntro, const RouterID& endpoint, - llarp_time_t, + std::chrono::milliseconds, uint64_t relayOrder) { - if (markedBad) + if (marked_bad) return true; updatingIntroSet = false; if (foundIntro) @@ -122,25 +103,25 @@ namespace llarp::service LogWarn(Name(), " got introset with zero timestamp: ", *foundIntro); return true; } - if (currentIntroSet.time_signed > foundIntro->time_signed) + if (current_intro.time_signed > foundIntro->time_signed) { LogInfo("introset is old, dropping"); return true; } - const llarp_time_t now = Now(); + const std::chrono::milliseconds now = Now(); if (foundIntro->IsExpired(now)) { LogError("got expired introset from lookup from ", endpoint); return true; } - currentIntroSet = *foundIntro; + current_intro = *foundIntro; ShiftIntroRouter(RouterID{}); } else if (relayOrder > 0) { - ++m_LookupFails; - LogWarn(Name(), " failed to look up introset, fails=", m_LookupFails); + ++lookup_fails; + LogWarn(Name(), " failed to look up introset, fails=", lookup_fails); } return true; } @@ -148,11 +129,11 @@ namespace llarp::service bool OutboundContext::ReadyToSend() const { - if (markedBad) + if (marked_bad) return false; - if (remoteIntro.router.IsZero()) + if (remote_intro.router.IsZero()) return false; - return IntroSent() and GetPathByRouter(remoteIntro.router); + return sent_intro and GetPathByRouter(remote_intro.router); } void @@ -160,7 +141,7 @@ namespace llarp::service { const auto now = Now(); Introduction selectedIntro{}; - for (const auto& intro : currentIntroSet.intros) + for (const auto& intro : current_intro.intros) { if (intro.expiry > selectedIntro.expiry and intro.router != r) { @@ -169,8 +150,8 @@ namespace llarp::service } if (selectedIntro.router.IsZero() || selectedIntro.ExpiresSoon(now)) return; - m_NextIntro = selectedIntro; - lastShift = now; + next_intro = selectedIntro; + last_shift = now; } void @@ -195,86 +176,86 @@ namespace llarp::service OutboundContext::HandlePathBuilt(path::Path_ptr p) { path::Builder::HandlePathBuilt(p); - p->SetDataHandler([self = weak_from_this()](auto path, auto frame) { - if (auto ptr = self.lock()) - return ptr->HandleHiddenServiceFrame(path, frame); - return false; - }); - p->SetDropHandler([self = weak_from_this()](auto path, auto id, auto seqno) { - if (auto ptr = self.lock()) - return ptr->HandleDataDrop(path, id, seqno); - return false; - }); - if (markedBad) + // p->SetDataHandler([self = weak_from_this()](auto path, auto frame) { + // if (auto ptr = self.lock()) + // return ptr->HandleHiddenServiceFrame(path, frame); + // return false; + // }); + // p->SetDropHandler([self = weak_from_this()](auto path, auto id, auto seqno) { + // if (auto ptr = self.lock()) + // return ptr->HandleDataDrop(path, id, seqno); + // return false; + // }); + if (marked_bad) { // ignore new path if we are marked dead LogInfo(Name(), " marked bad, ignoring new path"); p->EnterState(path::ePathIgnore, Now()); } - else if (p->Endpoint() == m_NextIntro.router) + else if (p->Endpoint() == next_intro.router) { // we now have a path to the next intro, swap intros - SwapIntros(); + swap_intros(); } } void OutboundContext::AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t) { - if (generatedIntro) + if (generated_intro) { LogWarn(Name(), " dropping packet as we are not fully handshaked right now"); return; } - if (remoteIntro.router.IsZero()) + if (remote_intro.router.IsZero()) { LogWarn(Name(), " dropping intro frame we have no intro ready yet"); return; } - auto path = GetPathByRouter(remoteIntro.router); + auto path = GetPathByRouter(remote_intro.router); if (path == nullptr) { - LogError(Name(), " has no path to ", remoteIntro.router, " when we should have had one"); + LogError(Name(), " has no path to ", remote_intro.router, " when we should have had one"); return; } auto frame = std::make_shared(); frame->clear(); auto ex = std::make_shared( - service_endpoint->Loop(), - remoteIdent, - service_endpoint->GetIdentity(), - currentIntroSet.sntru_pubkey, - remoteIntro, - service_endpoint, - currentConvoTag, + ep.Loop(), + remote_identity, + ep.GetIdentity(), + current_intro.sntru_pubkey, + remote_intro, + ep, + current_tag, t); ex->hook = [self = shared_from_this(), path](auto frame) { if (not self->Send(std::move(frame), path)) return; - self->service_endpoint->Loop()->call_later( - self->remoteIntro.latency, [self]() { self->sentIntro = true; }); + self->ep.Loop()->call_later( + self->remote_intro.latency, [self]() { self->sent_intro = true; }); }; ex->msg.PutBuffer(payload); ex->msg.introReply = path->intro; frame->path_id = ex->msg.introReply.path_id; frame->flag = 0; - generatedIntro = true; + generated_intro = true; // ensure we have a sender put for this convo tag - service_endpoint->PutSenderFor(currentConvoTag, currentIntroSet.address_keys, false); + ep.PutSenderFor(current_tag, current_intro.address_keys, false); // encrypt frame async - service_endpoint->router()->queue_work( + ep.router()->queue_work( [ex, frame] { return AsyncKeyExchange::Encrypt(ex, frame); }); - LogInfo(Name(), " send intro frame T=", currentConvoTag); + LogInfo(Name(), " send intro frame T=", current_tag); } std::string OutboundContext::Name() const { - return "OBContext:" + currentIntroSet.address_keys.Addr().ToString(); + return "OBContext:" + current_intro.address_keys.Addr().ToString(); } void @@ -282,14 +263,17 @@ namespace llarp::service { constexpr auto IntrosetUpdateInterval = 10s; const auto now = Now(); - if (updatingIntroSet or markedBad or now < m_LastIntrosetUpdateAt + IntrosetUpdateInterval) + if (updatingIntroSet or marked_bad or now < last_introset_update + IntrosetUpdateInterval) return; - LogInfo(Name(), " updating introset"); - m_LastIntrosetUpdateAt = now; + + log::info(link_cat, "{} updating introset", Name()); + last_introset_update = now; + // we want to use the parent endpoint's paths because outbound context // does not implement path::PathSet::HandleGotIntroMessage - const auto paths = GetManyPathsWithUniqueEndpoints(service_endpoint, 2, location); + const auto paths = GetManyPathsWithUniqueEndpoints(&ep, 2, location); [[maybe_unused]] uint64_t relayOrder = 0; + for ([[maybe_unused]] const auto& path : paths) { // TODO: implement this @@ -314,19 +298,17 @@ namespace llarp::service OutboundContext::ExtractStatus() const { auto obj = path::Builder::ExtractStatus(); - obj["estimatedRTT"] = to_json(estimatedRTT); - obj["currentConvoTag"] = currentConvoTag.ToHex(); - obj["remoteIntro"] = remoteIntro.ExtractStatus(); - obj["sessionCreatedAt"] = to_json(createdAt); - obj["lastGoodSend"] = to_json(lastGoodSend); - obj["lastRecv"] = to_json(m_LastInboundTraffic); - obj["lastIntrosetUpdate"] = to_json(m_LastIntrosetUpdateAt); - obj["seqno"] = sequenceNo; - obj["markedBad"] = markedBad; - obj["lastShift"] = to_json(lastShift); - obj["remoteIdentity"] = addr.ToString(); - obj["currentRemoteIntroset"] = currentIntroSet.ExtractStatus(); - obj["nextIntro"] = m_NextIntro.ExtractStatus(); + obj["current_tag"] = current_tag.ToHex(); + obj["remote_intro"] = remote_intro.ExtractStatus(); + obj["session_created"] = to_json(created_at); + obj["last_send"] = to_json(last_send); + obj["lastRecv"] = to_json(last_inbound_traffic); + obj["lastIntrosetUpdate"] = to_json(last_introset_update); + obj["marked_bad"] = marked_bad; + obj["last_shift"] = to_json(last_shift); + obj["remote_identityity"] = addr.ToString(); + obj["currentRemote_introset"] = current_intro.ExtractStatus(); + obj["nextIntro"] = next_intro.ExtractStatus(); obj["readyToSend"] = ReadyToSend(); return obj; } @@ -334,43 +316,45 @@ namespace llarp::service void OutboundContext::KeepAlive() { - std::array tmp; - llarp_buffer_t buf{tmp}; - CryptoManager::instance()->randomize(buf); + ustring buf(64, '\0'); + + CryptoManager::instance()->randomize(buf.data(), buf.size()); + SendPacketToRemote(buf, ProtocolType::Control); - m_LastKeepAliveAt = Now(); + + last_keep_alive = Now(); } bool - OutboundContext::Pump(llarp_time_t now) + OutboundContext::Pump(std::chrono::milliseconds now) { - if (ReadyToSend() and remoteIntro.router.IsZero()) + if (ReadyToSend() and remote_intro.router.IsZero()) { - SwapIntros(); + swap_intros(); } if (ReadyToSend()) { // if we dont have a cached session key after sending intro we are in a fugged state so // expunge SharedSecret discardme; - if (not service_endpoint->GetCachedSessionKeyFor(currentConvoTag, discardme)) + if (not ep.GetCachedSessionKeyFor(current_tag, discardme)) { LogError(Name(), " no cached key after sending intro, we are in a fugged state, oh no"); return true; } } - if (m_GotInboundTraffic and m_LastInboundTraffic + sendTimeout <= now) + if (got_inbound_traffic and last_inbound_traffic + send_timeout <= now) { // timeout on other side UpdateIntroSet(); MarkCurrentIntroBad(now); - ShiftIntroRouter(remoteIntro.router); + ShiftIntroRouter(remote_intro.router); } // check for stale intros // update the introset if we think we need to - if (currentIntroSet.HasStaleIntros(now, path::INTRO_PATH_SPREAD) - or remoteIntro.ExpiresSoon(now, path::INTRO_PATH_SPREAD)) + if (current_intro.HasStaleIntros(now, path::INTRO_PATH_SPREAD) + or remote_intro.ExpiresSoon(now, path::INTRO_PATH_SPREAD)) { UpdateIntroSet(); ShiftIntroduction(false); @@ -378,11 +362,11 @@ namespace llarp::service if (ReadyToSend()) { - if (not remoteIntro.router.IsZero() and not GetPathByRouter(remoteIntro.router)) + if (not remote_intro.router.IsZero() and not GetPathByRouter(remote_intro.router)) { // pick another good intro if we have no path on our current intro std::vector otherIntros; - ForEachPath([now, router = remoteIntro.router, &otherIntros](auto path) { + ForEachPath([now, router = remote_intro.router, &otherIntros](auto path) { if (path and path->IsReady() and path->Endpoint() != router and not path->ExpiresSoon(now, path::INTRO_PATH_SPREAD)) { @@ -392,33 +376,30 @@ namespace llarp::service if (not otherIntros.empty()) { std::shuffle(otherIntros.begin(), otherIntros.end(), CSRNG{}); - remoteIntro = otherIntros[0]; + remote_intro = otherIntros[0]; } } } // lookup router in intro if set and unknown - if (not m_NextIntro.router.IsZero()) - service_endpoint->EnsureRouterIsKnown(m_NextIntro.router); + if (not next_intro.router.IsZero()) + ep.EnsureRouterIsKnown(next_intro.router); - if (ReadyToSend() and not m_ReadyHooks.empty()) + if (ReadyToSend() and not ready_hooks.empty()) { - const auto path = GetPathByRouter(remoteIntro.router); + const auto path = GetPathByRouter(remote_intro.router); if (not path) { - LogWarn(Name(), " ready but no path to ", remoteIntro.router, " ???"); + LogWarn(Name(), " ready but no path to ", remote_intro.router, " ???"); return true; } - for (const auto& hook : m_ReadyHooks) - hook(this); - m_ReadyHooks.clear(); } - const auto timeout = std::max(lastGoodSend, m_LastInboundTraffic); - if (lastGoodSend > 0s and now >= timeout + (sendTimeout / 2)) + const auto timeout = std::max(last_send, last_inbound_traffic); + if (last_send > 0s and now >= timeout + (send_timeout / 2)) { // send a keep alive to keep this session alive KeepAlive(); - if (markedBad) + if (marked_bad) { LogWarn(Name(), " keepalive timeout hit"); return true; @@ -426,14 +407,14 @@ namespace llarp::service } // check for half open state where we can send but we get nothing back - if (m_LastInboundTraffic == 0s and now - createdAt > connectTimeout) + if (last_inbound_traffic == 0s and now - created_at > connect_timeout) { LogWarn(Name(), " half open state, we can send but we got nothing back"); return true; } // if we are dead return true so we are removed - const bool removeIt = timeout > 0s ? (now >= timeout && now - timeout > sendTimeout) - : (now >= createdAt && now - createdAt > connectTimeout); + const bool removeIt = timeout > 0s ? (now >= timeout && now - timeout > send_timeout) + : (now >= created_at && now - created_at > connect_timeout); if (removeIt) { LogInfo(Name(), " session is stale"); @@ -442,42 +423,22 @@ namespace llarp::service return false; } - void - OutboundContext::AddReadyHook(std::function hook, llarp_time_t timeout) - { - if (ReadyToSend()) - { - hook(this); - return; - } - if (m_ReadyHooks.empty()) - { - router->loop()->call_later(timeout, [this]() { - LogWarn(Name(), " did not obtain session in time"); - for (const auto& hook : m_ReadyHooks) - hook(nullptr); - m_ReadyHooks.clear(); - }); - } - m_ReadyHooks.push_back(hook); - } - std::optional> OutboundContext::GetHopsForBuild() { - if (m_NextIntro.router.IsZero()) + if (next_intro.router.IsZero()) { ShiftIntroduction(false); } - if (m_NextIntro.router.IsZero()) + if (next_intro.router.IsZero()) return std::nullopt; - return GetHopsAlignedToForBuild(m_NextIntro.router, service_endpoint->SnodeBlacklist()); + return GetHopsAlignedToForBuild(next_intro.router, ep.SnodeBlacklist()); } bool - OutboundContext::ShouldBuildMore(llarp_time_t now) const + OutboundContext::ShouldBuildMore(std::chrono::milliseconds now) const { - if (markedBad or path::Builder::BuildCooldownHit(now)) + if (marked_bad or path::Builder::BuildCooldownHit(now)) return false; if (NumInStatus(path::ePathBuilding) >= std::max(numDesiredPaths / size_t{2}, size_t{1})) @@ -491,44 +452,25 @@ namespace llarp::service if (not path->intro.ExpiresSoon(now, path::DEFAULT_LIFETIME - path::INTRO_PATH_SPREAD)) { numValidPaths++; - if (path->intro.router == m_NextIntro.router) + if (path->intro.router == next_intro.router) havePathToNextIntro = true; } }); return numValidPaths < numDesiredPaths or not havePathToNextIntro; } - void - OutboundContext::MarkCurrentIntroBad(llarp_time_t now) - { - MarkIntroBad(remoteIntro, now); - } - - void - OutboundContext::MarkIntroBad(const Introduction&, llarp_time_t) - {} - - bool - OutboundContext::IntroSent() const - { - return sentIntro; - } - - bool - OutboundContext::IntroGenerated() const - { - return generatedIntro; - } - bool OutboundContext::ShiftIntroduction(bool rebuild) { - bool success = false; + bool success = false, shifted = false; const auto now = Now(); - if (abs(now - lastShift) < shiftTimeout) + auto shift_timeout = send_timeout * 5 / 2; + + if (abs(now - last_shift) < shift_timeout) return false; - bool shifted = false; - std::vector intros = currentIntroSet.intros; + + std::vector intros = current_intro.intros; + if (intros.size() > 1) { std::shuffle(intros.begin(), intros.end(), CSRNG{}); @@ -539,14 +481,14 @@ namespace llarp::service { if (intro.ExpiresSoon(now)) continue; - if (service_endpoint->SnodeBlacklist().count(intro.router)) + if (ep.SnodeBlacklist().count(intro.router)) continue; - if (remoteIntro.router == intro.router) + if (remote_intro.router == intro.router) { - if (intro.expiry > m_NextIntro.expiry) + if (intro.expiry > next_intro.expiry) { success = true; - m_NextIntro = intro; + next_intro = intro; } } } @@ -555,28 +497,28 @@ namespace llarp::service /// pick newer intro not on same router for (const auto& intro : intros) { - if (service_endpoint->SnodeBlacklist().count(intro.router)) + if (ep.SnodeBlacklist().count(intro.router)) continue; - service_endpoint->EnsureRouterIsKnown(intro.router); + ep.EnsureRouterIsKnown(intro.router); if (intro.ExpiresSoon(now)) continue; - if (m_NextIntro != intro) + if (next_intro != intro) { - if (intro.expiry > m_NextIntro.expiry) + if (intro.expiry > next_intro.expiry) { - shifted = intro.router != m_NextIntro.router; - m_NextIntro = intro; + shifted = intro.router != next_intro.router; + next_intro = intro; success = true; } } } } - if (m_NextIntro.router.IsZero()) + if (next_intro.router.IsZero()) return false; if (shifted) - lastShift = now; + last_shift = now; if (rebuild && !BuildCooldownHit(Now())) - BuildOneAlignedTo(m_NextIntro.router); + BuildOneAlignedTo(next_intro.router); return success; } @@ -587,7 +529,7 @@ namespace llarp::service UpdateIntroSet(); const RouterID endpoint{path->Endpoint()}; // if a path to our current intro died... - if (endpoint == remoteIntro.router) + if (endpoint == remote_intro.router) { // figure out how many paths to this router we have size_t num = 0; @@ -600,117 +542,33 @@ namespace llarp::service // we have no more paths to this endpoint so we want to pivot off of it MarkCurrentIntroBad(Now()); ShiftIntroRouter(endpoint); - if (m_NextIntro.router != endpoint) - BuildOneAlignedTo(m_NextIntro.router); + if (next_intro.router != endpoint) + BuildOneAlignedTo(next_intro.router); } } } bool - OutboundContext::ShouldKeepAlive(llarp_time_t now) const + OutboundContext::ShouldKeepAlive(std::chrono::milliseconds now) const { - const auto SendKeepAliveInterval = sendTimeout / 2; - if (not m_GotInboundTraffic) + const auto SendKeepAliveInterval = send_timeout / 2; + if (not got_inbound_traffic) return false; - if (m_LastInboundTraffic == 0s) + if (last_inbound_traffic == 0s) return false; - return (now - m_LastKeepAliveAt) >= SendKeepAliveInterval; + return (now - last_keep_alive) >= SendKeepAliveInterval; } void - OutboundContext::Tick(llarp_time_t now) + OutboundContext::Tick(std::chrono::milliseconds now) { path::Builder::Tick(now); if (ShouldKeepAlive(now)) KeepAlive(); } - bool - OutboundContext::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrameMessage& frame) - { - m_LastInboundTraffic = service_endpoint->Now(); - m_GotInboundTraffic = true; - if (frame.flag) - { - // handle discard - ServiceInfo si; - if (!service_endpoint->GetSenderFor(frame.convo_tag, si)) - { - LogWarn("no sender for T=", frame.convo_tag); - return false; - } - // verify source - if (!frame.Verify(si)) - { - LogWarn("signature verification failed, T=", frame.convo_tag); - return false; - } - // remove convotag it doesn't exist - LogWarn("remove convotag T=", frame.convo_tag, " R=", frame.flag); - - AuthResult result{AuthResultCode::eAuthFailed, "unknown reason"}; - if (const auto maybe = AuthResultCodeFromInt(frame.flag)) - result.code = *maybe; - SharedSecret sessionKey{}; - if (service_endpoint->GetCachedSessionKeyFor(frame.convo_tag, sessionKey)) - { - ProtocolMessage msg{}; - if (frame.DecryptPayloadInto(sessionKey, msg)) - { - if (msg.proto == ProtocolType::Auth and not msg.payload.empty()) - { - result.reason = - std::string{reinterpret_cast(msg.payload.data()), msg.payload.size()}; - } - } - } - - service_endpoint->RemoveConvoTag(frame.convo_tag); - if (authResultListener) - { - authResultListener(result); - authResultListener = nullptr; - } - return true; - } - std::function)> hook = nullptr; - if (authResultListener) - { - std::function handler = authResultListener; - authResultListener = nullptr; - hook = [handler](std::shared_ptr msg) { - AuthResult result{AuthResultCode::eAuthAccepted, "OK"}; - if (msg->proto == ProtocolType::Auth and not msg->payload.empty()) - { - result.reason = - std::string{reinterpret_cast(msg->payload.data()), msg->payload.size()}; - } - handler(result); - }; - } - const auto& ident = service_endpoint->GetIdentity(); - if (not frame.AsyncDecryptAndVerify(service_endpoint->Loop(), p, ident, service_endpoint, hook)) - { - // send reset convo tag message - LogError("failed to decrypt and verify frame"); - ProtocolFrameMessage f; - f.flag = 1; - f.convo_tag = frame.convo_tag; - f.path_id = p->intro.path_id; - - f.Sign(ident); - { - LogWarn("invalidating convotag T=", frame.convo_tag); - service_endpoint->RemoveConvoTag(frame.convo_tag); - service_endpoint->_send_queue.tryPushBack( - SendEvent_t{std::make_shared(f, frame.path_id), p}); - } - } - return true; - } - void - OutboundContext::SendPacketToRemote(const llarp_buffer_t& buf, service::ProtocolType t) + OutboundContext::send_packet_to_remote(std::string buf) { AsyncEncryptAndSendTo(buf, t); } diff --git a/llarp/service/outbound_context.hpp b/llarp/service/outbound_context.hpp index 65e9ec8fd..7c2e9f657 100644 --- a/llarp/service/outbound_context.hpp +++ b/llarp/service/outbound_context.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "sendcontext.hpp" +#include #include #include @@ -13,16 +13,51 @@ namespace llarp::service struct Endpoint; /// context needed to initiate an outbound hidden service session - struct OutboundContext : public path::Builder, - public SendContext, + struct OutboundContext : public llarp::path::Builder, public std::enable_shared_from_this { - OutboundContext(const IntroSet& introSet, Endpoint* parent); + private: + Endpoint& ep; + IntroSet current_intro; + Introduction next_intro; + + const dht::Key_t location; + const Address addr; + + ServiceInfo remote_identity; + Introduction remote_intro; + + ConvoTag current_tag; + + uint64_t update_introset_tx = 0; + uint16_t lookup_fails = 0; + uint16_t build_fails = 0; + + bool got_inbound_traffic = false; + bool generated_intro = false; + bool sent_intro = false; + bool marked_bad = false; + + const std::chrono::milliseconds created_at; + std::chrono::milliseconds last_send = 0ms; + std::chrono::milliseconds send_timeout = path::BUILD_TIMEOUT; + std::chrono::milliseconds connect_timeout = send_timeout * 2; + std::chrono::milliseconds last_shift = 0ms; + std::chrono::milliseconds last_inbound_traffic = 0ms; + std::chrono::milliseconds last_introset_update = 0ms; + std::chrono::milliseconds last_keep_alive = 0ms; + + public: + OutboundContext(const IntroSet& introSet, Endpoint* parent); + ~OutboundContext() override; void - Tick(llarp_time_t now) override; + encrypt_and_send(std::string buf); + + void + Tick(std::chrono::milliseconds now) override; util::StatusObject ExtractStatus() const; @@ -30,9 +65,6 @@ namespace llarp::service void BlacklistSNode(const RouterID) override{}; - bool - ShouldBundleRC() const override; - path::PathSet_ptr GetSelf() override { @@ -51,9 +83,6 @@ namespace llarp::service bool Stop() override; - bool - HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t s); - void HandlePathDied(path::Path_ptr p) override; @@ -63,51 +92,41 @@ namespace llarp::service /// update the current selected intro to be a new best introduction /// return true if we have changed intros bool - ShiftIntroduction(bool rebuild = true) override; + ShiftIntroduction(bool rebuild = true); /// shift the intro off the current router it is using void - ShiftIntroRouter(const RouterID remote) override; - - /// mark the current remote intro as bad - void - MarkCurrentIntroBad(llarp_time_t now) override; - - void - MarkIntroBad(const Introduction& marked, llarp_time_t now); + ShiftIntroRouter(const RouterID remote); /// return true if we are ready to send bool ReadyToSend() const; - void - AddReadyHook(std::function readyHook, llarp_time_t timeout); - /// for exits void - SendPacketToRemote(const llarp_buffer_t&, ProtocolType t) override; + send_packet_to_remote(std::string buf) override; bool - ShouldBuildMore(llarp_time_t now) const override; + ShouldBuildMore(std::chrono::milliseconds now) const override; /// pump internal state /// return true to mark as dead bool - Pump(llarp_time_t now); + Pump(std::chrono::milliseconds now); /// return true if it's safe to remove ourselves bool - IsDone(llarp_time_t now) const; + IsDone(std::chrono::milliseconds now) const; bool - CheckPathIsDead(path::Path_ptr p, llarp_time_t dlt); + CheckPathIsDead(path::Path_ptr p, std::chrono::milliseconds dlt); void - AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t) override; + AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t); /// issues a lookup to find the current intro set of the remote service void - UpdateIntroSet() override; + UpdateIntroSet(); void HandlePathBuilt(path::Path_ptr path) override; @@ -121,9 +140,6 @@ namespace llarp::service std::optional> GetHopsForBuild() override; - bool - HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrameMessage& frame); - std::string Name() const override; @@ -131,15 +147,15 @@ namespace llarp::service KeepAlive(); bool - ShouldKeepAlive(llarp_time_t now) const; + ShouldKeepAlive(std::chrono::milliseconds now) const; const IntroSet& GetCurrentIntroSet() const { - return currentIntroSet; + return current_intro; } - llarp_time_t + std::chrono::milliseconds RTT() const; bool @@ -147,33 +163,12 @@ namespace llarp::service const Address& addr, std::optional i, const RouterID& endpoint, - llarp_time_t, + std::chrono::milliseconds, uint64_t relayOrder); private: /// swap remoteIntro with next intro void - SwapIntros(); - - bool - IntroGenerated() const override; - bool - IntroSent() const override; - - const dht::Key_t location; - const Address addr; - uint64_t m_UpdateIntrosetTX = 0; - IntroSet currentIntroSet; - Introduction m_NextIntro; - llarp_time_t lastShift = 0s; - uint16_t m_LookupFails = 0; - uint16_t m_BuildFails = 0; - llarp_time_t m_LastInboundTraffic = 0s; - bool m_GotInboundTraffic = false; - bool generatedIntro = false; - bool sentIntro = false; - std::vector> m_ReadyHooks; - llarp_time_t m_LastIntrosetUpdateAt = 0s; - llarp_time_t m_LastKeepAliveAt = 0s; + swap_intros(); }; } // namespace llarp::service