From c1f33bb1acca23e3892b4279b1f5f478b8c055c5 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 7 Aug 2019 12:33:29 -0400 Subject: [PATCH 01/44] initial mempipe implementation --- include/tuntap.h | 2 +- llarp/CMakeLists.txt | 2 + llarp/config/config.cpp | 21 +- llarp/config/config.hpp | 26 +- llarp/ev/ev_libuv.cpp | 21 +- llarp/link/factory.cpp | 52 +++ llarp/link/factory.hpp | 43 ++ llarp/link/server.hpp | 14 +- llarp/mempipe/mempipe.cpp | 534 +++++++++++++++++++++++ llarp/mempipe/mempipe.hpp | 25 ++ llarp/path/path.cpp | 4 +- llarp/path/path_context.cpp | 17 +- llarp/router/router.cpp | 113 +++-- llarp/router/router.hpp | 3 + llarp/service/endpoint.cpp | 2 +- llarp/service/protocol.cpp | 3 +- llarp/utp/utp.cpp | 14 +- llarp/utp/utp.hpp | 16 +- test/config/test_llarp_config_config.cpp | 6 +- test/link/test_llarp_link.cpp | 27 +- 20 files changed, 830 insertions(+), 115 deletions(-) create mode 100644 llarp/link/factory.cpp create mode 100644 llarp/link/factory.hpp create mode 100644 llarp/mempipe/mempipe.cpp create mode 100644 llarp/mempipe/mempipe.hpp diff --git a/include/tuntap.h b/include/tuntap.h index 8a56eb28e..6cc444a70 100644 --- a/include/tuntap.h +++ b/include/tuntap.h @@ -147,7 +147,7 @@ extern "C" int flags; /* ifr.ifr_flags on Unix */ char if_name[IF_NAMESIZE]; #if defined(Windows) - int idx; /* needed to set ipv6 address */ + int idx; /* needed to set ipv6 address */ #endif #if defined(FreeBSD) int mode; diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 36510c0e1..a05435ba5 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -178,10 +178,12 @@ set(LIB_SRC iwp/linklayer.cpp iwp/outermessage.cpp iwp/iwp.cpp + link/factory.cpp link/i_link_manager.cpp link/link_manager.cpp link/server.cpp link/session.cpp + mempipe/mempipe.cpp messages/dht_immediate.cpp messages/discard.cpp messages/link_intro.cpp diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index bf10ff91d..c68204354 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -33,6 +33,11 @@ namespace llarp void RouterConfig::fromSection(string_view key, string_view val) { + if(key == "default-protocol") + { + m_DefaultLinkProto = tostr(val); + LogInfo("overriding default link protocol to '", val, "'"); + } if(key == "netid") { if(val.size() <= NetID::size()) @@ -194,9 +199,8 @@ namespace llarp } void - IwpConfig::fromSection(string_view key, string_view val) + LinksConfig::fromSection(string_view key, string_view val) { - // try IPv4 first uint16_t proto = 0; std::set< std::string > parsed_opts; @@ -215,7 +219,7 @@ namespace llarp parsed_opts.insert(v); } } while(idx != std::string::npos); - + std::set< std::string > opts; /// for each option for(const auto &item : parsed_opts) { @@ -229,15 +233,20 @@ namespace llarp proto = port; } } + else + { + opts.insert(item); + } } if(key == "*") { - m_OutboundPort = proto; + m_OutboundLink = {"*", AF_INET, fromEnv(proto, "OUTBOUND_PORT"), + std::move(opts)}; } else { - m_servers.emplace_back(tostr(key), AF_INET, proto); + m_InboundLinks.emplace_back(tostr(key), AF_INET, proto, std::move(opts)); } } @@ -434,7 +443,7 @@ namespace llarp connect = find_section< ConnectConfig >(parser, "connect"); netdb = find_section< NetdbConfig >(parser, "netdb"); dns = find_section< DnsConfig >(parser, "dns"); - iwp_links = find_section< IwpConfig >(parser, "bind"); + links = find_section< LinksConfig >(parser, "bind"); services = find_section< ServicesConfig >(parser, "services"); system = find_section< SystemConfig >(parser, "system"); metrics = find_section< MetricsConfig >(parser, "metrics"); diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 6ed3ee297..916144cee 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -128,6 +128,8 @@ namespace llarp int m_workerThreads = 1; int m_numNetThreads = 1; + std::string m_DefaultLinkProto = "utp"; + public: // clang-format off size_t minConnectedRouters() const { return fromEnv(m_minConnectedRouters, "MIN_CONNECTED_ROUTERS"); } @@ -143,6 +145,7 @@ namespace llarp const AddressInfo& addrInfo() const { return m_addrInfo; } int workerThreads() const { return fromEnv(m_workerThreads, "WORKER_THREADS"); } int numNetThreads() const { return fromEnv(m_numNetThreads, "NUM_NET_THREADS"); } + std::string defaultLinkProto() const { return fromEnv(m_DefaultLinkProto, "LINK_PROTO"); } // clang-format on void @@ -194,20 +197,27 @@ namespace llarp fromSection(string_view key, string_view val); }; - class IwpConfig + class LinksConfig { public: - using Servers = std::vector< std::tuple< std::string, int, uint16_t > >; + static constexpr int Interface = 0; + static constexpr int AddressFamily = 1; + static constexpr int Port = 2; + static constexpr int Options = 3; - private: - uint16_t m_OutboundPort = 0; + using ServerOptions = std::set< std::string >; + using LinkInfo = std::tuple< std::string, int, uint16_t, ServerOptions >; + using Links = std::vector< LinkInfo >; - Servers m_servers; + private: + LinkInfo m_OutboundLink; + Links m_InboundLinks; public: // clang-format off - uint16_t outboundPort() const { return fromEnv(m_OutboundPort, "OUTBOUND_PORT"); } - const Servers& servers() const { return m_servers; } + const LinkInfo& outboundLink() const { return m_OutboundLink; } + + const Links& inboundLinks() const { return m_InboundLinks; } // clang-format on void @@ -306,7 +316,7 @@ namespace llarp ConnectConfig connect; NetdbConfig netdb; DnsConfig dns; - IwpConfig iwp_links; + LinksConfig links; ServicesConfig services; SystemConfig system; MetricsConfig metrics; diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index feb6221c6..224f0a1aa 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -633,16 +633,17 @@ namespace libuv Loop::CloseAll() { llarp::LogInfo("Closing all handles"); - uv_walk(m_Impl.get(), - [](uv_handle_t* h, void*) { - if(uv_is_closing(h)) - return; - if(h->data && uv_is_active(h)) - { - static_cast< glue* >(h->data)->Close(); - } - }, - nullptr); + uv_walk( + m_Impl.get(), + [](uv_handle_t* h, void*) { + if(uv_is_closing(h)) + return; + if(h->data && uv_is_active(h)) + { + static_cast< glue* >(h->data)->Close(); + } + }, + nullptr); } void diff --git a/llarp/link/factory.cpp b/llarp/link/factory.cpp new file mode 100644 index 000000000..ba71f9a1d --- /dev/null +++ b/llarp/link/factory.cpp @@ -0,0 +1,52 @@ +#include +#include +#include + +namespace llarp +{ + LinkFactory::LinkType + LinkFactory::TypeFromName(string_view str) + { + if(str == "utp") + return LinkType::eLinkUTP; + if(str == "iwp") + return LinkType::eLinkIWP; + if(str == "mempipe") + return LinkType::eLinkMempipe; + return LinkType::eLinkUnknown; + } + + std::string + LinkFactory::NameFromType(LinkFactory::LinkType tp) + { + switch(tp) + { + case LinkType::eLinkUTP: + return "utp"; + case LinkType::eLinkIWP: + return "iwp"; + case LinkType::eLinkMempipe: + return "mempipe"; + default: + return "unspec"; + } + } + + LinkFactory::Factory + LinkFactory::Obtain(LinkFactory::LinkType tp, bool permitInbound) + { + switch(tp) + { + case LinkType::eLinkUTP: + if(permitInbound) + return llarp::utp::NewInboundLink; + return llarp::utp::NewOutboundLink; + case LinkType::eLinkMempipe: + if(permitInbound) + return llarp::mempipe::NewInboundLink; + return llarp::mempipe::NewOutboundLink; + default: + return nullptr; + } + } +} // namespace llarp \ No newline at end of file diff --git a/llarp/link/factory.hpp b/llarp/link/factory.hpp new file mode 100644 index 000000000..5acf3063e --- /dev/null +++ b/llarp/link/factory.hpp @@ -0,0 +1,43 @@ +#ifndef LLARP_LINK_FACTORY_HPP +#define LLARP_LINK_FACTORY_HPP +#include +#include + +#include + +namespace llarp +{ + /// LinkFactory is responsible for returning std::functions that create the + /// link layer types + struct LinkFactory + { + enum class LinkType + { + eLinkUTP, + eLinkIWP, + eLinkMempipe, + eLinkUnknown + }; + + using Factory = std::function< LinkLayer_ptr( + const SecretKey&, GetRCFunc, LinkMessageHandler, SignBufferFunc, + SessionEstablishedHandler, SessionRenegotiateHandler, TimeoutHandler, + SessionClosedHandler) >; + + /// get link type by name string + /// if invalid returns eLinkUnspec + static LinkType + TypeFromName(string_view name); + + /// turns a link type into a string representation + static std::string + NameFromType(LinkType t); + + /// obtain a link factory of a certain type + static Factory + Obtain(LinkType t, bool permitInbound); + }; + +} // namespace llarp + +#endif \ No newline at end of file diff --git a/llarp/link/server.hpp b/llarp/link/server.hpp index 74f3cf3cf..3f12f455d 100644 --- a/llarp/link/server.hpp +++ b/llarp/link/server.hpp @@ -103,7 +103,7 @@ namespace llarp llarp_ev_udp_sendto(&m_udp, to, pkt); } - bool + virtual bool Configure(llarp_ev_loop_ptr loop, const std::string& ifname, int af, uint16_t port); @@ -125,7 +125,7 @@ namespace llarp virtual bool Start(std::shared_ptr< llarp::Logic > l); - void + virtual void Stop(); virtual const char* @@ -140,11 +140,11 @@ namespace llarp void KeepAliveSessionTo(const RouterID& remote); - bool + virtual bool SendTo(const RouterID& remote, const llarp_buffer_t& buf, ILinkSession::CompletionHandler completed); - bool + virtual bool GetOurAddressInfo(AddressInfo& addr) const; bool @@ -200,6 +200,12 @@ namespace llarp SessionClosedHandler SessionClosed; SessionRenegotiateHandler SessionRenegotiate; + std::shared_ptr< Logic > + logic() + { + return m_Logic; + } + bool operator<(const ILinkLayer& other) const { diff --git a/llarp/mempipe/mempipe.cpp b/llarp/mempipe/mempipe.cpp new file mode 100644 index 000000000..58a0a3696 --- /dev/null +++ b/llarp/mempipe/mempipe.cpp @@ -0,0 +1,534 @@ +#include +#include +#include +#include + +namespace llarp +{ + namespace mempipe + { + struct MemLink; + struct MemSession; + + struct MempipeContext + { + using Nodes_t = + std::unordered_map< RouterID, LinkLayer_ptr, RouterID::Hash >; + Nodes_t _nodes; + using SendEvent = std::tuple< RouterID, RouterID, std::vector< byte_t >, + ILinkSession::CompletionHandler >; + + std::deque< SendEvent > _sendQueue; + + /// (src, dst, session, hook) + using NodeConnection_t = std::tuple< RouterID, RouterID >; + + struct NodeConnectionHash + { + size_t + operator()(const NodeConnection_t con) const + { + const auto& a = std::get< 0 >(con); + const auto& b = std::get< 1 >(con); + auto op = std::bit_xor< size_t >(); + return std::accumulate(a.begin(), a.end(), + std::accumulate(b.begin(), b.end(), 0, op), + op); + } + }; + + using NodeConnections_t = + std::unordered_map< NodeConnection_t, std::shared_ptr< MemSession >, + NodeConnectionHash >; + + NodeConnections_t _connections; + + mutable util::Mutex _access; + + void + AddNode(LinkLayer_ptr ptr) LOCKS_EXCLUDED(_access); + + void + RemoveNode(LinkLayer_ptr ptr) LOCKS_EXCLUDED(_access); + + LinkLayer_ptr + FindNode(const RouterID pk) LOCKS_EXCLUDED(_access); + + /// connect src to dst + void + ConnectNode(const RouterID src, const RouterID dst, + const std::shared_ptr< MemSession >& ptr) + LOCKS_EXCLUDED(_access); + + /// remote both src and dst as connected + void + DisconnectNode(const RouterID src, const RouterID dst) + LOCKS_EXCLUDED(_access); + + bool + HasConnection(const RouterID src, const RouterID dst) const + LOCKS_EXCLUDED(_access); + + void + InboundConnection(const RouterID to, + const std::shared_ptr< MemSession >& obsession); + + void + CallLater(std::function< void(void) > f) + { + m_Logic->call_later(10, f); + } + + bool + SendTo(const RouterID src, const RouterID dst, + const std::vector< byte_t > msg, + ILinkSession::CompletionHandler delivery) LOCKS_EXCLUDED(_access); + + void + Pump() LOCKS_EXCLUDED(_access); + + void + Start() + { + m_Run.store(true); + m_Thread = new std::thread{[&]() { + m_Logic = std::make_shared< Logic >(); + while(m_Run.load()) + { + Pump(); + m_Logic->tick(time_now_ms()); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + m_Logic = nullptr; + }}; + } + + ~MempipeContext() + { + m_Run.store(false); + if(m_Thread) + { + m_Thread->join(); + delete m_Thread; + } + } + + std::atomic< bool > m_Run; + std::shared_ptr< Logic > m_Logic = nullptr; + std::thread* m_Thread = nullptr; + }; + + using Globals_ptr = std::unique_ptr< MempipeContext >; + + Globals_ptr _globals; + + struct MemSession : public ILinkSession, + public std::enable_shared_from_this< MemSession > + { + MemSession(LinkLayer_ptr _local, LinkLayer_ptr _remote) + : remote(std::move(_remote)), parent(std::move(_local)) + { + } + + LinkLayer_ptr remote; + LinkLayer_ptr parent; + + util::Mutex _access; + + std::deque< std::vector< byte_t > > m_recvQueue; + std::deque< std::tuple< std::vector< byte_t >, CompletionHandler > > + m_sendQueue; + + llarp_time_t lastRecv = 0; + + PubKey + GetPubKey() const override + { + return remote->GetOurRC().pubkey; + } + + bool + SendKeepAlive() override + { + std::array< byte_t, 128 > pkt; + DiscardMessage msg; + llarp_buffer_t buf{pkt}; + if(!msg.BEncode(&buf)) + return false; + buf.sz = buf.cur - buf.base; + buf.cur = buf.base; + return SendMessageBuffer(buf, nullptr); + } + + void + Recv(const std::vector< byte_t > msg) LOCKS_EXCLUDED(_access) + { + util::Lock lock(&_access); + m_recvQueue.emplace_back(std::move(msg)); + lastRecv = parent->Now(); + } + + void + OnLinkEstablished(ILinkLayer*) override + { + return; + } + + bool + TimedOut(llarp_time_t now) const override + { + return now >= lastRecv && now - lastRecv > 5000; + } + + void + PumpWrite() LOCKS_EXCLUDED(_access) + { + std::deque< std::tuple< std::vector< byte_t >, CompletionHandler > > q; + { + util::Lock lock(&_access); + if(m_sendQueue.size()) + q = std::move(m_sendQueue); + } + const RouterID src = parent->GetOurRC().pubkey; + const RouterID dst = GetPubKey(); + while(q.size()) + { + const auto& f = q.front(); + _globals->SendTo(src, dst, std::get< 0 >(f), std::get< 1 >(f)); + q.pop_front(); + } + } + + void + PumpRead() LOCKS_EXCLUDED(_access) + { + std::deque< std::vector< byte_t > > q; + { + util::Lock lock(&_access); + if(m_recvQueue.size()) + q = std::move(m_recvQueue); + } + while(q.size()) + { + const llarp_buffer_t buf{q.front()}; + parent->HandleMessage(this, buf); + q.pop_front(); + } + } + + void Tick(llarp_time_t) override + { + } + + void + Pump() override + { + PumpRead(); + PumpWrite(); + } + + void + Close() override + { + auto self = shared_from_this(); + _globals->CallLater([=]() { self->Disconnected(); }); + } + + RouterContact + GetRemoteRC() const override + { + return remote->GetOurRC(); + } + + bool + ShouldPing() const override + { + return true; + } + + bool + SendMessageBuffer(const llarp_buffer_t& pkt, + ILinkSession::CompletionHandler completed) override + { + if(completed == nullptr) + completed = [](ILinkSession::DeliveryStatus) {}; + auto self = shared_from_this(); + std::vector< byte_t > buf(pkt.sz); + std::copy_n(pkt.base, pkt.sz, buf.begin()); + return _globals->SendTo(parent->GetOurRC().pubkey, GetRemoteRC().pubkey, + buf, [=](ILinkSession::DeliveryStatus status) { + self->parent->logic()->call_later( + 10, std::bind(completed, status)); + }); + } + + void + Start() override + { + auto self = shared_from_this(); + _globals->CallLater( + [=]() { _globals->InboundConnection(self->GetPubKey(), self); }); + } + + bool + IsEstablished() const override + { + return _globals->HasConnection(parent->GetOurRC().pubkey, GetPubKey()); + } + + void + Disconnected() + { + _globals->DisconnectNode(parent->GetOurRC().pubkey, GetPubKey()); + } + + bool + RenegotiateSession() override + { + return true; + } + + ILinkLayer* + GetLinkLayer() const override + { + return parent.get(); + } + + util::StatusObject + ExtractStatus() const override + { + return {}; + } + + llarp::Addr + GetRemoteEndpoint() const override + { + return {}; + } + + size_t + SendQueueBacklog() const override + { + return m_sendQueue.size(); + } + }; + + struct MemLink : public ILinkLayer, + public std::enable_shared_from_this< MemLink > + { + MemLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, SessionRenegotiateHandler reneg, + TimeoutHandler timeout, SessionClosedHandler closed, + bool permitInbound) + : ILinkLayer(routerEncSecret, getrc, h, sign, est, reneg, timeout, + closed) + , allowInbound(permitInbound) + { + } + + const bool allowInbound; + + bool + KeyGen(SecretKey& k) override + { + k.Zero(); + return true; + } + + const char* + Name() const override + { + return "mempipe"; + } + + uint16_t + Rank() const override + { + return 100; + } + + void + RecvFrom(const llarp::Addr&, const void*, size_t) override + { + } + + bool + Configure(llarp_ev_loop_ptr, const std::string&, int, uint16_t) override + { + if(_globals == nullptr) + _globals = std::make_unique< MempipeContext >(); + return _globals != nullptr; + } + + std::shared_ptr< ILinkSession > + NewOutboundSession(const RouterContact& rc, + const AddressInfo& ai) override + { + if(ai.dialect != Name()) + return nullptr; + auto remote = _globals->FindNode(rc.pubkey); + if(remote == nullptr) + return nullptr; + return std::make_shared< MemSession >(shared_from_this(), remote); + } + + bool + Start(std::shared_ptr< Logic > l) override + { + if(!ILinkLayer::Start(l)) + return false; + _globals->AddNode(shared_from_this()); + return true; + } + + void + Stop() override + { + _globals->RemoveNode(shared_from_this()); + } + }; + + LinkLayer_ptr + NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) + { + return std::make_shared< MemLink >(routerEncSecret, getrc, h, sign, est, + reneg, timeout, closed, false); + } + + LinkLayer_ptr + NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) + { + return std::make_shared< MemLink >(routerEncSecret, getrc, h, sign, est, + reneg, timeout, closed, true); + } + + void + MempipeContext::AddNode(LinkLayer_ptr ptr) + { + util::Lock lock(&_access); + _nodes.emplace(RouterID(ptr->GetOurRC().pubkey), ptr); + } + + bool + MempipeContext::SendTo(const RouterID src, const RouterID dst, + const std::vector< byte_t > msg, + ILinkSession::CompletionHandler delivery) + { + util::Lock lock(&_access); + _sendQueue.emplace_back(std::move(src), std::move(dst), std::move(msg), + std::move(delivery)); + return true; + } + + void + MempipeContext::InboundConnection(const RouterID to, + const std::shared_ptr< MemSession >& ob) + { + std::shared_ptr< MemSession > other; + { + util::Lock lock(&_access); + auto itr = _nodes.find(to); + if(itr != _nodes.end()) + { + other = std::make_shared< MemSession >(itr->second, ob->parent); + } + } + if(other) + { + ConnectNode(other->GetPubKey(), ob->GetPubKey(), other); + ConnectNode(ob->GetPubKey(), other->GetPubKey(), ob); + } + else + { + ob->Disconnected(); + } + } + + void + MempipeContext::ConnectNode(const RouterID src, const RouterID dst, + const std::shared_ptr< MemSession >& session) + { + util::Lock lock(&_access); + _connections.emplace(std::make_pair(std::make_tuple(src, dst), session)); + } + + void + MempipeContext::DisconnectNode(const RouterID src, const RouterID dst) + { + util::Lock lock(&_access); + _connections.erase({src, dst}); + } + + LinkLayer_ptr + MempipeContext::FindNode(const RouterID rid) + { + util::Lock lock(&_access); + auto itr = _nodes.find(rid); + if(itr == _nodes.end()) + return nullptr; + return itr->second; + } + + bool + MempipeContext::HasConnection(const RouterID src, const RouterID dst) const + { + util::Lock lock(&_access); + return _connections.find({src, dst}) != _connections.end(); + } + + void + MempipeContext::RemoveNode(LinkLayer_ptr node) + { + util::Lock lock(&_access); + const RouterID pk = node->GetOurRC().pubkey; + _nodes.erase(pk); + auto itr = _connections.begin(); + while(itr != _connections.end()) + { + if(std::get< 0 >(itr->first) == pk || std::get< 1 >(itr->first) == pk) + { + auto s = itr->second->shared_from_this(); + itr->second->GetLinkLayer()->logic()->call_later( + 1, [s]() { s->Disconnected(); }); + } + ++itr; + } + } + + void + MempipeContext::Pump() + { + std::deque< SendEvent > q; + { + util::Lock lock(&_access); + q = std::move(_sendQueue); + } + while(q.size()) + { + const auto& f = q.front(); + { + util::Lock lock(&_access); + auto itr = _connections.find({std::get< 0 >(f), std::get< 1 >(f)}); + ILinkSession::DeliveryStatus status = + ILinkSession::DeliveryStatus::eDeliveryDropped; + if(itr != _connections.end()) + { + status = ILinkSession::DeliveryStatus::eDeliverySuccess; + itr->second->Recv(std::get< 2 >(f)); + } + CallLater(std::bind(std::get< 3 >(f), status)); + } + q.pop_front(); + } + } + } // namespace mempipe +} // namespace llarp \ No newline at end of file diff --git a/llarp/mempipe/mempipe.hpp b/llarp/mempipe/mempipe.hpp new file mode 100644 index 000000000..91094602a --- /dev/null +++ b/llarp/mempipe/mempipe.hpp @@ -0,0 +1,25 @@ +#ifndef LLARP_MEMPIPE_MEMPIPE_HPP +#define LLARP_MEMPIPE_MEMPIPE_HPP +#include +#include + +namespace llarp +{ + namespace mempipe + { + LinkLayer_ptr + NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); + LinkLayer_ptr + NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); + } // namespace mempipe +} // namespace llarp + +#endif \ No newline at end of file diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 97f69d3fe..c3585cff1 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -103,8 +103,8 @@ namespace llarp } bool - Path::HandleLRSM(uint64_t status, - std::array< EncryptedFrame, 8 >& frames, AbstractRouter* r) + Path::HandleLRSM(uint64_t status, std::array< EncryptedFrame, 8 >& frames, + AbstractRouter* r) { uint64_t currentStatus = status; diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp index b2460f84b..84a19f575 100644 --- a/llarp/path/path_context.cpp +++ b/llarp/path/path_context.cpp @@ -164,14 +164,15 @@ namespace llarp 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); - }); + 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; diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 686e44d1a..c0207304a 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -368,9 +368,17 @@ namespace llarp // reset netid in our rc _rc.netID = llarp::NetID(); } + const auto linktypename = conf->router.defaultLinkProto(); + _defaultLinkType = LinkFactory::TypeFromName(linktypename); + if(_defaultLinkType == LinkFactory::LinkType::eLinkUnknown) + { + LogError("failed to set link type to '", linktypename, + "' as that is invalid"); + return false; + } // IWP config - m_OutboundPort = conf->iwp_links.outboundPort(); + m_OutboundPort = std::get< LinksConfig::Port >(conf->links.outboundLink()); // Router config _rc.SetNick(conf->router.nickname()); maxConnectedRouters = conf->router.maxConnectedRouters(); @@ -391,7 +399,7 @@ namespace llarp lokidRPCPassword = conf->lokid.lokidRPCPassword; // TODO: add config flag for "is service node" - if(conf->iwp_links.servers().size()) + if(conf->links.inboundLinks().size()) { m_isServiceNode = true; } @@ -479,15 +487,34 @@ namespace llarp } // create inbound links, if we are a service node - for(const auto &serverConfig : conf->iwp_links.servers()) + for(const auto &serverConfig : conf->links.inboundLinks()) { - auto server = llarp::utp::NewInboundLink( + // get default factory + auto inboundLinkFactory = LinkFactory::Obtain(_defaultLinkType, true); + // for each option if provided ... + for(const auto &opt : std::get< LinksConfig::Options >(serverConfig)) + { + // try interpreting it as a link type + const auto linktype = LinkFactory::TypeFromName(opt); + if(linktype != LinkFactory::LinkType::eLinkUnknown) + { + // override link factory if it's a valid link type + auto factory = LinkFactory::Obtain(linktype, true); + if(factory) + { + inboundLinkFactory = std::move(factory); + break; + } + } + } + + auto server = inboundLinkFactory( encryption(), util::memFn(&AbstractRouter::rc, this), util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), + util::memFn(&AbstractRouter::Sign, this), util::memFn(&IOutboundSessionMaker::OnSessionEstablished, &_outboundSessionMaker), util::memFn(&AbstractRouter::CheckRenegotiateValid, this), - util::memFn(&AbstractRouter::Sign, this), util::memFn(&IOutboundSessionMaker::OnConnectTimeout, &_outboundSessionMaker), util::memFn(&AbstractRouter::SessionClosed, this)); @@ -498,9 +525,9 @@ namespace llarp return false; } - const auto &key = std::get< 0 >(serverConfig); - int af = std::get< 1 >(serverConfig); - uint16_t port = std::get< 2 >(serverConfig); + const auto &key = std::get< LinksConfig::Interface >(serverConfig); + int af = std::get< LinksConfig::AddressFamily >(serverConfig); + uint16_t port = std::get< LinksConfig::Port >(serverConfig); if(!server->Configure(netloop(), key, af, port)) { LogError("failed to bind inbound link on ", key, " port ", port); @@ -1059,48 +1086,44 @@ namespace llarp bool Router::InitOutboundLinks() { - using LinkFactory = std::function< LinkLayer_ptr( - const SecretKey &, GetRCFunc, LinkMessageHandler, - SessionEstablishedHandler, SessionRenegotiateHandler, SignBufferFunc, - TimeoutHandler, SessionClosedHandler) >; + const auto linkTypeName = LinkFactory::NameFromType(_defaultLinkType); + LogInfo("initialize outbound link: ", linkTypeName); + auto factory = LinkFactory::Obtain(_defaultLinkType, false); + if(factory == nullptr) + { + LogError("cannot initialize outbound link of type '", linkTypeName, + "' as it has no implementation"); + return false; + } + auto link = + factory(encryption(), util::memFn(&AbstractRouter::rc, this), + util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), + util::memFn(&AbstractRouter::Sign, this), + util::memFn(&IOutboundSessionMaker::OnSessionEstablished, + &_outboundSessionMaker), + util::memFn(&AbstractRouter::CheckRenegotiateValid, this), + util::memFn(&IOutboundSessionMaker::OnConnectTimeout, + &_outboundSessionMaker), + util::memFn(&AbstractRouter::SessionClosed, this)); + + if(!link) + return false; + if(!link->EnsureKeys(transport_keyfile.string().c_str())) + { + LogError("failed to load ", transport_keyfile); + return false; + } - static std::list< LinkFactory > linkFactories = {utp::NewOutboundLink, - iwp::NewServer}; + const auto afs = {AF_INET, AF_INET6}; - bool addedAtLeastOne = false; - for(const auto &factory : linkFactories) + for(const auto af : afs) { - auto link = factory( - encryption(), util::memFn(&AbstractRouter::rc, this), - util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), - util::memFn(&IOutboundSessionMaker::OnSessionEstablished, - &_outboundSessionMaker), - util::memFn(&AbstractRouter::CheckRenegotiateValid, this), - util::memFn(&AbstractRouter::Sign, this), - util::memFn(&IOutboundSessionMaker::OnConnectTimeout, - &_outboundSessionMaker), - util::memFn(&AbstractRouter::SessionClosed, this)); - - if(!link) + if(!link->Configure(netloop(), "*", af, m_OutboundPort)) continue; - if(!link->EnsureKeys(transport_keyfile.string().c_str())) - { - LogError("failed to load ", transport_keyfile); - continue; - } - - const auto afs = {AF_INET, AF_INET6}; - - for(const auto af : afs) - { - if(!link->Configure(netloop(), "*", af, m_OutboundPort)) - continue; - _linkManager.AddLink(std::move(link), false); - addedAtLeastOne = true; - break; - } + _linkManager.AddLink(std::move(link), false); + return true; } - return addedAtLeastOne; + return false; } bool diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 2b6b2df86..e4f2fb4d0 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -175,6 +176,8 @@ namespace llarp struct sockaddr_in ip4addr; AddressInfo addrInfo; + LinkFactory::LinkType _defaultLinkType; + llarp_ev_loop_ptr _netloop; std::shared_ptr< llarp::thread::ThreadPool > cryptoworker; std::shared_ptr< Logic > _logic; diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index f00fb9e9d..f70194c50 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -510,7 +510,7 @@ namespace llarp { auto msg = std::make_shared< routing::DHTMessage >(); msg->M.emplace_back( - std::make_unique< dht::PublishIntroMessage >(m_IntroSet, txid, 1)); + std::make_unique< dht::PublishIntroMessage >(m_IntroSet, txid, 5)); return msg; } diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index a42d24aba..31dab271e 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -309,7 +309,8 @@ namespace llarp if(self->frame.T != self->msg->tag) { - LogError("convotag missmatch: ", self->frame.T, " != ", self->msg->tag); + LogError("convotag missmatch: ", self->frame.T, + " != ", self->msg->tag); self->msg.reset(); delete self; return; diff --git a/llarp/utp/utp.cpp b/llarp/utp/utp.cpp index 01d47502d..911fdc309 100644 --- a/llarp/utp/utp.cpp +++ b/llarp/utp/utp.cpp @@ -10,9 +10,10 @@ namespace llarp { LinkLayer_ptr NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed) + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) { return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, reneg, timeout, closed, false); @@ -20,9 +21,10 @@ namespace llarp LinkLayer_ptr NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed) + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) { return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, reneg, timeout, closed, true); diff --git a/llarp/utp/utp.hpp b/llarp/utp/utp.hpp index 10857b796..d368065e2 100644 --- a/llarp/utp/utp.hpp +++ b/llarp/utp/utp.hpp @@ -6,20 +6,20 @@ namespace llarp { - struct AbstractRouter; - namespace utp { LinkLayer_ptr NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed); + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); LinkLayer_ptr NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed); + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); /// shim const auto NewServer = NewInboundLink; } // namespace utp diff --git a/test/config/test_llarp_config_config.cpp b/test/config/test_llarp_config_config.cpp index 55eadeb3c..a31a7ed79 100644 --- a/test/config/test_llarp_config_config.cpp +++ b/test/config/test_llarp_config_config.cpp @@ -102,10 +102,10 @@ metric-tank-host=52.80.56.123:2003 ASSERT_FALSE(config.metrics.disableMetrics); { - using kv = IwpConfig::Servers::value_type; + using kv = LinksConfig::Links::value_type; - ASSERT_THAT(config.iwp_links.servers(), - UnorderedElementsAre(kv("eth0", AF_INET, 5501))); + ASSERT_THAT(config.links.inboundLinks(), + UnorderedElementsAre(kv("eth0", AF_INET, 5501, {}))); } ASSERT_THAT(config.bootstrap.routers, diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index 3c83b5050..63aec45f2 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -193,14 +193,15 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) return true; } }, + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Alice.signingKey, buf); + }, [&](ILinkSession* s) -> bool { const auto rc = s->GetRemoteRC(); return rc.pubkey == Bob.GetRC().pubkey; }, [&](RouterContact, RouterContact) -> bool { return true; }, - [&](Signature& sig, const llarp_buffer_t& buf) -> bool { - return m_crypto.sign(sig, Alice.signingKey, buf); - }, + [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); Stop(); @@ -231,6 +232,10 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) Bob.gotLIM = true; return sendDiscardMessage(s); }, + + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Bob.signingKey, buf); + }, [&](ILinkSession* s) -> bool { if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey) return false; @@ -242,9 +247,6 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) success = newrc.pubkey == oldrc.pubkey; return true; }, - [&](Signature& sig, const llarp_buffer_t& buf) -> bool { - return m_crypto.sign(sig, Bob.signingKey, buf); - }, [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); }, [&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); }); @@ -280,6 +282,9 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return false; } return AliceGotMessage(buf); + }, + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Alice.signingKey, buf); }, [&](ILinkSession* s) -> bool { if(s->GetRemoteRC().pubkey != Bob.GetRC().pubkey) @@ -288,9 +293,7 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return true; }, [&](RouterContact, RouterContact) -> bool { return true; }, - [&](Signature& sig, const llarp_buffer_t& buf) -> bool { - return m_crypto.sign(sig, Alice.signingKey, buf); - }, + [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); Stop(); @@ -312,6 +315,9 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return false; } return true; + }, + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Bob.signingKey, buf); }, [&](ILinkSession* s) -> bool { if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey) @@ -332,9 +338,6 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return true; }, [&](RouterContact, RouterContact) -> bool { return true; }, - [&](Signature& sig, const llarp_buffer_t& buf) -> bool { - return m_crypto.sign(sig, Bob.signingKey, buf); - }, [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); }, [&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); }); From aea4542edd9e7f47f190c4eb9b6fe25824eed85f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 22 Aug 2019 07:18:05 -0400 Subject: [PATCH 02/44] more --- llarp/ev/ev.hpp | 5 ++ llarp/ev/ev_libuv.cpp | 81 ++++++++++++++++++++ llarp/ev/ev_libuv.hpp | 4 + llarp/ev/pipe.cpp | 4 +- llarp/ev/pipe.hpp | 2 +- llarp/mempipe/mempipe.cpp | 137 +++++++++++++++++++++++++++------- test/link/test_llarp_link.cpp | 94 +++++++++++++++++++++++ 7 files changed, 295 insertions(+), 32 deletions(-) diff --git a/llarp/ev/ev.hpp b/llarp/ev/ev.hpp index 0a4de55fa..1f610c100 100644 --- a/llarp/ev/ev.hpp +++ b/llarp/ev/ev.hpp @@ -40,6 +40,8 @@ typedef struct sockaddr_un #include #endif +struct llarp_ev_pkt_pipe; + #ifndef MAX_WRITE_QUEUE_SIZE #define MAX_WRITE_QUEUE_SIZE (1024UL) #endif @@ -772,6 +774,9 @@ struct llarp_ev_loop virtual llarp::ev_io* bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* addr) = 0; + virtual bool + add_pipe(llarp_ev_pkt_pipe* p) = 0; + /// register event listener virtual bool add_ev(llarp::ev_io* ev, bool write) = 0; diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 3b9ac4307..93a815892 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -427,6 +427,77 @@ namespace libuv } }; + struct pipe_glue : public glue + { + byte_t m_Buffer[1024 * 8]; + llarp_ev_pkt_pipe* const m_Pipe; + pipe_glue(uv_loop_t* loop, llarp_ev_pkt_pipe* pipe) : m_Pipe(pipe) + { + m_Handle.data = this; + m_Ticker.data = this; + uv_poll_init(loop, &m_Handle, m_Pipe->fd); + uv_check_init(loop, &m_Ticker); + } + + void + Tick() + { + m_Pipe->tick(); + } + + static void + OnRead(uv_poll_t* handle, int status, int) + { + if(status) + { + return; + } + pipe_glue* glue = static_cast< pipe_glue* >(handle->data); + int r = glue->m_Pipe->read(glue->m_Buffer, sizeof(glue->m_Buffer)); + if(r <= 0) + return; + const llarp_buffer_t buf{glue->m_Buffer, size_t{r}}; + glue->m_Pipe->OnRead(buf); + } + + static void + OnClosed(uv_handle_t* h) + { + auto* self = static_cast< pipe_glue* >(h->data); + if(self) + { + h->data = nullptr; + delete self; + } + } + + void + Close() override + { + uv_check_stop(&m_Ticker); + uv_close((uv_handle_t*)&m_Handle, &OnClosed); + } + + static void + OnTick(uv_check_t* h) + { + static_cast< pipe_glue* >(h->data)->Tick(); + } + + bool + Start() + { + if(uv_poll_start(&m_Handle, UV_READABLE, &OnRead)) + return false; + if(uv_check_start(&m_Ticker, &OnTick)) + return false; + return true; + } + + uv_poll_t m_Handle; + uv_check_t m_Ticker; + }; + struct tun_glue : public glue { uv_poll_t m_Handle; @@ -703,4 +774,14 @@ namespace libuv return false; } + bool + Loop::add_pipe(llarp_ev_pkt_pipe* p) + { + auto* glue = new pipe_glue(m_Impl.get(), p); + if(glue->Start()) + return true; + delete glue; + return false; + } + } // namespace libuv diff --git a/llarp/ev/ev_libuv.hpp b/llarp/ev/ev_libuv.hpp index b9b85d3df..3ad9a6389 100644 --- a/llarp/ev/ev_libuv.hpp +++ b/llarp/ev/ev_libuv.hpp @@ -1,6 +1,7 @@ #ifndef LLARP_EV_LIBUV_HPP #define LLARP_EV_LIBUV_HPP #include +#include #include #include #include @@ -68,6 +69,9 @@ namespace libuv bool tcp_listen(llarp_tcp_acceptor* tcp, const sockaddr* addr) override; + bool + add_pipe(llarp_ev_pkt_pipe* p) override; + llarp::ev_io* bind_tcp(llarp_tcp_acceptor*, const sockaddr*) override { diff --git a/llarp/ev/pipe.cpp b/llarp/ev/pipe.cpp index 76d141a9e..049e702ee 100644 --- a/llarp/ev/pipe.cpp +++ b/llarp/ev/pipe.cpp @@ -12,7 +12,7 @@ llarp_ev_pkt_pipe::llarp_ev_pkt_pipe(llarp_ev_loop_ptr loop) } bool -llarp_ev_pkt_pipe::Start() +llarp_ev_pkt_pipe::StartPipe() { #if defined(_WIN32) llarp::LogError("llarp_ev_pkt_pipe not supported on win32"); @@ -26,7 +26,7 @@ llarp_ev_pkt_pipe::Start() } fd = _fds[0]; writefd = _fds[1]; - return true; + return m_Loop->add_pipe(this); #endif } diff --git a/llarp/ev/pipe.hpp b/llarp/ev/pipe.hpp index 0bf1953fc..2abff3c48 100644 --- a/llarp/ev/pipe.hpp +++ b/llarp/ev/pipe.hpp @@ -10,7 +10,7 @@ struct llarp_ev_pkt_pipe : public llarp::ev_io /// start the pipe, initialize fds bool - Start(); + StartPipe(); /// write to the pipe from outside the event loop /// returns true on success diff --git a/llarp/mempipe/mempipe.cpp b/llarp/mempipe/mempipe.cpp index 58a0a3696..3f0042de4 100644 --- a/llarp/mempipe/mempipe.cpp +++ b/llarp/mempipe/mempipe.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace llarp { @@ -18,9 +19,8 @@ namespace llarp using SendEvent = std::tuple< RouterID, RouterID, std::vector< byte_t >, ILinkSession::CompletionHandler >; - std::deque< SendEvent > _sendQueue; - /// (src, dst, session, hook) + std::vector< SendEvent > _sendQueue; using NodeConnection_t = std::tuple< RouterID, RouterID >; struct NodeConnectionHash @@ -76,7 +76,10 @@ namespace llarp void CallLater(std::function< void(void) > f) { - m_Logic->call_later(10, f); + if(m_Logic && f) + m_Logic->queue_func(f); + else if(f) + LogError("dropping call"); } bool @@ -88,34 +91,38 @@ namespace llarp Pump() LOCKS_EXCLUDED(_access); void - Start() + Start(llarp_ev_loop_ptr loop) { + evloop = loop; m_Run.store(true); - m_Thread = new std::thread{[&]() { + std::promise< void > p; + m_Thread = std::make_unique< std::thread >([&]() { + LogDebug("mempipe started"); m_Logic = std::make_shared< Logic >(); + p.set_value(); while(m_Run.load()) { - Pump(); m_Logic->tick(time_now_ms()); std::this_thread::sleep_for(std::chrono::milliseconds(1)); + Pump(); } - m_Logic = nullptr; - }}; + m_Logic->stop(); + }); + p.get_future().wait(); + LogDebug("mempipe up"); } ~MempipeContext() { m_Run.store(false); if(m_Thread) - { m_Thread->join(); - delete m_Thread; - } } std::atomic< bool > m_Run; - std::shared_ptr< Logic > m_Logic = nullptr; - std::thread* m_Thread = nullptr; + std::shared_ptr< Logic > m_Logic; + std::unique_ptr< std::thread > m_Thread = nullptr; + llarp_ev_loop_ptr evloop = nullptr; }; using Globals_ptr = std::unique_ptr< MempipeContext >; @@ -123,15 +130,21 @@ namespace llarp Globals_ptr _globals; struct MemSession : public ILinkSession, + public llarp_ev_pkt_pipe, public std::enable_shared_from_this< MemSession > { - MemSession(LinkLayer_ptr _local, LinkLayer_ptr _remote) - : remote(std::move(_remote)), parent(std::move(_local)) + MemSession(llarp_ev_loop_ptr ev, LinkLayer_ptr _local, + LinkLayer_ptr _remote, bool inbound) + : llarp_ev_pkt_pipe(ev) + , remote{std::move(_remote)} + , parent{std::move(_local)} + , isInbound{inbound} { } LinkLayer_ptr remote; LinkLayer_ptr parent; + const bool isInbound; util::Mutex _access; @@ -160,6 +173,15 @@ namespace llarp return SendMessageBuffer(buf, nullptr); } + void + OnRead(const llarp_buffer_t& pkt) override + { + std::vector< byte_t > buf; + buf.resize(pkt.sz); + std::copy_n(pkt.base, pkt.sz, buf.begin()); + Recv(std::move(buf)); + } + void Recv(const std::vector< byte_t > msg) LOCKS_EXCLUDED(_access) { @@ -218,6 +240,7 @@ namespace llarp void Tick(llarp_time_t) override { + Pump(); } void @@ -265,9 +288,16 @@ namespace llarp void Start() override { + if(!StartPipe()) + return; + if(isInbound) + return; + LogDebug("outbound start"); auto self = shared_from_this(); - _globals->CallLater( - [=]() { _globals->InboundConnection(self->GetPubKey(), self); }); + _globals->CallLater([=]() { + LogDebug("Called inbound connection"); + _globals->InboundConnection(self->GetPubKey(), self); + }); } bool @@ -348,16 +378,49 @@ namespace llarp return 100; } + void + Pump() override + { + LogDebug("memlink pump"); + std::set< RouterID > sessions; + { + Lock l(&m_AuthedLinksMutex); + auto itr = m_AuthedLinks.begin(); + while(itr != m_AuthedLinks.end()) + { + sessions.insert(itr->first); + ++itr; + } + } + ILinkLayer::Pump(); + { + Lock l(&m_AuthedLinksMutex); + for(const auto& pk : sessions) + { + if(m_AuthedLinks.count(pk) == 0) + { + // all sessions were removed + SessionClosed(pk); + } + } + } + } + void RecvFrom(const llarp::Addr&, const void*, size_t) override { } bool - Configure(llarp_ev_loop_ptr, const std::string&, int, uint16_t) override + Configure(llarp_ev_loop_ptr ev, const std::string&, int, + uint16_t) override { + m_Loop = ev; if(_globals == nullptr) + { _globals = std::make_unique< MempipeContext >(); + _globals->Start(ev); + } return _globals != nullptr; } @@ -370,7 +433,8 @@ namespace llarp auto remote = _globals->FindNode(rc.pubkey); if(remote == nullptr) return nullptr; - return std::make_shared< MemSession >(shared_from_this(), remote); + return std::make_shared< MemSession >(m_Loop, shared_from_this(), + remote, false); } bool @@ -416,6 +480,7 @@ namespace llarp { util::Lock lock(&_access); _nodes.emplace(RouterID(ptr->GetOurRC().pubkey), ptr); + LogInfo("add mempipe node: ", RouterID(ptr->GetOurRC().pubkey)); } bool @@ -433,19 +498,30 @@ namespace llarp MempipeContext::InboundConnection(const RouterID to, const std::shared_ptr< MemSession >& ob) { + LogDebug("inbound connect to ", to, " from ", + RouterID(ob->parent->GetOurRC().pubkey)); std::shared_ptr< MemSession > other; { util::Lock lock(&_access); auto itr = _nodes.find(to); if(itr != _nodes.end()) { - other = std::make_shared< MemSession >(itr->second, ob->parent); + other = std::make_shared< MemSession >(evloop, itr->second, + ob->parent, true); } } if(other) { ConnectNode(other->GetPubKey(), ob->GetPubKey(), other); ConnectNode(ob->GetPubKey(), other->GetPubKey(), ob); + ob->parent->logic()->queue_func([ob]() { + ob->parent->MapAddr(RouterID{ob->GetPubKey()}, ob.get()); + ob->parent->SessionEstablished(ob.get()); + }); + other->parent->logic()->queue_func([other]() { + other->parent->MapAddr(RouterID{other->GetPubKey()}, other.get()); + other->parent->SessionEstablished(other.get()); + }); } else { @@ -457,6 +533,7 @@ namespace llarp MempipeContext::ConnectNode(const RouterID src, const RouterID dst, const std::shared_ptr< MemSession >& session) { + LogDebug("connect ", src, " to ", dst); util::Lock lock(&_access); _connections.emplace(std::make_pair(std::make_tuple(src, dst), session)); } @@ -464,6 +541,7 @@ namespace llarp void MempipeContext::DisconnectNode(const RouterID src, const RouterID dst) { + LogDebug("connect ", src, " from ", dst); util::Lock lock(&_access); _connections.erase({src, dst}); } @@ -507,27 +585,28 @@ namespace llarp void MempipeContext::Pump() { - std::deque< SendEvent > q; + std::vector< SendEvent > q; { util::Lock lock(&_access); q = std::move(_sendQueue); } - while(q.size()) + for(auto& f : q) { - const auto& f = q.front(); + ILinkSession::DeliveryStatus status = + ILinkSession::DeliveryStatus::eDeliveryDropped; { util::Lock lock(&_access); auto itr = _connections.find({std::get< 0 >(f), std::get< 1 >(f)}); - ILinkSession::DeliveryStatus status = - ILinkSession::DeliveryStatus::eDeliveryDropped; if(itr != _connections.end()) { - status = ILinkSession::DeliveryStatus::eDeliverySuccess; - itr->second->Recv(std::get< 2 >(f)); + const llarp_buffer_t pkt{std::get< 2 >(f)}; + if(itr->second->Write(pkt)) + status = ILinkSession::DeliveryStatus::eDeliverySuccess; } - CallLater(std::bind(std::get< 3 >(f), status)); } - q.pop_front(); + LogDebug(std::get< 0 >(f), "->", std::get< 1 >(f), + " status=", (int)status); + CallLater(std::bind(std::get< 3 >(f), status)); } } } // namespace mempipe diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index 63aec45f2..d214a9cc1 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -2,10 +2,12 @@ #include #include #include +#include #include #include #include + #include #include @@ -118,6 +120,7 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > void SetUp() { + SetLogLevel(eLogDebug); oldRCLifetime = RouterContact::Lifetime; RouterContact::IgnoreBogons = true; RouterContact::Lifetime = 500; @@ -134,6 +137,7 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > netLoop.reset(); RouterContact::IgnoreBogons = false; RouterContact::Lifetime = oldRCLifetime; + SetLogLevel(eLogInfo); } static void @@ -167,6 +171,96 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > } }; +TEST_F(LinkLayerTest, TestMemPipe) +{ + Alice.link = mempipe::NewInboundLink( + Alice.encryptionKey, + [&]() -> const RouterContact& { return Alice.GetRC(); }, + [&](ILinkSession* s, const llarp_buffer_t& buf) -> bool { + if(Alice.gotLIM) + { + Alice.Regen(); + return s->RenegotiateSession(); + } + else + { + LinkIntroMessage msg; + ManagedBuffer copy{buf}; + if(!msg.BDecode(©.underlying)) + return false; + if(!s->GotLIM(&msg)) + return false; + Alice.gotLIM = true; + return true; + } + }, + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Alice.signingKey, buf); + }, + [&](ILinkSession* s) -> bool { + const auto rc = s->GetRemoteRC(); + return rc.pubkey == Bob.GetRC().pubkey; + }, + [&](RouterContact, RouterContact) -> bool { return true; }, + + [&](ILinkSession* session) { + ASSERT_FALSE(session->IsEstablished()); + Stop(); + }, + [&](RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); }); + + auto sendDiscardMessage = [](ILinkSession* s) -> bool { + // send discard message in reply to complete unit test + std::array< byte_t, 32 > tmp; + llarp_buffer_t otherBuf(tmp); + DiscardMessage discard; + if(!discard.BEncode(&otherBuf)) + return false; + otherBuf.sz = otherBuf.cur - otherBuf.base; + otherBuf.cur = otherBuf.base; + return s->SendMessageBuffer(otherBuf, nullptr); + }; + + Bob.link = mempipe::NewInboundLink( + Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); }, + [&](ILinkSession* s, const llarp_buffer_t& buf) -> bool { + LinkIntroMessage msg; + ManagedBuffer copy{buf}; + if(!msg.BDecode(©.underlying)) + return false; + if(!s->GotLIM(&msg)) + return false; + Bob.gotLIM = true; + return sendDiscardMessage(s); + }, + + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Bob.signingKey, buf); + }, + [&](ILinkSession* s) -> bool { + if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey) + return false; + LogInfo("bob established with alice"); + return Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(), + sendDiscardMessage); + }, + [&](RouterContact newrc, RouterContact oldrc) -> bool { + success = newrc.pubkey == oldrc.pubkey; + return true; + }, + [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); }, + [&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); }); + + ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort)); + ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort)); + + ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC())); + + RunMainloop(); + ASSERT_TRUE(Bob.gotLIM); + ASSERT_TRUE(success); +}; + TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) { #ifdef WIN32 From 426ee41c46e809f345ec391b8950885381930cc9 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 22 Aug 2019 16:53:27 -0400 Subject: [PATCH 03/44] initial iwp --- llarp/CMakeLists.txt | 6 +- llarp/iwp/iwp.cpp | 34 +- llarp/iwp/iwp.hpp | 22 +- llarp/iwp/linklayer.cpp | 143 ++------ llarp/iwp/linklayer.hpp | 43 +-- llarp/iwp/message_buffer.cpp | 160 +++++++++ llarp/iwp/message_buffer.hpp | 97 ++++++ llarp/iwp/outermessage.cpp | 155 --------- llarp/iwp/outermessage.hpp | 86 ----- llarp/iwp/session.cpp | 536 +++++++++++++++++++++++++++++ llarp/iwp/session.hpp | 189 +++++++++++ llarp/link/factory.cpp | 8 +- llarp/link/session.hpp | 9 +- llarp/mempipe/mempipe.cpp | 613 ---------------------------------- llarp/mempipe/mempipe.hpp | 25 -- test/link/test_llarp_link.cpp | 13 +- 16 files changed, 1064 insertions(+), 1075 deletions(-) create mode 100644 llarp/iwp/message_buffer.cpp create mode 100644 llarp/iwp/message_buffer.hpp delete mode 100644 llarp/iwp/outermessage.cpp delete mode 100644 llarp/iwp/outermessage.hpp create mode 100644 llarp/iwp/session.cpp create mode 100644 llarp/iwp/session.hpp delete mode 100644 llarp/mempipe/mempipe.cpp delete mode 100644 llarp/mempipe/mempipe.hpp diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index db3854ce1..fd6a36fbc 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -176,15 +176,15 @@ set(LIB_SRC handlers/null.cpp handlers/tun.cpp hook/shell.cpp - iwp/linklayer.cpp - iwp/outermessage.cpp iwp/iwp.cpp + iwp/linklayer.cpp + iwp/message_buffer.cpp + iwp/session.cpp link/factory.cpp link/i_link_manager.cpp link/link_manager.cpp link/server.cpp link/session.cpp - mempipe/mempipe.cpp messages/dht_immediate.cpp messages/discard.cpp messages/link_intro.cpp diff --git a/llarp/iwp/iwp.cpp b/llarp/iwp/iwp.cpp index 457a51340..eae5384be 100644 --- a/llarp/iwp/iwp.cpp +++ b/llarp/iwp/iwp.cpp @@ -7,22 +7,26 @@ namespace llarp { namespace iwp { - std::unique_ptr< ILinkLayer > - NewServer(const SecretKey& enckey, GetRCFunc getrc, LinkMessageHandler h, - SessionEstablishedHandler est, SessionRenegotiateHandler reneg, - SignBufferFunc sign, TimeoutHandler t, - SessionClosedHandler closed) + LinkLayer_ptr + NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) { - (void)enckey; - (void)getrc; - (void)h; - (void)est; - (void)reneg; - (void)sign; - (void)t; - (void)closed; - // TODO: implement me - return nullptr; + return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, + reneg, timeout, closed, true); + } + + LinkLayer_ptr + NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) + { + return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, + reneg, timeout, closed, false); } } // namespace iwp } // namespace llarp diff --git a/llarp/iwp/iwp.hpp b/llarp/iwp/iwp.hpp index e7a10413e..0e9eacaac 100644 --- a/llarp/iwp/iwp.hpp +++ b/llarp/iwp/iwp.hpp @@ -2,21 +2,25 @@ #define LLARP_IWP_HPP #include - +#include #include namespace llarp { - struct AbstractRouter; - namespace iwp { - std::unique_ptr< ILinkLayer > - NewServer(const SecretKey& routerEncSecret, llarp::GetRCFunc getrc, - llarp::LinkMessageHandler h, llarp::SessionEstablishedHandler est, - llarp::SessionRenegotiateHandler reneg, - llarp::SignBufferFunc sign, llarp::TimeoutHandler timeout, - llarp::SessionClosedHandler closed); + LinkLayer_ptr + NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); + LinkLayer_ptr + NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); } // namespace iwp } // namespace llarp diff --git a/llarp/iwp/linklayer.cpp b/llarp/iwp/linklayer.cpp index 8a984d7c4..9de470693 100644 --- a/llarp/iwp/linklayer.cpp +++ b/llarp/iwp/linklayer.cpp @@ -1,16 +1,20 @@ #include +#include namespace llarp { namespace iwp { - LinkLayer::LinkLayer(const SecretKey& enckey, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler t, SessionClosedHandler closed) - : ILinkLayer(enckey, getrc, h, sign, est, reneg, t, closed) + LinkLayer::LinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, + TimeoutHandler timeout, SessionClosedHandler closed, + bool allowInbound) + : ILinkLayer(routerEncSecret, getrc, h, sign, est, reneg, timeout, + closed) + , permitInbound{allowInbound} { - m_FlowCookie.Randomize(); } LinkLayer::~LinkLayer() = default; @@ -44,135 +48,30 @@ namespace llarp bool LinkLayer::Start(std::shared_ptr< Logic > l) { - if(!ILinkLayer::Start(l)) - return false; - return false; + return ILinkLayer::Start(l); } void LinkLayer::RecvFrom(const Addr& from, const void* pkt, size_t sz) { - m_OuterMsg.Clear(); - llarp_buffer_t sigbuf(pkt, sz); - llarp_buffer_t decodebuf(pkt, sz); - if(!m_OuterMsg.Decode(&decodebuf)) + std::shared_ptr< ILinkSession > session; { - LogError("failed to decode outer message"); - return; - } - NetID ourNetID; - switch(m_OuterMsg.command) - { - case eOCMD_ObtainFlowID: - sigbuf.sz -= m_OuterMsg.Zsig.size(); - if(!CryptoManager::instance()->verify(m_OuterMsg.pubkey, sigbuf, - m_OuterMsg.Zsig)) - { - LogError("failed to verify signature on '", - (char)m_OuterMsg.command, "' message from ", from); - return; - } - if(!ShouldSendFlowID(from)) - { - SendReject(from, "no flo 4u :^)"); - return; - } - if(m_OuterMsg.netid == ourNetID) - { - if(GenFlowIDFor(m_OuterMsg.pubkey, from, m_OuterMsg.flow)) - SendFlowID(from, m_OuterMsg.flow); - else - SendReject(from, "genflow fail"); - } - else - SendReject(from, "bad netid"); + util::Lock lock(&m_PendingMutex); + if(m_Pending.count(from) == 0) + { + m_Pending.insert({from, std::make_shared< Session >(this, from)}); + } + session = m_Pending.find(from)->second; } + const llarp_buffer_t buf{pkt, sz}; + session->Recv_LL(buf); } std::shared_ptr< ILinkSession > LinkLayer::NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) { - (void)rc; - (void)ai; - // TODO: implement me - return {}; - } - - void - LinkLayer::SendFlowID(const Addr& to, const FlowID_t& flow) - { - // TODO: implement me - (void)to; - (void)flow; - } - - bool - LinkLayer::VerifyFlowID(const PubKey& pk, const Addr& from, - const FlowID_t& flow) const - { - FlowID_t expected; - if(!GenFlowIDFor(pk, from, expected)) - return false; - return expected == flow; - } - - bool - LinkLayer::GenFlowIDFor(const PubKey& pk, const Addr& from, - FlowID_t& flow) const - { - std::array< byte_t, 128 > tmp = {{0}}; - if(inet_ntop(AF_INET6, from.addr6(), (char*)tmp.data(), tmp.size()) - == nullptr) - return false; - std::copy_n(pk.begin(), pk.size(), tmp.begin() + 64); - std::copy_n(m_FlowCookie.begin(), m_FlowCookie.size(), - tmp.begin() + 64 + pk.size()); - llarp_buffer_t buf(tmp); - ShortHash h; - if(!CryptoManager::instance()->shorthash(h, buf)) - return false; - std::copy_n(h.begin(), flow.size(), flow.begin()); - return true; - } - - bool - LinkLayer::ShouldSendFlowID(const Addr& to) const - { - (void)to; - // TODO: implement me - return false; - } - - void - LinkLayer::SendReject(const Addr& to, const char* msg) - { - if(strlen(msg) > 14) - { - throw std::logic_error("reject message too big"); - } - std::array< byte_t, 120 > pkt; - auto now = Now(); - PubKey pk = GetOurRC().pubkey; - OuterMessage m; - m.CreateReject(msg, now, pk); - llarp_buffer_t encodebuf(pkt); - if(!m.Encode(&encodebuf)) - { - LogError("failed to encode reject message to ", to); - return; - } - llarp_buffer_t signbuf(pkt.data(), pkt.size() - m.Zsig.size()); - if(!Sign(m.Zsig, signbuf)) - { - LogError("failed to sign reject messsage to ", to); - return; - } - std::copy_n(m.Zsig.begin(), m.Zsig.size(), - pkt.begin() + (pkt.size() - m.Zsig.size())); - llarp_buffer_t pktbuf(pkt); - SendTo_LL(to, pktbuf); + return std::make_shared< Session >(this, rc, ai); } } // namespace iwp - } // namespace llarp diff --git a/llarp/iwp/linklayer.hpp b/llarp/iwp/linklayer.hpp index e7265188e..364716de8 100644 --- a/llarp/iwp/linklayer.hpp +++ b/llarp/iwp/linklayer.hpp @@ -6,7 +6,6 @@ #include #include #include -#include namespace llarp { @@ -14,10 +13,11 @@ namespace llarp { struct LinkLayer final : public ILinkLayer { - LinkLayer(const SecretKey &encryptionSecretKey, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler established, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed); + LinkLayer(const SecretKey &routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, SessionRenegotiateHandler reneg, + TimeoutHandler timeout, SessionClosedHandler closed, + bool permitInbound); ~LinkLayer() override; @@ -40,41 +40,14 @@ namespace llarp uint16_t Rank() const override; - /// verify that a new flow id matches addresses and pubkey - bool - VerifyFlowID(const PubKey &pk, const Addr &from, - const FlowID_t &flow) const; - void RecvFrom(const Addr &from, const void *buf, size_t sz) override; private: - bool - GenFlowIDFor(const PubKey &pk, const Addr &from, FlowID_t &flow) const; - - bool - ShouldSendFlowID(const Addr &from) const; - - void - SendReject(const Addr &to, const char *msg); - - void - SendFlowID(const Addr &to, const FlowID_t &flow); - - using ActiveFlows_t = - std::unordered_map< FlowID_t, RouterID, FlowID_t::Hash >; - - ActiveFlows_t m_ActiveFlows; - - using PendingFlows_t = std::unordered_map< Addr, FlowID_t, Addr::Hash >; - /// flows that are pending authentication - PendingFlows_t m_PendingFlows; - - /// cookie used in flow id computation - AlignedBuffer< 32 > m_FlowCookie; - - OuterMessage m_OuterMsg; + const bool permitInbound; }; + + using LinkLayer_ptr = std::shared_ptr< LinkLayer >; } // namespace iwp } // namespace llarp diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp new file mode 100644 index 000000000..b2ed59a87 --- /dev/null +++ b/llarp/iwp/message_buffer.cpp @@ -0,0 +1,160 @@ +#include +#include + +namespace llarp +{ + namespace iwp + { + OutboundMessage::OutboundMessage() : + m_Size{0} {} + + OutboundMessage::OutboundMessage(uint64_t msgid, const llarp_buffer_t& pkt, + ILinkSession::CompletionHandler handler) : + m_Size{std::min(pkt.sz, MAX_LINK_MSG_SIZE)}, + m_MsgID{msgid}, + m_Completed{handler} + { + m_Data.Zero(); + std::copy_n(pkt.base, m_Size, m_Data.begin()); + } + + std::vector + OutboundMessage::XMIT() const + { + std::vector xmit{LLARP_PROTO_VERSION, Command::eXMIT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + htobe16buf(xmit.data() + 2, m_Size); + htobe64buf(xmit.data() + 4, m_MsgID); + const llarp_buffer_t buf{m_Data.data(), m_Size}; + ShortHash H; + CryptoManager::instance()->shorthash(H, buf); + std::copy(H.begin(), H.end(), std::back_inserter(xmit)); + LogDebug("xmit H=", H.ToHex()); + return xmit; + } + + void + OutboundMessage::Completed() + { + if(m_Completed) + { + m_Completed(ILinkSession::DeliveryStatus::eDeliverySuccess); + } + m_Completed = nullptr; + } + + bool + OutboundMessage::ShouldFlush(llarp_time_t now) const + { + static constexpr llarp_time_t FlushInterval = 250; + return now - m_LastFlush >= FlushInterval; + } + + void + OutboundMessage::Ack(byte_t bitmask) + { + m_Acks = std::bitset<8>(bitmask); + } + + void + OutboundMessage::FlushUnAcked(std::function sendpkt, llarp_time_t now) + { + uint16_t idx = 0; + while(idx < m_Size) + { + if(not m_Acks[idx / FragmentSize]) + { + std::vector frag{LLARP_PROTO_VERSION, Command::eDATA, 0,0,0,0,0,0,0,0,0,0}; + htobe16buf(frag.data() + 2, idx); + htobe64buf(frag.data() + 4, m_MsgID); + std::copy(m_Data.begin() + idx, m_Data.begin() + idx + FragmentSize, std::back_inserter(frag)); + const llarp_buffer_t pkt{frag}; + sendpkt(pkt); + } + idx += FragmentSize; + } + m_LastFlush = now; + } + + bool + OutboundMessage::IsTransmitted() const + { + for(uint16_t idx = 0; idx < m_Size; idx += FragmentSize) + { + if(!m_Acks.test(idx / FragmentSize)) + return false; + } + return true; + } + + InboundMessage::InboundMessage() : m_Size{0} {} + + InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h) : + m_Digset{std::move(h)}, + m_Size{sz}, + m_MsgID{msgid} + {} + + void + InboundMessage::HandleData(uint16_t idx, const byte_t * ptr) + { + if(idx + FragmentSize > MAX_LINK_MSG_SIZE) + return; + auto * dst = m_Data.data() + idx; + std::copy_n(ptr, FragmentSize, dst); + m_Acks.set(idx / FragmentSize); + LogDebug("got fragment ", idx / FragmentSize , " of ", m_Size); + } + + + std::vector + InboundMessage::ACKS() const + { + std::vector acks{LLARP_PROTO_VERSION, Command::eACKS, 0, 0, 0, 0, 0, 0, 0, 0, uint8_t{m_Acks.to_ulong()}}; + + htobe64buf(acks.data() + 2, m_MsgID); + return acks; + } + + bool + InboundMessage::IsCompleted() const + { + for(uint16_t idx = 0; idx < m_Size; idx += FragmentSize) + { + if(!m_Acks.test(idx / FragmentSize)) + return false; + } + return true; + } + + bool + InboundMessage::ShouldSendACKS(llarp_time_t now) const + { + return now - m_LastACKSent > 1000 || IsCompleted(); + } + + void + InboundMessage::SendACKS(std::function sendpkt, llarp_time_t now) + { + auto acks = ACKS(); + const llarp_buffer_t pkt{acks}; + sendpkt(pkt); + m_LastACKSent = now; + } + + bool + InboundMessage::Verify() const + { + ShortHash gotten; + const llarp_buffer_t buf{m_Data.data(), m_Size}; + CryptoManager::instance()->shorthash(gotten, buf); + LogDebug("gotten=",gotten.ToHex()); + if(gotten != m_Digset) + { + DumpBuffer(buf); + return false; + } + return true; + } + + } +} \ No newline at end of file diff --git a/llarp/iwp/message_buffer.hpp b/llarp/iwp/message_buffer.hpp new file mode 100644 index 000000000..0d60e9a0a --- /dev/null +++ b/llarp/iwp/message_buffer.hpp @@ -0,0 +1,97 @@ +#ifndef LLARP_IWP_MESSAGE_BUFFER_HPP +#define LLARP_IWP_MESSAGE_BUFFER_HPP +#include +#include +#include +#include +#include +#include + +namespace llarp +{ + namespace iwp + { + enum Command + { + /// keep alive message + ePING = 0, + /// begin transission + eXMIT = 1, + /// fragment data + eDATA = 2, + /// acknolege fragments + eACKS = 3, + /// close session + eCLOS = 4 + }; + + static constexpr size_t FragmentSize = 1024; + + struct OutboundMessage + { + OutboundMessage(); + OutboundMessage(uint64_t msgid, const llarp_buffer_t& pkt, + ILinkSession::CompletionHandler handler); + + AlignedBuffer< MAX_LINK_MSG_SIZE > m_Data; + uint16_t m_Size = 0; + uint64_t m_MsgID = 0; + std::bitset< MAX_LINK_MSG_SIZE / FragmentSize > m_Acks; + ILinkSession::CompletionHandler m_Completed; + llarp_time_t m_LastFlush = 0; + + std::vector + XMIT() const; + + void + Ack(byte_t bitmask); + + void + FlushUnAcked(std::function sendpkt, llarp_time_t now); + + bool + ShouldFlush(llarp_time_t now) const; + + void + Completed(); + + bool + IsTransmitted() const; + }; + + struct InboundMessage + { + InboundMessage(); + InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h); + + AlignedBuffer< MAX_LINK_MSG_SIZE > m_Data; + ShortHash m_Digset; + uint16_t m_Size = 0; + uint64_t m_MsgID = 0; + llarp_time_t m_LastACKSent = 0; + std::bitset< MAX_LINK_MSG_SIZE / FragmentSize > m_Acks; + + void + HandleData(uint16_t idx, const byte_t * ptr); + + bool + IsCompleted() const; + + bool + Verify() const; + + bool + ShouldSendACKS(llarp_time_t now) const; + + void + SendACKS(std::function sendpkt, llarp_time_t now); + + std::vector + ACKS() const; + + }; + + } // namespace iwp +} // namespace llarp + +#endif \ No newline at end of file diff --git a/llarp/iwp/outermessage.cpp b/llarp/iwp/outermessage.cpp deleted file mode 100644 index 3d7ad2af7..000000000 --- a/llarp/iwp/outermessage.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include -#include - -namespace llarp -{ - namespace iwp - { - std::array< byte_t, 6 > OuterMessage::obtain_flow_id_magic = - std::array< byte_t, 6 >{{'n', 'e', 't', 'i', 'd', '?'}}; - - std::array< byte_t, 6 > OuterMessage::give_flow_id_magic = - std::array< byte_t, 6 >{{'n', 'e', 't', 'i', 'd', '!'}}; - - OuterMessage::OuterMessage() - { - Clear(); - } - - OuterMessage::~OuterMessage() = default; - - void - OuterMessage::Clear() - { - command = 0; - flow.Zero(); - netid.Zero(); - reject.fill(0); - N.Zero(); - X.Zero(); - Xsize = 0; - Zsig.Zero(); - Zhash.Zero(); - pubkey.Zero(); - magic.fill(0); - uinteger = 0; - A.reset(); - } - - void - OuterMessage::CreateReject(const char* msg, llarp_time_t now, - const PubKey& pk) - { - Clear(); - std::copy_n(msg, std::min(strlen(msg), reject.size()), reject.begin()); - uinteger = now; - pubkey = pk; - } - - bool - OuterMessage::Encode(llarp_buffer_t* buf) const - { - if(buf->size_left() < 2) - return false; - *buf->cur = command; - buf->cur++; - *buf->cur = '='; - buf->cur++; - switch(command) - { - case eOCMD_ObtainFlowID: - - case eOCMD_GiveFlowID: - if(!buf->write(reject.begin(), reject.end())) - return false; - if(!buf->write(give_flow_id_magic.begin(), give_flow_id_magic.end())) - return false; - if(!buf->write(flow.begin(), flow.end())) - return false; - if(!buf->write(pubkey.begin(), pubkey.end())) - return false; - return buf->write(Zsig.begin(), Zsig.end()); - default: - return false; - } - } - - bool - OuterMessage::Decode(llarp_buffer_t* buf) - { - static constexpr size_t header_size = 2; - - if(buf->size_left() < header_size) - return false; - command = *buf->cur; - ++buf->cur; - if(*buf->cur != '=') - return false; - ++buf->cur; - switch(command) - { - case eOCMD_ObtainFlowID: - if(!buf->read_into(magic.begin(), magic.end())) - return false; - if(!buf->read_into(netid.begin(), netid.end())) - return false; - if(!buf->read_uint64(uinteger)) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - if(buf->size_left() <= Zsig.size()) - return false; - Xsize = buf->size_left() - Zsig.size(); - if(!buf->read_into(X.begin(), X.begin() + Xsize)) - return false; - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_GiveFlowID: - if(!buf->read_into(magic.begin(), magic.end())) - return false; - if(!buf->read_into(flow.begin(), flow.end())) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - buf->cur += buf->size_left() - Zsig.size(); - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_Reject: - if(!buf->read_into(reject.begin(), reject.end())) - return false; - if(!buf->read_uint64(uinteger)) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - buf->cur += buf->size_left() - Zsig.size(); - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_SessionNegotiate: - if(!buf->read_into(flow.begin(), flow.end())) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - if(!buf->read_uint64(uinteger)) - return false; - if(buf->size_left() == Zsig.size() + 32) - { - A = std::make_unique< AlignedBuffer< 32 > >(); - if(!buf->read_into(A->begin(), A->end())) - return false; - } - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_TransmitData: - if(!buf->read_into(flow.begin(), flow.end())) - return false; - if(!buf->read_into(N.begin(), N.end())) - return false; - if(buf->size_left() <= Zhash.size()) - return false; - Xsize = buf->size_left() - Zhash.size(); - if(!buf->read_into(X.begin(), X.begin() + Xsize)) - return false; - return buf->read_into(Zhash.begin(), Zhash.end()); - default: - return false; - } - } - } // namespace iwp - -} // namespace llarp diff --git a/llarp/iwp/outermessage.hpp b/llarp/iwp/outermessage.hpp deleted file mode 100644 index eefc05593..000000000 --- a/llarp/iwp/outermessage.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef LLARP_IWP_OUTERMESSAGE_HPP -#define LLARP_IWP_OUTERMESSAGE_HPP - -#include -#include -#include - -#include - -namespace llarp -{ - namespace iwp - { - using FlowID_t = AlignedBuffer< 32 >; - - using OuterCommand_t = byte_t; - - constexpr OuterCommand_t eOCMD_ObtainFlowID = 'O'; - constexpr OuterCommand_t eOCMD_GiveFlowID = 'G'; - constexpr OuterCommand_t eOCMD_Reject = 'R'; - constexpr OuterCommand_t eOCMD_SessionNegotiate = 'S'; - constexpr OuterCommand_t eOCMD_TransmitData = 'D'; - - using InnerCommand_t = byte_t; - - constexpr InnerCommand_t eICMD_KeepAlive = 'k'; - constexpr InnerCommand_t eICMD_KeepAliveAck = 'l'; - constexpr InnerCommand_t eICMD_Congestion = 'c'; - constexpr InnerCommand_t eICMD_AntiCongestion = 'd'; - constexpr InnerCommand_t eICMD_Transmit = 't'; - constexpr InnerCommand_t eICMD_Ack = 'a'; - constexpr InnerCommand_t eICMD_RotateKeys = 'r'; - constexpr InnerCommand_t eICMD_UpgradeProtocol = 'u'; - constexpr InnerCommand_t eICMD_VersionUpgrade = 'v'; - - struct OuterMessage - { - // required members - byte_t command; - FlowID_t flow; - - OuterMessage(); - ~OuterMessage(); - - // static members - static std::array< byte_t, 6 > obtain_flow_id_magic; - static std::array< byte_t, 6 > give_flow_id_magic; - - void - CreateReject(const char *msg, llarp_time_t now, const PubKey &pk); - - // optional members follow - std::array< byte_t, 6 > magic; - NetID netid; - // either timestamp or counter - uint64_t uinteger; - std::array< byte_t, 14 > reject; - AlignedBuffer< 24 > N; - PubKey pubkey; - - std::unique_ptr< AlignedBuffer< 32 > > A; - - static constexpr size_t ipv6_mtu = 1280; - static constexpr size_t overhead_size = 16 + 24 + 32; - static constexpr size_t payload_size = ipv6_mtu - overhead_size; - - AlignedBuffer< payload_size > X; - size_t Xsize; - ShortHash Zhash; - Signature Zsig; - - /// encode to buffer - bool - Encode(llarp_buffer_t *buf) const; - - /// decode from buffer - bool - Decode(llarp_buffer_t *buf); - - /// clear members - void - Clear(); - }; - } // namespace iwp -} // namespace llarp -#endif diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp new file mode 100644 index 000000000..c81bb0b02 --- /dev/null +++ b/llarp/iwp/session.cpp @@ -0,0 +1,536 @@ +#include +#include +#include + +namespace llarp +{ + namespace iwp + { + static constexpr size_t PacketOverhead = HMACSIZE + TUNNONCESIZE; + + Session::Session(LinkLayer* p, RouterContact rc, AddressInfo ai) + : m_State{State::Initial} + , m_Inbound{false} + , m_Parent{p} + , m_CreatedAt{p->Now()} + , m_RemoteAddr{ai} + , m_ChosenAI{std::move(ai)} + , m_RemoteRC{std::move(rc)} + { + token.Zero(); + GotLIM = util::memFn(&Session::GotOutboundLIM, this); + } + + Session::Session(LinkLayer* p, Addr from) + : m_State{State::Initial} + , m_Inbound{true} + , m_Parent{p} + , m_CreatedAt{p->Now()} + , m_RemoteAddr{from} + { + token.Randomize(); + GotLIM = util::memFn(&Session::GotInboundLIM, this); + } + + Session::~Session() + { + } + + void + Session::Send_LL(const llarp_buffer_t& pkt) + { + LogDebug("send ", pkt.sz, " to ", m_RemoteAddr); + m_Parent->SendTo_LL(m_RemoteAddr, pkt); + m_LastTX = time_now_ms(); + } + + bool + Session::GotInboundLIM(const LinkIntroMessage * msg) + { + if(msg->rc.enckey != m_RemoteOnionKey) + return false; + m_State = State::Ready; + GotLIM = util::memFn(&Session::GotRenegLIM, this); + return true; + } + + bool + Session::GotOutboundLIM(const LinkIntroMessage * msg) + { + if(msg->rc.pubkey != m_RemoteRC.pubkey) + return false; + m_State = State::LinkIntro; + GotLIM = util::memFn(&Session::GotRenegLIM, this); + SendOurLIM(); + return true; + } + + void + Session::SendOurLIM() + { + LinkIntroMessage msg; + msg.rc = m_Parent->GetOurRC(); + msg.N.Randomize(); + msg.P = 60000; + if(not msg.Sign(m_Parent->Sign)) + { + LogError("failed to sign our RC for ", m_RemoteAddr); + return; + } + AlignedBuffer data; + llarp_buffer_t buf{data}; + if(not msg.BEncode(&buf)) + { + LogError("failed to encode LIM for ", m_RemoteAddr); + } + buf.sz = buf.cur - buf.base; + buf.cur = buf.base; + if(!SendMessageBuffer(buf, nullptr)) + { + LogError("failed to send LIM to ", m_RemoteAddr); + } + LogDebug("sent LIM to ", m_RemoteAddr); + } + + void + Session::EncryptAndSend(const llarp_buffer_t& data) + { + + std::vector< byte_t > pkt; + pkt.resize(data.sz + PacketOverhead); + CryptoManager::instance()->randbytes(pkt.data(), pkt.size()); + llarp_buffer_t pktbuf{pkt}; + pktbuf.base += PacketOverhead; + pktbuf.sz -= PacketOverhead; + byte_t* nonce_ptr = pkt.data() + HMACSIZE; + + + CryptoManager::instance()->xchacha20_alt(pktbuf, data, m_SessionKey, + nonce_ptr); + + pktbuf.base = nonce_ptr; + pktbuf.sz = data.sz + 32; + CryptoManager::instance()->hmac(pkt.data(), pktbuf, m_SessionKey); + + pktbuf.base = pkt.data(); + pktbuf.sz = pkt.size(); + Send_LL(pktbuf); + } + + void + Session::Close() + { + if(m_State == State::Closed) + return; + const std::vector close_msg = {LLARP_PROTO_VERSION, Command::eCLOS}; + const llarp_buffer_t buf{close_msg}; + EncryptAndSend(buf); + m_State = State::Closed; + } + + bool + Session::SendMessageBuffer(const llarp_buffer_t& buf, + ILinkSession::CompletionHandler completed) + { + const auto msgid = m_TXID++; + auto& msg = m_TXMsgs.emplace(msgid, OutboundMessage{msgid, buf, completed}) + .first->second; + auto xmit = msg.XMIT(); + const llarp_buffer_t pkt{xmit}; + EncryptAndSend(pkt); + msg.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), m_Parent->Now()); + LogDebug("send message ", msgid); + return true; + } + + void + Session::Pump() + { + static constexpr llarp_time_t IntroInterval = 500; + const auto now = m_Parent->Now(); + if(m_State == State::Introduction) + { + if(not m_Inbound) + { + // resend intro + if(now - m_LastTX >= IntroInterval) + { + GenerateAndSendIntro(); + } + } + } + else if(m_State == State::Ready || m_State == State::LinkIntro) + { + for(auto itr = m_RXMsgs.begin(); itr != m_RXMsgs.end(); ) + { + if(itr->second.ShouldSendACKS(now)) + { + itr->second.SendACKS(util::memFn(&Session::EncryptAndSend, this), now); + } + if(itr->second.IsCompleted()) + { + if(itr->second.Verify()) + { + const llarp_buffer_t buf{itr->second.m_Data.data(), itr->second.m_Size}; + LogDebug("got message ", itr->first); + m_Parent->HandleMessage(this, buf); + } + else + { + LogError("hash missmatch for message ", itr->first); + } + itr = m_RXMsgs.erase(itr); + continue; + } + ++itr; + } + for(auto itr = m_TXMsgs.begin(); itr != m_TXMsgs.end(); ) + { + if(itr->second.ShouldFlush(now)) + itr->second.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), now); + if(itr->second.IsTransmitted()) + { + LogDebug("sent message ", itr->first); + itr->second.Completed(); + itr = m_TXMsgs.erase(itr); + continue; + } + ++itr; + } + } + } + + bool + Session::GotRenegLIM(const LinkIntroMessage * lim) + { + return m_Parent->SessionRenegotiate(lim->rc, m_RemoteRC); + } + + bool + Session::RenegotiateSession() + { + SendOurLIM(); + return true; + } + + bool + Session::ShouldPing() const + { + static constexpr llarp_time_t PingInterval = 1000; + const auto now = m_Parent->Now(); + return now - m_LastTX > PingInterval; + } + + util::StatusObject + Session::ExtractStatus() const + { + return { + {"remoteAddr", m_RemoteAddr.ToString()}, + {"remoteRC", m_RemoteRC.ExtractStatus()} + }; + } + + bool + Session::TimedOut(llarp_time_t now) const + { + static constexpr llarp_time_t SessionAliveTimeout = 5000; + if(m_State != State::Ready) + return now - m_CreatedAt > SessionAliveTimeout; + return now - m_LastRX > SessionAliveTimeout; + } + + void + Session::Tick(llarp_time_t) + { + } + + using Introduction = AlignedBuffer<64>; + + void + Session::GenerateAndSendIntro() + { + Introduction intro; + + TunnelNonce N; + N.Randomize(); + if(not CryptoManager::instance()->transport_dh_client(m_SessionKey, m_ChosenAI.pubkey, m_Parent->RouterEncryptionSecret(), N)) + { + LogError("failed to transport_dh_client on outbound session to ", m_RemoteAddr); + return; + } + const auto pk = m_Parent->RouterEncryptionSecret().toPublic(); + std::copy_n(pk.begin(), pk.size(), intro.begin()); + std::copy(N.begin(), N.end(), intro.begin() + 32); + LogDebug("pk=", pk.ToHex(), " N=", N.ToHex(), " remote-pk=", m_ChosenAI.pubkey.ToHex()); + std::vector req; + req.resize(intro.size() + (randint() % 64)); + CryptoManager::instance()->randbytes(req.data(), req.size()); + std::copy_n(intro.begin(), intro.size(), req.begin()); + const llarp_buffer_t buf{req}; + Send_LL(buf); + m_State = State::Introduction; + } + + void + Session::HandleCreateSessionRequest(const llarp_buffer_t & buf) + { + std::vector result; + if(not DecryptMessage(buf, result)) + { + LogError("failed to decrypt session request from ", m_RemoteAddr); + return; + } + if(result.size() < token.size()) + { + LogError("bad session request size, ", result.size(), " < ", token.size(), " from ", m_RemoteAddr); + return; + } + if(not std::equal(result.begin(), result.begin() + token.size(), token.begin())) + { + LogError("token missmatch from ", m_RemoteAddr); + return; + } + SendOurLIM(); + m_State = State::LinkIntro; + } + + void + Session::HandleGotIntro(const llarp_buffer_t & buf) + { + if(buf.sz < Introduction::SIZE) + return; + TunnelNonce N; + std::copy_n(buf.base, PubKey::SIZE, m_RemoteOnionKey.begin()); + std::copy_n(buf.base + PubKey::SIZE, TunnelNonce::SIZE, N.begin()); + const PubKey pk = m_Parent->TransportSecretKey().toPublic(); + LogDebug("remote-pk=", m_RemoteOnionKey.ToHex(), " N=", N.ToHex(), " local-pk=", pk.ToHex()); + if(not CryptoManager::instance()->transport_dh_server(m_SessionKey, m_RemoteOnionKey, m_Parent->TransportSecretKey(), N)) + { + LogError("failed to transport_dh_server on inbound intro from ", m_RemoteAddr); + return; + } + std::vector reply; + reply.resize(token.size() + (randint() % 32)); + CryptoManager::instance()->randbytes(reply.data(), reply.size()); + std::copy_n(token.begin(), token.size(), reply.begin()); + const llarp_buffer_t pkt{reply}; + m_LastRX = m_Parent->Now(); + EncryptAndSend(pkt); + m_State = State::Introduction; + } + + void + Session::HandleGotIntroAck(const llarp_buffer_t & buf) + { + std::vector reply; + if(not DecryptMessage(buf, reply)) + { + LogError("intro ack decrypt failed from ", m_RemoteAddr); + return; + } + if(reply.size() < token.size()) + { + LogError("bad intro ack size ", reply.size(), " < ", token.size(), " from ", m_RemoteAddr); + return; + } + m_LastRX = m_Parent->Now(); + std::copy_n(reply.begin(), token.size(), token.begin()); + const llarp_buffer_t pkt{token}; + EncryptAndSend(pkt); + m_State = State::LinkIntro; + } + + bool + Session::DecryptMessage(const llarp_buffer_t & buf, std::vector & result) + { + if(buf.sz <= PacketOverhead) + return false; + ShortHash H; + llarp_buffer_t curbuf{buf.base, buf.sz}; + curbuf.base += ShortHash::SIZE; + curbuf.sz -= ShortHash::SIZE; + if(not CryptoManager::instance()->hmac(H.data(), curbuf, m_SessionKey)) + { + LogError("failed to caclulate keyed hash for ", m_RemoteAddr); + return false; + } + const ShortHash expected{buf.base}; + if(H != expected) + { + LogError("keyed hash missmatch ", H, " != ", expected, " from ", m_RemoteAddr); + return false; + } + const byte_t * nonce_ptr = curbuf.base; + curbuf.base += 32; + curbuf.sz -= 32; + result.resize(buf.sz - PacketOverhead); + const llarp_buffer_t outbuf{result}; + LogDebug("decrypt: ", result.size(), " bytes from ", m_RemoteAddr); + return CryptoManager::instance()->xchacha20_alt(outbuf, curbuf, m_SessionKey, nonce_ptr); + } + + void + Session::Start() + { + if(m_Inbound) + return; + GenerateAndSendIntro(); + } + + void + Session::HandleSessionData(const llarp_buffer_t & buf) + { + std::vector result; + if(not DecryptMessage(buf, result)) + { + LogError("failed to decrypt session data from ", m_RemoteAddr); + return; + } + if(result[0] != LLARP_PROTO_VERSION) + { + LogError("protocol version missmatch ", int(result[0]), " != ", LLARP_PROTO_VERSION); + return; + } + LogDebug("command ", int(result[1]), " from ", m_RemoteAddr); + switch(result[1]) + { + case Command::eXMIT: + HandleXMIT(std::move(result)); + break; + case Command::eDATA: + HandleDATA(std::move(result)); + break; + case Command::eACKS: + HandleACKS(std::move(result)); + break; + case Command::ePING: + HandlePING(std::move(result)); + break; + case Command::eCLOS: + HandleCLOS(std::move(result)); + break; + default: + LogError("invalid command ", int(result[1])); + } + } + + void + Session::HandleXMIT(std::vector data) + { + if(data.size() < 44) + { + LogError("short XMIT from ", m_RemoteAddr, " ", data.size(), " < 44"); + return; + } + uint16_t sz = bufbe16toh(data.data() + 2); + uint64_t rxid = bufbe64toh(data.data() + 4); + ShortHash h{data.data() + 12}; + LogDebug("rxid=", rxid, " sz=", sz, " h=", h.ToHex()); + m_RXMsgs.emplace(rxid, InboundMessage{rxid, sz, std::move(h)}); + m_LastRX = m_Parent->Now(); + } + + void + Session::HandleDATA(std::vector data) + { + if(data.size() < FragmentSize + 12) + { + LogError("short DATA from ", m_RemoteAddr, " ", data.size(), " < ", FragmentSize + 8); + return; + } + uint16_t sz = bufbe16toh(data.data() + 2); + uint64_t rxid = bufbe64toh(data.data() + 4); + auto itr = m_RXMsgs.find(rxid); + if(itr == m_RXMsgs.end()) + { + LogWarn("no rxid=", rxid, " for ", m_RemoteAddr); + return; + } + itr->second.HandleData(sz, data.data() + 12); + m_LastRX = m_Parent->Now(); + LogDebug(itr->first, " completed=", itr->second.IsCompleted()); + } + + void + Session::HandleACKS(std::vector data) + { + if(data.size() < 11) + { + LogError("short ACKS from ", m_RemoteAddr, " ", data.size(), " < 11"); + return; + } + uint64_t txid = bufbe64toh(data.data() + 2); + auto itr = m_TXMsgs.find(txid); + if(itr == m_TXMsgs.end()) + { + LogWarn("no txid=", txid, " for ", m_RemoteAddr); + return; + } + itr->second.Ack(data[10]); + m_LastRX = m_Parent->Now(); + } + + void + Session::HandleCLOS(std::vector) + { + Close(); + } + + void + Session::HandlePING(std::vector) + { + m_LastRX = m_Parent->Now(); + } + + bool + Session::SendKeepAlive() + { + // TODO: Implement me + return false; + } + + bool + Session::IsEstablished() const + { + return m_State == State::Ready; + } + + void + Session::Recv_LL(const llarp_buffer_t& buf) + { + switch(m_State) + { + case State::Initial: + if(m_Inbound) + { + // initial data + // enter introduction phase + HandleGotIntro(buf); + } + else + { + // this case should never happen + ::abort(); + } + break; + case State::Introduction: + if(m_Inbound) + { + // we are replying to an intro ack + HandleCreateSessionRequest(buf); + } + else + { + // we got an intro ack + // send a session request + HandleGotIntroAck(buf); + } + break; + case State::LinkIntro: + default: + HandleSessionData(buf); + break; + } + } + } // namespace iwp +} // namespace llarp \ No newline at end of file diff --git a/llarp/iwp/session.hpp b/llarp/iwp/session.hpp new file mode 100644 index 000000000..423348bc0 --- /dev/null +++ b/llarp/iwp/session.hpp @@ -0,0 +1,189 @@ +#ifndef LLARP_IWP_SESSION_HPP +#define LLARP_IWP_SESSION_HPP + +#include +#include +#include + +namespace llarp +{ + namespace iwp + { + struct Session : public ILinkSession, + public std::enable_shared_from_this< Session > + { + /// outbound session + Session(LinkLayer* parent, RouterContact rc, AddressInfo ai); + /// inbound session + Session(LinkLayer* parent, Addr from); + + ~Session(); + + void + Pump() override; + + void + Tick(llarp_time_t now) override; + + bool + SendMessageBuffer(const llarp_buffer_t& buf, + CompletionHandler resultHandler) override; + + void + Send_LL(const llarp_buffer_t& pkt); + + void + EncryptAndSend(const llarp_buffer_t& data); + + void + Start() override; + + void + Close() override; + + void + Recv_LL(const llarp_buffer_t& pkt) override; + + bool + SendKeepAlive() override; + + bool + IsEstablished() const override; + + bool + TimedOut(llarp_time_t now) const override; + + PubKey + GetPubKey() const override + { + return m_RemoteRC.pubkey; + } + + Addr + GetRemoteEndpoint() const override + { + return m_RemoteAddr; + } + + RouterContact + GetRemoteRC() const override + { + return m_RemoteRC; + } + + size_t + SendQueueBacklog() const override + { + return m_TXMsgs.size(); + } + + ILinkLayer* + GetLinkLayer() const override + { + return m_Parent; + } + + bool + RenegotiateSession() override; + + bool + ShouldPing() const override; + + util::StatusObject + ExtractStatus() const override; + + private: + enum class State + { + /// we have no data recv'd + Initial, + /// we are in introduction/intro ack phase + Introduction, + /// we sent our LIM + LinkIntro, + /// handshake done and LIM has been obtained + Ready, + /// we are closed now + Closed + }; + State m_State; + /// are we inbound session ? + const bool m_Inbound; + /// parent link layer + LinkLayer* const m_Parent; + const llarp_time_t m_CreatedAt; + const Addr m_RemoteAddr; + + AddressInfo m_ChosenAI; + /// remote rc + RouterContact m_RemoteRC; + /// session key + SharedSecret m_SessionKey; + /// session token + AlignedBuffer<16> token; + + PubKey m_RemoteOnionKey; + + llarp_time_t m_LastTX = 0; + llarp_time_t m_LastRX = 0; + + uint64_t m_TXID = 0; + + std::unordered_map< uint64_t, InboundMessage > m_RXMsgs; + std::unordered_map< uint64_t, OutboundMessage > m_TXMsgs; + + void + HandleGotIntro(const llarp_buffer_t& buf); + + void + HandleGotIntroAck(const llarp_buffer_t& buf); + + void + HandleCreateSessionRequest(const llarp_buffer_t& buf); + + void + ProcessSessionRequest(const llarp_buffer_t& buf); + + void + ProcessCreateSessionReply(const llarp_buffer_t& buf); + + void + HandleSessionData(const llarp_buffer_t& buf); + + bool + DecryptMessage(const llarp_buffer_t & buf, std::vector & result); + + void + GenerateAndSendIntro(); + + bool + GotInboundLIM(const LinkIntroMessage * msg); + + bool + GotOutboundLIM(const LinkIntroMessage * msg); + + bool + GotRenegLIM(const LinkIntroMessage * msg); + + void + SendOurLIM(); + + void + HandleXMIT(std::vector msg); + + void + HandleDATA(std::vector msg); + + void + HandleACKS(std::vector msg); + + void + HandlePING(std::vector msg); + + void + HandleCLOS(std::vector msg); + }; + } // namespace iwp +} // namespace llarp + +#endif \ No newline at end of file diff --git a/llarp/link/factory.cpp b/llarp/link/factory.cpp index ba71f9a1d..734e7b1ef 100644 --- a/llarp/link/factory.cpp +++ b/llarp/link/factory.cpp @@ -1,6 +1,6 @@ #include +#include #include -#include namespace llarp { @@ -41,10 +41,10 @@ namespace llarp if(permitInbound) return llarp::utp::NewInboundLink; return llarp::utp::NewOutboundLink; - case LinkType::eLinkMempipe: + case LinkType::eLinkIWP: if(permitInbound) - return llarp::mempipe::NewInboundLink; - return llarp::mempipe::NewOutboundLink; + return llarp::iwp::NewInboundLink; + return llarp::iwp::NewOutboundLink; default: return nullptr; } diff --git a/llarp/link/session.hpp b/llarp/link/session.hpp index 39dc1ae96..73a6efe3e 100644 --- a/llarp/link/session.hpp +++ b/llarp/link/session.hpp @@ -27,7 +27,7 @@ namespace llarp /// hook for utp for when we have established a connection virtual void - OnLinkEstablished(ILinkLayer *p) = 0; + OnLinkEstablished(ILinkLayer *){}; /// called every event loop tick virtual void @@ -50,6 +50,13 @@ namespace llarp virtual void Close() = 0; + /// recv packet on low layer + /// not used by utp + virtual void + Recv_LL(const llarp_buffer_t &) + { + } + /// send a keepalive to the remote endpoint virtual bool SendKeepAlive() = 0; diff --git a/llarp/mempipe/mempipe.cpp b/llarp/mempipe/mempipe.cpp deleted file mode 100644 index 3f0042de4..000000000 --- a/llarp/mempipe/mempipe.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include -#include -#include -#include -#include - -namespace llarp -{ - namespace mempipe - { - struct MemLink; - struct MemSession; - - struct MempipeContext - { - using Nodes_t = - std::unordered_map< RouterID, LinkLayer_ptr, RouterID::Hash >; - Nodes_t _nodes; - using SendEvent = std::tuple< RouterID, RouterID, std::vector< byte_t >, - ILinkSession::CompletionHandler >; - - /// (src, dst, session, hook) - std::vector< SendEvent > _sendQueue; - using NodeConnection_t = std::tuple< RouterID, RouterID >; - - struct NodeConnectionHash - { - size_t - operator()(const NodeConnection_t con) const - { - const auto& a = std::get< 0 >(con); - const auto& b = std::get< 1 >(con); - auto op = std::bit_xor< size_t >(); - return std::accumulate(a.begin(), a.end(), - std::accumulate(b.begin(), b.end(), 0, op), - op); - } - }; - - using NodeConnections_t = - std::unordered_map< NodeConnection_t, std::shared_ptr< MemSession >, - NodeConnectionHash >; - - NodeConnections_t _connections; - - mutable util::Mutex _access; - - void - AddNode(LinkLayer_ptr ptr) LOCKS_EXCLUDED(_access); - - void - RemoveNode(LinkLayer_ptr ptr) LOCKS_EXCLUDED(_access); - - LinkLayer_ptr - FindNode(const RouterID pk) LOCKS_EXCLUDED(_access); - - /// connect src to dst - void - ConnectNode(const RouterID src, const RouterID dst, - const std::shared_ptr< MemSession >& ptr) - LOCKS_EXCLUDED(_access); - - /// remote both src and dst as connected - void - DisconnectNode(const RouterID src, const RouterID dst) - LOCKS_EXCLUDED(_access); - - bool - HasConnection(const RouterID src, const RouterID dst) const - LOCKS_EXCLUDED(_access); - - void - InboundConnection(const RouterID to, - const std::shared_ptr< MemSession >& obsession); - - void - CallLater(std::function< void(void) > f) - { - if(m_Logic && f) - m_Logic->queue_func(f); - else if(f) - LogError("dropping call"); - } - - bool - SendTo(const RouterID src, const RouterID dst, - const std::vector< byte_t > msg, - ILinkSession::CompletionHandler delivery) LOCKS_EXCLUDED(_access); - - void - Pump() LOCKS_EXCLUDED(_access); - - void - Start(llarp_ev_loop_ptr loop) - { - evloop = loop; - m_Run.store(true); - std::promise< void > p; - m_Thread = std::make_unique< std::thread >([&]() { - LogDebug("mempipe started"); - m_Logic = std::make_shared< Logic >(); - p.set_value(); - while(m_Run.load()) - { - m_Logic->tick(time_now_ms()); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - Pump(); - } - m_Logic->stop(); - }); - p.get_future().wait(); - LogDebug("mempipe up"); - } - - ~MempipeContext() - { - m_Run.store(false); - if(m_Thread) - m_Thread->join(); - } - - std::atomic< bool > m_Run; - std::shared_ptr< Logic > m_Logic; - std::unique_ptr< std::thread > m_Thread = nullptr; - llarp_ev_loop_ptr evloop = nullptr; - }; - - using Globals_ptr = std::unique_ptr< MempipeContext >; - - Globals_ptr _globals; - - struct MemSession : public ILinkSession, - public llarp_ev_pkt_pipe, - public std::enable_shared_from_this< MemSession > - { - MemSession(llarp_ev_loop_ptr ev, LinkLayer_ptr _local, - LinkLayer_ptr _remote, bool inbound) - : llarp_ev_pkt_pipe(ev) - , remote{std::move(_remote)} - , parent{std::move(_local)} - , isInbound{inbound} - { - } - - LinkLayer_ptr remote; - LinkLayer_ptr parent; - const bool isInbound; - - util::Mutex _access; - - std::deque< std::vector< byte_t > > m_recvQueue; - std::deque< std::tuple< std::vector< byte_t >, CompletionHandler > > - m_sendQueue; - - llarp_time_t lastRecv = 0; - - PubKey - GetPubKey() const override - { - return remote->GetOurRC().pubkey; - } - - bool - SendKeepAlive() override - { - std::array< byte_t, 128 > pkt; - DiscardMessage msg; - llarp_buffer_t buf{pkt}; - if(!msg.BEncode(&buf)) - return false; - buf.sz = buf.cur - buf.base; - buf.cur = buf.base; - return SendMessageBuffer(buf, nullptr); - } - - void - OnRead(const llarp_buffer_t& pkt) override - { - std::vector< byte_t > buf; - buf.resize(pkt.sz); - std::copy_n(pkt.base, pkt.sz, buf.begin()); - Recv(std::move(buf)); - } - - void - Recv(const std::vector< byte_t > msg) LOCKS_EXCLUDED(_access) - { - util::Lock lock(&_access); - m_recvQueue.emplace_back(std::move(msg)); - lastRecv = parent->Now(); - } - - void - OnLinkEstablished(ILinkLayer*) override - { - return; - } - - bool - TimedOut(llarp_time_t now) const override - { - return now >= lastRecv && now - lastRecv > 5000; - } - - void - PumpWrite() LOCKS_EXCLUDED(_access) - { - std::deque< std::tuple< std::vector< byte_t >, CompletionHandler > > q; - { - util::Lock lock(&_access); - if(m_sendQueue.size()) - q = std::move(m_sendQueue); - } - const RouterID src = parent->GetOurRC().pubkey; - const RouterID dst = GetPubKey(); - while(q.size()) - { - const auto& f = q.front(); - _globals->SendTo(src, dst, std::get< 0 >(f), std::get< 1 >(f)); - q.pop_front(); - } - } - - void - PumpRead() LOCKS_EXCLUDED(_access) - { - std::deque< std::vector< byte_t > > q; - { - util::Lock lock(&_access); - if(m_recvQueue.size()) - q = std::move(m_recvQueue); - } - while(q.size()) - { - const llarp_buffer_t buf{q.front()}; - parent->HandleMessage(this, buf); - q.pop_front(); - } - } - - void Tick(llarp_time_t) override - { - Pump(); - } - - void - Pump() override - { - PumpRead(); - PumpWrite(); - } - - void - Close() override - { - auto self = shared_from_this(); - _globals->CallLater([=]() { self->Disconnected(); }); - } - - RouterContact - GetRemoteRC() const override - { - return remote->GetOurRC(); - } - - bool - ShouldPing() const override - { - return true; - } - - bool - SendMessageBuffer(const llarp_buffer_t& pkt, - ILinkSession::CompletionHandler completed) override - { - if(completed == nullptr) - completed = [](ILinkSession::DeliveryStatus) {}; - auto self = shared_from_this(); - std::vector< byte_t > buf(pkt.sz); - std::copy_n(pkt.base, pkt.sz, buf.begin()); - return _globals->SendTo(parent->GetOurRC().pubkey, GetRemoteRC().pubkey, - buf, [=](ILinkSession::DeliveryStatus status) { - self->parent->logic()->call_later( - 10, std::bind(completed, status)); - }); - } - - void - Start() override - { - if(!StartPipe()) - return; - if(isInbound) - return; - LogDebug("outbound start"); - auto self = shared_from_this(); - _globals->CallLater([=]() { - LogDebug("Called inbound connection"); - _globals->InboundConnection(self->GetPubKey(), self); - }); - } - - bool - IsEstablished() const override - { - return _globals->HasConnection(parent->GetOurRC().pubkey, GetPubKey()); - } - - void - Disconnected() - { - _globals->DisconnectNode(parent->GetOurRC().pubkey, GetPubKey()); - } - - bool - RenegotiateSession() override - { - return true; - } - - ILinkLayer* - GetLinkLayer() const override - { - return parent.get(); - } - - util::StatusObject - ExtractStatus() const override - { - return {}; - } - - llarp::Addr - GetRemoteEndpoint() const override - { - return {}; - } - - size_t - SendQueueBacklog() const override - { - return m_sendQueue.size(); - } - }; - - struct MemLink : public ILinkLayer, - public std::enable_shared_from_this< MemLink > - { - MemLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SignBufferFunc sign, - SessionEstablishedHandler est, SessionRenegotiateHandler reneg, - TimeoutHandler timeout, SessionClosedHandler closed, - bool permitInbound) - : ILinkLayer(routerEncSecret, getrc, h, sign, est, reneg, timeout, - closed) - , allowInbound(permitInbound) - { - } - - const bool allowInbound; - - bool - KeyGen(SecretKey& k) override - { - k.Zero(); - return true; - } - - const char* - Name() const override - { - return "mempipe"; - } - - uint16_t - Rank() const override - { - return 100; - } - - void - Pump() override - { - LogDebug("memlink pump"); - std::set< RouterID > sessions; - { - Lock l(&m_AuthedLinksMutex); - auto itr = m_AuthedLinks.begin(); - while(itr != m_AuthedLinks.end()) - { - sessions.insert(itr->first); - ++itr; - } - } - ILinkLayer::Pump(); - { - Lock l(&m_AuthedLinksMutex); - for(const auto& pk : sessions) - { - if(m_AuthedLinks.count(pk) == 0) - { - // all sessions were removed - SessionClosed(pk); - } - } - } - } - - void - RecvFrom(const llarp::Addr&, const void*, size_t) override - { - } - - bool - Configure(llarp_ev_loop_ptr ev, const std::string&, int, - uint16_t) override - { - m_Loop = ev; - if(_globals == nullptr) - { - _globals = std::make_unique< MempipeContext >(); - _globals->Start(ev); - } - return _globals != nullptr; - } - - std::shared_ptr< ILinkSession > - NewOutboundSession(const RouterContact& rc, - const AddressInfo& ai) override - { - if(ai.dialect != Name()) - return nullptr; - auto remote = _globals->FindNode(rc.pubkey); - if(remote == nullptr) - return nullptr; - return std::make_shared< MemSession >(m_Loop, shared_from_this(), - remote, false); - } - - bool - Start(std::shared_ptr< Logic > l) override - { - if(!ILinkLayer::Start(l)) - return false; - _globals->AddNode(shared_from_this()); - return true; - } - - void - Stop() override - { - _globals->RemoveNode(shared_from_this()); - } - }; - - LinkLayer_ptr - NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SignBufferFunc sign, - SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, TimeoutHandler timeout, - SessionClosedHandler closed) - { - return std::make_shared< MemLink >(routerEncSecret, getrc, h, sign, est, - reneg, timeout, closed, false); - } - - LinkLayer_ptr - NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SignBufferFunc sign, - SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, TimeoutHandler timeout, - SessionClosedHandler closed) - { - return std::make_shared< MemLink >(routerEncSecret, getrc, h, sign, est, - reneg, timeout, closed, true); - } - - void - MempipeContext::AddNode(LinkLayer_ptr ptr) - { - util::Lock lock(&_access); - _nodes.emplace(RouterID(ptr->GetOurRC().pubkey), ptr); - LogInfo("add mempipe node: ", RouterID(ptr->GetOurRC().pubkey)); - } - - bool - MempipeContext::SendTo(const RouterID src, const RouterID dst, - const std::vector< byte_t > msg, - ILinkSession::CompletionHandler delivery) - { - util::Lock lock(&_access); - _sendQueue.emplace_back(std::move(src), std::move(dst), std::move(msg), - std::move(delivery)); - return true; - } - - void - MempipeContext::InboundConnection(const RouterID to, - const std::shared_ptr< MemSession >& ob) - { - LogDebug("inbound connect to ", to, " from ", - RouterID(ob->parent->GetOurRC().pubkey)); - std::shared_ptr< MemSession > other; - { - util::Lock lock(&_access); - auto itr = _nodes.find(to); - if(itr != _nodes.end()) - { - other = std::make_shared< MemSession >(evloop, itr->second, - ob->parent, true); - } - } - if(other) - { - ConnectNode(other->GetPubKey(), ob->GetPubKey(), other); - ConnectNode(ob->GetPubKey(), other->GetPubKey(), ob); - ob->parent->logic()->queue_func([ob]() { - ob->parent->MapAddr(RouterID{ob->GetPubKey()}, ob.get()); - ob->parent->SessionEstablished(ob.get()); - }); - other->parent->logic()->queue_func([other]() { - other->parent->MapAddr(RouterID{other->GetPubKey()}, other.get()); - other->parent->SessionEstablished(other.get()); - }); - } - else - { - ob->Disconnected(); - } - } - - void - MempipeContext::ConnectNode(const RouterID src, const RouterID dst, - const std::shared_ptr< MemSession >& session) - { - LogDebug("connect ", src, " to ", dst); - util::Lock lock(&_access); - _connections.emplace(std::make_pair(std::make_tuple(src, dst), session)); - } - - void - MempipeContext::DisconnectNode(const RouterID src, const RouterID dst) - { - LogDebug("connect ", src, " from ", dst); - util::Lock lock(&_access); - _connections.erase({src, dst}); - } - - LinkLayer_ptr - MempipeContext::FindNode(const RouterID rid) - { - util::Lock lock(&_access); - auto itr = _nodes.find(rid); - if(itr == _nodes.end()) - return nullptr; - return itr->second; - } - - bool - MempipeContext::HasConnection(const RouterID src, const RouterID dst) const - { - util::Lock lock(&_access); - return _connections.find({src, dst}) != _connections.end(); - } - - void - MempipeContext::RemoveNode(LinkLayer_ptr node) - { - util::Lock lock(&_access); - const RouterID pk = node->GetOurRC().pubkey; - _nodes.erase(pk); - auto itr = _connections.begin(); - while(itr != _connections.end()) - { - if(std::get< 0 >(itr->first) == pk || std::get< 1 >(itr->first) == pk) - { - auto s = itr->second->shared_from_this(); - itr->second->GetLinkLayer()->logic()->call_later( - 1, [s]() { s->Disconnected(); }); - } - ++itr; - } - } - - void - MempipeContext::Pump() - { - std::vector< SendEvent > q; - { - util::Lock lock(&_access); - q = std::move(_sendQueue); - } - for(auto& f : q) - { - ILinkSession::DeliveryStatus status = - ILinkSession::DeliveryStatus::eDeliveryDropped; - { - util::Lock lock(&_access); - auto itr = _connections.find({std::get< 0 >(f), std::get< 1 >(f)}); - if(itr != _connections.end()) - { - const llarp_buffer_t pkt{std::get< 2 >(f)}; - if(itr->second->Write(pkt)) - status = ILinkSession::DeliveryStatus::eDeliverySuccess; - } - } - LogDebug(std::get< 0 >(f), "->", std::get< 1 >(f), - " status=", (int)status); - CallLater(std::bind(std::get< 3 >(f), status)); - } - } - } // namespace mempipe -} // namespace llarp \ No newline at end of file diff --git a/llarp/mempipe/mempipe.hpp b/llarp/mempipe/mempipe.hpp deleted file mode 100644 index 91094602a..000000000 --- a/llarp/mempipe/mempipe.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef LLARP_MEMPIPE_MEMPIPE_HPP -#define LLARP_MEMPIPE_MEMPIPE_HPP -#include -#include - -namespace llarp -{ - namespace mempipe - { - LinkLayer_ptr - NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SignBufferFunc sign, - SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, TimeoutHandler timeout, - SessionClosedHandler closed); - LinkLayer_ptr - NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SignBufferFunc sign, - SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, TimeoutHandler timeout, - SessionClosedHandler closed); - } // namespace mempipe -} // namespace llarp - -#endif \ No newline at end of file diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index d214a9cc1..5f03069fb 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -1,8 +1,8 @@ -#include +#include #include #include #include -#include +#include #include #include #include @@ -15,7 +15,7 @@ using namespace ::llarp; using namespace ::testing; -struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > +struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium > { static constexpr uint16_t AlicePort = 5000; static constexpr uint16_t BobPort = 6000; @@ -171,9 +171,9 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > } }; -TEST_F(LinkLayerTest, TestMemPipe) +TEST_F(LinkLayerTest, TestIWP) { - Alice.link = mempipe::NewInboundLink( + Alice.link = iwp::NewInboundLink( Alice.encryptionKey, [&]() -> const RouterContact& { return Alice.GetRC(); }, [&](ILinkSession* s, const llarp_buffer_t& buf) -> bool { @@ -221,7 +221,7 @@ TEST_F(LinkLayerTest, TestMemPipe) return s->SendMessageBuffer(otherBuf, nullptr); }; - Bob.link = mempipe::NewInboundLink( + Bob.link = iwp::NewInboundLink( Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); }, [&](ILinkSession* s, const llarp_buffer_t& buf) -> bool { LinkIntroMessage msg; @@ -258,7 +258,6 @@ TEST_F(LinkLayerTest, TestMemPipe) RunMainloop(); ASSERT_TRUE(Bob.gotLIM); - ASSERT_TRUE(success); }; TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) From ba316f85ba7d584d19ba64dec4fac5cc28a9dd3f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 22 Aug 2019 16:56:27 -0400 Subject: [PATCH 04/44] default to iwp --- llarp/config/config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 2a618154e..56f199d45 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -118,7 +118,7 @@ namespace llarp int m_workerThreads = 1; int m_numNetThreads = 1; - std::string m_DefaultLinkProto = "utp"; + std::string m_DefaultLinkProto = "iwp"; public: // clang-format off From acf5f789499056728c83bd8fe678376511e1615a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 07:32:52 -0400 Subject: [PATCH 05/44] update iwp , add NACK --- llarp/iwp/linklayer.cpp | 52 +++- llarp/iwp/linklayer.hpp | 7 + llarp/iwp/message_buffer.cpp | 128 +++++---- llarp/iwp/message_buffer.hpp | 37 +-- llarp/iwp/session.cpp | 329 +++++++++++++++--------- llarp/iwp/session.hpp | 52 ++-- llarp/link/link_manager.cpp | 5 +- llarp/link/server.hpp | 2 +- llarp/router/outbound_session_maker.cpp | 2 + llarp/router/outbound_session_maker.hpp | 7 + llarp/router/router.cpp | 2 +- 11 files changed, 392 insertions(+), 231 deletions(-) diff --git a/llarp/iwp/linklayer.cpp b/llarp/iwp/linklayer.cpp index 9de470693..57d0c499a 100644 --- a/llarp/iwp/linklayer.cpp +++ b/llarp/iwp/linklayer.cpp @@ -22,7 +22,28 @@ namespace llarp void LinkLayer::Pump() { + std::set< RouterID > sessions; + { + Lock l(&m_AuthedLinksMutex); + auto itr = m_AuthedLinks.begin(); + while(itr != m_AuthedLinks.end()) + { + sessions.insert(itr->first); + ++itr; + } + } ILinkLayer::Pump(); + { + Lock l(&m_AuthedLinksMutex); + for(const auto& pk : sessions) + { + if(m_AuthedLinks.count(pk) == 0) + { + // all sessions were removed + SessionClosed(pk); + } + } + } } const char* @@ -55,16 +76,43 @@ namespace llarp LinkLayer::RecvFrom(const Addr& from, const void* pkt, size_t sz) { std::shared_ptr< ILinkSession > session; + auto itr = m_AuthedAddrs.find(from); + if(itr == m_AuthedAddrs.end()) { util::Lock lock(&m_PendingMutex); if(m_Pending.count(from) == 0) { + if(not permitInbound) + return; m_Pending.insert({from, std::make_shared< Session >(this, from)}); } session = m_Pending.find(from)->second; } - const llarp_buffer_t buf{pkt, sz}; - session->Recv_LL(buf); + else + { + auto range = m_AuthedLinks.equal_range(itr->second); + session = range.first->second; + } + if(session) + { + const llarp_buffer_t buf{pkt, sz}; + session->Recv_LL(buf); + } + } + + bool + LinkLayer::MapAddr(const RouterID& r, ILinkSession* s) + { + if(!ILinkLayer::MapAddr(r, s)) + return false; + m_AuthedAddrs.emplace(s->GetRemoteEndpoint(), r); + return true; + } + + void + LinkLayer::UnmapAddr(const Addr& a) + { + m_AuthedAddrs.erase(a); } std::shared_ptr< ILinkSession > diff --git a/llarp/iwp/linklayer.hpp b/llarp/iwp/linklayer.hpp index 364716de8..13ecf3ecf 100644 --- a/llarp/iwp/linklayer.hpp +++ b/llarp/iwp/linklayer.hpp @@ -43,7 +43,14 @@ namespace llarp void RecvFrom(const Addr &from, const void *buf, size_t sz) override; + bool + MapAddr(const RouterID &pk, ILinkSession *s) override; + + void + UnmapAddr(const Addr &addr); + private: + std::unordered_map< Addr, RouterID, Addr::Hash > m_AuthedAddrs; const bool permitInbound; }; diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp index b2ed59a87..283bb3b91 100644 --- a/llarp/iwp/message_buffer.cpp +++ b/llarp/iwp/message_buffer.cpp @@ -5,23 +5,25 @@ namespace llarp { namespace iwp { - OutboundMessage::OutboundMessage() : - m_Size{0} {} - - OutboundMessage::OutboundMessage(uint64_t msgid, const llarp_buffer_t& pkt, - ILinkSession::CompletionHandler handler) : - m_Size{std::min(pkt.sz, MAX_LINK_MSG_SIZE)}, - m_MsgID{msgid}, - m_Completed{handler} - { - m_Data.Zero(); - std::copy_n(pkt.base, m_Size, m_Data.begin()); - } - - std::vector - OutboundMessage::XMIT() const - { - std::vector xmit{LLARP_PROTO_VERSION, Command::eXMIT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + OutboundMessage::OutboundMessage() : m_Size{0} + { + } + + OutboundMessage::OutboundMessage(uint64_t msgid, const llarp_buffer_t &pkt, + ILinkSession::CompletionHandler handler) + : m_Size{std::min(pkt.sz, MAX_LINK_MSG_SIZE)} + , m_MsgID{msgid} + , m_Completed{handler} + { + m_Data.Zero(); + std::copy_n(pkt.base, m_Size, m_Data.begin()); + } + + std::vector< byte_t > + OutboundMessage::XMIT() const + { + std::vector< byte_t > xmit{ + LLARP_PROTO_VERSION, Command::eXMIT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; htobe16buf(xmit.data() + 2, m_Size); htobe64buf(xmit.data() + 4, m_MsgID); const llarp_buffer_t buf{m_Data.data(), m_Size}; @@ -33,7 +35,7 @@ namespace llarp } void - OutboundMessage::Completed() + OutboundMessage::Completed() { if(m_Completed) { @@ -45,28 +47,41 @@ namespace llarp bool OutboundMessage::ShouldFlush(llarp_time_t now) const { - static constexpr llarp_time_t FlushInterval = 250; + static constexpr llarp_time_t FlushInterval = 500; return now - m_LastFlush >= FlushInterval; } - void + void OutboundMessage::Ack(byte_t bitmask) { - m_Acks = std::bitset<8>(bitmask); + m_Acks = std::bitset< 8 >(bitmask); } - void - OutboundMessage::FlushUnAcked(std::function sendpkt, llarp_time_t now) + void + OutboundMessage::FlushUnAcked( + std::function< void(const llarp_buffer_t &) > sendpkt, llarp_time_t now) { uint16_t idx = 0; while(idx < m_Size) { if(not m_Acks[idx / FragmentSize]) { - std::vector frag{LLARP_PROTO_VERSION, Command::eDATA, 0,0,0,0,0,0,0,0,0,0}; + std::vector< byte_t > frag{LLARP_PROTO_VERSION, + Command::eDATA, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0}; htobe16buf(frag.data() + 2, idx); htobe64buf(frag.data() + 4, m_MsgID); - std::copy(m_Data.begin() + idx, m_Data.begin() + idx + FragmentSize, std::back_inserter(frag)); + std::copy(m_Data.begin() + idx, m_Data.begin() + idx + FragmentSize, + std::back_inserter(frag)); const llarp_buffer_t pkt{frag}; sendpkt(pkt); } @@ -75,47 +90,49 @@ namespace llarp m_LastFlush = now; } - bool - OutboundMessage::IsTransmitted() const - { - for(uint16_t idx = 0; idx < m_Size; idx += FragmentSize) - { - if(!m_Acks.test(idx / FragmentSize)) - return false; + bool + OutboundMessage::IsTransmitted() const + { + for(uint16_t idx = 0; idx < m_Size; idx += FragmentSize) + { + if(!m_Acks.test(idx / FragmentSize)) + return false; + } + return true; } - return true; - } - InboundMessage::InboundMessage() : m_Size{0} {} + InboundMessage::InboundMessage() : m_Size{0} + { + } - InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h) : - m_Digset{std::move(h)}, - m_Size{sz}, - m_MsgID{msgid} - {} + InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h) + : m_Digset{std::move(h)}, m_Size{sz}, m_MsgID{msgid} + { + } - void - InboundMessage::HandleData(uint16_t idx, const byte_t * ptr) + void + InboundMessage::HandleData(uint16_t idx, const byte_t *ptr) { if(idx + FragmentSize > MAX_LINK_MSG_SIZE) return; - auto * dst = m_Data.data() + idx; + auto *dst = m_Data.data() + idx; std::copy_n(ptr, FragmentSize, dst); m_Acks.set(idx / FragmentSize); - LogDebug("got fragment ", idx / FragmentSize , " of ", m_Size); + LogDebug("got fragment ", idx / FragmentSize, " of ", m_Size); } - - std::vector - InboundMessage::ACKS() const + std::vector< byte_t > + InboundMessage::ACKS() const { - std::vector acks{LLARP_PROTO_VERSION, Command::eACKS, 0, 0, 0, 0, 0, 0, 0, 0, uint8_t{m_Acks.to_ulong()}}; - + std::vector< byte_t > acks{ + LLARP_PROTO_VERSION, Command::eACKS, 0, 0, 0, 0, 0, 0, 0, 0, + uint8_t{m_Acks.to_ulong()}}; + htobe64buf(acks.data() + 2, m_MsgID); return acks; } - bool + bool InboundMessage::IsCompleted() const { for(uint16_t idx = 0; idx < m_Size; idx += FragmentSize) @@ -133,7 +150,8 @@ namespace llarp } void - InboundMessage::SendACKS(std::function sendpkt, llarp_time_t now) + InboundMessage::SendACKS( + std::function< void(const llarp_buffer_t &) > sendpkt, llarp_time_t now) { auto acks = ACKS(); const llarp_buffer_t pkt{acks}; @@ -141,13 +159,13 @@ namespace llarp m_LastACKSent = now; } - bool + bool InboundMessage::Verify() const { ShortHash gotten; const llarp_buffer_t buf{m_Data.data(), m_Size}; CryptoManager::instance()->shorthash(gotten, buf); - LogDebug("gotten=",gotten.ToHex()); + LogDebug("gotten=", gotten.ToHex()); if(gotten != m_Digset) { DumpBuffer(buf); @@ -156,5 +174,5 @@ namespace llarp return true; } - } -} \ No newline at end of file + } // namespace iwp +} // namespace llarp \ No newline at end of file diff --git a/llarp/iwp/message_buffer.hpp b/llarp/iwp/message_buffer.hpp index 0d60e9a0a..8082fb706 100644 --- a/llarp/iwp/message_buffer.hpp +++ b/llarp/iwp/message_buffer.hpp @@ -21,8 +21,10 @@ namespace llarp eDATA = 2, /// acknolege fragments eACKS = 3, + /// negative ack + eNACK = 4, /// close session - eCLOS = 4 + eCLOS = 5 }; static constexpr size_t FragmentSize = 1024; @@ -30,26 +32,27 @@ namespace llarp struct OutboundMessage { OutboundMessage(); - OutboundMessage(uint64_t msgid, const llarp_buffer_t& pkt, + OutboundMessage(uint64_t msgid, const llarp_buffer_t &pkt, ILinkSession::CompletionHandler handler); AlignedBuffer< MAX_LINK_MSG_SIZE > m_Data; - uint16_t m_Size = 0; + uint16_t m_Size = 0; uint64_t m_MsgID = 0; std::bitset< MAX_LINK_MSG_SIZE / FragmentSize > m_Acks; ILinkSession::CompletionHandler m_Completed; llarp_time_t m_LastFlush = 0; - std::vector + std::vector< byte_t > XMIT() const; void Ack(byte_t bitmask); - void - FlushUnAcked(std::function sendpkt, llarp_time_t now); + void + FlushUnAcked(std::function< void(const llarp_buffer_t &) > sendpkt, + llarp_time_t now); - bool + bool ShouldFlush(llarp_time_t now) const; void @@ -66,29 +69,29 @@ namespace llarp AlignedBuffer< MAX_LINK_MSG_SIZE > m_Data; ShortHash m_Digset; - uint16_t m_Size = 0; - uint64_t m_MsgID = 0; + uint16_t m_Size = 0; + uint64_t m_MsgID = 0; llarp_time_t m_LastACKSent = 0; std::bitset< MAX_LINK_MSG_SIZE / FragmentSize > m_Acks; void - HandleData(uint16_t idx, const byte_t * ptr); + HandleData(uint16_t idx, const byte_t *ptr); - bool + bool IsCompleted() const; - bool + bool Verify() const; - bool + bool ShouldSendACKS(llarp_time_t now) const; - void - SendACKS(std::function sendpkt, llarp_time_t now); + void + SendACKS(std::function< void(const llarp_buffer_t &) > sendpkt, + llarp_time_t now); - std::vector + std::vector< byte_t > ACKS() const; - }; } // namespace iwp diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index c81bb0b02..3321c8a7b 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace llarp { @@ -45,28 +46,44 @@ namespace llarp } bool - Session::GotInboundLIM(const LinkIntroMessage * msg) + Session::GotInboundLIM(const LinkIntroMessage* msg) { if(msg->rc.enckey != m_RemoteOnionKey) + { + LogError("key missmatch"); return false; - m_State = State::Ready; - GotLIM = util::memFn(&Session::GotRenegLIM, this); - return true; + } + m_State = State::Ready; + GotLIM = util::memFn(&Session::GotRenegLIM, this); + m_RemoteRC = msg->rc; + m_Parent->MapAddr(m_RemoteRC.pubkey, this); + return m_Parent->SessionEstablished(this); } bool - Session::GotOutboundLIM(const LinkIntroMessage * msg) + Session::GotOutboundLIM(const LinkIntroMessage* msg) { if(msg->rc.pubkey != m_RemoteRC.pubkey) + { + LogError("ident key missmatch"); return false; - m_State = State::LinkIntro; - GotLIM = util::memFn(&Session::GotRenegLIM, this); - SendOurLIM(); + } + m_RemoteRC = msg->rc; + GotLIM = util::memFn(&Session::GotRenegLIM, this); + auto self = shared_from_this(); + SendOurLIM([self](ILinkSession::DeliveryStatus st) { + if(st == ILinkSession::DeliveryStatus::eDeliverySuccess) + { + self->m_State = State::Ready; + self->m_Parent->MapAddr(self->m_RemoteRC.pubkey, self.get()); + self->m_Parent->SessionEstablished(self.get()); + } + }); return true; } void - Session::SendOurLIM() + Session::SendOurLIM(ILinkSession::CompletionHandler h) { LinkIntroMessage msg; msg.rc = m_Parent->GetOurRC(); @@ -77,15 +94,15 @@ namespace llarp LogError("failed to sign our RC for ", m_RemoteAddr); return; } - AlignedBuffer data; + AlignedBuffer< LinkIntroMessage::MaxSize > data; llarp_buffer_t buf{data}; if(not msg.BEncode(&buf)) { LogError("failed to encode LIM for ", m_RemoteAddr); } - buf.sz = buf.cur - buf.base; + buf.sz = buf.cur - buf.base; buf.cur = buf.base; - if(!SendMessageBuffer(buf, nullptr)) + if(!SendMessageBuffer(buf, h)) { LogError("failed to send LIM to ", m_RemoteAddr); } @@ -95,7 +112,6 @@ namespace llarp void Session::EncryptAndSend(const llarp_buffer_t& data) { - std::vector< byte_t > pkt; pkt.resize(data.sz + PacketOverhead); CryptoManager::instance()->randbytes(pkt.data(), pkt.size()); @@ -104,16 +120,15 @@ namespace llarp pktbuf.sz -= PacketOverhead; byte_t* nonce_ptr = pkt.data() + HMACSIZE; - CryptoManager::instance()->xchacha20_alt(pktbuf, data, m_SessionKey, nonce_ptr); pktbuf.base = nonce_ptr; - pktbuf.sz = data.sz + 32; + pktbuf.sz = data.sz + 32; CryptoManager::instance()->hmac(pkt.data(), pktbuf, m_SessionKey); pktbuf.base = pkt.data(); - pktbuf.sz = pkt.size(); + pktbuf.sz = pkt.size(); Send_LL(pktbuf); } @@ -122,10 +137,14 @@ namespace llarp { if(m_State == State::Closed) return; - const std::vector close_msg = {LLARP_PROTO_VERSION, Command::eCLOS}; + const std::vector< byte_t > close_msg = {LLARP_PROTO_VERSION, + Command::eCLOS}; const llarp_buffer_t buf{close_msg}; EncryptAndSend(buf); + if(m_State == State::Ready) + m_Parent->UnmapAddr(m_RemoteAddr); m_State = State::Closed; + LogInfo("closing connection to ", m_RemoteAddr); } bool @@ -133,12 +152,14 @@ namespace llarp ILinkSession::CompletionHandler completed) { const auto msgid = m_TXID++; - auto& msg = m_TXMsgs.emplace(msgid, OutboundMessage{msgid, buf, completed}) - .first->second; - auto xmit = msg.XMIT(); + auto& msg = + m_TXMsgs.emplace(msgid, OutboundMessage{msgid, buf, completed}) + .first->second; + const auto xmit = msg.XMIT(); const llarp_buffer_t pkt{xmit}; EncryptAndSend(pkt); - msg.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), m_Parent->Now()); + msg.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), + m_Parent->Now()); LogDebug("send message ", msgid); return true; } @@ -146,67 +167,34 @@ namespace llarp void Session::Pump() { - static constexpr llarp_time_t IntroInterval = 500; const auto now = m_Parent->Now(); - if(m_State == State::Introduction) + if(m_State == State::Ready || m_State == State::LinkIntro) { - if(not m_Inbound) - { - // resend intro - if(now - m_LastTX >= IntroInterval) - { - GenerateAndSendIntro(); - } - } - } - else if(m_State == State::Ready || m_State == State::LinkIntro) - { - for(auto itr = m_RXMsgs.begin(); itr != m_RXMsgs.end(); ) + for(auto itr = m_RXMsgs.begin(); itr != m_RXMsgs.end(); ++itr) { if(itr->second.ShouldSendACKS(now)) { - itr->second.SendACKS(util::memFn(&Session::EncryptAndSend, this), now); - } - if(itr->second.IsCompleted()) - { - if(itr->second.Verify()) - { - const llarp_buffer_t buf{itr->second.m_Data.data(), itr->second.m_Size}; - LogDebug("got message ", itr->first); - m_Parent->HandleMessage(this, buf); - } - else - { - LogError("hash missmatch for message ", itr->first); - } - itr = m_RXMsgs.erase(itr); - continue; + itr->second.SendACKS(util::memFn(&Session::EncryptAndSend, this), + now); } - ++itr; } - for(auto itr = m_TXMsgs.begin(); itr != m_TXMsgs.end(); ) + for(auto itr = m_TXMsgs.begin(); itr != m_TXMsgs.end(); ++itr) { if(itr->second.ShouldFlush(now)) - itr->second.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), now); - if(itr->second.IsTransmitted()) - { - LogDebug("sent message ", itr->first); - itr->second.Completed(); - itr = m_TXMsgs.erase(itr); - continue; - } - ++itr; + itr->second.FlushUnAcked( + util::memFn(&Session::EncryptAndSend, this), now); } } } - bool - Session::GotRenegLIM(const LinkIntroMessage * lim) + bool + Session::GotRenegLIM(const LinkIntroMessage* lim) { + LogInfo("renegotiate session on ", m_RemoteAddr); return m_Parent->SessionRenegotiate(lim->rc, m_RemoteRC); } - bool + bool Session::RenegotiateSession() { SendOurLIM(); @@ -216,65 +204,73 @@ namespace llarp bool Session::ShouldPing() const { - static constexpr llarp_time_t PingInterval = 1000; - const auto now = m_Parent->Now(); - return now - m_LastTX > PingInterval; + if(m_State == State::Ready || m_State == State::LinkIntro) + { + static constexpr llarp_time_t PingInterval = 500; + const auto now = m_Parent->Now(); + return now - m_LastTX > PingInterval; + } + return false; } util::StatusObject Session::ExtractStatus() const { - return { - {"remoteAddr", m_RemoteAddr.ToString()}, - {"remoteRC", m_RemoteRC.ExtractStatus()} - }; + return {{"remoteAddr", m_RemoteAddr.ToString()}, + {"remoteRC", m_RemoteRC.ExtractStatus()}}; } bool Session::TimedOut(llarp_time_t now) const { - static constexpr llarp_time_t SessionAliveTimeout = 5000; - if(m_State != State::Ready) - return now - m_CreatedAt > SessionAliveTimeout; - return now - m_LastRX > SessionAliveTimeout; + static constexpr llarp_time_t SessionAliveTimeout = 10000; + if(m_State == State::Ready || m_State == State::LinkIntro) + { + return now > m_LastRX && now - m_LastRX > SessionAliveTimeout; + } + return now - m_CreatedAt > SessionAliveTimeout; } - void - Session::Tick(llarp_time_t) + void Session::Tick(llarp_time_t) { } - using Introduction = AlignedBuffer<64>; + using Introduction = AlignedBuffer< 64 >; - void + void Session::GenerateAndSendIntro() { Introduction intro; - + TunnelNonce N; N.Randomize(); - if(not CryptoManager::instance()->transport_dh_client(m_SessionKey, m_ChosenAI.pubkey, m_Parent->RouterEncryptionSecret(), N)) + if(not CryptoManager::instance()->transport_dh_client( + m_SessionKey, m_ChosenAI.pubkey, + m_Parent->RouterEncryptionSecret(), N)) { - LogError("failed to transport_dh_client on outbound session to ", m_RemoteAddr); + LogError("failed to transport_dh_client on outbound session to ", + m_RemoteAddr); return; } const auto pk = m_Parent->RouterEncryptionSecret().toPublic(); std::copy_n(pk.begin(), pk.size(), intro.begin()); std::copy(N.begin(), N.end(), intro.begin() + 32); - LogDebug("pk=", pk.ToHex(), " N=", N.ToHex(), " remote-pk=", m_ChosenAI.pubkey.ToHex()); - std::vector req; + LogDebug("pk=", pk.ToHex(), " N=", N.ToHex(), + " remote-pk=", m_ChosenAI.pubkey.ToHex()); + std::vector< byte_t > req; req.resize(intro.size() + (randint() % 64)); CryptoManager::instance()->randbytes(req.data(), req.size()); std::copy_n(intro.begin(), intro.size(), req.begin()); const llarp_buffer_t buf{req}; Send_LL(buf); m_State = State::Introduction; + LogDebug("sent intro to ", m_RemoteAddr); } - + void - Session::HandleCreateSessionRequest(const llarp_buffer_t & buf) + Session::HandleCreateSessionRequest(const llarp_buffer_t& buf) { - std::vector result; + std::vector< byte_t > result; if(not DecryptMessage(buf, result)) { LogError("failed to decrypt session request from ", m_RemoteAddr); @@ -282,47 +278,57 @@ namespace llarp } if(result.size() < token.size()) { - LogError("bad session request size, ", result.size(), " < ", token.size(), " from ", m_RemoteAddr); + LogError("bad session request size, ", result.size(), " < ", + token.size(), " from ", m_RemoteAddr); return; } - if(not std::equal(result.begin(), result.begin() + token.size(), token.begin())) + if(not std::equal(result.begin(), result.begin() + token.size(), + token.begin())) { LogError("token missmatch from ", m_RemoteAddr); return; } + m_LastRX = m_Parent->Now(); + m_State = State::LinkIntro; SendOurLIM(); - m_State = State::LinkIntro; } - void - Session::HandleGotIntro(const llarp_buffer_t & buf) + void + Session::HandleGotIntro(const llarp_buffer_t& buf) { if(buf.sz < Introduction::SIZE) + { + LogWarn("intro too small from ", m_RemoteAddr); return; + } TunnelNonce N; std::copy_n(buf.base, PubKey::SIZE, m_RemoteOnionKey.begin()); std::copy_n(buf.base + PubKey::SIZE, TunnelNonce::SIZE, N.begin()); const PubKey pk = m_Parent->TransportSecretKey().toPublic(); - LogDebug("remote-pk=", m_RemoteOnionKey.ToHex(), " N=", N.ToHex(), " local-pk=", pk.ToHex()); - if(not CryptoManager::instance()->transport_dh_server(m_SessionKey, m_RemoteOnionKey, m_Parent->TransportSecretKey(), N)) + LogDebug("got intro: remote-pk=", m_RemoteOnionKey.ToHex(), + " N=", N.ToHex(), " local-pk=", pk.ToHex(), " sz=", buf.sz); + if(not CryptoManager::instance()->transport_dh_server( + m_SessionKey, m_RemoteOnionKey, m_Parent->TransportSecretKey(), N)) { - LogError("failed to transport_dh_server on inbound intro from ", m_RemoteAddr); + LogError("failed to transport_dh_server on inbound intro from ", + m_RemoteAddr); return; } - std::vector reply; + std::vector< byte_t > reply; reply.resize(token.size() + (randint() % 32)); CryptoManager::instance()->randbytes(reply.data(), reply.size()); std::copy_n(token.begin(), token.size(), reply.begin()); const llarp_buffer_t pkt{reply}; m_LastRX = m_Parent->Now(); EncryptAndSend(pkt); + LogDebug("sent intro ack to ", m_RemoteAddr); m_State = State::Introduction; } void - Session::HandleGotIntroAck(const llarp_buffer_t & buf) + Session::HandleGotIntroAck(const llarp_buffer_t& buf) { - std::vector reply; + std::vector< byte_t > reply; if(not DecryptMessage(buf, reply)) { LogError("intro ack decrypt failed from ", m_RemoteAddr); @@ -330,21 +336,27 @@ namespace llarp } if(reply.size() < token.size()) { - LogError("bad intro ack size ", reply.size(), " < ", token.size(), " from ", m_RemoteAddr); + LogError("bad intro ack size ", reply.size(), " < ", token.size(), + " from ", m_RemoteAddr); return; } m_LastRX = m_Parent->Now(); std::copy_n(reply.begin(), token.size(), token.begin()); const llarp_buffer_t pkt{token}; EncryptAndSend(pkt); + LogDebug("sent session request to ", m_RemoteAddr); m_State = State::LinkIntro; } bool - Session::DecryptMessage(const llarp_buffer_t & buf, std::vector & result) + Session::DecryptMessage(const llarp_buffer_t& buf, + std::vector< byte_t >& result) { if(buf.sz <= PacketOverhead) + { + LogError("packet too small ", buf.sz); return false; + } ShortHash H; llarp_buffer_t curbuf{buf.base, buf.sz}; curbuf.base += ShortHash::SIZE; @@ -357,16 +369,18 @@ namespace llarp const ShortHash expected{buf.base}; if(H != expected) { - LogError("keyed hash missmatch ", H, " != ", expected, " from ", m_RemoteAddr); + LogError("keyed hash missmatch ", H, " != ", expected, " from ", + m_RemoteAddr, " state=", int(m_State), " size=", buf.sz); return false; } - const byte_t * nonce_ptr = curbuf.base; + const byte_t* nonce_ptr = curbuf.base; curbuf.base += 32; curbuf.sz -= 32; result.resize(buf.sz - PacketOverhead); const llarp_buffer_t outbuf{result}; LogDebug("decrypt: ", result.size(), " bytes from ", m_RemoteAddr); - return CryptoManager::instance()->xchacha20_alt(outbuf, curbuf, m_SessionKey, nonce_ptr); + return CryptoManager::instance()->xchacha20_alt(outbuf, curbuf, + m_SessionKey, nonce_ptr); } void @@ -378,17 +392,25 @@ namespace llarp } void - Session::HandleSessionData(const llarp_buffer_t & buf) + Session::HandleSessionData(const llarp_buffer_t& buf) { - std::vector result; + std::vector< byte_t > result; if(not DecryptMessage(buf, result)) { LogError("failed to decrypt session data from ", m_RemoteAddr); return; } + if(result.size() == token.size()) + { + /// we got a token so we return it + const llarp_buffer_t pktbuf{token}; + EncryptAndSend(pktbuf); + return; + } if(result[0] != LLARP_PROTO_VERSION) { - LogError("protocol version missmatch ", int(result[0]), " != ", LLARP_PROTO_VERSION); + LogError("protocol version missmatch ", int(result[0]), + " != ", LLARP_PROTO_VERSION); return; } LogDebug("command ", int(result[1]), " from ", m_RemoteAddr); @@ -406,78 +428,127 @@ namespace llarp case Command::ePING: HandlePING(std::move(result)); break; + case Command::eNACK: + HandleNACK(std::move(result)); + break; case Command::eCLOS: HandleCLOS(std::move(result)); break; - default: + default: LogError("invalid command ", int(result[1])); } } void - Session::HandleXMIT(std::vector data) + Session::HandleNACK(std::vector< byte_t > data) + { + uint64_t txid = bufbe64toh(data.data() + 2); + LogDebug("got nack on ", txid, " from ", m_RemoteAddr); + auto itr = m_TXMsgs.find(txid); + if(itr != m_TXMsgs.end()) + { + auto xmit = itr->second.XMIT(); + const llarp_buffer_t pkt{xmit}; + EncryptAndSend(pkt); + } + } + + void + Session::HandleXMIT(std::vector< byte_t > data) { if(data.size() < 44) { LogError("short XMIT from ", m_RemoteAddr, " ", data.size(), " < 44"); return; } - uint16_t sz = bufbe16toh(data.data() + 2); + uint16_t sz = bufbe16toh(data.data() + 2); uint64_t rxid = bufbe64toh(data.data() + 4); ShortHash h{data.data() + 12}; LogDebug("rxid=", rxid, " sz=", sz, " h=", h.ToHex()); - m_RXMsgs.emplace(rxid, InboundMessage{rxid, sz, std::move(h)}); + auto itr = m_RXMsgs.find(rxid); + if(itr == m_RXMsgs.end()) + m_RXMsgs.emplace(rxid, InboundMessage{rxid, sz, std::move(h)}); + else + LogWarn("got duplicate xmit on ", rxid, " from ", m_RemoteAddr); m_LastRX = m_Parent->Now(); } void - Session::HandleDATA(std::vector data) + Session::HandleDATA(std::vector< byte_t > data) { if(data.size() < FragmentSize + 12) { - LogError("short DATA from ", m_RemoteAddr, " ", data.size(), " < ", FragmentSize + 8); + LogError("short DATA from ", m_RemoteAddr, " ", data.size()); return; } - uint16_t sz = bufbe16toh(data.data() + 2); + m_LastRX = m_Parent->Now(); + uint16_t sz = bufbe16toh(data.data() + 2); uint64_t rxid = bufbe64toh(data.data() + 4); - auto itr = m_RXMsgs.find(rxid); + auto itr = m_RXMsgs.find(rxid); if(itr == m_RXMsgs.end()) { LogWarn("no rxid=", rxid, " for ", m_RemoteAddr); + std::vector< byte_t > nack = { + LLARP_PROTO_VERSION, Command::eNACK, 0, 0, 0, 0, 0, 0, 0, 0}; + htobe64buf(nack.data() + 2, rxid); + const llarp_buffer_t nackbuf{nack}; + EncryptAndSend(nackbuf); return; } itr->second.HandleData(sz, data.data() + 12); - m_LastRX = m_Parent->Now(); - LogDebug(itr->first, " completed=", itr->second.IsCompleted()); + + if(itr->second.IsCompleted()) + { + itr->second.SendACKS(util::memFn(&Session::EncryptAndSend, this), + m_Parent->Now()); + if(itr->second.Verify()) + { + const llarp_buffer_t buf{itr->second.m_Data.data(), + itr->second.m_Size}; + LogDebug("got message ", itr->first); + m_Parent->HandleMessage(this, buf); + } + else + { + LogError("hash missmatch for message ", itr->first); + } + m_RXMsgs.erase(itr); + } } - void - Session::HandleACKS(std::vector data) + void + Session::HandleACKS(std::vector< byte_t > data) { if(data.size() < 11) { LogError("short ACKS from ", m_RemoteAddr, " ", data.size(), " < 11"); return; } + m_LastRX = m_Parent->Now(); uint64_t txid = bufbe64toh(data.data() + 2); - auto itr = m_TXMsgs.find(txid); + auto itr = m_TXMsgs.find(txid); if(itr == m_TXMsgs.end()) { LogWarn("no txid=", txid, " for ", m_RemoteAddr); return; } itr->second.Ack(data[10]); - m_LastRX = m_Parent->Now(); + + if(itr->second.IsTransmitted()) + { + LogDebug("sent message ", itr->first); + itr->second.Completed(); + itr = m_TXMsgs.erase(itr); + } } - void - Session::HandleCLOS(std::vector) + void Session::HandleCLOS(std::vector< byte_t >) { + LogInfo("remote closed by ", m_RemoteAddr); Close(); } - void - Session::HandlePING(std::vector) + void Session::HandlePING(std::vector< byte_t >) { m_LastRX = m_Parent->Now(); } @@ -485,7 +556,13 @@ namespace llarp bool Session::SendKeepAlive() { - // TODO: Implement me + if(m_State == State::Ready) + { + std::vector< byte_t > ping{LLARP_PROTO_VERSION, Command::ePING}; + const llarp_buffer_t buf{ping}; + EncryptAndSend(buf); + return true; + } return false; } diff --git a/llarp/iwp/session.hpp b/llarp/iwp/session.hpp index 423348bc0..cb83494de 100644 --- a/llarp/iwp/session.hpp +++ b/llarp/iwp/session.hpp @@ -97,7 +97,7 @@ namespace llarp { /// we have no data recv'd Initial, - /// we are in introduction/intro ack phase + /// we are in introduction phase Introduction, /// we sent our LIM LinkIntro, @@ -120,7 +120,7 @@ namespace llarp /// session key SharedSecret m_SessionKey; /// session token - AlignedBuffer<16> token; + AlignedBuffer< 24 > token; PubKey m_RemoteOnionKey; @@ -142,46 +142,46 @@ namespace llarp HandleCreateSessionRequest(const llarp_buffer_t& buf); void - ProcessSessionRequest(const llarp_buffer_t& buf); - - void - ProcessCreateSessionReply(const llarp_buffer_t& buf); + HandleAckSession(const llarp_buffer_t& buf); void HandleSessionData(const llarp_buffer_t& buf); - bool - DecryptMessage(const llarp_buffer_t & buf, std::vector & result); + bool + DecryptMessage(const llarp_buffer_t& buf, std::vector< byte_t >& result); - void + void GenerateAndSendIntro(); bool - GotInboundLIM(const LinkIntroMessage * msg); - + GotInboundLIM(const LinkIntroMessage* msg); + bool - GotOutboundLIM(const LinkIntroMessage * msg); + GotOutboundLIM(const LinkIntroMessage* msg); bool - GotRenegLIM(const LinkIntroMessage * msg); - + GotRenegLIM(const LinkIntroMessage* msg); + + void + SendOurLIM(ILinkSession::CompletionHandler h = nullptr); + void - SendOurLIM(); + HandleXMIT(std::vector< byte_t > msg); - void - HandleXMIT(std::vector msg); - - void - HandleDATA(std::vector msg); + void + HandleDATA(std::vector< byte_t > msg); - void - HandleACKS(std::vector msg); + void + HandleACKS(std::vector< byte_t > msg); - void - HandlePING(std::vector msg); + void + HandleNACK(std::vector< byte_t > msg); - void - HandleCLOS(std::vector msg); + void + HandlePING(std::vector< byte_t > msg); + + void + HandleCLOS(std::vector< byte_t > msg); }; } // namespace iwp } // namespace llarp diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 8c6c5a42f..69b58dc0a 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -346,21 +346,20 @@ namespace llarp if(stopping) return nullptr; - for(const auto &link : inboundLinks) + for(const auto &link : outboundLinks) { if(link->HasSessionTo(remote)) { return link; } } - for(const auto &link : outboundLinks) + for(const auto &link : inboundLinks) { if(link->HasSessionTo(remote)) { return link; } } - return nullptr; } diff --git a/llarp/link/server.hpp b/llarp/link/server.hpp index 3f12f455d..be25c4fdc 100644 --- a/llarp/link/server.hpp +++ b/llarp/link/server.hpp @@ -186,7 +186,7 @@ namespace llarp bool GenEphemeralKeys(); - bool + virtual bool MapAddr(const RouterID& pk, ILinkSession* s); void diff --git a/llarp/router/outbound_session_maker.cpp b/llarp/router/outbound_session_maker.cpp index efdc73b1d..fd64990ce 100644 --- a/llarp/router/outbound_session_maker.cpp +++ b/llarp/router/outbound_session_maker.cpp @@ -226,6 +226,8 @@ namespace llarp bool OutboundSessionMaker::ShouldConnectTo(const RouterID &router) const { + if(router == us) + return false; size_t numPending = 0; { util::Lock lock(&_mutex); diff --git a/llarp/router/outbound_session_maker.hpp b/llarp/router/outbound_session_maker.hpp index f14352651..9be7f47c5 100644 --- a/llarp/router/outbound_session_maker.hpp +++ b/llarp/router/outbound_session_maker.hpp @@ -61,6 +61,12 @@ namespace llarp std::shared_ptr< Logic > logic, llarp_nodedb *nodedb, std::shared_ptr< llarp::thread::ThreadPool > threadpool); + void + SetOurRouter(RouterID r) + { + us = std::move(r); + } + /// always maintain this many connections to other routers size_t minConnectedRouters = 4; /// hard upperbound limit on the number of router to router connections @@ -108,6 +114,7 @@ namespace llarp std::shared_ptr< Logic > _logic; llarp_nodedb *_nodedb; std::shared_ptr< llarp::thread::ThreadPool > _threadpool; + RouterID us; }; } // namespace llarp diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 67760fd4e..917172a63 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -906,7 +906,7 @@ namespace llarp LogError("failed to save RC"); return false; } - + _outboundSessionMaker.SetOurRouter(pubkey()); if(!_linkManager.StartLinks(_logic)) { LogWarn("One or more links failed to start."); From 461f41a4c65cbe04f0ccf56ae135fcdfa6e2cbfb Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 07:36:11 -0400 Subject: [PATCH 06/44] mark alive on nack --- llarp/iwp/session.cpp | 3 ++- llarp/link/server.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 3321c8a7b..a5c729b2c 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -204,7 +204,7 @@ namespace llarp bool Session::ShouldPing() const { - if(m_State == State::Ready || m_State == State::LinkIntro) + if(m_State == State::Ready) { static constexpr llarp_time_t PingInterval = 500; const auto now = m_Parent->Now(); @@ -451,6 +451,7 @@ namespace llarp const llarp_buffer_t pkt{xmit}; EncryptAndSend(pkt); } + m_LastRX = m_Parent->Now(); } void diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 73da6dcb3..28da29194 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -175,6 +175,7 @@ namespace llarp { if(m_AuthedLinks.count(pk) > MaxSessionsPerKey) { + LogWarn("too many session for ", pk); s->Close(); return false; } From d6ec5e7ed7df621aeb94ef0af66a43b6dd6950c0 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 07:50:22 -0400 Subject: [PATCH 07/44] don't crash --- llarp/iwp/session.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index a5c729b2c..af28443a0 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -504,16 +504,15 @@ namespace llarp m_Parent->Now()); if(itr->second.Verify()) { - const llarp_buffer_t buf{itr->second.m_Data.data(), - itr->second.m_Size}; - LogDebug("got message ", itr->first); + auto msg = std::move(itr->second); + const llarp_buffer_t buf{msg.m_Data.data(), msg.m_Size}; m_Parent->HandleMessage(this, buf); } else { LogError("hash missmatch for message ", itr->first); } - m_RXMsgs.erase(itr); + m_RXMsgs.erase(rxid); } } From 7e38a133d81dcaf88e6a151c8f7df7041ad54b10 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 07:57:57 -0400 Subject: [PATCH 08/44] send keep alive on pump when needed --- llarp/iwp/session.cpp | 2 ++ llarp/link/server.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index af28443a0..09c3c7694 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -170,6 +170,8 @@ namespace llarp const auto now = m_Parent->Now(); if(m_State == State::Ready || m_State == State::LinkIntro) { + if(ShouldPing()) + SendKeepAlive(); for(auto itr = m_RXMsgs.begin(); itr != m_RXMsgs.end(); ++itr) { if(itr->second.ShouldSendACKS(now)) diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 28da29194..e1478fc9b 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -129,7 +129,7 @@ namespace llarp auto itr = m_AuthedLinks.begin(); while(itr != m_AuthedLinks.end()) { - if(itr->second.get() && !itr->second->TimedOut(_now)) + if(not itr->second->TimedOut(_now)) { itr->second->Pump(); ++itr; @@ -149,7 +149,7 @@ namespace llarp auto itr = m_Pending.begin(); while(itr != m_Pending.end()) { - if(itr->second.get() && !itr->second->TimedOut(_now)) + if(not itr->second->TimedOut(_now)) { itr->second->Pump(); ++itr; From f8bf907f2405c924b323c72799c8402223310263 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 08:27:57 -0400 Subject: [PATCH 09/44] disable log spew --- test/link/test_llarp_link.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index 5f03069fb..23316cc05 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -120,7 +120,6 @@ struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium > void SetUp() { - SetLogLevel(eLogDebug); oldRCLifetime = RouterContact::Lifetime; RouterContact::IgnoreBogons = true; RouterContact::Lifetime = 500; @@ -137,7 +136,6 @@ struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium > netLoop.reset(); RouterContact::IgnoreBogons = false; RouterContact::Lifetime = oldRCLifetime; - SetLogLevel(eLogInfo); } static void From 5f8388b1c08fdf818aff55d364ed924503eab1f2 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 08:30:07 -0400 Subject: [PATCH 10/44] lower log level for renegotiate --- llarp/iwp/session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 09c3c7694..480c3da7e 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -192,7 +192,7 @@ namespace llarp bool Session::GotRenegLIM(const LinkIntroMessage* lim) { - LogInfo("renegotiate session on ", m_RemoteAddr); + LogDebug("renegotiate session on ", m_RemoteAddr); return m_Parent->SessionRenegotiate(lim->rc, m_RemoteRC); } From 4ac07ea9fbf6ba7d5c7cf0f8733a26d3d23f4c6e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 08:40:56 -0400 Subject: [PATCH 11/44] use std::make_tuple --- llarp/config/config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 489701197..a8b67849e 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -242,8 +242,8 @@ namespace llarp if(key == "*") { - m_OutboundLink = {"*", AF_INET, fromEnv(proto, "OUTBOUND_PORT"), - std::move(opts)}; + m_OutboundLink = std::make_tuple( + "*", AF_INET, fromEnv(proto, "OUTBOUND_PORT"), std::move(opts)); } else { From 82ea973137103aa8b8eac5b2788da6f86db79b6b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 08:48:40 -0400 Subject: [PATCH 12/44] silence clang errors --- llarp/iwp/message_buffer.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp index 283bb3b91..76d7240d7 100644 --- a/llarp/iwp/message_buffer.cpp +++ b/llarp/iwp/message_buffer.cpp @@ -11,7 +11,7 @@ namespace llarp OutboundMessage::OutboundMessage(uint64_t msgid, const llarp_buffer_t &pkt, ILinkSession::CompletionHandler handler) - : m_Size{std::min(pkt.sz, MAX_LINK_MSG_SIZE)} + : m_Size{(uint16_t)std::min(pkt.sz, MAX_LINK_MSG_SIZE)} , m_MsgID{msgid} , m_Completed{handler} { @@ -124,9 +124,17 @@ namespace llarp std::vector< byte_t > InboundMessage::ACKS() const { - std::vector< byte_t > acks{ - LLARP_PROTO_VERSION, Command::eACKS, 0, 0, 0, 0, 0, 0, 0, 0, - uint8_t{m_Acks.to_ulong()}}; + std::vector< byte_t > acks{LLARP_PROTO_VERSION, + Command::eACKS, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + uint8_t{(uint8_t)m_Acks.to_ulong()}}; htobe64buf(acks.data() + 2, m_MsgID); return acks; From 1d32e6a28f9757e36b98e0f8754cfc2f54501703 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 08:55:28 -0400 Subject: [PATCH 13/44] silence clang errors again --- llarp/ev/ev_libuv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 93a815892..732770dda 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -456,7 +456,7 @@ namespace libuv int r = glue->m_Pipe->read(glue->m_Buffer, sizeof(glue->m_Buffer)); if(r <= 0) return; - const llarp_buffer_t buf{glue->m_Buffer, size_t{r}}; + const llarp_buffer_t buf{glue->m_Buffer, static_cast< size_t >(r)}; glue->m_Pipe->OnRead(buf); } From 35c78348f211f6e0a322075cf98705eb42576f33 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 09:29:57 -0400 Subject: [PATCH 14/44] default to no implementation on pipe for pleasing win32 --- llarp/ev/ev.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/llarp/ev/ev.hpp b/llarp/ev/ev.hpp index 1f610c100..4d351292e 100644 --- a/llarp/ev/ev.hpp +++ b/llarp/ev/ev.hpp @@ -775,7 +775,10 @@ struct llarp_ev_loop bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* addr) = 0; virtual bool - add_pipe(llarp_ev_pkt_pipe* p) = 0; + add_pipe(llarp_ev_pkt_pipe*) + { + return false; + } /// register event listener virtual bool From 647f874d0f44751cac6a990633e46314eae42fbf Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 23 Aug 2019 16:49:12 -0400 Subject: [PATCH 15/44] ignore test on win32 --- test/link/test_llarp_link.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index 23316cc05..21f197118 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -171,6 +171,9 @@ struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium > TEST_F(LinkLayerTest, TestIWP) { +#ifdef WIN32 + GTEST_SKIP(); +#else Alice.link = iwp::NewInboundLink( Alice.encryptionKey, [&]() -> const RouterContact& { return Alice.GetRC(); }, @@ -256,6 +259,7 @@ TEST_F(LinkLayerTest, TestIWP) RunMainloop(); ASSERT_TRUE(Bob.gotLIM); +#endif }; TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) From 3f6f636bbff9de30918c66141e3b6e6c2da4ed82 Mon Sep 17 00:00:00 2001 From: Rick V Date: Wed, 14 Aug 2019 17:40:17 -0500 Subject: [PATCH 16/44] reeeee --- cmake/win32.cmake | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cmake/win32.cmake b/cmake/win32.cmake index 52956bd99..dc8040722 100644 --- a/cmake/win32.cmake +++ b/cmake/win32.cmake @@ -21,9 +21,7 @@ if(NOT MSVC_VERSION) # GNU ld sees fit to merge *all* the .ident sections in object files # to .r[o]data section one after the other! add_compile_options(-fno-ident -Wa,-mbig-obj) - find_library(shlwapi_lib shlwapi) - find_library(dbghelp_lib dbghelp) - link_libraries( ${shlwapi_lib} ${dbghelp_lib} ) + link_libraries( -lshlwapi -ldbghelp ) add_definitions(-DWINVER=0x0500 -D_WIN32_WINNT=0x0500) # Wait a minute, if we're not Microsoft C++, nor a Clang paired with Microsoft C++, # then the only possible option has to be GNU or a GNU-linked Clang! @@ -35,10 +33,7 @@ endif() get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c ABSOLUTE) get_filename_component(EV_SRC "llarp/ev/ev_win32.cpp" ABSOLUTE) add_definitions(-DWIN32_LEAN_AND_MEAN -DWIN32 -DWINVER=0x0500) - -find_library(ws2_32_lib ws2_32) -find_library(iphlpapi_lib iphlpapi) -set(EXE_LIBS ${STATIC_LIB} ${FS_LIB} ${ws2_32_lib} ${iphlpapi_lib}) +set(EXE_LIBS ${STATIC_LIB} ${FS_LIB} ws2_32 iphlpapi) if(RELEASE_MOTTO) add_definitions(-DLLARP_RELEASE_MOTTO="${RELEASE_MOTTO}") From 447c4e6012f63a785eda2a7ea99cdf82af9f5435 Mon Sep 17 00:00:00 2001 From: Rick V Date: Wed, 14 Aug 2019 17:45:49 -0500 Subject: [PATCH 17/44] header got stripped --- llarp/win32/win32_inet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/llarp/win32/win32_inet.c b/llarp/win32/win32_inet.c index 6dbe35938..be88293d9 100644 --- a/llarp/win32/win32_inet.c +++ b/llarp/win32/win32_inet.c @@ -10,6 +10,7 @@ // these need to be in a specific order #include +#include #include #include #include From 50d4b4b40ce90008bd9b971a0a2c979468dcd532 Mon Sep 17 00:00:00 2001 From: Rick V Date: Thu, 15 Aug 2019 01:27:40 -0500 Subject: [PATCH 18/44] fix log colours on old win32 platforms --- llarp/util/win32_logger.cpp | 59 +++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/llarp/util/win32_logger.cpp b/llarp/util/win32_logger.cpp index 847864398..df3b507ed 100644 --- a/llarp/util/win32_logger.cpp +++ b/llarp/util/win32_logger.cpp @@ -26,6 +26,45 @@ namespace llarp void Win32LogStream::PreLog(std::stringstream& ss, LogLevel lvl, const char* fname, int lineno, const std::string& nodename) const + { + if(!isConsoleModern) + { + switch(lvl) + { + case eLogNone: + break; + case eLogDebug: + ss << "[DBG] "; + break; + case eLogInfo: + ss << "[NFO] "; + break; + case eLogWarn: + ss << "[WRN] "; + break; + case eLogError: + ss << "[ERR] "; + break; + } + ss << "[" << nodename << "]" + << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname + << ":" << lineno << "\t"; + } + else + OStreamLogStream::PreLog(ss, lvl, fname, lineno, nodename); + } + + void + Win32LogStream::PostLog(std::stringstream& ss) const + { + if(!isConsoleModern) + ss << std::endl; + else + OStreamLogStream::PostLog(ss); + } + + void + Win32LogStream::Print(LogLevel lvl, const char*, const std::string& msg) { if(!isConsoleModern) { @@ -39,46 +78,34 @@ namespace llarp SetConsoleTextAttribute(fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); // low white on black - ss << "[DBG] "; break; case eLogInfo: SetConsoleTextAttribute( fd1, FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); // high white on black - ss << "[NFO] "; break; case eLogWarn: SetConsoleTextAttribute(fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); // bright yellow - ss << "[WRN] "; break; case eLogError: SetConsoleTextAttribute( fd1, FOREGROUND_RED | FOREGROUND_INTENSITY); // bright red - ss << "[ERR] "; break; } - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname - << ":" << lineno << "\t"; } - else - OStreamLogStream::PreLog(ss, lvl, fname, lineno, nodename); - } + + m_Out << msg << std::flush; - void - Win32LogStream::PostLog(std::stringstream& ss) const - { if(!isConsoleModern) { + ss << std::endl; SetConsoleTextAttribute( fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - ss << std::endl; } - else - OStreamLogStream::PostLog(ss); } + } // namespace llarp #endif From 2a7d2d9e025f91294af140596739ab67051b281f Mon Sep 17 00:00:00 2001 From: Rick V Date: Thu, 15 Aug 2019 03:08:39 -0500 Subject: [PATCH 19/44] add new and improved 32-bit lokinet-rcutil to install pkg --- win32-setup/lokinet-win32.iss | 1 + 1 file changed, 1 insertion(+) diff --git a/win32-setup/lokinet-win32.iss b/win32-setup/lokinet-win32.iss index 1e3c589cb..586ccd071 100644 --- a/win32-setup/lokinet-win32.iss +++ b/win32-setup/lokinet-win32.iss @@ -89,6 +89,7 @@ Source: "{#DevPath}ui-win32\bin\release\lokinetui.pdb"; DestDir: "{app}"; Flags: #endif ; eh, might as well ship the 32-bit port of everything else Source: "{#DevPath}build\testAll.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#DevPath}build\lokinet-rcutil.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#DevPath}LICENSE"; DestDir: "{app}"; Flags: ignoreversion ; delet this after finishing setup, we only need it to extract the drivers ; and download an initial RC. The UI has its own bootstrap built-in! From 2000826a357ea48e71c972e8161032556aabcf02 Mon Sep 17 00:00:00 2001 From: Rick V Date: Thu, 15 Aug 2019 03:11:18 -0500 Subject: [PATCH 20/44] override print --- llarp/util/win32_logger.cpp | 3 +-- llarp/util/win32_logger.hpp | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/llarp/util/win32_logger.cpp b/llarp/util/win32_logger.cpp index df3b507ed..ba95ac895 100644 --- a/llarp/util/win32_logger.cpp +++ b/llarp/util/win32_logger.cpp @@ -7,7 +7,7 @@ static short old_attrs; namespace llarp { - Win32LogStream::Win32LogStream(std::ostream& out) : OStreamLogStream(out) + Win32LogStream::Win32LogStream(std::ostream& out) : OStreamLogStream(out), m_Out(out) { // Attempt to use ANSI escapes directly // if the modern console is active. @@ -101,7 +101,6 @@ namespace llarp if(!isConsoleModern) { - ss << std::endl; SetConsoleTextAttribute( fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } diff --git a/llarp/util/win32_logger.hpp b/llarp/util/win32_logger.hpp index 75add272e..7a329351b 100644 --- a/llarp/util/win32_logger.hpp +++ b/llarp/util/win32_logger.hpp @@ -19,9 +19,16 @@ namespace llarp PostLog(std::stringstream& s) const override; void Tick(llarp_time_t) override{}; + + void + Print(LogLevel lvl, const char*, const std::string& msg) override; + + private: + std::ostream& m_Out; bool isConsoleModern = true; // qol fix so oldfag clients don't see ugly escapes + HANDLE fd1 = GetStdHandle(STD_OUTPUT_HANDLE); }; } // namespace llarp From 55612bc032bce760752eb2f34d47f6558536bedd Mon Sep 17 00:00:00 2001 From: Rick V Date: Thu, 15 Aug 2019 03:41:04 -0500 Subject: [PATCH 21/44] ok use clang-format v8 --- llarp/util/win32_logger.cpp | 7 ++++--- llarp/util/win32_logger.hpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/llarp/util/win32_logger.cpp b/llarp/util/win32_logger.cpp index ba95ac895..2f9fd4afe 100644 --- a/llarp/util/win32_logger.cpp +++ b/llarp/util/win32_logger.cpp @@ -7,7 +7,8 @@ static short old_attrs; namespace llarp { - Win32LogStream::Win32LogStream(std::ostream& out) : OStreamLogStream(out), m_Out(out) + Win32LogStream::Win32LogStream(std::ostream& out) + : OStreamLogStream(out), m_Out(out) { // Attempt to use ANSI escapes directly // if the modern console is active. @@ -96,8 +97,8 @@ namespace llarp break; } } - - m_Out << msg << std::flush; + + m_Out << msg << std::flush; if(!isConsoleModern) { diff --git a/llarp/util/win32_logger.hpp b/llarp/util/win32_logger.hpp index 7a329351b..3a9cb6342 100644 --- a/llarp/util/win32_logger.hpp +++ b/llarp/util/win32_logger.hpp @@ -19,7 +19,7 @@ namespace llarp PostLog(std::stringstream& s) const override; void Tick(llarp_time_t) override{}; - + void Print(LogLevel lvl, const char*, const std::string& msg) override; From 6a48a3b402547612ef0e2097c402229d8e1f6f36 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Aug 2019 07:16:46 -0400 Subject: [PATCH 22/44] code review fixes: * use std::unordered_set * use default for ctor/dtor * don't crash on short packet with nack --- llarp/config/config.cpp | 4 ++-- llarp/config/config.hpp | 3 ++- llarp/iwp/message_buffer.cpp | 16 +++------------- llarp/iwp/message_buffer.hpp | 5 +++-- llarp/iwp/session.cpp | 9 +++++---- llarp/iwp/session.hpp | 2 +- 6 files changed, 16 insertions(+), 23 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index a8b67849e..75a193ac3 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -204,7 +204,7 @@ namespace llarp { uint16_t proto = 0; - std::set< std::string > parsed_opts; + std::unordered_set< std::string > parsed_opts; std::string v = tostr(val); std::string::size_type idx; do @@ -220,7 +220,7 @@ namespace llarp parsed_opts.insert(v); } } while(idx != std::string::npos); - std::set< std::string > opts; + std::unordered_set< std::string > opts; /// for each option for(const auto &item : parsed_opts) { diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 56f199d45..950c8a75f 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace llarp { @@ -195,7 +196,7 @@ namespace llarp static constexpr int Port = 2; static constexpr int Options = 3; - using ServerOptions = std::set< std::string >; + using ServerOptions = std::unordered_set< std::string >; using LinkInfo = std::tuple< std::string, int, uint16_t, ServerOptions >; using Links = std::vector< LinkInfo >; diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp index 76d7240d7..af73c23ce 100644 --- a/llarp/iwp/message_buffer.cpp +++ b/llarp/iwp/message_buffer.cpp @@ -5,10 +5,6 @@ namespace llarp { namespace iwp { - OutboundMessage::OutboundMessage() : m_Size{0} - { - } - OutboundMessage::OutboundMessage(uint64_t msgid, const llarp_buffer_t &pkt, ILinkSession::CompletionHandler handler) : m_Size{(uint16_t)std::min(pkt.sz, MAX_LINK_MSG_SIZE)} @@ -17,6 +13,8 @@ namespace llarp { m_Data.Zero(); std::copy_n(pkt.base, m_Size, m_Data.begin()); + const llarp_buffer_t buf{m_Data.data(), m_Size}; + CryptoManager::instance()->shorthash(digest, buf); } std::vector< byte_t > @@ -26,11 +24,7 @@ namespace llarp LLARP_PROTO_VERSION, Command::eXMIT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; htobe16buf(xmit.data() + 2, m_Size); htobe64buf(xmit.data() + 4, m_MsgID); - const llarp_buffer_t buf{m_Data.data(), m_Size}; - ShortHash H; - CryptoManager::instance()->shorthash(H, buf); - std::copy(H.begin(), H.end(), std::back_inserter(xmit)); - LogDebug("xmit H=", H.ToHex()); + std::copy(digest.begin(), digest.end(), std::back_inserter(xmit)); return xmit; } @@ -101,10 +95,6 @@ namespace llarp return true; } - InboundMessage::InboundMessage() : m_Size{0} - { - } - InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h) : m_Digset{std::move(h)}, m_Size{sz}, m_MsgID{msgid} { diff --git a/llarp/iwp/message_buffer.hpp b/llarp/iwp/message_buffer.hpp index 8082fb706..ded62a3a4 100644 --- a/llarp/iwp/message_buffer.hpp +++ b/llarp/iwp/message_buffer.hpp @@ -31,7 +31,7 @@ namespace llarp struct OutboundMessage { - OutboundMessage(); + OutboundMessage() = default; OutboundMessage(uint64_t msgid, const llarp_buffer_t &pkt, ILinkSession::CompletionHandler handler); @@ -41,6 +41,7 @@ namespace llarp std::bitset< MAX_LINK_MSG_SIZE / FragmentSize > m_Acks; ILinkSession::CompletionHandler m_Completed; llarp_time_t m_LastFlush = 0; + ShortHash digest; std::vector< byte_t > XMIT() const; @@ -64,7 +65,7 @@ namespace llarp struct InboundMessage { - InboundMessage(); + InboundMessage() = default; InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h); AlignedBuffer< MAX_LINK_MSG_SIZE > m_Data; diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 480c3da7e..235761b8d 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -33,10 +33,6 @@ namespace llarp GotLIM = util::memFn(&Session::GotInboundLIM, this); } - Session::~Session() - { - } - void Session::Send_LL(const llarp_buffer_t& pkt) { @@ -444,6 +440,11 @@ namespace llarp void Session::HandleNACK(std::vector< byte_t > data) { + if(data.size() < 10) + { + LogError("short nack from ", m_RemoteAddr); + return; + } uint64_t txid = bufbe64toh(data.data() + 2); LogDebug("got nack on ", txid, " from ", m_RemoteAddr); auto itr = m_TXMsgs.find(txid); diff --git a/llarp/iwp/session.hpp b/llarp/iwp/session.hpp index cb83494de..b9f598bf1 100644 --- a/llarp/iwp/session.hpp +++ b/llarp/iwp/session.hpp @@ -17,7 +17,7 @@ namespace llarp /// inbound session Session(LinkLayer* parent, Addr from); - ~Session(); + ~Session() = default; void Pump() override; From 94f853177603046717ba227b1f406c45e1b2b05a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Aug 2019 10:29:29 -0400 Subject: [PATCH 23/44] more fixups --- llarp/config/config.cpp | 19 ++++++++++++++++--- llarp/iwp/session.cpp | 15 +++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 75a193ac3..ca5f69b62 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -207,17 +207,30 @@ namespace llarp std::unordered_set< std::string > parsed_opts; std::string v = tostr(val); std::string::size_type idx; + static constexpr char delimiter = ','; + static const auto strip_spaces = [](const auto &begin, + const auto &end) -> std::string { + std::string val; + std::for_each(begin, end, [&val](const char &ch) { + // strip spaces + if(::isspace(ch) || ch == delimiter) + return; + val += ch; + }); + return val; + }; + do { - idx = v.find_first_of(','); + idx = v.find_first_of(delimiter); if(idx != std::string::npos) { - parsed_opts.insert(v.substr(0, idx)); + parsed_opts.emplace(strip_spaces(v.begin(), v.begin() + idx)); v = v.substr(idx + 1); } else { - parsed_opts.insert(v); + parsed_opts.insert(strip_spaces(v.begin(), v.end())); } } while(idx != std::string::npos); std::unordered_set< std::string > opts; diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 235761b8d..26499b6d6 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -416,25 +416,24 @@ namespace llarp { case Command::eXMIT: HandleXMIT(std::move(result)); - break; + return; case Command::eDATA: HandleDATA(std::move(result)); - break; + return; case Command::eACKS: HandleACKS(std::move(result)); - break; + return; case Command::ePING: HandlePING(std::move(result)); - break; + return; case Command::eNACK: HandleNACK(std::move(result)); - break; + return; case Command::eCLOS: HandleCLOS(std::move(result)); - break; - default: - LogError("invalid command ", int(result[1])); + return; } + LogError("invalid command ", int(result[1])); } void From 7d39f84ef3d4528d8f3488c4088f61bc4a546aa8 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 26 Aug 2019 23:10:48 +0000 Subject: [PATCH 24/44] Partial fixes for shadow --- CMakeLists.txt | 6 +++--- Makefile | 9 +++++---- cmake/shadow.cmake | 2 +- contrib/shadow/genconf.py | 2 +- llarp/testnet.c | 2 +- .../abseil-cpp/absl/debugging/internal/vdso_support.cc | 6 +++++- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3882731db..8842f0ded 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,9 @@ endif(WITH_SHELLHOOKS) add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}) +# Always build PIC +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(ABSEIL_DIR vendor/abseil-cpp) add_subdirectory(vendor/gtest) @@ -117,9 +120,6 @@ add_subdirectory(vendor/cxxopts) add_subdirectory(vendor/nlohmann) include_directories(SYSTEM vendor/cxxopts/include) -# Always build PIC -set(CMAKE_POSITION_INDEPENDENT_CODE ON) - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wno-unknown-warning-option) endif() diff --git a/Makefile b/Makefile index 274d530e0..f82077ddb 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,8 @@ CXX ?= c++ BUILD_TYPE ?= Debug -PYTHON ?= python3 +PYTHON ?= python +PYTHON3 ?= python3 SETCAP ?= which setcap && setcap cap_net_admin,cap_net_bind_service=+eip @@ -165,7 +166,7 @@ shadow-build: shadow-configure $(MAKE) -C $(BUILD_ROOT) shadow-run: shadow-build - $(PYTHON) $(REPO)/contrib/shadow/genconf.py $(SHADOW_CONFIG) + $(PYTHON3) $(REPO)/contrib/shadow/genconf.py $(SHADOW_CONFIG) cp $(SHADOW_PLUGIN) $(REPO)/libshadow-plugin-lokinet.so $(SHADOW_BIN) $(SHADOW_OPTS) $(SHADOW_CONFIG) | $(SHADOW_PARSE) @@ -187,7 +188,7 @@ testnet-build: testnet-configure testnet: cp $(EXE) $(TESTNET_EXE) mkdir -p $(TESTNET_ROOT) - $(PYTHON) $(REPO)/contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --ifname=$(TESTNET_IFNAME) --baseport=$(TESTNET_BASEPORT) --ip=$(TESTNET_IP) --netid=$(TESTNET_NETID) + $(PYTHON3) $(REPO)/contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --ifname=$(TESTNET_IFNAME) --baseport=$(TESTNET_BASEPORT) --ip=$(TESTNET_IP) --netid=$(TESTNET_NETID) LLARP_DEBUG=$(TESTNET_DEBUG) supervisord -n -d $(TESTNET_ROOT) -l $(TESTNET_LOG) -c $(TESTNET_CONF) $(TEST_EXE): debug @@ -279,7 +280,7 @@ docker-kubernetes: docker build -f docker/loki-svc-kubernetes.Dockerfile . install-pylokinet: - cd $(REPO)/contrib/py/pylokinet && $(PYTHON) setup.py install + cd $(REPO)/contrib/py/pylokinet && $(PYTHON3) setup.py install kubernetes-install: install install-pylokinet diff --git a/cmake/shadow.cmake b/cmake/shadow.cmake index 6bdd95bb1..deed362b1 100644 --- a/cmake/shadow.cmake +++ b/cmake/shadow.cmake @@ -14,5 +14,5 @@ include_directories(${CMAKE_MODULE_PATH}) include(ShadowTools) add_compile_options(-fno-inline -fno-strict-aliasing ) add_definitions(-DTESTNET=1) -add_definitions(-DSHADOW_TESTNET) +add_definitions(-DLOKINET_SHADOW) include_directories(${SHADOW_ROOT}/include) diff --git a/contrib/shadow/genconf.py b/contrib/shadow/genconf.py index 8cc6bf3b2..0a4c0794a 100644 --- a/contrib/shadow/genconf.py +++ b/contrib/shadow/genconf.py @@ -13,7 +13,7 @@ def getSetting(s, name, fallback): return name in s and s[name] or fallback shadowRoot = getSetting(os.environ, "SHADOW_ROOT", os.path.join(os.environ['HOME'], '.shadow')) -libpath = 'libshadow-plugin-lokinet-shared.so' +libpath = 'libshadow-plugin-lokinet.so' def nodeconf(conf, baseDir, name, ifname=None, port=None): diff --git a/llarp/testnet.c b/llarp/testnet.c index 60f501489..7825445be 100644 --- a/llarp/testnet.c +++ b/llarp/testnet.c @@ -1,4 +1,4 @@ -#ifdef SHADOW_TESTNET +#ifdef LOKINET_SHADOW #include /** insert shadow test network specific code here */ diff --git a/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc b/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc index 85b52bc8f..29162622f 100644 --- a/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc +++ b/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc @@ -184,7 +184,11 @@ int GetCPU() { // global constructors. static class VDSOInitHelper { public: - VDSOInitHelper() { VDSOSupport::Init(); } + VDSOInitHelper() { +#ifndef LOKINET_SHADOW + VDSOSupport::Init(); +#endif + } } vdso_init_helper; } // namespace debugging_internal From 70937ab503abe6cbc235415a65eb56a0fca5afea Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 27 Aug 2019 00:29:17 +0100 Subject: [PATCH 25/44] Fix docker-compose isolated network --- docker/compose/bootstrap.Dockerfile | 2 + docker/compose/bootstrap.ini | 21 +---------- docker/compose/client.Dockerfile | 6 +++ docker/compose/client.ini | 52 ++++++++++++++++++++++++++ docker/compose/docker-compose.yml | 30 ++++++++++++++- docker/compose/router.ini | 12 +----- llarp/config/config.cpp | 40 +++++++++++++++----- llarp/config/config.hpp | 29 +++++++------- llarp/metrics/metrictank_publisher.cpp | 3 +- llarp/router/router.cpp | 7 +++- llarp/router_contact.cpp | 33 +++++++++++++--- llarp/router_contact.hpp | 4 +- llarp/router_id.cpp | 2 + llarp/router_id.hpp | 2 +- test/link/test_llarp_link.cpp | 12 +++--- 15 files changed, 183 insertions(+), 72 deletions(-) create mode 100644 docker/compose/client.Dockerfile create mode 100644 docker/compose/client.ini diff --git a/docker/compose/bootstrap.Dockerfile b/docker/compose/bootstrap.Dockerfile index cbefe5925..070e27802 100644 --- a/docker/compose/bootstrap.Dockerfile +++ b/docker/compose/bootstrap.Dockerfile @@ -1,5 +1,7 @@ FROM compose-base:latest +ENV LOKINET_NETID=docker + COPY ./docker/compose/bootstrap.ini /root/.lokinet/lokinet.ini CMD ["/lokinet"] diff --git a/docker/compose/bootstrap.ini b/docker/compose/bootstrap.ini index 6b01cb265..b592e0dc4 100644 --- a/docker/compose/bootstrap.ini +++ b/docker/compose/bootstrap.ini @@ -1,7 +1,3 @@ -# this configuration was auto generated with 'sane' defaults -# change these values as desired - - [router] # number of crypto worker threads threads=4 @@ -13,18 +9,13 @@ transport-privkey=/root/.lokinet/transport.private ident-privkey=/root/.lokinet/identity.private # encryption key for onion routing encryption-privkey=/root/.lokinet/encryption.private +block-bogons=false # uncomment following line to set router nickname to 'lokinet' -#nickname=lokinet - +nickname=bootstrap [logging] level=info -# uncomment for logging to file -#type=file -#file=/path/to/logfile -# uncomment for syslog logging -#type=syslog [metrics] json-metrics-path=/root/.lokinet/metrics.json @@ -32,9 +23,6 @@ json-metrics-path=/root/.lokinet/metrics.json # admin api (disabled by default) [api] enabled=true -#authkey=insertpubkey1here -#authkey=insertpubkey2here -#authkey=insertpubkey3here bind=127.0.0.1:1190 # system settings for privileges and such @@ -58,17 +46,12 @@ dir=/netdb [lokid] enabled=false jsonrpc=127.0.0.1:22023 -#service-node-seed=/path/to/servicenode/seed # network settings [network] profiles=/root/.lokinet/profiles.dat enabled=true exit=false -#exit-blacklist=tcp:25 -#exit-whitelist=tcp:* -#exit-whitelist=udp:* -ifaddr=10.200.0.1/8 ifname=loki-docker0 # ROUTERS ONLY: publish network interfaces for handling inbound traffic diff --git a/docker/compose/client.Dockerfile b/docker/compose/client.Dockerfile new file mode 100644 index 000000000..a209c5330 --- /dev/null +++ b/docker/compose/client.Dockerfile @@ -0,0 +1,6 @@ +FROM compose-base:latest + +COPY ./docker/compose/client.ini /root/.lokinet/lokinet.ini + +CMD ["/lokinet"] +EXPOSE 1090/udp 1190/tcp diff --git a/docker/compose/client.ini b/docker/compose/client.ini new file mode 100644 index 000000000..8b98efdb7 --- /dev/null +++ b/docker/compose/client.ini @@ -0,0 +1,52 @@ +[router] +# number of crypto worker threads +threads=4 +# path to store signed RC +contact-file=/root/.lokinet/self.signed +# path to store transport private key +transport-privkey=/root/.lokinet/transport.private +# path to store identity signing key +ident-privkey=/root/.lokinet/identity.private +# encryption key for onion routing +encryption-privkey=/root/.lokinet/encryption.private +block-bogons=false + +[logging] +level=info + +[metrics] +json-metrics-path=/root/.lokinet/metrics.json + +# admin api (disabled by default) +[api] +enabled=true +bind=127.0.0.1:1190 + +# system settings for privileges and such +[system] +user=lokinet +group=lokinet +pidfile=/root/.lokinet/lokinet.pid + +# dns provider configuration section +[dns] +# resolver +upstream=1.1.1.1 +bind=127.0.0.1:53 + +# network database settings block +[netdb] +# directory for network database skiplist storage +dir=/netdb + +# lokid settings (disabled by default) +[lokid] +enabled=false +jsonrpc=127.0.0.1:22023 + +# network settings +[network] +profiles=/root/.lokinet/profiles.dat +enabled=true +exit=false +ifname=loki-docker0 diff --git a/docker/compose/docker-compose.yml b/docker/compose/docker-compose.yml index d2983e1e8..42fd6748c 100644 --- a/docker/compose/docker-compose.yml +++ b/docker/compose/docker-compose.yml @@ -12,10 +12,8 @@ services: ports: - target: 1090 protocol: udp - mode: host - target: 1190 protocol: tcp - mode: host volumes: - bootstrap-dir:/root/.lokinet/ environment: @@ -48,6 +46,34 @@ services: networks: testing_net: + client: + depends_on: + - bootstrap-router + build: + context: . + dockerfile: docker/compose/router.Dockerfile + image: router + devices: + - "/dev/net/tun:/dev/net/tun" + ports: + - target: 1090 + protocol: udp + mode: host + - target: 1190 + protocol: tcp + mode: host + - target: 53 + protocol: tcp + mode: host + cap_add: + - NET_ADMIN + volumes: + - bootstrap-dir:/bootstrap/ + environment: + - LOKINET_NETID=docker + networks: + testing_net: + volumes: bootstrap-dir: diff --git a/docker/compose/router.ini b/docker/compose/router.ini index 873bb617c..f6a620948 100644 --- a/docker/compose/router.ini +++ b/docker/compose/router.ini @@ -1,7 +1,3 @@ -# this configuration was auto generated with 'sane' defaults -# change these values as desired - - [router] # number of crypto worker threads threads=4 @@ -13,6 +9,7 @@ transport-privkey=/root/.lokinet/transport.private ident-privkey=/root/.lokinet/identity.private # encryption key for onion routing encryption-privkey=/root/.lokinet/encryption.private +block-bogons=false # uncomment following line to set router nickname to 'lokinet' #nickname=lokinet @@ -32,9 +29,6 @@ json-metrics-path=/root/.lokinet/metrics.json # admin api (disabled by default) [api] enabled=true -#authkey=insertpubkey1here -#authkey=insertpubkey2here -#authkey=insertpubkey3here bind=127.0.0.1:1190 # system settings for privileges and such @@ -64,16 +58,12 @@ add-node=/bootstrap/self.signed [lokid] enabled=false jsonrpc=127.0.0.1:22023 -#service-node-seed=/path/to/servicenode/seed # network settings [network] profiles=/root/.lokinet/profiles.dat enabled=true exit=false -#exit-blacklist=tcp:25 -#exit-whitelist=tcp:* -#exit-whitelist=udp:* ifaddr=10.200.0.1/8 ifname=loki-docker0 diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index b06ec79dd..d8edb168c 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -4,9 +4,10 @@ #include #include #include +#include #include -#include #include +#include #include #include #include @@ -31,6 +32,20 @@ namespace llarp return std::atoi(str.c_str()); } + absl::optional< bool > + setOptBool(string_view val) + { + if(IsTrueValue(val)) + { + return true; + } + else if(IsFalseValue(val)) + { + return false; + } + return {}; + } + void RouterConfig::fromSection(string_view key, string_view val) { @@ -139,6 +154,10 @@ namespace llarp LogDebug("set to use ", m_numNetThreads, " net threads"); } } + if(key == "block-bogons") + { + m_blockBogons = setOptBool(val); + } } void @@ -146,14 +165,7 @@ namespace llarp { if(key == "profiling") { - if(IsTrueValue(val)) - { - m_enableProfiling.emplace(true); - } - else if(IsFalseValue(val)) - { - m_enableProfiling.emplace(false); - } + m_enableProfiling = setOptBool(val); } else if(key == "profiles") { @@ -398,7 +410,9 @@ namespace llarp }; if(c.VisitSection(name.c_str(), visitor)) + { return ret; + } return {}; } @@ -465,7 +479,7 @@ llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, return false; } - std::string basepath = ""; + std::string basepath; if(basedir) { basepath = basedir; @@ -641,10 +655,14 @@ llarp_ensure_router_config(std::ofstream &f, std::string basepath) // get ifname std::string ifname; if(llarp::GetBestNetIF(ifname, AF_INET)) + { f << ifname << "=1090\n"; + } else + { f << "# could not autodetect network interface\n" << "#eth0=1090\n"; + } f << std::endl; } @@ -658,7 +676,9 @@ llarp_ensure_client_config(std::ofstream &f, std::string basepath) auto stream = llarp::util::OpenFileStream< std::ofstream >( snappExample_fpath, std::ios::binary); if(!stream) + { return false; + } auto &example_f = stream.value(); if(example_f.is_open()) { diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 58e5cc4a5..328475fb8 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -111,6 +111,8 @@ namespace llarp // long term identity key std::string m_identKeyfile = "identity.key"; + absl::optional< bool > m_blockBogons; + bool m_publicOverride = false; struct sockaddr_in m_ip4addr; AddressInfo m_addrInfo; @@ -120,19 +122,20 @@ namespace llarp public: // clang-format off - size_t minConnectedRouters() const { return fromEnv(m_minConnectedRouters, "MIN_CONNECTED_ROUTERS"); } - size_t maxConnectedRouters() const { return fromEnv(m_maxConnectedRouters, "MAX_CONNECTED_ROUTERS"); } - std::string encryptionKeyfile() const { return fromEnv(m_encryptionKeyfile, "ENCRYPTION_KEYFILE"); } - std::string ourRcFile() const { return fromEnv(m_ourRcFile, "OUR_RC_FILE"); } - std::string transportKeyfile() const { return fromEnv(m_transportKeyfile, "TRANSPORT_KEYFILE"); } - std::string identKeyfile() const { return fromEnv(m_identKeyfile, "IDENT_KEYFILE"); } - std::string netId() const { return fromEnv(m_netId, "NETID"); } - std::string nickname() const { return fromEnv(m_nickname, "NICKNAME"); } - bool publicOverride() const { return fromEnv(m_publicOverride, "PUBLIC_OVERRIDE"); } - const struct sockaddr_in& ip4addr() const { return m_ip4addr; } - const AddressInfo& addrInfo() const { return m_addrInfo; } - int workerThreads() const { return fromEnv(m_workerThreads, "WORKER_THREADS"); } - int numNetThreads() const { return fromEnv(m_numNetThreads, "NUM_NET_THREADS"); } + size_t minConnectedRouters() const { return fromEnv(m_minConnectedRouters, "MIN_CONNECTED_ROUTERS"); } + size_t maxConnectedRouters() const { return fromEnv(m_maxConnectedRouters, "MAX_CONNECTED_ROUTERS"); } + std::string encryptionKeyfile() const { return fromEnv(m_encryptionKeyfile, "ENCRYPTION_KEYFILE"); } + std::string ourRcFile() const { return fromEnv(m_ourRcFile, "OUR_RC_FILE"); } + std::string transportKeyfile() const { return fromEnv(m_transportKeyfile, "TRANSPORT_KEYFILE"); } + std::string identKeyfile() const { return fromEnv(m_identKeyfile, "IDENT_KEYFILE"); } + std::string netId() const { return fromEnv(m_netId, "NETID"); } + std::string nickname() const { return fromEnv(m_nickname, "NICKNAME"); } + bool publicOverride() const { return fromEnv(m_publicOverride, "PUBLIC_OVERRIDE"); } + const struct sockaddr_in& ip4addr() const { return m_ip4addr; } + const AddressInfo& addrInfo() const { return m_addrInfo; } + int workerThreads() const { return fromEnv(m_workerThreads, "WORKER_THREADS"); } + int numNetThreads() const { return fromEnv(m_numNetThreads, "NUM_NET_THREADS"); } + absl::optional< bool > blockBogons() const { return fromEnv(m_blockBogons, "BLOCK_BOGONS"); } // clang-format on void diff --git a/llarp/metrics/metrictank_publisher.cpp b/llarp/metrics/metrictank_publisher.cpp index ab9a98597..751d2cecb 100644 --- a/llarp/metrics/metrictank_publisher.cpp +++ b/llarp/metrics/metrictank_publisher.cpp @@ -205,7 +205,8 @@ namespace llarp publishData(const std::vector< std::string > &toSend, const std::string &host, short port) { - struct addrinfo hints, *addrs; + struct addrinfo hints; + struct addrinfo *addrs; bzero(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 22841d17f..e4fef1523 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -384,6 +384,11 @@ namespace llarp publicOverride = conf->router.publicOverride(); ip4addr = conf->router.ip4addr(); + if(!conf->router.blockBogons().value_or(true)) + { + RouterContact::BlockBogons = false; + } + // Lokid Config usingSNSeed = conf->lokid.usingSNSeed; ident_keyfile = conf->lokid.ident_keyfile; @@ -851,7 +856,7 @@ namespace llarp ai.ip = *publicAddr.addr6(); ai.port = publicAddr.port(); } - if(IsBogon(ai.ip)) + if(RouterContact::BlockBogons && IsBogon(ai.ip)) return; _rc.addrs.push_back(ai); if(ExitEnabled()) diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 469700c52..8930a609a 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -23,7 +23,7 @@ namespace llarp return defaultID; } - bool RouterContact::IgnoreBogons = false; + bool RouterContact::BlockBogons = true; #ifdef TESTNET // 1 minute for testnet @@ -37,7 +37,7 @@ namespace llarp /// an RC inserted long enough ago (30 min) is considered stale and is removed llarp_time_t RouterContact::StaleInsertionAge = 30 * 60 * 1000; - NetID::NetID(const byte_t *val) : AlignedBuffer< 8 >() + NetID::NetID(const byte_t *val) { size_t len = strnlen(reinterpret_cast< const char * >(val), size()); std::copy(val, val + len, begin()); @@ -67,6 +67,7 @@ namespace llarp llarp_buffer_t strbuf; if(!bencode_read_string(buf, &strbuf)) return false; + if(strbuf.sz > size()) return false; @@ -106,13 +107,17 @@ namespace llarp return false; std::string nick = Nick(); - if(nick.size()) + if(!nick.empty()) { /* write nickname */ if(!bencode_write_bytestring(buf, "n", 1)) + { return false; + } if(!bencode_write_bytestring(buf, nick.c_str(), nick.size())) + { return false; + } } /* write encryption pubkey */ @@ -167,7 +172,9 @@ namespace llarp {"addresses", addrs}}; if(HasNick()) + { obj["nickname"] = Nick(); + } return obj; } @@ -189,9 +196,13 @@ namespace llarp { llarp_buffer_t strbuf; if(!bencode_read_string(buf, &strbuf)) + { return false; - if(strbuf.sz > nickname.size()) + } + if(strbuf.sz > llarp::AlignedBuffer< (32) >::size()) + { return false; + } nickname.Zero(); std::copy(strbuf.base, strbuf.base + strbuf.sz, nickname.begin()); return true; @@ -218,7 +229,7 @@ namespace llarp bool RouterContact::IsPublicRouter() const { - return addrs.size() > 0; + return !addrs.empty(); } bool @@ -277,7 +288,9 @@ namespace llarp signature.Zero(); last_updated = time_now_ms(); if(!BEncode(&buf)) + { return false; + } buf.sz = buf.cur - buf.base; buf.cur = buf.base; return CryptoManager::instance()->sign(signature, secretkey, buf); @@ -303,7 +316,7 @@ namespace llarp } for(const auto &a : addrs) { - if(IsBogon(a.ip) && !IgnoreBogons) + if(IsBogon(a.ip) && BlockBogons) { llarp::LogError("invalid address info: ", a); return false; @@ -349,17 +362,23 @@ namespace llarp std::array< byte_t, MAX_RC_SIZE > tmp; llarp_buffer_t buf(tmp); if(!BEncode(&buf)) + { return false; + } buf.sz = buf.cur - buf.base; buf.cur = buf.base; const fs::path fpath = std::string(fname); /* */ auto optional_f = llarp::util::OpenFileStream< std::ofstream >(fpath, std::ios::binary); if(!optional_f) + { return false; + } auto &f = optional_f.value(); if(!f.is_open()) + { return false; + } f.write((char *)buf.base, buf.sz); return true; } @@ -379,7 +398,9 @@ namespace llarp f.seekg(0, std::ios::end); auto l = f.tellg(); if(l > static_cast< std::streamoff >(sizeof tmp)) + { return false; + } f.seekg(0, std::ios::beg); f.read((char *)tmp.data(), l); return BDecode(&buf); diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 8ec3730da..280900335 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -67,7 +67,7 @@ namespace llarp struct RouterContact { /// for unit tests - static bool IgnoreBogons; + static bool BlockBogons; static llarp_time_t Lifetime; static llarp_time_t UpdateInterval; @@ -144,7 +144,7 @@ namespace llarp bool IsExit() const { - return exits.size() > 0; + return !exits.empty(); } bool diff --git a/llarp/router_id.cpp b/llarp/router_id.cpp index a48181131..81d1534e3 100644 --- a/llarp/router_id.cpp +++ b/llarp/router_id.cpp @@ -21,7 +21,9 @@ namespace llarp { auto pos = str.find(".snode"); if(pos == std::string::npos || pos == 0) + { return false; + } return Base32Decode(str.substr(0, pos), *this); } } // namespace llarp diff --git a/llarp/router_id.hpp b/llarp/router_id.hpp index dc48565a6..bdc643179 100644 --- a/llarp/router_id.hpp +++ b/llarp/router_id.hpp @@ -12,7 +12,7 @@ namespace llarp using Data = std::array< byte_t, SIZE >; - RouterID() : AlignedBuffer< SIZE >() + RouterID() { } diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index 3c83b5050..f69728de4 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -118,10 +118,10 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > void SetUp() { - oldRCLifetime = RouterContact::Lifetime; - RouterContact::IgnoreBogons = true; - RouterContact::Lifetime = 500; - netLoop = llarp_make_ev_loop(); + oldRCLifetime = RouterContact::Lifetime; + RouterContact::BlockBogons = false; + RouterContact::Lifetime = 500; + netLoop = llarp_make_ev_loop(); m_logic.reset(new Logic()); } @@ -132,8 +132,8 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > Bob.TearDown(); m_logic.reset(); netLoop.reset(); - RouterContact::IgnoreBogons = false; - RouterContact::Lifetime = oldRCLifetime; + RouterContact::BlockBogons = true; + RouterContact::Lifetime = oldRCLifetime; } static void From b3a975ff8ecf288074d5fafd10f2567475f111e1 Mon Sep 17 00:00:00 2001 From: Rick V Date: Mon, 26 Aug 2019 08:44:01 -0500 Subject: [PATCH 26/44] sun fix fix testing on sun --- cmake/unix.cmake | 4 ++-- crypto/include/sodium/crypto_int32.h | 3 ++- crypto/include/sodium/crypto_uint32.h | 3 ++- crypto/libntrup/src/ref/rq.c | 1 - llarp/net/net.h | 4 ++++ test/link/test_llarp_link.cpp | 2 +- vendor/gtest/googletest/src/gtest.cc | 2 +- 7 files changed, 12 insertions(+), 7 deletions(-) diff --git a/cmake/unix.cmake b/cmake/unix.cmake index e8f36a08c..d991e7a83 100644 --- a/cmake/unix.cmake +++ b/cmake/unix.cmake @@ -85,14 +85,12 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES " set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") find_library(FS_LIB NAMES c++fs c++experimental stdc++fs) - if(FS_LIB STREQUAL FS_LIB-NOTFOUND) add_subdirectory(vendor) include_directories("${CMAKE_CURRENT_LIST_DIR}/../vendor/cppbackport-master/lib") add_definitions(-DLOKINET_USE_CPPBACKPORT) set(FS_LIB cppbackport) endif() - set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-sunos.c) @@ -103,6 +101,8 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") include_directories("${CMAKE_CURRENT_LIST_DIR}/../vendor/cppbackport-master/lib") add_definitions(-DLOKINET_USE_CPPBACKPORT) set(FS_LIB cppbackport) + else() + set(FS_LIB stdc++fs) endif() else() message(FATAL_ERROR "Your operating system is not supported yet") diff --git a/crypto/include/sodium/crypto_int32.h b/crypto/include/sodium/crypto_int32.h index 334f570d3..9e5d7ff3b 100644 --- a/crypto/include/sodium/crypto_int32.h +++ b/crypto/include/sodium/crypto_int32.h @@ -1,2 +1,3 @@ +#pragma once #include -typedef int32_t crypto_int32; \ No newline at end of file +typedef int32_t crypto_int32; diff --git a/crypto/include/sodium/crypto_uint32.h b/crypto/include/sodium/crypto_uint32.h index 21bf085a4..0147a9867 100644 --- a/crypto/include/sodium/crypto_uint32.h +++ b/crypto/include/sodium/crypto_uint32.h @@ -1,2 +1,3 @@ +#pragma once #include -typedef uint32_t crypto_uint32; \ No newline at end of file +typedef uint32_t crypto_uint32; diff --git a/crypto/libntrup/src/ref/rq.c b/crypto/libntrup/src/ref/rq.c index 2832c912e..36c21ed7d 100644 --- a/crypto/libntrup/src/ref/rq.c +++ b/crypto/libntrup/src/ref/rq.c @@ -1,5 +1,4 @@ #include "params.h" -#include #include "rq.h" void diff --git a/llarp/net/net.h b/llarp/net/net.h index fbcb02411..248d3f3d6 100644 --- a/llarp/net/net.h +++ b/llarp/net/net.h @@ -26,6 +26,10 @@ typedef unsigned int in_addr_t; #include #endif +#ifndef __cplusplus +#include +#endif + #include bool diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index f69728de4..d1a3eb01a 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -62,7 +62,7 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > localLoopBack() { #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ - || (__APPLE__ && __MACH__) + || (__APPLE__ && __MACH__) || (__sun) return "lo0"; #else return "lo"; diff --git a/vendor/gtest/googletest/src/gtest.cc b/vendor/gtest/googletest/src/gtest.cc index 23b6e5f5d..fc9bb0ad0 100644 --- a/vendor/gtest/googletest/src/gtest.cc +++ b/vendor/gtest/googletest/src/gtest.cc @@ -4739,7 +4739,7 @@ void UnitTest::AddTestPartResult( ((defined(__clang__) || defined(__GNUC__)) && \ (defined(__x86_64__) || defined(__i386__))) // with clang/gcc we can achieve the same effect on x86 by invoking int3 - asm("int3"); + asm("int $0x3"); #else // Dereference nullptr through a volatile pointer to prevent the compiler // from removing. We use this rather than abort() or __builtin_trap() for From 60cf1be75765392a3fa2796dc7c19baf2d1c2a9a Mon Sep 17 00:00:00 2001 From: despair Date: Mon, 26 Aug 2019 20:40:37 -0500 Subject: [PATCH 27/44] fix cmake (restore crypto opts) --- CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8842f0ded..dde5b7850 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,13 +106,10 @@ if(WITH_SHELLHOOKS) add_definitions(-DENABLE_SHELLHOOKS) endif(WITH_SHELLHOOKS) -add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}) - # Always build PIC set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(ABSEIL_DIR vendor/abseil-cpp) - add_subdirectory(vendor/gtest) add_subdirectory(${ABSEIL_DIR}) include_directories(SYSTEM ${ABSEIL_DIR}) @@ -160,6 +157,8 @@ if(AMD_RYZEN_HACK AND USE_AVX2) message(WARNING "This option may be removed in a future release. Contact your computer manufacturer for updated ROMs or microcode patches.") endif(AMD_RYZEN_HACK AND USE_AVX2) +add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}) + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) From 6ade591a6e25d6bb5a3f5e8348f6008ddaa0c097 Mon Sep 17 00:00:00 2001 From: Rick V Date: Tue, 27 Aug 2019 07:05:37 -0500 Subject: [PATCH 28/44] add native build option --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dde5b7850..4e09a39b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ project(${PROJECT_NAME} C CXX) option(USE_AVX2 "enable avx2 code" ) option(USE_NETNS "enable networking namespace support. Linux only" ) option(AMD_RYZEN_HACK "hack for AMD Ryzen FPU bug (support FMA3 and FMA4 in FPU, but does not show in CPUID)" ) +option(NATIVE_BUILD "optimise for host system and FPU, may not be portable" ) if (NOT MSVC) option(STATIC_LINK_RUNTIME "link statically against compiler runtime, standard library and pthreads") endif() @@ -157,6 +158,11 @@ if(AMD_RYZEN_HACK AND USE_AVX2) message(WARNING "This option may be removed in a future release. Contact your computer manufacturer for updated ROMs or microcode patches.") endif(AMD_RYZEN_HACK AND USE_AVX2) +if(NATIVE_BUILD) + message(WARNING "May fail at runtime if the floating-point unit on the target system does not implement required features, some platforms will check this for you") + set(CRYPTO_FLAGS -march=native -mfpmath=sse -mtune=native) +endif() + add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) From 0241851b72eb5ace7ad5675a543a115aa601af41 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 27 Aug 2019 08:07:48 -0400 Subject: [PATCH 29/44] add likn layer delivery timeout notification for iwp --- llarp/config/config.cpp | 21 ++++-------- llarp/iwp/message_buffer.cpp | 31 +++++++++++++++-- llarp/iwp/message_buffer.hpp | 23 ++++++++++--- llarp/iwp/session.cpp | 41 +++++++++++++++++------ llarp/router/outbound_message_handler.cpp | 19 ++++------- 5 files changed, 91 insertions(+), 44 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index ca5f69b62..e6726dc63 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -11,6 +11,8 @@ #include #include +#include + #include #include #include @@ -208,29 +210,20 @@ namespace llarp std::string v = tostr(val); std::string::size_type idx; static constexpr char delimiter = ','; - static const auto strip_spaces = [](const auto &begin, - const auto &end) -> std::string { - std::string val; - std::for_each(begin, end, [&val](const char &ch) { - // strip spaces - if(::isspace(ch) || ch == delimiter) - return; - val += ch; - }); - return val; - }; - do { idx = v.find_first_of(delimiter); if(idx != std::string::npos) { - parsed_opts.emplace(strip_spaces(v.begin(), v.begin() + idx)); + std::string val = v.substr(0, idx); + absl::StripAsciiWhitespace(&val); + parsed_opts.emplace(std::move(val)); v = v.substr(idx + 1); } else { - parsed_opts.insert(strip_spaces(v.begin(), v.end())); + absl::StripAsciiWhitespace(&v); + parsed_opts.insert(std::move(v)); } } while(idx != std::string::npos); std::unordered_set< std::string > opts; diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp index af73c23ce..4ec5e663e 100644 --- a/llarp/iwp/message_buffer.cpp +++ b/llarp/iwp/message_buffer.cpp @@ -6,10 +6,12 @@ namespace llarp namespace iwp { OutboundMessage::OutboundMessage(uint64_t msgid, const llarp_buffer_t &pkt, + llarp_time_t now, ILinkSession::CompletionHandler handler) : m_Size{(uint16_t)std::min(pkt.sz, MAX_LINK_MSG_SIZE)} , m_MsgID{msgid} , m_Completed{handler} + , m_StartedAt{now} { m_Data.Zero(); std::copy_n(pkt.base, m_Size, m_Data.begin()); @@ -95,13 +97,35 @@ namespace llarp return true; } - InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h) - : m_Digset{std::move(h)}, m_Size{sz}, m_MsgID{msgid} + bool + OutboundMessage::IsTimedOut(const llarp_time_t now) const + { + // TODO: make configurable by outbound message deliverer + return now > m_StartedAt && now - m_StartedAt > 5000; + } + + void + OutboundMessage::InformTimeout() + { + if(m_Completed) + { + m_Completed(ILinkSession::DeliveryStatus::eDeliveryDropped); + } + m_Completed = nullptr; + } + + InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h, + llarp_time_t now) + : m_Digset{std::move(h)} + , m_Size{sz} + , m_MsgID{msgid} + , m_LastActiveAt{now} { } void - InboundMessage::HandleData(uint16_t idx, const byte_t *ptr) + InboundMessage::HandleData(uint16_t idx, const byte_t *ptr, + llarp_time_t now) { if(idx + FragmentSize > MAX_LINK_MSG_SIZE) return; @@ -109,6 +133,7 @@ namespace llarp std::copy_n(ptr, FragmentSize, dst); m_Acks.set(idx / FragmentSize); LogDebug("got fragment ", idx / FragmentSize, " of ", m_Size); + m_LastActiveAt = now; } std::vector< byte_t > diff --git a/llarp/iwp/message_buffer.hpp b/llarp/iwp/message_buffer.hpp index ded62a3a4..8a714f045 100644 --- a/llarp/iwp/message_buffer.hpp +++ b/llarp/iwp/message_buffer.hpp @@ -33,6 +33,7 @@ namespace llarp { OutboundMessage() = default; OutboundMessage(uint64_t msgid, const llarp_buffer_t &pkt, + llarp_time_t now, ILinkSession::CompletionHandler handler); AlignedBuffer< MAX_LINK_MSG_SIZE > m_Data; @@ -42,6 +43,7 @@ namespace llarp ILinkSession::CompletionHandler m_Completed; llarp_time_t m_LastFlush = 0; ShortHash digest; + llarp_time_t m_StartedAt = 0; std::vector< byte_t > XMIT() const; @@ -61,26 +63,37 @@ namespace llarp bool IsTransmitted() const; + + bool + IsTimedOut(llarp_time_t now) const; + + void + InformTimeout(); }; struct InboundMessage { InboundMessage() = default; - InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h); + InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h, + llarp_time_t now); AlignedBuffer< MAX_LINK_MSG_SIZE > m_Data; ShortHash m_Digset; - uint16_t m_Size = 0; - uint64_t m_MsgID = 0; - llarp_time_t m_LastACKSent = 0; + uint16_t m_Size = 0; + uint64_t m_MsgID = 0; + llarp_time_t m_LastACKSent = 0; + llarp_time_t m_LastActiveAt = 0; std::bitset< MAX_LINK_MSG_SIZE / FragmentSize > m_Acks; void - HandleData(uint16_t idx, const byte_t *ptr); + HandleData(uint16_t idx, const byte_t *ptr, llarp_time_t now); bool IsCompleted() const; + bool + IsTimedOut(llarp_time_t now) const; + bool Verify() const; diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 26499b6d6..6adf14ea6 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -147,15 +147,15 @@ namespace llarp Session::SendMessageBuffer(const llarp_buffer_t& buf, ILinkSession::CompletionHandler completed) { + const auto now = m_Parent->Now(); const auto msgid = m_TXID++; auto& msg = - m_TXMsgs.emplace(msgid, OutboundMessage{msgid, buf, completed}) + m_TXMsgs.emplace(msgid, OutboundMessage{msgid, buf, now, completed}) .first->second; const auto xmit = msg.XMIT(); const llarp_buffer_t pkt{xmit}; EncryptAndSend(pkt); - msg.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), - m_Parent->Now()); + msg.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), now); LogDebug("send message ", msgid); return true; } @@ -168,19 +168,21 @@ namespace llarp { if(ShouldPing()) SendKeepAlive(); - for(auto itr = m_RXMsgs.begin(); itr != m_RXMsgs.end(); ++itr) + for(auto& item : m_RXMsgs) { - if(itr->second.ShouldSendACKS(now)) + if(item.second.ShouldSendACKS(now)) { - itr->second.SendACKS(util::memFn(&Session::EncryptAndSend, this), + item.second.SendACKS(util::memFn(&Session::EncryptAndSend, this), now); } } - for(auto itr = m_TXMsgs.begin(); itr != m_TXMsgs.end(); ++itr) + for(auto& item : m_TXMsgs) { - if(itr->second.ShouldFlush(now)) - itr->second.FlushUnAcked( + if(item.second.ShouldFlush(now)) + { + item.second.FlushUnAcked( util::memFn(&Session::EncryptAndSend, this), now); + } } } } @@ -229,8 +231,27 @@ namespace llarp return now - m_CreatedAt > SessionAliveTimeout; } - void Session::Tick(llarp_time_t) + void + Session::Tick(llarp_time_t now) { + // remove pending outbound messsages that timed out + // inform waiters + auto itr = m_TXMsgs.begin(); + while(itr != m_TXMsgs.end()) + { + if(itr->second.IsTimedOut(now)) + { + itr->second.InformTimeout(); + itr = m_TXMsgs.erase(itr); + } + else + ++itr; + } + // remove pending inbound messages that timed out + std::remove_if(m_RXMsgs.begin(), m_RXMsgs.end(), + [now](const auto& item) -> bool { + return item.second.IsTimedOut(now); + }); } using Introduction = AlignedBuffer< 64 >; diff --git a/llarp/router/outbound_message_handler.cpp b/llarp/router/outbound_message_handler.cpp index d5102a2ed..99782de55 100644 --- a/llarp/router/outbound_message_handler.cpp +++ b/llarp/router/outbound_message_handler.cpp @@ -170,18 +170,13 @@ namespace llarp { const llarp_buffer_t buf(msg.first); auto callback = msg.second; - if(!_linkManager->SendTo( - remote, buf, [=](ILinkSession::DeliveryStatus status) { - if(status == ILinkSession::DeliveryStatus::eDeliverySuccess) - DoCallback(callback, SendStatus::Success); - else - DoCallback(callback, SendStatus::Congestion); - })) - { - DoCallback(callback, SendStatus::Congestion); - return false; - } - return true; + return _linkManager->SendTo( + remote, buf, [=](ILinkSession::DeliveryStatus status) { + if(status == ILinkSession::DeliveryStatus::eDeliverySuccess) + DoCallback(callback, SendStatus::Success); + else + DoCallback(callback, SendStatus::Congestion); + }); } bool From 88f685b74ad80f4d6d1f56e1768a504ea9be97d4 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 27 Aug 2019 08:13:55 -0400 Subject: [PATCH 30/44] add forgotten bits --- llarp/iwp/message_buffer.cpp | 6 ++++++ llarp/iwp/session.cpp | 39 +++++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp index 4ec5e663e..dc3319700 100644 --- a/llarp/iwp/message_buffer.cpp +++ b/llarp/iwp/message_buffer.cpp @@ -172,6 +172,12 @@ namespace llarp return now - m_LastACKSent > 1000 || IsCompleted(); } + bool + InboundMessage::IsTimedOut(const llarp_time_t now) const + { + return now > m_LastActiveAt && now - m_LastActiveAt > 5000; + } + void InboundMessage::SendACKS( std::function< void(const llarp_buffer_t &) > sendpkt, llarp_time_t now) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 6adf14ea6..81e859d8e 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -236,22 +236,32 @@ namespace llarp { // remove pending outbound messsages that timed out // inform waiters - auto itr = m_TXMsgs.begin(); - while(itr != m_TXMsgs.end()) { - if(itr->second.IsTimedOut(now)) + auto itr = m_TXMsgs.begin(); + while(itr != m_TXMsgs.end()) { - itr->second.InformTimeout(); - itr = m_TXMsgs.erase(itr); + if(itr->second.IsTimedOut(now)) + { + itr->second.InformTimeout(); + itr = m_TXMsgs.erase(itr); + } + else + ++itr; + } + } + { + // remove pending inbound messages that timed out + auto itr = m_RXMsgs.begin(); + while(itr != m_RXMsgs.end()) + { + if(itr->second.IsTimedOut(now)) + { + itr = m_RXMsgs.erase(itr); + } + else + ++itr; } - else - ++itr; } - // remove pending inbound messages that timed out - std::remove_if(m_RXMsgs.begin(), m_RXMsgs.end(), - [now](const auto& item) -> bool { - return item.second.IsTimedOut(now); - }); } using Introduction = AlignedBuffer< 64 >; @@ -491,7 +501,8 @@ namespace llarp LogDebug("rxid=", rxid, " sz=", sz, " h=", h.ToHex()); auto itr = m_RXMsgs.find(rxid); if(itr == m_RXMsgs.end()) - m_RXMsgs.emplace(rxid, InboundMessage{rxid, sz, std::move(h)}); + m_RXMsgs.emplace( + rxid, InboundMessage{rxid, sz, std::move(h), m_Parent->Now()}); else LogWarn("got duplicate xmit on ", rxid, " from ", m_RemoteAddr); m_LastRX = m_Parent->Now(); @@ -519,7 +530,7 @@ namespace llarp EncryptAndSend(nackbuf); return; } - itr->second.HandleData(sz, data.data() + 12); + itr->second.HandleData(sz, data.data() + 12, m_Parent->Now()); if(itr->second.IsCompleted()) { From 4c8da9bb6d060afa565f85f42590406f571d3d25 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 27 Aug 2019 09:14:44 -0400 Subject: [PATCH 31/44] use correct constructor for llarp_buffer_t --- llarp/iwp/session.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 81e859d8e..00b2c868a 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -91,7 +91,7 @@ namespace llarp return; } AlignedBuffer< LinkIntroMessage::MaxSize > data; - llarp_buffer_t buf{data}; + llarp_buffer_t buf(data); if(not msg.BEncode(&buf)) { LogError("failed to encode LIM for ", m_RemoteAddr); @@ -111,7 +111,7 @@ namespace llarp std::vector< byte_t > pkt; pkt.resize(data.sz + PacketOverhead); CryptoManager::instance()->randbytes(pkt.data(), pkt.size()); - llarp_buffer_t pktbuf{pkt}; + llarp_buffer_t pktbuf(pkt); pktbuf.base += PacketOverhead; pktbuf.sz -= PacketOverhead; byte_t* nonce_ptr = pkt.data() + HMACSIZE; @@ -135,7 +135,7 @@ namespace llarp return; const std::vector< byte_t > close_msg = {LLARP_PROTO_VERSION, Command::eCLOS}; - const llarp_buffer_t buf{close_msg}; + const llarp_buffer_t buf(close_msg); EncryptAndSend(buf); if(m_State == State::Ready) m_Parent->UnmapAddr(m_RemoteAddr); @@ -290,7 +290,7 @@ namespace llarp req.resize(intro.size() + (randint() % 64)); CryptoManager::instance()->randbytes(req.data(), req.size()); std::copy_n(intro.begin(), intro.size(), req.begin()); - const llarp_buffer_t buf{req}; + const llarp_buffer_t buf(req); Send_LL(buf); m_State = State::Introduction; LogDebug("sent intro to ", m_RemoteAddr); @@ -387,7 +387,7 @@ namespace llarp return false; } ShortHash H; - llarp_buffer_t curbuf{buf.base, buf.sz}; + llarp_buffer_t curbuf(buf.base, buf.sz); curbuf.base += ShortHash::SIZE; curbuf.sz -= ShortHash::SIZE; if(not CryptoManager::instance()->hmac(H.data(), curbuf, m_SessionKey)) @@ -406,7 +406,7 @@ namespace llarp curbuf.base += 32; curbuf.sz -= 32; result.resize(buf.sz - PacketOverhead); - const llarp_buffer_t outbuf{result}; + const llarp_buffer_t outbuf(result); LogDebug("decrypt: ", result.size(), " bytes from ", m_RemoteAddr); return CryptoManager::instance()->xchacha20_alt(outbuf, curbuf, m_SessionKey, nonce_ptr); @@ -432,7 +432,7 @@ namespace llarp if(result.size() == token.size()) { /// we got a token so we return it - const llarp_buffer_t pktbuf{token}; + const llarp_buffer_t pktbuf(token); EncryptAndSend(pktbuf); return; } @@ -481,7 +481,7 @@ namespace llarp if(itr != m_TXMsgs.end()) { auto xmit = itr->second.XMIT(); - const llarp_buffer_t pkt{xmit}; + const llarp_buffer_t pkt(xmit); EncryptAndSend(pkt); } m_LastRX = m_Parent->Now(); @@ -526,7 +526,7 @@ namespace llarp std::vector< byte_t > nack = { LLARP_PROTO_VERSION, Command::eNACK, 0, 0, 0, 0, 0, 0, 0, 0}; htobe64buf(nack.data() + 2, rxid); - const llarp_buffer_t nackbuf{nack}; + const llarp_buffer_t nackbuf(nack); EncryptAndSend(nackbuf); return; } @@ -539,7 +539,7 @@ namespace llarp if(itr->second.Verify()) { auto msg = std::move(itr->second); - const llarp_buffer_t buf{msg.m_Data.data(), msg.m_Size}; + const llarp_buffer_t buf(msg.m_Data.data(), msg.m_Size); m_Parent->HandleMessage(this, buf); } else @@ -593,7 +593,7 @@ namespace llarp if(m_State == State::Ready) { std::vector< byte_t > ping{LLARP_PROTO_VERSION, Command::ePING}; - const llarp_buffer_t buf{ping}; + const llarp_buffer_t buf(ping); EncryptAndSend(buf); return true; } From 3c2c89559301a6f572d1b3476e92d898a956d9a0 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 27 Aug 2019 13:10:25 -0400 Subject: [PATCH 32/44] fix log level --- llarp/iwp/session.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 00b2c868a..13d638d6c 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -504,7 +504,7 @@ namespace llarp m_RXMsgs.emplace( rxid, InboundMessage{rxid, sz, std::move(h), m_Parent->Now()}); else - LogWarn("got duplicate xmit on ", rxid, " from ", m_RemoteAddr); + LogDebug("got duplicate xmit on ", rxid, " from ", m_RemoteAddr); m_LastRX = m_Parent->Now(); } @@ -522,7 +522,7 @@ namespace llarp auto itr = m_RXMsgs.find(rxid); if(itr == m_RXMsgs.end()) { - LogWarn("no rxid=", rxid, " for ", m_RemoteAddr); + LogDebug("no rxid=", rxid, " for ", m_RemoteAddr); std::vector< byte_t > nack = { LLARP_PROTO_VERSION, Command::eNACK, 0, 0, 0, 0, 0, 0, 0, 0}; htobe64buf(nack.data() + 2, rxid); @@ -563,7 +563,7 @@ namespace llarp auto itr = m_TXMsgs.find(txid); if(itr == m_TXMsgs.end()) { - LogWarn("no txid=", txid, " for ", m_RemoteAddr); + LogDebug("no txid=", txid, " for ", m_RemoteAddr); return; } itr->second.Ack(data[10]); From e0424a91a7fe3ba9094df503a15dac8c5c5f61bd Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 27 Aug 2019 16:00:00 -0400 Subject: [PATCH 33/44] bump path build handover window, check cooldown on build. --- llarp/service/endpoint.cpp | 5 +++-- llarp/service/intro.hpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 2b084b637..8b419a56d 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1208,8 +1208,9 @@ namespace llarp const auto dlt = intro.expiresAt - now; return should || ( // try spacing tunnel builds out evenly in time - (dlt <= (path::default_lifetime / 4)) - && (NumInStatus(path::ePathBuilding) < numPaths)); + (dlt < (path::default_lifetime / 4)) + && (NumInStatus(path::ePathBuilding) < numPaths) + && !path::Builder::BuildCooldownHit(now)); } std::shared_ptr< Logic > diff --git a/llarp/service/intro.hpp b/llarp/service/intro.hpp index e3c4ba628..7edbd174e 100644 --- a/llarp/service/intro.hpp +++ b/llarp/service/intro.hpp @@ -30,7 +30,7 @@ namespace llarp } bool - ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 15000) const + ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 30000) const { if(dlt) return now >= (expiresAt - dlt); From eabbb83149b1039e4540f2d5826544b52bfd8f7e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 27 Aug 2019 16:07:09 -0400 Subject: [PATCH 34/44] use estimated build time instead of expiration time for delta when determining when to space out builds --- llarp/service/endpoint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 8b419a56d..a30bf1fca 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1205,10 +1205,10 @@ namespace llarp // time from now that the newest intro expires at if(intro.ExpiresSoon(now)) return should; - const auto dlt = intro.expiresAt - now; + const auto dlt = now - (intro.expiresAt - path::default_lifetime); return should || ( // try spacing tunnel builds out evenly in time - (dlt < (path::default_lifetime / 4)) + (dlt >= (path::default_lifetime / 4)) && (NumInStatus(path::ePathBuilding) < numPaths) && !path::Builder::BuildCooldownHit(now)); } From ba2aaa68c65609498bd3d696df0ad4ec27af9111 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 28 Aug 2019 07:02:00 -0400 Subject: [PATCH 35/44] add short data fragments and rx replay filter --- llarp/iwp/message_buffer.cpp | 24 +++++--- llarp/iwp/message_buffer.hpp | 2 +- llarp/iwp/session.cpp | 90 +++++++++++++++++++++--------- llarp/iwp/session.hpp | 24 ++++++++ llarp/router/rc_lookup_handler.cpp | 1 + 5 files changed, 104 insertions(+), 37 deletions(-) diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp index dc3319700..cc8b50dce 100644 --- a/llarp/iwp/message_buffer.cpp +++ b/llarp/iwp/message_buffer.cpp @@ -1,4 +1,5 @@ #include +#include #include namespace llarp @@ -43,8 +44,7 @@ namespace llarp bool OutboundMessage::ShouldFlush(llarp_time_t now) const { - static constexpr llarp_time_t FlushInterval = 500; - return now - m_LastFlush >= FlushInterval; + return now - m_LastFlush >= Session::TXFlushInterval; } void @@ -76,8 +76,12 @@ namespace llarp 0}; htobe16buf(frag.data() + 2, idx); htobe64buf(frag.data() + 4, m_MsgID); - std::copy(m_Data.begin() + idx, m_Data.begin() + idx + FragmentSize, - std::back_inserter(frag)); + if(idx + FragmentSize < m_Size) + std::copy(m_Data.begin() + idx, m_Data.begin() + idx + FragmentSize, + std::back_inserter(frag)); + else + std::copy(m_Data.begin() + idx, m_Data.begin() + m_Size, + std::back_inserter(frag)); const llarp_buffer_t pkt{frag}; sendpkt(pkt); } @@ -101,7 +105,7 @@ namespace llarp OutboundMessage::IsTimedOut(const llarp_time_t now) const { // TODO: make configurable by outbound message deliverer - return now > m_StartedAt && now - m_StartedAt > 5000; + return now > m_StartedAt && now - m_StartedAt > Session::DeliveryTimeout; } void @@ -124,13 +128,13 @@ namespace llarp } void - InboundMessage::HandleData(uint16_t idx, const byte_t *ptr, + InboundMessage::HandleData(uint16_t idx, const llarp_buffer_t &buf, llarp_time_t now) { - if(idx + FragmentSize > MAX_LINK_MSG_SIZE) + if(idx + buf.sz > MAX_LINK_MSG_SIZE) return; auto *dst = m_Data.data() + idx; - std::copy_n(ptr, FragmentSize, dst); + std::copy_n(buf.base, buf.sz, dst); m_Acks.set(idx / FragmentSize); LogDebug("got fragment ", idx / FragmentSize, " of ", m_Size); m_LastActiveAt = now; @@ -175,7 +179,8 @@ namespace llarp bool InboundMessage::IsTimedOut(const llarp_time_t now) const { - return now > m_LastActiveAt && now - m_LastActiveAt > 5000; + return now > m_LastActiveAt + && now - m_LastActiveAt > Session::DeliveryTimeout; } void @@ -183,6 +188,7 @@ namespace llarp std::function< void(const llarp_buffer_t &) > sendpkt, llarp_time_t now) { auto acks = ACKS(); + AddRandomPadding(acks); const llarp_buffer_t pkt{acks}; sendpkt(pkt); m_LastACKSent = now; diff --git a/llarp/iwp/message_buffer.hpp b/llarp/iwp/message_buffer.hpp index 8a714f045..7671506c2 100644 --- a/llarp/iwp/message_buffer.hpp +++ b/llarp/iwp/message_buffer.hpp @@ -86,7 +86,7 @@ namespace llarp std::bitset< MAX_LINK_MSG_SIZE / FragmentSize > m_Acks; void - HandleData(uint16_t idx, const byte_t *ptr, llarp_time_t now); + HandleData(uint16_t idx, const llarp_buffer_t &buf, llarp_time_t now); bool IsCompleted() const; diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 13d638d6c..6c527c857 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -9,6 +9,15 @@ namespace llarp { static constexpr size_t PacketOverhead = HMACSIZE + TUNNONCESIZE; + void + AddRandomPadding(std::vector< byte_t >& pkt, size_t min, size_t variance) + { + const auto sz = pkt.size(); + const size_t randpad = min + randint() % variance; + pkt.resize(sz + randpad); + CryptoManager::instance()->randbytes(pkt.data() + sz, randpad); + } + Session::Session(LinkLayer* p, RouterContact rc, AddressInfo ai) : m_State{State::Initial} , m_Inbound{false} @@ -133,8 +142,8 @@ namespace llarp { if(m_State == State::Closed) return; - const std::vector< byte_t > close_msg = {LLARP_PROTO_VERSION, - Command::eCLOS}; + std::vector< byte_t > close_msg = {LLARP_PROTO_VERSION, Command::eCLOS}; + AddRandomPadding(close_msg); const llarp_buffer_t buf(close_msg); EncryptAndSend(buf); if(m_State == State::Ready) @@ -152,8 +161,9 @@ namespace llarp auto& msg = m_TXMsgs.emplace(msgid, OutboundMessage{msgid, buf, now, completed}) .first->second; - const auto xmit = msg.XMIT(); - const llarp_buffer_t pkt{xmit}; + auto xmit = msg.XMIT(); + AddRandomPadding(xmit); + const llarp_buffer_t pkt(xmit); EncryptAndSend(pkt); msg.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), now); LogDebug("send message ", msgid); @@ -206,8 +216,7 @@ namespace llarp { if(m_State == State::Ready) { - static constexpr llarp_time_t PingInterval = 500; - const auto now = m_Parent->Now(); + const auto now = m_Parent->Now(); return now - m_LastTX > PingInterval; } return false; @@ -223,7 +232,6 @@ namespace llarp bool Session::TimedOut(llarp_time_t now) const { - static constexpr llarp_time_t SessionAliveTimeout = 10000; if(m_State == State::Ready || m_State == State::LinkIntro) { return now > m_LastRX && now - m_LastRX > SessionAliveTimeout; @@ -262,6 +270,12 @@ namespace llarp ++itr; } } + // decay replay window + m_ReplayFilter.erase( + std::remove_if(m_ReplayFilter.begin(), m_ReplayFilter.end(), + [now](const auto& item) -> bool { + return item.second + ReplayWindow > now; + })); } using Introduction = AlignedBuffer< 64 >; @@ -283,13 +297,12 @@ namespace llarp } const auto pk = m_Parent->RouterEncryptionSecret().toPublic(); std::copy_n(pk.begin(), pk.size(), intro.begin()); - std::copy(N.begin(), N.end(), intro.begin() + 32); + std::copy(N.begin(), N.end(), intro.begin() + PubKey::SIZE); LogDebug("pk=", pk.ToHex(), " N=", N.ToHex(), " remote-pk=", m_ChosenAI.pubkey.ToHex()); std::vector< byte_t > req; - req.resize(intro.size() + (randint() % 64)); - CryptoManager::instance()->randbytes(req.data(), req.size()); - std::copy_n(intro.begin(), intro.size(), req.begin()); + std::copy_n(intro.begin(), intro.size(), std::back_inserter(req)); + AddRandomPadding(req); const llarp_buffer_t buf(req); Send_LL(buf); m_State = State::Introduction; @@ -344,10 +357,9 @@ namespace llarp return; } std::vector< byte_t > reply; - reply.resize(token.size() + (randint() % 32)); - CryptoManager::instance()->randbytes(reply.data(), reply.size()); - std::copy_n(token.begin(), token.size(), reply.begin()); - const llarp_buffer_t pkt{reply}; + std::copy_n(token.begin(), token.size(), std::back_inserter(reply)); + AddRandomPadding(reply); + const llarp_buffer_t pkt(reply); m_LastRX = m_Parent->Now(); EncryptAndSend(pkt); LogDebug("sent intro ack to ", m_RemoteAddr); @@ -371,7 +383,7 @@ namespace llarp } m_LastRX = m_Parent->Now(); std::copy_n(reply.begin(), token.size(), token.begin()); - const llarp_buffer_t pkt{token}; + const llarp_buffer_t pkt(token); EncryptAndSend(pkt); LogDebug("sent session request to ", m_RemoteAddr); m_State = State::LinkIntro; @@ -481,6 +493,7 @@ namespace llarp if(itr != m_TXMsgs.end()) { auto xmit = itr->second.XMIT(); + AddRandomPadding(xmit); const llarp_buffer_t pkt(xmit); EncryptAndSend(pkt); } @@ -499,19 +512,30 @@ namespace llarp uint64_t rxid = bufbe64toh(data.data() + 4); ShortHash h{data.data() + 12}; LogDebug("rxid=", rxid, " sz=", sz, " h=", h.ToHex()); - auto itr = m_RXMsgs.find(rxid); - if(itr == m_RXMsgs.end()) - m_RXMsgs.emplace( - rxid, InboundMessage{rxid, sz, std::move(h), m_Parent->Now()}); - else - LogDebug("got duplicate xmit on ", rxid, " from ", m_RemoteAddr); m_LastRX = m_Parent->Now(); + { + // check for replay + auto itr = m_ReplayFilter.find(rxid); + if(itr != m_ReplayFilter.end()) + { + LogDebug("duplicate rxid=", rxid, " from ", m_RemoteAddr); + return; + } + } + { + auto itr = m_RXMsgs.find(rxid); + if(itr == m_RXMsgs.end()) + m_RXMsgs.emplace( + rxid, InboundMessage{rxid, sz, std::move(h), m_Parent->Now()}); + else + LogDebug("got duplicate xmit on ", rxid, " from ", m_RemoteAddr); + } } void Session::HandleDATA(std::vector< byte_t > data) { - if(data.size() < FragmentSize + 12) + if(data.size() <= 12) { LogError("short DATA from ", m_RemoteAddr, " ", data.size()); return; @@ -526,11 +550,16 @@ namespace llarp std::vector< byte_t > nack = { LLARP_PROTO_VERSION, Command::eNACK, 0, 0, 0, 0, 0, 0, 0, 0}; htobe64buf(nack.data() + 2, rxid); + AddRandomPadding(nack); const llarp_buffer_t nackbuf(nack); EncryptAndSend(nackbuf); return; } - itr->second.HandleData(sz, data.data() + 12, m_Parent->Now()); + + { + const llarp_buffer_t buf(data.data() + 12, data.size() - 12); + itr->second.HandleData(sz, buf, m_Parent->Now()); + } if(itr->second.IsCompleted()) { @@ -541,6 +570,7 @@ namespace llarp auto msg = std::move(itr->second); const llarp_buffer_t buf(msg.m_Data.data(), msg.m_Size); m_Parent->HandleMessage(this, buf); + m_ReplayFilter.emplace(itr->first, m_Parent->Now()); } else { @@ -558,9 +588,10 @@ namespace llarp LogError("short ACKS from ", m_RemoteAddr, " ", data.size(), " < 11"); return; } - m_LastRX = m_Parent->Now(); - uint64_t txid = bufbe64toh(data.data() + 2); - auto itr = m_TXMsgs.find(txid); + const auto now = m_Parent->Now(); + m_LastRX = now; + uint64_t txid = bufbe64toh(data.data() + 2); + auto itr = m_TXMsgs.find(txid); if(itr == m_TXMsgs.end()) { LogDebug("no txid=", txid, " for ", m_RemoteAddr); @@ -574,6 +605,11 @@ namespace llarp itr->second.Completed(); itr = m_TXMsgs.erase(itr); } + else + { + itr->second.FlushUnAcked(util::memFn(&Session::EncryptAndSend, this), + now); + } } void Session::HandleCLOS(std::vector< byte_t >) diff --git a/llarp/iwp/session.hpp b/llarp/iwp/session.hpp index b9f598bf1..22d5f0896 100644 --- a/llarp/iwp/session.hpp +++ b/llarp/iwp/session.hpp @@ -9,9 +9,30 @@ namespace llarp { namespace iwp { + void + AddRandomPadding(std::vector< byte_t >& pkt, size_t min = 16, + size_t variance = 16); + struct Session : public ILinkSession, public std::enable_shared_from_this< Session > { + /// Time how long we try delivery for + static constexpr llarp_time_t DeliveryTimeout = 5000; + /// How long to keep a replay window for + static constexpr llarp_time_t ReplayWindow = (DeliveryTimeout * 3) / 2; + /// Time how long we wait to recieve a message + static constexpr llarp_time_t RecievalTimeout = (DeliveryTimeout * 8) / 5; + /// How often to acks RX messages + static constexpr llarp_time_t ACKResendInterval = 500; + /// How often to retransmit TX fragments + static constexpr llarp_time_t TXFlushInterval = + (ACKResendInterval * 3) / 2; + /// How often we send a keepalive + static constexpr llarp_time_t PingInterval = 2000; + /// How long we wait for a session to die with no tx from them + static constexpr llarp_time_t SessionAliveTimeout = + (PingInterval * 13) / 3; + /// outbound session Session(LinkLayer* parent, RouterContact rc, AddressInfo ai); /// inbound session @@ -132,6 +153,9 @@ namespace llarp std::unordered_map< uint64_t, InboundMessage > m_RXMsgs; std::unordered_map< uint64_t, OutboundMessage > m_TXMsgs; + /// maps rxid to time recieved + std::unordered_map< uint64_t, llarp_time_t > m_ReplayFilter; + void HandleGotIntro(const llarp_buffer_t& buf); diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index b79b454a4..2f4b05322 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -133,6 +133,7 @@ namespace llarp if(not rc.Verify(_dht->impl->Now())) { + LogWarn("RC for ", RouterID(rc.pubkey), " is invalid"); return false; } From 16934cdd209d4f66cd2fdc016eb691f5e39f3b30 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 28 Aug 2019 07:11:03 -0400 Subject: [PATCH 36/44] please the CI gods, wololo --- llarp/iwp/session.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 6c527c857..4143b31fd 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -270,12 +270,19 @@ namespace llarp ++itr; } } - // decay replay window - m_ReplayFilter.erase( - std::remove_if(m_ReplayFilter.begin(), m_ReplayFilter.end(), - [now](const auto& item) -> bool { - return item.second + ReplayWindow > now; - })); + { + // decay replay window + auto itr = m_ReplayFilter.begin(); + while(itr != m_ReplayFilter.end()) + { + if(itr->second + ReplayWindow > now) + { + itr = m_ReplayFilter.erase(itr); + } + else + ++itr; + } + } } using Introduction = AlignedBuffer< 64 >; From 444d832b7c19dd9035eeaef5a6b593dc324a42be Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 28 Aug 2019 07:38:32 -0400 Subject: [PATCH 37/44] correct constructors on llarp_buffer_t and check rc on regen --- llarp/iwp/message_buffer.cpp | 10 +++++----- llarp/router/router.cpp | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/llarp/iwp/message_buffer.cpp b/llarp/iwp/message_buffer.cpp index cc8b50dce..14a5eb8fd 100644 --- a/llarp/iwp/message_buffer.cpp +++ b/llarp/iwp/message_buffer.cpp @@ -16,7 +16,7 @@ namespace llarp { m_Data.Zero(); std::copy_n(pkt.base, m_Size, m_Data.begin()); - const llarp_buffer_t buf{m_Data.data(), m_Size}; + const llarp_buffer_t buf(m_Data.data(), m_Size); CryptoManager::instance()->shorthash(digest, buf); } @@ -82,7 +82,7 @@ namespace llarp else std::copy(m_Data.begin() + idx, m_Data.begin() + m_Size, std::back_inserter(frag)); - const llarp_buffer_t pkt{frag}; + const llarp_buffer_t pkt(frag); sendpkt(pkt); } idx += FragmentSize; @@ -131,7 +131,7 @@ namespace llarp InboundMessage::HandleData(uint16_t idx, const llarp_buffer_t &buf, llarp_time_t now) { - if(idx + buf.sz > MAX_LINK_MSG_SIZE) + if(idx + buf.sz > m_Data.size()) return; auto *dst = m_Data.data() + idx; std::copy_n(buf.base, buf.sz, dst); @@ -189,7 +189,7 @@ namespace llarp { auto acks = ACKS(); AddRandomPadding(acks); - const llarp_buffer_t pkt{acks}; + const llarp_buffer_t pkt(acks); sendpkt(pkt); m_LastACKSent = now; } @@ -198,7 +198,7 @@ namespace llarp InboundMessage::Verify() const { ShortHash gotten; - const llarp_buffer_t buf{m_Data.data(), m_Size}; + const llarp_buffer_t buf(m_Data.data(), m_Size); CryptoManager::instance()->shorthash(gotten, buf); LogDebug("gotten=", gotten.ToHex()); if(gotten != m_Digset) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 61e515db5..a7475cfc8 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -336,10 +336,11 @@ namespace llarp _encryption = nextOnionKey; } } - nextRC.last_updated = Now(); if(!nextRC.Sign(identity())) return false; - _rc = nextRC; + if(!nextRC.Verify(time_now_ms(), false)) + return false; + _rc = std::move(nextRC); // propagate RC by renegotiating sessions ForEachPeer([](ILinkSession *s) { if(s->RenegotiateSession()) From 0986b6ab5ec11442833d7ff68239633c8077c2b6 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 28 Aug 2019 07:59:08 -0400 Subject: [PATCH 38/44] quick little fixes --- llarp/iwp/session.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 4143b31fd..95e7f0b2c 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -122,6 +122,7 @@ namespace llarp CryptoManager::instance()->randbytes(pkt.data(), pkt.size()); llarp_buffer_t pktbuf(pkt); pktbuf.base += PacketOverhead; + pktbuf.cur = pktbuf.base; pktbuf.sz -= PacketOverhead; byte_t* nonce_ptr = pkt.data() + HMACSIZE; @@ -133,6 +134,7 @@ namespace llarp CryptoManager::instance()->hmac(pkt.data(), pktbuf, m_SessionKey); pktbuf.base = pkt.data(); + pktbuf.cur = pkt.data(); pktbuf.sz = pkt.size(); Send_LL(pktbuf); } @@ -583,7 +585,7 @@ namespace llarp { LogError("hash missmatch for message ", itr->first); } - m_RXMsgs.erase(rxid); + m_RXMsgs.erase(itr); } } From b904a4ee225ab20f3901811d558d8e2a02484b27 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 28 Aug 2019 08:44:50 -0400 Subject: [PATCH 39/44] fix explore --- llarp/dht/messages/gotrouter.cpp | 2 ++ llarp/dht/recursiverouterlookup.cpp | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/llarp/dht/messages/gotrouter.cpp b/llarp/dht/messages/gotrouter.cpp index bcc2a9b1e..64115bbe9 100644 --- a/llarp/dht/messages/gotrouter.cpp +++ b/llarp/dht/messages/gotrouter.cpp @@ -97,6 +97,7 @@ namespace llarp if(dht.pendingExploreLookups().HasPendingLookupFrom(owner)) { + LogDebug("got ", N.size(), " results in GRM for explore"); if(N.size() == 0) dht.pendingExploreLookups().NotFound(owner, K); else @@ -108,6 +109,7 @@ namespace llarp // not explore lookup if(dht.pendingRouterLookups().HasPendingLookupFrom(owner)) { + LogDebug("got ", R.size(), " results in GRM for lookup"); if(R.size() == 0) dht.pendingRouterLookups().NotFound(owner, K); else diff --git a/llarp/dht/recursiverouterlookup.cpp b/llarp/dht/recursiverouterlookup.cpp index ae7b44ede..f0bcb1b84 100644 --- a/llarp/dht/recursiverouterlookup.cpp +++ b/llarp/dht/recursiverouterlookup.cpp @@ -76,11 +76,10 @@ namespace llarp parent->DHTSendTo( whoasked.node.as_array(), new GotRouterMessage({}, whoasked.txid, valuesFound, false), false); - - // store this in our nodedb for caching - if(valuesFound.size() > 0) - parent->StoreRC(valuesFound[0]); } + // store this in our nodedb for caching + if(valuesFound.size() > 0) + parent->StoreRC(valuesFound[0]); } } // namespace dht } // namespace llarp From 795ac6bab3f52a7659eb9dafb2bb3c608c23e92f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 28 Aug 2019 10:15:16 -0400 Subject: [PATCH 40/44] get rid of dead code --- llarp/iwp/session.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 95e7f0b2c..6c81f7420 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -450,13 +450,6 @@ namespace llarp LogError("failed to decrypt session data from ", m_RemoteAddr); return; } - if(result.size() == token.size()) - { - /// we got a token so we return it - const llarp_buffer_t pktbuf(token); - EncryptAndSend(pktbuf); - return; - } if(result[0] != LLARP_PROTO_VERSION) { LogError("protocol version missmatch ", int(result[0]), From d1e590ce9d08c596ce3d0b4dd700749a2207eb58 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 28 Aug 2019 10:42:32 -0400 Subject: [PATCH 41/44] fix sign --- llarp/iwp/session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 6c81f7420..e14ccc2fb 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -277,7 +277,7 @@ namespace llarp auto itr = m_ReplayFilter.begin(); while(itr != m_ReplayFilter.end()) { - if(itr->second + ReplayWindow > now) + if(itr->second + ReplayWindow <= now) { itr = m_ReplayFilter.erase(itr); } From 78d191bd750adceaf5b998a9e7f9db94bffc9461 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 29 Aug 2019 07:45:58 -0400 Subject: [PATCH 42/44] prepare for 0.5.0 --- .clang-tidy | 2 +- .travis.yml | 94 ++- CMakeLists.txt | 53 +- Makefile | 14 +- cmake/cross_compile.cmake | 6 +- cmake/shadow.cmake | 2 +- cmake/unix.cmake | 47 +- cmake/win32.cmake | 4 + contrib/cross/mingw.cmake | 34 +- contrib/cross/mingw32.cmake | 33 +- contrib/shadow/genconf.py | 2 +- crypto/include/sodium/crypto_int32.h | 3 +- crypto/include/sodium/crypto_uint32.h | 3 +- crypto/libntrup/src/ref/rq.c | 1 - daemon/rcutil.cpp | 625 ++---------------- docker/router.Dockerfile | 3 +- include/tuntap.h | 2 +- llarp/CMakeLists.txt | 7 +- llarp/config/config.cpp | 305 +++++---- llarp/config/config.hpp | 91 +-- llarp/constants/link_layer.hpp | 2 +- llarp/constants/version.cpp | 5 +- llarp/constants/version.hpp | 4 +- llarp/context.cpp | 10 +- llarp/crypto/constants.hpp | 2 +- llarp/crypto/crypto.hpp | 8 +- llarp/crypto/crypto_libsodium.cpp | 2 +- llarp/crypto/crypto_libsodium.hpp | 4 +- llarp/crypto/crypto_noop.hpp | 2 +- llarp/crypto/encrypted_frame.hpp | 6 +- llarp/dht/bucket.hpp | 5 +- llarp/dht/context.cpp | 18 +- llarp/dht/dht.h | 2 +- llarp/dht/key.hpp | 6 + llarp/dht/message.cpp | 15 +- llarp/dht/message.hpp | 4 +- llarp/dht/messages/findintro.cpp | 4 +- llarp/dht/messages/findintro.hpp | 2 +- llarp/dht/messages/findrouter.cpp | 8 +- llarp/dht/messages/findrouter.hpp | 6 +- llarp/dht/messages/gotintro.cpp | 24 +- llarp/dht/messages/gotintro.hpp | 9 +- llarp/dht/messages/gotrouter.cpp | 9 +- llarp/dht/messages/gotrouter.hpp | 16 +- llarp/dht/messages/pubintro.cpp | 4 +- llarp/dht/messages/pubintro.hpp | 9 +- llarp/dht/node.hpp | 3 +- llarp/dht/publishservicejob.cpp | 5 +- llarp/dht/publishservicejob.hpp | 2 +- llarp/dht/recursiverouterlookup.cpp | 10 +- llarp/dht/recursiverouterlookup.hpp | 2 +- llarp/dht/serviceaddresslookup.cpp | 3 +- llarp/dht/serviceaddresslookup.hpp | 2 +- llarp/dht/tx.hpp | 12 +- llarp/dht/txholder.hpp | 10 +- llarp/dns.cpp | 37 +- llarp/dns.h | 2 +- llarp/dns.hpp | 16 +- llarp/dns/dns.hpp | 2 +- llarp/dns/name.cpp | 4 +- llarp/dns/rectypes.cpp | 4 +- llarp/dns/rectypes.hpp | 32 +- llarp/dns/serialize.cpp | 4 +- llarp/dns/server.cpp | 9 +- llarp/dns/server.hpp | 4 +- llarp/dnsc.cpp | 20 +- llarp/dnsc.hpp | 2 +- llarp/dnsd.cpp | 9 +- llarp/ev/ev.h | 6 +- llarp/ev/ev.hpp | 31 +- llarp/ev/ev_libuv.cpp | 154 ++++- llarp/ev/ev_libuv.hpp | 4 + llarp/ev/pipe.cpp | 7 +- llarp/ev/pipe.hpp | 4 +- llarp/exit/context.cpp | 9 +- llarp/exit/exit_messages.hpp | 14 +- llarp/exit/session.cpp | 15 +- llarp/exit/session.hpp | 10 +- llarp/handlers/exit.cpp | 11 +- llarp/handlers/exit.hpp | 2 +- llarp/handlers/tun.cpp | 38 +- llarp/handlers/tun.hpp | 8 +- llarp/hook/ihook.hpp | 4 +- llarp/iwp/iwp.cpp | 34 +- llarp/iwp/iwp.hpp | 22 +- llarp/iwp/linklayer.cpp | 179 ++--- llarp/iwp/linklayer.hpp | 46 +- llarp/iwp/outermessage.cpp | 156 ----- llarp/iwp/outermessage.hpp | 86 --- llarp/link/i_link_manager.hpp | 5 - llarp/link/link_manager.cpp | 5 +- llarp/link/link_manager.hpp | 4 +- llarp/link/server.cpp | 31 +- llarp/link/server.hpp | 16 +- llarp/link/session.hpp | 18 +- llarp/messages/dht_immediate.hpp | 4 +- llarp/messages/link_intro.cpp | 14 +- llarp/messages/link_message_parser.cpp | 4 +- llarp/messages/relay_commit.cpp | 10 +- llarp/messages/relay_commit.hpp | 7 +- llarp/messages/relay_status.cpp | 13 +- llarp/messages/relay_status.hpp | 7 +- llarp/metrics/json_publisher.hpp | 7 +- llarp/metrics/metrictank_publisher.cpp | 3 +- llarp/metrics/metrictank_publisher.hpp | 11 +- llarp/metrics/stream_publisher.hpp | 2 +- llarp/net/address_info.cpp | 15 +- llarp/net/address_info.hpp | 4 +- llarp/net/exit_info.cpp | 2 +- llarp/net/exit_info.hpp | 4 +- llarp/net/ip.cpp | 8 +- llarp/net/ip.hpp | 11 +- llarp/net/net.cpp | 8 +- llarp/net/net.h | 4 + llarp/net/net.hpp | 2 +- llarp/net/net_addr.cpp | 26 +- llarp/net/net_inaddr.cpp | 4 +- llarp/net/net_int.hpp | 2 +- llarp/nodedb.cpp | 17 +- llarp/nodedb.hpp | 5 +- llarp/path/ihophandler.hpp | 4 +- llarp/path/path.cpp | 22 +- llarp/path/path_context.cpp | 17 +- llarp/path/path_context.hpp | 1 + llarp/path/pathbuilder.cpp | 4 +- llarp/path/pathbuilder.hpp | 16 +- llarp/path/transit_hop.cpp | 4 +- llarp/pow.cpp | 4 +- llarp/router/i_outbound_message_handler.hpp | 7 +- llarp/router/i_outbound_session_maker.hpp | 9 +- llarp/router/outbound_message_handler.cpp | 19 +- llarp/router/outbound_message_handler.hpp | 7 +- llarp/router/outbound_session_maker.cpp | 31 +- llarp/router/outbound_session_maker.hpp | 37 +- llarp/router/rc_lookup_handler.cpp | 1 + llarp/router/rc_lookup_handler.hpp | 22 +- llarp/router/router.cpp | 191 +++--- llarp/router/router.hpp | 12 +- llarp/router_contact.cpp | 40 +- llarp/router_contact.hpp | 11 +- llarp/router_id.cpp | 2 + llarp/router_id.hpp | 2 +- llarp/routing/dht_message.hpp | 2 +- llarp/routing/message.hpp | 10 +- llarp/routing/message_parser.cpp | 9 +- llarp/routing/message_parser.hpp | 6 +- llarp/routing/path_confirm_message.hpp | 2 +- llarp/routing/path_latency_message.cpp | 4 +- llarp/routing/path_transfer_message.hpp | 2 +- llarp/rpc/rpc.cpp | 44 +- llarp/service/async_key_exchange.cpp | 20 +- llarp/service/async_key_exchange.hpp | 2 +- llarp/service/context.cpp | 6 +- llarp/service/endpoint.cpp | 48 +- llarp/service/endpoint.hpp | 10 +- llarp/service/endpoint_state.cpp | 35 +- llarp/service/endpoint_state.hpp | 4 +- .../service/hidden_service_address_lookup.cpp | 3 +- .../service/hidden_service_address_lookup.hpp | 8 +- llarp/service/intro.hpp | 2 +- llarp/service/intro_set.cpp | 4 +- llarp/service/lookup.cpp | 6 +- llarp/service/lookup.hpp | 9 +- llarp/service/outbound_context.cpp | 34 +- llarp/service/outbound_context.hpp | 2 +- llarp/service/protocol.cpp | 25 +- llarp/service/protocol.hpp | 2 +- llarp/service/router_lookup_job.cpp | 3 +- llarp/service/sendcontext.cpp | 8 +- llarp/service/sendcontext.hpp | 2 +- llarp/service/tag_lookup_job.hpp | 8 +- llarp/testnet.c | 2 +- llarp/util/bencode.cpp | 4 +- llarp/util/bencode.h | 4 +- llarp/util/buffer.cpp | 4 +- llarp/util/buffer.hpp | 18 +- llarp/util/codel.hpp | 8 +- llarp/util/common.hpp | 6 +- llarp/util/encode.hpp | 2 +- llarp/util/endian.hpp | 4 +- llarp/util/file_logger.cpp | 3 +- llarp/util/file_logger.hpp | 2 +- llarp/util/json.cpp | 4 +- llarp/util/json.hpp | 4 +- llarp/util/mem.cpp | 8 +- llarp/util/mem.h | 6 +- llarp/util/metrics_core.cpp | 38 +- llarp/util/metrics_core.hpp | 39 +- llarp/util/metrics_types.hpp | 35 +- llarp/util/ostream_logger.hpp | 8 +- llarp/util/queue_manager.cpp | 8 +- llarp/util/scheduler.cpp | 7 +- llarp/util/scheduler.hpp | 7 +- llarp/util/status.cpp | 63 -- llarp/util/status.hpp | 45 +- llarp/util/stopwatch.hpp | 4 +- llarp/util/threading.hpp | 1 + llarp/util/threadpool.h | 12 +- llarp/util/timer.cpp | 11 +- llarp/util/timerqueue.hpp | 16 +- llarp/util/win32_logger.cpp | 61 +- llarp/util/win32_logger.hpp | 7 + llarp/utp/inbound_message.hpp | 4 +- llarp/utp/linklayer.cpp | 20 +- llarp/utp/linklayer.hpp | 2 +- llarp/utp/session.cpp | 63 +- llarp/utp/session.hpp | 18 +- llarp/utp/utp.cpp | 14 +- llarp/utp/utp.hpp | 16 +- llarp/win32/win32_inet.c | 1 + motto.txt | 2 +- test/config/test_llarp_config_config.cpp | 6 +- test/link/test_llarp_link.cpp | 140 +++- .../absl/debugging/internal/vdso_support.cc | 6 +- vendor/cxxopts/CHANGELOG.md | 14 + vendor/cxxopts/CMakeLists.txt | 70 +- vendor/cxxopts/README.md | 12 + vendor/cxxopts/include/cxxopts.hpp | 222 +++++-- vendor/cxxopts/src/example.cpp | 11 + vendor/cxxopts/test/options.cpp | 234 ++++++- vendor/gtest/googletest/src/gtest.cc | 2 +- win32-setup/lokinet-win32.iss | 1 + 222 files changed, 2392 insertions(+), 2514 deletions(-) delete mode 100644 llarp/iwp/outermessage.cpp delete mode 100644 llarp/iwp/outermessage.hpp diff --git a/.clang-tidy b/.clang-tidy index 5d635f09e..234f1e1d9 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,2 +1,2 @@ HeaderFilterRegex: 'llarp/.*' -Checks: 'readability-else-after-return,clang-analyzer-core-*' +Checks: 'readability-else-after-return,clang-analyzer-core-*,modernize-*' diff --git a/.travis.yml b/.travis.yml index a2a4566e4..d3a674fff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,58 +5,82 @@ cache: ccache matrix: fast_finish: true include: - - os: linux + - name: "lint check" + os: linux dist: xenial compiler: gcc - env: BUILD_TYPE=Debug IS_NOTIFICATION=1 - - os: linux - dist: xenial - env: DOCKER_FILE=docker/router.Dockerfile - services: docker - - os: linux - dist: xenial - env: DOCKER_FILE=docker/alpine-windows.Dockerfile - services: docker - - os: linux + env: MAKE_TARGET=format-verify PATH="/usr/lib/llvm-8/bin:$PATH" + addons: + apt: + sources: + - llvm-toolchain-xenial-8 + packages: + - clang-format-8 + - name: "make debug (linux/gcc)" + os: linux dist: xenial - env: DOCKER_FILE=docker/gcc-trunk.Dockerfile - services: docker - - os: linux + compiler: gcc + env: BUILD_TYPE=Debug IS_NOTIFICATION=1 + - name: "make release (linux/gcc)" + os: linux dist: xenial compiler: gcc env: BUILD_TYPE=Release - - os: linux + - name: "make debug (linux/clang)" + os: linux dist: xenial compiler: clang env: BUILD_TYPE=Debug - - os: linux + - name: "make release (linux/clang)" + os: linux dist: xenial compiler: clang env: BUILD_TYPE=Release - - os: osx - osx_image: xcode10.2 - compiler: gcc - env: BUILD_TYPE=Debug - - os: osx - osx_image: xcode10.2 - compiler: gcc - env: BUILD_TYPE=Release - - os: osx + - name: "make debug (macOS/clang)" + os: osx osx_image: xcode10.2 env: BUILD_TYPE=Debug PATH="/usr/local/opt/ccache/libexec:$PATH" - - os: osx + - name: "make release (macOS/clang)" + os: osx osx_image: xcode10.2 env: BUILD_TYPE=Release PATH="/usr/local/opt/ccache/libexec:$PATH" - - os: osx + - name: "make windows (macOS)" + os: osx + osx_image: xcode10.2 + env: MAKE_TARGET=windows PATH="/usr/local/opt/ccache/libexec:$PATH" + - name: "make windows-release (macOS)" + os: osx + osx_image: xcode10.2 + env: MAKE_TARGET=windows-release PATH="/usr/local/opt/ccache/libexec:$PATH" + - name: "make release (macOS beta/clang)" + os: osx osx_image: xcode11 env: BUILD_TYPE=Release PATH="/usr/local/opt/ccache/libexec:$PATH" - - os: osx + - name: "address sanitizer" + os: osx osx_image: xcode10.2 env: BUILD_TYPE=Debug ASAN=ON PATH="/usr/local/opt/ccache/libexec:$PATH" CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++ - - os: windows + - name: "native windows debug" + os: windows env: BUILD_TYPE=Debug - - os: windows + - name: "native windows release" + os: windows env: BUILD_TYPE=Release + - name: "router docker image" + os: linux + dist: xenial + env: DOCKER_FILE=docker/router.Dockerfile + services: docker + - name: "make windows docker image" + os: linux + dist: xenial + env: DOCKER_FILE=docker/alpine-windows.Dockerfile + services: docker + - name: "gcc trunk" + os: linux + dist: xenial + env: DOCKER_FILE=docker/gcc-trunk.Dockerfile + services: docker allow_failures: - os: linux dist: xenial @@ -66,6 +90,12 @@ matrix: dist: xenial env: DOCKER_FILE=docker/gcc-trunk.Dockerfile services: docker + - os: osx + osx_image: xcode10.2 + env: MAKE_TARGET=windows PATH="/usr/local/opt/ccache/libexec:$PATH" + - os: osx + osx_image: xcode10.2 + env: MAKE_TARGET=windows-release PATH="/usr/local/opt/ccache/libexec:$PATH" env: global: @@ -77,6 +107,7 @@ addons: packages: - binutils-gold - build-essential + - clang-format - cmake - curl - docker-ce @@ -94,8 +125,9 @@ addons: - cmake - libuv - llvm - - ninja - make + - mingw-w64 + - ninja before_install: - if [ "$TRAVIS_OS_NAME" == "windows" ]; then diff --git a/CMakeLists.txt b/CMakeLists.txt index 428b39950..4e09a39b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ project(${PROJECT_NAME} C CXX) option(USE_AVX2 "enable avx2 code" ) option(USE_NETNS "enable networking namespace support. Linux only" ) option(AMD_RYZEN_HACK "hack for AMD Ryzen FPU bug (support FMA3 and FMA4 in FPU, but does not show in CPUID)" ) +option(NATIVE_BUILD "optimise for host system and FPU, may not be portable" ) if (NOT MSVC) option(STATIC_LINK_RUNTIME "link statically against compiler runtime, standard library and pthreads") endif() @@ -106,10 +107,10 @@ if(WITH_SHELLHOOKS) add_definitions(-DENABLE_SHELLHOOKS) endif(WITH_SHELLHOOKS) -add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}) +# Always build PIC +set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(ABSEIL_DIR vendor/abseil-cpp) - add_subdirectory(vendor/gtest) add_subdirectory(${ABSEIL_DIR}) include_directories(SYSTEM ${ABSEIL_DIR}) @@ -117,9 +118,6 @@ add_subdirectory(vendor/cxxopts) add_subdirectory(vendor/nlohmann) include_directories(SYSTEM vendor/cxxopts/include) -# Always build PIC -set(CMAKE_POSITION_INDEPENDENT_CODE ON) - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wno-unknown-warning-option) endif() @@ -160,40 +158,18 @@ if(AMD_RYZEN_HACK AND USE_AVX2) message(WARNING "This option may be removed in a future release. Contact your computer manufacturer for updated ROMs or microcode patches.") endif(AMD_RYZEN_HACK AND USE_AVX2) +if(NATIVE_BUILD) + message(WARNING "May fail at runtime if the floating-point unit on the target system does not implement required features, some platforms will check this for you") + set(CRYPTO_FLAGS -march=native -mfpmath=sse -mtune=native) +endif() + +add_compile_options(${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}) + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) -# not supported on Solaris - system libraries are not available as archives -# LTO is supported only for native builds -if(STATIC_LINK_RUNTIME) - if (NOT SOLARIS) - if(NOT CMAKE_CROSSCOMPILING) - add_compile_options(-static -flto) - else() - add_compile_options(-static) - endif() - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - link_libraries( -static -static-libstdc++ -pthread -flto ) - else() - if(NOT CMAKE_CROSSCOMPILING) - # this is messing with release builds - add_compile_options(-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0) - set(CMAKE_AR "gcc-ar") - set(CMAKE_C_ARCHIVE_CREATE " qcs ") - set(CMAKE_C_ARCHIVE_FINISH "true") - set(CMAKE_CXX_ARCHIVE_CREATE " qcs ") - set(CMAKE_CXX_ARCHIVE_FINISH "true") - link_libraries( -flto -static-libstdc++ -static-libgcc -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive ) - else() - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" ) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") - endif() - endif() - else() - link_libraries( -static-libstdc++ -static-libgcc ) - endif() -endif(STATIC_LINK_RUNTIME) +include(cmake/static_link.cmake) if(USE_NETNS) add_definitions(-DNETNS=1) @@ -286,15 +262,20 @@ if(SHADOW) else() if(NOT WIN32) add_executable(${EXE} ${EXE_SRC}) + add_executable(lokinet-rcutil daemon/rcutil.cpp) elseif(NOT MSVC_VERSION) add_executable(${EXE} ${EXE_SRC} llarp/win32/version.rc) + add_executable(lokinet-rcutil daemon/rcutil.cpp llarp/win32/version.rc) else() add_executable(${EXE} ${EXE_SRC}) + add_executable(lokinet-rcutil daemon/rcutil.cpp) endif(NOT WIN32) add_log_tag(${EXE}) + add_log_tag(lokinet-rcutil) install(TARGETS ${EXE} RUNTIME DESTINATION bin) + install(TARGETS lokinet-rcutil RUNTIME DESTINATION bin) if(WIN32) install(PROGRAMS ${CMAKE_SOURCE_DIR}/lokinet-bootstrap.exe DESTINATION bin) else() @@ -306,8 +287,10 @@ else() endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") target_link_directories(${EXE} PRIVATE /usr/local/lib) + target_link_directories(lokinet-rcutil PRIVATE /usr/local/lib) endif() target_link_libraries(${EXE} PUBLIC ${EXE_LIBS} ${LIBS}) + target_link_libraries(lokinet-rcutil PUBLIC ${EXE_LIBS} ${LIBS}) if(ANDROID) add_library(${ANDROID_LIB} SHARED jni/lokinet_android.cpp) diff --git a/Makefile b/Makefile index 6f2e3b591..f82077ddb 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,8 @@ CXX ?= c++ BUILD_TYPE ?= Debug -PYTHON ?= python3 +PYTHON ?= python +PYTHON3 ?= python3 SETCAP ?= which setcap && setcap cap_net_admin,cap_net_bind_service=+eip @@ -165,7 +166,7 @@ shadow-build: shadow-configure $(MAKE) -C $(BUILD_ROOT) shadow-run: shadow-build - $(PYTHON) $(REPO)/contrib/shadow/genconf.py $(SHADOW_CONFIG) + $(PYTHON3) $(REPO)/contrib/shadow/genconf.py $(SHADOW_CONFIG) cp $(SHADOW_PLUGIN) $(REPO)/libshadow-plugin-lokinet.so $(SHADOW_BIN) $(SHADOW_OPTS) $(SHADOW_CONFIG) | $(SHADOW_PARSE) @@ -187,7 +188,7 @@ testnet-build: testnet-configure testnet: cp $(EXE) $(TESTNET_EXE) mkdir -p $(TESTNET_ROOT) - $(PYTHON) $(REPO)/contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --ifname=$(TESTNET_IFNAME) --baseport=$(TESTNET_BASEPORT) --ip=$(TESTNET_IP) --netid=$(TESTNET_NETID) + $(PYTHON3) $(REPO)/contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --ifname=$(TESTNET_IFNAME) --baseport=$(TESTNET_BASEPORT) --ip=$(TESTNET_IP) --netid=$(TESTNET_NETID) LLARP_DEBUG=$(TESTNET_DEBUG) supervisord -n -d $(TESTNET_ROOT) -l $(TESTNET_LOG) -c $(TESTNET_CONF) $(TEST_EXE): debug @@ -243,6 +244,11 @@ abyss: debug format: clang-format -i $$(find jni daemon llarp include libabyss | grep -E '\.[h,c](pp)?$$') +format-verify: format + (type clang-format) + clang-format --version + git diff --quiet || (echo 'Please run make format!!' && git --no-pager diff ; exit 1) + analyze-config: clean mkdir -p '$(BUILD_ROOT)' $(ANALYZE_CONFIG_CMD) @@ -274,7 +280,7 @@ docker-kubernetes: docker build -f docker/loki-svc-kubernetes.Dockerfile . install-pylokinet: - cd $(REPO)/contrib/py/pylokinet && $(PYTHON) setup.py install + cd $(REPO)/contrib/py/pylokinet && $(PYTHON3) setup.py install kubernetes-install: install install-pylokinet diff --git a/cmake/cross_compile.cmake b/cmake/cross_compile.cmake index 1539f3b19..7b3e74799 100644 --- a/cmake/cross_compile.cmake +++ b/cmake/cross_compile.cmake @@ -4,8 +4,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wno-unused-command-line-argument -Wno-c++11-narrowing) add_compile_options($<$:-Wno-bad-function-cast>) if (NO_LIBGCC) - set(CMAKE_CXX_STANDARD_LIBRARIES "-lunwind -lpsapi ${CMAKE_CXX_STANDARD_LIBRARIES}") - set(CMAKE_C_STANDARD_LIBRARIES "-lunwind -lpsapi ${CMAKE_C_STANDARD_LIBRARIES}") + find_library(UNWIND_LIB unwind) + link_libraries(${UNWIND_LIB}) + find_library(PSAPI_LIB psapi) + link_libraries(${PSAPI_LIB}) endif(NO_LIBGCC) else() # found it. this is GNU only diff --git a/cmake/shadow.cmake b/cmake/shadow.cmake index 6bdd95bb1..deed362b1 100644 --- a/cmake/shadow.cmake +++ b/cmake/shadow.cmake @@ -14,5 +14,5 @@ include_directories(${CMAKE_MODULE_PATH}) include(ShadowTools) add_compile_options(-fno-inline -fno-strict-aliasing ) add_definitions(-DTESTNET=1) -add_definitions(-DSHADOW_TESTNET) +add_definitions(-DLOKINET_SHADOW) include_directories(${SHADOW_ROOT}/include) diff --git a/cmake/unix.cmake b/cmake/unix.cmake index 6f23640c2..d991e7a83 100644 --- a/cmake/unix.cmake +++ b/cmake/unix.cmake @@ -2,6 +2,9 @@ if(NOT UNIX) return() endif() +include(CheckCXXSourceCompiles) +include(CheckLibraryExists) + add_definitions(-DUNIX) add_definitions(-DPOSIX) @@ -21,9 +24,49 @@ endif() include_directories(${LIBUV_INCLUDE_DIRS}) +function(check_working_cxx_atomics64 varname) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++14") + check_cxx_source_compiles(" +#include +#include +std::atomic x (0); +int main() { + uint64_t i = x.load(std::memory_order_relaxed); + return 0; +} +" ${varname}) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endfunction() + +function(link_libatomic) + check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB) + + if(HAVE_CXX_ATOMICS64_WITHOUT_LIB) + message(STATUS "Have working 64bit atomics") + return() + endif() + + check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64) + if (HAVE_CXX_LIBATOMICS64) + message(STATUS "Have 64bit atomics via library") + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB) + if (HAVE_CXX_ATOMICS64_WITH_LIB) + message(STATUS "Can link with libatomic") + link_libraries(-latomic) + return() + endif() + endif() + + message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!") +endfunction() + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(FS_LIB stdc++fs) get_filename_component(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-linux.c ABSOLUTE) + + link_libatomic() elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android") find_library(FS_LIB NAMES c++fs c++experimental stdc++fs) if(FS_LIB STREQUAL FS_LIB-NOTFOUND) @@ -42,14 +85,12 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES " set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") find_library(FS_LIB NAMES c++fs c++experimental stdc++fs) - if(FS_LIB STREQUAL FS_LIB-NOTFOUND) add_subdirectory(vendor) include_directories("${CMAKE_CURRENT_LIST_DIR}/../vendor/cppbackport-master/lib") add_definitions(-DLOKINET_USE_CPPBACKPORT) set(FS_LIB cppbackport) endif() - set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c) elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-sunos.c) @@ -60,6 +101,8 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") include_directories("${CMAKE_CURRENT_LIST_DIR}/../vendor/cppbackport-master/lib") add_definitions(-DLOKINET_USE_CPPBACKPORT) set(FS_LIB cppbackport) + else() + set(FS_LIB stdc++fs) endif() else() message(FATAL_ERROR "Your operating system is not supported yet") diff --git a/cmake/win32.cmake b/cmake/win32.cmake index 31f826968..dc8040722 100644 --- a/cmake/win32.cmake +++ b/cmake/win32.cmake @@ -8,6 +8,10 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) if (MSVC OR MSVC_VERSION) add_compile_options(/EHca /arch:AVX2 /MD) add_definitions(-D_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING) + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + add_compile_options(-Wno-nonportable-system-include-path) + endif() endif() if(NOT MSVC_VERSION) diff --git a/contrib/cross/mingw.cmake b/contrib/cross/mingw.cmake index 9521c8009..0a591fb53 100644 --- a/contrib/cross/mingw.cmake +++ b/contrib/cross/mingw.cmake @@ -1,28 +1,16 @@ set(CMAKE_SYSTEM_NAME Windows) set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) set(TOOLCHAIN_SUFFIX "") +set(WIN64_CROSS_COMPILE ON) -add_definitions("-DWINNT_CROSS_COMPILE") - -# target environment on the build host system -# second one is for non-root installs -set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /usr/local/opt/mingw-w64/toolchain-x86_64/ /opt/mingw64 /home/$ENV{USER}/mingw32 /home/$ENV{USER}/mingw64 /home/$ENV{USER}/mingw64/${TOOLCHAIN_PREFIX} /home/$ENV{USER}/mingw32/${TOOLCHAIN_PREFIX}) - -# modify default behavior of FIND_XXX() commands -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -# cross compilers to use -if($ENV{COMPILER} MATCHES "clang") - set(USING_CLANG ON) - set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang) - set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++) -else() - set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc${TOOLCHAIN_SUFFIX}) - set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++${TOOLCHAIN_SUFFIX}) - add_compile_options("-Wa,-mbig-obj") -endif() +set(TOOLCHAIN_PATHS + /usr/${TOOLCHAIN_PREFIX} + /usr/local/opt/mingw-w64/toolchain-x86_64 + /usr/local/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32 + /opt/mingw64 + /home/$ENV{USER}/mingw32 + /home/$ENV{USER}/mingw64 + /home/$ENV{USER}/mingw64/${TOOLCHAIN_PREFIX} + /home/$ENV{USER}/mingw32/${TOOLCHAIN_PREFIX}) -set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) -set(WIN64_CROSS_COMPILE ON) +include("${CMAKE_CURRENT_LIST_DIR}/mingw_core.cmake") diff --git a/contrib/cross/mingw32.cmake b/contrib/cross/mingw32.cmake index 6a853511f..3e1e490ff 100644 --- a/contrib/cross/mingw32.cmake +++ b/contrib/cross/mingw32.cmake @@ -1,26 +1,15 @@ set(CMAKE_SYSTEM_NAME Windows) set(TOOLCHAIN_PREFIX i686-w64-mingw32) +set(TOOLCHAIN_SUFFIX "") +set(WOW64_CROSS_COMPILE ON) -add_definitions("-DWINNT_CROSS_COMPILE") - -# target environment on the build host system -# second one is for non-root installs -set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /opt/mingw32 /home/$ENV{USER}/mingw32 /home/$ENV{USER}/mingw32/${TOOLCHAIN_PREFIX}) - -# modify default behavior of FIND_XXX() commands -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -# cross compilers to use -if($ENV{COMPILER} MATCHES "clang") -set(USING_CLANG ON) -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-clang) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++) -else() -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) -endif() +set(TOOLCHAIN_PATHS + /usr/${TOOLCHAIN_PREFIX} + /usr/local/opt/mingw-w64/toolchain-i686 + /usr/local/opt/mingw-w64/toolchain-i686/i686-w64-mingw32 + /opt/mingw32 + /home/$ENV{USER}/mingw32 + /home/$ENV{USER}/mingw32/${TOOLCHAIN_PREFIX} +) -set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) -set(WOW64_CROSS_COMPILE ON) +include("${CMAKE_CURRENT_LIST_DIR}/mingw_core.cmake") diff --git a/contrib/shadow/genconf.py b/contrib/shadow/genconf.py index 8cc6bf3b2..0a4c0794a 100644 --- a/contrib/shadow/genconf.py +++ b/contrib/shadow/genconf.py @@ -13,7 +13,7 @@ def getSetting(s, name, fallback): return name in s and s[name] or fallback shadowRoot = getSetting(os.environ, "SHADOW_ROOT", os.path.join(os.environ['HOME'], '.shadow')) -libpath = 'libshadow-plugin-lokinet-shared.so' +libpath = 'libshadow-plugin-lokinet.so' def nodeconf(conf, baseDir, name, ifname=None, port=None): diff --git a/crypto/include/sodium/crypto_int32.h b/crypto/include/sodium/crypto_int32.h index 334f570d3..9e5d7ff3b 100644 --- a/crypto/include/sodium/crypto_int32.h +++ b/crypto/include/sodium/crypto_int32.h @@ -1,2 +1,3 @@ +#pragma once #include -typedef int32_t crypto_int32; \ No newline at end of file +typedef int32_t crypto_int32; diff --git a/crypto/include/sodium/crypto_uint32.h b/crypto/include/sodium/crypto_uint32.h index 21bf085a4..0147a9867 100644 --- a/crypto/include/sodium/crypto_uint32.h +++ b/crypto/include/sodium/crypto_uint32.h @@ -1,2 +1,3 @@ +#pragma once #include -typedef uint32_t crypto_uint32; \ No newline at end of file +typedef uint32_t crypto_uint32; diff --git a/crypto/libntrup/src/ref/rq.c b/crypto/libntrup/src/ref/rq.c index 2832c912e..36c21ed7d 100644 --- a/crypto/libntrup/src/ref/rq.c +++ b/crypto/libntrup/src/ref/rq.c @@ -1,5 +1,4 @@ #include "params.h" -#include #include "rq.h" void diff --git a/daemon/rcutil.cpp b/daemon/rcutil.cpp index 380ed7b62..7759032e7 100644 --- a/daemon/rcutil.cpp +++ b/daemon/rcutil.cpp @@ -1,598 +1,99 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include +#include +#include -#include -#include -#include +#include +#include +#include +#include -struct llarp_main *ctx = 0; - -void -handle_signal(int sig) -{ - if(ctx) - llarp_main_signal(ctx, sig); -} - -#ifndef TESTNET -#define TESTNET 0 -#endif - -void -displayRC(const llarp::RouterContact &rc) -{ - std::cout << rc.pubkey << std::endl; - for(const auto &addr : rc.addrs) - { - std::cout << "AddressInfo: " << addr << std::endl; - } -} - -// fwd declr -struct check_online_request; - -void -HandleDHTLocate(llarp_router_lookup_job *job) +bool +dumpRc(const std::vector< std::string >& files, bool json) { - llarp::LogInfo("DHT result: ", job->found ? "found" : "not found"); - if(job->found) - { - // save to nodedb? - displayRC(job->result); - } - // shutdown router - - // well because we're in the gotroutermessage, we can't sigint because we'll - // deadlock because we're session locked - // llarp_main_signal(ctx, SIGINT); - - // llarp_timer_run(logic->timer, logic->thread); - // we'll we don't want logic thread - // but we want to switch back to the main thread - // llarp_logic_stop(); - // still need to exit this logic thread... - llarp_main_abort(ctx); -} - -int -main(int argc, char *argv[]) -{ - // take -c to set location of daemon.ini - // take -o to set log level - // --generate-blank /path/to/file.signed - // --update-ifs /path/to/file.signed - // --key /path/to/long_term_identity.key - // --import - // --export - - // --generate /path/to/file.signed - // --update /path/to/file.signed - // --verify /path/to/file.signed - // printf("has [%d]options\n", argc); - if(argc < 2) - { - printf( - "please specify: \n" - "--generate with a path to a router contact file\n" - "--update with a path to a router contact file\n" - "--list path to nodedb skiplist\n" - "--import with a path to a router contact file\n" - "--export a hex formatted public key\n" - "--locate a hex formatted public key\n" - "--find a base32 formatted service address\n" - "--b32 a hex formatted public key\n" - "--hex a base32 formatted public key\n" - "--localInfo \n" - "--read with a path to a router contact file\n" - "--verify with a path to a router contact file\n" - "\n"); - return 0; - } - bool haveRequiredOptions = false; - bool genMode = false; - bool updMode = false; - bool listMode = false; - bool importMode = false; - bool exportMode = false; - bool locateMode = false; - bool findMode = false; - bool localMode = false; - bool verifyMode = false; - bool readMode = false; - bool toHexMode = false; - bool toB32Mode = false; - int c; - char *conffname; - char defaultConfName[] = "daemon.ini"; - conffname = defaultConfName; - char *rcfname = nullptr; - char *nodesdir = nullptr; - - llarp::RouterContact rc; - while(1) - { - static struct option long_options[] = { - {"file", required_argument, 0, 'f'}, - {"config", required_argument, 0, 'c'}, - {"logLevel", required_argument, 0, 'o'}, - {"generate", required_argument, 0, 'g'}, - {"update", required_argument, 0, 'u'}, - {"list", required_argument, 0, 'l'}, - {"import", required_argument, 0, 'i'}, - {"export", required_argument, 0, 'e'}, - {"locate", required_argument, 0, 'q'}, - {"find", required_argument, 0, 'F'}, - {"localInfo", no_argument, 0, 'n'}, - {"read", required_argument, 0, 'r'}, - {"b32", required_argument, 0, 'b'}, - {"hex", required_argument, 0, 'h'}, - {"verify", required_argument, 0, 'V'}, - {0, 0, 0, 0}}; - int option_index = 0; - c = getopt_long(argc, argv, "c:f:o:g:lu:i:e:q:F:nr:b:h:V:", long_options, - &option_index); -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) - if(c == -1) - break; - switch(c) - { - case 0: - break; - case 'c': - conffname = optarg; - break; - case 'o': - if(strncmp(optarg, "debug", - MIN(strlen(optarg), static_cast< unsigned long >(5))) - == 0) - { - llarp::SetLogLevel(llarp::eLogDebug); - } - else if(strncmp(optarg, "info", - MIN(strlen(optarg), static_cast< unsigned long >(4))) - == 0) - { - llarp::SetLogLevel(llarp::eLogInfo); - } - else if(strncmp(optarg, "warn", - MIN(strlen(optarg), static_cast< unsigned long >(4))) - == 0) - { - llarp::SetLogLevel(llarp::eLogWarn); - } - else if(strncmp(optarg, "error", - MIN(strlen(optarg), static_cast< unsigned long >(5))) - == 0) - { - llarp::SetLogLevel(llarp::eLogError); - } - break; - case 'V': - rcfname = optarg; - haveRequiredOptions = true; - verifyMode = true; - break; - case 'f': - rcfname = optarg; - break; - case 'l': - nodesdir = optarg; - listMode = true; - break; - case 'i': - // printf ("option -g with value `%s'\n", optarg); - nodesdir = optarg; - importMode = true; - break; - case 'e': - // printf ("option -g with value `%s'\n", optarg); - rcfname = optarg; - exportMode = true; - break; - case 'q': - // printf ("option -g with value `%s'\n", optarg); - rcfname = optarg; - locateMode = true; - break; - case 'F': - rcfname = optarg; - haveRequiredOptions = true; - findMode = true; - break; - case 'g': - // printf ("option -g with value `%s'\n", optarg); - rcfname = optarg; - genMode = true; - break; - case 'u': - // printf ("option -u with value `%s'\n", optarg); - rcfname = optarg; - updMode = true; - break; - case 'n': - localMode = true; - break; - case 'r': - rcfname = optarg; - readMode = true; - break; - case 'b': - rcfname = optarg; - haveRequiredOptions = true; - toB32Mode = true; - break; - case 'h': - rcfname = optarg; - haveRequiredOptions = true; - toHexMode = true; - break; - default: - printf("Bad option: %c\n", c); - return -1; - } - } -#undef MIN - if(!haveRequiredOptions) - { - llarp::LogError("Parameters dont all have their required parameters.\n"); - return 0; - } - // printf("parsed options\n"); - - if(!genMode && !updMode && !listMode && !importMode && !exportMode - && !locateMode && !localMode && !readMode && !findMode && !toB32Mode - && !toHexMode && !verifyMode) + nlohmann::json result; + for(const auto& file : files) { - llarp::LogError( - "I don't know what to do, no generate or update parameter\n"); - return 1; - } - -#ifdef LOKINET_DEBUG - absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); -#endif + llarp::RouterContact rc; + const bool ret = rc.Read(file.c_str()); - llarp::RouterContact tmp; - - if(verifyMode) - { - llarp::Crypto crypto(llarp::Crypto::sodium{}); - if(!rc.Read(rcfname)) + if(ret) { - std::cout << "failed to read " << rcfname << std::endl; - return 1; - } - if(!rc.Verify(&crypto)) - { - std::cout << rcfname << " is invalid" << std::endl; - return 1; - } - if(!rc.IsPublicRouter()) - { - std::cout << rcfname << " is not a public router"; - if(rc.addrs.size() == 0) + if(json) { - std::cout << " because it has no public addresses"; + result[file] = rc.ToJson(); } - std::cout << std::endl; - return 1; - } - - std::cout << "router identity and dht routing key: " << rc.pubkey - << std::endl; - - std::cout << "router encryption key: " << rc.enckey << std::endl; - - if(rc.HasNick()) - std::cout << "router nickname: " << rc.Nick() << std::endl; - - std::cout << "advertised addresses: " << std::endl; - for(const auto &addr : rc.addrs) - { - std::cout << addr << std::endl; - } - std::cout << std::endl; - - std::cout << "advertised exits: "; - if(rc.exits.size()) - { - for(const auto &exit : rc.exits) + else { - std::cout << exit << std::endl; + std::cout << "file = " << file << "\n"; + std::cout << rc << "\n\n"; } } else { - std::cout << "none"; + std::cerr << "file = " << file << " was not a valid rc file\n"; } - std::cout << std::endl; - return 0; } - ctx = llarp_main_init(conffname, !TESTNET); - if(!ctx) - { - llarp::LogError("Cant set up context"); - return 1; - } - signal(SIGINT, handle_signal); + if(json) + std::cout << result << "\n"; - // is this Neuro or Jeff's? - // this is the only one... - if(listMode) - { - llarp::Crypto crypto(llarp::Crypto::sodium{}); - auto nodedb = llarp_nodedb_new(&crypto); - llarp_nodedb_iter itr; - itr.visit = [](llarp_nodedb_iter *i) -> bool { - std::cout << i->rc->pubkey << std::endl; - return true; - }; - if(llarp_nodedb_load_dir(nodedb, nodesdir) > 0) - llarp_nodedb_iterate_all(nodedb, itr); - llarp_nodedb_free(&nodedb); - return 0; - } - - if(importMode) - { - if(rcfname == nullptr) - { - std::cout << "no file to import" << std::endl; - return 1; - } - llarp::Crypto crypto(llarp::Crypto::sodium{}); - auto nodedb = llarp_nodedb_new(&crypto); - if(!llarp_nodedb_ensure_dir(nodesdir)) - { - std::cout << "failed to ensure " << nodesdir << strerror(errno) - << std::endl; - return 1; - } - llarp_nodedb_set_dir(nodedb, nodesdir); - if(!rc.Read(rcfname)) - { - std::cout << "failed to read " << rcfname << " " << strerror(errno) - << std::endl; - return 1; - } - - if(!rc.Verify(&crypto)) - { - std::cout << rcfname << " is invalid" << std::endl; - return 1; - } + return true; +} - if(!llarp_nodedb_put_rc(nodedb, rc)) - { - std::cout << "failed to store " << strerror(errno) << std::endl; - return 1; - } +int +main(int argc, char* argv[]) +{ +#ifdef LOKINET_DEBUG + absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); +#endif - std::cout << "imported " << rc.pubkey << std::endl; + // clang-format off + cxxopts::Options options( + "lokinet-rcutil", + "LokiNET is a free, open source, private, decentralized, \"market based sybil resistant\" and IP based onion routing network" + ); - return 0; - } + options.add_options() + ("v,verbose", "Verbose", cxxopts::value()) + ("h,help", "help", cxxopts::value()) + ("j,json", "output in json", cxxopts::value()) + ("dump", "dump rc file", cxxopts::value >(), "FILE"); + // clang-format on - if(genMode) + try { - printf("Creating [%s]\n", rcfname); - // if we zero it out then - // set updated timestamp - rc.last_updated = llarp::time_now_ms(); - // load longterm identity - llarp::Crypto crypt(llarp::Crypto::sodium{}); - - // which is in daemon.ini config: router.encryption-privkey (defaults - // "encryption.key") - fs::path encryption_keyfile = "encryption.key"; - llarp::SecretKey encryption; + const auto result = options.parse(argc, argv); - llarp_findOrCreateEncryption(&crypt, encryption_keyfile, encryption); + const bool json = result["json"].as< bool >(); - rc.enckey = llarp::seckey_topublic(encryption); - - // get identity public sig key - fs::path ident_keyfile = "identity.key"; - llarp::SecretKey identity; - llarp_findOrCreateIdentity(&crypt, ident_keyfile, identity); - - rc.pubkey = llarp::seckey_topublic(identity); - - // this causes a segfault - if(!rc.Sign(&crypt, identity)) + if(result.count("verbose") > 0) { - std::cout << "failed to sign" << std::endl; - return 1; + SetLogLevel(llarp::eLogDebug); + llarp::LogContext::Instance().logStream = + std::make_unique< llarp::OStreamLogStream >(std::cerr); + llarp::LogDebug("debug logging activated"); } - // set filename - fs::path our_rc_file = rcfname; - // write file - rc.Write(our_rc_file.string().c_str()); - - // llarp_rc_write(&tmp, our_rc_file.string().c_str()); - - // release memory for tmp lists - // llarp_rc_free(&tmp); - } - if(updMode) - { - printf("rcutil.cpp - Loading [%s]\n", rcfname); - llarp::RouterContact tmp; - // llarp_rc_clear(&rc); - rc.Clear(); - // FIXME: new rc api - // llarp_rc_read(rcfname, &rc); - - // set updated timestamp - rc.last_updated = llarp::time_now_ms(); - // load longterm identity - llarp::Crypto crypt(llarp::Crypto::sodium{}); - // no longer used? - // llarp_crypto_libsodium_init(&crypt); - llarp::SecretKey identityKey; // FIXME: Jeff requests we use this - fs::path ident_keyfile = "identity.key"; - llarp::SecretKey identity; - llarp_findOrCreateIdentity(&crypt, ident_keyfile, identity); - - // FIXME: update RC API - // get identity public key - // const uint8_t *pubkey = llarp::seckey_topublic(identity); - - // FIXME: update RC API - // llarp_rc_set_pubsigkey(&rc, pubkey); - // // FIXME: update RC API - // llarp_rc_sign(&crypt, identity, &rc); - - // set filename - fs::path our_rc_file_out = "update_debug.rc"; - // write file - // FIXME: update RC API - // rc.Write(our_rc_file.string().c_str()); - // llarp_rc_write(&tmp, our_rc_file_out.string().c_str()); - } - - if(listMode) - { - llarp::Crypto crypto(llarp::Crypto::sodium{}); - auto nodedb = llarp_nodedb_new(&crypto); - llarp_nodedb_iter itr; - itr.visit = [](llarp_nodedb_iter *i) -> bool { - std::cout << llarp::PubKey(i->rc->pubkey) << std::endl; - return true; - }; - if(llarp_nodedb_load_dir(nodedb, nodesdir) > 0) - llarp_nodedb_iterate_all(nodedb, itr); - llarp_nodedb_free(&nodedb); - return 0; - } - if(exportMode) - { - llarp_main_loadDatabase(ctx); - // llarp::LogInfo("Looking for string: ", rcfname); - - llarp::PubKey binaryPK; - llarp::HexDecode(rcfname, binaryPK.data(), binaryPK.size()); - - llarp::LogInfo("Looking for binary: ", binaryPK); - llarp::RouterContact *rc = llarp_main_getDatabase(ctx, binaryPK.data()); - if(!rc) + if(result.count("help") > 0) { - llarp::LogError("Can't load RC from database"); + std::cout << options.help() << std::endl; + return 0; } - std::string filename(rcfname); - filename.append(".signed"); - llarp::LogInfo("Writing out: ", filename); - // FIXME: update RC API - // rc.Write(our_rc_file.string().c_str()); - // llarp_rc_write(rc, filename.c_str()); - } - if(locateMode) - { - llarp::LogInfo("Going online"); - llarp_main_setup(ctx); - - llarp::PubKey binaryPK; - llarp::HexDecode(rcfname, binaryPK.data(), binaryPK.size()); - - llarp::LogInfo("Queueing job"); - llarp_router_lookup_job *job = new llarp_router_lookup_job; - job->iterative = true; - job->found = false; - job->hook = &HandleDHTLocate; - // llarp_rc_new(&job->result); - job->target = binaryPK; // set job's target - - // create query DHT request - check_online_request *request = new check_online_request; - request->ptr = ctx; - request->job = job; - request->online = false; - request->nodes = 0; - request->first = false; - llarp_main_queryDHT(request); - - llarp::LogInfo("Processing"); - // run system and wait - llarp_main_run(ctx); - } - if(findMode) - { - llarp::LogInfo("Going online"); - llarp_main_setup(ctx); - - llarp::LogInfo("Please find ", rcfname); - std::string str(rcfname); - - llarp::service::Tag tag(rcfname); - llarp::LogInfo("Tag ", tag); - - llarp::service::Address addr; - str = str.append(".loki"); - llarp::LogInfo("Prestring ", str); - bool res = addr.FromString(str.c_str()); - llarp::LogInfo(res ? "Success" : "not a base32 string"); - - // Base32Decode(rcfname, addr); - llarp::LogInfo("Addr ", addr); - // uint64_t txid, const llarp::service::Address& addr - // FIXME: new API? - // msg->M.push_back(new llarp::dht::FindIntroMessage(tag, 1)); - - // I guess we may need a router to get any replies - llarp::LogInfo("Processing"); - // run system and wait - llarp_main_run(ctx); - } - if(localMode) - { - // FIXME: update llarp_main_getLocalRC - // llarp::RouterContact *rc = llarp_main_getLocalRC(ctx); - // displayRC(rc); - // delete it - } - { - if(rc.Read(rcfname)) - displayRC(rc); + if(result.count("dump") > 0) + { + if(!dumpRc(result["dump"].as< std::vector< std::string > >(), json)) + { + return 1; + } + } } - - if(toB32Mode) + catch(const cxxopts::OptionParseException& ex) { - llarp::LogInfo("Converting hex string ", rcfname); - std::string str(rcfname); - - llarp::PubKey binaryPK; - // llarp::service::Address::FromString - llarp::HexDecode(rcfname, binaryPK.data(), binaryPK.size()); - char tmp[(1 + 32) * 2] = {0}; - std::string b32 = llarp::Base32Encode(binaryPK, tmp); - llarp::LogInfo("to base32 ", b32); + std::cerr << ex.what() << std::endl; + std::cout << options.help() << std::endl; + return 1; } - if(toHexMode) - { - llarp::service::Address addr; - llarp::Base32Decode(rcfname, addr); - llarp::LogInfo("Converting base32 string ", addr); - - // llarp::service::Address::ToString - char ftmp[68] = {0}; - const char *hexname = - llarp::HexEncode< llarp::service::Address, decltype(ftmp) >(addr, ftmp); - llarp::LogInfo("to hex ", hexname); - } - // it's a unique_ptr, should clean up itself - // llarp_main_free(ctx); - return 0; // success + return 0; } diff --git a/docker/router.Dockerfile b/docker/router.Dockerfile index 7e0c00549..33c913bdf 100644 --- a/docker/router.Dockerfile +++ b/docker/router.Dockerfile @@ -1,3 +1,4 @@ +ARG bootstrap="https://i2p.rocks/i2procks.signed" FROM alpine:edge as builder RUN apk update && \ @@ -7,7 +8,7 @@ WORKDIR /src/ COPY . /src/ RUN make NINJA=ninja STATIC_LINK=ON BUILD_TYPE=Release -RUN ./lokinet-bootstrap +RUN ./lokinet-bootstrap ${bootstrap} FROM alpine:latest diff --git a/include/tuntap.h b/include/tuntap.h index 8a56eb28e..6cc444a70 100644 --- a/include/tuntap.h +++ b/include/tuntap.h @@ -147,7 +147,7 @@ extern "C" int flags; /* ifr.ifr_flags on Unix */ char if_name[IF_NAMESIZE]; #if defined(Windows) - int idx; /* needed to set ipv6 address */ + int idx; /* needed to set ipv6 address */ #endif #if defined(FreeBSD) int mode; diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 36510c0e1..fd6a36fbc 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -2,6 +2,7 @@ set(LIB_UTIL_SRC config/config.cpp config/ini.cpp constants/defaults.cpp + constants/limits.cpp constants/link_layer.cpp constants/path.cpp constants/proto.cpp @@ -175,9 +176,11 @@ set(LIB_SRC handlers/null.cpp handlers/tun.cpp hook/shell.cpp - iwp/linklayer.cpp - iwp/outermessage.cpp iwp/iwp.cpp + iwp/linklayer.cpp + iwp/message_buffer.cpp + iwp/session.cpp + link/factory.cpp link/i_link_manager.cpp link/link_manager.cpp link/server.cpp diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index bf10ff91d..78f5e3a94 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -2,14 +2,18 @@ #include #include +#include #include +#include #include -#include #include +#include #include #include #include +#include + #include #include #include @@ -30,9 +34,28 @@ namespace llarp return std::atoi(str.c_str()); } + absl::optional< bool > + setOptBool(string_view val) + { + if(IsTrueValue(val)) + { + return true; + } + else if(IsFalseValue(val)) + { + return false; + } + return {}; + } + void RouterConfig::fromSection(string_view key, string_view val) { + if(key == "default-protocol") + { + m_DefaultLinkProto = tostr(val); + LogInfo("overriding default link protocol to '", val, "'"); + } if(key == "netid") { if(val.size() <= NetID::size()) @@ -138,6 +161,10 @@ namespace llarp LogDebug("set to use ", m_numNetThreads, " net threads"); } } + if(key == "block-bogons") + { + m_blockBogons = setOptBool(val); + } } void @@ -145,14 +172,7 @@ namespace llarp { if(key == "profiling") { - if(IsTrueValue(val)) - { - m_enableProfiling.emplace(true); - } - else if(IsFalseValue(val)) - { - m_enableProfiling.emplace(false); - } + m_enableProfiling = setOptBool(val); } else if(key == "profiles") { @@ -194,28 +214,31 @@ namespace llarp } void - IwpConfig::fromSection(string_view key, string_view val) + LinksConfig::fromSection(string_view key, string_view val) { - // try IPv4 first uint16_t proto = 0; - std::set< std::string > parsed_opts; + std::unordered_set< std::string > parsed_opts; std::string v = tostr(val); std::string::size_type idx; + static constexpr char delimiter = ','; do { - idx = v.find_first_of(','); + idx = v.find_first_of(delimiter); if(idx != std::string::npos) { - parsed_opts.insert(v.substr(0, idx)); + std::string val = v.substr(0, idx); + absl::StripAsciiWhitespace(&val); + parsed_opts.emplace(std::move(val)); v = v.substr(idx + 1); } else { - parsed_opts.insert(v); + absl::StripAsciiWhitespace(&v); + parsed_opts.insert(std::move(v)); } } while(idx != std::string::npos); - + std::unordered_set< std::string > opts; /// for each option for(const auto &item : parsed_opts) { @@ -229,15 +252,20 @@ namespace llarp proto = port; } } + else + { + opts.insert(item); + } } if(key == "*") { - m_OutboundPort = proto; + m_OutboundLink = std::make_tuple( + "*", AF_INET, fromEnv(proto, "OUTBOUND_PORT"), std::move(opts)); } else { - m_servers.emplace_back(tostr(key), AF_INET, proto); + m_InboundLinks.emplace_back(tostr(key), AF_INET, proto, std::move(opts)); } } @@ -397,7 +425,9 @@ namespace llarp }; if(c.VisitSection(name.c_str(), visitor)) + { return ret; + } return {}; } @@ -434,7 +464,7 @@ namespace llarp connect = find_section< ConnectConfig >(parser, "connect"); netdb = find_section< NetdbConfig >(parser, "netdb"); dns = find_section< DnsConfig >(parser, "dns"); - iwp_links = find_section< IwpConfig >(parser, "bind"); + links = find_section< LinksConfig >(parser, "bind"); services = find_section< ServicesConfig >(parser, "services"); system = find_section< SystemConfig >(parser, "system"); metrics = find_section< MetricsConfig >(parser, "metrics"); @@ -464,7 +494,7 @@ llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, return false; } - std::string basepath = ""; + std::string basepath; if(basedir) { basepath = basedir; @@ -501,7 +531,7 @@ llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, return false; } auto &f = optional_f.value(); - llarp_generic_ensure_config(f, basepath); + llarp_generic_ensure_config(f, basepath, asRouter); if(asRouter) { llarp_ensure_router_config(f, basepath); @@ -515,63 +545,70 @@ llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, } void -llarp_generic_ensure_config(std::ofstream &f, std::string basepath) +llarp_generic_ensure_config(std::ofstream &f, std::string basepath, + bool isRouter) { - f << "# this configuration was auto generated with 'sane' defaults" - << std::endl; - f << "# change these values as desired" << std::endl; - f << std::endl << std::endl; - f << "[router]" << std::endl; - f << "# number of crypto worker threads " << std::endl; - f << "threads=4" << std::endl; - f << "# path to store signed RC" << std::endl; - f << "contact-file=" << basepath << "self.signed" << std::endl; - f << "# path to store transport private key" << std::endl; - f << "transport-privkey=" << basepath << "transport.private" << std::endl; - f << "# path to store identity signing key" << std::endl; - f << "ident-privkey=" << basepath << "identity.private" << std::endl; - f << "# encryption key for onion routing" << std::endl; - f << "encryption-privkey=" << basepath << "encryption.private" << std::endl; + f << "# this configuration was auto generated with 'sane' defaults\n"; + f << "# change these values as desired\n"; + f << "\n\n"; + f << "[router]\n"; + f << "# number of crypto worker threads \n"; + f << "threads=4\n"; + f << "# path to store signed RC\n"; + f << "contact-file=" << basepath << "self.signed\n"; + f << "# path to store transport private key\n"; + f << "transport-privkey=" << basepath << "transport.private\n"; + f << "# path to store identity signing key\n"; + f << "ident-privkey=" << basepath << "identity.private\n"; + f << "# encryption key for onion routing\n"; + f << "encryption-privkey=" << basepath << "encryption.private\n"; f << std::endl; f << "# uncomment following line to set router nickname to 'lokinet'" << std::endl; - f << "#nickname=lokinet" << std::endl; - f << std::endl << std::endl; + f << "#nickname=lokinet\n"; + const auto limits = isRouter ? llarp::limits::snode : llarp::limits::client; + + f << "# maintain min connections to other routers\n"; + f << "min-routers=" << std::to_string(limits.DefaultMinRouters) << std::endl; + f << "# hard limit of routers globally we are connected to at any given " + "time\n"; + f << "max-routers=" << std::to_string(limits.DefaultMaxRouters) << std::endl; + f << "\n\n"; // logging - f << "[logging]" << std::endl; - f << "level=info" << std::endl; - f << "# uncomment for logging to file" << std::endl; - f << "#type=file" << std::endl; - f << "#file=/path/to/logfile" << std::endl; - f << "# uncomment for syslog logging" << std::endl; - f << "#type=syslog" << std::endl; + f << "[logging]\n"; + f << "level=info\n"; + f << "# uncomment for logging to file\n"; + f << "#type=file\n"; + f << "#file=/path/to/logfile\n"; + f << "# uncomment for syslog logging\n"; + f << "#type=syslog\n"; // metrics - f << "[metrics]" << std::endl; - f << "json-metrics-path=" << basepath << "metrics.json" << std::endl; - - f << std::endl << std::endl; - - f << "# admin api (disabled by default)" << std::endl; - f << "[api]" << std::endl; - f << "enabled=false" << std::endl; - f << "#authkey=insertpubkey1here" << std::endl; - f << "#authkey=insertpubkey2here" << std::endl; - f << "#authkey=insertpubkey3here" << std::endl; - f << "bind=127.0.0.1:1190" << std::endl; - f << std::endl << std::endl; - - f << "# system settings for privileges and such" << std::endl; - f << "[system]" << std::endl; + f << "[metrics]\n"; + f << "json-metrics-path=" << basepath << "metrics.json\n"; + + f << "\n\n"; + + f << "# admin api (disabled by default)\n"; + f << "[api]\n"; + f << "enabled=false\n"; + f << "#authkey=insertpubkey1here\n"; + f << "#authkey=insertpubkey2here\n"; + f << "#authkey=insertpubkey3here\n"; + f << "bind=127.0.0.1:1190\n"; + f << "\n\n"; + + f << "# system settings for privileges and such\n"; + f << "[system]\n"; f << "user=" << DEFAULT_LOKINET_USER << std::endl; f << "group=" << DEFAULT_LOKINET_GROUP << std::endl; - f << "pidfile=" << basepath << "lokinet.pid" << std::endl; - f << std::endl << std::endl; + f << "pidfile=" << basepath << "lokinet.pid\n"; + f << "\n\n"; - f << "# dns provider configuration section" << std::endl; - f << "[dns]" << std::endl; - f << "# resolver" << std::endl; + f << "# dns provider configuration section\n"; + f << "[dns]\n"; + f << "# resolver\n"; f << "upstream=" << DEFAULT_RESOLVER_US << std::endl; // Make auto-config smarter @@ -579,65 +616,68 @@ llarp_generic_ensure_config(std::ofstream &f, std::string basepath) // (probably) #ifdef __linux__ #ifdef ANDROID - f << "bind=127.0.0.1:1153" << std::endl; + f << "bind=127.0.0.1:1153\n"; #else - f << "bind=127.3.2.1:53" << std::endl; + f << "bind=127.3.2.1:53\n"; #endif #else - f << "bind=127.0.0.1:53" << std::endl; + f << "bind=127.0.0.1:53\n"; #endif - f << std::endl << std::endl; + f << "\n\n"; - f << "# network database settings block " << std::endl; - f << "[netdb]" << std::endl; - f << "# directory for network database skiplist storage" << std::endl; - f << "dir=" << basepath << "netdb" << std::endl; - f << std::endl << std::endl; + f << "# network database settings block \n"; + f << "[netdb]\n"; + f << "# directory for network database skiplist storage\n"; + f << "dir=" << basepath << "netdb\n"; + f << "\n\n"; - f << "# bootstrap settings" << std::endl; - f << "[bootstrap]" << std::endl; + f << "# bootstrap settings\n"; + f << "[bootstrap]\n"; f << "# add a bootstrap node's signed identity to the list of nodes we want " - "to bootstrap from" - << std::endl; - f << "# if we don't have any peers we connect to this router" << std::endl; - f << "add-node=" << basepath << "bootstrap.signed" << std::endl; + "to bootstrap from\n"; + f << "# if we don't have any peers we connect to this router\n"; + f << "add-node=" << basepath << "bootstrap.signed\n"; // we only process one of these... - // f << "# add another bootstrap node" << std::endl; - // f << "#add-node=/path/to/alternative/self.signed" << std::endl; - f << std::endl << std::endl; + // f << "# add another bootstrap node\n"; + // f << "#add-node=/path/to/alternative/self.signed\n"; + f << "\n\n"; } void llarp_ensure_router_config(std::ofstream &f, std::string basepath) { - f << "# lokid settings (disabled by default)" << std::endl; - f << "[lokid]" << std::endl; - f << "enabled=false" << std::endl; - f << "jsonrpc=127.0.0.1:22023" << std::endl; - f << "#service-node-seed=/path/to/servicenode/seed" << std::endl; + f << "# lokid settings (disabled by default)\n"; + f << "[lokid]\n"; + f << "enabled=false\n"; + f << "jsonrpc=127.0.0.1:22023\n"; + f << "#service-node-seed=/path/to/servicenode/seed\n"; f << std::endl; - f << "# network settings " << std::endl; - f << "[network]" << std::endl; - f << "profiles=" << basepath << "profiles.dat" << std::endl; + f << "# network settings \n"; + f << "[network]\n"; + f << "profiles=" << basepath << "profiles.dat\n"; // better to let the routers auto-configure - // f << "ifaddr=auto" << std::endl; - // f << "ifname=auto" << std::endl; - f << "enabled=true" << std::endl; - f << "exit=false" << std::endl; - f << "#exit-blacklist=tcp:25" << std::endl; - f << "#exit-whitelist=tcp:*" << std::endl; - f << "#exit-whitelist=udp:*" << std::endl; + // f << "ifaddr=auto\n"; + // f << "ifname=auto\n"; + f << "enabled=true\n"; + f << "exit=false\n"; + f << "#exit-blacklist=tcp:25\n"; + f << "#exit-whitelist=tcp:*\n"; + f << "#exit-whitelist=udp:*\n"; f << std::endl; - f << "# ROUTERS ONLY: publish network interfaces for handling inbound traffic" - << std::endl; - f << "[bind]" << std::endl; + f << "# ROUTERS ONLY: publish network interfaces for handling inbound " + "traffic\n"; + f << "[bind]\n"; // get ifname std::string ifname; if(llarp::GetBestNetIF(ifname, AF_INET)) - f << ifname << "=1090" << std::endl; + { + f << ifname << "=1090\n"; + } else - f << "# could not autodetect network interface" << std::endl - << "#eth0=1090" << std::endl; + { + f << "# could not autodetect network interface\n" + << "#eth0=1090\n"; + } f << std::endl; } @@ -651,7 +691,9 @@ llarp_ensure_client_config(std::ofstream &f, std::string basepath) auto stream = llarp::util::OpenFileStream< std::ofstream >( snappExample_fpath, std::ios::binary); if(!stream) + { return false; + } auto &example_f = stream.value(); if(example_f.is_open()) { @@ -667,23 +709,18 @@ llarp_ensure_client_config(std::ofstream &f, std::string basepath) return false; } */ - example_f << "# this is an example configuration for a snapp" - << std::endl; - example_f << "[example-snapp]" << std::endl; + example_f << "# this is an example configuration for a snapp\n"; + example_f << "[example-snapp]\n"; example_f << "# keyfile is the path to the private key of the snapp, " - "your .loki is tied to this key, DON'T LOSE IT" - << std::endl; - example_f << "keyfile=" << basepath << "example-snap-keyfile.private" - << std::endl; - example_f << "# ifaddr is the ip range to allocate to this snapp" - << std::endl; + "your .loki is tied to this key, DON'T LOSE IT\n"; + example_f << "keyfile=" << basepath << "example-snap-keyfile.private\n"; + example_f << "# ifaddr is the ip range to allocate to this snapp\n"; example_f << "ifaddr=" << ip << std::endl; // probably fine to leave this (and not-auto-detect it) I'm not worried // about any collisions example_f << "# ifname is the name to try and give to the network " - "interface this snap owns" - << std::endl; - example_f << "ifname=snapp-tun0" << std::endl; + "interface this snap owns\n"; + example_f << "ifname=snapp-tun0\n"; } else { @@ -691,31 +728,29 @@ llarp_ensure_client_config(std::ofstream &f, std::string basepath) } } // now do up fname - f << std::endl << std::endl; - f << "# snapps configuration section" << std::endl; - f << "[services]"; - f << "# uncomment next line to enable a snapp" << std::endl; + f << "\n\n"; + f << "# snapps configuration section\n"; + f << "[services]\n"; + f << "# uncomment next line to enable a snapp\n"; f << "#example-snapp=" << snappExample_fpath << std::endl; - f << std::endl << std::endl; + f << "\n\n"; - f << "# network settings " << std::endl; - f << "[network]" << std::endl; - f << "profiles=" << basepath << "profiles.dat" << std::endl; + f << "# network settings \n"; + f << "[network]\n"; + f << "profiles=" << basepath << "profiles.dat\n"; f << "# uncomment next line to add router with pubkey to list of routers we " - "connect directly to" - << std::endl; - f << "#strict-connect=pubkey" << std::endl; - f << "# uncomment next line to use router with pubkey as an exit node" - << std::endl; - f << "#exit-node=pubkey" << std::endl; + "connect directly to\n"; + f << "#strict-connect=pubkey\n"; + f << "# uncomment next line to use router with pubkey as an exit node\n"; + f << "#exit-node=pubkey\n"; // better to set them to auto then to hard code them now // operating environment may change over time and this will help adapt - // f << "ifname=auto" << std::endl; - // f << "ifaddr=auto" << std::endl; + // f << "ifname=auto\n"; + // f << "ifaddr=auto\n"; // should this also be auto? or not declared? // probably auto in case they want to set up a hidden service - f << "enabled=true" << std::endl; + f << "enabled=true\n"; return true; } diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 6ed3ee297..25df1815a 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace llarp { @@ -27,10 +28,8 @@ namespace llarp { return ptr; } - else - { - return val; - } + + return val; } template <> @@ -43,10 +42,8 @@ namespace llarp { return std::atoi(ptr); } - else - { - return val; - } + + return val; } template <> @@ -59,10 +56,8 @@ namespace llarp { return std::atoi(ptr); } - else - { - return val; - } + + return val; } template <> @@ -75,10 +70,8 @@ namespace llarp { return std::atoll(ptr); } - else - { - return val; - } + + return val; } template <> @@ -92,10 +85,8 @@ namespace llarp { return IsTrueValue(ptr); } - else - { - return val; - } + + return val; } class RouterConfig @@ -105,7 +96,7 @@ namespace llarp size_t m_minConnectedRouters = 2; /// hard upperbound limit on the number of router to router connections - size_t m_maxConnectedRouters = 2000; + size_t m_maxConnectedRouters = 5; std::string m_netId; std::string m_nickname; @@ -121,6 +112,8 @@ namespace llarp // long term identity key std::string m_identKeyfile = "identity.key"; + absl::optional< bool > m_blockBogons; + bool m_publicOverride = false; struct sockaddr_in m_ip4addr; AddressInfo m_addrInfo; @@ -128,21 +121,25 @@ namespace llarp int m_workerThreads = 1; int m_numNetThreads = 1; + std::string m_DefaultLinkProto = "iwp"; + public: // clang-format off - size_t minConnectedRouters() const { return fromEnv(m_minConnectedRouters, "MIN_CONNECTED_ROUTERS"); } - size_t maxConnectedRouters() const { return fromEnv(m_maxConnectedRouters, "MAX_CONNECTED_ROUTERS"); } - std::string encryptionKeyfile() const { return fromEnv(m_encryptionKeyfile, "ENCRYPTION_KEYFILE"); } - std::string ourRcFile() const { return fromEnv(m_ourRcFile, "OUR_RC_FILE"); } - std::string transportKeyfile() const { return fromEnv(m_transportKeyfile, "TRANSPORT_KEYFILE"); } - std::string identKeyfile() const { return fromEnv(m_identKeyfile, "IDENT_KEYFILE"); } - std::string netId() const { return fromEnv(m_netId, "NETID"); } - std::string nickname() const { return fromEnv(m_nickname, "NICKNAME"); } - bool publicOverride() const { return fromEnv(m_publicOverride, "PUBLIC_OVERRIDE"); } - const struct sockaddr_in& ip4addr() const { return m_ip4addr; } - const AddressInfo& addrInfo() const { return m_addrInfo; } - int workerThreads() const { return fromEnv(m_workerThreads, "WORKER_THREADS"); } - int numNetThreads() const { return fromEnv(m_numNetThreads, "NUM_NET_THREADS"); } + size_t minConnectedRouters() const { return fromEnv(m_minConnectedRouters, "MIN_CONNECTED_ROUTERS"); } + size_t maxConnectedRouters() const { return fromEnv(m_maxConnectedRouters, "MAX_CONNECTED_ROUTERS"); } + std::string encryptionKeyfile() const { return fromEnv(m_encryptionKeyfile, "ENCRYPTION_KEYFILE"); } + std::string ourRcFile() const { return fromEnv(m_ourRcFile, "OUR_RC_FILE"); } + std::string transportKeyfile() const { return fromEnv(m_transportKeyfile, "TRANSPORT_KEYFILE"); } + std::string identKeyfile() const { return fromEnv(m_identKeyfile, "IDENT_KEYFILE"); } + std::string netId() const { return fromEnv(m_netId, "NETID"); } + std::string nickname() const { return fromEnv(m_nickname, "NICKNAME"); } + bool publicOverride() const { return fromEnv(m_publicOverride, "PUBLIC_OVERRIDE"); } + const struct sockaddr_in& ip4addr() const { return m_ip4addr; } + const AddressInfo& addrInfo() const { return m_addrInfo; } + int workerThreads() const { return fromEnv(m_workerThreads, "WORKER_THREADS"); } + int numNetThreads() const { return fromEnv(m_numNetThreads, "NUM_NET_THREADS"); } + std::string defaultLinkProto() const { return fromEnv(m_DefaultLinkProto, "LINK_PROTO"); } + absl::optional< bool > blockBogons() const { return fromEnv(m_blockBogons, "BLOCK_BOGONS"); } // clang-format on void @@ -194,20 +191,27 @@ namespace llarp fromSection(string_view key, string_view val); }; - class IwpConfig + class LinksConfig { public: - using Servers = std::vector< std::tuple< std::string, int, uint16_t > >; + static constexpr int Interface = 0; + static constexpr int AddressFamily = 1; + static constexpr int Port = 2; + static constexpr int Options = 3; - private: - uint16_t m_OutboundPort = 0; + using ServerOptions = std::unordered_set< std::string >; + using LinkInfo = std::tuple< std::string, int, uint16_t, ServerOptions >; + using Links = std::vector< LinkInfo >; - Servers m_servers; + private: + LinkInfo m_OutboundLink; + Links m_InboundLinks; public: // clang-format off - uint16_t outboundPort() const { return fromEnv(m_OutboundPort, "OUTBOUND_PORT"); } - const Servers& servers() const { return m_servers; } + const LinkInfo& outboundLink() const { return m_OutboundLink; } + + const Links& inboundLinks() const { return m_InboundLinks; } // clang-format on void @@ -306,7 +310,7 @@ namespace llarp ConnectConfig connect; NetdbConfig netdb; DnsConfig dns; - IwpConfig iwp_links; + LinksConfig links; ServicesConfig services; SystemConfig system; MetricsConfig metrics; @@ -325,7 +329,8 @@ namespace llarp } // namespace llarp void -llarp_generic_ensure_config(std::ofstream& f, std::string basepath); +llarp_generic_ensure_config(std::ofstream& f, std::string basepath, + bool isRouter); void llarp_ensure_router_config(std::ofstream& f, std::string basepath); diff --git a/llarp/constants/link_layer.hpp b/llarp/constants/link_layer.hpp index 7fa0f6082..b09ee5e4c 100644 --- a/llarp/constants/link_layer.hpp +++ b/llarp/constants/link_layer.hpp @@ -2,7 +2,7 @@ #define LLARP_LINK_LAYER_HPP #include -#include +#include constexpr size_t MAX_LINK_MSG_SIZE = 8192; constexpr llarp_time_t DefaultLinkSessionLifetime = 60 * 1000; diff --git a/llarp/constants/version.cpp b/llarp/constants/version.cpp index cd296d656..ae5848aed 100644 --- a/llarp/constants/version.cpp +++ b/llarp/constants/version.cpp @@ -1,3 +1,6 @@ #include -const char Version::LLARP_NET_ID[] = "testnet"; +#ifndef LLARP_DEFAULT_NETID +#define LLARP_DEFAULT_NETID "testnet" +#endif +const char Version::LLARP_NET_ID[] = LLARP_DEFAULT_NETID; diff --git a/llarp/constants/version.hpp b/llarp/constants/version.hpp index 9b05582df..25a75377f 100644 --- a/llarp/constants/version.hpp +++ b/llarp/constants/version.hpp @@ -6,11 +6,11 @@ #endif #ifndef LLARP_VERSION_MIN -#define LLARP_VERSION_MIN "4" +#define LLARP_VERSION_MIN "5" #endif #ifndef LLARP_VERSION_PATCH -#define LLARP_VERSION_PATCH "3" +#define LLARP_VERSION_PATCH "0" #endif #ifndef LLARP_VERSION_NUM diff --git a/llarp/context.cpp b/llarp/context.cpp index 9817a3956..ab989ec53 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #if(__FreeBSD__) || (__OpenBSD__) || (__NetBSD__) #include @@ -27,9 +27,7 @@ namespace llarp { - Context::Context() - { - } + Context::Context() = default; Context::~Context() { @@ -421,8 +419,8 @@ extern "C" { cSetLogLevel(eLogDebug); } - llarp_main *m = new llarp_main; - m->ctx = std::make_unique< llarp::Context >(); + auto *m = new llarp_main; + m->ctx = std::make_unique< llarp::Context >(); if(!m->ctx->LoadConfig(fname)) { m->ctx->Close(); diff --git a/llarp/crypto/constants.hpp b/llarp/crypto/constants.hpp index 81e45f9d1..d0331f279 100644 --- a/llarp/crypto/constants.hpp +++ b/llarp/crypto/constants.hpp @@ -1,7 +1,7 @@ #ifndef LLARP_CRYPTO_CONSTANTS_HPP #define LLARP_CRYPTO_CONSTANTS_HPP -#include +#include #include diff --git a/llarp/crypto/crypto.hpp b/llarp/crypto/crypto.hpp index d248062d5..f97bdbfc7 100644 --- a/llarp/crypto/crypto.hpp +++ b/llarp/crypto/crypto.hpp @@ -8,8 +8,8 @@ #include #include -#include -#include + +#include /** * crypto.hpp @@ -89,9 +89,7 @@ namespace llarp pqe_encrypt(PQCipherBlock &, SharedSecret &, const PQPubKey &) = 0; }; - inline Crypto::~Crypto() - { - } + inline Crypto::~Crypto() = default; /// return random 64bit unsigned interger uint64_t diff --git a/llarp/crypto/crypto_libsodium.cpp b/llarp/crypto/crypto_libsodium.cpp index 9402af1ed..aab38665e 100644 --- a/llarp/crypto/crypto_libsodium.cpp +++ b/llarp/crypto/crypto_libsodium.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include extern "C" { diff --git a/llarp/crypto/crypto_libsodium.hpp b/llarp/crypto/crypto_libsodium.hpp index 4a06a3054..a2eebe0e4 100644 --- a/llarp/crypto/crypto_libsodium.hpp +++ b/llarp/crypto/crypto_libsodium.hpp @@ -11,9 +11,7 @@ namespace llarp { CryptoLibSodium(); - ~CryptoLibSodium() - { - } + ~CryptoLibSodium() override = default; /// xchacha symmetric cipher bool diff --git a/llarp/crypto/crypto_noop.hpp b/llarp/crypto/crypto_noop.hpp index 28373f2dd..177515258 100644 --- a/llarp/crypto/crypto_noop.hpp +++ b/llarp/crypto/crypto_noop.hpp @@ -20,7 +20,7 @@ namespace llarp { } - ~NoOpCrypto() = default; + ~NoOpCrypto() override = default; bool xchacha20(const llarp_buffer_t &, const SharedSecret &, diff --git a/llarp/crypto/encrypted_frame.hpp b/llarp/crypto/encrypted_frame.hpp index f8d1ae644..bbd7537da 100644 --- a/llarp/crypto/encrypted_frame.hpp +++ b/llarp/crypto/encrypted_frame.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -60,8 +61,7 @@ namespace llarp static void Decrypt(void* user) { - AsyncFrameDecrypter< User >* ctx = - static_cast< AsyncFrameDecrypter< User >* >(user); + auto* ctx = static_cast< AsyncFrameDecrypter< User >* >(user); if(ctx->target.DecryptInPlace(ctx->seckey)) { @@ -75,7 +75,7 @@ namespace llarp } AsyncFrameDecrypter(const SecretKey& secretkey, DecryptHandler h) - : result(h), seckey(secretkey) + : result(std::move(h)), seckey(secretkey) { } diff --git a/llarp/dht/bucket.hpp b/llarp/dht/bucket.hpp index d796bc480..3fec209e8 100644 --- a/llarp/dht/bucket.hpp +++ b/llarp/dht/bucket.hpp @@ -19,7 +19,8 @@ namespace llarp using BucketStorage_t = std::map< Key_t, Val_t, XorMetric >; using Random_t = std::function< uint64_t() >; - Bucket(const Key_t& us, Random_t r) : nodes(XorMetric(us)), random(r) + Bucket(const Key_t& us, Random_t r) + : nodes(XorMetric(us)), random(std::move(r)) { } @@ -29,7 +30,7 @@ namespace llarp util::StatusObject obj{}; for(const auto& item : nodes) { - obj.Put(item.first.ToHex(), item.second.ExtractStatus()); + obj[item.first.ToString()] = item.second.ExtractStatus(); } return obj; } diff --git a/llarp/dht/context.cpp b/llarp/dht/context.cpp index 56b8683e4..0a77440e8 100644 --- a/llarp/dht/context.cpp +++ b/llarp/dht/context.cpp @@ -26,17 +26,13 @@ namespace llarp { namespace dht { - AbstractContext::~AbstractContext() - { - } + AbstractContext::~AbstractContext() = default; struct Context final : public AbstractContext { Context(); - ~Context() - { - } + ~Context() override = default; util::StatusObject ExtractStatus() const override; @@ -167,7 +163,7 @@ namespace llarp void Explore(size_t N = 3); - llarp::AbstractRouter* router; + llarp::AbstractRouter* router{nullptr}; // for router contacts std::unique_ptr< Bucket< RCNode > > _nodes; @@ -180,7 +176,7 @@ namespace llarp return _services.get(); } - bool allowTransit; + bool allowTransit{false}; bool& AllowTransit() override @@ -308,7 +304,7 @@ namespace llarp Key_t ourKey; }; - Context::Context() : router(nullptr), allowTransit(false) + Context::Context() { randombytes((byte_t*)&ids, sizeof(uint64_t)); } @@ -346,7 +342,7 @@ namespace llarp { if(left) return; - Context* ctx = static_cast< Context* >(u); + auto* ctx = static_cast< Context* >(u); const auto num = std::min(ctx->router->NumberOfConnectedRouters(), size_t(4)); if(num) @@ -361,7 +357,7 @@ namespace llarp { if(left) return; - Context* ctx = static_cast< Context* >(u); + auto* ctx = static_cast< Context* >(u); // clean up transactions ctx->CleanupTX(); diff --git a/llarp/dht/dht.h b/llarp/dht/dht.h index 24b84468c..c7854085c 100644 --- a/llarp/dht/dht.h +++ b/llarp/dht/dht.h @@ -33,7 +33,7 @@ llarp_dht_context_start(struct llarp_dht_context* ctx, const byte_t* key); // remove this? dns needs it atm struct llarp_router_lookup_job; -typedef void (*llarp_router_lookup_handler)(struct llarp_router_lookup_job*); +using llarp_router_lookup_handler = void (*)(struct llarp_router_lookup_job*); struct llarp_router_lookup_job { diff --git a/llarp/dht/key.hpp b/llarp/dht/key.hpp index 869a39c7b..d3a303494 100644 --- a/llarp/dht/key.hpp +++ b/llarp/dht/key.hpp @@ -37,6 +37,12 @@ namespace llarp return rid.ToString(); } + std::string + ToString() const + { + return SNode(); + } + Key_t operator^(const Key_t& other) const { diff --git a/llarp/dht/message.cpp b/llarp/dht/message.cpp index 98786fd66..04889f1b2 100644 --- a/llarp/dht/message.cpp +++ b/llarp/dht/message.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -46,29 +47,29 @@ namespace llarp switch(*strbuf.base) { case 'F': - msg.reset(new FindIntroMessage(From, relayed)); + msg = std::make_unique< FindIntroMessage >(From, relayed); break; case 'R': if(relayed) - msg.reset(new RelayedFindRouterMessage(From)); + msg = std::make_unique< RelayedFindRouterMessage >(From); else - msg.reset(new FindRouterMessage(From)); + msg = std::make_unique< FindRouterMessage >(From); break; case 'S': - msg.reset(new GotRouterMessage(From, relayed)); + msg = std::make_unique< GotRouterMessage >(From, relayed); break; case 'I': - msg.reset(new PublishIntroMessage()); + msg = std::make_unique< PublishIntroMessage >(); break; case 'G': if(relayed) { - msg.reset(new RelayedGotIntroMessage()); + msg = std::make_unique< RelayedGotIntroMessage >(); break; } else { - msg.reset(new GotIntroMessage(From)); + msg = std::make_unique< GotIntroMessage >(From); break; } default: diff --git a/llarp/dht/message.hpp b/llarp/dht/message.hpp index e5aa63ff5..cf5adf199 100644 --- a/llarp/dht/message.hpp +++ b/llarp/dht/message.hpp @@ -16,9 +16,7 @@ namespace llarp struct IMessage { - virtual ~IMessage() - { - } + virtual ~IMessage() = default; /// construct IMessage(const Key_t& from) : From(from) diff --git a/llarp/dht/messages/findintro.cpp b/llarp/dht/messages/findintro.cpp index 8240385d6..ad654f33c 100644 --- a/llarp/dht/messages/findintro.cpp +++ b/llarp/dht/messages/findintro.cpp @@ -7,9 +7,7 @@ namespace llarp { namespace dht { - FindIntroMessage::~FindIntroMessage() - { - } + FindIntroMessage::~FindIntroMessage() = default; bool FindIntroMessage::DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* val) diff --git a/llarp/dht/messages/findintro.hpp b/llarp/dht/messages/findintro.hpp index e16946bda..bf510aadc 100644 --- a/llarp/dht/messages/findintro.hpp +++ b/llarp/dht/messages/findintro.hpp @@ -45,7 +45,7 @@ namespace llarp R = 1; } - ~FindIntroMessage(); + ~FindIntroMessage() override; bool BEncode(llarp_buffer_t* buf) const override; diff --git a/llarp/dht/messages/findrouter.cpp b/llarp/dht/messages/findrouter.cpp index 8828a4e91..d2cef6c0d 100644 --- a/llarp/dht/messages/findrouter.cpp +++ b/llarp/dht/messages/findrouter.cpp @@ -57,9 +57,7 @@ namespace llarp return true; } - FindRouterMessage::~FindRouterMessage() - { - } + FindRouterMessage::~FindRouterMessage() = default; bool FindRouterMessage::BEncode(llarp_buffer_t *buf) const @@ -183,8 +181,8 @@ namespace llarp replies.emplace_back(new GotRouterMessage(k, txid, {found}, false)); return true; } - else - dht.LookupRouterRelayed(From, txid, k, !iterative, replies); + + dht.LookupRouterRelayed(From, txid, k, !iterative, replies); return true; } } // namespace dht diff --git a/llarp/dht/messages/findrouter.hpp b/llarp/dht/messages/findrouter.hpp index 903925dac..cb4f0a824 100644 --- a/llarp/dht/messages/findrouter.hpp +++ b/llarp/dht/messages/findrouter.hpp @@ -25,7 +25,7 @@ namespace llarp K.Randomize(); } - ~FindRouterMessage(); + ~FindRouterMessage() override; bool BEncode(llarp_buffer_t* buf) const override; @@ -33,7 +33,7 @@ namespace llarp bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; - virtual bool + bool HandleMessage( llarp_dht_context* ctx, std::vector< std::unique_ptr< IMessage > >& replies) const override; @@ -55,7 +55,7 @@ namespace llarp /// handle a relayed FindRouterMessage, do a lookup on the dht and inform /// the path of the result /// TODO: smart path expiration logic needs to be implemented - virtual bool + bool HandleMessage(llarp_dht_context* ctx, std::vector< IMessage::Ptr_t >& replies) const override; }; diff --git a/llarp/dht/messages/gotintro.cpp b/llarp/dht/messages/gotintro.cpp index 49db69753..8556d398f 100644 --- a/llarp/dht/messages/gotintro.cpp +++ b/llarp/dht/messages/gotintro.cpp @@ -1,29 +1,27 @@ #include #include +#include #include #include #include +#include namespace llarp { namespace dht { - GotIntroMessage::GotIntroMessage( - const std::vector< llarp::service::IntroSet > &results, uint64_t tx) - : IMessage({}), I(results), T(tx) - { - } - - GotIntroMessage::~GotIntroMessage() + GotIntroMessage::GotIntroMessage(std::vector< service::IntroSet > results, + uint64_t tx) + : IMessage({}), I(std::move(results)), T(tx) { } bool GotIntroMessage::HandleMessage( llarp_dht_context *ctx, - __attribute__((unused)) - std::vector< std::unique_ptr< IMessage > > &replies) const + ABSL_ATTRIBUTE_UNUSED std::vector< std::unique_ptr< IMessage > > + &replies) const { auto &dht = *ctx->impl; @@ -31,7 +29,7 @@ namespace llarp { if(!introset.Verify(dht.Now())) { - llarp::LogWarn( + LogWarn( "Invalid introset while handling direct GotIntro " "from ", From); @@ -59,7 +57,7 @@ namespace llarp } return true; } - llarp::LogError("no pending TX for GIM from ", From, " txid=", T); + LogError("no pending TX for GIM from ", From, " txid=", T); return false; } @@ -77,7 +75,7 @@ namespace llarp auto copy = std::make_shared< const RelayedGotIntroMessage >(*this); return pathset->HandleGotIntroMessage(copy); } - llarp::LogWarn("No path for got intro message pathid=", pathID); + LogWarn("No path for got intro message pathid=", pathID); return false; } @@ -92,7 +90,7 @@ namespace llarp { if(K) // duplicate key? return false; - K.reset(new dht::Key_t()); + K = std::make_unique< dht::Key_t >(); return K->BDecode(buf); } bool read = false; diff --git a/llarp/dht/messages/gotintro.hpp b/llarp/dht/messages/gotintro.hpp index bee067055..42a1e5ffb 100644 --- a/llarp/dht/messages/gotintro.hpp +++ b/llarp/dht/messages/gotintro.hpp @@ -15,7 +15,7 @@ namespace llarp struct GotIntroMessage : public IMessage { /// the found introsets - std::vector< llarp::service::IntroSet > I; + std::vector< service::IntroSet > I; /// txid uint64_t T = 0; /// the key of a router closer in keyspace if iterative lookup @@ -41,10 +41,9 @@ namespace llarp } /// for recursive reply - GotIntroMessage(const std::vector< llarp::service::IntroSet >& results, - uint64_t txid); + GotIntroMessage(std::vector< service::IntroSet > results, uint64_t txid); - ~GotIntroMessage(); + ~GotIntroMessage() override = default; bool BEncode(llarp_buffer_t* buf) const override; @@ -52,7 +51,7 @@ namespace llarp bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; - virtual bool + bool HandleMessage(llarp_dht_context* ctx, std::vector< IMessage::Ptr_t >& replies) const override; }; diff --git a/llarp/dht/messages/gotrouter.cpp b/llarp/dht/messages/gotrouter.cpp index 9d73f4639..64115bbe9 100644 --- a/llarp/dht/messages/gotrouter.cpp +++ b/llarp/dht/messages/gotrouter.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -8,9 +9,7 @@ namespace llarp { namespace dht { - GotRouterMessage::~GotRouterMessage() - { - } + GotRouterMessage::~GotRouterMessage() = default; bool GotRouterMessage::BEncode(llarp_buffer_t *buf) const @@ -56,7 +55,7 @@ namespace llarp { if(K) // duplicate key? return false; - K.reset(new dht::Key_t()); + K = std::make_unique< dht::Key_t >(); return K->BDecode(val); } if(key == "N") @@ -98,6 +97,7 @@ namespace llarp if(dht.pendingExploreLookups().HasPendingLookupFrom(owner)) { + LogDebug("got ", N.size(), " results in GRM for explore"); if(N.size() == 0) dht.pendingExploreLookups().NotFound(owner, K); else @@ -109,6 +109,7 @@ namespace llarp // not explore lookup if(dht.pendingRouterLookups().HasPendingLookupFrom(owner)) { + LogDebug("got ", R.size(), " results in GRM for lookup"); if(R.size() == 0) dht.pendingRouterLookups().NotFound(owner, K); else diff --git a/llarp/dht/messages/gotrouter.hpp b/llarp/dht/messages/gotrouter.hpp index 173b91936..4bb174410 100644 --- a/llarp/dht/messages/gotrouter.hpp +++ b/llarp/dht/messages/gotrouter.hpp @@ -1,8 +1,11 @@ #ifndef LLARP_DHT_MESSAGES_GOT_ROUTER_HPP #define LLARP_DHT_MESSAGES_GOT_ROUTER_HPP + #include #include #include +#include +#include namespace llarp { @@ -15,9 +18,8 @@ namespace llarp { } GotRouterMessage(const Key_t& from, uint64_t id, - const std::vector< RouterContact >& results, - bool tunneled) - : IMessage(from), R(results), txid(id), relayed(tunneled) + std::vector< RouterContact > results, bool tunneled) + : IMessage(from), R(std::move(results)), txid(id), relayed(tunneled) { } @@ -27,9 +29,9 @@ namespace llarp { } - GotRouterMessage(uint64_t id, const std::vector< RouterID >& near, + GotRouterMessage(uint64_t id, std::vector< RouterID > _near, bool tunneled) - : IMessage({}), N(near), txid(id), relayed(tunneled) + : IMessage({}), N(std::move(_near)), txid(id), relayed(tunneled) { } @@ -44,7 +46,7 @@ namespace llarp version = other.version; } - ~GotRouterMessage(); + ~GotRouterMessage() override; bool BEncode(llarp_buffer_t* buf) const override; @@ -52,7 +54,7 @@ namespace llarp bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; - virtual bool + bool HandleMessage( llarp_dht_context* ctx, std::vector< std::unique_ptr< IMessage > >& replies) const override; diff --git a/llarp/dht/messages/pubintro.cpp b/llarp/dht/messages/pubintro.cpp index 5c0e231b9..ce7a10768 100644 --- a/llarp/dht/messages/pubintro.cpp +++ b/llarp/dht/messages/pubintro.cpp @@ -10,9 +10,7 @@ namespace llarp { namespace dht { - PublishIntroMessage::~PublishIntroMessage() - { - } + PublishIntroMessage::~PublishIntroMessage() = default; bool PublishIntroMessage::DecodeKey(const llarp_buffer_t &key, diff --git a/llarp/dht/messages/pubintro.hpp b/llarp/dht/messages/pubintro.hpp index 6854965d1..9cf34f9d1 100644 --- a/llarp/dht/messages/pubintro.hpp +++ b/llarp/dht/messages/pubintro.hpp @@ -3,6 +3,7 @@ #include #include +#include #include namespace llarp @@ -22,14 +23,14 @@ namespace llarp } PublishIntroMessage(const llarp::service::IntroSet& i, uint64_t tx, - uint64_t s, const std::vector< Key_t >& exclude = {}) - : IMessage({}), E(exclude), txID(tx) + uint64_t s, std::vector< Key_t > exclude = {}) + : IMessage({}), E(std::move(exclude)), txID(tx) { I = i; S = s; } - ~PublishIntroMessage(); + ~PublishIntroMessage() override; bool BEncode(llarp_buffer_t* buf) const override; @@ -37,7 +38,7 @@ namespace llarp bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; - virtual bool + bool HandleMessage( llarp_dht_context* ctx, std::vector< std::unique_ptr< IMessage > >& replies) const override; diff --git a/llarp/dht/node.hpp b/llarp/dht/node.hpp index 59cb96372..1c8dac67d 100644 --- a/llarp/dht/node.hpp +++ b/llarp/dht/node.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace llarp { @@ -47,7 +48,7 @@ namespace llarp ID.Zero(); } - ISNode(const service::IntroSet& other) : introset(other) + ISNode(service::IntroSet other) : introset(std::move(other)) { introset.A.CalculateAddress(ID.as_array()); } diff --git a/llarp/dht/publishservicejob.cpp b/llarp/dht/publishservicejob.cpp index 12a9a7752..22e130d31 100644 --- a/llarp/dht/publishservicejob.cpp +++ b/llarp/dht/publishservicejob.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace llarp { @@ -10,11 +11,11 @@ namespace llarp PublishServiceJob::PublishServiceJob(const TXOwner &asker, const service::IntroSet &introset, AbstractContext *ctx, uint64_t s, - const std::set< Key_t > &exclude) + std::set< Key_t > exclude) : TX< service::Address, service::IntroSet >(asker, introset.A.Addr(), ctx) , S(s) - , dontTell(exclude) + , dontTell(std::move(exclude)) , I(introset) { } diff --git a/llarp/dht/publishservicejob.hpp b/llarp/dht/publishservicejob.hpp index 52da0993e..b86bdf912 100644 --- a/llarp/dht/publishservicejob.hpp +++ b/llarp/dht/publishservicejob.hpp @@ -20,7 +20,7 @@ namespace llarp PublishServiceJob(const TXOwner &asker, const service::IntroSet &introset, AbstractContext *ctx, uint64_t s, - const std::set< Key_t > &exclude); + std::set< Key_t > exclude); bool Validate(const service::IntroSet &introset) const override; diff --git a/llarp/dht/recursiverouterlookup.cpp b/llarp/dht/recursiverouterlookup.cpp index 11468d659..f0bcb1b84 100644 --- a/llarp/dht/recursiverouterlookup.cpp +++ b/llarp/dht/recursiverouterlookup.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace llarp { @@ -13,7 +14,7 @@ namespace llarp AbstractContext *ctx, RouterLookupHandler result) : TX< RouterID, RouterContact >(_whoasked, _target, ctx) - , resultHandler(result) + , resultHandler(std::move(result)) { peersAsked.insert(ctx->OurKey()); @@ -75,11 +76,10 @@ namespace llarp parent->DHTSendTo( whoasked.node.as_array(), new GotRouterMessage({}, whoasked.txid, valuesFound, false), false); - - // store this in our nodedb for caching - if(valuesFound.size() > 0) - parent->StoreRC(valuesFound[0]); } + // store this in our nodedb for caching + if(valuesFound.size() > 0) + parent->StoreRC(valuesFound[0]); } } // namespace dht } // namespace llarp diff --git a/llarp/dht/recursiverouterlookup.hpp b/llarp/dht/recursiverouterlookup.hpp index 653f94a6a..b7f56e063 100644 --- a/llarp/dht/recursiverouterlookup.hpp +++ b/llarp/dht/recursiverouterlookup.hpp @@ -28,7 +28,7 @@ namespace llarp void Start(const TXOwner &peer) override; - virtual void + void SendReply() override; }; } // namespace dht diff --git a/llarp/dht/serviceaddresslookup.cpp b/llarp/dht/serviceaddresslookup.cpp index 99f358a1d..958deb972 100644 --- a/llarp/dht/serviceaddresslookup.cpp +++ b/llarp/dht/serviceaddresslookup.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace llarp { @@ -13,7 +14,7 @@ namespace llarp AbstractContext *ctx, uint64_t r, service::IntroSetLookupHandler handler) : TX< service::Address, service::IntroSet >(asker, addr, ctx) - , handleResult(handler) + , handleResult(std::move(handler)) , R(r) { peersAsked.insert(ctx->OurKey()); diff --git a/llarp/dht/serviceaddresslookup.hpp b/llarp/dht/serviceaddresslookup.hpp index 122ea31a0..7e3626585 100644 --- a/llarp/dht/serviceaddresslookup.hpp +++ b/llarp/dht/serviceaddresslookup.hpp @@ -34,7 +34,7 @@ namespace llarp void DoNextRequest(const Key_t &ask) override; - virtual void + void SendReply() override; }; } // namespace dht diff --git a/llarp/dht/tx.hpp b/llarp/dht/tx.hpp index 1edc36200..8fc89c7cd 100644 --- a/llarp/dht/tx.hpp +++ b/llarp/dht/tx.hpp @@ -29,9 +29,7 @@ namespace llarp { } - virtual ~TX() - { - } + virtual ~TX() = default; void OnFound(const Key_t& askedPeer, const V& value); @@ -44,7 +42,7 @@ namespace llarp ExtractStatus() const { util::StatusObject obj{{"whoasked", whoasked.ExtractStatus()}, - {"target", target.ToHex()}}; + {"target", target.ToString()}}; std::vector< util::StatusObject > foundObjs; std::transform(valuesFound.begin(), valuesFound.end(), std::back_inserter(foundObjs), @@ -52,12 +50,12 @@ namespace llarp return item.ExtractStatus(); }); - obj.Put("found", foundObjs); + obj["found"] = foundObjs; std::vector< std::string > asked; std::transform( peersAsked.begin(), peersAsked.end(), std::back_inserter(asked), - [](const auto& item) -> std::string { return item.ToHex(); }); - obj.Put("asked", asked); + [](const auto& item) -> std::string { return item.ToString(); }); + obj["asked"] = asked; return obj; } diff --git a/llarp/dht/txholder.hpp b/llarp/dht/txholder.hpp index 3f57f465d..77d672f46 100644 --- a/llarp/dht/txholder.hpp +++ b/llarp/dht/txholder.hpp @@ -40,22 +40,22 @@ namespace llarp {"owner", item.first.ExtractStatus()}, {"tx", item.second->ExtractStatus()}}; }); - obj.Put("tx", txObjs); + obj["tx"] = txObjs; std::transform( timeouts.begin(), timeouts.end(), std::back_inserter(timeoutsObjs), [](const auto& item) -> util::StatusObject { return util::StatusObject{{"time", item.second}, - {"target", item.first.ToHex()}}; + {"target", item.first.ToString()}}; }); - obj.Put("timeouts", timeoutsObjs); + obj["timeouts"] = timeoutsObjs; std::transform(waiting.begin(), waiting.end(), std::back_inserter(waitingObjs), [](const auto& item) -> util::StatusObject { return util::StatusObject{ - {"target", item.first.ToHex()}, + {"target", item.first.ToString()}, {"whoasked", item.second.ExtractStatus()}}; }); - obj.Put("waiting", waitingObjs); + obj["waiting"] = waitingObjs; return obj; } diff --git a/llarp/dns.cpp b/llarp/dns.cpp index e3e4c36ab..0fb3abd4f 100644 --- a/llarp/dns.cpp +++ b/llarp/dns.cpp @@ -96,7 +96,7 @@ getDNSstring(const char *const buffer, uint32_t *pos) } void -code_domain(char *&buffer, const std::string &domain) throw() +code_domain(char *&buffer, const std::string &domain) noexcept { std::string::size_type start(0); std::string::size_type end; // indexes @@ -124,7 +124,7 @@ code_domain(char *&buffer, const std::string &domain) throw() } void -vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) throw() +vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) noexcept { std::string::size_type start(0); std::string::size_type end; // indexes @@ -153,7 +153,7 @@ vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) throw() // expects host order void -vput16bits(std::vector< byte_t > &bytes, uint16_t value) throw() +vput16bits(std::vector< byte_t > &bytes, uint16_t value) noexcept { char buf[2] = {0}; char *write_buffer = buf; @@ -164,7 +164,7 @@ vput16bits(std::vector< byte_t > &bytes, uint16_t value) throw() // expects host order void -vput32bits(std::vector< byte_t > &bytes, uint32_t value) throw() +vput32bits(std::vector< byte_t > &bytes, uint32_t value) noexcept { char buf[4] = {0}; char *write_buffer = buf; @@ -178,7 +178,7 @@ vput32bits(std::vector< byte_t > &bytes, uint32_t value) throw() void dns_writeType(std::vector< byte_t > &bytes, llarp::dns::record *record) { - llarp::dns::type_1a *type1a = dynamic_cast< llarp::dns::type_1a * >(record); + auto *type1a = dynamic_cast< llarp::dns::type_1a * >(record); if(type1a) { std::vector< byte_t > more_bytes = type1a->to_bytes(); @@ -186,8 +186,7 @@ dns_writeType(std::vector< byte_t > &bytes, llarp::dns::record *record) bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end()); } - llarp::dns::type_2ns *type2ns = - dynamic_cast< llarp::dns::type_2ns * >(record); + auto *type2ns = dynamic_cast< llarp::dns::type_2ns * >(record); if(type2ns) { std::vector< byte_t > more_bytes = type2ns->to_bytes(); @@ -195,8 +194,7 @@ dns_writeType(std::vector< byte_t > &bytes, llarp::dns::record *record) bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end()); } - llarp::dns::type_5cname *type5cname = - dynamic_cast< llarp::dns::type_5cname * >(record); + auto *type5cname = dynamic_cast< llarp::dns::type_5cname * >(record); if(type5cname) { std::vector< byte_t > more_bytes = type5cname->to_bytes(); @@ -204,24 +202,21 @@ dns_writeType(std::vector< byte_t > &bytes, llarp::dns::record *record) bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end()); } - llarp::dns::type_12ptr *type12ptr = - dynamic_cast< llarp::dns::type_12ptr * >(record); + auto *type12ptr = dynamic_cast< llarp::dns::type_12ptr * >(record); if(type12ptr) { std::vector< byte_t > more_bytes = type12ptr->to_bytes(); llarp::LogDebug("[12]Adding ", more_bytes.size()); bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end()); } - llarp::dns::type_15mx *type15mx = - dynamic_cast< llarp::dns::type_15mx * >(record); + auto *type15mx = dynamic_cast< llarp::dns::type_15mx * >(record); if(type15mx) { std::vector< byte_t > more_bytes = type15mx->to_bytes(); llarp::LogDebug("[15]Adding ", more_bytes.size()); bytes.insert(bytes.end(), more_bytes.begin(), more_bytes.end()); } - llarp::dns::type_16txt *type16txt = - dynamic_cast< llarp::dns::type_16txt * >(record); + auto *type16txt = dynamic_cast< llarp::dns::type_16txt * >(record); if(type16txt) { std::vector< byte_t > more_bytes = type16txt->to_bytes(); @@ -292,7 +287,7 @@ packet2bytes(dns_packet &in) extern "C" { uint16_t - get16bits(const char *&buffer) throw() + get16bits(const char *&buffer) noexcept { uint16_t value = bufbe16toh(buffer); buffer += 2; @@ -300,7 +295,7 @@ extern "C" } uint32_t - get32bits(const char *&buffer) throw() + get32bits(const char *&buffer) noexcept { uint32_t value = bufbe32toh(buffer); buffer += 4; @@ -350,7 +345,7 @@ extern "C" dns_msg_question * decode_question(const char *buffer, uint32_t *pos) { - dns_msg_question *question = new dns_msg_question; + auto *question = new dns_msg_question; std::string m_qName = getDNSstring(buffer, pos); llarp::LogDebug("Got question name: ", m_qName); @@ -369,7 +364,7 @@ extern "C" dns_msg_answer * decode_answer(const char *const buffer, uint32_t *pos) { - dns_msg_answer *answer = new dns_msg_answer; + auto *answer = new dns_msg_answer; /* llarp_buffer_t bob; bob.base = (unsigned char *)buffer; @@ -589,14 +584,14 @@ extern "C" } void - put16bits(char *&buffer, uint16_t value) throw() + put16bits(char *&buffer, uint16_t value) noexcept { htobe16buf(buffer, value); buffer += 2; } void - put32bits(char *&buffer, uint32_t value) throw() + put32bits(char *&buffer, uint32_t value) noexcept { htobe32buf(buffer, value); buffer += 4; diff --git a/llarp/dns.h b/llarp/dns.h index 728009a37..a2eee4a42 100644 --- a/llarp/dns.h +++ b/llarp/dns.h @@ -14,7 +14,7 @@ extern "C" // fwd declr struct dnsc_answer_request; - typedef void (*dnsc_answer_hook_func)(dnsc_answer_request *request); + using dnsc_answer_hook_func = void (*)(dnsc_answer_request *); #ifdef __cplusplus } diff --git a/llarp/dns.hpp b/llarp/dns.hpp index a0edeeaf5..b290994b5 100644 --- a/llarp/dns.hpp +++ b/llarp/dns.hpp @@ -111,24 +111,24 @@ std::string getDNSstring(const char *const buffer, uint32_t *pos); void -code_domain(char *&buffer, const std::string &domain) throw(); +code_domain(char *&buffer, const std::string &domain) noexcept; void -vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) throw(); +vcode_domain(std::vector< byte_t > &bytes, const std::string &domain) noexcept; void -vput16bits(std::vector< byte_t > &bytes, uint16_t value) throw(); +vput16bits(std::vector< byte_t > &bytes, uint16_t value) noexcept; void -vput32bits(std::vector< byte_t > &bytes, uint32_t value) throw(); +vput32bits(std::vector< byte_t > &bytes, uint32_t value) noexcept; extern "C" { uint16_t - get16bits(const char *&buffer) throw(); + get16bits(const char *&buffer) noexcept; uint32_t - get32bits(const char *&buffer) throw(); + get32bits(const char *&buffer) noexcept; bool decode_hdr(llarp_buffer_t *buffer, dns_msg_header *hdr); @@ -140,10 +140,10 @@ extern "C" decode_answer(const char *const buffer, uint32_t *pos); void - put16bits(char *&buffer, uint16_t value) throw(); + put16bits(char *&buffer, uint16_t value) noexcept; void - put32bits(char *&buffer, uint32_t value) throw(); + put32bits(char *&buffer, uint32_t value) noexcept; void llarp_handle_dns_recvfrom(struct llarp_udp_io *udp, diff --git a/llarp/dns/dns.hpp b/llarp/dns/dns.hpp index 921b16f38..cfcd5ee9c 100644 --- a/llarp/dns/dns.hpp +++ b/llarp/dns/dns.hpp @@ -1,7 +1,7 @@ #ifndef LLARP_DNS_DNS_HPP #define LLARP_DNS_DNS_HPP -#include +#include namespace llarp { diff --git a/llarp/dns/name.cpp b/llarp/dns/name.cpp index f23e2c1c9..ad51ad6c3 100644 --- a/llarp/dns/name.cpp +++ b/llarp/dns/name.cpp @@ -107,11 +107,11 @@ namespace llarp ip = net::IPPacket::ExpandV4(llarp::ipaddr_ipv4_bits(a, b, c, d)); return true; } - else if(numdots == 32 && isV6) + if(numdots == 32 && isV6) { size_t idx = 0; uint8_t lo, hi; - uint8_t* ptr = (uint8_t*)&ip.h; + auto* ptr = (uint8_t*)&ip.h; while(idx < 16) { pos = sub.find('.'); diff --git a/llarp/dns/rectypes.cpp b/llarp/dns/rectypes.cpp index a552b7509..d2771cb3c 100644 --- a/llarp/dns/rectypes.cpp +++ b/llarp/dns/rectypes.cpp @@ -5,9 +5,7 @@ namespace llarp { namespace dns { - record::~record() - { - } + record::~record() = default; bool record::parse(std::vector< byte_t > bytes) diff --git a/llarp/dns/rectypes.hpp b/llarp/dns/rectypes.hpp index a56b4f89d..4d651f4a7 100644 --- a/llarp/dns/rectypes.hpp +++ b/llarp/dns/rectypes.hpp @@ -13,9 +13,7 @@ namespace llarp struct record { virtual ~record() = 0; - record() - { - } + record() = default; virtual bool parse(std::vector< byte_t > bytes) = 0; @@ -28,9 +26,7 @@ namespace llarp { huint32_t ipaddr; - virtual ~type_1a() - { - } + ~type_1a() override = default; type_1a(); bool @@ -44,9 +40,7 @@ namespace llarp { std::string ns; - virtual ~type_2ns() - { - } + ~type_2ns() override = default; type_2ns(); bool @@ -66,9 +60,7 @@ namespace llarp uint32_t expire; uint32_t minimum; - virtual ~type_6soa() - { - } + ~type_6soa() override = default; type_6soa(); bool @@ -82,9 +74,7 @@ namespace llarp { std::string cname; - virtual ~type_5cname() - { - } + ~type_5cname() override = default; type_5cname(); bool @@ -98,9 +88,7 @@ namespace llarp { std::string revname; - virtual ~type_12ptr() - { - } + ~type_12ptr() override = default; type_12ptr(); bool @@ -115,9 +103,7 @@ namespace llarp std::string mx; uint16_t priority; - virtual ~type_15mx() - { - } + ~type_15mx() override = default; type_15mx(); bool @@ -131,9 +117,7 @@ namespace llarp { std::string txt; - virtual ~type_16txt() - { - } + ~type_16txt() override = default; type_16txt(); bool diff --git a/llarp/dns/serialize.cpp b/llarp/dns/serialize.cpp index f6c32239a..70a29c356 100644 --- a/llarp/dns/serialize.cpp +++ b/llarp/dns/serialize.cpp @@ -5,9 +5,7 @@ namespace llarp { namespace dns { - Serialize::~Serialize() - { - } + Serialize::~Serialize() = default; bool EncodeRData(llarp_buffer_t* buf, const std::vector< byte_t >& v) diff --git a/llarp/dns/server.cpp b/llarp/dns/server.cpp index 6ea3394e1..eae005b8b 100644 --- a/llarp/dns/server.cpp +++ b/llarp/dns/server.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace llarp { @@ -11,10 +12,10 @@ namespace llarp Proxy::Proxy(llarp_ev_loop_ptr serverLoop, Logic_ptr serverLogic, llarp_ev_loop_ptr clientLoop, Logic_ptr clientLogic, IQueryHandler* h) - : m_ServerLoop(serverLoop) - , m_ClientLoop(clientLoop) - , m_ServerLogic(serverLogic) - , m_ClientLogic(clientLogic) + : m_ServerLoop(std::move(serverLoop)) + , m_ClientLoop(std::move(clientLoop)) + , m_ServerLogic(std::move(serverLogic)) + , m_ClientLogic(std::move(clientLogic)) , m_QueryHandler(h) { m_Client.user = this; diff --git a/llarp/dns/server.hpp b/llarp/dns/server.hpp index b7d9aa195..f2f66ab5a 100644 --- a/llarp/dns/server.hpp +++ b/llarp/dns/server.hpp @@ -16,9 +16,7 @@ namespace llarp /// handler of dns query hooking struct IQueryHandler { - virtual ~IQueryHandler() - { - } + virtual ~IQueryHandler() = default; /// return true if we should hook this message virtual bool diff --git a/llarp/dnsc.cpp b/llarp/dnsc.cpp index 3e1034849..37cf990eb 100644 --- a/llarp/dnsc.cpp +++ b/llarp/dnsc.cpp @@ -10,12 +10,12 @@ #include /* close */ #endif -#include /* exit */ -#include /* memset */ +#include /* exit */ +#include /* memset */ #include #include // for std::find_if -#include // sprintf +#include // sprintf dns_tracker dns_udp_tracker; @@ -36,8 +36,8 @@ struct dns_query struct dns_query * build_dns_packet(char *url, uint16_t id, uint16_t reqType) { - dns_query *dnsQuery = new dns_query; - dnsQuery->length = 12; + auto *dnsQuery = new dns_query; + dnsQuery->length = 12; // ID // buffer[0] = (value & 0xFF00) >> 8; // buffer[1] = value & 0xFF; @@ -505,7 +505,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request, } else if(answer->type == 15) { - llarp::dns::type_15mx *record = + auto *record = dynamic_cast< llarp::dns::type_15mx * >(answer->record.get()); llarp::LogDebug("Resolving MX ", record->mx, "@", record->priority); request->found = true; @@ -639,7 +639,7 @@ raw_resolve_host(struct dnsc_context *const dnsc, const char *url, llarp::LogInfo("response header says it belongs to id #", hdr.id); // if we sent this out, then there's an id - struct dns_tracker *tracker = (struct dns_tracker *)dnsc->tracker; + auto *tracker = (struct dns_tracker *)dnsc->tracker; struct dnsc_answer_request *request = tracker->client_request[hdr.id].get(); if(request) @@ -675,7 +675,7 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *const udp, llarp::LogDebug("Header got client responses for id: ", hdr.id); // if we sent this out, then there's an id - struct dns_tracker *tracker = (struct dns_tracker *)udp->user; + auto *tracker = (struct dns_tracker *)udp->user; struct dnsc_answer_request *request = tracker->client_request[hdr.id].get(); // sometimes we'll get double responses @@ -766,8 +766,8 @@ llarp_resolve_host(struct dnsc_context *const dnsc, const char *url, void llarp_host_resolved(dnsc_answer_request *const request) { - dns_tracker *tracker = (dns_tracker *)request->context->tracker; - auto val = std::find_if( + auto *tracker = (dns_tracker *)request->context->tracker; + auto val = std::find_if( tracker->client_request.begin(), tracker->client_request.end(), [request]( std::pair< const uint32_t, std::unique_ptr< dnsc_answer_request > > diff --git a/llarp/dnsc.hpp b/llarp/dnsc.hpp index f67ddd54a..7ae53da5b 100644 --- a/llarp/dnsc.hpp +++ b/llarp/dnsc.hpp @@ -26,7 +26,7 @@ build_dns_packet(char *url, uint16_t id, uint16_t reqType); /// hook function to handle an dns client request // should we pass by llarp::Addr // not as long as we're supporting raw -typedef void (*dnsc_answer_hook_func)(dnsc_answer_request *request); +using dnsc_answer_hook_func = void (*)(dnsc_answer_request *); /// struct for dns client requests struct dnsc_answer_request diff --git a/llarp/dnsd.cpp b/llarp/dnsd.cpp index 813c98cde..6f8eb7a42 100644 --- a/llarp/dnsd.cpp +++ b/llarp/dnsd.cpp @@ -27,7 +27,7 @@ ssize_t llarp_sendto_dns_hook_func(void *sock, const struct sockaddr *from, ManagedBuffer buf) { - struct llarp_udp_io *udp = (struct llarp_udp_io *)sock; + auto *udp = (struct llarp_udp_io *)sock; if(!udp) { llarp::LogWarn("couldnt cast to udp"); @@ -333,8 +333,7 @@ writesend_dnss_txtresponse(std::string txt, const struct sockaddr *from, void handle_dnsc_result(dnsc_answer_request *client_request) { - dnsd_question_request *server_request = - (dnsd_question_request *)client_request->user; + auto *server_request = (dnsd_question_request *)client_request->user; if(!server_request) { llarp::LogError("Couldn't map client requser user to a server request"); @@ -522,7 +521,7 @@ llarp_handle_dnsd_recvfrom(struct llarp_udp_io *udp, return; } // create new request - dnsd_question_request *llarp_dns_request = new dnsd_question_request; + auto *llarp_dns_request = new dnsd_question_request; llarp_dns_request->context = dns_udp_tracker.dnsd; // set context llarp_dns_request->from = new sockaddr(*saddr); // make a copy of the sockaddr @@ -543,7 +542,7 @@ raw_handle_recvfrom(int *sockfd, const struct sockaddr *saddr, llarp::LogError("No tracker set in dnsd context"); return; } - dnsd_question_request *llarp_dns_request = new dnsd_question_request; + auto *llarp_dns_request = new dnsd_question_request; llarp_dns_request->context = dns_udp_tracker.dnsd; // set context llarp_dns_request->from = new sockaddr(*saddr); // make a copy of the sockaddr diff --git a/llarp/ev/ev.h b/llarp/ev/ev.h index 71e772071..961dcbcc9 100644 --- a/llarp/ev/ev.h +++ b/llarp/ev/ev.h @@ -23,9 +23,9 @@ typedef SSIZE_T ssize_t; #endif #include -#include -#include -#include + +#include +#include #if !defined(WIN32) #include diff --git a/llarp/ev/ev.hpp b/llarp/ev/ev.hpp index e53e125b3..4d351292e 100644 --- a/llarp/ev/ev.hpp +++ b/llarp/ev/ev.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -39,6 +40,8 @@ typedef struct sockaddr_un #include #endif +struct llarp_ev_pkt_pipe; + #ifndef MAX_WRITE_QUEUE_SIZE #define MAX_WRITE_QUEUE_SIZE (1024UL) #endif @@ -305,7 +308,7 @@ namespace llarp struct GetNow { llarp_ev_loop_ptr loop; - GetNow(llarp_ev_loop_ptr l) : loop(l) + GetNow(llarp_ev_loop_ptr l) : loop(std::move(l)) { } @@ -319,7 +322,7 @@ namespace llarp struct PutTime { llarp_ev_loop_ptr loop; - PutTime(llarp_ev_loop_ptr l) : loop(l) + PutTime(llarp_ev_loop_ptr l) : loop(std::move(l)) { } void @@ -570,9 +573,7 @@ namespace llarp tcp.close = &DoClose; } - virtual ~tcp_conn() - { - } + ~tcp_conn() override = default; /// start connecting void @@ -631,10 +632,10 @@ namespace llarp errno = 0; } - virtual ssize_t + ssize_t do_write(void* buf, size_t sz) override; - virtual int + int read(byte_t* buf, size_t sz) override; bool @@ -652,7 +653,7 @@ namespace llarp } bool - tick() + tick() override { if(tcp->tick) tcp->tick(tcp); @@ -660,8 +661,8 @@ namespace llarp } /// actually does accept() :^) - virtual int - read(byte_t*, size_t); + int + read(byte_t*, size_t) override; }; } // namespace llarp @@ -773,6 +774,12 @@ struct llarp_ev_loop virtual llarp::ev_io* bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* addr) = 0; + virtual bool + add_pipe(llarp_ev_pkt_pipe*) + { + return false; + } + /// register event listener virtual bool add_ev(llarp::ev_io* ev, bool write) = 0; @@ -784,9 +791,7 @@ struct llarp_ev_loop return conn && add_ev(conn, true); } - virtual ~llarp_ev_loop() - { - } + virtual ~llarp_ev_loop() = default; std::list< std::unique_ptr< llarp::ev_io > > handlers; diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index feb6221c6..732770dda 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include namespace libuv { @@ -65,7 +65,7 @@ namespace libuv static void OnOutboundConnect(uv_connect_t* c, int status) { - conn_glue* self = static_cast< conn_glue* >(c->data); + auto* self = static_cast< conn_glue* >(c->data); self->HandleConnectResult(status); c->data = nullptr; } @@ -181,9 +181,9 @@ namespace libuv { m_WriteQueue.emplace_back(sz); std::copy_n(data, sz, m_WriteQueue.back().begin()); - auto buf = uv_buf_init(m_WriteQueue.back().data(), sz); - uv_write_t* req = new uv_write_t(); - req->data = this; + auto buf = uv_buf_init(m_WriteQueue.back().data(), sz); + auto* req = new uv_write_t(); + req->data = this; return uv_write(req, Stream(), &buf, 1, &OnWritten) == 0 ? sz : 0; } @@ -196,10 +196,10 @@ namespace libuv static void FullClose(uv_handle_t* h) { - conn_glue* self = static_cast< conn_glue* >(h->data); - h->data = nullptr; + auto* self = static_cast< conn_glue* >(h->data); + h->data = nullptr; delete self; - llarp::LogInfo("deleted"); + llarp::LogDebug("deleted"); } void @@ -217,7 +217,7 @@ namespace libuv m_Conn.closed(&m_Conn); } m_Conn.impl = nullptr; - llarp::LogInfo("closed"); + llarp::LogDebug("closed"); uv_close((uv_handle_t*)&m_Ticker, &FullClose); } @@ -225,7 +225,7 @@ namespace libuv OnShutdown(uv_shutdown_t* shut, int code) { llarp::LogDebug("shut down ", code); - conn_glue* self = static_cast< conn_glue* >(shut->data); + auto* self = static_cast< conn_glue* >(shut->data); uv_close((uv_handle_t*)&self->m_Handle, &OnClosed); delete shut; } @@ -236,8 +236,8 @@ namespace libuv llarp::LogDebug("close tcp connection"); uv_check_stop(&m_Ticker); uv_read_stop(Stream()); - uv_shutdown_t* shut = new uv_shutdown_t(); - shut->data = this; + auto* shut = new uv_shutdown_t(); + shut->data = this; uv_shutdown(shut, Stream(), &OnShutdown); } @@ -285,7 +285,7 @@ namespace libuv { if(m_Accept && m_Accept->accepted) { - conn_glue* child = new conn_glue(this); + auto* child = new conn_glue(this); llarp::LogDebug("accepted new connection"); child->m_Conn.impl = child; child->m_Conn.loop = m_Accept->loop; @@ -375,7 +375,7 @@ namespace libuv static int SendTo(llarp_udp_io* udp, const sockaddr* to, const byte_t* ptr, size_t sz) { - udp_glue* self = static_cast< udp_glue* >(udp->impl); + auto* self = static_cast< udp_glue* >(udp->impl); if(self == nullptr) return -1; uv_buf_t buf = uv_buf_init((char*)ptr, sz); @@ -410,7 +410,7 @@ namespace libuv static void OnClosed(uv_handle_t* h) { - udp_glue* glue = static_cast< udp_glue* >(h->data); + auto* glue = static_cast< udp_glue* >(h->data); if(glue) { h->data = nullptr; @@ -427,6 +427,77 @@ namespace libuv } }; + struct pipe_glue : public glue + { + byte_t m_Buffer[1024 * 8]; + llarp_ev_pkt_pipe* const m_Pipe; + pipe_glue(uv_loop_t* loop, llarp_ev_pkt_pipe* pipe) : m_Pipe(pipe) + { + m_Handle.data = this; + m_Ticker.data = this; + uv_poll_init(loop, &m_Handle, m_Pipe->fd); + uv_check_init(loop, &m_Ticker); + } + + void + Tick() + { + m_Pipe->tick(); + } + + static void + OnRead(uv_poll_t* handle, int status, int) + { + if(status) + { + return; + } + pipe_glue* glue = static_cast< pipe_glue* >(handle->data); + int r = glue->m_Pipe->read(glue->m_Buffer, sizeof(glue->m_Buffer)); + if(r <= 0) + return; + const llarp_buffer_t buf{glue->m_Buffer, static_cast< size_t >(r)}; + glue->m_Pipe->OnRead(buf); + } + + static void + OnClosed(uv_handle_t* h) + { + auto* self = static_cast< pipe_glue* >(h->data); + if(self) + { + h->data = nullptr; + delete self; + } + } + + void + Close() override + { + uv_check_stop(&m_Ticker); + uv_close((uv_handle_t*)&m_Handle, &OnClosed); + } + + static void + OnTick(uv_check_t* h) + { + static_cast< pipe_glue* >(h->data)->Tick(); + } + + bool + Start() + { + if(uv_poll_start(&m_Handle, UV_READABLE, &OnRead)) + return false; + if(uv_check_start(&m_Ticker, &OnTick)) + return false; + return true; + } + + uv_poll_t m_Handle; + uv_check_t m_Ticker; + }; + struct tun_glue : public glue { uv_poll_t m_Handle; @@ -443,7 +514,7 @@ namespace libuv readpkt = false; } - ~tun_glue() + ~tun_glue() override { tuntap_destroy(m_Device); } @@ -488,7 +559,7 @@ namespace libuv static void OnClosed(uv_handle_t* h) { - tun_glue* self = static_cast< tun_glue* >(h->data); + auto* self = static_cast< tun_glue* >(h->data); if(self) { self->m_Tun->impl = nullptr; @@ -597,8 +668,8 @@ namespace libuv bool Loop::tcp_connect(llarp_tcp_connecter* tcp, const sockaddr* addr) { - conn_glue* impl = new conn_glue(m_Impl.get(), tcp, addr); - tcp->impl = impl; + auto* impl = new conn_glue(m_Impl.get(), tcp, addr); + tcp->impl = impl; if(impl->ConnectAsync()) return true; delete impl; @@ -633,16 +704,17 @@ namespace libuv Loop::CloseAll() { llarp::LogInfo("Closing all handles"); - uv_walk(m_Impl.get(), - [](uv_handle_t* h, void*) { - if(uv_is_closing(h)) - return; - if(h->data && uv_is_active(h)) - { - static_cast< glue* >(h->data)->Close(); - } - }, - nullptr); + uv_walk( + m_Impl.get(), + [](uv_handle_t* h, void*) { + if(uv_is_closing(h)) + return; + if(h->data && uv_is_active(h)) + { + static_cast< glue* >(h->data)->Close(); + } + }, + nullptr); } void @@ -655,8 +727,8 @@ namespace libuv bool Loop::udp_listen(llarp_udp_io* udp, const sockaddr* src) { - udp_glue* impl = new udp_glue(m_Impl.get(), udp, src); - udp->impl = impl; + auto* impl = new udp_glue(m_Impl.get(), udp, src); + udp->impl = impl; if(impl->Bind()) { return true; @@ -670,7 +742,7 @@ namespace libuv { if(udp == nullptr) return false; - udp_glue* glue = static_cast< udp_glue* >(udp->impl); + auto* glue = static_cast< udp_glue* >(udp->impl); if(glue == nullptr) return false; glue->Close(); @@ -680,8 +752,8 @@ namespace libuv bool Loop::tun_listen(llarp_tun_io* tun) { - tun_glue* glue = new tun_glue(tun); - tun->impl = glue; + auto* glue = new tun_glue(tun); + tun->impl = glue; if(glue->Init(m_Impl.get())) { return true; @@ -693,8 +765,8 @@ namespace libuv bool Loop::tcp_listen(llarp_tcp_acceptor* tcp, const sockaddr* addr) { - conn_glue* glue = new conn_glue(m_Impl.get(), tcp, addr); - tcp->impl = glue; + auto* glue = new conn_glue(m_Impl.get(), tcp, addr); + tcp->impl = glue; if(glue->Server()) return true; tcp->impl = nullptr; @@ -702,4 +774,14 @@ namespace libuv return false; } + bool + Loop::add_pipe(llarp_ev_pkt_pipe* p) + { + auto* glue = new pipe_glue(m_Impl.get(), p); + if(glue->Start()) + return true; + delete glue; + return false; + } + } // namespace libuv diff --git a/llarp/ev/ev_libuv.hpp b/llarp/ev/ev_libuv.hpp index b9b85d3df..3ad9a6389 100644 --- a/llarp/ev/ev_libuv.hpp +++ b/llarp/ev/ev_libuv.hpp @@ -1,6 +1,7 @@ #ifndef LLARP_EV_LIBUV_HPP #define LLARP_EV_LIBUV_HPP #include +#include #include #include #include @@ -68,6 +69,9 @@ namespace libuv bool tcp_listen(llarp_tcp_acceptor* tcp, const sockaddr* addr) override; + bool + add_pipe(llarp_ev_pkt_pipe* p) override; + llarp::ev_io* bind_tcp(llarp_tcp_acceptor*, const sockaddr*) override { diff --git a/llarp/ev/pipe.cpp b/llarp/ev/pipe.cpp index b92f5ba0b..049e702ee 100644 --- a/llarp/ev/pipe.cpp +++ b/llarp/ev/pipe.cpp @@ -1,4 +1,5 @@ #include +#include #ifndef _MSC_VER #include @@ -6,12 +7,12 @@ #include llarp_ev_pkt_pipe::llarp_ev_pkt_pipe(llarp_ev_loop_ptr loop) - : llarp::ev_io(-1, new LosslessWriteQueue_t()), m_Loop(loop) + : llarp::ev_io(-1, new LosslessWriteQueue_t()), m_Loop(std::move(loop)) { } bool -llarp_ev_pkt_pipe::Start() +llarp_ev_pkt_pipe::StartPipe() { #if defined(_WIN32) llarp::LogError("llarp_ev_pkt_pipe not supported on win32"); @@ -25,7 +26,7 @@ llarp_ev_pkt_pipe::Start() } fd = _fds[0]; writefd = _fds[1]; - return true; + return m_Loop->add_pipe(this); #endif } diff --git a/llarp/ev/pipe.hpp b/llarp/ev/pipe.hpp index 6800b1b8b..2abff3c48 100644 --- a/llarp/ev/pipe.hpp +++ b/llarp/ev/pipe.hpp @@ -10,7 +10,7 @@ struct llarp_ev_pkt_pipe : public llarp::ev_io /// start the pipe, initialize fds bool - Start(); + StartPipe(); /// write to the pipe from outside the event loop /// returns true on success @@ -25,7 +25,7 @@ struct llarp_ev_pkt_pipe : public llarp::ev_io ssize_t do_write(void* buf, size_t sz) override; - virtual bool + bool tick() override; int diff --git a/llarp/exit/context.cpp b/llarp/exit/context.cpp index f8e995c92..fceafb040 100644 --- a/llarp/exit/context.cpp +++ b/llarp/exit/context.cpp @@ -1,4 +1,5 @@ #include +#include namespace llarp { @@ -7,9 +8,7 @@ namespace llarp Context::Context(AbstractRouter* r) : m_Router(r) { } - Context::~Context() - { - } + Context::~Context() = default; void Context::Tick(llarp_time_t now) @@ -53,7 +52,7 @@ namespace llarp auto itr = m_Exits.begin(); while(itr != m_Exits.end()) { - obj.Put(itr->first, itr->second->ExtractStatus()); + obj[itr->first] = itr->second->ExtractStatus(); ++itr; } return obj; @@ -112,7 +111,7 @@ namespace llarp } std::unique_ptr< handlers::ExitEndpoint > endpoint; // make new endpoint - endpoint.reset(new handlers::ExitEndpoint(name, m_Router)); + endpoint = std::make_unique< handlers::ExitEndpoint >(name, m_Router); // configure { auto itr = conf.begin(); diff --git a/llarp/exit/exit_messages.hpp b/llarp/exit/exit_messages.hpp index 168c3833e..6f7ffffbb 100644 --- a/llarp/exit/exit_messages.hpp +++ b/llarp/exit/exit_messages.hpp @@ -14,20 +14,18 @@ namespace llarp struct ObtainExitMessage final : public IMessage { std::vector< llarp::exit::Policy > B; - uint64_t E; + uint64_t E{0}; llarp::PubKey I; - uint64_t T; + uint64_t T{0}; std::vector< llarp::exit::Policy > W; - llarp_time_t X; + llarp_time_t X{0}; llarp::Signature Z; - ObtainExitMessage() : IMessage(), E(0), T(0), X(0) + ObtainExitMessage() : IMessage() { } - ~ObtainExitMessage() - { - } + ~ObtainExitMessage() override = default; void Clear() override @@ -132,7 +130,7 @@ namespace llarp Nonce_t Y; llarp::Signature Z; - ~UpdateExitVerifyMessage() = default; + ~UpdateExitVerifyMessage() override = default; void Clear() override diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 9ae0b5d01..2a0ecba36 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace llarp { @@ -17,7 +18,7 @@ namespace llarp AbstractRouter* r, size_t numpaths, size_t hoplen, bool bundleRC) : llarp::path::Builder(r, numpaths, hoplen) , m_ExitRouter(routerId) - , m_WritePacket(writepkt) + , m_WritePacket(std::move(writepkt)) , m_Counter(0) , m_LastUse(0) , m_BundleRC(bundleRC) @@ -25,9 +26,7 @@ namespace llarp CryptoManager::instance()->identity_keygen(m_ExitIdentity); } - BaseSession::~BaseSession() - { - } + BaseSession::~BaseSession() = default; void BaseSession::HandlePathDied(path::Path_ptr p) @@ -38,10 +37,10 @@ namespace llarp util::StatusObject BaseSession::ExtractStatus() const { - auto obj = path::Builder::ExtractStatus(); - obj.Put("lastExitUse", m_LastUse); - auto pub = m_ExitIdentity.toPublic(); - obj.Put("exitIdentity", pub.ToString()); + auto obj = path::Builder::ExtractStatus(); + obj["lastExitUse"] = m_LastUse; + auto pub = m_ExitIdentity.toPublic(); + obj["exitIdentity"] = pub.ToString(); return obj; } diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index 449c2fb77..550173ce6 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -31,7 +31,7 @@ namespace llarp AbstractRouter* r, size_t numpaths, size_t hoplen, bool bundleRC); - virtual ~BaseSession(); + ~BaseSession() override; std::shared_ptr< path::PathSet > GetSelf() override @@ -51,7 +51,7 @@ namespace llarp return m_BundleRC; } - virtual void + void ResetInternalState() override; bool UrgentBuild(llarp_time_t) const override; @@ -175,13 +175,13 @@ namespace llarp { } - ~ExitSession() = default; + ~ExitSession() override = default; std::string Name() const override; protected: - virtual void + void PopulateRequest(llarp::routing::ObtainExitMessage& msg) const override { // TODO: set expiration time @@ -197,7 +197,7 @@ namespace llarp AbstractRouter* r, size_t numpaths, size_t hoplen, bool useRouterSNodeKey, bool bundleRC); - ~SNodeSession() = default; + ~SNodeSession() override = default; std::string Name() const override; diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index 18524ceec..ca68b9f60 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -29,7 +29,8 @@ namespace llarp , m_Resolver(std::make_shared< dns::Proxy >( r->netloop(), r->logic(), r->netloop(), r->logic(), this)) , m_Name(name) - , m_Tun{{0}, 0, {0}, 0, 0, 0, 0, 0, 0, 0, 0} + , m_Tun{{0}, 0, {0}, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr} , m_LocalResolverAddr("127.0.0.1", 53) , m_InetToNetwork(name + "_exit_rx", r->netloop(), r->netloop()) @@ -40,9 +41,7 @@ namespace llarp m_ShouldInitTun = true; } - ExitEndpoint::~ExitEndpoint() - { - } + ExitEndpoint::~ExitEndpoint() = default; util::StatusObject ExitEndpoint::ExtractStatus() const @@ -52,9 +51,9 @@ namespace llarp util::StatusObject exitsObj{}; for(const auto &item : m_ActiveExits) { - exitsObj.Put(item.first.ToHex(), item.second->ExtractStatus()); + exitsObj[item.first.ToString()] = item.second->ExtractStatus(); } - obj.Put("exits", exitsObj); + obj["exits"] = exitsObj; return obj; } diff --git a/llarp/handlers/exit.hpp b/llarp/handlers/exit.hpp index d8d6abbab..21a499160 100644 --- a/llarp/handlers/exit.hpp +++ b/llarp/handlers/exit.hpp @@ -14,7 +14,7 @@ namespace llarp struct ExitEndpoint : public dns::IQueryHandler { ExitEndpoint(const std::string& name, AbstractRouter* r); - ~ExitEndpoint(); + ~ExitEndpoint() override; void Tick(llarp_time_t now); diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index d796fd033..ca54318e6 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -31,7 +31,7 @@ namespace llarp static void tunifTick(llarp_tun_io *tun) { - TunEndpoint *self = static_cast< TunEndpoint * >(tun->user); + auto *self = static_cast< TunEndpoint * >(tun->user); self->Flush(); } @@ -66,14 +66,14 @@ namespace llarp util::StatusObject TunEndpoint::ExtractStatus() const { - auto obj = service::Endpoint::ExtractStatus(); - obj.Put("ifaddr", m_OurRange.ToString()); + auto obj = service::Endpoint::ExtractStatus(); + obj["ifaddr"] = m_OurRange.ToString(); std::vector< std::string > resolvers; for(const auto &addr : m_UpstreamResolvers) resolvers.emplace_back(addr.ToString()); - obj.Put("ustreamResolvers", resolvers); - obj.Put("localResolver", m_LocalResolverAddr.ToString()); + obj["ustreamResolvers"] = resolvers; + obj["localResolver"] = m_LocalResolverAddr.ToString(); util::StatusObject ips{}; for(const auto &item : m_IPActivity) { @@ -84,14 +84,14 @@ namespace llarp remoteStr = RouterID(addr.as_array()).ToString(); else remoteStr = service::Address(addr.as_array()).ToString(); - ipObj.Put("remote", remoteStr); + ipObj["remote"] = remoteStr; std::string ipaddr = item.first.ToString(); - ips.Put(ipaddr.c_str(), ipObj); + ips[ipaddr] = ipObj; } - obj.Put("addrs", ips); - obj.Put("ourIP", m_OurIP.ToString()); - obj.Put("nextIP", m_NextIP.ToString()); - obj.Put("maxIP", m_MaxIP.ToString()); + obj["addrs"] = ips; + obj["ourIP"] = m_OurIP.ToString(); + obj["nextIP"] = m_NextIP.ToString(); + obj["maxIP"] = m_MaxIP.ToString(); return obj; } @@ -412,7 +412,7 @@ namespace llarp } else { - dns::Message *replyMsg = new dns::Message(std::move(msg)); + auto *replyMsg = new dns::Message(std::move(msg)); using service::Address; using service::OutboundContext; return EnsurePathToService( @@ -432,7 +432,7 @@ namespace llarp } else { - dns::Message *replyMsg = new dns::Message(std::move(msg)); + auto *replyMsg = new dns::Message(std::move(msg)); EnsurePathToSNode(addr.as_array(), [=](const RouterID &, exit::BaseSession_ptr s) { SendDNSReply(addr, s, replyMsg, reply, true, @@ -577,7 +577,7 @@ namespace llarp return false; } - struct addrinfo hint, *res = NULL; + struct addrinfo hint, *res = nullptr; int ret; memset(&hint, 0, sizeof hint); @@ -585,7 +585,7 @@ namespace llarp hint.ai_family = PF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; - ret = getaddrinfo(tunif.ifaddr, NULL, &hint, &res); + ret = getaddrinfo(tunif.ifaddr, nullptr, &hint, &res); if(ret) { llarp::LogError(Name(), @@ -909,7 +909,7 @@ namespace llarp TunEndpoint::tunifBeforeWrite(llarp_tun_io *tun) { // called in the isolated network thread - TunEndpoint *self = static_cast< TunEndpoint * >(tun->user); + auto *self = static_cast< TunEndpoint * >(tun->user); // flush user to network self->FlushSend(); // flush exit traffic queues if it's there @@ -928,15 +928,13 @@ namespace llarp TunEndpoint::tunifRecvPkt(llarp_tun_io *tun, const llarp_buffer_t &b) { // called for every packet read from user in isolated network thread - TunEndpoint *self = static_cast< TunEndpoint * >(tun->user); + auto *self = static_cast< TunEndpoint * >(tun->user); const ManagedBuffer buf(b); self->m_UserToNetworkPktQueue.EmplaceIf( [&buf](net::IPPacket &pkt) -> bool { return pkt.Load(buf); }); } - TunEndpoint::~TunEndpoint() - { - } + TunEndpoint::~TunEndpoint() = default; } // namespace handlers } // namespace llarp diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 98d47daf7..8af830e07 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -21,7 +21,7 @@ namespace llarp { TunEndpoint(const std::string& nickname, AbstractRouter* r, llarp::service::Context* parent); - ~TunEndpoint(); + ~TunEndpoint() override; path::PathSet_ptr GetSelf() override @@ -29,10 +29,10 @@ namespace llarp return shared_from_this(); } - virtual bool + bool SetOption(const std::string& k, const std::string& v) override; - virtual void + void Tick(llarp_time_t now) override; util::StatusObject @@ -165,7 +165,7 @@ namespace llarp void Flush(); - virtual void + void ResetInternalState() override; protected: diff --git a/llarp/hook/ihook.hpp b/llarp/hook/ihook.hpp index 83d57d0fa..553de68e0 100644 --- a/llarp/hook/ihook.hpp +++ b/llarp/hook/ihook.hpp @@ -26,9 +26,7 @@ namespace llarp using Backend_ptr = std::shared_ptr< IBackend >; - inline IBackend::~IBackend() - { - } + inline IBackend::~IBackend() = default; } // namespace hooks } // namespace llarp diff --git a/llarp/iwp/iwp.cpp b/llarp/iwp/iwp.cpp index 457a51340..eae5384be 100644 --- a/llarp/iwp/iwp.cpp +++ b/llarp/iwp/iwp.cpp @@ -7,22 +7,26 @@ namespace llarp { namespace iwp { - std::unique_ptr< ILinkLayer > - NewServer(const SecretKey& enckey, GetRCFunc getrc, LinkMessageHandler h, - SessionEstablishedHandler est, SessionRenegotiateHandler reneg, - SignBufferFunc sign, TimeoutHandler t, - SessionClosedHandler closed) + LinkLayer_ptr + NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) { - (void)enckey; - (void)getrc; - (void)h; - (void)est; - (void)reneg; - (void)sign; - (void)t; - (void)closed; - // TODO: implement me - return nullptr; + return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, + reneg, timeout, closed, true); + } + + LinkLayer_ptr + NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) + { + return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, + reneg, timeout, closed, false); } } // namespace iwp } // namespace llarp diff --git a/llarp/iwp/iwp.hpp b/llarp/iwp/iwp.hpp index e7a10413e..0e9eacaac 100644 --- a/llarp/iwp/iwp.hpp +++ b/llarp/iwp/iwp.hpp @@ -2,21 +2,25 @@ #define LLARP_IWP_HPP #include - +#include #include namespace llarp { - struct AbstractRouter; - namespace iwp { - std::unique_ptr< ILinkLayer > - NewServer(const SecretKey& routerEncSecret, llarp::GetRCFunc getrc, - llarp::LinkMessageHandler h, llarp::SessionEstablishedHandler est, - llarp::SessionRenegotiateHandler reneg, - llarp::SignBufferFunc sign, llarp::TimeoutHandler timeout, - llarp::SessionClosedHandler closed); + LinkLayer_ptr + NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); + LinkLayer_ptr + NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); } // namespace iwp } // namespace llarp diff --git a/llarp/iwp/linklayer.cpp b/llarp/iwp/linklayer.cpp index 2f0af3226..57d0c499a 100644 --- a/llarp/iwp/linklayer.cpp +++ b/llarp/iwp/linklayer.cpp @@ -1,26 +1,49 @@ #include +#include namespace llarp { namespace iwp { - LinkLayer::LinkLayer(const SecretKey& enckey, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler t, SessionClosedHandler closed) - : ILinkLayer(enckey, getrc, h, sign, est, reneg, t, closed) + LinkLayer::LinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, + TimeoutHandler timeout, SessionClosedHandler closed, + bool allowInbound) + : ILinkLayer(routerEncSecret, getrc, h, sign, est, reneg, timeout, + closed) + , permitInbound{allowInbound} { - m_FlowCookie.Randomize(); } - LinkLayer::~LinkLayer() - { - } + LinkLayer::~LinkLayer() = default; void LinkLayer::Pump() { + std::set< RouterID > sessions; + { + Lock l(&m_AuthedLinksMutex); + auto itr = m_AuthedLinks.begin(); + while(itr != m_AuthedLinks.end()) + { + sessions.insert(itr->first); + ++itr; + } + } ILinkLayer::Pump(); + { + Lock l(&m_AuthedLinksMutex); + for(const auto& pk : sessions) + { + if(m_AuthedLinks.count(pk) == 0) + { + // all sessions were removed + SessionClosed(pk); + } + } + } } const char* @@ -46,135 +69,57 @@ namespace llarp bool LinkLayer::Start(std::shared_ptr< Logic > l) { - if(!ILinkLayer::Start(l)) - return false; - return false; + return ILinkLayer::Start(l); } void LinkLayer::RecvFrom(const Addr& from, const void* pkt, size_t sz) { - m_OuterMsg.Clear(); - llarp_buffer_t sigbuf(pkt, sz); - llarp_buffer_t decodebuf(pkt, sz); - if(!m_OuterMsg.Decode(&decodebuf)) + std::shared_ptr< ILinkSession > session; + auto itr = m_AuthedAddrs.find(from); + if(itr == m_AuthedAddrs.end()) { - LogError("failed to decode outer message"); - return; + util::Lock lock(&m_PendingMutex); + if(m_Pending.count(from) == 0) + { + if(not permitInbound) + return; + m_Pending.insert({from, std::make_shared< Session >(this, from)}); + } + session = m_Pending.find(from)->second; } - NetID ourNetID; - switch(m_OuterMsg.command) + else { - case eOCMD_ObtainFlowID: - sigbuf.sz -= m_OuterMsg.Zsig.size(); - if(!CryptoManager::instance()->verify(m_OuterMsg.pubkey, sigbuf, - m_OuterMsg.Zsig)) - { - LogError("failed to verify signature on '", - (char)m_OuterMsg.command, "' message from ", from); - return; - } - if(!ShouldSendFlowID(from)) - { - SendReject(from, "no flo 4u :^)"); - return; - } - if(m_OuterMsg.netid == ourNetID) - { - if(GenFlowIDFor(m_OuterMsg.pubkey, from, m_OuterMsg.flow)) - SendFlowID(from, m_OuterMsg.flow); - else - SendReject(from, "genflow fail"); - } - else - SendReject(from, "bad netid"); + auto range = m_AuthedLinks.equal_range(itr->second); + session = range.first->second; + } + if(session) + { + const llarp_buffer_t buf{pkt, sz}; + session->Recv_LL(buf); } - } - - std::shared_ptr< ILinkSession > - LinkLayer::NewOutboundSession(const RouterContact& rc, - const AddressInfo& ai) - { - (void)rc; - (void)ai; - // TODO: implement me - return {}; - } - - void - LinkLayer::SendFlowID(const Addr& to, const FlowID_t& flow) - { - // TODO: implement me - (void)to; - (void)flow; - } - - bool - LinkLayer::VerifyFlowID(const PubKey& pk, const Addr& from, - const FlowID_t& flow) const - { - FlowID_t expected; - if(!GenFlowIDFor(pk, from, expected)) - return false; - return expected == flow; } bool - LinkLayer::GenFlowIDFor(const PubKey& pk, const Addr& from, - FlowID_t& flow) const + LinkLayer::MapAddr(const RouterID& r, ILinkSession* s) { - std::array< byte_t, 128 > tmp = {{0}}; - if(inet_ntop(AF_INET6, from.addr6(), (char*)tmp.data(), tmp.size()) - == nullptr) - return false; - std::copy_n(pk.begin(), pk.size(), tmp.begin() + 64); - std::copy_n(m_FlowCookie.begin(), m_FlowCookie.size(), - tmp.begin() + 64 + pk.size()); - llarp_buffer_t buf(tmp); - ShortHash h; - if(!CryptoManager::instance()->shorthash(h, buf)) + if(!ILinkLayer::MapAddr(r, s)) return false; - std::copy_n(h.begin(), flow.size(), flow.begin()); + m_AuthedAddrs.emplace(s->GetRemoteEndpoint(), r); return true; } - bool - LinkLayer::ShouldSendFlowID(const Addr& to) const + void + LinkLayer::UnmapAddr(const Addr& a) { - (void)to; - // TODO: implement me - return false; + m_AuthedAddrs.erase(a); } - void - LinkLayer::SendReject(const Addr& to, const char* msg) + std::shared_ptr< ILinkSession > + LinkLayer::NewOutboundSession(const RouterContact& rc, + const AddressInfo& ai) { - if(strlen(msg) > 14) - { - throw std::logic_error("reject message too big"); - } - std::array< byte_t, 120 > pkt; - auto now = Now(); - PubKey pk = GetOurRC().pubkey; - OuterMessage m; - m.CreateReject(msg, now, pk); - llarp_buffer_t encodebuf(pkt); - if(!m.Encode(&encodebuf)) - { - LogError("failed to encode reject message to ", to); - return; - } - llarp_buffer_t signbuf(pkt.data(), pkt.size() - m.Zsig.size()); - if(!Sign(m.Zsig, signbuf)) - { - LogError("failed to sign reject messsage to ", to); - return; - } - std::copy_n(m.Zsig.begin(), m.Zsig.size(), - pkt.begin() + (pkt.size() - m.Zsig.size())); - llarp_buffer_t pktbuf(pkt); - SendTo_LL(to, pktbuf); + return std::make_shared< Session >(this, rc, ai); } } // namespace iwp - } // namespace llarp diff --git a/llarp/iwp/linklayer.hpp b/llarp/iwp/linklayer.hpp index 50f9f3557..13ecf3ecf 100644 --- a/llarp/iwp/linklayer.hpp +++ b/llarp/iwp/linklayer.hpp @@ -6,7 +6,6 @@ #include #include #include -#include namespace llarp { @@ -14,12 +13,13 @@ namespace llarp { struct LinkLayer final : public ILinkLayer { - LinkLayer(const SecretKey &encryptionSecretKey, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler established, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed); + LinkLayer(const SecretKey &routerEncSecret, GetRCFunc getrc, + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, SessionRenegotiateHandler reneg, + TimeoutHandler timeout, SessionClosedHandler closed, + bool permitInbound); - ~LinkLayer(); + ~LinkLayer() override; bool Start(std::shared_ptr< Logic > l) override; @@ -40,41 +40,21 @@ namespace llarp uint16_t Rank() const override; - /// verify that a new flow id matches addresses and pubkey - bool - VerifyFlowID(const PubKey &pk, const Addr &from, - const FlowID_t &flow) const; - void RecvFrom(const Addr &from, const void *buf, size_t sz) override; - private: bool - GenFlowIDFor(const PubKey &pk, const Addr &from, FlowID_t &flow) const; - - bool - ShouldSendFlowID(const Addr &from) const; - - void - SendReject(const Addr &to, const char *msg); + MapAddr(const RouterID &pk, ILinkSession *s) override; void - SendFlowID(const Addr &to, const FlowID_t &flow); + UnmapAddr(const Addr &addr); - using ActiveFlows_t = - std::unordered_map< FlowID_t, RouterID, FlowID_t::Hash >; - - ActiveFlows_t m_ActiveFlows; - - using PendingFlows_t = std::unordered_map< Addr, FlowID_t, Addr::Hash >; - /// flows that are pending authentication - PendingFlows_t m_PendingFlows; - - /// cookie used in flow id computation - AlignedBuffer< 32 > m_FlowCookie; - - OuterMessage m_OuterMsg; + private: + std::unordered_map< Addr, RouterID, Addr::Hash > m_AuthedAddrs; + const bool permitInbound; }; + + using LinkLayer_ptr = std::shared_ptr< LinkLayer >; } // namespace iwp } // namespace llarp diff --git a/llarp/iwp/outermessage.cpp b/llarp/iwp/outermessage.cpp deleted file mode 100644 index bb3b9b724..000000000 --- a/llarp/iwp/outermessage.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include - -namespace llarp -{ - namespace iwp - { - std::array< byte_t, 6 > OuterMessage::obtain_flow_id_magic = - std::array< byte_t, 6 >{{'n', 'e', 't', 'i', 'd', '?'}}; - - std::array< byte_t, 6 > OuterMessage::give_flow_id_magic = - std::array< byte_t, 6 >{{'n', 'e', 't', 'i', 'd', '!'}}; - - OuterMessage::OuterMessage() - { - Clear(); - } - - OuterMessage::~OuterMessage() - { - } - - void - OuterMessage::Clear() - { - command = 0; - flow.Zero(); - netid.Zero(); - reject.fill(0); - N.Zero(); - X.Zero(); - Xsize = 0; - Zsig.Zero(); - Zhash.Zero(); - pubkey.Zero(); - magic.fill(0); - uinteger = 0; - A.reset(); - } - - void - OuterMessage::CreateReject(const char* msg, llarp_time_t now, - const PubKey& pk) - { - Clear(); - std::copy_n(msg, std::min(strlen(msg), reject.size()), reject.begin()); - uinteger = now; - pubkey = pk; - } - - bool - OuterMessage::Encode(llarp_buffer_t* buf) const - { - if(buf->size_left() < 2) - return false; - *buf->cur = command; - buf->cur++; - *buf->cur = '='; - buf->cur++; - switch(command) - { - case eOCMD_ObtainFlowID: - - case eOCMD_GiveFlowID: - if(!buf->write(reject.begin(), reject.end())) - return false; - if(!buf->write(give_flow_id_magic.begin(), give_flow_id_magic.end())) - return false; - if(!buf->write(flow.begin(), flow.end())) - return false; - if(!buf->write(pubkey.begin(), pubkey.end())) - return false; - return buf->write(Zsig.begin(), Zsig.end()); - default: - return false; - } - } - - bool - OuterMessage::Decode(llarp_buffer_t* buf) - { - static constexpr size_t header_size = 2; - - if(buf->size_left() < header_size) - return false; - command = *buf->cur; - ++buf->cur; - if(*buf->cur != '=') - return false; - ++buf->cur; - switch(command) - { - case eOCMD_ObtainFlowID: - if(!buf->read_into(magic.begin(), magic.end())) - return false; - if(!buf->read_into(netid.begin(), netid.end())) - return false; - if(!buf->read_uint64(uinteger)) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - if(buf->size_left() <= Zsig.size()) - return false; - Xsize = buf->size_left() - Zsig.size(); - if(!buf->read_into(X.begin(), X.begin() + Xsize)) - return false; - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_GiveFlowID: - if(!buf->read_into(magic.begin(), magic.end())) - return false; - if(!buf->read_into(flow.begin(), flow.end())) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - buf->cur += buf->size_left() - Zsig.size(); - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_Reject: - if(!buf->read_into(reject.begin(), reject.end())) - return false; - if(!buf->read_uint64(uinteger)) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - buf->cur += buf->size_left() - Zsig.size(); - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_SessionNegotiate: - if(!buf->read_into(flow.begin(), flow.end())) - return false; - if(!buf->read_into(pubkey.begin(), pubkey.end())) - return false; - if(!buf->read_uint64(uinteger)) - return false; - if(buf->size_left() == Zsig.size() + 32) - { - A.reset(new AlignedBuffer< 32 >()); - if(!buf->read_into(A->begin(), A->end())) - return false; - } - return buf->read_into(Zsig.begin(), Zsig.end()); - case eOCMD_TransmitData: - if(!buf->read_into(flow.begin(), flow.end())) - return false; - if(!buf->read_into(N.begin(), N.end())) - return false; - if(buf->size_left() <= Zhash.size()) - return false; - Xsize = buf->size_left() - Zhash.size(); - if(!buf->read_into(X.begin(), X.begin() + Xsize)) - return false; - return buf->read_into(Zhash.begin(), Zhash.end()); - default: - return false; - } - } - } // namespace iwp - -} // namespace llarp diff --git a/llarp/iwp/outermessage.hpp b/llarp/iwp/outermessage.hpp deleted file mode 100644 index eefc05593..000000000 --- a/llarp/iwp/outermessage.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef LLARP_IWP_OUTERMESSAGE_HPP -#define LLARP_IWP_OUTERMESSAGE_HPP - -#include -#include -#include - -#include - -namespace llarp -{ - namespace iwp - { - using FlowID_t = AlignedBuffer< 32 >; - - using OuterCommand_t = byte_t; - - constexpr OuterCommand_t eOCMD_ObtainFlowID = 'O'; - constexpr OuterCommand_t eOCMD_GiveFlowID = 'G'; - constexpr OuterCommand_t eOCMD_Reject = 'R'; - constexpr OuterCommand_t eOCMD_SessionNegotiate = 'S'; - constexpr OuterCommand_t eOCMD_TransmitData = 'D'; - - using InnerCommand_t = byte_t; - - constexpr InnerCommand_t eICMD_KeepAlive = 'k'; - constexpr InnerCommand_t eICMD_KeepAliveAck = 'l'; - constexpr InnerCommand_t eICMD_Congestion = 'c'; - constexpr InnerCommand_t eICMD_AntiCongestion = 'd'; - constexpr InnerCommand_t eICMD_Transmit = 't'; - constexpr InnerCommand_t eICMD_Ack = 'a'; - constexpr InnerCommand_t eICMD_RotateKeys = 'r'; - constexpr InnerCommand_t eICMD_UpgradeProtocol = 'u'; - constexpr InnerCommand_t eICMD_VersionUpgrade = 'v'; - - struct OuterMessage - { - // required members - byte_t command; - FlowID_t flow; - - OuterMessage(); - ~OuterMessage(); - - // static members - static std::array< byte_t, 6 > obtain_flow_id_magic; - static std::array< byte_t, 6 > give_flow_id_magic; - - void - CreateReject(const char *msg, llarp_time_t now, const PubKey &pk); - - // optional members follow - std::array< byte_t, 6 > magic; - NetID netid; - // either timestamp or counter - uint64_t uinteger; - std::array< byte_t, 14 > reject; - AlignedBuffer< 24 > N; - PubKey pubkey; - - std::unique_ptr< AlignedBuffer< 32 > > A; - - static constexpr size_t ipv6_mtu = 1280; - static constexpr size_t overhead_size = 16 + 24 + 32; - static constexpr size_t payload_size = ipv6_mtu - overhead_size; - - AlignedBuffer< payload_size > X; - size_t Xsize; - ShortHash Zhash; - Signature Zsig; - - /// encode to buffer - bool - Encode(llarp_buffer_t *buf) const; - - /// decode from buffer - bool - Decode(llarp_buffer_t *buf); - - /// clear members - void - Clear(); - }; - } // namespace iwp -} // namespace llarp -#endif diff --git a/llarp/link/i_link_manager.hpp b/llarp/link/i_link_manager.hpp index 7ba246980..8af30e7aa 100644 --- a/llarp/link/i_link_manager.hpp +++ b/llarp/link/i_link_manager.hpp @@ -18,11 +18,6 @@ namespace llarp struct IOutboundSessionMaker; struct RouterID; - namespace util - { - struct StatusObject; - } // namespace util - struct ILinkManager { virtual ~ILinkManager() = default; diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index 8c6c5a42f..69b58dc0a 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -346,21 +346,20 @@ namespace llarp if(stopping) return nullptr; - for(const auto &link : inboundLinks) + for(const auto &link : outboundLinks) { if(link->HasSessionTo(remote)) { return link; } } - for(const auto &link : outboundLinks) + for(const auto &link : inboundLinks) { if(link->HasSessionTo(remote)) { return link; } } - return nullptr; } diff --git a/llarp/link/link_manager.hpp b/llarp/link/link_manager.hpp index 4e9296781..17f29f8c3 100644 --- a/llarp/link/link_manager.hpp +++ b/llarp/link/link_manager.hpp @@ -18,7 +18,7 @@ namespace llarp struct LinkManager final : public ILinkManager { public: - ~LinkManager() = default; + ~LinkManager() override = default; LinkLayer_ptr GetCompatibleLink(const RouterContact &rc) const override; @@ -71,7 +71,7 @@ namespace llarp void CheckPersistingSessions(llarp_time_t now) override; - virtual util::StatusObject + util::StatusObject ExtractStatus() const override; void diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index ec6da7c3d..8f0cc2d2d 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace llarp { @@ -12,20 +13,18 @@ namespace llarp SessionEstablishedHandler establishedSession, SessionRenegotiateHandler reneg, TimeoutHandler timeout, SessionClosedHandler closed) - : HandleMessage(handler) - , HandleTimeout(timeout) - , Sign(signbuf) - , GetOurRC(getrc) - , SessionEstablished(establishedSession) - , SessionClosed(closed) - , SessionRenegotiate(reneg) + : HandleMessage(std::move(handler)) + , HandleTimeout(std::move(timeout)) + , Sign(std::move(signbuf)) + , GetOurRC(std::move(getrc)) + , SessionEstablished(std::move(establishedSession)) + , SessionClosed(std::move(closed)) + , SessionRenegotiate(std::move(reneg)) , m_RouterEncSecret(routerEncSecret) { } - ILinkLayer::~ILinkLayer() - { - } + ILinkLayer::~ILinkLayer() = default; bool ILinkLayer::HasSessionTo(const RouterID& id) @@ -130,7 +129,7 @@ namespace llarp auto itr = m_AuthedLinks.begin(); while(itr != m_AuthedLinks.end()) { - if(itr->second.get() && !itr->second->TimedOut(_now)) + if(not itr->second->TimedOut(_now)) { itr->second->Pump(); ++itr; @@ -150,7 +149,7 @@ namespace llarp auto itr = m_Pending.begin(); while(itr != m_Pending.end()) { - if(itr->second.get() && !itr->second->TimedOut(_now)) + if(not itr->second->TimedOut(_now)) { itr->second->Pump(); ++itr; @@ -158,7 +157,12 @@ namespace llarp else { LogInfo("pending session at ", itr->first, " timed out"); - itr->second->Close(); + // defer call so we can acquire mutexes later + auto self = itr->second->BorrowSelf(); + m_Logic->queue_func([&, self]() { + this->HandleTimeout(self.get()); + self->Close(); + }); itr = m_Pending.erase(itr); } } @@ -176,6 +180,7 @@ namespace llarp { if(m_AuthedLinks.count(pk) > MaxSessionsPerKey) { + LogWarn("too many session for ", pk); s->Close(); return false; } diff --git a/llarp/link/server.hpp b/llarp/link/server.hpp index 74f3cf3cf..be25c4fdc 100644 --- a/llarp/link/server.hpp +++ b/llarp/link/server.hpp @@ -103,7 +103,7 @@ namespace llarp llarp_ev_udp_sendto(&m_udp, to, pkt); } - bool + virtual bool Configure(llarp_ev_loop_ptr loop, const std::string& ifname, int af, uint16_t port); @@ -125,7 +125,7 @@ namespace llarp virtual bool Start(std::shared_ptr< llarp::Logic > l); - void + virtual void Stop(); virtual const char* @@ -140,11 +140,11 @@ namespace llarp void KeepAliveSessionTo(const RouterID& remote); - bool + virtual bool SendTo(const RouterID& remote, const llarp_buffer_t& buf, ILinkSession::CompletionHandler completed); - bool + virtual bool GetOurAddressInfo(AddressInfo& addr) const; bool @@ -186,7 +186,7 @@ namespace llarp bool GenEphemeralKeys(); - bool + virtual bool MapAddr(const RouterID& pk, ILinkSession* s); void @@ -200,6 +200,12 @@ namespace llarp SessionClosedHandler SessionClosed; SessionRenegotiateHandler SessionRenegotiate; + std::shared_ptr< Logic > + logic() + { + return m_Logic; + } + bool operator<(const ILinkLayer& other) const { diff --git a/llarp/link/session.hpp b/llarp/link/session.hpp index 5b904f633..8647b6ca9 100644 --- a/llarp/link/session.hpp +++ b/llarp/link/session.hpp @@ -16,9 +16,7 @@ namespace llarp struct ILinkSession { - virtual ~ILinkSession() - { - } + virtual ~ILinkSession() = default; /// delivery status of a message enum class DeliveryStatus @@ -27,9 +25,14 @@ namespace llarp eDeliveryDropped = 1 }; + /// equiv of shared_from_this but for the interface type so + /// that each implementation can use shared_from_this + virtual std::shared_ptr< ILinkSession > + BorrowSelf() = 0; + /// hook for utp for when we have established a connection virtual void - OnLinkEstablished(ILinkLayer *p) = 0; + OnLinkEstablished(ILinkLayer *){}; /// called every event loop tick virtual void @@ -52,6 +55,13 @@ namespace llarp virtual void Close() = 0; + /// recv packet on low layer + /// not used by utp + virtual void + Recv_LL(const llarp_buffer_t &) + { + } + /// send a keepalive to the remote endpoint virtual bool SendKeepAlive() = 0; diff --git a/llarp/messages/dht_immediate.hpp b/llarp/messages/dht_immediate.hpp index 88f4e765d..31afbba9e 100644 --- a/llarp/messages/dht_immediate.hpp +++ b/llarp/messages/dht_immediate.hpp @@ -10,8 +10,8 @@ namespace llarp { struct DHTImmediateMessage final : public ILinkMessage { - DHTImmediateMessage() = default; - ~DHTImmediateMessage() = default; + DHTImmediateMessage() = default; + ~DHTImmediateMessage() override = default; std::vector< std::unique_ptr< dht::IMessage > > msgs; diff --git a/llarp/messages/link_intro.cpp b/llarp/messages/link_intro.cpp index b414d95d4..a4f3c8d1c 100644 --- a/llarp/messages/link_intro.cpp +++ b/llarp/messages/link_intro.cpp @@ -31,7 +31,7 @@ namespace llarp { return bencode_read_integer(buf, &P); } - else if(key == "r") + if(key == "r") { if(rc.BDecode(buf)) return true; @@ -39,7 +39,7 @@ namespace llarp llarp::DumpBuffer(*buf); return false; } - else if(key == "v") + if(key == "v") { if(!bencode_read_integer(buf, &version)) return false; @@ -52,15 +52,13 @@ namespace llarp llarp::LogDebug("LIM version ", version); return true; } - else if(key == "z") + if(key == "z") { return Z.BDecode(buf); } - else - { - llarp::LogWarn("invalid LIM key: ", *key.cur); - return false; - } + + llarp::LogWarn("invalid LIM key: ", *key.cur); + return false; } bool diff --git a/llarp/messages/link_message_parser.cpp b/llarp/messages/link_message_parser.cpp index 3e8859ad5..e7fd1b16b 100644 --- a/llarp/messages/link_message_parser.cpp +++ b/llarp/messages/link_message_parser.cpp @@ -37,9 +37,7 @@ namespace llarp { } - LinkMessageParser::~LinkMessageParser() - { - } + LinkMessageParser::~LinkMessageParser() = default; bool LinkMessageParser::operator()(llarp_buffer_t* buffer, llarp_buffer_t* key) diff --git a/llarp/messages/relay_commit.cpp b/llarp/messages/relay_commit.cpp index d0a19bd55..a269590be 100644 --- a/llarp/messages/relay_commit.cpp +++ b/llarp/messages/relay_commit.cpp @@ -171,9 +171,9 @@ namespace llarp struct LRCMFrameDecrypt { - typedef llarp::path::PathContext Context; - typedef llarp::path::TransitHop Hop; - typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter; + using Context = llarp::path::PathContext; + using Hop = llarp::path::TransitHop; + using Decrypter = AsyncFrameDecrypter< LRCMFrameDecrypt >; using Decrypter_ptr = std::unique_ptr< Decrypter >; Decrypter_ptr decrypter; std::array< EncryptedFrame, 8 > frames; @@ -193,9 +193,7 @@ namespace llarp hop->info.downstream = commit->session->GetPubKey(); } - ~LRCMFrameDecrypt() - { - } + ~LRCMFrameDecrypt() = default; static void OnForwardLRCMResult(AbstractRouter* router, const PathID_t pathid, diff --git a/llarp/messages/relay_commit.hpp b/llarp/messages/relay_commit.hpp index 86abf5d95..7c54349fc 100644 --- a/llarp/messages/relay_commit.hpp +++ b/llarp/messages/relay_commit.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace llarp { @@ -49,14 +50,14 @@ namespace llarp { std::array< EncryptedFrame, 8 > frames; - LR_CommitMessage(const std::array< EncryptedFrame, 8 > &_frames) - : ILinkMessage(), frames(_frames) + LR_CommitMessage(std::array< EncryptedFrame, 8 > _frames) + : ILinkMessage(), frames(std::move(_frames)) { } LR_CommitMessage() = default; - ~LR_CommitMessage() = default; + ~LR_CommitMessage() override = default; void Clear() override; diff --git a/llarp/messages/relay_status.cpp b/llarp/messages/relay_status.cpp index 5ca6b07d1..d72e41d87 100644 --- a/llarp/messages/relay_status.cpp +++ b/llarp/messages/relay_status.cpp @@ -12,6 +12,7 @@ #include #include +#include namespace llarp { @@ -25,10 +26,12 @@ namespace llarp HopHandler_ptr path; AbstractRouter* router; - LRSM_AsyncHandler(const std::array< EncryptedFrame, 8 >& _frames, - uint64_t _status, HopHandler_ptr _path, - AbstractRouter* _router) - : frames(_frames), status(_status), path(_path), router(_router) + LRSM_AsyncHandler(std::array< EncryptedFrame, 8 > _frames, uint64_t _status, + HopHandler_ptr _path, AbstractRouter* _router) + : frames(std::move(_frames)) + , status(_status) + , path(std::move(_path)) + , router(_router) { } @@ -57,7 +60,7 @@ namespace llarp { return BEncodeReadArray(frames, buf); } - else if(key == "p") + if(key == "p") { if(!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf)) { diff --git a/llarp/messages/relay_status.hpp b/llarp/messages/relay_status.hpp index fd8684123..2e744f8dd 100644 --- a/llarp/messages/relay_status.hpp +++ b/llarp/messages/relay_status.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace llarp { @@ -56,14 +57,14 @@ namespace llarp uint64_t status = 0; - LR_StatusMessage(const std::array< EncryptedFrame, 8 > &_frames) - : ILinkMessage(), frames(_frames) + LR_StatusMessage(std::array< EncryptedFrame, 8 > _frames) + : ILinkMessage(), frames(std::move(_frames)) { } LR_StatusMessage() = default; - ~LR_StatusMessage() = default; + ~LR_StatusMessage() override = default; void Clear() override; diff --git a/llarp/metrics/json_publisher.hpp b/llarp/metrics/json_publisher.hpp index d0cc2b06c..b684a2495 100644 --- a/llarp/metrics/json_publisher.hpp +++ b/llarp/metrics/json_publisher.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace llarp { @@ -22,13 +23,11 @@ namespace llarp PublishFunction m_publish; public: - JsonPublisher(const PublishFunction& publish) : m_publish(publish) + JsonPublisher(PublishFunction publish) : m_publish(std::move(publish)) { } - ~JsonPublisher() - { - } + ~JsonPublisher() override = default; void publish(const Sample& values) override; diff --git a/llarp/metrics/metrictank_publisher.cpp b/llarp/metrics/metrictank_publisher.cpp index ab9a98597..751d2cecb 100644 --- a/llarp/metrics/metrictank_publisher.cpp +++ b/llarp/metrics/metrictank_publisher.cpp @@ -205,7 +205,8 @@ namespace llarp publishData(const std::vector< std::string > &toSend, const std::string &host, short port) { - struct addrinfo hints, *addrs; + struct addrinfo hints; + struct addrinfo *addrs; bzero(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; diff --git a/llarp/metrics/metrictank_publisher.hpp b/llarp/metrics/metrictank_publisher.hpp index 23fbb699f..044b4ec87 100644 --- a/llarp/metrics/metrictank_publisher.hpp +++ b/llarp/metrics/metrictank_publisher.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace llarp @@ -32,9 +33,7 @@ namespace llarp { } - ~MetricTankPublisherInterface() - { - } + ~MetricTankPublisherInterface() override = default; static std::string makeSuffix(const Tags& tags); @@ -66,16 +65,16 @@ namespace llarp work(); public: - MetricTankPublisher(const Tags& tags, const std::string& host, short port) + MetricTankPublisher(const Tags& tags, std::string host, short port) : MetricTankPublisherInterface(tags) - , m_host(host) + , m_host(std::move(host)) , m_port(port) , m_queue(100) , m_worker(&MetricTankPublisher::work, this) { } - ~MetricTankPublisher() + ~MetricTankPublisher() override { // Push back a signal value onto the queue m_queue.pushBack(StopStruct()); diff --git a/llarp/metrics/stream_publisher.hpp b/llarp/metrics/stream_publisher.hpp index a50ebe686..4fbb9ff7a 100644 --- a/llarp/metrics/stream_publisher.hpp +++ b/llarp/metrics/stream_publisher.hpp @@ -18,7 +18,7 @@ namespace llarp { } - ~StreamPublisher() = default; + ~StreamPublisher() override = default; void publish(const Sample& values) override; diff --git a/llarp/net/address_info.cpp b/llarp/net/address_info.cpp index 6a81f7490..f1e2bd6ad 100644 --- a/llarp/net/address_info.cpp +++ b/llarp/net/address_info.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include namespace llarp { @@ -160,4 +160,17 @@ namespace llarp return stream; } + + void + to_json(nlohmann::json &j, const AddressInfo &a) + { + char tmp[128] = {0}; + inet_ntop(AF_INET6, (void *)&a.ip, tmp, sizeof(tmp)); + + j = nlohmann::json{{"rank", a.rank}, + {"dialect", a.dialect}, + {"pubkey", a.pubkey.ToString()}, + {"in6_addr", tmp}, + {"port", a.port}}; + } } // namespace llarp diff --git a/llarp/net/address_info.hpp b/llarp/net/address_info.hpp index 48ec5f6d1..7bbeaf1b3 100644 --- a/llarp/net/address_info.hpp +++ b/llarp/net/address_info.hpp @@ -8,7 +8,6 @@ #include #include -#include /** * address_info.hpp @@ -53,6 +52,9 @@ namespace llarp }; }; + void + to_json(nlohmann::json& j, const AddressInfo& a); + inline std::ostream& operator<<(std::ostream& out, const AddressInfo& a) { diff --git a/llarp/net/exit_info.cpp b/llarp/net/exit_info.cpp index 9c4435356..be1e6efd3 100644 --- a/llarp/net/exit_info.cpp +++ b/llarp/net/exit_info.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include namespace llarp { diff --git a/llarp/net/exit_info.hpp b/llarp/net/exit_info.hpp index b7355abee..c1fe6f678 100644 --- a/llarp/net/exit_info.hpp +++ b/llarp/net/exit_info.hpp @@ -23,9 +23,7 @@ namespace llarp PubKey pubkey; uint64_t version = LLARP_PROTO_VERSION; - ExitInfo() - { - } + ExitInfo() = default; ExitInfo(const PubKey &pk, const nuint32_t &ipv4_exit) : pubkey(pk) { diff --git a/llarp/net/ip.cpp b/llarp/net/ip.cpp index 8723d7636..80df045e3 100644 --- a/llarp/net/ip.cpp +++ b/llarp/net/ip.cpp @@ -71,8 +71,8 @@ namespace llarp { if(IsV6()) return In6ToHUInt(HeaderV6()->srcaddr); - else - return ExpandV4(srcv4()); + + return ExpandV4(srcv4()); } huint128_t @@ -80,8 +80,8 @@ namespace llarp { if(IsV6()) return In6ToHUInt(HeaderV6()->dstaddr); - else - return ExpandV4(dstv4()); + + return ExpandV4(dstv4()); } bool diff --git a/llarp/net/ip.hpp b/llarp/net/ip.hpp index 49f062e2b..83ddf3714 100644 --- a/llarp/net/ip.hpp +++ b/llarp/net/ip.hpp @@ -88,6 +88,7 @@ struct ipv6_header #include #include +#include struct llarp_ev_loop; @@ -136,7 +137,7 @@ namespace llarp struct PutTime { llarp_ev_loop_ptr loop; - PutTime(llarp_ev_loop_ptr evloop) : loop(evloop) + PutTime(llarp_ev_loop_ptr evloop) : loop(std::move(evloop)) { } void @@ -149,7 +150,7 @@ namespace llarp struct GetNow { llarp_ev_loop_ptr loop; - GetNow(llarp_ev_loop_ptr evloop) : loop(evloop) + GetNow(llarp_ev_loop_ptr evloop) : loop(std::move(evloop)) { } llarp_time_t @@ -224,10 +225,10 @@ namespace llarp { if(IsV4()) return service::eProtocolTrafficV4; - else if(IsV6()) + if(IsV6()) return service::eProtocolTrafficV6; - else - return service::eProtocolControl; + + return service::eProtocolControl; } huint128_t diff --git a/llarp/net/net.cpp b/llarp/net/net.cpp index 010797d3c..f55916912 100644 --- a/llarp/net/net.cpp +++ b/llarp/net/net.cpp @@ -786,7 +786,7 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr) if(af == AF_INET6) { // set scope id - sockaddr_in6* ip6addr = (sockaddr_in6*)addr; + auto* ip6addr = (sockaddr_in6*)addr; ip6addr->sin6_scope_id = if_nametoindex(ifname); ip6addr->sin6_flowinfo = 0; } @@ -861,8 +861,8 @@ namespace llarp const auto fam = i->ifa_addr->sa_family; if(fam != AF_INET) return; - sockaddr_in* addr = (sockaddr_in*)i->ifa_addr; - sockaddr_in* mask = (sockaddr_in*)i->ifa_netmask; + auto* addr = (sockaddr_in*)i->ifa_addr; + auto* mask = (sockaddr_in*)i->ifa_netmask; nuint32_t ifaddr{addr->sin_addr.s_addr}; nuint32_t ifmask{mask->sin_addr.s_addr}; currentRanges.emplace_back( @@ -926,7 +926,7 @@ namespace llarp GetIFAddr(const std::string& ifname, Addr& addr, int af) { sockaddr_storage s; - sockaddr* sptr = (sockaddr*)&s; + auto* sptr = (sockaddr*)&s; if(!llarp_getifaddr(ifname.c_str(), af, sptr)) return false; addr = *sptr; diff --git a/llarp/net/net.h b/llarp/net/net.h index 55b349cad..248d3f3d6 100644 --- a/llarp/net/net.h +++ b/llarp/net/net.h @@ -25,7 +25,11 @@ typedef unsigned int in_addr_t; #include #include #endif + +#ifndef __cplusplus #include +#endif + #include bool diff --git a/llarp/net/net.hpp b/llarp/net/net.hpp index f9848c948..044e512f6 100644 --- a/llarp/net/net.hpp +++ b/llarp/net/net.hpp @@ -11,7 +11,7 @@ #include #include -#include // for itoa +#include // for itoa #include // for addrinfo diff --git a/llarp/net/net_addr.cpp b/llarp/net/net_addr.cpp index de2387e51..bed44a9c6 100644 --- a/llarp/net/net_addr.cpp +++ b/llarp/net/net_addr.cpp @@ -16,12 +16,8 @@ namespace llarp { - Addr::Addr() - { - } - Addr::~Addr() - { - } + Addr::Addr() = default; + Addr::~Addr() = default; void Addr::port(uint16_t port) @@ -87,7 +83,7 @@ namespace llarp this->port(port); } Zero(&_addr, sizeof(sockaddr_in6)); - struct addrinfo hint, *res = NULL; + struct addrinfo hint, *res = nullptr; int ret; memset(&hint, '\0', sizeof hint); @@ -98,11 +94,11 @@ namespace llarp if(pPosition != string_view::npos) { ret = getaddrinfo(std::string(in.begin(), in.begin() + pPosition).c_str(), - NULL, &hint, &res); + nullptr, &hint, &res); } else { - ret = getaddrinfo(std::string(in).c_str(), NULL, &hint, &res); + ret = getaddrinfo(std::string(in).c_str(), nullptr, &hint, &res); } if(ret) @@ -152,7 +148,7 @@ namespace llarp { Zero(&_addr, sizeof(sockaddr_in6)); struct in_addr* addr = &_addr4.sin_addr; - unsigned char* ip = (unsigned char*)&(addr->s_addr); + auto* ip = (unsigned char*)&(addr->s_addr); _addr.sin6_family = AF_INET; // set ipv4 mode _addr4.sin_family = AF_INET; @@ -311,11 +307,11 @@ namespace llarp { case AF_INET: { - sockaddr_in* ipv4_dst = (sockaddr_in*)other; - dst = (void*)&ipv4_dst->sin_addr.s_addr; - src = (void*)&_addr4.sin_addr.s_addr; - ptr = &((sockaddr_in*)other)->sin_port; - slen = sizeof(in_addr); + auto* ipv4_dst = (sockaddr_in*)other; + dst = (void*)&ipv4_dst->sin_addr.s_addr; + src = (void*)&_addr4.sin_addr.s_addr; + ptr = &((sockaddr_in*)other)->sin_port; + slen = sizeof(in_addr); break; } case AF_INET6: diff --git a/llarp/net/net_inaddr.cpp b/llarp/net/net_inaddr.cpp index 45af70628..1617bf3a3 100644 --- a/llarp/net/net_inaddr.cpp +++ b/llarp/net/net_inaddr.cpp @@ -32,7 +32,7 @@ namespace llarp this->reset(); // maybe refactor the family detection out - struct addrinfo hint, *res = NULL; + struct addrinfo hint, *res = nullptr; int ret; memset(&hint, '\0', sizeof hint); @@ -40,7 +40,7 @@ namespace llarp hint.ai_family = PF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; - ret = getaddrinfo(str, NULL, &hint, &res); + ret = getaddrinfo(str, nullptr, &hint, &res); if(ret) { llarp::LogError("failed to determine address family: ", str); diff --git a/llarp/net/net_int.hpp b/llarp/net/net_int.hpp index 5a64093ce..5421abc4d 100644 --- a/llarp/net/net_int.hpp +++ b/llarp/net/net_int.hpp @@ -14,7 +14,7 @@ #include -#include // for itoa +#include // for itoa #include #include #include diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 9d7134258..9490f37e7 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -12,12 +12,13 @@ #include #include +#include static const char skiplist_subdirs[] = "0123456789abcdef"; static const std::string RC_FILE_EXT = ".signed"; -llarp_nodedb::NetDBEntry::NetDBEntry(const llarp::RouterContact &value) - : rc(value), inserted(llarp::time_now_ms()) +llarp_nodedb::NetDBEntry::NetDBEntry(llarp::RouterContact value) + : rc(std::move(value)), inserted(llarp::time_now_ms()) { } @@ -151,7 +152,7 @@ llarp_nodedb::UpdateAsyncIfNewer(llarp::RouterContact rc, InsertAsync(rc, logic, completionHandler); return true; } - else if(itr != entries.end()) + if(itr != entries.end()) { // insertion time is set on...insertion. But it should be updated here // even if there is no insertion of a new RC, to show that the existing one @@ -362,8 +363,7 @@ llarp_nodedb::Save() void logic_threadworker_callback(void *user) { - llarp_async_verify_rc *verify_request = - static_cast< llarp_async_verify_rc * >(user); + auto *verify_request = static_cast< llarp_async_verify_rc * >(user); if(verify_request->hook) verify_request->hook(verify_request); } @@ -382,8 +382,7 @@ disk_threadworker_setRC(llarp_async_verify_rc *verify_request) void crypto_threadworker_verifyrc(void *user) { - llarp_async_verify_rc *verify_request = - static_cast< llarp_async_verify_rc * >(user); + auto *verify_request = static_cast< llarp_async_verify_rc * >(user); llarp::RouterContact rc = verify_request->rc; verify_request->valid = rc.Verify(llarp::time_now_ms()); // if it's valid we need to set it @@ -404,14 +403,14 @@ crypto_threadworker_verifyrc(void *user) void nodedb_inform_load_rc(void *user) { - llarp_async_load_rc *job = static_cast< llarp_async_load_rc * >(user); + auto *job = static_cast< llarp_async_load_rc * >(user); job->hook(job); } void nodedb_async_load_rc(void *user) { - llarp_async_load_rc *job = static_cast< llarp_async_load_rc * >(user); + auto *job = static_cast< llarp_async_load_rc * >(user); auto fpath = job->nodedb->getRCFilePath(job->pubkey); job->loaded = job->nodedb->loadfile(fpath); diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 29d29faa7..d88eda827 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -10,6 +10,7 @@ #include #include +#include #ifdef _MSC_VER #include @@ -45,7 +46,7 @@ struct llarp_nodedb_iter struct llarp_nodedb { explicit llarp_nodedb(std::shared_ptr< llarp::thread::ThreadPool > diskworker) - : disk(diskworker) + : disk(std::move(diskworker)) { } @@ -62,7 +63,7 @@ struct llarp_nodedb const llarp::RouterContact rc; llarp_time_t inserted; - NetDBEntry(const llarp::RouterContact &data); + NetDBEntry(llarp::RouterContact data); }; using NetDBMap_t = diff --git a/llarp/path/ihophandler.hpp b/llarp/path/ihophandler.hpp index f3a4e5685..ea672d74b 100644 --- a/llarp/path/ihophandler.hpp +++ b/llarp/path/ihophandler.hpp @@ -22,9 +22,7 @@ namespace llarp { struct IHopHandler { - virtual ~IHopHandler() - { - } + virtual ~IHopHandler() = default; virtual bool Expired(llarp_time_t now) const = 0; diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 97f69d3fe..e9021de50 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -103,8 +103,8 @@ namespace llarp } bool - Path::HandleLRSM(uint64_t status, - std::array< EncryptedFrame, 8 >& frames, AbstractRouter* r) + Path::HandleLRSM(uint64_t status, std::array< EncryptedFrame, 8 >& frames, + AbstractRouter* r) { uint64_t currentStatus = status; @@ -215,7 +215,7 @@ namespace llarp m_PathSet->HandlePathBuildFailed(shared_from_this()); return; } - else if(st == ePathExpired && _status == ePathBuilding) + if(st == ePathExpired && _status == ePathBuilding) { _status = st; m_PathSet->HandlePathBuildTimeout(shared_from_this()); @@ -272,30 +272,30 @@ namespace llarp [](const auto& hop) -> util::StatusObject { return hop.ExtractStatus(); }); - obj.Put("hops", hopsObj); + obj["hops"] = hopsObj; switch(_status) { case ePathBuilding: - obj.Put("status", "building"); + obj["status"] = "building"; break; case ePathEstablished: - obj.Put("status", "established"); + obj["status"] = "established"; break; case ePathTimeout: - obj.Put("status", "timeout"); + obj["status"] = "timeout"; break; case ePathExpired: - obj.Put("status", "expired"); + obj["status"] = "expired"; break; case ePathFailed: - obj.Put("status", "failed"); + obj["status"] = "failed"; break; case ePathIgnore: - obj.Put("status", "ignored"); + obj["status"] = "ignored"; break; default: - obj.Put("status", "unknown"); + obj["status"] = "unknown"; break; } return obj; diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp index b2460f84b..84a19f575 100644 --- a/llarp/path/path_context.cpp +++ b/llarp/path/path_context.cpp @@ -164,14 +164,15 @@ namespace llarp 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); - }); + 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; diff --git a/llarp/path/path_context.hpp b/llarp/path/path_context.hpp index f6b9add0d..fce0f1454 100644 --- a/llarp/path/path_context.hpp +++ b/llarp/path/path_context.hpp @@ -107,6 +107,7 @@ namespace llarp void ForEach(std::function< void(const TransitHop_ptr&) > visit) + LOCKS_EXCLUDED(first) { util::Lock lock(&first); for(const auto& item : second) diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 7b4bff011..a1026cca7 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -186,13 +186,11 @@ namespace llarp util::StatusObject obj{{"buildStats", m_BuildStats.ExtractStatus()}, {"numHops", uint64_t(numHops)}, {"numPaths", uint64_t(numPaths)}}; - std::vector< util::StatusObject > pathObjs; std::transform(m_Paths.begin(), m_Paths.end(), - std::back_inserter(pathObjs), + std::back_inserter(obj["paths"]), [](const auto& item) -> util::StatusObject { return item.second->ExtractStatus(); }); - obj.Put("paths", pathObjs); return obj; } diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index fe49954f5..8e35f89d8 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -53,18 +53,18 @@ namespace llarp util::StatusObject ExtractStatus() const; - virtual bool + bool SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev, RouterContact& cur, size_t hop, PathRole roles) override; - virtual bool + bool ShouldBuildMore(llarp_time_t now) const override; /// should we bundle RCs in builds? virtual bool ShouldBundleRC() const = 0; - virtual void + void ResetInternalState() override; /// return true if we hit our soft limit for building paths too fast @@ -78,7 +78,7 @@ namespace llarp return ePathRoleAny; } - virtual bool + bool Stop() override; bool @@ -90,7 +90,7 @@ namespace llarp llarp_time_t Now() const override; - virtual void + void Tick(llarp_time_t now) override; void @@ -113,13 +113,13 @@ namespace llarp virtual const SecretKey& GetTunnelEncryptionSecretKey() const; - virtual void + void HandlePathBuilt(Path_ptr p) override; - virtual void + void HandlePathBuildTimeout(Path_ptr p) override; - virtual void + void HandlePathBuildFailed(Path_ptr p) override; }; diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index f2a1d3bc3..b9a46c24c 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -31,9 +31,7 @@ namespace llarp return stream; } - TransitHop::TransitHop() - { - } + TransitHop::TransitHop() = default; bool TransitHop::Expired(llarp_time_t now) const diff --git a/llarp/pow.cpp b/llarp/pow.cpp index d8f20cd35..11673ff43 100644 --- a/llarp/pow.cpp +++ b/llarp/pow.cpp @@ -7,9 +7,7 @@ namespace llarp { - PoW::~PoW() - { - } + PoW::~PoW() = default; bool PoW::DecodeKey(ABSL_ATTRIBUTE_UNUSED const llarp_buffer_t& k, diff --git a/llarp/router/i_outbound_message_handler.hpp b/llarp/router/i_outbound_message_handler.hpp index 4789c1bf9..931207c8b 100644 --- a/llarp/router/i_outbound_message_handler.hpp +++ b/llarp/router/i_outbound_message_handler.hpp @@ -1,6 +1,8 @@ #ifndef LLARP_ROUTER_I_OUTBOUND_MESSAGE_HANDLER_HPP #define LLARP_ROUTER_I_OUTBOUND_MESSAGE_HANDLER_HPP +#include + #include #include @@ -19,11 +21,6 @@ namespace llarp struct ILinkMessage; struct RouterID; - namespace util - { - struct StatusObject; - } - using SendStatusHandler = std::function< void(SendStatus) >; struct IOutboundMessageHandler diff --git a/llarp/router/i_outbound_session_maker.hpp b/llarp/router/i_outbound_session_maker.hpp index fdebf0839..746897d2e 100644 --- a/llarp/router/i_outbound_session_maker.hpp +++ b/llarp/router/i_outbound_session_maker.hpp @@ -1,17 +1,13 @@ #ifndef LLARP_ROUTER_I_OUTBOUND_SESSION_MAKER_HPP #define LLARP_ROUTER_I_OUTBOUND_SESSION_MAKER_HPP +#include #include #include namespace llarp { - namespace util - { - struct StatusObject; - } // namespace util - struct ILinkSession; struct RouterID; struct RouterContact; @@ -52,6 +48,9 @@ namespace llarp virtual util::StatusObject ExtractStatus() const = 0; + + virtual bool + ShouldConnectTo(const RouterID &router) const = 0; }; } // namespace llarp diff --git a/llarp/router/outbound_message_handler.cpp b/llarp/router/outbound_message_handler.cpp index d5102a2ed..99782de55 100644 --- a/llarp/router/outbound_message_handler.cpp +++ b/llarp/router/outbound_message_handler.cpp @@ -170,18 +170,13 @@ namespace llarp { const llarp_buffer_t buf(msg.first); auto callback = msg.second; - if(!_linkManager->SendTo( - remote, buf, [=](ILinkSession::DeliveryStatus status) { - if(status == ILinkSession::DeliveryStatus::eDeliverySuccess) - DoCallback(callback, SendStatus::Success); - else - DoCallback(callback, SendStatus::Congestion); - })) - { - DoCallback(callback, SendStatus::Congestion); - return false; - } - return true; + return _linkManager->SendTo( + remote, buf, [=](ILinkSession::DeliveryStatus status) { + if(status == ILinkSession::DeliveryStatus::eDeliverySuccess) + DoCallback(callback, SendStatus::Success); + else + DoCallback(callback, SendStatus::Congestion); + }); } bool diff --git a/llarp/router/outbound_message_handler.hpp b/llarp/router/outbound_message_handler.hpp index 54efeea63..d64a7c905 100644 --- a/llarp/router/outbound_message_handler.hpp +++ b/llarp/router/outbound_message_handler.hpp @@ -22,11 +22,11 @@ namespace llarp struct OutboundMessageHandler final : public IOutboundMessageHandler { public: - ~OutboundMessageHandler() = default; + ~OutboundMessageHandler() override = default; bool QueueMessage(const RouterID &remote, const ILinkMessage *msg, - SendStatusHandler callback) override; + SendStatusHandler callback) override LOCKS_EXCLUDED(_mutex); util::StatusObject ExtractStatus() const override; @@ -72,7 +72,8 @@ namespace llarp SendIfSession(const RouterID &remote, const Message &msg); void - FinalizeRequest(const RouterID &router, SendStatus status); + FinalizeRequest(const RouterID &router, SendStatus status) + LOCKS_EXCLUDED(_mutex); mutable util::Mutex _mutex; // protects outboundMessageQueue diff --git a/llarp/router/outbound_session_maker.cpp b/llarp/router/outbound_session_maker.cpp index 5a52a0aba..fd64990ce 100644 --- a/llarp/router/outbound_session_maker.cpp +++ b/llarp/router/outbound_session_maker.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace llarp { @@ -22,8 +23,8 @@ namespace llarp size_t attemptCount = 0; - PendingSession(const RouterContact &_rc, LinkLayer_ptr _link) - : rc(_rc), link(_link) + PendingSession(RouterContact _rc, LinkLayer_ptr _link) + : rc(std::move(_rc)), link(std::move(_link)) { } }; @@ -192,7 +193,7 @@ namespace llarp const RouterContact &rc) { { - util::Lock l(&_mutex); + util::ReleasableLock l(&_mutex); // in case other request found RC for this router after this request was // made @@ -206,6 +207,7 @@ namespace llarp if(!link) { + l.Release(); FinalizeRequest(router, SessionResult::NoLink); return; } @@ -214,9 +216,28 @@ namespace llarp itr->second = session; } + if(ShouldConnectTo(router)) + { + auto fn = std::bind(&OutboundSessionMaker::DoEstablish, this, router); + _logic->queue_func(fn); + } + } - auto fn = std::bind(&OutboundSessionMaker::DoEstablish, this, router); - _logic->queue_func(fn); + bool + OutboundSessionMaker::ShouldConnectTo(const RouterID &router) const + { + if(router == us) + return false; + size_t numPending = 0; + { + util::Lock lock(&_mutex); + if(pendingSessions.find(router) == pendingSessions.end()) + numPending += pendingSessions.size(); + } + if(_linkManager->HasSessionTo(router)) + return false; + return _linkManager->NumberOfConnectedRouters() + numPending + < maxConnectedRouters; } void diff --git a/llarp/router/outbound_session_maker.hpp b/llarp/router/outbound_session_maker.hpp index 4b5e291a4..9be7f47c5 100644 --- a/llarp/router/outbound_session_maker.hpp +++ b/llarp/router/outbound_session_maker.hpp @@ -26,7 +26,7 @@ namespace llarp using CallbacksQueue = std::list< RouterCallback >; public: - ~OutboundSessionMaker() = default; + ~OutboundSessionMaker() override = default; bool OnSessionEstablished(ILinkSession *session) override; @@ -35,13 +35,16 @@ namespace llarp OnConnectTimeout(ILinkSession *session) override; void - CreateSessionTo(const RouterID &router, RouterCallback on_result) override; + CreateSessionTo(const RouterID &router, RouterCallback on_result) override + LOCKS_EXCLUDED(_mutex); void - CreateSessionTo(const RouterContact &rc, RouterCallback on_result) override; + CreateSessionTo(const RouterContact &rc, RouterCallback on_result) override + LOCKS_EXCLUDED(_mutex); bool - HavePendingSessionTo(const RouterID &router) const override; + HavePendingSessionTo(const RouterID &router) const override + LOCKS_EXCLUDED(_mutex); void ConnectToRandomRouters(int numDesired, llarp_time_t now) override; @@ -49,17 +52,33 @@ namespace llarp util::StatusObject ExtractStatus() const override; + bool + ShouldConnectTo(const RouterID &router) const override + LOCKS_EXCLUDED(_mutex); + void Init(ILinkManager *linkManager, I_RCLookupHandler *rcLookup, std::shared_ptr< Logic > logic, llarp_nodedb *nodedb, std::shared_ptr< llarp::thread::ThreadPool > threadpool); + void + SetOurRouter(RouterID r) + { + us = std::move(r); + } + + /// always maintain this many connections to other routers + size_t minConnectedRouters = 4; + /// hard upperbound limit on the number of router to router connections + size_t maxConnectedRouters = 6; + private: void - DoEstablish(const RouterID &router); + DoEstablish(const RouterID &router) LOCKS_EXCLUDED(_mutex); void - GotRouterContact(const RouterID &router, const RouterContact &rc); + GotRouterContact(const RouterID &router, const RouterContact &rc) + LOCKS_EXCLUDED(_mutex); void InvalidRouter(const RouterID &router); @@ -75,10 +94,11 @@ namespace llarp VerifyRC(const RouterContact rc); void - CreatePendingSession(const RouterID &router); + CreatePendingSession(const RouterID &router) LOCKS_EXCLUDED(_mutex); void - FinalizeRequest(const RouterID &router, const SessionResult type); + FinalizeRequest(const RouterID &router, const SessionResult type) + LOCKS_EXCLUDED(_mutex); mutable util::Mutex _mutex; // protects pendingSessions, pendingCallbacks @@ -94,6 +114,7 @@ namespace llarp std::shared_ptr< Logic > _logic; llarp_nodedb *_nodedb; std::shared_ptr< llarp::thread::ThreadPool > _threadpool; + RouterID us; }; } // namespace llarp diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index b79b454a4..2f4b05322 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -133,6 +133,7 @@ namespace llarp if(not rc.Verify(_dht->impl->Now())) { + LogWarn("RC for ", RouterID(rc.pubkey), " is invalid"); return false; } diff --git a/llarp/router/rc_lookup_handler.hpp b/llarp/router/rc_lookup_handler.hpp index 1638da6c6..a94a60a1c 100644 --- a/llarp/router/rc_lookup_handler.hpp +++ b/llarp/router/rc_lookup_handler.hpp @@ -28,28 +28,32 @@ namespace llarp public: using CallbacksQueue = std::list< RCRequestCallback >; - ~RCLookupHandler() = default; + ~RCLookupHandler() override = default; void - AddValidRouter(const RouterID &router) override; + AddValidRouter(const RouterID &router) override LOCKS_EXCLUDED(_mutex); void - RemoveValidRouter(const RouterID &router) override; + RemoveValidRouter(const RouterID &router) override LOCKS_EXCLUDED(_mutex); void - SetRouterWhitelist(const std::vector< RouterID > &routers) override; + SetRouterWhitelist(const std::vector< RouterID > &routers) override + LOCKS_EXCLUDED(_mutex); void - GetRC(const RouterID &router, RCRequestCallback callback) override; + GetRC(const RouterID &router, RCRequestCallback callback) override + LOCKS_EXCLUDED(_mutex); bool - RemoteIsAllowed(const RouterID &remote) const override; + RemoteIsAllowed(const RouterID &remote) const override + LOCKS_EXCLUDED(_mutex); bool CheckRC(const RouterContact &rc) const override; bool - GetRandomWhitelistRouter(RouterID &router) const override; + GetRandomWhitelistRouter(RouterID &router) const override + LOCKS_EXCLUDED(_mutex); bool CheckRenegotiateValid(RouterContact newrc, RouterContact oldrc) override; @@ -74,14 +78,14 @@ namespace llarp const std::vector< RouterContact > &results); bool - HavePendingLookup(RouterID remote) const; + HavePendingLookup(RouterID remote) const LOCKS_EXCLUDED(_mutex); bool RemoteInBootstrap(const RouterID &remote) const; void FinalizeRequest(const RouterID &router, const RouterContact *const rc, - RCRequestResult result); + RCRequestResult result) LOCKS_EXCLUDED(_mutex); mutable util::Mutex _mutex; // protects pendingCallbacks, whitelistRouters diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 686e44d1a..a7475cfc8 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include @@ -81,9 +83,9 @@ namespace llarp Router::Router(std::shared_ptr< llarp::thread::ThreadPool > _tp, llarp_ev_loop_ptr __netloop, std::shared_ptr< Logic > l) : ready(false) - , _netloop(__netloop) - , cryptoworker(_tp) - , _logic(l) + , _netloop(std::move(__netloop)) + , cryptoworker(std::move(_tp)) + , _logic(std::move(l)) , paths(this) , _exitContext(this) , disk(std::make_shared< llarp::thread::ThreadPool >(1, 1000, @@ -108,13 +110,11 @@ namespace llarp util::StatusObject Router::ExtractStatus() const { - util::StatusObject obj{{"dht", _dht->impl->ExtractStatus()}, - {"services", _hiddenServiceContext.ExtractStatus()}, - {"exit", _exitContext.ExtractStatus()}}; - - obj.Put("links", _linkManager.ExtractStatus()); - - return obj; + return util::StatusObject{ + {"dht", _dht->impl->ExtractStatus()}, + {"services", _hiddenServiceContext.ExtractStatus()}, + {"exit", _exitContext.ExtractStatus()}, + {"links", _linkManager.ExtractStatus()}}; } bool @@ -288,7 +288,7 @@ namespace llarp { if(left) return; - Router *self = static_cast< Router * >(user); + auto *self = static_cast< Router * >(user); self->ticker_job_id = 0; self->Tick(); self->ScheduleTicker(orig); @@ -336,10 +336,11 @@ namespace llarp _encryption = nextOnionKey; } } - nextRC.last_updated = Now(); if(!nextRC.Sign(identity())) return false; - _rc = nextRC; + if(!nextRC.Verify(time_now_ms(), false)) + return false; + _rc = std::move(nextRC); // propagate RC by renegotiating sessions ForEachPeer([](ILinkSession *s) { if(s->RenegotiateSession()) @@ -368,19 +369,34 @@ namespace llarp // reset netid in our rc _rc.netID = llarp::NetID(); } + const auto linktypename = conf->router.defaultLinkProto(); + _defaultLinkType = LinkFactory::TypeFromName(linktypename); + if(_defaultLinkType == LinkFactory::LinkType::eLinkUnknown) + { + LogError("failed to set link type to '", linktypename, + "' as that is invalid"); + return false; + } // IWP config - m_OutboundPort = conf->iwp_links.outboundPort(); + m_OutboundPort = std::get< LinksConfig::Port >(conf->links.outboundLink()); // Router config _rc.SetNick(conf->router.nickname()); - maxConnectedRouters = conf->router.maxConnectedRouters(); - minConnectedRouters = conf->router.minConnectedRouters(); - encryption_keyfile = conf->router.encryptionKeyfile(); - our_rc_file = conf->router.ourRcFile(); - transport_keyfile = conf->router.transportKeyfile(); - addrInfo = conf->router.addrInfo(); - publicOverride = conf->router.publicOverride(); - ip4addr = conf->router.ip4addr(); + _outboundSessionMaker.maxConnectedRouters = + conf->router.maxConnectedRouters(); + _outboundSessionMaker.minConnectedRouters = + conf->router.minConnectedRouters(); + encryption_keyfile = conf->router.encryptionKeyfile(); + our_rc_file = conf->router.ourRcFile(); + transport_keyfile = conf->router.transportKeyfile(); + addrInfo = conf->router.addrInfo(); + publicOverride = conf->router.publicOverride(); + ip4addr = conf->router.ip4addr(); + + if(!conf->router.blockBogons().value_or(true)) + { + RouterContact::BlockBogons = false; + } // Lokid Config usingSNSeed = conf->lokid.usingSNSeed; @@ -391,7 +407,7 @@ namespace llarp lokidRPCPassword = conf->lokid.lokidRPCPassword; // TODO: add config flag for "is service node" - if(conf->iwp_links.servers().size()) + if(conf->links.inboundLinks().size()) { m_isServiceNode = true; } @@ -479,15 +495,34 @@ namespace llarp } // create inbound links, if we are a service node - for(const auto &serverConfig : conf->iwp_links.servers()) + for(const auto &serverConfig : conf->links.inboundLinks()) { - auto server = llarp::utp::NewInboundLink( + // get default factory + auto inboundLinkFactory = LinkFactory::Obtain(_defaultLinkType, true); + // for each option if provided ... + for(const auto &opt : std::get< LinksConfig::Options >(serverConfig)) + { + // try interpreting it as a link type + const auto linktype = LinkFactory::TypeFromName(opt); + if(linktype != LinkFactory::LinkType::eLinkUnknown) + { + // override link factory if it's a valid link type + auto factory = LinkFactory::Obtain(linktype, true); + if(factory) + { + inboundLinkFactory = std::move(factory); + break; + } + } + } + + auto server = inboundLinkFactory( encryption(), util::memFn(&AbstractRouter::rc, this), util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), + util::memFn(&AbstractRouter::Sign, this), util::memFn(&IOutboundSessionMaker::OnSessionEstablished, &_outboundSessionMaker), util::memFn(&AbstractRouter::CheckRenegotiateValid, this), - util::memFn(&AbstractRouter::Sign, this), util::memFn(&IOutboundSessionMaker::OnConnectTimeout, &_outboundSessionMaker), util::memFn(&AbstractRouter::SessionClosed, this)); @@ -498,9 +533,9 @@ namespace llarp return false; } - const auto &key = std::get< 0 >(serverConfig); - int af = std::get< 1 >(serverConfig); - uint16_t port = std::get< 2 >(serverConfig); + const auto &key = std::get< LinksConfig::Interface >(serverConfig); + int af = std::get< LinksConfig::AddressFamily >(serverConfig); + uint16_t port = std::get< LinksConfig::Port >(serverConfig); if(!server->Configure(netloop(), key, af, port)) { LogError("failed to bind inbound link on ", key, " port ", port); @@ -655,16 +690,16 @@ namespace llarp const size_t connected = NumberOfConnectedRouters(); const size_t N = nodedb()->num_loaded(); - if(N < minRequiredRouters) + if(N < llarp::path::default_len) { - LogInfo("We need at least ", minRequiredRouters, + LogInfo("We need at least ", llarp::path::default_len, " service nodes to build paths but we have ", N, " in nodedb"); _rcLookupHandler.ExploreNetwork(); } - if(connected < minConnectedRouters) + if(connected < _outboundSessionMaker.minConnectedRouters) { - size_t dlt = minConnectedRouters - connected; + size_t dlt = _outboundSessionMaker.minConnectedRouters - connected; LogInfo("connecting to ", dlt, " random routers to keep alive"); _outboundSessionMaker.ConnectToRandomRouters(dlt, now); } @@ -849,7 +884,7 @@ namespace llarp ai.ip = *publicAddr.addr6(); ai.port = publicAddr.port(); } - if(IsBogon(ai.ip)) + if(RouterContact::BlockBogons && IsBogon(ai.ip)) return; _rc.addrs.push_back(ai); if(ExitEnabled()) @@ -877,7 +912,7 @@ namespace llarp LogError("failed to save RC"); return false; } - + _outboundSessionMaker.SetOurRouter(pubkey()); if(!_linkManager.StartLinks(_logic)) { LogWarn("One or more links failed to start."); @@ -886,6 +921,14 @@ namespace llarp EnsureNetConfigDefaultsSane(netConfig); + const auto limits = + IsServiceNode() ? llarp::limits::snode : llarp::limits::client; + + _outboundSessionMaker.minConnectedRouters = std::max( + _outboundSessionMaker.minConnectedRouters, limits.DefaultMinRouters); + _outboundSessionMaker.maxConnectedRouters = std::max( + _outboundSessionMaker.maxConnectedRouters, limits.DefaultMaxRouters); + if(IsServiceNode()) { // initialize as service node @@ -896,14 +939,12 @@ namespace llarp } RouterID us = pubkey(); LogInfo("initalized service node: ", us); - if(minConnectedRouters < 6) - minConnectedRouters = 6; + // relays do not use profiling routerProfiling().Disable(); } else { - maxConnectedRouters = minConnectedRouters + 1; // we are a client // regenerate keys and resign rc before everything else CryptoManager::instance()->identity_keygen(_identity); @@ -965,14 +1006,14 @@ namespace llarp static void RouterAfterStopLinks(void *u, uint64_t, uint64_t) { - Router *self = static_cast< Router * >(u); + auto *self = static_cast< Router * >(u); self->Close(); } static void RouterAfterStopIssued(void *u, uint64_t, uint64_t) { - Router *self = static_cast< Router * >(u); + auto *self = static_cast< Router * >(u); self->StopLinks(); self->nodedb()->AsyncFlushToDisk(); self->_logic->call_later({200, self, &RouterAfterStopLinks}); @@ -1059,48 +1100,44 @@ namespace llarp bool Router::InitOutboundLinks() { - using LinkFactory = std::function< LinkLayer_ptr( - const SecretKey &, GetRCFunc, LinkMessageHandler, - SessionEstablishedHandler, SessionRenegotiateHandler, SignBufferFunc, - TimeoutHandler, SessionClosedHandler) >; + const auto linkTypeName = LinkFactory::NameFromType(_defaultLinkType); + LogInfo("initialize outbound link: ", linkTypeName); + auto factory = LinkFactory::Obtain(_defaultLinkType, false); + if(factory == nullptr) + { + LogError("cannot initialize outbound link of type '", linkTypeName, + "' as it has no implementation"); + return false; + } + auto link = + factory(encryption(), util::memFn(&AbstractRouter::rc, this), + util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), + util::memFn(&AbstractRouter::Sign, this), + util::memFn(&IOutboundSessionMaker::OnSessionEstablished, + &_outboundSessionMaker), + util::memFn(&AbstractRouter::CheckRenegotiateValid, this), + util::memFn(&IOutboundSessionMaker::OnConnectTimeout, + &_outboundSessionMaker), + util::memFn(&AbstractRouter::SessionClosed, this)); + + if(!link) + return false; + if(!link->EnsureKeys(transport_keyfile.string().c_str())) + { + LogError("failed to load ", transport_keyfile); + return false; + } - static std::list< LinkFactory > linkFactories = {utp::NewOutboundLink, - iwp::NewServer}; + const auto afs = {AF_INET, AF_INET6}; - bool addedAtLeastOne = false; - for(const auto &factory : linkFactories) + for(const auto af : afs) { - auto link = factory( - encryption(), util::memFn(&AbstractRouter::rc, this), - util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this), - util::memFn(&IOutboundSessionMaker::OnSessionEstablished, - &_outboundSessionMaker), - util::memFn(&AbstractRouter::CheckRenegotiateValid, this), - util::memFn(&AbstractRouter::Sign, this), - util::memFn(&IOutboundSessionMaker::OnConnectTimeout, - &_outboundSessionMaker), - util::memFn(&AbstractRouter::SessionClosed, this)); - - if(!link) - continue; - if(!link->EnsureKeys(transport_keyfile.string().c_str())) - { - LogError("failed to load ", transport_keyfile); + if(!link->Configure(netloop(), "*", af, m_OutboundPort)) continue; - } - - const auto afs = {AF_INET, AF_INET6}; - - for(const auto af : afs) - { - if(!link->Configure(netloop(), "*", af, m_OutboundPort)) - continue; - _linkManager.AddLink(std::move(link), false); - addedAtLeastOne = true; - break; - } + _linkManager.AddLink(std::move(link), false); + return true; } - return addedAtLeastOne; + return false; } bool diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 2b6b2df86..27a83b1c5 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -175,6 +176,8 @@ namespace llarp struct sockaddr_in ip4addr; AddressInfo addrInfo; + LinkFactory::LinkType _defaultLinkType; + llarp_ev_loop_ptr _netloop; std::shared_ptr< llarp::thread::ThreadPool > cryptoworker; std::shared_ptr< Logic > _logic; @@ -194,13 +197,6 @@ namespace llarp Sign(Signature &sig, const llarp_buffer_t &buf) const override; uint16_t m_OutboundPort = 0; - - /// always maintain this many connections to other routers - size_t minConnectedRouters = 2; - /// hard upperbound limit on the number of router to router connections - size_t maxConnectedRouters = 2000; - - size_t minRequiredRouters = 4; /// how often do we resign our RC? milliseconds. // TODO: make configurable llarp_time_t rcRegenInterval = 60 * 60 * 1000; @@ -297,7 +293,7 @@ namespace llarp Router(std::shared_ptr< llarp::thread::ThreadPool > worker, llarp_ev_loop_ptr __netloop, std::shared_ptr< Logic > logic); - ~Router(); + ~Router() override; bool HandleRecvLinkMessageBuffer(ILinkSession *from, diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 7ab78174d..8930a609a 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -23,7 +23,7 @@ namespace llarp return defaultID; } - bool RouterContact::IgnoreBogons = false; + bool RouterContact::BlockBogons = true; #ifdef TESTNET // 1 minute for testnet @@ -37,7 +37,7 @@ namespace llarp /// an RC inserted long enough ago (30 min) is considered stale and is removed llarp_time_t RouterContact::StaleInsertionAge = 30 * 60 * 1000; - NetID::NetID(const byte_t *val) : AlignedBuffer< 8 >() + NetID::NetID(const byte_t *val) { size_t len = strnlen(reinterpret_cast< const char * >(val), size()); std::copy(val, val + len, begin()); @@ -67,6 +67,7 @@ namespace llarp llarp_buffer_t strbuf; if(!bencode_read_string(buf, &strbuf)) return false; + if(strbuf.sz > size()) return false; @@ -106,13 +107,17 @@ namespace llarp return false; std::string nick = Nick(); - if(nick.size()) + if(!nick.empty()) { /* write nickname */ if(!bencode_write_bytestring(buf, "n", 1)) + { return false; + } if(!bencode_write_bytestring(buf, nick.c_str(), nick.size())) + { return false; + } } /* write encryption pubkey */ @@ -163,9 +168,14 @@ namespace llarp util::StatusObject obj{{"lastUpdated", last_updated}, {"exit", IsExit()}, {"publicRouter", IsPublicRouter()}, - {"identity", pubkey.ToHex()}}; + {"identity", pubkey.ToString()}, + {"addresses", addrs}}; + if(HasNick()) - obj.Put("nickname", Nick()); + { + obj["nickname"] = Nick(); + } + return obj; } @@ -186,9 +196,13 @@ namespace llarp { llarp_buffer_t strbuf; if(!bencode_read_string(buf, &strbuf)) + { return false; - if(strbuf.sz > nickname.size()) + } + if(strbuf.sz > llarp::AlignedBuffer< (32) >::size()) + { return false; + } nickname.Zero(); std::copy(strbuf.base, strbuf.base + strbuf.sz, nickname.begin()); return true; @@ -215,7 +229,7 @@ namespace llarp bool RouterContact::IsPublicRouter() const { - return addrs.size() > 0; + return !addrs.empty(); } bool @@ -274,7 +288,9 @@ namespace llarp signature.Zero(); last_updated = time_now_ms(); if(!BEncode(&buf)) + { return false; + } buf.sz = buf.cur - buf.base; buf.cur = buf.base; return CryptoManager::instance()->sign(signature, secretkey, buf); @@ -300,7 +316,7 @@ namespace llarp } for(const auto &a : addrs) { - if(IsBogon(a.ip) && !IgnoreBogons) + if(IsBogon(a.ip) && BlockBogons) { llarp::LogError("invalid address info: ", a); return false; @@ -346,17 +362,23 @@ namespace llarp std::array< byte_t, MAX_RC_SIZE > tmp; llarp_buffer_t buf(tmp); if(!BEncode(&buf)) + { return false; + } buf.sz = buf.cur - buf.base; buf.cur = buf.base; const fs::path fpath = std::string(fname); /* */ auto optional_f = llarp::util::OpenFileStream< std::ofstream >(fpath, std::ios::binary); if(!optional_f) + { return false; + } auto &f = optional_f.value(); if(!f.is_open()) + { return false; + } f.write((char *)buf.base, buf.sz); return true; } @@ -376,7 +398,9 @@ namespace llarp f.seekg(0, std::ios::end); auto l = f.tellg(); if(l > static_cast< std::streamoff >(sizeof tmp)) + { return false; + } f.seekg(0, std::ios::beg); f.read((char *)tmp.data(), l); return BDecode(&buf); diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index a65f7bcea..280900335 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #define MAX_RC_SIZE (1024) @@ -66,7 +67,7 @@ namespace llarp struct RouterContact { /// for unit tests - static bool IgnoreBogons; + static bool BlockBogons; static llarp_time_t Lifetime; static llarp_time_t UpdateInterval; @@ -107,6 +108,12 @@ namespace llarp util::StatusObject ExtractStatus() const; + nlohmann::json + ToJson() const + { + return ExtractStatus(); + } + bool BEncode(llarp_buffer_t *buf) const; @@ -137,7 +144,7 @@ namespace llarp bool IsExit() const { - return exits.size() > 0; + return !exits.empty(); } bool diff --git a/llarp/router_id.cpp b/llarp/router_id.cpp index a48181131..81d1534e3 100644 --- a/llarp/router_id.cpp +++ b/llarp/router_id.cpp @@ -21,7 +21,9 @@ namespace llarp { auto pos = str.find(".snode"); if(pos == std::string::npos || pos == 0) + { return false; + } return Base32Decode(str.substr(0, pos), *this); } } // namespace llarp diff --git a/llarp/router_id.hpp b/llarp/router_id.hpp index dc48565a6..bdc643179 100644 --- a/llarp/router_id.hpp +++ b/llarp/router_id.hpp @@ -12,7 +12,7 @@ namespace llarp using Data = std::array< byte_t, SIZE >; - RouterID() : AlignedBuffer< SIZE >() + RouterID() { } diff --git a/llarp/routing/dht_message.hpp b/llarp/routing/dht_message.hpp index ae249401d..24534087b 100644 --- a/llarp/routing/dht_message.hpp +++ b/llarp/routing/dht_message.hpp @@ -15,7 +15,7 @@ namespace llarp std::vector< llarp::dht::IMessage::Ptr_t > M; uint64_t V = 0; - ~DHTMessage() = default; + ~DHTMessage() override = default; bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; diff --git a/llarp/routing/message.hpp b/llarp/routing/message.hpp index e42909b5f..89cda76c7 100644 --- a/llarp/routing/message.hpp +++ b/llarp/routing/message.hpp @@ -15,16 +15,12 @@ namespace llarp struct IMessage { PathID_t from; - uint64_t S; + uint64_t S{0}; uint64_t version = LLARP_PROTO_VERSION; - IMessage() : S(0) - { - } + IMessage() = default; - virtual ~IMessage() - { - } + virtual ~IMessage() = default; virtual bool BEncode(llarp_buffer_t* buf) const = 0; diff --git a/llarp/routing/message_parser.cpp b/llarp/routing/message_parser.cpp index af90db319..b1173b29b 100644 --- a/llarp/routing/message_parser.cpp +++ b/llarp/routing/message_parser.cpp @@ -31,16 +31,11 @@ namespace llarp }; InboundMessageParser::InboundMessageParser() - : firstKey(false) - , ourKey('\0') - , msg(nullptr) - , m_Holder(std::make_unique< MessageHolder >()) + : m_Holder(std::make_unique< MessageHolder >()) { } - InboundMessageParser::~InboundMessageParser() - { - } + InboundMessageParser::~InboundMessageParser() = default; bool InboundMessageParser::operator()(llarp_buffer_t* buffer, diff --git a/llarp/routing/message_parser.hpp b/llarp/routing/message_parser.hpp index 5c0d7f78d..7353ce470 100644 --- a/llarp/routing/message_parser.hpp +++ b/llarp/routing/message_parser.hpp @@ -29,12 +29,12 @@ namespace llarp operator()(llarp_buffer_t* buffer, llarp_buffer_t* key); private: - bool firstKey; - char ourKey; + bool firstKey{false}; + char ourKey{'\0'}; struct MessageHolder; - IMessage* msg; + IMessage* msg{nullptr}; std::unique_ptr< MessageHolder > m_Holder; }; } // namespace routing diff --git a/llarp/routing/path_confirm_message.hpp b/llarp/routing/path_confirm_message.hpp index 7cfc008f6..58b3e5b80 100644 --- a/llarp/routing/path_confirm_message.hpp +++ b/llarp/routing/path_confirm_message.hpp @@ -14,7 +14,7 @@ namespace llarp PathConfirmMessage() = default; PathConfirmMessage(uint64_t lifetime); - ~PathConfirmMessage() = default; + ~PathConfirmMessage() override = default; bool BEncode(llarp_buffer_t* buf) const override; diff --git a/llarp/routing/path_latency_message.cpp b/llarp/routing/path_latency_message.cpp index 5d8d51a08..906f36497 100644 --- a/llarp/routing/path_latency_message.cpp +++ b/llarp/routing/path_latency_message.cpp @@ -7,9 +7,7 @@ namespace llarp { namespace routing { - PathLatencyMessage::PathLatencyMessage() - { - } + PathLatencyMessage::PathLatencyMessage() = default; bool PathLatencyMessage::DecodeKey(const llarp_buffer_t& key, diff --git a/llarp/routing/path_transfer_message.hpp b/llarp/routing/path_transfer_message.hpp index f0d9332f4..4dbcd56ef 100644 --- a/llarp/routing/path_transfer_message.hpp +++ b/llarp/routing/path_transfer_message.hpp @@ -22,7 +22,7 @@ namespace llarp { Y.Randomize(); } - ~PathTransferMessage() = default; + ~PathTransferMessage() override = default; bool DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; diff --git a/llarp/rpc/rpc.cpp b/llarp/rpc/rpc.cpp index 8ae892ea1..c7cb7a1b8 100644 --- a/llarp/rpc/rpc.cpp +++ b/llarp/rpc/rpc.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace llarp { @@ -22,15 +23,13 @@ namespace llarp { } - ~CallerHandler() - { - } + ~CallerHandler() override = default; virtual bool HandleJSONResult(const nlohmann::json& val) = 0; bool - HandleResponse(::abyss::http::RPC_Response response) + HandleResponse(::abyss::http::RPC_Response response) override { if(!response.is_object()) { @@ -50,7 +49,7 @@ namespace llarp } void - PopulateReqHeaders(abyss::http::Headers_t& hdr); + PopulateReqHeaders(abyss::http::Headers_t& hdr) override; }; struct GetServiceNodeListHandler final : public CallerHandler @@ -58,14 +57,12 @@ namespace llarp using PubkeyList_t = std::vector< RouterID >; using Callback_t = std::function< void(const PubkeyList_t&, bool) >; - ~GetServiceNodeListHandler() - { - } + ~GetServiceNodeListHandler() override = default; Callback_t handler; GetServiceNodeListHandler(::abyss::http::ConnImpl* impl, CallerImpl* parent, Callback_t h) - : CallerHandler(impl, parent), handler(h) + : CallerHandler(impl, parent), handler(std::move(h)) { } @@ -178,9 +175,7 @@ namespace llarp LogError("service node list not updated"); } - ~CallerImpl() - { - } + ~CallerImpl() = default; }; void @@ -197,15 +192,12 @@ namespace llarp { } - ~Handler() - { - } + ~Handler() override = default; Response DumpState() const { - const util::StatusObject dump = router->ExtractStatus(); - return dump.get(); + return router->ExtractStatus(); } Response @@ -269,7 +261,7 @@ namespace llarp absl::optional< Response > HandleJSONRPC(Method_t method, - __attribute__((unused)) const Params& params) + ABSL_ATTRIBUTE_UNUSED const Params& params) override { if(method == "llarp.admin.link.neighboors") { @@ -283,7 +275,7 @@ namespace llarp { return DumpState(); } - else if(method == "llarp.admin.status") + if(method == "llarp.admin.status") { return DumpStatus(); } @@ -299,7 +291,7 @@ namespace llarp } AbstractRouter* router; ::abyss::httpd::IRPCHandler* - CreateHandler(::abyss::httpd::ConnImpl* conn) + CreateHandler(::abyss::httpd::ConnImpl* conn) override { return new Handler(conn, router); } @@ -314,9 +306,7 @@ namespace llarp { } - ~ServerImpl() - { - } + ~ServerImpl() = default; void Stop() @@ -349,9 +339,7 @@ namespace llarp { } - Caller::~Caller() - { - } + Caller::~Caller() = default; void Caller::Stop() @@ -382,9 +370,7 @@ namespace llarp { } - Server::~Server() - { - } + Server::~Server() = default; void Server::Stop() diff --git a/llarp/service/async_key_exchange.cpp b/llarp/service/async_key_exchange.cpp index a788e24e3..660277c95 100644 --- a/llarp/service/async_key_exchange.cpp +++ b/llarp/service/async_key_exchange.cpp @@ -4,20 +4,18 @@ #include #include #include +#include namespace llarp { namespace service { - AsyncKeyExchange::AsyncKeyExchange(std::shared_ptr< Logic > l, - const ServiceInfo& r, - const Identity& localident, - const PQPubKey& introsetPubKey, - const Introduction& remote, - IDataHandler* h, const ConvoTag& t, - ProtocolType proto) - : logic(l) - , m_remote(r) + AsyncKeyExchange::AsyncKeyExchange( + std::shared_ptr< Logic > l, ServiceInfo r, const Identity& localident, + const PQPubKey& introsetPubKey, const Introduction& remote, + IDataHandler* h, const ConvoTag& t, ProtocolType proto) + : logic(std::move(l)) + , m_remote(std::move(r)) , m_LocalIdentity(localident) , introPubKey(introsetPubKey) , remoteIntro(remote) @@ -30,7 +28,7 @@ namespace llarp void AsyncKeyExchange::Result(void* user) { - AsyncKeyExchange* self = static_cast< AsyncKeyExchange* >(user); + auto* self = static_cast< AsyncKeyExchange* >(user); // put values self->handler->PutSenderFor(self->msg.tag, self->m_remote, false); self->handler->PutCachedSessionKeyFor(self->msg.tag, self->sharedKey); @@ -43,7 +41,7 @@ namespace llarp void AsyncKeyExchange::Encrypt(void* user) { - AsyncKeyExchange* self = static_cast< AsyncKeyExchange* >(user); + auto* self = static_cast< AsyncKeyExchange* >(user); // derive ntru session key component SharedSecret K; auto crypto = CryptoManager::instance(); diff --git a/llarp/service/async_key_exchange.hpp b/llarp/service/async_key_exchange.hpp index a555632f4..358481b23 100644 --- a/llarp/service/async_key_exchange.hpp +++ b/llarp/service/async_key_exchange.hpp @@ -26,7 +26,7 @@ namespace llarp IDataHandler* handler; ConvoTag tag; - AsyncKeyExchange(std::shared_ptr< Logic > l, const ServiceInfo& r, + AsyncKeyExchange(std::shared_ptr< Logic > l, ServiceInfo r, const Identity& localident, const PQPubKey& introsetPubKey, const Introduction& remote, IDataHandler* h, diff --git a/llarp/service/context.cpp b/llarp/service/context.cpp index ca1e3e420..072f178d1 100644 --- a/llarp/service/context.cpp +++ b/llarp/service/context.cpp @@ -49,9 +49,7 @@ namespace llarp { } - Context::~Context() - { - } + Context::~Context() = default; bool Context::StopAll() @@ -73,7 +71,7 @@ namespace llarp auto itr = m_Endpoints.begin(); while(itr != m_Endpoints.end()) { - obj.Put(itr->first, itr->second->ExtractStatus()); + obj[itr->first] = itr->second->ExtractStatus(); ++itr; } return obj; diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index f00fb9e9d..a30bf1fca 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace llarp { @@ -138,18 +139,17 @@ namespace llarp addr = itr->second.remote.Addr(); return true; } - else + + for(const auto& item : m_state->m_SNodeSessions) { - for(const auto& item : m_state->m_SNodeSessions) + if(item.second.second == tag) { - if(item.second.second == tag) - { - snode = true; - addr = item.first; - return true; - } + snode = true; + addr = item.first; + return true; } } + return false; } @@ -162,8 +162,8 @@ namespace llarp util::StatusObject Endpoint::ExtractStatus() const { - auto obj = path::Builder::ExtractStatus(); - obj.Put("identity", m_Identity.pub.Addr().ToString()); + auto obj = path::Builder::ExtractStatus(); + obj["identity"] = m_Identity.pub.Addr().ToString(); return m_state->ExtractStatus(obj); } @@ -497,25 +497,24 @@ namespace llarp { IntroSet m_IntroSet; Endpoint* m_Endpoint; - PublishIntroSetJob(Endpoint* parent, uint64_t id, - const IntroSet& introset) + PublishIntroSetJob(Endpoint* parent, uint64_t id, IntroSet introset) : IServiceLookup(parent, id, "PublishIntroSet") - , m_IntroSet(introset) + , m_IntroSet(std::move(introset)) , m_Endpoint(parent) { } std::shared_ptr< routing::IMessage > - BuildRequestMessage() + BuildRequestMessage() override { auto msg = std::make_shared< routing::DHTMessage >(); msg->M.emplace_back( - std::make_unique< dht::PublishIntroMessage >(m_IntroSet, txid, 1)); + std::make_unique< dht::PublishIntroMessage >(m_IntroSet, txid, 5)); return msg; } bool - HandleResponse(const std::set< IntroSet >& response) + HandleResponse(const std::set< IntroSet >& response) override { if(response.size()) m_Endpoint->IntroSetPublished(); @@ -698,11 +697,11 @@ namespace llarp { if(msg->R.size()) { - llarp_async_verify_rc* job = new llarp_async_verify_rc; - job->nodedb = Router()->nodedb(); - job->cryptoworker = Router()->threadpool(); - job->diskworker = Router()->diskworker(); - job->logic = Router()->logic(); + auto* job = new llarp_async_verify_rc; + job->nodedb = Router()->nodedb(); + job->cryptoworker = Router()->threadpool(); + job->diskworker = Router()->diskworker(); + job->logic = Router()->logic(); job->hook = std::bind(&Endpoint::HandleVerifyGotRouter, this, msg, std::placeholders::_1); job->rc = msg->R[0]; @@ -1206,11 +1205,12 @@ namespace llarp // time from now that the newest intro expires at if(intro.ExpiresSoon(now)) return should; - const auto dlt = intro.expiresAt - now; + const auto dlt = now - (intro.expiresAt - path::default_lifetime); return should || ( // try spacing tunnel builds out evenly in time - (dlt <= (path::default_lifetime / 4)) - && (NumInStatus(path::ePathBuilding) < numPaths)); + (dlt >= (path::default_lifetime / 4)) + && (NumInStatus(path::ePathBuilding) < numPaths) + && !path::Builder::BuildCooldownHit(now)); } std::shared_ptr< Logic > diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index d895e900a..b40dfc345 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -71,7 +71,7 @@ namespace llarp static const size_t MAX_OUTBOUND_CONTEXT_COUNT = 4; Endpoint(const std::string& nickname, AbstractRouter* r, Context* parent); - ~Endpoint(); + ~Endpoint() override; /// return true if we are ready to recv packets from the void bool @@ -94,7 +94,7 @@ namespace llarp virtual bool SetOption(const std::string& k, const std::string& v); - virtual void + void Tick(llarp_time_t now) override; /// return true if we have a resolvable ip address @@ -111,7 +111,7 @@ namespace llarp return {0}; } - virtual void + void ResetInternalState() override; /// router's logic @@ -142,7 +142,7 @@ namespace llarp virtual bool Start(); - virtual std::string + std::string Name() const override; bool @@ -335,7 +335,7 @@ namespace llarp uint64_t GetSeqNoForConvo(const ConvoTag& tag); - virtual bool + bool SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev, RouterContact& cur, size_t hop, path::PathRole roles) override; diff --git a/llarp/service/endpoint_state.cpp b/llarp/service/endpoint_state.cpp index 0e0e31c00..d60e5d566 100644 --- a/llarp/service/endpoint_state.cpp +++ b/llarp/service/endpoint_state.cpp @@ -116,31 +116,40 @@ namespace llarp util::StatusObject EndpointState::ExtractStatus(util::StatusObject& obj) const { - obj.Put("lastPublished", m_LastPublish); - obj.Put("lastPublishAttempt", m_LastPublishAttempt); - obj.Put("introset", m_IntroSet.ExtractStatus()); + obj["lastPublished"] = m_LastPublish; + obj["lastPublishAttempt"] = m_LastPublishAttempt; + obj["introset"] = m_IntroSet.ExtractStatus(); if(!m_Tag.IsZero()) - obj.Put("tag", m_Tag.ToString()); - static auto getSecond = [](const auto& item) -> const auto& { - return item.second; + obj["tag"] = m_Tag.ToString(); + } + + static auto getSecond = [](const auto& item) -> auto + { + return item.second->ExtractStatus(); }; - obj.PutContainer("deadSessions", m_DeadSessions, getSecond); - obj.PutContainer("remoteSessions", m_RemoteSessions, getSecond); - obj.PutContainer("lookups", m_PendingLookups, getSecond); - obj.PutContainer("snodeSessions", m_SNodeSessions, - [](const auto& item) { return item.second.first; }); + + std::transform(m_DeadSessions.begin(), m_DeadSessions.end(), + std::back_inserter(obj["deadSessions"]), getSecond); + std::transform(m_RemoteSessions.begin(), m_RemoteSessions.end(), + std::back_inserter(obj["remoteSessions"]), getSecond); + std::transform(m_PendingLookups.begin(), m_PendingLookups.end(), + std::back_inserter(obj["lookups"]), getSecond); + std::transform( + m_SNodeSessions.begin(), m_SNodeSessions.end(), + std::back_inserter(obj["snodeSessions"]), + [](const auto& item) { return item.second.first->ExtractStatus(); }); util::StatusObject sessionObj{}; for(const auto& item : m_Sessions) { std::string k = item.first.ToHex(); - sessionObj.Put(k, item.second.ExtractStatus()); + sessionObj[k] = item.second.ExtractStatus(); } - obj.Put("converstations", sessionObj); + obj["converstations"] = sessionObj; return obj; } } // namespace service diff --git a/llarp/service/endpoint_state.hpp b/llarp/service/endpoint_state.hpp index 0164c3e2e..d01b274ac 100644 --- a/llarp/service/endpoint_state.hpp +++ b/llarp/service/endpoint_state.hpp @@ -40,7 +40,7 @@ namespace llarp hooks::Backend_ptr m_OnDown; hooks::Backend_ptr m_OnReady; - util::Mutex m_InboundTrafficQueueMutex; + util::Mutex m_InboundTrafficQueueMutex; // protects m_InboundTrafficQueue /// ordered queue for inbound hidden service traffic RecvPacketQueue_t m_InboundTrafficQueue GUARDED_BY(m_InboundTrafficQueueMutex); @@ -55,7 +55,7 @@ namespace llarp std::string m_NetNS; bool m_BundleRC = false; - util::Mutex m_SendQueueMutex; + util::Mutex m_SendQueueMutex; // protects m_SendQueue std::deque< SendEvent_t > m_SendQueue GUARDED_BY(m_SendQueueMutex); PendingTraffic m_PendingTraffic; diff --git a/llarp/service/hidden_service_address_lookup.cpp b/llarp/service/hidden_service_address_lookup.cpp index dd9340f7a..fda8cba45 100644 --- a/llarp/service/hidden_service_address_lookup.cpp +++ b/llarp/service/hidden_service_address_lookup.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace llarp { @@ -11,7 +12,7 @@ namespace llarp HandlerFunc h, const Address& addr, uint64_t tx) - : IServiceLookup(p, tx, "HSLookup"), remote(addr), handle(h) + : IServiceLookup(p, tx, "HSLookup"), remote(addr), handle(std::move(h)) { } diff --git a/llarp/service/hidden_service_address_lookup.hpp b/llarp/service/hidden_service_address_lookup.hpp index 9fdccd472..86aaeee64 100644 --- a/llarp/service/hidden_service_address_lookup.hpp +++ b/llarp/service/hidden_service_address_lookup.hpp @@ -20,15 +20,13 @@ namespace llarp HiddenServiceAddressLookup(Endpoint* p, HandlerFunc h, const Address& addr, uint64_t tx); - ~HiddenServiceAddressLookup() - { - } + ~HiddenServiceAddressLookup() override = default; bool - HandleResponse(const std::set< IntroSet >& results); + HandleResponse(const std::set< IntroSet >& results) override; std::shared_ptr< routing::IMessage > - BuildRequestMessage(); + BuildRequestMessage() override; }; } // namespace service } // namespace llarp diff --git a/llarp/service/intro.hpp b/llarp/service/intro.hpp index e3c4ba628..7edbd174e 100644 --- a/llarp/service/intro.hpp +++ b/llarp/service/intro.hpp @@ -30,7 +30,7 @@ namespace llarp } bool - ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 15000) const + ExpiresSoon(llarp_time_t now, llarp_time_t dlt = 30000) const { if(dlt) return now >= (expiresAt - dlt); diff --git a/llarp/service/intro_set.cpp b/llarp/service/intro_set.cpp index 5f9ae1fd7..cc403856b 100644 --- a/llarp/service/intro_set.cpp +++ b/llarp/service/intro_set.cpp @@ -15,9 +15,9 @@ namespace llarp [](const auto& intro) -> util::StatusObject { return intro.ExtractStatus(); }); - obj.Put("intros", introsObjs); + obj["intros"] = introsObjs; if(!topic.IsZero()) - obj.Put("topic", topic.ToString()); + obj["topic"] = topic.ToString(); return obj; } diff --git a/llarp/service/lookup.cpp b/llarp/service/lookup.cpp index 51f9cfbbf..e231615f5 100644 --- a/llarp/service/lookup.cpp +++ b/llarp/service/lookup.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace llarp { @@ -11,9 +12,8 @@ namespace llarp namespace service { - IServiceLookup::IServiceLookup(ILookupHolder *p, uint64_t tx, - const std::string &n) - : m_parent(p), txid(tx), name(n) + IServiceLookup::IServiceLookup(ILookupHolder *p, uint64_t tx, std::string n) + : m_parent(p), txid(tx), name(std::move(n)) { m_created = time_now_ms(); p->PutLookup(this, tx); diff --git a/llarp/service/lookup.hpp b/llarp/service/lookup.hpp index 25c2dba68..03ffb09e4 100644 --- a/llarp/service/lookup.hpp +++ b/llarp/service/lookup.hpp @@ -23,10 +23,8 @@ namespace llarp struct IServiceLookup { - IServiceLookup() = delete; - virtual ~IServiceLookup() - { - } + IServiceLookup() = delete; + virtual ~IServiceLookup() = default; /// handle lookup result virtual bool @@ -71,8 +69,7 @@ namespace llarp } protected: - IServiceLookup(ILookupHolder* parent, uint64_t tx, - const std::string& name); + IServiceLookup(ILookupHolder* parent, uint64_t tx, std::string name); llarp_time_t m_created; }; diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 53f630a21..2b6c708e7 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -66,9 +66,7 @@ namespace llarp } } - OutboundContext::~OutboundContext() - { - } + OutboundContext::~OutboundContext() = default; /// actually swap intros void @@ -215,27 +213,25 @@ namespace llarp util::StatusObject OutboundContext::ExtractStatus() const { - auto obj = path::Builder::ExtractStatus(); - obj.Put("currentConvoTag", currentConvoTag.ToHex()); - obj.Put("remoteIntro", remoteIntro.ExtractStatus()); - obj.Put("sessionCreatedAt", createdAt); - obj.Put("lastGoodSend", lastGoodSend); - obj.Put("seqno", sequenceNo); - obj.Put("markedBad", markedBad); - obj.Put("lastShift", lastShift); - obj.Put("remoteIdentity", remoteIdent.Addr().ToString()); - obj.Put("currentRemoteIntroset", currentIntroSet.ExtractStatus()); - obj.Put("nextIntro", m_NextIntro.ExtractStatus()); - std::vector< util::StatusObject > badIntrosObj; + auto obj = path::Builder::ExtractStatus(); + obj["currentConvoTag"] = currentConvoTag.ToHex(); + obj["remoteIntro"] = remoteIntro.ExtractStatus(); + obj["sessionCreatedAt"] = createdAt; + obj["lastGoodSend"] = lastGoodSend; + obj["seqno"] = sequenceNo; + obj["markedBad"] = markedBad; + obj["lastShift"] = lastShift; + obj["remoteIdentity"] = remoteIdent.Addr().ToString(); + obj["currentRemoteIntroset"] = currentIntroSet.ExtractStatus(); + obj["nextIntro"] = m_NextIntro.ExtractStatus(); + std::transform(m_BadIntros.begin(), m_BadIntros.end(), - std::back_inserter(badIntrosObj), + std::back_inserter(obj["badIntros"]), [](const auto& item) -> util::StatusObject { - util::StatusObject o{ + return util::StatusObject{ {"count", item.second}, {"intro", item.first.ExtractStatus()}}; - return o; }); - obj.Put("badIntros", badIntrosObj); return obj; } diff --git a/llarp/service/outbound_context.hpp b/llarp/service/outbound_context.hpp index 6cffa1296..1f591540b 100644 --- a/llarp/service/outbound_context.hpp +++ b/llarp/service/outbound_context.hpp @@ -21,7 +21,7 @@ namespace llarp public std::enable_shared_from_this< OutboundContext > { OutboundContext(const IntroSet& introSet, Endpoint* parent); - ~OutboundContext(); + ~OutboundContext() override; util::StatusObject ExtractStatus() const; diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index c3d0b245e..09fb02d82 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace llarp { @@ -19,9 +20,7 @@ namespace llarp { } - ProtocolMessage::~ProtocolMessage() - { - } + ProtocolMessage::~ProtocolMessage() = default; void ProtocolMessage::PutBuffer(const llarp_buffer_t& buf) @@ -92,9 +91,7 @@ namespace llarp return bencode_end(buf); } - ProtocolFrame::~ProtocolFrame() - { - } + ProtocolFrame::~ProtocolFrame() = default; bool ProtocolFrame::BEncode(llarp_buffer_t* buf) const @@ -255,11 +252,10 @@ namespace llarp const Introduction fromIntro; AsyncFrameDecrypt(std::shared_ptr< Logic > l, const Identity& localIdent, - IDataHandler* h, - const std::shared_ptr< ProtocolMessage >& m, + IDataHandler* h, std::shared_ptr< ProtocolMessage > m, const ProtocolFrame& f, const Introduction& recvIntro) - : logic(l) - , msg(m) + : logic(std::move(l)) + , msg(std::move(m)) , m_LocalIdentity(localIdent) , handler(h) , frame(f) @@ -270,8 +266,8 @@ namespace llarp static void Work(void* user) { - AsyncFrameDecrypt* self = static_cast< AsyncFrameDecrypt* >(user); - auto crypto = CryptoManager::instance(); + auto* self = static_cast< AsyncFrameDecrypt* >(user); + auto crypto = CryptoManager::instance(); SharedSecret K; SharedSecret sharedKey; // copy @@ -405,6 +401,11 @@ namespace llarp LogError("failed to decrypt message"); return false; } + if(T != msg->tag && !msg->tag.IsZero()) + { + LogError("convotag missmatch: ", T, " != ", msg->tag); + return false; + } msg->handler = handler; const PathID_t fromPath = F; logic->queue_func( diff --git a/llarp/service/protocol.hpp b/llarp/service/protocol.hpp index 80e5ed8e2..c26963986 100644 --- a/llarp/service/protocol.hpp +++ b/llarp/service/protocol.hpp @@ -104,7 +104,7 @@ namespace llarp Clear(); } - ~ProtocolFrame(); + ~ProtocolFrame() override; bool operator==(const ProtocolFrame& other) const; diff --git a/llarp/service/router_lookup_job.cpp b/llarp/service/router_lookup_job.cpp index 1b60d2cd4..395a6c1e3 100644 --- a/llarp/service/router_lookup_job.cpp +++ b/llarp/service/router_lookup_job.cpp @@ -1,13 +1,14 @@ #include #include +#include namespace llarp { namespace service { RouterLookupJob::RouterLookupJob(Endpoint* p, RouterLookupHandler h) - : handler(h), txid(p->GenTXID()), started(p->Now()) + : handler(std::move(h)), txid(p->GenTXID()), started(p->Now()) { } diff --git a/llarp/service/sendcontext.cpp b/llarp/service/sendcontext.cpp index a7ba5a088..e25647978 100644 --- a/llarp/service/sendcontext.cpp +++ b/llarp/service/sendcontext.cpp @@ -4,15 +4,15 @@ #include #include #include +#include namespace llarp { namespace service { - SendContext::SendContext(const ServiceInfo& ident, - const Introduction& intro, path::PathSet* send, - Endpoint* ep) - : remoteIdent(ident) + SendContext::SendContext(ServiceInfo ident, const Introduction& intro, + path::PathSet* send, Endpoint* ep) + : remoteIdent(std::move(ident)) , remoteIntro(intro) , m_PathSet(send) , m_DataHandler(ep) diff --git a/llarp/service/sendcontext.hpp b/llarp/service/sendcontext.hpp index d289c5640..9ca0cb8c0 100644 --- a/llarp/service/sendcontext.hpp +++ b/llarp/service/sendcontext.hpp @@ -20,7 +20,7 @@ namespace llarp struct SendContext { - SendContext(const ServiceInfo& ident, const Introduction& intro, + SendContext(ServiceInfo ident, const Introduction& intro, path::PathSet* send, Endpoint* ep); void diff --git a/llarp/service/tag_lookup_job.hpp b/llarp/service/tag_lookup_job.hpp index f061df504..0221e4e6b 100644 --- a/llarp/service/tag_lookup_job.hpp +++ b/llarp/service/tag_lookup_job.hpp @@ -28,9 +28,7 @@ namespace llarp { } - ~CachedTagResult() - { - } + ~CachedTagResult() = default; void Expire(llarp_time_t now); @@ -54,9 +52,7 @@ namespace llarp { TagLookupJob(Endpoint* parent, CachedTagResult* result); - ~TagLookupJob() - { - } + ~TagLookupJob() override = default; std::shared_ptr< routing::IMessage > BuildRequestMessage() override diff --git a/llarp/testnet.c b/llarp/testnet.c index 60f501489..7825445be 100644 --- a/llarp/testnet.c +++ b/llarp/testnet.c @@ -1,4 +1,4 @@ -#ifdef SHADOW_TESTNET +#ifdef LOKINET_SHADOW #include /** insert shadow test network specific code here */ diff --git a/llarp/util/bencode.cpp b/llarp/util/bencode.cpp index b8b32b3ee..25e46238f 100644 --- a/llarp/util/bencode.cpp +++ b/llarp/util/bencode.cpp @@ -1,8 +1,8 @@ #include #include #include -#include -#include +#include +#include bool bencode_read_integer(struct llarp_buffer_t* buffer, uint64_t* result) diff --git a/llarp/util/bencode.h b/llarp/util/bencode.h index 04fe12c8a..46284126d 100644 --- a/llarp/util/bencode.h +++ b/llarp/util/bencode.h @@ -6,8 +6,8 @@ #include #include -#include -#include + +#include /** * bencode.h diff --git a/llarp/util/buffer.cpp b/llarp/util/buffer.cpp index 8a0f0d9bc..aca4fa1ae 100644 --- a/llarp/util/buffer.cpp +++ b/llarp/util/buffer.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include size_t llarp_buffer_t::size_left() const diff --git a/llarp/util/buffer.hpp b/llarp/util/buffer.hpp index e95e66d93..e9a635378 100644 --- a/llarp/util/buffer.hpp +++ b/llarp/util/buffer.hpp @@ -7,10 +7,10 @@ #include #include -#include -#include -#include -#include + +#include +#include +#include #include #include @@ -64,20 +64,18 @@ struct ManagedBuffer; struct llarp_buffer_t { /// starting memory address - byte_t *base; + byte_t *base{nullptr}; /// memory address of stream position - byte_t *cur; + byte_t *cur{nullptr}; /// max size of buffer - size_t sz; + size_t sz{0}; byte_t operator[](size_t x) { return *(this->base + x); } - llarp_buffer_t() : base(nullptr), cur(nullptr), sz(0) - { - } + llarp_buffer_t() = default; llarp_buffer_t(byte_t *b, byte_t *c, size_t s) : base(b), cur(c), sz(s) { diff --git a/llarp/util/codel.hpp b/llarp/util/codel.hpp index 02486ea50..2d9e5d0bd 100644 --- a/llarp/util/codel.hpp +++ b/llarp/util/codel.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace llarp { @@ -31,8 +32,11 @@ namespace llarp llarp_time_t initialIntervalMs = 100, size_t MaxSize = 1024 > struct CoDelQueue { - CoDelQueue(const std::string& name, const PutTime& put, const GetNow& now) - : m_QueueIdx(0), m_name(name), _putTime(put), _getNow(now) + CoDelQueue(std::string name, PutTime put, GetNow now) + : m_QueueIdx(0) + , m_name(std::move(name)) + , _putTime(std::move(put)) + , _getNow(std::move(now)) { } diff --git a/llarp/util/common.hpp b/llarp/util/common.hpp index 3ef490f75..4223ebf52 100644 --- a/llarp/util/common.hpp +++ b/llarp/util/common.hpp @@ -5,7 +5,7 @@ #else #define INLINE inline #endif -#include -#include -#include + +#include +#include #endif diff --git a/llarp/util/encode.hpp b/llarp/util/encode.hpp index dee452a89..472007f61 100644 --- a/llarp/util/encode.hpp +++ b/llarp/util/encode.hpp @@ -1,6 +1,6 @@ #ifndef LLARP_ENCODE_HPP #define LLARP_ENCODE_HPP -#include +#include #include #include #include diff --git a/llarp/util/endian.hpp b/llarp/util/endian.hpp index 087517348..60d0a4659 100644 --- a/llarp/util/endian.hpp +++ b/llarp/util/endian.hpp @@ -3,8 +3,8 @@ // adapted from libi2pd -#include -#include +#include +#include #include #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) diff --git a/llarp/util/file_logger.cpp b/llarp/util/file_logger.cpp index 4c335e854..0b0bcbf4e 100644 --- a/llarp/util/file_logger.cpp +++ b/llarp/util/file_logger.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace llarp { @@ -16,7 +17,7 @@ namespace llarp FileLogStream::FileLogStream(std::shared_ptr< thread::ThreadPool > disk, FILE *f, llarp_time_t flushInterval, bool closeFile) - : m_Disk(disk) + : m_Disk(std::move(disk)) , m_File(f) , m_FlushInterval(flushInterval) , m_Close(closeFile) diff --git a/llarp/util/file_logger.hpp b/llarp/util/file_logger.hpp index 6143e775b..463b987bf 100644 --- a/llarp/util/file_logger.hpp +++ b/llarp/util/file_logger.hpp @@ -15,7 +15,7 @@ namespace llarp FileLogStream(std::shared_ptr< thread::ThreadPool > disk, FILE* f, llarp_time_t flushInterval, bool closefile = true); - ~FileLogStream(); + ~FileLogStream() override; void PreLog(std::stringstream& out, LogLevel lvl, const char* fname, int lineno, diff --git a/llarp/util/json.cpp b/llarp/util/json.cpp index dadf9d47f..9c9358ca2 100644 --- a/llarp/util/json.cpp +++ b/llarp/util/json.cpp @@ -21,7 +21,7 @@ namespace llarp size_t m_Offset; bool - FeedData(const char* buf, size_t sz) + FeedData(const char* buf, size_t sz) override { if(m_Offset + sz > m_Buf.size() - 1) return false; @@ -32,7 +32,7 @@ namespace llarp } Result - Parse(nlohmann::json& obj) const + Parse(nlohmann::json& obj) const override { if(m_Offset < m_Buf.size() - 1) return eNeedData; diff --git a/llarp/util/json.hpp b/llarp/util/json.hpp index 0fdd4a3dc..a9b8b8571 100644 --- a/llarp/util/json.hpp +++ b/llarp/util/json.hpp @@ -16,9 +16,7 @@ namespace llarp struct IParser { - virtual ~IParser() - { - } + virtual ~IParser() = default; /// result from feeding data to parser enum Result diff --git a/llarp/util/mem.cpp b/llarp/util/mem.cpp index cb082353a..210c9a8c8 100644 --- a/llarp/util/mem.cpp +++ b/llarp/util/mem.cpp @@ -9,7 +9,7 @@ namespace llarp void Zero(void *ptr, size_t sz) { - uint8_t *p = (uint8_t *)ptr; + auto *p = (uint8_t *)ptr; while(sz--) { *p = 0; @@ -30,9 +30,9 @@ llarp_mem_slab(ABSL_ATTRIBUTE_UNUSED struct llarp_alloc *mem, bool llarp_eq(const void *a, const void *b, size_t sz) { - bool result = true; - const uint8_t *a_ptr = (const uint8_t *)a; - const uint8_t *b_ptr = (const uint8_t *)b; + bool result = true; + const auto *a_ptr = (const uint8_t *)a; + const auto *b_ptr = (const uint8_t *)b; while(sz--) { result &= a_ptr[sz] == b_ptr[sz]; diff --git a/llarp/util/mem.h b/llarp/util/mem.h index acc98855c..313837038 100644 --- a/llarp/util/mem.h +++ b/llarp/util/mem.h @@ -1,8 +1,8 @@ #ifndef LLARP_MEM_H_ #define LLARP_MEM_H_ -#include -#include -#include + +#include +#include /** constant time memcmp */ bool diff --git a/llarp/util/metrics_core.cpp b/llarp/util/metrics_core.cpp index 932d5215a..e58b63dbc 100644 --- a/llarp/util/metrics_core.cpp +++ b/llarp/util/metrics_core.cpp @@ -135,7 +135,7 @@ namespace llarp void Registry::setFormat(const Id &id, const Format &format) { - Description *description = const_cast< Description * >(id.description()); + auto *description = const_cast< Description * >(id.description()); absl::WriterMutexLock l(&m_mutex); @@ -197,7 +197,7 @@ namespace llarp const SampleGroup< int > &intGroup, const absl::Time &timeStamp) { - SampleCache::iterator it = cache.find(publisher); + auto it = cache.find(publisher); if(it == cache.end()) { Sample sample; @@ -227,7 +227,7 @@ namespace llarp manager.m_intRepo.collect(category)); // Get the time since last reset, and clear if needed. - Manager::ResetTimes::iterator it = manager.m_resetTimes.find(category); + auto it = manager.m_resetTimes.find(category); if(it == manager.m_resetTimes.end()) { if(clear) @@ -432,14 +432,13 @@ namespace llarp struct PublisherSchedulerData { util::Mutex m_mutex; - thread::Scheduler::Handle m_handle; - std::set< const Category * > m_categories; + thread::Scheduler::Handle m_handle GUARDED_BY(m_mutex); + std::set< const Category * > m_categories GUARDED_BY(m_mutex); - bool m_default; - std::set< const Category * > m_nonDefaultCategories; + bool m_default GUARDED_BY(m_mutex){false}; + std::set< const Category * > m_nonDefaultCategories GUARDED_BY(m_mutex); - PublisherSchedulerData() - : m_handle(thread::Scheduler::INVALID_HANDLE), m_default(false) + PublisherSchedulerData() : m_handle(thread::Scheduler::INVALID_HANDLE) { } }; @@ -506,11 +505,9 @@ namespace llarp m_categories.erase(it); auto data = repeatIt->second; - { - util::Lock l(&data->m_mutex); - assert(data->m_categories.find(category) != data->m_categories.end()); - data->m_categories.erase(category); - } + util::Lock l(&data->m_mutex); + assert(data->m_categories.find(category) != data->m_categories.end()); + data->m_categories.erase(category); if(!data->m_default) { @@ -526,7 +523,7 @@ namespace llarp assert(defaultIntervalIt != m_repeaters.end()); auto &defaultRepeater = defaultIntervalIt->second; - util::Lock l(&defaultRepeater->m_mutex); + util::Lock lock(&defaultRepeater->m_mutex); defaultRepeater->m_nonDefaultCategories.erase(category); } } @@ -547,6 +544,8 @@ namespace llarp assert(repeatIt != m_repeaters.end()); auto data = repeatIt->second; + util::Lock l(&data->m_mutex); + if(data->m_categories.empty()) { assert(data->m_handle != thread::Scheduler::INVALID_HANDLE); @@ -555,7 +554,6 @@ namespace llarp } else { - util::Lock l(&data->m_mutex); data->m_default = false; data->m_nonDefaultCategories.clear(); } @@ -593,9 +591,9 @@ namespace llarp if(repeatIt == m_repeaters.end()) { data = std::make_shared< PublisherSchedulerData >(); + util::Lock lock(&data->m_mutex); data->m_categories.insert(category); m_repeaters.emplace(interval, data); - util::Lock lock(&data->m_mutex); data->m_handle = m_scheduler.scheduleRepeat( interval, std::bind(&PublisherScheduler::publish, this, data)); } @@ -609,6 +607,7 @@ namespace llarp // If this isn't being added to the default schedule, then add to the set // of non-default categories in the default schedule. + util::Lock dataLock(&data->m_mutex); if(!data->m_default && m_defaultInterval != absl::Duration()) { auto defaultIntervalIt = m_repeaters.find(m_defaultInterval); @@ -656,7 +655,7 @@ namespace llarp util::Lock lock(&data->m_mutex); data->m_default = true; - Categories::iterator cIt = m_categories.begin(); + auto cIt = m_categories.begin(); for(; cIt != m_categories.end(); ++cIt) { if(cIt->second != interval) @@ -679,7 +678,7 @@ namespace llarp { util::Lock l(&m_mutex); - Categories::iterator it = m_categories.find(category); + auto it = m_categories.find(category); if(it == m_categories.end()) { // This category has no specific schedule. @@ -703,6 +702,7 @@ namespace llarp util::Lock l(&m_mutex); for(auto &repeat : m_repeaters) { + util::Lock dataLock(&repeat.second->m_mutex); m_scheduler.cancelRepeat(repeat.second->m_handle, true); } diff --git a/llarp/util/metrics_core.hpp b/llarp/util/metrics_core.hpp index fecfbee27..512fa18ac 100644 --- a/llarp/util/metrics_core.hpp +++ b/llarp/util/metrics_core.hpp @@ -8,6 +8,7 @@ #include #include +#include #include namespace llarp @@ -56,7 +57,7 @@ namespace llarp private: TaggedRecordsType m_records GUARDED_BY(m_mutex); - mutable util::Mutex m_mutex; + mutable util::Mutex m_mutex; // protects m_records Collector(const Collector &) = delete; Collector & @@ -279,8 +280,9 @@ namespace llarp std::set< std::string > m_stringmem GUARDED_BY(m_mutex); CategoryMap m_categories GUARDED_BY(m_mutex); MetricMap m_metrics GUARDED_BY(m_mutex); - bool m_defaultEnabled GUARDED_BY(m_mutex); - mutable util::Mutex m_mutex; + bool m_defaultEnabled GUARDED_BY(m_mutex){true}; + mutable util::Mutex m_mutex; // protects m_stringmem, m_categories, + // m_metrics, m_defaultEnabled Registry(const Registry &) = delete; Registry & @@ -291,9 +293,7 @@ namespace llarp EXCLUSIVE_LOCKS_REQUIRED(m_mutex); public: - Registry() : m_defaultEnabled(true) - { - } + Registry() = default; Id add(string_view category, string_view name) LOCKS_EXCLUDED(m_mutex); @@ -347,12 +347,10 @@ namespace llarp DoubleRecords doubleRecords; IntRecords intRecords; - Records() - { - } + Records() = default; - Records(const DoubleRecords &d, const IntRecords &i) - : doubleRecords(d), intRecords(i) + Records(DoubleRecords d, IntRecords i) + : doubleRecords(std::move(d)), intRecords(std::move(i)) { } }; @@ -374,16 +372,16 @@ namespace llarp Registry *m_registry; IdCollectors m_collectors; - CategoryCollectors m_categories; + CategoryCollectors m_categories GUARDED_BY(m_mutex); - mutable util::Mutex m_mutex; + mutable util::Mutex m_mutex; // protects m_categories CollectorRepo(const CollectorRepo &) = delete; CollectorRepo & operator=(const CollectorRepo &) = delete; Collectors< Type > & - getCollectors(const Id &id) + getCollectors(const Id &id) SHARED_LOCKS_REQUIRED(m_mutex) { auto it = m_collectors.find(id); @@ -406,7 +404,7 @@ namespace llarp template < TaggedRecords< Type > (Collectors< Type >::*func)() > std::vector< TaggedRecords< Type > > - collectOp(const Category *category) + collectOp(const Category *category) LOCKS_EXCLUDED(m_mutex) { absl::WriterMutexLock l(&m_mutex); @@ -452,7 +450,7 @@ namespace llarp } Collector< Type > * - defaultCollector(const Id &id) + defaultCollector(const Id &id) LOCKS_EXCLUDED(m_mutex) { { absl::ReaderMutexLock l(&m_mutex); @@ -476,14 +474,14 @@ namespace llarp } std::shared_ptr< Collector< Type > > - addCollector(const Id &id) + addCollector(const Id &id) LOCKS_EXCLUDED(m_mutex) { absl::WriterMutexLock l(&m_mutex); return getCollectors(id).add(); } std::vector< std::shared_ptr< Collector< Type > > > - allCollectors(const Id &id) + allCollectors(const Id &id) LOCKS_EXCLUDED(m_mutex) { absl::ReaderMutexLock l(&m_mutex); @@ -916,7 +914,7 @@ namespace llarp { manager = DefaultManager::manager(manager); return manager ? (manager->*repoFunc)().defaultCollector(category, name) - : 0; + : nullptr; } static Collector * @@ -1134,7 +1132,8 @@ namespace llarp Repeaters m_repeaters GUARDED_BY(m_mutex); absl::Duration m_defaultInterval GUARDED_BY(m_mutex); - mutable util::Mutex m_mutex; + mutable util::Mutex + m_mutex; // protected m_categories, m_repeaters, m_defaultInterval void publish(const std::shared_ptr< PublisherSchedulerData > &data) const; diff --git a/llarp/util/metrics_types.hpp b/llarp/util/metrics_types.hpp index 78836e18d..6a9d9dfe6 100644 --- a/llarp/util/metrics_types.hpp +++ b/llarp/util/metrics_types.hpp @@ -51,12 +51,12 @@ namespace llarp struct FormatSpec { - float m_scale; + float m_scale{1.0}; string_view m_format; static constexpr char DEFAULT_FORMAT[] = "%f"; - constexpr FormatSpec() : m_scale(1.0), m_format(DEFAULT_FORMAT) + constexpr FormatSpec() : m_format(DEFAULT_FORMAT) { } @@ -200,56 +200,56 @@ namespace llarp } void - category(const Category *c) + category(const Category *c) LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); m_category = c; } const Category * - category() const + category() const LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); return m_category; } void - name(string_view n) + name(string_view n) LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); m_name = n; } string_view - name() const + name() const LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); return m_name; } void - type(Publication::Type t) + type(Publication::Type t) LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); m_type = t; } Publication::Type - type() const + type() const LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); return m_type; } void - format(const std::shared_ptr< Format > &f) + format(const std::shared_ptr< Format > &f) LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); m_format = f; } std::shared_ptr< Format > - format() const + format() const LOCKS_EXCLUDED(m_mutex) { util::Lock l(&m_mutex); return m_format; @@ -272,12 +272,10 @@ namespace llarp /// order to make things like static initialisation cleaner. class Id { - const Description *m_description; + const Description *m_description{nullptr}; public: - constexpr Id() : m_description(nullptr) - { - } + constexpr Id() = default; constexpr Id(const Description *description) : m_description(description) { @@ -395,7 +393,7 @@ namespace llarp template < typename Type > class Record { - size_t m_count; + size_t m_count{0}; Type m_total; Type m_min; Type m_max; @@ -406,8 +404,7 @@ namespace llarp static constexpr Type DEFAULT_MAX() { return RecordMax::max(); }; // clang-format on - Record() - : m_count(0), m_total(0.0), m_min(DEFAULT_MIN()), m_max(DEFAULT_MAX()) + Record() : m_total(0.0), m_min(DEFAULT_MIN()), m_max(DEFAULT_MAX()) { } @@ -603,12 +600,12 @@ namespace llarp absl::Time m_sampleTime; std::vector< absl::variant< SampleGroup< double >, SampleGroup< int > > > m_samples; - size_t m_recordCount; + size_t m_recordCount{0}; public: using const_iterator = typename decltype(m_samples)::const_iterator; - Sample() : m_sampleTime(), m_recordCount(0) + Sample() : m_sampleTime() { } diff --git a/llarp/util/ostream_logger.hpp b/llarp/util/ostream_logger.hpp index cbcb9d9ac..f423d8cc4 100644 --- a/llarp/util/ostream_logger.hpp +++ b/llarp/util/ostream_logger.hpp @@ -10,18 +10,16 @@ namespace llarp { OStreamLogStream(std::ostream& out); - ~OStreamLogStream() - { - } + ~OStreamLogStream() override = default; - virtual void + void PreLog(std::stringstream& s, LogLevel lvl, const char* fname, int lineno, const std::string& nodename) const override; void Print(LogLevel lvl, const char* tag, const std::string& msg) override; - virtual void + void PostLog(std::stringstream& ss) const override; void Tick(llarp_time_t) override diff --git a/llarp/util/queue_manager.cpp b/llarp/util/queue_manager.cpp index e799ba668..bdec4b55e 100644 --- a/llarp/util/queue_manager.cpp +++ b/llarp/util/queue_manager.cpp @@ -226,7 +226,7 @@ namespace llarp uint32_t elemGen = decodeGenerationFromElementState(compare); - int32_t difference = static_cast< int32_t >(currGen - elemGen); + auto difference = static_cast< int32_t >(currGen - elemGen); if(difference == 1 || (difference == -static_cast< int32_t >(m_maxGeneration))) @@ -326,7 +326,7 @@ namespace llarp uint32_t elemGen = decodeGenerationFromElementState(compare); ElementState state = decodeStateFromElementState(compare); - int32_t difference = static_cast< int32_t >(currGen - elemGen); + auto difference = static_cast< int32_t >(currGen - elemGen); if(difference == 1 || (difference == -static_cast< int32_t >(m_maxGeneration))) @@ -455,9 +455,9 @@ namespace llarp assert(0 < circularDifference(endCombinedIndex, loadedCombinedIndex, m_maxCombinedIndex + 1)); - uint32_t currIdx = + auto currIdx = static_cast< uint32_t >(loadedCombinedIndex % m_capacity); - uint32_t currGen = + auto currGen = static_cast< uint32_t >(loadedCombinedIndex / m_capacity); // Try to swap this cell from Full to Reading. diff --git a/llarp/util/scheduler.cpp b/llarp/util/scheduler.cpp index 3c45c1878..0b56f4efc 100644 --- a/llarp/util/scheduler.cpp +++ b/llarp/util/scheduler.cpp @@ -1,4 +1,5 @@ #include +#include namespace llarp { @@ -152,9 +153,9 @@ namespace llarp } } - Scheduler::Scheduler(const EventDispatcher& dispatcher, const Clock& clock) - : m_clock(clock) - , m_dispatcher(dispatcher) + Scheduler::Scheduler(EventDispatcher dispatcher, Clock clock) + : m_clock(std::move(clock)) + , m_dispatcher(std::move(dispatcher)) , m_running(false) , m_iterationCount(0) , m_eventIt() diff --git a/llarp/util/scheduler.hpp b/llarp/util/scheduler.hpp index 7bcb9854f..970ecfda1 100644 --- a/llarp/util/scheduler.hpp +++ b/llarp/util/scheduler.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace llarp @@ -40,8 +41,8 @@ namespace llarp std::atomic_bool m_isCancelled; Handle m_handle; - RepeatData(const Callback& callback, absl::Duration period) - : m_callback(callback) + RepeatData(Callback callback, absl::Duration period) + : m_callback(std::move(callback)) , m_period(period) , m_isCancelled(false) , m_handle(0) @@ -133,7 +134,7 @@ namespace llarp { } - Scheduler(const EventDispatcher& dispatcher, const Clock& clock); + Scheduler(EventDispatcher dispatcher, Clock clock); ~Scheduler(); diff --git a/llarp/util/status.cpp b/llarp/util/status.cpp index 14d533d97..15c76b583 100644 --- a/llarp/util/status.cpp +++ b/llarp/util/status.cpp @@ -1,64 +1 @@ #include - -#include - -namespace llarp -{ - namespace util - { - struct StatusVisitor - { - std::string name; - std::reference_wrapper< nlohmann::json > data; - - StatusVisitor(StatusObject::String_t n, nlohmann::json& d) - : name(n), data(d) - { - } - void - operator()(uint64_t val) - { - data.get()[name] = val; - } - void - operator()(const std::string& val) - { - data.get()[name] = val; - } - void - operator()(bool val) - { - data.get()[name] = val; - } - void - operator()(const StatusObject& obj) - { - data.get()[name] = obj.Impl; - } - void - operator()(const std::vector< std::string >& val) - { - data.get()[name] = val; - } - void - operator()(const std::vector< StatusObject >& val) - { - auto arr = nlohmann::json::array(); - std::transform(val.begin(), val.end(), std::back_inserter(arr), - [](const auto& x) { return x.Impl; }); - data.get()[name] = arr; - } - }; - void - StatusObject::Put(const value_type& val) - { - Put(std::get< 0 >(val), std::get< 1 >(val)); - } - - void - StatusObject::Put(String_t name, const Variant& data) - { - absl::visit(StatusVisitor{name, Impl}, data); - } - } // namespace util -} // namespace llarp diff --git a/llarp/util/status.hpp b/llarp/util/status.hpp index f9fda5d4f..6e70e9c2c 100644 --- a/llarp/util/status.hpp +++ b/llarp/util/status.hpp @@ -14,50 +14,7 @@ namespace llarp { namespace util { - struct StatusVisitor; - struct StatusObject - { - using String_t = string_view; - using Variant = absl::variant< uint64_t, std::string, bool, StatusObject, - std::vector< std::string >, - std::vector< StatusObject > >; - using value_type = std::pair< String_t, Variant >; - - StatusObject(std::initializer_list< value_type > vals) - { - std::for_each(vals.begin(), vals.end(), - [&](const value_type& item) { Put(item); }); - } - - void - Put(String_t name, const Variant& value); - - void - Put(const value_type& value); - - template < typename Container, typename Getter > - void - PutContainer(String_t keyname, const Container& container, Getter get) - { - std::vector< util::StatusObject > objs; - std::transform(container.begin(), container.end(), - std::back_inserter(objs), - [get](const auto& item) -> util::StatusObject { - return get(item)->ExtractStatus(); - }); - Put(keyname, objs); - } - - nlohmann::json - get() const - { - return Impl; - } - - private: - friend struct StatusVisitor; - nlohmann::json Impl; - }; + using StatusObject = nlohmann::json; } // namespace util } // namespace llarp diff --git a/llarp/util/stopwatch.hpp b/llarp/util/stopwatch.hpp index cfc992793..25a772c22 100644 --- a/llarp/util/stopwatch.hpp +++ b/llarp/util/stopwatch.hpp @@ -14,9 +14,7 @@ namespace llarp absl::optional< absl::Time > m_stop; public: - Stopwatch() - { - } + Stopwatch() = default; void start() diff --git a/llarp/util/threading.hpp b/llarp/util/threading.hpp index fb3608171..05113a2b3 100644 --- a/llarp/util/threading.hpp +++ b/llarp/util/threading.hpp @@ -32,6 +32,7 @@ namespace llarp ~NullLock() UNLOCK_FUNCTION() { + (void)this; // trick clang-tidy } }; diff --git a/llarp/util/threadpool.h b/llarp/util/threadpool.h index 3a513d44e..bd1103ea4 100644 --- a/llarp/util/threadpool.h +++ b/llarp/util/threadpool.h @@ -25,7 +25,7 @@ struct llarp_threadpool } llarp_threadpool() - : jobs(new llarp::thread::Queue< std::function< void(void) > >(128)) + : jobs(new llarp::thread::Queue< std::function< void() > >(128)) , callingPID(llarp::util::GetPid()) { jobs->enable(); @@ -59,23 +59,21 @@ llarp_init_same_process_threadpool(); void llarp_free_threadpool(struct llarp_threadpool **tp); -typedef void (*llarp_thread_work_func)(void *); +using llarp_thread_work_func = void (*)(void *); /** job to be done in worker thread */ struct llarp_thread_job { /** user data to pass to work function */ - void *user; + void *user{nullptr}; /** called in threadpool worker thread */ - llarp_thread_work_func work; + llarp_thread_work_func work{nullptr}; #ifdef __cplusplus llarp_thread_job(void *u, llarp_thread_work_func w) : user(u), work(w) { } - llarp_thread_job() : user(nullptr), work(nullptr) - { - } + llarp_thread_job() = default; #endif }; diff --git a/llarp/util/timer.cpp b/llarp/util/timer.cpp index 08d8ae522..c9278b5af 100644 --- a/llarp/util/timer.cpp +++ b/llarp/util/timer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace llarp { @@ -28,15 +29,13 @@ namespace llarp , called_at(0) , started(now) , timeout(ms) - , func(_func) + , func(std::move(_func)) , done(false) , canceled(false) { } - ~timer() - { - } + ~timer() = default; void exec(); @@ -75,9 +74,7 @@ struct llarp_timer_context uint32_t currentId = 0; bool _run = true; - ~llarp_timer_context() - { - } + ~llarp_timer_context() = default; bool run() diff --git a/llarp/util/timerqueue.hpp b/llarp/util/timerqueue.hpp index eb2e0fd9c..5dd283748 100644 --- a/llarp/util/timerqueue.hpp +++ b/llarp/util/timerqueue.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace llarp { @@ -55,7 +56,7 @@ namespace llarp private: struct Node { - int m_index; + int m_index{0}; absl::Time m_time; Key m_key; Node* m_prev; @@ -63,8 +64,7 @@ namespace llarp object::Buffer< Value > m_value; Node() - : m_index(0) - , m_time() + : m_time() , m_key(nullptr) , m_prev(nullptr) , m_next(nullptr) @@ -73,8 +73,7 @@ namespace llarp } explicit Node(const absl::Time& time) - : m_index(0) - , m_time(time) + : m_time(time) , m_key(nullptr) , m_prev(nullptr) , m_next(nullptr) @@ -311,9 +310,12 @@ namespace llarp { } - TimerQueueItem(absl::Time time, const Value& value, Handle handle, + TimerQueueItem(absl::Time time, Value value, Handle handle, const Key& key) - : m_time(time), m_value(value), m_handle(handle), m_key(key) + : m_time(time) + , m_value(std::move(value)) + , m_handle(handle) + , m_key(key) { } diff --git a/llarp/util/win32_logger.cpp b/llarp/util/win32_logger.cpp index 847864398..2f9fd4afe 100644 --- a/llarp/util/win32_logger.cpp +++ b/llarp/util/win32_logger.cpp @@ -7,7 +7,8 @@ static short old_attrs; namespace llarp { - Win32LogStream::Win32LogStream(std::ostream& out) : OStreamLogStream(out) + Win32LogStream::Win32LogStream(std::ostream& out) + : OStreamLogStream(out), m_Out(out) { // Attempt to use ANSI escapes directly // if the modern console is active. @@ -26,6 +27,45 @@ namespace llarp void Win32LogStream::PreLog(std::stringstream& ss, LogLevel lvl, const char* fname, int lineno, const std::string& nodename) const + { + if(!isConsoleModern) + { + switch(lvl) + { + case eLogNone: + break; + case eLogDebug: + ss << "[DBG] "; + break; + case eLogInfo: + ss << "[NFO] "; + break; + case eLogWarn: + ss << "[WRN] "; + break; + case eLogError: + ss << "[ERR] "; + break; + } + ss << "[" << nodename << "]" + << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname + << ":" << lineno << "\t"; + } + else + OStreamLogStream::PreLog(ss, lvl, fname, lineno, nodename); + } + + void + Win32LogStream::PostLog(std::stringstream& ss) const + { + if(!isConsoleModern) + ss << std::endl; + else + OStreamLogStream::PostLog(ss); + } + + void + Win32LogStream::Print(LogLevel lvl, const char*, const std::string& msg) { if(!isConsoleModern) { @@ -39,46 +79,33 @@ namespace llarp SetConsoleTextAttribute(fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); // low white on black - ss << "[DBG] "; break; case eLogInfo: SetConsoleTextAttribute( fd1, FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); // high white on black - ss << "[NFO] "; break; case eLogWarn: SetConsoleTextAttribute(fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); // bright yellow - ss << "[WRN] "; break; case eLogError: SetConsoleTextAttribute( fd1, FOREGROUND_RED | FOREGROUND_INTENSITY); // bright red - ss << "[ERR] "; break; } - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname - << ":" << lineno << "\t"; } - else - OStreamLogStream::PreLog(ss, lvl, fname, lineno, nodename); - } - void - Win32LogStream::PostLog(std::stringstream& ss) const - { + m_Out << msg << std::flush; + if(!isConsoleModern) { SetConsoleTextAttribute( fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - ss << std::endl; } - else - OStreamLogStream::PostLog(ss); } + } // namespace llarp #endif diff --git a/llarp/util/win32_logger.hpp b/llarp/util/win32_logger.hpp index 75add272e..3a9cb6342 100644 --- a/llarp/util/win32_logger.hpp +++ b/llarp/util/win32_logger.hpp @@ -20,8 +20,15 @@ namespace llarp void Tick(llarp_time_t) override{}; + void + Print(LogLevel lvl, const char*, const std::string& msg) override; + + private: + std::ostream& m_Out; + bool isConsoleModern = true; // qol fix so oldfag clients don't see ugly escapes + HANDLE fd1 = GetStdHandle(STD_OUTPUT_HANDLE); }; } // namespace llarp diff --git a/llarp/utp/inbound_message.hpp b/llarp/utp/inbound_message.hpp index e8d492425..0bcf69757 100644 --- a/llarp/utp/inbound_message.hpp +++ b/llarp/utp/inbound_message.hpp @@ -45,7 +45,7 @@ namespace llarp struct InboundMessage { /// timestamp of last activity - llarp_time_t lastActive; + llarp_time_t lastActive{0}; /// the underlying message buffer MessageBuffer _msg; @@ -63,7 +63,7 @@ namespace llarp bool AppendData(const byte_t* ptr, uint16_t sz); - InboundMessage() : lastActive(0), _msg(), buffer(_msg) + InboundMessage() : _msg(), buffer(_msg) { } diff --git a/llarp/utp/linklayer.cpp b/llarp/utp/linklayer.cpp index 3078e9884..b0b589fc5 100644 --- a/llarp/utp/linklayer.cpp +++ b/llarp/utp/linklayer.cpp @@ -18,7 +18,7 @@ #endif #include -#include +#include namespace llarp { @@ -27,9 +27,9 @@ namespace llarp uint64 LinkLayer::OnConnect(utp_callback_arguments* arg) { - LinkLayer* l = + auto* l = static_cast< LinkLayer* >(utp_context_get_userdata(arg->context)); - Session* session = static_cast< Session* >(utp_get_userdata(arg->socket)); + auto* session = static_cast< Session* >(utp_get_userdata(arg->socket)); if(session && l) session->OutboundLinkEstablished(l); return 0; @@ -38,7 +38,7 @@ namespace llarp uint64 LinkLayer::SendTo(utp_callback_arguments* arg) { - LinkLayer* l = + auto* l = static_cast< LinkLayer* >(utp_context_get_userdata(arg->context)); if(l == nullptr) return 0; @@ -49,9 +49,9 @@ namespace llarp uint64 LinkLayer::OnError(utp_callback_arguments* arg) { - Session* session = static_cast< Session* >(utp_get_userdata(arg->socket)); + auto* session = static_cast< Session* >(utp_get_userdata(arg->socket)); - LinkLayer* link = + auto* link = static_cast< LinkLayer* >(utp_context_get_userdata(arg->context)); if(session && link) @@ -270,7 +270,7 @@ namespace llarp uint64 LinkLayer::OnRead(utp_callback_arguments* arg) { - Session* self = static_cast< Session* >(utp_get_userdata(arg->socket)); + auto* self = static_cast< Session* >(utp_get_userdata(arg->socket)); if(self) { @@ -297,12 +297,12 @@ namespace llarp uint64 LinkLayer::OnStateChange(utp_callback_arguments* arg) { - Session* session = static_cast< Session* >(utp_get_userdata(arg->socket)); + auto* session = static_cast< Session* >(utp_get_userdata(arg->socket)); if(session) { if(arg->state == UTP_STATE_WRITABLE) { - session->PumpWrite(); + session->Pump(); } else if(arg->state == UTP_STATE_EOF) { @@ -316,7 +316,7 @@ namespace llarp uint64 LinkLayer::OnAccept(utp_callback_arguments* arg) { - LinkLayer* self = + auto* self = static_cast< LinkLayer* >(utp_context_get_userdata(arg->context)); Addr remote(*arg->address); diff --git a/llarp/utp/linklayer.hpp b/llarp/utp/linklayer.hpp index 44c1d0f29..cb7f6929f 100644 --- a/llarp/utp/linklayer.hpp +++ b/llarp/utp/linklayer.hpp @@ -53,7 +53,7 @@ namespace llarp SessionClosedHandler closed, bool acceptInbound); /// destruct - ~LinkLayer(); + ~LinkLayer() override; /// get AI rank uint16_t diff --git a/llarp/utp/session.cpp b/llarp/utp/session.cpp index 99444b352..1be1c16ff 100644 --- a/llarp/utp/session.cpp +++ b/llarp/utp/session.cpp @@ -20,7 +20,7 @@ namespace llarp /// pump tx queue void - Session::PumpWrite() + Session::PumpWrite(size_t numSend) { if(!sock) return; @@ -31,10 +31,11 @@ namespace llarp { for(const auto& vec : msg.vecs) { - if(vec.iov_len) + if(vec.iov_len > 0) { expect += vec.iov_len; send.emplace_back(vec); + numSend--; } } } @@ -147,10 +148,20 @@ namespace llarp Session::Tick(llarp_time_t now) { PruneInboundMessages(now); - m_TXRate = 0; - m_RXRate = 0; - metrics::integerTick("utp.session.sendq", "size", sendq.size(), "id", - RouterID(remoteRC.pubkey).ToString()); + // ensure that this section is called every 1s or so + if(now > m_LastTick && now - m_LastTick >= 1000) + { + m_TXRate = 0; + m_RXRate = 0; + metrics::integerTick("utp.session.sendq", "size", sendq.size(), "id", + RouterID(remoteRC.pubkey).ToString()); + m_LastTick = now; + } + else + { + // try sending 1 segment + PumpWrite(1); + } } /// low level read @@ -209,13 +220,29 @@ namespace llarp return now - lastActive > 5000; if(state == eSessionReady) { - // don't time out the connection if backlogged in downstream direction - // for clients dangling off the side of the network - const auto timestamp = - remoteRC.IsPublicRouter() ? lastSend : lastActive; - if(now <= timestamp) - return false; - return now - timestamp > 30000; + const bool remoteIsSNode = remoteRC.IsPublicRouter(); + const bool weAreSnode = parent->GetOurRC().IsPublicRouter(); + const bool recvTimeout = + (now > lastActive) && now - lastActive > sessionTimeout; + const bool sendTimeout = + (now > lastSend) && now - lastSend > sessionTimeout; + if(remoteIsSNode && weAreSnode) + { + /// for s2s connections only check write direction + return sendTimeout; + } + else if(weAreSnode) + { + // for edge connection as service node check either direction for + // timeout + return recvTimeout || sendTimeout; + } + else + { + /// for edge connections as client we check if both directions have + /// been silent for 60s + return recvTimeout && sendTimeout; + } } if(state == eLinkEstablished) return now - lastActive @@ -268,8 +295,10 @@ namespace llarp void Session::Pump() { - // pump write queue - PumpWrite(); + if(sendq.size() > (MaxSendQueueSize / 4)) + PumpWrite(sendq.size() / 2); + else + PumpWrite(sendq.size()); // prune inbound messages PruneInboundMessages(parent->Now()); } @@ -282,7 +311,7 @@ namespace llarp if(SendQueueBacklog() >= MaxSendQueueSize) { // pump write queue if we seem to be full - PumpWrite(); + PumpWrite(MaxSendQueueSize / 2); } if(SendQueueBacklog() >= MaxSendQueueSize) { @@ -308,7 +337,7 @@ namespace llarp sz -= s; } if(state != eSessionReady) - PumpWrite(); + PumpWrite(sendq.size()); return true; } diff --git a/llarp/utp/session.hpp b/llarp/utp/session.hpp index b605850f3..a275a64db 100644 --- a/llarp/utp/session.hpp +++ b/llarp/utp/session.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -14,7 +15,8 @@ namespace llarp { struct LinkLayer; - struct Session : public ILinkSession + struct Session : public ILinkSession, + public std::enable_shared_from_this< Session > { /// remote router's rc RouterContact remoteRC; @@ -42,7 +44,7 @@ namespace llarp struct OutboundMessage { OutboundMessage(uint32_t id, CompletionHandler func) - : msgid{id}, completed{func} + : msgid{id}, completed{std::move(func)} { } @@ -101,6 +103,8 @@ namespace llarp uint64_t m_RXRate = 0; uint64_t m_TXRate = 0; + llarp_time_t m_LastTick = 0; + /// mark session as alive void Alive(); @@ -108,7 +112,7 @@ namespace llarp util::StatusObject ExtractStatus() const override; - virtual ~Session() = 0; + ~Session() override = 0; /// base explicit Session(LinkLayer* p); @@ -147,11 +151,17 @@ namespace llarp /// pump tx queue void - PumpWrite(); + PumpWrite(size_t numMessages); void Pump() override; + std::shared_ptr< ILinkSession > + BorrowSelf() override + { + return shared_from_this(); + } + bool SendKeepAlive() override; diff --git a/llarp/utp/utp.cpp b/llarp/utp/utp.cpp index 01d47502d..911fdc309 100644 --- a/llarp/utp/utp.cpp +++ b/llarp/utp/utp.cpp @@ -10,9 +10,10 @@ namespace llarp { LinkLayer_ptr NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed) + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) { return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, reneg, timeout, closed, false); @@ -20,9 +21,10 @@ namespace llarp LinkLayer_ptr NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed) + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed) { return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est, reneg, timeout, closed, true); diff --git a/llarp/utp/utp.hpp b/llarp/utp/utp.hpp index 10857b796..d368065e2 100644 --- a/llarp/utp/utp.hpp +++ b/llarp/utp/utp.hpp @@ -6,20 +6,20 @@ namespace llarp { - struct AbstractRouter; - namespace utp { LinkLayer_ptr NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed); + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); LinkLayer_ptr NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc, - LinkMessageHandler h, SessionEstablishedHandler est, - SessionRenegotiateHandler reneg, SignBufferFunc sign, - TimeoutHandler timeout, SessionClosedHandler closed); + LinkMessageHandler h, SignBufferFunc sign, + SessionEstablishedHandler est, + SessionRenegotiateHandler reneg, TimeoutHandler timeout, + SessionClosedHandler closed); /// shim const auto NewServer = NewInboundLink; } // namespace utp diff --git a/llarp/win32/win32_inet.c b/llarp/win32/win32_inet.c index 6dbe35938..be88293d9 100644 --- a/llarp/win32/win32_inet.c +++ b/llarp/win32/win32_inet.c @@ -10,6 +10,7 @@ // these need to be in a specific order #include +#include #include #include #include diff --git a/motto.txt b/motto.txt index f0d987eaf..8b197bac5 100644 --- a/motto.txt +++ b/motto.txt @@ -1 +1 @@ -just a lot of wind \ No newline at end of file +breaking winds diff --git a/test/config/test_llarp_config_config.cpp b/test/config/test_llarp_config_config.cpp index 55eadeb3c..a31a7ed79 100644 --- a/test/config/test_llarp_config_config.cpp +++ b/test/config/test_llarp_config_config.cpp @@ -102,10 +102,10 @@ metric-tank-host=52.80.56.123:2003 ASSERT_FALSE(config.metrics.disableMetrics); { - using kv = IwpConfig::Servers::value_type; + using kv = LinksConfig::Links::value_type; - ASSERT_THAT(config.iwp_links.servers(), - UnorderedElementsAre(kv("eth0", AF_INET, 5501))); + ASSERT_THAT(config.links.inboundLinks(), + UnorderedElementsAre(kv("eth0", AF_INET, 5501, {}))); } ASSERT_THAT(config.bootstrap.routers, diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index 3c83b5050..958e85da8 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -1,11 +1,13 @@ -#include +#include #include #include #include +#include #include #include #include + #include #include @@ -13,7 +15,7 @@ using namespace ::llarp; using namespace ::testing; -struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > +struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium > { static constexpr uint16_t AlicePort = 5000; static constexpr uint16_t BobPort = 6000; @@ -62,7 +64,7 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > localLoopBack() { #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ - || (__APPLE__ && __MACH__) + || (__APPLE__ && __MACH__) || (__sun) return "lo0"; #else return "lo"; @@ -118,10 +120,10 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > void SetUp() { - oldRCLifetime = RouterContact::Lifetime; - RouterContact::IgnoreBogons = true; - RouterContact::Lifetime = 500; - netLoop = llarp_make_ev_loop(); + oldRCLifetime = RouterContact::Lifetime; + RouterContact::BlockBogons = false; + RouterContact::Lifetime = 500; + netLoop = llarp_make_ev_loop(); m_logic.reset(new Logic()); } @@ -132,8 +134,8 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > Bob.TearDown(); m_logic.reset(); netLoop.reset(); - RouterContact::IgnoreBogons = false; - RouterContact::Lifetime = oldRCLifetime; + RouterContact::BlockBogons = true; + RouterContact::Lifetime = oldRCLifetime; } static void @@ -167,12 +169,12 @@ struct LinkLayerTest : public test::LlarpTest< NoOpCrypto > } }; -TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) +TEST_F(LinkLayerTest, TestIWP) { #ifdef WIN32 - GTEST_SKIP(); + GTEST_SKIP(); #else - Alice.link = utp::NewServer( + Alice.link = iwp::NewInboundLink( Alice.encryptionKey, [&]() -> const RouterContact& { return Alice.GetRC(); }, [&](ILinkSession* s, const llarp_buffer_t& buf) -> bool { @@ -193,14 +195,108 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) return true; } }, + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Alice.signingKey, buf); + }, [&](ILinkSession* s) -> bool { const auto rc = s->GetRemoteRC(); return rc.pubkey == Bob.GetRC().pubkey; }, [&](RouterContact, RouterContact) -> bool { return true; }, + + [&](ILinkSession* session) { + ASSERT_FALSE(session->IsEstablished()); + Stop(); + }, + [&](RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); }); + + auto sendDiscardMessage = [](ILinkSession* s) -> bool { + // send discard message in reply to complete unit test + std::array< byte_t, 32 > tmp; + llarp_buffer_t otherBuf(tmp); + DiscardMessage discard; + if(!discard.BEncode(&otherBuf)) + return false; + otherBuf.sz = otherBuf.cur - otherBuf.base; + otherBuf.cur = otherBuf.base; + return s->SendMessageBuffer(otherBuf, nullptr); + }; + + Bob.link = iwp::NewInboundLink( + Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); }, + [&](ILinkSession* s, const llarp_buffer_t& buf) -> bool { + LinkIntroMessage msg; + ManagedBuffer copy{buf}; + if(!msg.BDecode(©.underlying)) + return false; + if(!s->GotLIM(&msg)) + return false; + Bob.gotLIM = true; + return sendDiscardMessage(s); + }, + + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Bob.signingKey, buf); + }, + [&](ILinkSession* s) -> bool { + if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey) + return false; + LogInfo("bob established with alice"); + return Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(), + sendDiscardMessage); + }, + [&](RouterContact newrc, RouterContact oldrc) -> bool { + success = newrc.pubkey == oldrc.pubkey; + return true; + }, + [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); }, + [&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); }); + + ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort)); + ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort)); + + ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC())); + + RunMainloop(); + ASSERT_TRUE(Bob.gotLIM); +#endif +}; + +TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) +{ +#ifdef WIN32 + GTEST_SKIP(); +#else + Alice.link = utp::NewServer( + Alice.encryptionKey, + [&]() -> const RouterContact& { return Alice.GetRC(); }, + [&](ILinkSession* s, const llarp_buffer_t& buf) -> bool { + if(Alice.gotLIM) + { + Alice.Regen(); + return s->RenegotiateSession(); + } + else + { + LinkIntroMessage msg; + ManagedBuffer copy{buf}; + if(!msg.BDecode(©.underlying)) + return false; + if(!s->GotLIM(&msg)) + return false; + Alice.gotLIM = true; + return true; + } + }, [&](Signature& sig, const llarp_buffer_t& buf) -> bool { return m_crypto.sign(sig, Alice.signingKey, buf); }, + [&](ILinkSession* s) -> bool { + const auto rc = s->GetRemoteRC(); + return rc.pubkey == Bob.GetRC().pubkey; + }, + [&](RouterContact, RouterContact) -> bool { return true; }, + [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); Stop(); @@ -231,6 +327,10 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) Bob.gotLIM = true; return sendDiscardMessage(s); }, + + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Bob.signingKey, buf); + }, [&](ILinkSession* s) -> bool { if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey) return false; @@ -242,9 +342,6 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob) success = newrc.pubkey == oldrc.pubkey; return true; }, - [&](Signature& sig, const llarp_buffer_t& buf) -> bool { - return m_crypto.sign(sig, Bob.signingKey, buf); - }, [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); }, [&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); }); @@ -280,6 +377,9 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return false; } return AliceGotMessage(buf); + }, + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Alice.signingKey, buf); }, [&](ILinkSession* s) -> bool { if(s->GetRemoteRC().pubkey != Bob.GetRC().pubkey) @@ -288,9 +388,7 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return true; }, [&](RouterContact, RouterContact) -> bool { return true; }, - [&](Signature& sig, const llarp_buffer_t& buf) -> bool { - return m_crypto.sign(sig, Alice.signingKey, buf); - }, + [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); Stop(); @@ -312,6 +410,9 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return false; } return true; + }, + [&](Signature& sig, const llarp_buffer_t& buf) -> bool { + return m_crypto.sign(sig, Bob.signingKey, buf); }, [&](ILinkSession* s) -> bool { if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey) @@ -332,9 +433,6 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob) return true; }, [&](RouterContact, RouterContact) -> bool { return true; }, - [&](Signature& sig, const llarp_buffer_t& buf) -> bool { - return m_crypto.sign(sig, Bob.signingKey, buf); - }, [&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); }, [&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); }); diff --git a/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc b/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc index 85b52bc8f..29162622f 100644 --- a/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc +++ b/vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc @@ -184,7 +184,11 @@ int GetCPU() { // global constructors. static class VDSOInitHelper { public: - VDSOInitHelper() { VDSOSupport::Init(); } + VDSOInitHelper() { +#ifndef LOKINET_SHADOW + VDSOSupport::Init(); +#endif + } } vdso_init_helper; } // namespace debugging_internal diff --git a/vendor/cxxopts/CHANGELOG.md b/vendor/cxxopts/CHANGELOG.md index 7bcbf72ab..bd0eed198 100644 --- a/vendor/cxxopts/CHANGELOG.md +++ b/vendor/cxxopts/CHANGELOG.md @@ -3,16 +3,29 @@ This is the changelog for `cxxopts`, a C++11 library for parsing command line options. The project adheres to semantic versioning. +## Next version + +### Changed + +* Only search for a C++ compiler in CMakeLists.txt. +* Allow for exceptions to be disabled. +* Fix duplicate default options when there is a short and long option. +* Add `CXXOPTS_NO_EXCEPTIONS` to disable exceptions. + ## 2.2 ### Changed * Allow integers to have leading zeroes. * Build the tests by default. +* Don't check for container when showing positional help. ### Added * Iterator inputs to `parse_positional`. +* Throw an exception if the option in `parse_positional` doesn't exist. +* Parse a delimited list in a single argument for vector options. +* Add an option to disable implicit value on booleans. ### Bug Fixes @@ -22,6 +35,7 @@ options. The project adheres to semantic versioning. * Throw on invalid option syntax when beginning with a `-`. * Throw in `as` when option wasn't present. * Fix catching exceptions by reference. +* Fix out of bounds errors parsing integers. ## 2.1.1 diff --git a/vendor/cxxopts/CMakeLists.txt b/vendor/cxxopts/CMakeLists.txt index e866cb128..98cc56ccc 100644 --- a/vendor/cxxopts/CMakeLists.txt +++ b/vendor/cxxopts/CMakeLists.txt @@ -1,15 +1,15 @@ # Copyright (c) 2014 Jarryd Beck -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -30,12 +30,13 @@ endforeach() set(VERSION ${CXXOPTS__VERSION_MAJOR}.${CXXOPTS__VERSION_MINOR}.${CXXOPTS__VERSION_PATCH}) message(STATUS "cxxopts version ${VERSION}") -project(cxxopts VERSION "${VERSION}") +project(cxxopts VERSION "${VERSION}" LANGUAGES CXX) enable_testing() option(CXXOPTS_BUILD_EXAMPLES "Set to ON to build examples" ON) option(CXXOPTS_BUILD_TESTS "Set to ON to build tests" ON) +option(CXXOPTS_ENABLE_INSTALL "Generate the install target" OFF) # request c++11 without gnu extension for the whole project and enable more warnings if (CXXOPTS_CXX_STANDARD) @@ -53,6 +54,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES endif() add_library(cxxopts INTERFACE) +add_library(cxxopts::cxxopts ALIAS cxxopts) # optionally, enable unicode support using the ICU library set(CXXOPTS_USE_UNICODE_HELP FALSE CACHE BOOL "Use ICU Unicode library") @@ -70,35 +72,37 @@ target_include_directories(cxxopts INTERFACE $ ) -include(CMakePackageConfigHelpers) -set(CXXOPTS_CMAKE_DIR "lib/cmake/cxxopts" CACHE STRING - "Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.") -set(version_config "${PROJECT_BINARY_DIR}/cxxopts-config-version.cmake") -set(project_config "${PROJECT_BINARY_DIR}/cxxopts-config.cmake") -set(targets_export_name cxxopts-targets) - -# Generate the version, config and target files into the build directory. -write_basic_package_version_file( - ${version_config} - VERSION ${VERSION} - COMPATIBILITY AnyNewerVersion) -configure_package_config_file( - ${PROJECT_SOURCE_DIR}/cxxopts-config.cmake.in - ${project_config} - INSTALL_DESTINATION ${CXXOPTS_CMAKE_DIR}) -export(TARGETS cxxopts NAMESPACE cxxopts:: - FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) - -# Install version, config and target files. -#install( -# FILES ${project_config} ${version_config} -# DESTINATION ${CXXOPTS_CMAKE_DIR}) -#install(EXPORT ${targets_export_name} DESTINATION ${CXXOPTS_CMAKE_DIR} -# NAMESPACE cxxopts::) - -# Install the header file and export the target -#install(TARGETS cxxopts EXPORT ${targets_export_name} DESTINATION lib) -#install(FILES ${PROJECT_SOURCE_DIR}/include/cxxopts.hpp DESTINATION include) +if(CXXOPTS_ENABLE_INSTALL) + include(CMakePackageConfigHelpers) + set(CXXOPTS_CMAKE_DIR "lib/cmake/cxxopts" CACHE STRING + "Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.") + set(version_config "${PROJECT_BINARY_DIR}/cxxopts-config-version.cmake") + set(project_config "${PROJECT_BINARY_DIR}/cxxopts-config.cmake") + set(targets_export_name cxxopts-targets) + + # Generate the version, config and target files into the build directory. + write_basic_package_version_file( + ${version_config} + VERSION ${VERSION} + COMPATIBILITY AnyNewerVersion) + configure_package_config_file( + ${PROJECT_SOURCE_DIR}/cxxopts-config.cmake.in + ${project_config} + INSTALL_DESTINATION ${CXXOPTS_CMAKE_DIR}) + export(TARGETS cxxopts NAMESPACE cxxopts:: + FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake) + + # Install version, config and target files. + install( + FILES ${project_config} ${version_config} + DESTINATION ${CXXOPTS_CMAKE_DIR}) + install(EXPORT ${targets_export_name} DESTINATION ${CXXOPTS_CMAKE_DIR} + NAMESPACE cxxopts::) + + # Install the header file and export the target + install(TARGETS cxxopts EXPORT ${targets_export_name} DESTINATION lib) + install(FILES ${PROJECT_SOURCE_DIR}/include/cxxopts.hpp DESTINATION include) +endif() add_subdirectory(src) add_subdirectory(test) diff --git a/vendor/cxxopts/README.md b/vendor/cxxopts/README.md index fa2bce56c..93dcf3b10 100644 --- a/vendor/cxxopts/README.md +++ b/vendor/cxxopts/README.md @@ -116,6 +116,18 @@ There is no way to disambiguate positional arguments from the value following a boolean, so we have chosen that they will be positional arguments, and therefore, `-o false` does not work. +## `std::vector` values + +Parsing of list of values in form of an `std::vector` is also supported, as long as `T` +can be parsed. To separate single values in a list the definition `CXXOPTS_VECTOR_DELIMITER` +is used, which is ',' by default. Ensure that you use no whitespaces between values because +those would be interpreted as the next command line option. Example for a command line option +that can be parsed as a `std::vector`: + +~~~ +--my_list=1,-2.1,3,4.5 +~~~ + ## Custom help The string after the program name on the first line of the help can be diff --git a/vendor/cxxopts/include/cxxopts.hpp b/vendor/cxxopts/include/cxxopts.hpp index 94b81ef0b..9cde72d6b 100644 --- a/vendor/cxxopts/include/cxxopts.hpp +++ b/vendor/cxxopts/include/cxxopts.hpp @@ -29,6 +29,7 @@ THE SOFTWARE. #include #include #include +#include #include #include #include @@ -43,6 +44,10 @@ THE SOFTWARE. #define CXXOPTS_HAS_OPTIONAL #endif +#ifndef CXXOPTS_VECTOR_DELIMITER +#define CXXOPTS_VECTOR_DELIMITER ',' +#endif + #define CXXOPTS__VERSION_MAJOR 2 #define CXXOPTS__VERSION_MINOR 2 #define CXXOPTS__VERSION_PATCH 0 @@ -309,6 +314,9 @@ namespace cxxopts virtual std::shared_ptr implicit_value(const std::string& value) = 0; + virtual std::shared_ptr + no_implicit_value() = 0; + virtual bool is_boolean() const = 0; }; @@ -354,7 +362,7 @@ namespace cxxopts { public: option_exists_error(const std::string& option) - : OptionSpecException(u8"Option " + LQUOTE + option + RQUOTE + u8" already exists") + : OptionSpecException("Option " + LQUOTE + option + RQUOTE + " already exists") { } }; @@ -363,7 +371,7 @@ namespace cxxopts { public: invalid_option_format_error(const std::string& format) - : OptionSpecException(u8"Invalid option format " + LQUOTE + format + RQUOTE) + : OptionSpecException("Invalid option format " + LQUOTE + format + RQUOTE) { } }; @@ -371,8 +379,8 @@ namespace cxxopts class option_syntax_exception : public OptionParseException { public: option_syntax_exception(const std::string& text) - : OptionParseException(u8"Argument " + LQUOTE + text + RQUOTE + - u8" starts with a - but has incorrect syntax") + : OptionParseException("Argument " + LQUOTE + text + RQUOTE + + " starts with a - but has incorrect syntax") { } }; @@ -381,7 +389,7 @@ namespace cxxopts { public: option_not_exists_exception(const std::string& option) - : OptionParseException(u8"Option " + LQUOTE + option + RQUOTE + u8" does not exist") + : OptionParseException("Option " + LQUOTE + option + RQUOTE + " does not exist") { } }; @@ -391,7 +399,7 @@ namespace cxxopts public: missing_argument_exception(const std::string& option) : OptionParseException( - u8"Option " + LQUOTE + option + RQUOTE + u8" is missing an argument" + "Option " + LQUOTE + option + RQUOTE + " is missing an argument" ) { } @@ -402,7 +410,7 @@ namespace cxxopts public: option_requires_argument_exception(const std::string& option) : OptionParseException( - u8"Option " + LQUOTE + option + RQUOTE + u8" requires an argument" + "Option " + LQUOTE + option + RQUOTE + " requires an argument" ) { } @@ -417,8 +425,8 @@ namespace cxxopts const std::string& arg ) : OptionParseException( - u8"Option " + LQUOTE + option + RQUOTE + - u8" does not take an argument, but argument " + + "Option " + LQUOTE + option + RQUOTE + + " does not take an argument, but argument " + LQUOTE + arg + RQUOTE + " given" ) { @@ -429,7 +437,7 @@ namespace cxxopts { public: option_not_present_exception(const std::string& option) - : OptionParseException(u8"Option " + LQUOTE + option + RQUOTE + u8" not present") + : OptionParseException("Option " + LQUOTE + option + RQUOTE + " not present") { } }; @@ -442,7 +450,7 @@ namespace cxxopts const std::string& arg ) : OptionParseException( - u8"Argument " + LQUOTE + arg + RQUOTE + u8" failed to parse" + "Argument " + LQUOTE + arg + RQUOTE + " failed to parse" ) { } @@ -453,12 +461,32 @@ namespace cxxopts public: option_required_exception(const std::string& option) : OptionParseException( - u8"Option " + LQUOTE + option + RQUOTE + u8" is required but not present" + "Option " + LQUOTE + option + RQUOTE + " is required but not present" ) { } }; + template + void throw_or_mimic(const std::string& text) + { + static_assert(std::is_base_of::value, + "throw_or_mimic only works on std::exception and " + "deriving classes"); + +#ifndef CXXOPTS_NO_EXCEPTIONS + // If CXXOPTS_NO_EXCEPTIONS is not defined, just throw + throw T{text}; +#else + // Otherwise manually instantiate the exception, print what() to stderr, + // and abort + T exception{text}; + std::cerr << exception.what() << std::endl; + std::cerr << "Aborting (exceptions disabled)..." << std::endl; + std::abort(); +#endif + } + namespace values { namespace @@ -466,9 +494,9 @@ namespace cxxopts std::basic_regex integer_pattern ("(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)"); std::basic_regex truthy_pattern - ("(t|T)(rue)?"); + ("(t|T)(rue)?|1"); std::basic_regex falsy_pattern - ("((f|F)(alse)?)?"); + ("(f|F)(alse)?|0"); } namespace detail @@ -485,16 +513,16 @@ namespace cxxopts { if (negative) { - if (u > static_cast(-(std::numeric_limits::min)())) + if (u > static_cast((std::numeric_limits::min)())) { - throw argument_incorrect_type(text); + throw_or_mimic(text); } } else { if (u > static_cast((std::numeric_limits::max)())) { - throw argument_incorrect_type(text); + throw_or_mimic(text); } } } @@ -523,14 +551,15 @@ namespace cxxopts // if we got to here, then `t` is a positive number that fits into // `R`. So to avoid MSVC C4146, we first cast it to `R`. // See https://github.com/jarro2783/cxxopts/issues/62 for more details. - return -static_cast(t); + return -static_cast(t-1)-1; } template T - checked_negate(T&&, const std::string& text, std::false_type) + checked_negate(T&& t, const std::string& text, std::false_type) { - throw argument_incorrect_type(text); + throw_or_mimic(text); + return t; } template @@ -542,7 +571,7 @@ namespace cxxopts if (match.length() == 0) { - throw argument_incorrect_type(text); + throw_or_mimic(text); } if (match.length(4) > 0) @@ -553,7 +582,6 @@ namespace cxxopts using US = typename std::make_unsigned::type; - constexpr auto umax = (std::numeric_limits::max)(); constexpr bool is_signed = std::numeric_limits::is_signed; const bool negative = match.length(1) > 0; const uint8_t base = match.length(2) > 0 ? 16 : 10; @@ -568,27 +596,28 @@ namespace cxxopts if (*iter >= '0' && *iter <= '9') { - digit = *iter - '0'; + digit = static_cast(*iter - '0'); } else if (base == 16 && *iter >= 'a' && *iter <= 'f') { - digit = *iter - 'a' + 10; + digit = static_cast(*iter - 'a' + 10); } else if (base == 16 && *iter >= 'A' && *iter <= 'F') { - digit = *iter - 'A' + 10; + digit = static_cast(*iter - 'A' + 10); } else { - throw argument_incorrect_type(text); + throw_or_mimic(text); } - if (umax - digit < result * base) + US next = result * base + digit; + if (result > next) { - throw argument_incorrect_type(text); + throw_or_mimic(text); } - result = result * base + digit; + result = next; } detail::check_signed_range(negative, result, text); @@ -601,7 +630,7 @@ namespace cxxopts } else { - value = result; + value = static_cast(result); } } @@ -611,7 +640,7 @@ namespace cxxopts std::stringstream in(text); in >> value; if (!in) { - throw argument_incorrect_type(text); + throw_or_mimic(text); } } @@ -691,7 +720,7 @@ namespace cxxopts return; } - throw argument_incorrect_type(text); + throw_or_mimic(text); } inline @@ -714,9 +743,13 @@ namespace cxxopts void parse_value(const std::string& text, std::vector& value) { - T v; - parse_value(text, v); - value.push_back(v); + std::stringstream in(text); + std::string token; + while(in.eof() == false && std::getline(in, token, CXXOPTS_VECTOR_DELIMITER)) { + T v; + parse_value(token, v); + value.emplace_back(std::move(v)); + } } #ifdef CXXOPTS_HAS_OPTIONAL @@ -825,6 +858,13 @@ namespace cxxopts return shared_from_this(); } + std::shared_ptr + no_implicit_value() + { + m_implicit = false; + return shared_from_this(); + } + std::string get_default_value() const { @@ -1035,21 +1075,29 @@ namespace cxxopts parse_default(std::shared_ptr details) { ensure_value(details); + m_default = true; m_value->parse(); } size_t - count() const + count() const noexcept { return m_count; } + // TODO: maybe default options should count towards the number of arguments + bool + has_default() const noexcept + { + return m_default; + } + template const T& as() const { if (m_value == nullptr) { - throw std::domain_error("No value"); + throw_or_mimic("No value"); } #ifdef CXXOPTS_NO_RTTI @@ -1071,6 +1119,7 @@ namespace cxxopts std::shared_ptr m_value; size_t m_count = 0; + bool m_default = false; }; class KeyValue @@ -1143,7 +1192,7 @@ namespace cxxopts if (iter == m_options->end()) { - throw option_not_present_exception(option); + throw_or_mimic(option); } auto riter = m_results.find(iter->second); @@ -1202,6 +1251,28 @@ namespace cxxopts std::vector m_sequential; }; + struct Option + { + Option + ( + const std::string& opts, + const std::string& desc, + const std::shared_ptr& value = ::cxxopts::value(), + const std::string& arg_help = "" + ) + : opts_(opts) + , desc_(desc) + , value_(value) + , arg_help_(arg_help) + { + } + + std::string opts_; + std::string desc_; + std::shared_ptr value_; + std::string arg_help_; + }; + class Options { typedef std::unordered_map> @@ -1254,6 +1325,20 @@ namespace cxxopts OptionAdder add_options(std::string group = ""); + void + add_options + ( + const std::string& group, + std::initializer_list