From 99c29cf05a20032c28684cdc2a5d800300664c51 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 23 Apr 2019 10:28:59 -0400 Subject: [PATCH] prepare for ios/android jazz move to use std::shared_ptr instead of bare pointers so we can multithread everything. --- llarp/exit/endpoint.cpp | 2 +- llarp/exit/endpoint.hpp | 2 +- llarp/exit/session.cpp | 16 ++--- llarp/exit/session.hpp | 12 ++-- llarp/path/path.cpp | 66 ++++++++++--------- llarp/path/path.hpp | 44 +++++++------ llarp/path/pathbuilder.cpp | 31 ++++----- llarp/path/pathbuilder.hpp | 9 ++- llarp/path/pathset.cpp | 33 +++++----- llarp/path/pathset.hpp | 45 +++++-------- llarp/routing/handler.hpp | 5 ++ llarp/service/endpoint.cpp | 47 +++++++------ llarp/service/endpoint.hpp | 20 +++--- .../service/hidden_service_address_lookup.cpp | 4 +- .../service/hidden_service_address_lookup.hpp | 2 +- llarp/service/lookup.cpp | 10 ++- llarp/service/lookup.hpp | 5 +- llarp/service/outbound_context.cpp | 18 ++--- llarp/service/outbound_context.hpp | 10 +-- llarp/service/protocol.cpp | 2 +- llarp/service/protocol.hpp | 3 +- llarp/service/tag_lookup_job.cpp | 4 +- llarp/service/tag_lookup_job.hpp | 4 +- 23 files changed, 203 insertions(+), 191 deletions(-) diff --git a/llarp/exit/endpoint.cpp b/llarp/exit/endpoint.cpp index 58e2d0bc3..b0d4f9067 100644 --- a/llarp/exit/endpoint.cpp +++ b/llarp/exit/endpoint.cpp @@ -190,7 +190,7 @@ namespace llarp return sent; } - llarp::path::IHopHandler* + llarp::path::HopHandler_ptr Endpoint::GetCurrentPath() const { auto router = m_Parent->GetRouter(); diff --git a/llarp/exit/endpoint.hpp b/llarp/exit/endpoint.hpp index 943123d07..309d0da96 100644 --- a/llarp/exit/endpoint.hpp +++ b/llarp/exit/endpoint.hpp @@ -70,7 +70,7 @@ namespace llarp bool UpdateLocalPath(const llarp::PathID_t& nextPath); - llarp::path::IHopHandler* + llarp::path::HopHandler_ptr GetCurrentPath() const; const llarp::PubKey& diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 476a4f158..112508205 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -26,7 +26,7 @@ namespace llarp } void - BaseSession::HandlePathDied(path::Path*) + BaseSession::HandlePathDied(path::Path_ptr) { } @@ -76,13 +76,13 @@ namespace llarp } bool - BaseSession::CheckPathDead(path::Path*, llarp_time_t dlt) + BaseSession::CheckPathDead(path::Path_ptr, llarp_time_t dlt) { return dlt >= 10000; } void - BaseSession::HandlePathBuilt(llarp::path::Path* p) + BaseSession::HandlePathBuilt(llarp::path::Path_ptr p) { path::Builder::HandlePathBuilt(p); p->SetDropHandler(std::bind(&BaseSession::HandleTrafficDrop, this, @@ -120,7 +120,7 @@ namespace llarp } bool - BaseSession::HandleGotExit(llarp::path::Path* p, llarp_time_t b) + BaseSession::HandleGotExit(llarp::path::Path_ptr p, llarp_time_t b) { m_LastUse = router->Now(); if(b == 0) @@ -150,7 +150,7 @@ namespace llarp BaseSession::Stop() { CallPendingCallbacks(false); - auto sendExitClose = [&](llarp::path::Path* p) { + auto sendExitClose = [&](const llarp::path::Path_ptr p) { if(p->SupportsAnyRoles(llarp::path::ePathRoleExit)) { llarp::LogInfo(p->Name(), " closing exit path"); @@ -165,10 +165,9 @@ namespace llarp } bool - BaseSession::HandleTraffic(llarp::path::Path* p, const llarp_buffer_t& buf, + BaseSession::HandleTraffic(llarp::path::Path_ptr, const llarp_buffer_t& buf, uint64_t counter) { - (void)p; if(m_WritePacket) { llarp::net::IPv4Packet pkt; @@ -183,10 +182,9 @@ namespace llarp } bool - BaseSession::HandleTrafficDrop(llarp::path::Path* p, const PathID_t& path, + BaseSession::HandleTrafficDrop(llarp::path::Path_ptr, const PathID_t& path, uint64_t s) { - (void)p; llarp::LogError("dropped traffic on exit ", m_ExitRouter, " S=", s, " P=", path); return true; diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index 752bc01bf..3f6b9b421 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -40,10 +40,10 @@ namespace llarp } void - HandlePathDied(llarp::path::Path* p) override; + HandlePathDied(llarp::path::Path_ptr p) override; bool - CheckPathDead(path::Path* p, llarp_time_t dlt); + CheckPathDead(path::Path_ptr p, llarp_time_t dlt); bool SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur, @@ -53,7 +53,7 @@ namespace llarp ShouldBuildMore(llarp_time_t now) const override; void - HandlePathBuilt(llarp::path::Path* p) override; + HandlePathBuilt(llarp::path::Path_ptr p) override; bool QueueUpstreamTraffic(llarp::net::IPv4Packet pkt, const size_t packSize); @@ -99,14 +99,14 @@ namespace llarp PopulateRequest(llarp::routing::ObtainExitMessage& msg) const = 0; bool - HandleTrafficDrop(llarp::path::Path* p, const llarp::PathID_t& path, + HandleTrafficDrop(llarp::path::Path_ptr p, const llarp::PathID_t& path, uint64_t s); bool - HandleGotExit(llarp::path::Path* p, llarp_time_t b); + HandleGotExit(llarp::path::Path_ptr p, llarp_time_t b); bool - HandleTraffic(llarp::path::Path* p, const llarp_buffer_t& buf, + HandleTraffic(llarp::path::Path_ptr p, const llarp_buffer_t& buf, uint64_t seqno); private: diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 93a3aa180..365c88901 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -93,7 +93,7 @@ namespace llarp } template < typename Map_t, typename Key_t, typename CheckValue_t, typename GetFunc_t > - IHopHandler* + HopHandler_ptr MapGet(Map_t& map, const Key_t& k, CheckValue_t check, GetFunc_t get) { util::Lock lock(&map.first); @@ -153,7 +153,7 @@ namespace llarp } void - PathContext::AddOwnPath(PathSet* set, Path* path) + PathContext::AddOwnPath(PathSet_ptr set, Path_ptr path) { set->AddPath(path); MapPut(m_OurPaths, path->TXID(), set); @@ -169,16 +169,16 @@ namespace llarp }); } - IHopHandler* + HopHandler_ptr PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id) { auto own = MapGet( m_OurPaths, id, - [](ABSL_ATTRIBUTE_UNUSED const PathSet* s) -> bool { + [](const PathSet_ptr) -> bool { // TODO: is this right? return true; }, - [remote, id](PathSet* p) -> IHopHandler* { + [remote, id](PathSet_ptr p) -> HopHandler_ptr { return p->GetByUpstream(remote, id); }); if(own) @@ -189,8 +189,8 @@ namespace llarp [remote](const std::shared_ptr< TransitHop >& hop) -> bool { return hop->info.upstream == remote; }, - [](const std::shared_ptr< TransitHop >& h) -> IHopHandler* { - return h.get(); + [](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr { + return h; }); } @@ -205,7 +205,7 @@ namespace llarp return itr->second->info.downstream == otherRouter; } - IHopHandler* + HopHandler_ptr PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id) { return MapGet( @@ -213,12 +213,12 @@ namespace llarp [remote](const std::shared_ptr< TransitHop >& hop) -> bool { return hop->info.downstream == remote; }, - [](const std::shared_ptr< TransitHop >& h) -> IHopHandler* { - return h.get(); + [](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr { + return h; }); } - PathSet* + PathSet_ptr PathContext::GetLocalPathSet(const PathID_t& id) { auto& map = m_OurPaths; @@ -243,7 +243,7 @@ namespace llarp return m_Router; } - IHopHandler* + HopHandler_ptr PathContext::GetPathForTransfer(const PathID_t& id) { RouterID us(OurRouterID()); @@ -254,7 +254,7 @@ namespace llarp for(auto i = range.first; i != range.second; ++i) { if(i->second->info.upstream == us) - return i->second.get(); + return i->second; } } return nullptr; @@ -309,10 +309,10 @@ namespace llarp builder->Tick(now, m_Router); } - routing::IMessageHandler* + routing::MessageHandler_ptr PathContext::GetHandler(const PathID_t& id) { - routing::IMessageHandler* h = nullptr; + routing::MessageHandler_ptr h = nullptr; auto pathset = GetLocalPathSet(id); if(pathset) { @@ -328,27 +328,27 @@ namespace llarp for(auto i = range.first; i != range.second; ++i) { if(i->second->info.upstream == us) - return i->second.get(); + return i->second; } } return nullptr; } void - PathContext::AddPathBuilder(Builder* ctx) + PathContext::AddPathBuilder(Builder_ptr ctx) { - m_PathBuilders.push_back(ctx); + m_PathBuilders.emplace_back(ctx); } void - PathContext::RemovePathSet(PathSet* set) + PathContext::RemovePathSet(PathSet_ptr set) { util::Lock lock(&m_OurPaths.first); auto& map = m_OurPaths.second; auto itr = map.begin(); while(itr != map.end()) { - if(itr->second == set) + if(itr->second.get() == set.get()) itr = map.erase(itr); else ++itr; @@ -356,7 +356,7 @@ namespace llarp } void - PathContext::RemovePathBuilder(Builder* ctx) + PathContext::RemovePathBuilder(Builder_ptr ctx) { m_PathBuilders.remove(ctx); RemovePathSet(ctx); @@ -468,7 +468,7 @@ namespace llarp if(st == ePathExpired && _status == ePathBuilding) { _status = st; - m_PathSet->HandlePathBuildTimeout(this); + m_PathSet->HandlePathBuildTimeout(shared_from_this()); } else if(st == ePathBuilding) { @@ -483,7 +483,7 @@ namespace llarp { LogInfo("path ", Name(), " died"); _status = st; - m_PathSet->HandlePathDied(this); + m_PathSet->HandlePathDied(shared_from_this()); } else if(st == ePathEstablished && _status == ePathTimeout) { @@ -580,7 +580,7 @@ namespace llarp if(m_LastRecvMessage && now > m_LastRecvMessage) { auto dlt = now - m_LastRecvMessage; - if(m_CheckForDead && m_CheckForDead(this, dlt)) + if(m_CheckForDead && m_CheckForDead(shared_from_this(), dlt)) { r->routerProfiling().MarkPathFail(this); EnterState(ePathTimeout, now); @@ -588,7 +588,7 @@ namespace llarp } else if(dlt >= path::alive_timeout && m_LastRecvMessage == 0) { - if(m_CheckForDead && m_CheckForDead(this, dlt)) + if(m_CheckForDead && m_CheckForDead(shared_from_this(), dlt)) { r->routerProfiling().MarkPathFail(this); EnterState(ePathTimeout, now); @@ -673,12 +673,12 @@ namespace llarp if(m_UpdateExitTX && msg.T == m_UpdateExitTX) { if(m_ExitUpdated) - return m_ExitUpdated(this); + return m_ExitUpdated(shared_from_this()); } if(m_CloseExitTX && msg.T == m_CloseExitTX) { if(m_ExitClosed) - return m_ExitClosed(this); + return m_ExitClosed(shared_from_this()); } return false; } @@ -729,7 +729,7 @@ namespace llarp { MarkActive(r->Now()); if(m_DropHandler) - return m_DropHandler(this, msg.P, msg.S); + return m_DropHandler(shared_from_this(), msg.P, msg.S); return true; } @@ -765,7 +765,7 @@ namespace llarp Path::HandleHiddenServiceFrame(const service::ProtocolFrame& frame) { MarkActive(m_PathSet->Now()); - return m_DataHandler && m_DataHandler(this, frame); + return m_DataHandler && m_DataHandler(shared_from_this(), frame); } bool @@ -780,7 +780,7 @@ namespace llarp m_LastLatencyTestID = 0; EnterState(ePathEstablished, now); if(m_BuiltHook) - m_BuiltHook(this); + m_BuiltHook(shared_from_this()); m_BuiltHook = nullptr; LogDebug("path latency is now ", intro.latency, " for ", Name()); return true; @@ -906,9 +906,10 @@ namespace llarp bool Path::InformExitResult(llarp_time_t B) { + auto self = shared_from_this(); bool result = true; for(const auto& hook : m_ObtainedExitHooks) - result &= hook(this, B); + result &= hook(self, B); m_ObtainedExitHooks.clear(); return result; } @@ -924,13 +925,14 @@ namespace llarp if(!m_ExitTrafficHandler) return false; bool sent = msg.X.size() > 0; + auto self = shared_from_this(); for(const auto& pkt : msg.X) { if(pkt.size() <= 8) return false; uint64_t counter = bufbe64toh(pkt.data()); if(m_ExitTrafficHandler( - this, llarp_buffer_t(pkt.data() + 8, pkt.size() - 8), counter)) + self, llarp_buffer_t(pkt.data() + 8, pkt.size() - 8), counter)) { MarkActive(r->Now()); EnterState(ePathEstablished, r->Now()); diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index a01c310bc..28a7bcf05 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -149,6 +149,8 @@ namespace llarp uint64_t m_SequenceNum = 0; }; + using HopHandler_ptr = std::shared_ptr; + struct TransitHop : public IHopHandler, public routing::IMessageHandler { TransitHop(); @@ -301,25 +303,25 @@ namespace llarp }; /// A path we made - struct Path : public IHopHandler, public routing::IMessageHandler + struct Path : public IHopHandler, public routing::IMessageHandler, public std::enable_shared_from_this { - using BuildResultHookFunc = std::function< void(Path*) >; - using CheckForDeadFunc = std::function< bool(Path*, llarp_time_t) >; + using BuildResultHookFunc = std::function< void(Path_ptr) >; + using CheckForDeadFunc = std::function< bool(Path_ptr, llarp_time_t) >; using DropHandlerFunc = - std::function< bool(Path*, const PathID_t&, uint64_t) >; + std::function< bool(Path_ptr, const PathID_t&, uint64_t) >; using HopList = std::vector< PathHopConfig >; using DataHandlerFunc = - std::function< bool(Path*, const service::ProtocolFrame&) >; - using ExitUpdatedFunc = std::function< bool(Path*) >; - using ExitClosedFunc = std::function< bool(Path*) >; + std::function< bool(Path_ptr, const service::ProtocolFrame&) >; + using ExitUpdatedFunc = std::function< bool(Path_ptr) >; + using ExitClosedFunc = std::function< bool(Path_ptr) >; using ExitTrafficHandlerFunc = - std::function< bool(Path*, const llarp_buffer_t&, uint64_t) >; + std::function< bool(Path_ptr, const llarp_buffer_t&, uint64_t) >; /// (path, backoff) backoff is 0 on success - using ObtainedExitHandler = std::function< bool(Path*, llarp_time_t) >; + using ObtainedExitHandler = std::function< bool(Path_ptr, llarp_time_t) >; HopList hops; - PathSet* m_PathSet; + PathSet *const m_PathSet; service::Introduction intro; @@ -588,7 +590,7 @@ namespace llarp /// track a path builder with this context void - AddPathBuilder(Builder* set); + AddPathBuilder(Builder_ptr set); void AllowTransit(); @@ -608,22 +610,22 @@ namespace llarp void PutTransitHop(std::shared_ptr< TransitHop > hop); - IHopHandler* + HopHandler_ptr GetByUpstream(const RouterID& id, const PathID_t& path); bool TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r); - IHopHandler* + HopHandler_ptr GetPathForTransfer(const PathID_t& topath); - IHopHandler* + HopHandler_ptr GetByDownstream(const RouterID& id, const PathID_t& path); - PathSet* + PathSet_ptr GetLocalPathSet(const PathID_t& id); - routing::IMessageHandler* + routing::MessageHandler_ptr GetHandler(const PathID_t& id); bool @@ -640,13 +642,13 @@ namespace llarp HandleLRDM(const RelayDownstreamMessage& msg); void - AddOwnPath(PathSet* set, Path* p); + AddOwnPath(PathSet_ptr set, Path_ptr p); void - RemovePathBuilder(Builder* ctx); + RemovePathBuilder(Builder_ptr ctx); void - RemovePathSet(PathSet* set); + RemovePathSet(PathSet_ptr set); using TransitHopsMap_t = std::multimap< PathID_t, std::shared_ptr< TransitHop > >; @@ -658,7 +660,7 @@ namespace llarp }; // maps path id -> pathset owner of path - using OwnedPathsMap_t = std::map< PathID_t, PathSet* >; + using OwnedPathsMap_t = std::map< PathID_t, PathSet_ptr >; struct SyncOwnedPathsMap_t { @@ -689,7 +691,7 @@ namespace llarp SyncTransitMap_t m_TransitPaths; SyncTransitMap_t m_Paths; SyncOwnedPathsMap_t m_OurPaths; - std::list< Builder* > m_PathBuilders; + std::list< Builder_ptr > m_PathBuilders; bool m_AllowTransit; }; } // namespace path diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 33f5c3e86..893daaee0 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -15,10 +15,10 @@ namespace llarp template < typename User > struct AsyncPathKeyExchangeContext { - typedef path::Path Path_t; - typedef path::Builder PathSet_t; - PathSet_t* pathset = nullptr; - Path_t* path = nullptr; + typedef path::Path_ptr Path_t; + typedef path::Builder_ptr PathSet_t; + PathSet_t pathset = nullptr; + Path_t path = nullptr; typedef std::function< void(AsyncPathKeyExchangeContext< User >*) > Handler; User* user = nullptr; @@ -32,8 +32,6 @@ namespace llarp ~AsyncPathKeyExchangeContext() { - if(path) - delete path; } static void @@ -134,7 +132,7 @@ namespace llarp /// Generate all keys asynchronously and call handler when done void - AsyncGenerateKeys(Path_t* p, Logic* l, llarp_threadpool* pool, User* u, + AsyncGenerateKeys(Path_t p, Logic* l, llarp_threadpool* pool, User* u, Handler func) { path = p; @@ -164,7 +162,6 @@ namespace llarp ctx->router->PersistSessionUntil(remote, ctx->path->ExpireTime()); // add own path ctx->router->pathContext().AddOwnPath(ctx->pathset, ctx->path); - ctx->path = nullptr; } else LogError(ctx->pathset->Name(), " failed to send LRCM to ", remote); @@ -179,7 +176,7 @@ namespace llarp size_t pathNum, size_t hops) : path::PathSet(pathNum), router(p_router), dht(p_dht), numHops(hops) { - p_router->pathContext().AddPathBuilder(this); + p_router->pathContext().AddPathBuilder(shared_from_this()); p_router->crypto()->encryption_keygen(enckey); _run.store(true); keygens.store(0); @@ -187,7 +184,6 @@ namespace llarp Builder::~Builder() { - router->pathContext().RemovePathBuilder(this); } util::StatusObject @@ -247,6 +243,7 @@ namespace llarp Builder::Stop() { _run.store(false); + router->pathContext().RemovePathBuilder(shared_from_this()); return true; } @@ -340,30 +337,30 @@ namespace llarp AsyncPathKeyExchangeContext< Builder >* ctx = new AsyncPathKeyExchangeContext< Builder >(router->crypto()); ctx->router = router; - ctx->pathset = this; - auto path = new path::Path(hops, this, roles); - path->SetBuildResultHook([this](Path* p) { this->HandlePathBuilt(p); }); + ctx->pathset = shared_from_this(); + auto path = std::make_shared(hops, this, roles); + path->SetBuildResultHook([this](Path_ptr p) { this->HandlePathBuilt(p); }); ++keygens; ctx->AsyncGenerateKeys(path, router->logic(), router->threadpool(), this, &PathBuilderKeysGenerated); } void - Builder::HandlePathBuilt(Path* p) + Builder::HandlePathBuilt(Path_ptr p) { buildIntervalLimit = MIN_PATH_BUILD_INTERVAL; - router->routerProfiling().MarkPathSuccess(p); + router->routerProfiling().MarkPathSuccess(p.get()); LogInfo(p->Name(), " built latency=", p->intro.latency); } void - Builder::HandlePathBuildTimeout(Path* p) + Builder::HandlePathBuildTimeout(Path_ptr p) { // linear backoff static constexpr llarp_time_t MaxBuildInterval = 30 * 1000; buildIntervalLimit = std::min(1000 + buildIntervalLimit, MaxBuildInterval); - router->routerProfiling().MarkPathFail(p); + router->routerProfiling().MarkPathFail(p.get()); PathSet::HandlePathBuildTimeout(p); } diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index e0da716b7..2d8202f20 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -15,7 +15,7 @@ namespace llarp // milliseconds waiting between builds on a path constexpr llarp_time_t MIN_PATH_BUILD_INTERVAL = 1000; - struct Builder : public PathSet + struct Builder : public PathSet, std::enable_shared_from_this // yes private scope { protected: /// flag for PathSet::Stop() @@ -93,11 +93,14 @@ namespace llarp GetTunnelEncryptionSecretKey() const; virtual void - HandlePathBuilt(Path* p) override; + HandlePathBuilt(Path_ptr p) override; virtual void - HandlePathBuildTimeout(Path* p) override; + HandlePathBuildTimeout(Path_ptr p) override; }; + + using Builder_ptr = std::shared_ptr; + } // namespace path } // namespace llarp diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index 36f98acda..b4ce52954 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -80,20 +80,17 @@ namespace llarp while(itr != m_Paths.end()) { if(itr->second->Expired(now)) - { - delete itr->second; itr = m_Paths.erase(itr); - } else ++itr; } } - Path* + Path_ptr PathSet::GetEstablishedPathClosestTo(RouterID id, PathRole roles) const { Lock_t l(&m_PathsMutex); - Path* path = nullptr; + Path_ptr path = nullptr; AlignedBuffer< 32 > dist; AlignedBuffer< 32 > to = id; dist.Fill(0xff); @@ -113,11 +110,11 @@ namespace llarp return path; } - Path* + Path_ptr PathSet::GetNewestPathByRouter(RouterID id, PathRole roles) const { Lock_t l(&m_PathsMutex); - Path* chosen = nullptr; + Path_ptr chosen = nullptr; auto itr = m_Paths.begin(); while(itr != m_Paths.end()) { @@ -136,11 +133,11 @@ namespace llarp return chosen; } - Path* + Path_ptr PathSet::GetPathByRouter(RouterID id, PathRole roles) const { Lock_t l(&m_PathsMutex); - Path* chosen = nullptr; + Path_ptr chosen = nullptr; auto itr = m_Paths.begin(); while(itr != m_Paths.end()) { @@ -159,7 +156,7 @@ namespace llarp return chosen; } - Path* + Path_ptr PathSet::GetByEndpointWithID(RouterID ep, PathID_t id) const { Lock_t l(&m_PathsMutex); @@ -175,7 +172,7 @@ namespace llarp return nullptr; } - Path* + Path_ptr PathSet::GetPathByID(PathID_t id) const { Lock_t l(&m_PathsMutex); @@ -221,22 +218,22 @@ namespace llarp } void - PathSet::AddPath(Path* path) + PathSet::AddPath(Path_ptr path) { Lock_t l(&m_PathsMutex); auto upstream = path->Upstream(); // RouterID auto RXID = path->RXID(); // PathID - m_Paths.emplace(std::make_pair(upstream, RXID), path); + m_Paths.emplace(std::make_pair(upstream, RXID), std::move(path)); } void - PathSet::RemovePath(Path* path) + PathSet::RemovePath(Path_ptr path) { Lock_t l(&m_PathsMutex); m_Paths.erase({path->Upstream(), path->RXID()}); } - Path* + Path_ptr PathSet::GetByUpstream(RouterID remote, PathID_t rxid) const { Lock_t l(&m_PathsMutex); @@ -288,7 +285,7 @@ namespace llarp } void - PathSet::HandlePathBuildTimeout(Path* p) + PathSet::HandlePathBuildTimeout(Path_ptr p) { LogInfo(Name(), " path build ", p->HopsString(), " timed out"); } @@ -313,10 +310,10 @@ namespace llarp return found; } - Path* + Path_ptr PathSet::PickRandomEstablishedPath(PathRole roles) const { - std::vector< Path* > established; + std::vector< Path_ptr > established; Lock_t l(&m_PathsMutex); auto itr = m_Paths.begin(); while(itr != m_Paths.end()) diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index 756e0dc9b..7f4c9367d 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -57,6 +56,8 @@ namespace llarp // forward declare struct Path; + using Path_ptr = std::shared_ptr; + /// a set of paths owned by an entity struct PathSet { @@ -73,25 +74,25 @@ namespace llarp NumPathsExistingAt(llarp_time_t futureTime) const; void - RemovePath(Path* path); + RemovePath(Path_ptr path); virtual void - HandlePathBuilt(Path* path) = 0; + HandlePathBuilt(Path_ptr path) = 0; virtual void - HandlePathBuildTimeout(__attribute__((unused)) Path* path); + HandlePathBuildTimeout(__attribute__((unused)) Path_ptr path); /// a path died now what? virtual void - HandlePathDied(Path* path) = 0; + HandlePathDied(Path_ptr path) = 0; bool GetNewestIntro(service::Introduction& intro) const; void - AddPath(Path* path); + AddPath(Path_ptr path); - Path* + Path_ptr GetByUpstream(RouterID remote, PathID_t rxid) const; void @@ -167,24 +168,24 @@ namespace llarp return nullptr; } - Path* + Path_ptr GetEstablishedPathClosestTo(RouterID router, PathRole roles = ePathRoleAny) const; - Path* + Path_ptr PickRandomEstablishedPath(PathRole roles = ePathRoleAny) const; - Path* + Path_ptr GetPathByRouter(RouterID router, PathRole roles = ePathRoleAny) const; - Path* + Path_ptr GetNewestPathByRouter(RouterID router, PathRole roles = ePathRoleAny) const; - Path* + Path_ptr GetPathByID(PathID_t id) const; - Path* + Path_ptr GetByEndpointWithID(RouterID router, PathID_t id) const; bool @@ -209,19 +210,7 @@ namespace llarp size_t m_NumPaths; void - ForEachPath(std::function< void(Path*) > visit) - { - Lock_t lock(&m_PathsMutex); - auto itr = m_Paths.begin(); - while(itr != m_Paths.end()) - { - visit(itr->second); - ++itr; - } - } - - void - ForEachPath(std::function< void(const Path*) > visit) const + ForEachPath(std::function< void(const Path_ptr &) > visit) const { Lock_t lock(&m_PathsMutex); auto itr = m_Paths.begin(); @@ -244,11 +233,13 @@ namespace llarp }; using Mtx_t = util::NullMutex; using Lock_t = util::NullLock; - using PathMap_t = std::unordered_map< PathInfo_t, Path*, PathInfoHash >; + using PathMap_t = std::unordered_map< PathInfo_t, Path_ptr, PathInfoHash >; mutable Mtx_t m_PathsMutex; PathMap_t m_Paths; }; + using PathSet_ptr = std::shared_ptr; + } // namespace path } // namespace llarp diff --git a/llarp/routing/handler.hpp b/llarp/routing/handler.hpp index 163da1540..d3f87793b 100644 --- a/llarp/routing/handler.hpp +++ b/llarp/routing/handler.hpp @@ -1,6 +1,8 @@ #ifndef LLARP_ROUTING_HANDLER_HPP #define LLARP_ROUTING_HANDLER_HPP +#include + namespace llarp { struct AbstractRouter; @@ -81,6 +83,9 @@ namespace llarp virtual bool HandleDHTMessage(const dht::IMessage& msg, AbstractRouter *r) = 0; }; + + using MessageHandler_ptr = std::shared_ptr; + } // namespace routing } // namespace llarp diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index e99761084..f290cdc83 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -670,10 +670,10 @@ namespace llarp { } - std::unique_ptr< routing::IMessage > + std::shared_ptr< routing::IMessage > BuildRequestMessage() { - auto msg = std::make_unique< routing::DHTMessage >(); + auto msg = std::make_shared< routing::DHTMessage >(); msg->M.emplace_back( std::make_unique< dht::PublishIntroMessage >(m_IntroSet, txid, 1)); return msg; @@ -707,7 +707,7 @@ namespace llarp } bool - Endpoint::PublishIntroSetVia(AbstractRouter* r, path::Path* path) + Endpoint::PublishIntroSetVia(AbstractRouter* r, path::Path_ptr path) { auto job = new PublishIntroSetJob(this, GenTXID(), m_IntroSet); if(job->SendRequestViaPath(path, r)) @@ -726,7 +726,7 @@ namespace llarp // make sure we have all paths that are established // in our introset bool should = false; - ForEachPath([&](const path::Path* p) { + ForEachPath([&](const path::Path_ptr & p) { if(!p->IsReady()) return; for(const auto& i : m_IntroSet.I) @@ -868,7 +868,7 @@ namespace llarp } void - Endpoint::HandlePathBuilt(path::Path* p) + Endpoint::HandlePathBuilt(path::Path_ptr p) { using namespace std::placeholders; p->SetDataHandler( @@ -879,7 +879,7 @@ namespace llarp } bool - Endpoint::HandleDataDrop(path::Path* p, const PathID_t& dst, uint64_t seq) + Endpoint::HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t seq) { LogWarn(Name(), " message ", seq, " dropped by endpoint ", p->Endpoint(), " via ", dst); @@ -946,7 +946,7 @@ namespace llarp } bool - Endpoint::HandleHiddenServiceFrame(path::Path* p, + Endpoint::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame) { if(frame.R) @@ -964,7 +964,7 @@ namespace llarp return true; } if(!frame.AsyncDecryptAndVerify(EndpointLogic(), GetCrypto(), p, - Worker(), m_Identity, m_DataHandler)) + CryptoWorker(), m_Identity, m_DataHandler)) { // send discard @@ -974,20 +974,23 @@ namespace llarp f.F = p->intro.pathID; if(!f.Sign(GetCrypto(), m_Identity)) return false; - const routing::PathTransferMessage d(f, frame.F); - return p->SendRoutingMessage(d, router); + auto d = std::make_shared(f, frame.F); + RouterLogic()->queue_func([=]() { + p->SendRoutingMessage(*d, router); + }); + return true; } return true; } void - Endpoint::HandlePathDied(path::Path*) + Endpoint::HandlePathDied(path::Path_ptr) { RegenAndPublishIntroSet(Now(), true); } bool - Endpoint::CheckPathIsDead(path::Path*, llarp_time_t dlt) + Endpoint::CheckPathIsDead(path::Path_ptr, llarp_time_t dlt) { return dlt > path::alive_timeout; } @@ -1022,7 +1025,7 @@ namespace llarp llarp_time_t timeoutMS, bool randomPath) { - path::Path* path = nullptr; + path::Path_ptr path = nullptr; if(randomPath) path = PickRandomEstablishedPath(); else @@ -1127,9 +1130,9 @@ namespace llarp auto itr = m_AddressToService.find(remote); if(itr != m_AddressToService.end()) { - routing::PathTransferMessage transfer; - ProtocolFrame& f = transfer.T; - path::Path* p = nullptr; + auto transfer = std::make_shared(); + ProtocolFrame& f = transfer->T; + std::shared_ptr p; std::set< ConvoTag > tags; if(GetConvoTagsForService(itr->second, tags)) { @@ -1160,21 +1163,25 @@ namespace llarp m.PutBuffer(data); f.N.Randomize(); f.C.Zero(); - transfer.Y.Randomize(); + transfer->Y.Randomize(); m.proto = t; m.introReply = p->intro; PutReplyIntroFor(f.T, m.introReply); m.sender = m_Identity.pub; f.F = m.introReply.pathID; f.S = GetSeqNoForConvo(f.T); - transfer.P = remoteIntro.pathID; + transfer->P = remoteIntro.pathID; if(!f.EncryptAndSign(Router()->crypto(), m, K, m_Identity)) { LogError("failed to encrypt and sign"); return false; } LogDebug(Name(), " send ", data.sz, " via ", remoteIntro.router); - return p->SendRoutingMessage(transfer, Router()); + auto router = Router(); + RouterLogic()->queue_func([=]() { + p->SendRoutingMessage(*transfer, router); + }); + return true; } } } @@ -1263,7 +1270,7 @@ namespace llarp } llarp_threadpool* - Endpoint::Worker() + Endpoint::CryptoWorker() { return m_Router->threadpool(); } diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 1abeab3cb..49dd6a244 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -83,22 +83,26 @@ namespace llarp } /// router's logic + /// use when sending any data on a path Logic* RouterLogic(); /// endpoint's logic + /// use when writing any data to local network interfaces Logic* EndpointLogic(); - /// borrow endpoint's net loop for sending data to user + /// borrow endpoint's net loop for sending data to user on local network interface llarp_ev_loop_ptr EndpointNetLoop(); Crypto* GetCrypto(); + + /// crypto worker threadpool llarp_threadpool* - Worker(); + CryptoWorker(); AbstractRouter* Router() @@ -119,7 +123,7 @@ namespace llarp ShouldPublishDescriptors(llarp_time_t now) const override; void - HandlePathDied(path::Path* p) override; + HandlePathDied(path::Path_ptr p) override; void EnsureReplyPath(const ServiceInfo& addr); @@ -128,7 +132,7 @@ namespace llarp PublishIntroSet(AbstractRouter* r) override; bool - PublishIntroSetVia(AbstractRouter* r, path::Path* p); + PublishIntroSetVia(AbstractRouter* r, path::Path_ptr p); bool HandleGotIntroMessage(const dht::GotIntroMessage* msg) override; @@ -137,7 +141,7 @@ namespace llarp HandleGotRouterMessage(const dht::GotRouterMessage* msg) override; bool - HandleHiddenServiceFrame(path::Path* p, + HandleHiddenServiceFrame(path::Path_ptr p, const service::ProtocolFrame& msg); /// return true if we have an established path to a hidden service @@ -192,7 +196,7 @@ namespace llarp PutLookup(IServiceLookup* lookup, uint64_t txid) override; void - HandlePathBuilt(path::Path* path) override; + HandlePathBuilt(path::Path_ptr path) override; bool SendToServiceOrQueue(const RouterID& addr, const llarp_buffer_t& payload, @@ -205,10 +209,10 @@ namespace llarp FlushSNodeTraffic(); bool - HandleDataDrop(path::Path* p, const PathID_t& dst, uint64_t s); + HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t s); bool - CheckPathIsDead(path::Path* p, llarp_time_t latency); + CheckPathIsDead(path::Path_ptr p, llarp_time_t latency); using PendingBufferQueue = std::queue< PendingBuffer >; diff --git a/llarp/service/hidden_service_address_lookup.cpp b/llarp/service/hidden_service_address_lookup.cpp index d3b1c6f5f..ff9d1f529 100644 --- a/llarp/service/hidden_service_address_lookup.cpp +++ b/llarp/service/hidden_service_address_lookup.cpp @@ -33,10 +33,10 @@ namespace llarp return handle(remote, nullptr, endpoint); } - std::unique_ptr< routing::IMessage > + std::shared_ptr< routing::IMessage > HiddenServiceAddressLookup::BuildRequestMessage() { - auto msg = std::make_unique< routing::DHTMessage >(); + auto msg = std::make_shared< routing::DHTMessage >(); msg->M.emplace_back( std::make_unique< dht::FindIntroMessage >(txid, remote, 0)); return msg; diff --git a/llarp/service/hidden_service_address_lookup.hpp b/llarp/service/hidden_service_address_lookup.hpp index a7077b93d..3cda5f578 100644 --- a/llarp/service/hidden_service_address_lookup.hpp +++ b/llarp/service/hidden_service_address_lookup.hpp @@ -27,7 +27,7 @@ namespace llarp bool HandleResponse(const std::set< IntroSet >& results); - std::unique_ptr< routing::IMessage > + std::shared_ptr< routing::IMessage > BuildRequestMessage(); }; } // namespace service diff --git a/llarp/service/lookup.cpp b/llarp/service/lookup.cpp index 22445c68f..c9a0fb7c0 100644 --- a/llarp/service/lookup.cpp +++ b/llarp/service/lookup.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include namespace llarp { @@ -18,14 +20,16 @@ namespace llarp } bool - IServiceLookup::SendRequestViaPath(path::Path *path, AbstractRouter *r) + IServiceLookup::SendRequestViaPath(path::Path_ptr path, AbstractRouter *r) { auto msg = BuildRequestMessage(); if(!msg) return false; - auto result = path->SendRoutingMessage(*msg, r); endpoint = path->Endpoint(); - return result; + r->logic()->queue_func([=]() { + path->SendRoutingMessage(*msg, r); + }); + return true; } } // namespace service } // namespace llarp diff --git a/llarp/service/lookup.hpp b/llarp/service/lookup.hpp index e0738fc21..d7924b039 100644 --- a/llarp/service/lookup.hpp +++ b/llarp/service/lookup.hpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -43,12 +44,12 @@ namespace llarp } /// build request message for service lookup - virtual std::unique_ptr< routing::IMessage > + virtual std::shared_ptr< routing::IMessage > BuildRequestMessage() = 0; /// build a new request message and send it via a path bool - SendRequestViaPath(path::Path* p, AbstractRouter* r); + SendRequestViaPath(path::Path_ptr p, AbstractRouter* r); ILookupHolder* parent; uint64_t txid; diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 22a86d5f9..dcad519f8 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -32,7 +32,7 @@ namespace llarp } bool - OutboundContext::HandleDataDrop(path::Path* p, const PathID_t& dst, + OutboundContext::HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t seq) { // pick another intro @@ -122,7 +122,7 @@ namespace llarp } void - OutboundContext::HandlePathBuilt(path::Path* p) + OutboundContext::HandlePathBuilt(path::Path_ptr p) { path::Builder::HandlePathBuilt(p); /// don't use it if we are marked bad @@ -204,7 +204,7 @@ namespace llarp ex->msg.PutBuffer(payload); ex->msg.introReply = path->intro; ex->frame.F = ex->msg.introReply.pathID; - llarp_threadpool_queue_job(m_Endpoint->Worker(), + llarp_threadpool_queue_job(m_Endpoint->CryptoWorker(), {ex, &AsyncKeyExchange::Encrypt}); } @@ -222,7 +222,7 @@ namespace llarp return; auto addr = currentIntroSet.A.Addr(); - path::Path* path = nullptr; + path::Path_ptr path = nullptr; if(randomizePath) path = m_Endpoint->PickRandomEstablishedPath(); else @@ -470,7 +470,7 @@ namespace llarp } void - OutboundContext::HandlePathDied(path::Path* path) + OutboundContext::HandlePathDied(path::Path_ptr path) { // unconditionally update introset UpdateIntroSet(true); @@ -480,7 +480,7 @@ namespace llarp { // figure out how many paths to this router we have size_t num = 0; - ForEachPath([&](path::Path* p) { + ForEachPath([&](const path::Path_ptr & p) { if(p->Endpoint() == endpoint && p->IsReady()) ++num; }); @@ -491,7 +491,7 @@ namespace llarp if(num == 1) { num = 0; - ForEachPath([&](path::Path* p) { + ForEachPath([&](const path::Path_ptr & p) { if(p->Endpoint() == endpoint) ++num; }); @@ -521,7 +521,7 @@ namespace llarp m_NextIntro = picked; // check if we have a path to this router num = 0; - ForEachPath([&](path::Path* p) { + ForEachPath([&](const path::Path_ptr & p) { if(p->Endpoint() == m_NextIntro.router) ++num; }); @@ -534,7 +534,7 @@ namespace llarp } bool - OutboundContext::HandleHiddenServiceFrame(path::Path* p, + OutboundContext::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame) { return m_Endpoint->HandleHiddenServiceFrame(p, frame); diff --git a/llarp/service/outbound_context.hpp b/llarp/service/outbound_context.hpp index 7a5737871..213e97671 100644 --- a/llarp/service/outbound_context.hpp +++ b/llarp/service/outbound_context.hpp @@ -30,10 +30,10 @@ namespace llarp Stop() override; bool - HandleDataDrop(path::Path* p, const PathID_t& dst, uint64_t s); + HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t s); void - HandlePathDied(path::Path* p) override; + HandlePathDied(path::Path_ptr p) override; /// set to true if we are updating the remote introset right now bool updatingIntroSet; @@ -64,7 +64,7 @@ namespace llarp IsDone(llarp_time_t now) const; bool - CheckPathIsDead(path::Path* p, llarp_time_t dlt); + CheckPathIsDead(path::Path_ptr p, llarp_time_t dlt); void AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t) override; @@ -77,14 +77,14 @@ namespace llarp BuildOneAlignedTo(const RouterID& remote); void - HandlePathBuilt(path::Path* path) override; + HandlePathBuilt(path::Path_ptr path) override; bool SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur, size_t hop, path::PathRole roles) override; bool - HandleHiddenServiceFrame(path::Path* p, const ProtocolFrame& frame); + HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame); std::string Name() const override; diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index 313cab593..516611989 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -363,7 +363,7 @@ namespace llarp bool ProtocolFrame::AsyncDecryptAndVerify(Logic* logic, Crypto* c, - path::Path* recvPath, + path::Path_ptr recvPath, llarp_threadpool* worker, const Identity& localIdent, IDataHandler* handler) const diff --git a/llarp/service/protocol.hpp b/llarp/service/protocol.hpp index b223761be..f0e46acf6 100644 --- a/llarp/service/protocol.hpp +++ b/llarp/service/protocol.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -118,7 +119,7 @@ namespace llarp Sign(Crypto* c, const Identity& localIdent); bool - AsyncDecryptAndVerify(Logic* logic, Crypto* c, path::Path* fromPath, + AsyncDecryptAndVerify(Logic* logic, Crypto* c, path::Path_ptr fromPath, llarp_threadpool* worker, const Identity& localIdent, IDataHandler* handler) const; diff --git a/llarp/service/tag_lookup_job.cpp b/llarp/service/tag_lookup_job.cpp index f3698c4e8..889eaad09 100644 --- a/llarp/service/tag_lookup_job.cpp +++ b/llarp/service/tag_lookup_job.cpp @@ -42,10 +42,10 @@ namespace llarp } } - std::unique_ptr< routing::IMessage > + std::shared_ptr< routing::IMessage > CachedTagResult::BuildRequestMessage(uint64_t txid) { - auto msg = std::make_unique< routing::DHTMessage >(); + auto msg = std::make_shared< routing::DHTMessage >(); msg->M.emplace_back(std::make_unique< dht::FindIntroMessage >(tag, txid)); lastRequest = parent->Now(); return msg; diff --git a/llarp/service/tag_lookup_job.hpp b/llarp/service/tag_lookup_job.hpp index 76834dd91..fcc8a700a 100644 --- a/llarp/service/tag_lookup_job.hpp +++ b/llarp/service/tag_lookup_job.hpp @@ -43,7 +43,7 @@ namespace llarp return (now - lastRequest) > TTL; } - std::unique_ptr< routing::IMessage > + std::shared_ptr< routing::IMessage > BuildRequestMessage(uint64_t txid); bool @@ -58,7 +58,7 @@ namespace llarp { } - std::unique_ptr< routing::IMessage > + std::shared_ptr< routing::IMessage > BuildRequestMessage() override { return m_result->BuildRequestMessage(txid);