diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index ac4cfbdb0..383fe55d8 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -1,6 +1,7 @@ set(LIB_UTIL_SRC constants/defaults.cpp constants/link_layer.cpp + constants/path.cpp constants/proto.cpp constants/version.cpp util/aligned.cpp @@ -196,8 +197,10 @@ set(LIB_SRC net/ip.cpp net/net_int.cpp nodedb.cpp - path/path.cpp + path/ihophandler.cpp + path/path_context.cpp path/path_types.cpp + path/path.cpp path/pathbuilder.cpp path/pathset.cpp path/transit_hop.cpp diff --git a/llarp/constants/path.cpp b/llarp/constants/path.cpp new file mode 100644 index 000000000..79ff4567e --- /dev/null +++ b/llarp/constants/path.cpp @@ -0,0 +1 @@ +#include diff --git a/llarp/constants/path.hpp b/llarp/constants/path.hpp new file mode 100644 index 000000000..f226ecc31 --- /dev/null +++ b/llarp/constants/path.hpp @@ -0,0 +1,31 @@ +#ifndef LLARP_CONSTANTS_PATH_HPP +#define LLARP_CONSTANTS_PATH_HPP + +#include + +#include + +namespace llarp +{ + namespace path + { + /// maximum path length + constexpr std::size_t max_len = 8; + /// default path length + constexpr std::size_t default_len = 4; + /// pad messages to the nearest this many bytes + constexpr std::size_t pad_size = 128; + /// default path lifetime in ms + constexpr llarp_time_t default_lifetime = 10 * 60 * 1000; + /// after this many ms a path build times out + constexpr llarp_time_t build_timeout = 30000; + + /// measure latency every this interval ms + constexpr llarp_time_t latency_interval = 5000; + + /// if a path is inactive for this amount of time it's dead + constexpr llarp_time_t alive_timeout = 60000; + } // namespace path +} // namespace llarp + +#endif diff --git a/llarp/dht/context.cpp b/llarp/dht/context.cpp index 01dba22a1..c1f6958e2 100644 --- a/llarp/dht/context.cpp +++ b/llarp/dht/context.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/llarp/dht/localrouterlookup.cpp b/llarp/dht/localrouterlookup.cpp index d33fcf680..753b3ae25 100644 --- a/llarp/dht/localrouterlookup.cpp +++ b/llarp/dht/localrouterlookup.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/llarp/dht/localserviceaddresslookup.cpp b/llarp/dht/localserviceaddresslookup.cpp index c5797ea05..3827ed221 100644 --- a/llarp/dht/localserviceaddresslookup.cpp +++ b/llarp/dht/localserviceaddresslookup.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/llarp/dht/localtaglookup.cpp b/llarp/dht/localtaglookup.cpp index 4750a6366..9e5c5f1f9 100644 --- a/llarp/dht/localtaglookup.cpp +++ b/llarp/dht/localtaglookup.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include namespace llarp diff --git a/llarp/dht/messages/findrouter.cpp b/llarp/dht/messages/findrouter.cpp index 793d0a1ac..cb3d3092c 100644 --- a/llarp/dht/messages/findrouter.cpp +++ b/llarp/dht/messages/findrouter.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/llarp/dht/messages/gotintro.cpp b/llarp/dht/messages/gotintro.cpp index ddd099e1d..0fc524fea 100644 --- a/llarp/dht/messages/gotintro.cpp +++ b/llarp/dht/messages/gotintro.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include namespace llarp diff --git a/llarp/dht/messages/gotrouter.cpp b/llarp/dht/messages/gotrouter.cpp index 1e57f4189..9d73f4639 100644 --- a/llarp/dht/messages/gotrouter.cpp +++ b/llarp/dht/messages/gotrouter.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include namespace llarp diff --git a/llarp/ev/ev.cpp b/llarp/ev/ev.cpp index 5de32bc52..0a09180af 100644 --- a/llarp/ev/ev.cpp +++ b/llarp/ev/ev.cpp @@ -2,9 +2,10 @@ #include #include #include -#include "net/net_addr.hpp" +#include -#include +#include +#include // We libuv now #ifndef _WIN32 @@ -90,7 +91,6 @@ llarp_ev_udp_sendto(struct llarp_udp_io *udp, const sockaddr *to, return udp->sendto(udp, to, buf.base, buf.sz); } -#include bool llarp_ev_add_tun(struct llarp_ev_loop *loop, struct llarp_tun_io *tun) { diff --git a/llarp/exit/endpoint.cpp b/llarp/exit/endpoint.cpp index 68fdf5d77..4ac7b40ba 100644 --- a/llarp/exit/endpoint.cpp +++ b/llarp/exit/endpoint.cpp @@ -1,5 +1,7 @@ #include + #include +#include #include namespace llarp diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 6c532baad..22797e229 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index 0b0f4043c..7dc659156 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include diff --git a/llarp/messages/relay.cpp b/llarp/messages/relay.cpp index d6694471a..3cfe7f65a 100644 --- a/llarp/messages/relay.cpp +++ b/llarp/messages/relay.cpp @@ -1,19 +1,11 @@ #include -#include +#include #include #include namespace llarp { - RelayUpstreamMessage::RelayUpstreamMessage() : ILinkMessage() - { - } - - RelayUpstreamMessage::~RelayUpstreamMessage() - { - } - void RelayUpstreamMessage::Clear() { @@ -69,14 +61,6 @@ namespace llarp return false; } - RelayDownstreamMessage::RelayDownstreamMessage() : ILinkMessage() - { - } - - RelayDownstreamMessage::~RelayDownstreamMessage() - { - } - void RelayDownstreamMessage::Clear() { diff --git a/llarp/messages/relay.hpp b/llarp/messages/relay.hpp index e64975c34..1685e8b9f 100644 --- a/llarp/messages/relay.hpp +++ b/llarp/messages/relay.hpp @@ -16,10 +16,6 @@ namespace llarp Encrypted< MAX_LINK_MSG_SIZE - 128 > X; TunnelNonce Y; - RelayUpstreamMessage(); - RelayUpstreamMessage(ILinkSession* from); - ~RelayUpstreamMessage(); - bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf) override; @@ -44,9 +40,6 @@ namespace llarp PathID_t pathid; Encrypted< MAX_LINK_MSG_SIZE - 128 > X; TunnelNonce Y; - RelayDownstreamMessage(); - RelayDownstreamMessage(ILinkSession* from); - ~RelayDownstreamMessage(); bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf) override; diff --git a/llarp/messages/relay_commit.cpp b/llarp/messages/relay_commit.cpp index a33cbee3a..7b59b6fe5 100644 --- a/llarp/messages/relay_commit.cpp +++ b/llarp/messages/relay_commit.cpp @@ -2,7 +2,8 @@ #include #include -#include +#include +#include #include #include #include diff --git a/llarp/path/ihophandler.cpp b/llarp/path/ihophandler.cpp new file mode 100644 index 000000000..02c202d5f --- /dev/null +++ b/llarp/path/ihophandler.cpp @@ -0,0 +1 @@ +#include diff --git a/llarp/path/ihophandler.hpp b/llarp/path/ihophandler.hpp new file mode 100644 index 000000000..5ed17f56a --- /dev/null +++ b/llarp/path/ihophandler.hpp @@ -0,0 +1,65 @@ +#ifndef LLARP_PATH_IHOPHANDLER_HPP +#define LLARP_PATH_IHOPHANDLER_HPP + +#include +#include + +#include + +struct llarp_buffer_t; + +namespace llarp +{ + struct AbstractRouter; + + namespace routing + { + struct IMessage; + } + + namespace path + { + struct IHopHandler + { + virtual ~IHopHandler() + { + } + + virtual bool + Expired(llarp_time_t now) const = 0; + + virtual bool + ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const = 0; + + /// send routing message and increment sequence number + virtual bool + SendRoutingMessage(const routing::IMessage& msg, AbstractRouter* r) = 0; + + // handle data in upstream direction + virtual bool + HandleUpstream(const llarp_buffer_t& X, const TunnelNonce& Y, + AbstractRouter* r) = 0; + + // handle data in downstream direction + virtual bool + HandleDownstream(const llarp_buffer_t& X, const TunnelNonce& Y, + AbstractRouter* r) = 0; + + /// return timestamp last remote activity happened at + virtual llarp_time_t + LastRemoteActivityAt() const = 0; + + uint64_t + NextSeqNo() + { + return m_SequenceNum++; + } + + protected: + uint64_t m_SequenceNum = 0; + }; + + using HopHandler_ptr = std::shared_ptr< IHopHandler >; + } // namespace path +} // namespace llarp +#endif diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index f9c11dc12..52a5d50ee 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -18,365 +19,6 @@ namespace llarp { namespace path { - std::ostream& - TransitHopInfo::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("tx", txID); - printer.printAttribute("rx", rxID); - printer.printAttribute("upstream", upstream); - printer.printAttribute("downstream", downstream); - - return stream; - } - - PathContext::PathContext(AbstractRouter* router) - : m_Router(router), m_AllowTransit(false) - { - } - - PathContext::~PathContext() - { - } - - void - PathContext::AllowTransit() - { - m_AllowTransit = true; - } - - bool - PathContext::AllowingTransit() const - { - return m_AllowTransit; - } - - llarp_threadpool* - PathContext::Worker() - { - return m_Router->threadpool(); - } - - std::shared_ptr< Logic > - PathContext::logic() - { - return m_Router->logic(); - } - - const SecretKey& - PathContext::EncryptionSecretKey() - { - return m_Router->encryption(); - } - - bool - PathContext::HopIsUs(const RouterID& k) const - { - return std::equal(m_Router->pubkey(), m_Router->pubkey() + PUBKEYSIZE, - k.begin()); - } - - PathContext::EndpointPathPtrSet - PathContext::FindOwnedPathsWithEndpoint(const RouterID& r) - { - EndpointPathPtrSet found; - m_OurPaths.ForEach([&](const PathSet_ptr& set) { - set->ForEachPath([&](const Path_ptr& p) { - if(p->Endpoint() == r && p->IsReady()) - found.insert(p); - }); - }); - return found; - } - - bool - PathContext::ForwardLRCM(const RouterID& nextHop, - const std::array< EncryptedFrame, 8 >& frames) - { - auto msg = std::make_shared< const LR_CommitMessage >(frames); - - LogDebug("forwarding LRCM to ", nextHop); - if(m_Router->HasSessionTo(nextHop)) - { - return m_Router->SendToOrQueue(nextHop, msg.get()); - } - const RouterID router = nextHop; - AbstractRouter* const r = m_Router; - m_Router->EnsureRouter( - nextHop, [msg, r, router](const std::vector< RouterContact >& found) { - if(found.size()) - { - r->TryConnectAsync(found[0], 1); - r->SendToOrQueue(router, msg.get()); - } - else - LogError("dropped LRCM to ", router, - " as we cannot find in via DHT"); - }); - LogInfo("we are not directly connected to ", router, - " so we need to do a lookup"); - return true; - } - template < typename Map_t, typename Key_t, typename CheckValue_t, - typename GetFunc_t > - HopHandler_ptr - MapGet(Map_t& map, const Key_t& k, CheckValue_t check, GetFunc_t get) - { - util::Lock lock(&map.first); - auto range = map.second.equal_range(k); - for(auto i = range.first; i != range.second; ++i) - { - if(check(i->second)) - return get(i->second); - } - return nullptr; - } - - template < typename Map_t, typename Key_t, typename CheckValue_t > - bool - MapHas(Map_t& map, const Key_t& k, CheckValue_t check) - { - util::Lock lock(&map.first); - auto range = map.second.equal_range(k); - for(auto i = range.first; i != range.second; ++i) - { - if(check(i->second)) - return true; - } - return false; - } - - template < typename Map_t, typename Key_t, typename Value_t > - void - MapPut(Map_t& map, const Key_t& k, const Value_t& v) - { - util::Lock lock(&map.first); - map.second.emplace(k, v); - } - - template < typename Map_t, typename Visit_t > - void - MapIter(Map_t& map, Visit_t v) - { - util::Lock lock(map.first); - for(const auto& item : map.second) - v(item); - } - - template < typename Map_t, typename Key_t, typename Check_t > - void - MapDel(Map_t& map, const Key_t& k, Check_t check) - { - util::Lock lock(map.first); - auto range = map.second.equal_range(k); - for(auto i = range.first; i != range.second;) - { - if(check(i->second)) - i = map.second.erase(i); - else - ++i; - } - } - - void - PathContext::AddOwnPath(PathSet_ptr set, Path_ptr path) - { - set->AddPath(path); - MapPut(m_OurPaths, path->TXID(), set); - MapPut(m_OurPaths, path->RXID(), set); - } - - bool - PathContext::HasTransitHop(const TransitHopInfo& info) - { - return MapHas(m_TransitPaths, info.txID, - [info](const std::shared_ptr< TransitHop >& hop) -> bool { - return info == hop->info; - }); - } - - HopHandler_ptr - PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id) - { - auto own = MapGet(m_OurPaths, id, - [](const PathSet_ptr) -> bool { - // TODO: is this right? - return true; - }, - [remote, id](PathSet_ptr p) -> HopHandler_ptr { - return p->GetByUpstream(remote, id); - }); - if(own) - return own; - - return MapGet( - m_TransitPaths, id, - [remote](const std::shared_ptr< TransitHop >& hop) -> bool { - return hop->info.upstream == remote; - }, - [](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr { - return h; - }); - } - - bool - PathContext::TransitHopPreviousIsRouter(const PathID_t& path, - const RouterID& otherRouter) - { - util::Lock lock(&m_TransitPaths.first); - auto itr = m_TransitPaths.second.find(path); - if(itr == m_TransitPaths.second.end()) - return false; - return itr->second->info.downstream == otherRouter; - } - - HopHandler_ptr - PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id) - { - return MapGet( - m_TransitPaths, id, - [remote](const std::shared_ptr< TransitHop >& hop) -> bool { - return hop->info.downstream == remote; - }, - [](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr { - return h; - }); - } - - PathSet_ptr - PathContext::GetLocalPathSet(const PathID_t& id) - { - auto& map = m_OurPaths; - util::Lock lock(&map.first); - auto itr = map.second.find(id); - if(itr != map.second.end()) - { - return itr->second; - } - return nullptr; - } - - const byte_t* - PathContext::OurRouterID() const - { - return m_Router->pubkey(); - } - - AbstractRouter* - PathContext::Router() - { - return m_Router; - } - - HopHandler_ptr - PathContext::GetPathForTransfer(const PathID_t& id) - { - RouterID us(OurRouterID()); - auto& map = m_TransitPaths; - { - util::Lock lock(&map.first); - auto range = map.second.equal_range(id); - for(auto i = range.first; i != range.second; ++i) - { - if(i->second->info.upstream == us) - return i->second; - } - } - return nullptr; - } - - void - PathContext::PutTransitHop(std::shared_ptr< TransitHop > hop) - { - MapPut(m_TransitPaths, hop->info.txID, hop); - MapPut(m_TransitPaths, hop->info.rxID, hop); - } - - void - PathContext::ExpirePaths(llarp_time_t now) - { - { - util::Lock lock(&m_TransitPaths.first); - auto& map = m_TransitPaths.second; - auto itr = map.begin(); - while(itr != map.end()) - { - if(itr->second->Expired(now)) - { - itr = map.erase(itr); - } - else - ++itr; - } - } - { - util::Lock lock(&m_OurPaths.first); - auto& map = m_OurPaths.second; - for(auto& item : map) - { - item.second->ExpirePaths(now); - } - } - } - routing::MessageHandler_ptr - PathContext::GetHandler(const PathID_t& id) - { - routing::MessageHandler_ptr h = nullptr; - auto pathset = GetLocalPathSet(id); - if(pathset) - { - h = pathset->GetPathByID(id); - } - if(h) - return h; - const RouterID us(OurRouterID()); - auto& map = m_TransitPaths; - { - util::Lock lock(&map.first); - auto range = map.second.equal_range(id); - for(auto i = range.first; i != range.second; ++i) - { - if(i->second->info.upstream == us) - return i->second; - } - } - return nullptr; - } - - void - 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.get() == set.get()) - itr = map.erase(itr); - else - ++itr; - } - } - - std::ostream& - TransitHop::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("TransitHop", info); - printer.printAttribute("started", started); - printer.printAttribute("lifetime", lifetime); - - return stream; - } - - PathHopConfig::PathHopConfig() - { - } - - PathHopConfig::~PathHopConfig() - { - } - Path::Path(const std::vector< RouterContact >& h, PathSet* parent, PathRole startingRoles) : m_PathSet(parent), _role(startingRoles) diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index 9005089f8..e257cec9e 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -1,9 +1,11 @@ #ifndef LLARP_PATH_HPP #define LLARP_PATH_HPP +#include #include #include #include +#include #include #include #include @@ -28,254 +30,14 @@ namespace llarp class Logic; struct AbstractRouter; struct LR_CommitMessage; - struct LR_CommitRecord; namespace path { - /// maximum path length - constexpr size_t max_len = 8; - /// default path length - constexpr size_t default_len = 4; - /// pad messages to the nearest this many bytes - constexpr size_t pad_size = 128; - /// default path lifetime in ms - constexpr llarp_time_t default_lifetime = 10 * 60 * 1000; - /// after this many ms a path build times out - constexpr llarp_time_t build_timeout = 30000; - - /// measure latency every this interval ms - constexpr llarp_time_t latency_interval = 5000; - - /// if a path is inactive for this amount of time it's dead - constexpr llarp_time_t alive_timeout = 60000; - - struct TransitHopInfo - { - TransitHopInfo() = default; - TransitHopInfo(const RouterID& down, const LR_CommitRecord& record); - - PathID_t txID, rxID; - RouterID upstream; - RouterID downstream; - - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - - bool - operator==(const TransitHopInfo& other) const - { - return txID == other.txID && rxID == other.rxID - && upstream == other.upstream && downstream == other.downstream; - } - - bool - operator!=(const TransitHopInfo& other) const - { - return !(*this == other); - } - - bool - operator<(const TransitHopInfo& other) const - { - return txID < other.txID || rxID < other.rxID - || upstream < other.upstream || downstream < other.downstream; - } - - struct PathIDHash - { - std::size_t - operator()(const PathID_t& a) const - { - return AlignedBuffer< PathID_t::SIZE >::Hash()(a); - } - }; - - struct Hash - { - std::size_t - operator()(TransitHopInfo const& a) const - { - std::size_t idx0 = RouterID::Hash()(a.upstream); - std::size_t idx1 = RouterID::Hash()(a.downstream); - std::size_t idx2 = PathIDHash()(a.txID); - std::size_t idx3 = PathIDHash()(a.rxID); - return idx0 ^ idx1 ^ idx2 ^ idx3; - } - }; - }; - - inline std::ostream& - operator<<(std::ostream& out, const TransitHopInfo& info) - { - return info.print(out, -1, -1); - } - - struct IHopHandler - { - virtual ~IHopHandler() - { - } - - virtual bool - Expired(llarp_time_t now) const = 0; - - virtual bool - ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const = 0; - - /// send routing message and increment sequence number - virtual bool - SendRoutingMessage(const routing::IMessage& msg, AbstractRouter* r) = 0; - - // handle data in upstream direction - virtual bool - HandleUpstream(const llarp_buffer_t& X, const TunnelNonce& Y, - AbstractRouter* r) = 0; - - // handle data in downstream direction - virtual bool - HandleDownstream(const llarp_buffer_t& X, const TunnelNonce& Y, - AbstractRouter* r) = 0; - - /// return timestamp last remote activity happened at - virtual llarp_time_t - LastRemoteActivityAt() const = 0; - - uint64_t - NextSeqNo() - { - return m_SequenceNum++; - } - - protected: - uint64_t m_SequenceNum = 0; - }; - - using HopHandler_ptr = std::shared_ptr< IHopHandler >; - - struct TransitHop : public IHopHandler, public routing::IMessageHandler - { - TransitHop(); - - TransitHopInfo info; - SharedSecret pathKey; - ShortHash nonceXOR; - llarp_time_t started = 0; - // 10 minutes default - llarp_time_t lifetime = default_lifetime; - llarp_proto_version_t version; - llarp_time_t m_LastActivity = 0; - - bool - IsEndpoint(const RouterID& us) const - { - return info.upstream == us; - } - - llarp_time_t - ExpireTime() const; - - llarp_time_t - LastRemoteActivityAt() const override - { - return m_LastActivity; - } - - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - - bool - Expired(llarp_time_t now) const override; - - bool - ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const override - { - return now >= ExpireTime() - dlt; - } - - // send routing message when end of path - bool - SendRoutingMessage(const routing::IMessage& msg, - AbstractRouter* r) override; - - // handle routing message when end of path - bool - HandleRoutingMessage(const routing::IMessage& msg, AbstractRouter* r); - - bool - HandleDataDiscardMessage(const routing::DataDiscardMessage& msg, - AbstractRouter* r) override; - - bool - HandlePathConfirmMessage(const routing::PathConfirmMessage& msg, - AbstractRouter* r) override; - bool - HandlePathTransferMessage(const routing::PathTransferMessage& msg, - AbstractRouter* r) override; - bool - HandlePathLatencyMessage(const routing::PathLatencyMessage& msg, - AbstractRouter* r) override; - - bool - HandleObtainExitMessage(const routing::ObtainExitMessage& msg, - AbstractRouter* r) override; - - bool - HandleUpdateExitVerifyMessage(const routing::UpdateExitVerifyMessage& msg, - AbstractRouter* r) override; - - bool - HandleTransferTrafficMessage(const routing::TransferTrafficMessage& msg, - AbstractRouter* r) override; - - bool - HandleUpdateExitMessage(const routing::UpdateExitMessage& msg, - AbstractRouter* r) override; - - bool - HandleGrantExitMessage(const routing::GrantExitMessage& msg, - AbstractRouter* r) override; - bool - HandleRejectExitMessage(const routing::RejectExitMessage& msg, - AbstractRouter* r) override; - - bool - HandleCloseExitMessage(const routing::CloseExitMessage& msg, - AbstractRouter* r) override; - - bool - HandleHiddenServiceFrame( - ABSL_ATTRIBUTE_UNUSED const service::ProtocolFrame& frame) override - { - /// TODO: implement me - LogWarn("Got hidden service data on transit hop"); - return false; - } - - bool - HandleGotIntroMessage(const dht::GotIntroMessage& msg); - - bool - HandleDHTMessage(const dht::IMessage& msg, AbstractRouter* r) override; - - // handle data in upstream direction - bool - HandleUpstream(const llarp_buffer_t& X, const TunnelNonce& Y, - AbstractRouter* r) override; - - // handle data in downstream direction - bool - HandleDownstream(const llarp_buffer_t& X, const TunnelNonce& Y, - AbstractRouter* r) override; - }; + struct TransitHop; + struct TransitHopInfo; using TransitHop_ptr = std::shared_ptr< TransitHop >; - inline std::ostream& - operator<<(std::ostream& out, const TransitHop& h) - { - return h.print(out, -1, -1); - } - /// configuration for a single hop when building a path struct PathHopConfig { @@ -296,21 +58,17 @@ namespace llarp // lifetime llarp_time_t lifetime = default_lifetime; - ~PathHopConfig(); - PathHopConfig(); - util::StatusObject ExtractStatus() const; - - bool - operator<(const PathHopConfig& other) const - { - return std::tie(txID, rxID, rc, upstream, lifetime) - < std::tie(other.txID, other.rxID, other.rc, other.upstream, - other.lifetime); - } }; + inline bool + operator<(const PathHopConfig& lhs, const PathHopConfig& rhs) + { + return std::tie(lhs.txID, lhs.rxID, lhs.rc, lhs.upstream, lhs.lifetime) + < std::tie(rhs.txID, rhs.rxID, rhs.rc, rhs.upstream, rhs.lifetime); + } + /// A path we made struct Path : public IHopHandler, public routing::IMessageHandler, @@ -591,137 +349,6 @@ namespace llarp PathStatus _status; PathRole _role; }; - - enum PathBuildStatus - { - ePathBuildSuccess, - ePathBuildTimeout, - ePathBuildReject - }; - - struct PathContext - { - PathContext(AbstractRouter* router); - ~PathContext(); - - /// called from router tick function - void - ExpirePaths(llarp_time_t now); - - void - AllowTransit(); - - void - RejectTransit(); - - bool - AllowingTransit() const; - - bool - HasTransitHop(const TransitHopInfo& info); - - bool - HandleRelayCommit(const LR_CommitMessage& msg); - - void - PutTransitHop(std::shared_ptr< TransitHop > hop); - - HopHandler_ptr - GetByUpstream(const RouterID& id, const PathID_t& path); - - bool - TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r); - - HopHandler_ptr - GetPathForTransfer(const PathID_t& topath); - - HopHandler_ptr - GetByDownstream(const RouterID& id, const PathID_t& path); - - PathSet_ptr - GetLocalPathSet(const PathID_t& id); - - routing::MessageHandler_ptr - GetHandler(const PathID_t& id); - - using EndpointPathPtrSet = std::set< Path_ptr, ComparePtr< Path_ptr > >; - /// get a set of all paths that we own who's endpoint is r - EndpointPathPtrSet - FindOwnedPathsWithEndpoint(const RouterID& r); - - bool - ForwardLRCM(const RouterID& nextHop, - const std::array< EncryptedFrame, 8 >& frames); - - bool - HopIsUs(const RouterID& k) const; - - bool - HandleLRUM(const RelayUpstreamMessage& msg); - - bool - HandleLRDM(const RelayDownstreamMessage& msg); - - void - AddOwnPath(PathSet_ptr set, Path_ptr p); - - void - RemovePathSet(PathSet_ptr set); - - using TransitHopsMap_t = std::multimap< PathID_t, TransitHop_ptr >; - - struct SyncTransitMap_t - { - util::Mutex first; // protects second - TransitHopsMap_t second GUARDED_BY(first); - - void - ForEach(std::function< void(const TransitHop_ptr&) > visit) - { - util::Lock lock(&first); - for(const auto& item : second) - visit(item.second); - } - }; - - // maps path id -> pathset owner of path - using OwnedPathsMap_t = std::map< PathID_t, PathSet_ptr >; - - struct SyncOwnedPathsMap_t - { - util::Mutex first; // protects second - OwnedPathsMap_t second GUARDED_BY(first); - - void - ForEach(std::function< void(const PathSet_ptr&) > visit) - { - util::Lock lock(&first); - for(const auto& item : second) - visit(item.second); - } - }; - - llarp_threadpool* - Worker(); - - std::shared_ptr< Logic > - logic(); - - AbstractRouter* - Router(); - - const SecretKey& - EncryptionSecretKey(); - - const byte_t* - OurRouterID() const; - - private: - AbstractRouter* m_Router; - SyncTransitMap_t m_TransitPaths; - SyncOwnedPathsMap_t m_OurPaths; - bool m_AllowTransit; - }; } // namespace path } // namespace llarp diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp new file mode 100644 index 000000000..01d6dbb70 --- /dev/null +++ b/llarp/path/path_context.cpp @@ -0,0 +1,336 @@ +#include + +#include +#include +#include + +namespace llarp +{ + namespace path + { + PathContext::PathContext(AbstractRouter* router) + : m_Router(router), m_AllowTransit(false) + { + } + + void + PathContext::AllowTransit() + { + m_AllowTransit = true; + } + + bool + PathContext::AllowingTransit() const + { + return m_AllowTransit; + } + + llarp_threadpool* + PathContext::Worker() + { + return m_Router->threadpool(); + } + + std::shared_ptr< Logic > + PathContext::logic() + { + return m_Router->logic(); + } + + const SecretKey& + PathContext::EncryptionSecretKey() + { + return m_Router->encryption(); + } + + bool + PathContext::HopIsUs(const RouterID& k) const + { + return std::equal(m_Router->pubkey(), m_Router->pubkey() + PUBKEYSIZE, + k.begin()); + } + + PathContext::EndpointPathPtrSet + PathContext::FindOwnedPathsWithEndpoint(const RouterID& r) + { + EndpointPathPtrSet found; + m_OurPaths.ForEach([&](const PathSet_ptr& set) { + set->ForEachPath([&](const Path_ptr& p) { + if(p->Endpoint() == r && p->IsReady()) + found.insert(p); + }); + }); + return found; + } + + bool + PathContext::ForwardLRCM(const RouterID& nextHop, + const std::array< EncryptedFrame, 8 >& frames) + { + auto msg = std::make_shared< const LR_CommitMessage >(frames); + + LogDebug("forwarding LRCM to ", nextHop); + if(m_Router->HasSessionTo(nextHop)) + { + return m_Router->SendToOrQueue(nextHop, msg.get()); + } + const RouterID router = nextHop; + AbstractRouter* const r = m_Router; + m_Router->EnsureRouter( + nextHop, [msg, r, router](const std::vector< RouterContact >& found) { + if(found.size()) + { + r->TryConnectAsync(found[0], 1); + r->SendToOrQueue(router, msg.get()); + } + else + LogError("dropped LRCM to ", router, + " as we cannot find in via DHT"); + }); + LogInfo("we are not directly connected to ", router, + " so we need to do a lookup"); + return true; + } + template < typename Map_t, typename Key_t, typename CheckValue_t, + typename GetFunc_t > + HopHandler_ptr + MapGet(Map_t& map, const Key_t& k, CheckValue_t check, GetFunc_t get) + { + util::Lock lock(&map.first); + auto range = map.second.equal_range(k); + for(auto i = range.first; i != range.second; ++i) + { + if(check(i->second)) + return get(i->second); + } + return nullptr; + } + + template < typename Map_t, typename Key_t, typename CheckValue_t > + bool + MapHas(Map_t& map, const Key_t& k, CheckValue_t check) + { + util::Lock lock(&map.first); + auto range = map.second.equal_range(k); + for(auto i = range.first; i != range.second; ++i) + { + if(check(i->second)) + return true; + } + return false; + } + + template < typename Map_t, typename Key_t, typename Value_t > + void + MapPut(Map_t& map, const Key_t& k, const Value_t& v) + { + util::Lock lock(&map.first); + map.second.emplace(k, v); + } + + template < typename Map_t, typename Visit_t > + void + MapIter(Map_t& map, Visit_t v) + { + util::Lock lock(map.first); + for(const auto& item : map.second) + v(item); + } + + template < typename Map_t, typename Key_t, typename Check_t > + void + MapDel(Map_t& map, const Key_t& k, Check_t check) + { + util::Lock lock(map.first); + auto range = map.second.equal_range(k); + for(auto i = range.first; i != range.second;) + { + if(check(i->second)) + i = map.second.erase(i); + else + ++i; + } + } + + void + PathContext::AddOwnPath(PathSet_ptr set, Path_ptr path) + { + set->AddPath(path); + MapPut(m_OurPaths, path->TXID(), set); + MapPut(m_OurPaths, path->RXID(), set); + } + + bool + PathContext::HasTransitHop(const TransitHopInfo& info) + { + return MapHas(m_TransitPaths, info.txID, + [info](const std::shared_ptr< TransitHop >& hop) -> bool { + return info == hop->info; + }); + } + + HopHandler_ptr + PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id) + { + auto own = MapGet( + m_OurPaths, id, + [](const PathSet_ptr) -> bool { + // TODO: is this right? + return true; + }, + [remote, id](PathSet_ptr p) -> HopHandler_ptr { + return p->GetByUpstream(remote, id); + }); + if(own) + return own; + + return MapGet( + m_TransitPaths, id, + [remote](const std::shared_ptr< TransitHop >& hop) -> bool { + return hop->info.upstream == remote; + }, + [](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr { + return h; + }); + } + + bool + PathContext::TransitHopPreviousIsRouter(const PathID_t& path, + const RouterID& otherRouter) + { + util::Lock lock(&m_TransitPaths.first); + auto itr = m_TransitPaths.second.find(path); + if(itr == m_TransitPaths.second.end()) + return false; + return itr->second->info.downstream == otherRouter; + } + + HopHandler_ptr + PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id) + { + return MapGet( + m_TransitPaths, id, + [remote](const std::shared_ptr< TransitHop >& hop) -> bool { + return hop->info.downstream == remote; + }, + [](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr { + return h; + }); + } + + PathSet_ptr + PathContext::GetLocalPathSet(const PathID_t& id) + { + auto& map = m_OurPaths; + util::Lock lock(&map.first); + auto itr = map.second.find(id); + if(itr != map.second.end()) + { + return itr->second; + } + return nullptr; + } + + const byte_t* + PathContext::OurRouterID() const + { + return m_Router->pubkey(); + } + + AbstractRouter* + PathContext::Router() + { + return m_Router; + } + + HopHandler_ptr + PathContext::GetPathForTransfer(const PathID_t& id) + { + RouterID us(OurRouterID()); + auto& map = m_TransitPaths; + { + util::Lock lock(&map.first); + auto range = map.second.equal_range(id); + for(auto i = range.first; i != range.second; ++i) + { + if(i->second->info.upstream == us) + return i->second; + } + } + return nullptr; + } + + void + PathContext::PutTransitHop(std::shared_ptr< TransitHop > hop) + { + MapPut(m_TransitPaths, hop->info.txID, hop); + MapPut(m_TransitPaths, hop->info.rxID, hop); + } + + void + PathContext::ExpirePaths(llarp_time_t now) + { + { + util::Lock lock(&m_TransitPaths.first); + auto& map = m_TransitPaths.second; + auto itr = map.begin(); + while(itr != map.end()) + { + if(itr->second->Expired(now)) + { + itr = map.erase(itr); + } + else + ++itr; + } + } + { + util::Lock lock(&m_OurPaths.first); + auto& map = m_OurPaths.second; + for(auto& item : map) + { + item.second->ExpirePaths(now); + } + } + } + routing::MessageHandler_ptr + PathContext::GetHandler(const PathID_t& id) + { + routing::MessageHandler_ptr h = nullptr; + auto pathset = GetLocalPathSet(id); + if(pathset) + { + h = pathset->GetPathByID(id); + } + if(h) + return h; + const RouterID us(OurRouterID()); + auto& map = m_TransitPaths; + { + util::Lock lock(&map.first); + auto range = map.second.equal_range(id); + for(auto i = range.first; i != range.second; ++i) + { + if(i->second->info.upstream == us) + return i->second; + } + } + return nullptr; + } + + void + 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.get() == set.get()) + itr = map.erase(itr); + else + ++itr; + } + } + } // namespace path +} // namespace llarp diff --git a/llarp/path/path_context.hpp b/llarp/path/path_context.hpp new file mode 100644 index 000000000..7393338a0 --- /dev/null +++ b/llarp/path/path_context.hpp @@ -0,0 +1,156 @@ +#ifndef LLARP_PATH_CONTEXT_HPP +#define LLARP_PATH_CONTEXT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace llarp +{ + class Logic; + struct AbstractRouter; + struct LR_CommitMessage; + struct RelayDownstreamMessage; + struct RelayUpstreamMessage; + struct RouterID; + + namespace path + { + struct TransitHop; + struct TransitHopInfo; + + using TransitHop_ptr = std::shared_ptr< TransitHop >; + + struct PathContext + { + PathContext(AbstractRouter* router); + + /// called from router tick function + void + ExpirePaths(llarp_time_t now); + + void + AllowTransit(); + + void + RejectTransit(); + + bool + AllowingTransit() const; + + bool + HasTransitHop(const TransitHopInfo& info); + + bool + HandleRelayCommit(const LR_CommitMessage& msg); + + void + PutTransitHop(std::shared_ptr< TransitHop > hop); + + HopHandler_ptr + GetByUpstream(const RouterID& id, const PathID_t& path); + + bool + TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r); + + HopHandler_ptr + GetPathForTransfer(const PathID_t& topath); + + HopHandler_ptr + GetByDownstream(const RouterID& id, const PathID_t& path); + + PathSet_ptr + GetLocalPathSet(const PathID_t& id); + + routing::MessageHandler_ptr + GetHandler(const PathID_t& id); + + using EndpointPathPtrSet = std::set< Path_ptr, ComparePtr< Path_ptr > >; + /// get a set of all paths that we own who's endpoint is r + EndpointPathPtrSet + FindOwnedPathsWithEndpoint(const RouterID& r); + + bool + ForwardLRCM(const RouterID& nextHop, + const std::array< EncryptedFrame, 8 >& frames); + + bool + HopIsUs(const RouterID& k) const; + + bool + HandleLRUM(const RelayUpstreamMessage& msg); + + bool + HandleLRDM(const RelayDownstreamMessage& msg); + + void + AddOwnPath(PathSet_ptr set, Path_ptr p); + + void + RemovePathSet(PathSet_ptr set); + + using TransitHopsMap_t = std::multimap< PathID_t, TransitHop_ptr >; + + struct SyncTransitMap_t + { + util::Mutex first; // protects second + TransitHopsMap_t second GUARDED_BY(first); + + void + ForEach(std::function< void(const TransitHop_ptr&) > visit) + { + util::Lock lock(&first); + for(const auto& item : second) + visit(item.second); + } + }; + + // maps path id -> pathset owner of path + using OwnedPathsMap_t = std::map< PathID_t, PathSet_ptr >; + + struct SyncOwnedPathsMap_t + { + util::Mutex first; // protects second + OwnedPathsMap_t second GUARDED_BY(first); + + void + ForEach(std::function< void(const PathSet_ptr&) > visit) + { + util::Lock lock(&first); + for(const auto& item : second) + visit(item.second); + } + }; + + llarp_threadpool* + Worker(); + + std::shared_ptr< Logic > + logic(); + + AbstractRouter* + Router(); + + const SecretKey& + EncryptionSecretKey(); + + const byte_t* + OurRouterID() const; + + private: + AbstractRouter* m_Router; + SyncTransitMap_t m_TransitPaths; + SyncOwnedPathsMap_t m_OurPaths; + bool m_AllowTransit; + }; + } // namespace path +} // namespace llarp + +#endif diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 8b64f9e05..2bb11e862 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index 0aeb170d0..4a721820a 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -1,5 +1,5 @@ -#ifndef LLARP_PATHBUILDER_HPP_ -#define LLARP_PATHBUILDER_HPP_ +#ifndef LLARP_PATHBUILDER_HPP +#define LLARP_PATHBUILDER_HPP #include #include diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index b638c9fbd..9ed7aefda 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -16,6 +18,18 @@ namespace llarp { namespace path { + std::ostream& + TransitHopInfo::print(std::ostream& stream, int level, int spaces) const + { + Printer printer(stream, level, spaces); + printer.printAttribute("tx", txID); + printer.printAttribute("rx", rxID); + printer.printAttribute("upstream", upstream); + printer.printAttribute("downstream", downstream); + + return stream; + } + TransitHop::TransitHop() { } @@ -303,5 +317,15 @@ namespace llarp return SendRoutingMessage(discarded, r); } + std::ostream& + TransitHop::print(std::ostream& stream, int level, int spaces) const + { + Printer printer(stream, level, spaces); + printer.printAttribute("TransitHop", info); + printer.printAttribute("started", started); + printer.printAttribute("lifetime", lifetime); + + return stream; + } } // namespace path } // namespace llarp diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp new file mode 100644 index 000000000..5cad3eda2 --- /dev/null +++ b/llarp/path/transit_hop.hpp @@ -0,0 +1,206 @@ +#ifndef LLARP_PATH_TRANSIT_HOP_HPP +#define LLARP_PATH_TRANSIT_HOP_HPP + +#include +#include +#include +#include +#include + +namespace llarp +{ + struct LR_CommitRecord; + + namespace dht + { + struct GotIntroMessage; + } + + namespace path + { + struct TransitHopInfo + { + TransitHopInfo() = default; + TransitHopInfo(const RouterID& down, const LR_CommitRecord& record); + + PathID_t txID, rxID; + RouterID upstream; + RouterID downstream; + + std::ostream& + print(std::ostream& stream, int level, int spaces) const; + + struct PathIDHash + { + std::size_t + operator()(const PathID_t& a) const + { + return AlignedBuffer< PathID_t::SIZE >::Hash()(a); + } + }; + + struct Hash + { + std::size_t + operator()(TransitHopInfo const& a) const + { + std::size_t idx0 = RouterID::Hash()(a.upstream); + std::size_t idx1 = RouterID::Hash()(a.downstream); + std::size_t idx2 = PathIDHash()(a.txID); + std::size_t idx3 = PathIDHash()(a.rxID); + return idx0 ^ idx1 ^ idx2 ^ idx3; + } + }; + }; + + inline bool + operator==(const TransitHopInfo& lhs, const TransitHopInfo& rhs) + { + return std::tie(lhs.txID, lhs.rxID, lhs.upstream, lhs.downstream) + == std::tie(rhs.txID, rhs.rxID, rhs.upstream, rhs.downstream); + } + + inline bool + operator!=(const TransitHopInfo& lhs, const TransitHopInfo& rhs) + { + return !(lhs == rhs); + } + + inline bool + operator<(const TransitHopInfo& lhs, const TransitHopInfo& rhs) + { + return std::tie(lhs.txID, lhs.rxID, lhs.upstream, lhs.downstream) + < std::tie(rhs.txID, rhs.rxID, rhs.upstream, rhs.downstream); + } + + inline std::ostream& + operator<<(std::ostream& out, const TransitHopInfo& info) + { + return info.print(out, -1, -1); + } + + struct TransitHop : public IHopHandler, public routing::IMessageHandler + { + TransitHop(); + + TransitHopInfo info; + SharedSecret pathKey; + ShortHash nonceXOR; + llarp_time_t started = 0; + // 10 minutes default + llarp_time_t lifetime = default_lifetime; + llarp_proto_version_t version; + llarp_time_t m_LastActivity = 0; + + bool + IsEndpoint(const RouterID& us) const + { + return info.upstream == us; + } + + llarp_time_t + ExpireTime() const; + + llarp_time_t + LastRemoteActivityAt() const override + { + return m_LastActivity; + } + + std::ostream& + print(std::ostream& stream, int level, int spaces) const; + + bool + Expired(llarp_time_t now) const override; + + bool + ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const override + { + return now >= ExpireTime() - dlt; + } + + // send routing message when end of path + bool + SendRoutingMessage(const routing::IMessage& msg, + AbstractRouter* r) override; + + // handle routing message when end of path + bool + HandleRoutingMessage(const routing::IMessage& msg, AbstractRouter* r); + + bool + HandleDataDiscardMessage(const routing::DataDiscardMessage& msg, + AbstractRouter* r) override; + + bool + HandlePathConfirmMessage(const routing::PathConfirmMessage& msg, + AbstractRouter* r) override; + bool + HandlePathTransferMessage(const routing::PathTransferMessage& msg, + AbstractRouter* r) override; + bool + HandlePathLatencyMessage(const routing::PathLatencyMessage& msg, + AbstractRouter* r) override; + + bool + HandleObtainExitMessage(const routing::ObtainExitMessage& msg, + AbstractRouter* r) override; + + bool + HandleUpdateExitVerifyMessage(const routing::UpdateExitVerifyMessage& msg, + AbstractRouter* r) override; + + bool + HandleTransferTrafficMessage(const routing::TransferTrafficMessage& msg, + AbstractRouter* r) override; + + bool + HandleUpdateExitMessage(const routing::UpdateExitMessage& msg, + AbstractRouter* r) override; + + bool + HandleGrantExitMessage(const routing::GrantExitMessage& msg, + AbstractRouter* r) override; + bool + HandleRejectExitMessage(const routing::RejectExitMessage& msg, + AbstractRouter* r) override; + + bool + HandleCloseExitMessage(const routing::CloseExitMessage& msg, + AbstractRouter* r) override; + + bool + HandleHiddenServiceFrame( + ABSL_ATTRIBUTE_UNUSED const service::ProtocolFrame& frame) override + { + /// TODO: implement me + LogWarn("Got hidden service data on transit hop"); + return false; + } + + bool + HandleGotIntroMessage(const dht::GotIntroMessage& msg); + + bool + HandleDHTMessage(const dht::IMessage& msg, AbstractRouter* r) override; + + // handle data in upstream direction + bool + HandleUpstream(const llarp_buffer_t& X, const TunnelNonce& Y, + AbstractRouter* r) override; + + // handle data in downstream direction + bool + HandleDownstream(const llarp_buffer_t& X, const TunnelNonce& Y, + AbstractRouter* r) override; + }; + + inline std::ostream& + operator<<(std::ostream& out, const TransitHop& h) + { + return h.print(out, -1, -1); + } + } // namespace path +} // namespace llarp + +#endif diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 3f94ec87c..0de221b37 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include