From d3082fffc9858142f0f05ea2212cddb1e7be8034 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 22 Nov 2019 17:05:51 -0400 Subject: [PATCH 01/58] Lower the ev tick interval to 10ms When there's nothing waiting we wait this long unconditionally, but that can add a lot of latency across a path. There are likely better ways to handle this via libuv's run handlers, but this addresses the latency until we figure that out. --- llarp/ev/ev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/ev/ev.h b/llarp/ev/ev.h index f7365decf..22dc5443b 100644 --- a/llarp/ev/ev.h +++ b/llarp/ev/ev.h @@ -40,7 +40,7 @@ typedef SSIZE_T ssize_t; * event handler (cross platform high performance event system for IO) */ -#define EV_TICK_INTERVAL 100 +#define EV_TICK_INTERVAL 10 // forward declare struct llarp_threadpool; From d7f09a365d09bf342ff658489b82753699bb27af Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 14 Nov 2019 13:50:45 -0500 Subject: [PATCH 02/58] contention killer --- llarp/ev/ev_libuv.cpp | 4 ++-- llarp/router/outbound_message_handler.cpp | 16 +++++++++++----- llarp/router/outbound_message_handler.hpp | 2 ++ llarp/util/thread/threading.cpp | 8 ++++++++ llarp/util/thread/threading.hpp | 10 ++++++++++ 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index b003e76bb..f08fdd9b5 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -10,7 +10,7 @@ namespace libuv /// call a function in logic thread via a handle template < typename Handle, typename Func > void - Call(Handle* h, Func&& f) + Call(Handle* h, Func f) { static_cast< Loop* >(h->loop->data)->Call(f); } @@ -416,7 +416,7 @@ namespace libuv OnTick(uv_check_t* t) { ticker_glue* ticker = static_cast< ticker_glue* >(t->data); - Call(&ticker->m_Ticker, [ticker]() { ticker->func(); }); + Call(t, ticker->func); } bool diff --git a/llarp/router/outbound_message_handler.cpp b/llarp/router/outbound_message_handler.cpp index 0774f974b..abe7edc2a 100644 --- a/llarp/router/outbound_message_handler.cpp +++ b/llarp/router/outbound_message_handler.cpp @@ -71,9 +71,12 @@ namespace llarp void OutboundMessageHandler::Tick() { - ProcessOutboundQueue(); - RemoveEmptyPathQueues(); - SendRoundRobin(); + auto self = this; + m_Killer.TryAccess([self]() { + self->ProcessOutboundQueue(); + self->RemoveEmptyPathQueues(); + self->SendRoundRobin(); + }); } void @@ -265,7 +268,9 @@ namespace llarp void OutboundMessageHandler::RemoveEmptyPathQueues() { - removedSomePaths = (not removedPaths.empty()); + removedSomePaths = false; + if(removedPaths.empty()) + return; while(not removedPaths.empty()) { @@ -275,6 +280,7 @@ namespace llarp outboundMessageQueues.erase(itr); } } + removedSomePaths = true; } void @@ -282,7 +288,7 @@ namespace llarp { // send non-routing messages first priority auto &non_routing_mq = outboundMessageQueues[zeroID]; - while(!non_routing_mq.empty()) + while(not non_routing_mq.empty()) { MessageQueueEntry entry = std::move(non_routing_mq.front()); non_routing_mq.pop(); diff --git a/llarp/router/outbound_message_handler.hpp b/llarp/router/outbound_message_handler.hpp index af18bc9d6..9db745efd 100644 --- a/llarp/router/outbound_message_handler.hpp +++ b/llarp/router/outbound_message_handler.hpp @@ -123,6 +123,8 @@ namespace llarp ILinkManager *_linkManager; std::shared_ptr< Logic > _logic; + util::ContentionKiller m_Killer; + // paths cannot have pathid "0", so it can be used as the "pathid" // for non-traffic (control) messages, so they can be prioritized. static const PathID_t zeroID; diff --git a/llarp/util/thread/threading.cpp b/llarp/util/thread/threading.cpp index 359417a03..74d5c6652 100644 --- a/llarp/util/thread/threading.cpp +++ b/llarp/util/thread/threading.cpp @@ -53,5 +53,13 @@ namespace llarp (void)name; #endif } + + void + ContentionKiller::TryAccess(std::function< void(void) > visit) const + { + NullLock lock(&__access); + visit(); + } + } // namespace util } // namespace llarp diff --git a/llarp/util/thread/threading.hpp b/llarp/util/thread/threading.hpp index 960acc917..a61b3d627 100644 --- a/llarp/util/thread/threading.hpp +++ b/llarp/util/thread/threading.hpp @@ -156,6 +156,16 @@ namespace llarp return ::getpid(); #endif } + + // type for detecting contention on a resource + struct ContentionKiller + { + void + TryAccess(std::function< void(void) > visit) const; + + private: + mutable NullMutex __access; + }; } // namespace util } // namespace llarp From eb6d042e73852efa4ccb8770d9cac4cb69a4d770 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 14 Nov 2019 14:32:03 -0500 Subject: [PATCH 03/58] make sure all calls of logic thread jobs are not having contention --- llarp/router/outbound_message_handler.cpp | 9 +++++---- llarp/util/thread/logic.cpp | 5 ++++- llarp/util/thread/logic.hpp | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/llarp/router/outbound_message_handler.cpp b/llarp/router/outbound_message_handler.cpp index abe7edc2a..8866cbe7e 100644 --- a/llarp/router/outbound_message_handler.cpp +++ b/llarp/router/outbound_message_handler.cpp @@ -71,8 +71,7 @@ namespace llarp void OutboundMessageHandler::Tick() { - auto self = this; - m_Killer.TryAccess([self]() { + m_Killer.TryAccess([self = this]() { self->ProcessOutboundQueue(); self->RemoveEmptyPathQueues(); self->SendRoundRobin(); @@ -82,7 +81,8 @@ namespace llarp void OutboundMessageHandler::QueueRemoveEmptyPath(const PathID_t &pathid) { - removedPaths.pushBack(pathid); + m_Killer.TryAccess( + [self = this, pathid]() { self->removedPaths.pushBack(pathid); }); } // TODO: this @@ -168,7 +168,8 @@ namespace llarp if(callback) { auto func = std::bind(callback, status); - _logic->queue_func(func); + _logic->queue_func( + [self = this, func]() { self->m_Killer.TryAccess(func); }); } } diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index d3fd3bad9..efb5de58a 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -53,8 +53,11 @@ namespace llarp } bool - Logic::queue_func(std::function< void(void) > f) + Logic::queue_func(std::function< void(void) > func) { + // wrap the function so that we ensure that it's always calling stuff one at + // a time + auto f = [self = this, func]() { self->m_Killer.TryAccess(func); }; if(m_Thread->LooksFull(5)) { LogWarn( diff --git a/llarp/util/thread/logic.hpp b/llarp/util/thread/logic.hpp index bd8dbcb61..5a27386e0 100644 --- a/llarp/util/thread/logic.hpp +++ b/llarp/util/thread/logic.hpp @@ -49,6 +49,7 @@ namespace llarp llarp_threadpool* const m_Thread; llarp_timer_context* const m_Timer; absl::optional< ID_t > m_ID; + util::ContentionKiller m_Killer; }; } // namespace llarp From 56dce90de9398dd6badce428ef85e8bd68824c77 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 14 Nov 2019 16:56:01 -0500 Subject: [PATCH 04/58] add trace log level for tracking logic thread jobs --- libabyss/main.cpp | 2 +- llarp/context.cpp | 6 ++-- llarp/dht/context.cpp | 4 +-- llarp/dns/server.cpp | 24 +++++++------- llarp/ev/ev_libuv.cpp | 29 +++++++---------- llarp/ev/ev_libuv.hpp | 9 +----- llarp/ev/ev_win32.cpp | 2 +- llarp/handlers/exit.cpp | 2 +- llarp/handlers/tun.cpp | 9 +++--- llarp/iwp/session.cpp | 3 +- llarp/link/server.cpp | 4 +-- llarp/messages/relay_commit.cpp | 4 +-- llarp/messages/relay_status.cpp | 2 +- llarp/nodedb.cpp | 2 +- llarp/path/path.cpp | 18 +++++------ llarp/path/pathbuilder.cpp | 2 +- llarp/path/transit_hop.cpp | 18 +++++------ llarp/router/outbound_message_handler.cpp | 5 ++- llarp/router/outbound_session_maker.cpp | 4 +-- llarp/router/router.cpp | 2 +- llarp/service/async_key_exchange.cpp | 2 +- llarp/service/endpoint.cpp | 3 +- llarp/service/lookup.cpp | 2 +- llarp/service/protocol.cpp | 9 +++--- llarp/service/sendcontext.cpp | 2 +- llarp/util/logging/android_logger.cpp | 10 ++++-- llarp/util/logging/logger.hpp | 14 +++++++++ llarp/util/logging/loglevel.cpp | 2 ++ llarp/util/logging/loglevel.hpp | 1 + llarp/util/logging/ostream_logger.cpp | 3 +- llarp/util/logging/syslog_logger.cpp | 1 + llarp/util/logging/win32_logger.cpp | 2 ++ llarp/util/thread/logic.cpp | 38 +++++++++++++++++------ llarp/util/thread/logic.hpp | 15 ++++++++- test/link/test_llarp_link.cpp | 6 ++-- 35 files changed, 156 insertions(+), 105 deletions(-) diff --git a/libabyss/main.cpp b/libabyss/main.cpp index 626ffb719..274a6968d 100644 --- a/libabyss/main.cpp +++ b/libabyss/main.cpp @@ -39,7 +39,7 @@ struct DemoCall : public abyss::http::IRPCClientHandler bool HandleResponse(abyss::http::RPC_Response) override { llarp::LogInfo("response get"); - m_Logic->queue_func([=]() { m_Callback(); }); + LogicCall(m_Logic, m_Callback); return true; } diff --git a/llarp/context.cpp b/llarp/context.cpp index 7f88b6107..2e79d03bd 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -39,7 +39,7 @@ namespace llarp bool Context::CallSafe(std::function< void(void) > f) { - return logic && logic->queue_func(std::move(f)); + return logic && LogicCall(logic, f); } void @@ -482,8 +482,8 @@ extern "C" void llarp_main_signal(struct llarp_main *ptr, int sig) { - ptr->ctx->logic->queue_func( - std::bind(&llarp::Context::HandleSignal, ptr->ctx.get(), sig)); + LogicCall(ptr->ctx->logic, + std::bind(&llarp::Context::HandleSignal, ptr->ctx.get(), sig)); } int diff --git a/llarp/dht/context.cpp b/llarp/dht/context.cpp index d729543e9..1f95b0120 100644 --- a/llarp/dht/context.cpp +++ b/llarp/dht/context.cpp @@ -199,14 +199,14 @@ namespace llarp PutRCNodeAsync(const RCNode& val) override { auto func = std::bind(&Bucket< RCNode >::PutNode, Nodes(), val); - router->logic()->queue_func(func); + LogicCall(router->logic(), func); } void DelRCNodeAsync(const Key_t& val) override { auto func = std::bind(&Bucket< RCNode >::DelNode, Nodes(), val); - router->logic()->queue_func(func); + LogicCall(router->logic(), func); } const Key_t& diff --git a/llarp/dns/server.cpp b/llarp/dns/server.cpp index dfb0d5834..75373282b 100644 --- a/llarp/dns/server.cpp +++ b/llarp/dns/server.cpp @@ -39,10 +39,10 @@ namespace llarp m_Resolvers = resolvers; const llarp::Addr any("0.0.0.0", 0); auto self = shared_from_this(); - m_ClientLogic->queue_func([=]() { + LogicCall(m_ClientLogic, [=]() { llarp_ev_add_udp(self->m_ClientLoop.get(), &self->m_Client, any); }); - m_ServerLogic->queue_func([=]() { + LogicCall(m_ServerLogic, [=]() { llarp_ev_add_udp(self->m_ServerLoop.get(), &self->m_Server, addr); }); return true; @@ -65,8 +65,9 @@ namespace llarp auto self = static_cast< Proxy* >(u->user)->shared_from_this(); // yes we use the server loop here because if the server loop is not the // client loop we'll crash again - self->m_ServerLogic->queue_func( - [self, addr, msgbuf]() { self->HandlePktServer(addr, msgbuf); }); + LogicCall(self->m_ServerLogic, [self, addr, msgbuf]() { + self->HandlePktServer(addr, msgbuf); + }); } void @@ -76,8 +77,9 @@ namespace llarp const llarp::Addr addr(*from); Buffer_t msgbuf = CopyBuffer(buf.underlying); auto self = static_cast< Proxy* >(u->user)->shared_from_this(); - self->m_ServerLogic->queue_func( - [self, addr, msgbuf]() { self->HandlePktClient(addr, msgbuf); }); + LogicCall(self->m_ServerLogic, [self, addr, msgbuf]() { + self->HandlePktClient(addr, msgbuf); + }); } llarp::Addr @@ -100,7 +102,7 @@ namespace llarp Proxy::SendServerMessageTo(llarp::Addr to, Message msg) { auto self = shared_from_this(); - m_ServerLogic->queue_func([to, msg, self]() { + LogicCall(m_ServerLogic, [to, msg, self]() { std::array< byte_t, 1500 > tmp = {{0}}; llarp_buffer_t buf(tmp); if(msg.Encode(&buf)) @@ -118,7 +120,7 @@ namespace llarp Proxy::SendClientMessageTo(llarp::Addr to, Message msg) { auto self = shared_from_this(); - m_ClientLogic->queue_func([to, msg, self]() { + LogicCall(m_ClientLogic, [to, msg, self]() { std::array< byte_t, 1500 > tmp = {{0}}; llarp_buffer_t buf(tmp); if(msg.Encode(&buf)) @@ -151,7 +153,7 @@ namespace llarp const Addr requester = itr->second; auto self = shared_from_this(); - m_ServerLogic->queue_func([=]() { + LogicCall(m_ServerLogic, [=]() { // forward reply to requester via server const llarp_buffer_t tmpbuf(buf); llarp_ev_udp_sendto(&self->m_Server, requester, tmpbuf); @@ -222,7 +224,7 @@ namespace llarp // new forwarded query tx.from = PickRandomResolver(); m_Forwarded[tx] = from; - m_ClientLogic->queue_func([=] { + LogicCall(m_ClientLogic, [=] { // do query const llarp_buffer_t tmpbuf(buf); llarp_ev_udp_sendto(&self->m_Client, tx.from, tmpbuf); @@ -232,7 +234,7 @@ namespace llarp { // send the query again because it's probably FEC from the requester const auto resolver = itr->first.from; - m_ClientLogic->queue_func([=] { + LogicCall(m_ClientLogic, [=] { // send it const llarp_buffer_t tmpbuf(buf); llarp_ev_udp_sendto(&self->m_Client, resolver, tmpbuf); diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index f08fdd9b5..2055126d0 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -7,13 +7,8 @@ namespace libuv { - /// call a function in logic thread via a handle - template < typename Handle, typename Func > - void - Call(Handle* h, Func f) - { - static_cast< Loop* >(h->loop->data)->Call(f); - } +#define LoopCall(h, ...) \ + LogicCall(static_cast< Loop* >((h)->loop->data)->m_Logic, __VA_ARGS__) struct glue { @@ -110,8 +105,8 @@ namespace libuv OnOutboundConnect(uv_connect_t* c, int status) { conn_glue* self = static_cast< conn_glue* >(c->data); - Call(self->Stream(), - std::bind(&conn_glue::HandleConnectResult, self, status)); + LoopCall(self->Stream(), + std::bind(&conn_glue::HandleConnectResult, self, status)); c->data = nullptr; } @@ -145,7 +140,7 @@ namespace libuv if(nread >= 0) { auto* conn = static_cast< conn_glue* >(stream->data); - Call(stream, std::bind(&conn_glue::Read, conn, buf->base, nread)); + LoopCall(stream, std::bind(&conn_glue::Read, conn, buf->base, nread)); return; } else if(nread < 0) @@ -262,7 +257,7 @@ namespace libuv OnClosed(uv_handle_t* h) { conn_glue* conn = static_cast< conn_glue* >(h->data); - Call(h, std::bind(&conn_glue::HandleClosed, conn)); + LoopCall(h, std::bind(&conn_glue::HandleClosed, conn)); } static void @@ -329,7 +324,7 @@ namespace libuv if(status == 0) { conn_glue* conn = static_cast< conn_glue* >(stream->data); - Call(stream, std::bind(&conn_glue::Accept, conn)); + LoopCall(stream, std::bind(&conn_glue::Accept, conn)); } else { @@ -347,7 +342,7 @@ namespace libuv OnTick(uv_check_t* t) { conn_glue* conn = static_cast< conn_glue* >(t->data); - Call(t, std::bind(&conn_glue::Tick, conn)); + LoopCall(t, std::bind(&conn_glue::Tick, conn)); } void @@ -416,7 +411,7 @@ namespace libuv OnTick(uv_check_t* t) { ticker_glue* ticker = static_cast< ticker_glue* >(t->data); - Call(t, ticker->func); + LoopCall(t, ticker->func); } bool @@ -586,7 +581,7 @@ namespace libuv void Tick() { - Call(&m_Handle, std::bind(&llarp_ev_pkt_pipe::tick, m_Pipe)); + LoopCall(&m_Handle, std::bind(&llarp_ev_pkt_pipe::tick, m_Pipe)); } static void @@ -626,7 +621,7 @@ namespace libuv OnTick(uv_check_t* h) { pipe_glue* pipe = static_cast< pipe_glue* >(h->data); - Call(h, std::bind(&pipe_glue::Tick, pipe)); + LoopCall(h, std::bind(&pipe_glue::Tick, pipe)); } bool @@ -668,7 +663,7 @@ namespace libuv OnTick(uv_check_t* timer) { tun_glue* tun = static_cast< tun_glue* >(timer->data); - Call(timer, std::bind(&tun_glue::Tick, tun)); + LoopCall(timer, std::bind(&tun_glue::Tick, tun)); } static void diff --git a/llarp/ev/ev_libuv.hpp b/llarp/ev/ev_libuv.hpp index d5c86845b..f9e6336d4 100644 --- a/llarp/ev/ev_libuv.hpp +++ b/llarp/ev/ev_libuv.hpp @@ -92,19 +92,12 @@ namespace libuv m_Logic = l; } - /// call function in logic thread - template < typename F > - void - Call(F f) - { - m_Logic->queue_func(f); - } + std::shared_ptr< llarp::Logic > m_Logic; private: uv_loop_t m_Impl; uv_timer_t m_TickTimer; std::atomic< bool > m_Run; - std::shared_ptr< llarp::Logic > m_Logic; }; } // namespace libuv diff --git a/llarp/ev/ev_win32.cpp b/llarp/ev/ev_win32.cpp index b15d29169..164d64326 100644 --- a/llarp/ev/ev_win32.cpp +++ b/llarp/ev/ev_win32.cpp @@ -727,7 +727,7 @@ llarp_win32_loop::tick_listeners() { llarp_ev_loop::tick_listeners(); for(auto& func : m_Tickers) - m_Logic->queue_func([func]() { func(); }); + LogicCall(m_Logic, func); } bool diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index 5b207056f..c8d5431c5 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -23,7 +23,7 @@ namespace llarp ExitHandlerFlush(llarp_tun_io *tun) { auto *ep = static_cast< ExitEndpoint * >(tun->user); - ep->GetRouter()->logic()->queue_func(std::bind(&ExitEndpoint::Flush, ep)); + LogicCall(ep->GetRouter()->logic(), std::bind(&ExitEndpoint::Flush, ep)); } ExitEndpoint::ExitEndpoint(const std::string &name, AbstractRouter *r) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 837093bfd..cdd538094 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -310,7 +310,7 @@ namespace llarp { auto self = shared_from_this(); FlushSend(); - RouterLogic()->queue_func([=] { + LogicCall(RouterLogic(), [=] { self->m_ExitMap.ForEachValue( [](const auto &exit) { exit->FlushUpstream(); }); self->Pump(self->Now()); @@ -749,7 +749,7 @@ namespace llarp void TunEndpoint::Tick(llarp_time_t now) { - EndpointLogic()->queue_func([&]() { + LogicCall(EndpointLogic(), [&]() { m_ExitMap.ForEachValue([&](const auto &exit) { this->EnsureRouterIsKnown(exit->Endpoint()); exit->Tick(now); @@ -982,8 +982,9 @@ namespace llarp } return false; }; - self->EndpointLogic()->queue_func(std::bind( - &TunEndpoint::FlushToUser, self->shared_from_this(), sendpkt)); + LogicCall(self->EndpointLogic(), + std::bind(&TunEndpoint::FlushToUser, self->shared_from_this(), + sendpkt)); } void diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 41cbf7c94..b5318c20e 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -557,7 +557,8 @@ namespace llarp recvMsgs->emplace_back(std::move(pkt)); } LogDebug("decrypted ", recvMsgs->size(), " packets from ", m_RemoteAddr); - m_Parent->logic()->queue_func( + LogicCall( + m_Parent->logic(), std::bind(&Session::HandlePlaintext, shared_from_this(), recvMsgs)); } diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index c7e540d06..87f7a0f33 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -161,7 +161,7 @@ namespace llarp LogInfo("pending session at ", itr->first, " timed out"); // defer call so we can acquire mutexes later auto self = itr->second->BorrowSelf(); - m_Logic->queue_func([&, self]() { + LogicCall(m_Logic, [&, self]() { this->HandleTimeout(self.get()); self->Close(); }); @@ -470,7 +470,7 @@ namespace llarp auto logic = link->logic(); if(logic == nullptr) return; - logic->queue_func([pkts, link]() { + LogicCall(logic, [pkts, link]() { auto itr = pkts->begin(); while(itr != pkts->end()) { diff --git a/llarp/messages/relay_commit.cpp b/llarp/messages/relay_commit.cpp index 261e1c6f3..c4f312bc5 100644 --- a/llarp/messages/relay_commit.cpp +++ b/llarp/messages/relay_commit.cpp @@ -410,7 +410,7 @@ namespace llarp // we are the farthest hop llarp::LogDebug("We are the farthest hop for ", info); // send a LRSM down the path - self->context->logic()->queue_func([=]() { + LogicCall(self->context->logic(), [=]() { SendPathConfirm(self); self->decrypter = nullptr; }); @@ -419,7 +419,7 @@ namespace llarp { // forward upstream // we are still in the worker thread so post job to logic - self->context->logic()->queue_func([=]() { + LogicCall(self->context->logic(), [=]() { SendLRCM(self); self->decrypter = nullptr; }); diff --git a/llarp/messages/relay_status.cpp b/llarp/messages/relay_status.cpp index ea99a677e..df553c6b9 100644 --- a/llarp/messages/relay_status.cpp +++ b/llarp/messages/relay_status.cpp @@ -222,7 +222,7 @@ namespace llarp std::shared_ptr< LR_StatusMessage > msg) { auto func = std::bind(&LR_StatusMessage::SendMessage, router, nextHop, msg); - router->pathContext().logic()->queue_func(func); + LogicCall(router->logic(), func); } void diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 6c4b51fbf..c9b7d7f4e 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -122,7 +122,7 @@ llarp_nodedb::InsertAsync(llarp::RouterContact rc, this->Insert(rc); if(logic && completionHandler) { - logic->queue_func([completionHandler] { completionHandler(); }); + LogicCall(logic, completionHandler); } }); } diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index bcee180dc..be2fa17ce 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -155,7 +155,7 @@ namespace llarp { llarp::LogDebug("LR_Status message processed, path build successful"); auto self = shared_from_this(); - r->logic()->queue_func([=]() { self->HandlePathConfirmMessage(r); }); + LogicCall(r->logic(), [=]() { self->HandlePathConfirmMessage(r); }); } else { @@ -206,8 +206,8 @@ namespace llarp llarp::LogDebug("Path build failed for an unspecified reason"); } auto self = shared_from_this(); - r->logic()->queue_func( - [=]() { self->EnterState(ePathFailed, r->Now()); }); + LogicCall(r->logic(), + [=]() { self->EnterState(ePathFailed, r->Now()); }); } // TODO: meaningful return value? @@ -411,9 +411,9 @@ namespace llarp msg.pathid = TXID(); ++idx; } - r->logic()->queue_func(std::bind(&Path::HandleAllUpstream, - shared_from_this(), std::move(sendmsgs), - r)); + LogicCall(r->logic(), + std::bind(&Path::HandleAllUpstream, shared_from_this(), + std::move(sendmsgs), r)); } void @@ -482,9 +482,9 @@ namespace llarp sendMsgs[idx].X = buf; ++idx; } - r->logic()->queue_func(std::bind(&Path::HandleAllDownstream, - shared_from_this(), std::move(sendMsgs), - r)); + LogicCall(r->logic(), + std::bind(&Path::HandleAllDownstream, shared_from_this(), + std::move(sendMsgs), r)); } void diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index b30dbbc96..07be157dc 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -98,7 +98,7 @@ namespace llarp { // farthest hop // TODO: encrypt junk frames because our public keys are not eligator - logic->queue_func(std::bind(result, shared_from_this())); + LogicCall(logic, std::bind(result, shared_from_this())); } else { diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index c3c2e9d03..f207dd462 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -132,9 +132,9 @@ namespace llarp info.upstream, " to ", info.downstream); ++idx; } - r->logic()->queue_func(std::bind(&TransitHop::HandleAllDownstream, - shared_from_this(), std::move(sendmsgs), - r)); + LogicCall(r->logic(), + std::bind(&TransitHop::HandleAllDownstream, shared_from_this(), + std::move(sendmsgs), r)); } void @@ -152,9 +152,9 @@ namespace llarp msg.X = buf; ++idx; } - r->logic()->queue_func(std::bind(&TransitHop::HandleAllUpstream, - shared_from_this(), std::move(sendmsgs), - r)); + LogicCall(r->logic(), + std::bind(&TransitHop::HandleAllUpstream, shared_from_this(), + std::move(sendmsgs), r)); } void @@ -183,7 +183,7 @@ namespace llarp r->SendToOrQueue(info.upstream, &msg); } } - r->linkManager().PumpLinks(); + r->PumpLL(); } void @@ -196,7 +196,7 @@ namespace llarp info.upstream, " to ", info.downstream); r->SendToOrQueue(info.downstream, &msg); } - r->linkManager().PumpLinks(); + r->PumpLL(); } void @@ -435,7 +435,7 @@ namespace llarp TransitHop::QueueDestroySelf(AbstractRouter* r) { auto func = std::bind(&TransitHop::SetSelfDestruct, shared_from_this()); - r->logic()->queue_func(func); + LogicCall(r->logic(), func); } } // namespace path } // namespace llarp diff --git a/llarp/router/outbound_message_handler.cpp b/llarp/router/outbound_message_handler.cpp index 8866cbe7e..825532aa1 100644 --- a/llarp/router/outbound_message_handler.cpp +++ b/llarp/router/outbound_message_handler.cpp @@ -167,9 +167,8 @@ namespace llarp { if(callback) { - auto func = std::bind(callback, status); - _logic->queue_func( - [self = this, func]() { self->m_Killer.TryAccess(func); }); + auto f = std::bind(callback, status); + LogicCall(_logic, [self = this, f]() { self->m_Killer.TryAccess(f); }); } } diff --git a/llarp/router/outbound_session_maker.cpp b/llarp/router/outbound_session_maker.cpp index f3418171b..4a536f81a 100644 --- a/llarp/router/outbound_session_maker.cpp +++ b/llarp/router/outbound_session_maker.cpp @@ -219,7 +219,7 @@ namespace llarp if(ShouldConnectTo(router)) { auto fn = std::bind(&OutboundSessionMaker::DoEstablish, this, router); - _logic->queue_func(fn); + LogicCall(_logic, fn); } } @@ -326,7 +326,7 @@ namespace llarp for(const auto &callback : movedCallbacks) { auto func = std::bind(callback, router, type); - _logic->queue_func(func); + LogicCall(_logic, func); } { diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index d9086ecd3..17aacd206 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -307,7 +307,7 @@ namespace llarp return; auto *self = static_cast< Router * >(user); self->ticker_job_id = 0; - self->logic()->queue_func(std::bind(&Router::Tick, self)); + LogicCall(self->logic(), std::bind(&Router::Tick, self)); self->ScheduleTicker(orig); } diff --git a/llarp/service/async_key_exchange.cpp b/llarp/service/async_key_exchange.cpp index b948520bf..1267cfa60 100644 --- a/llarp/service/async_key_exchange.cpp +++ b/llarp/service/async_key_exchange.cpp @@ -69,7 +69,7 @@ namespace llarp self->msg.version = LLARP_PROTO_VERSION; // encrypt and sign if(self->frame->EncryptAndSign(self->msg, K, self->m_LocalIdentity)) - self->logic->queue_func(std::bind(&AsyncKeyExchange::Result, self)); + LogicCall(self->logic, std::bind(&AsyncKeyExchange::Result, self)); else { LogError("failed to encrypt and sign"); diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 617dcdc4d..94c344f7c 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1046,7 +1046,8 @@ namespace llarp { const auto& sessions = m_state->m_SNodeSessions; auto& queue = m_state->m_InboundTrafficQueue; - EndpointLogic()->queue_func([&]() { + + LogicCall(EndpointLogic(), [&]() { // send downstream packets to user for snode for(const auto& item : sessions) item.second.first->FlushDownstream(); diff --git a/llarp/service/lookup.cpp b/llarp/service/lookup.cpp index 90dbcfe84..6ffbebd71 100644 --- a/llarp/service/lookup.cpp +++ b/llarp/service/lookup.cpp @@ -26,7 +26,7 @@ namespace llarp if(!msg) return false; endpoint = path->Endpoint(); - r->logic()->queue_func([=]() { path->SendRoutingMessage(*msg, r); }); + LogicCall(r->logic(), [=]() { path->SendRoutingMessage(*msg, r); }); return true; } } // namespace service diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index 8f723c1f2..236998848 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -343,8 +343,8 @@ namespace llarp std::shared_ptr< ProtocolMessage > msg = std::move(self->msg); path::Path_ptr path = std::move(self->path); const PathID_t from = self->frame.F; - self->logic->queue_func( - [=]() { ProtocolMessage::ProcessAsync(path, from, msg); }); + LogicCall(self->logic, + [=]() { ProtocolMessage::ProcessAsync(path, from, msg); }); delete self; } }; @@ -409,8 +409,9 @@ namespace llarp } msg->handler = handler; const PathID_t fromPath = F; - logic->queue_func( - [=]() { ProtocolMessage::ProcessAsync(recvPath, fromPath, msg); }); + LogicCall(logic, [=]() { + ProtocolMessage::ProcessAsync(recvPath, fromPath, msg); + }); return true; } diff --git a/llarp/service/sendcontext.cpp b/llarp/service/sendcontext.cpp index d4c9dc8a5..6a2c107bc 100644 --- a/llarp/service/sendcontext.cpp +++ b/llarp/service/sendcontext.cpp @@ -100,7 +100,7 @@ namespace llarp LogError(self->m_Endpoint->Name(), " failed to sign message"); return; } - self->m_Endpoint->RouterLogic()->queue_func([self, f, path]() { + LogicCall(self->m_Endpoint->RouterLogic(), [self, f, path]() { self->Send(f, path); self->FlushUpstream(); }); diff --git a/llarp/util/logging/android_logger.cpp b/llarp/util/logging/android_logger.cpp index 439a99036..2757cb746 100644 --- a/llarp/util/logging/android_logger.cpp +++ b/llarp/util/logging/android_logger.cpp @@ -14,9 +14,10 @@ namespace llarp switch(lvl) { case eLogNone: - break; - case eLogDebug: - ss << "[DBG] "; + return; + case eLogTrace: + ss << "[TRC] "; + break case eLogDebug : ss << "[DBG] "; break; case eLogInfo: ss << "[NFO] "; @@ -49,6 +50,9 @@ namespace llarp str += tag; switch(lvl) { + case eLogTrace: + __android_log_write(ANDROID_LOG_TRACE, str.c_str(), msg.c_str()); + return; case eLogDebug: __android_log_write(ANDROID_LOG_DEBUG, str.c_str(), msg.c_str()); return; diff --git a/llarp/util/logging/logger.hpp b/llarp/util/logging/logger.hpp index 300cc8684..206c8a000 100644 --- a/llarp/util/logging/logger.hpp +++ b/llarp/util/logging/logger.hpp @@ -236,15 +236,29 @@ namespace llarp */ } // namespace llarp +#define LogTrace(...) _Log(llarp::eLogTrace, LOG_TAG, __LINE__, __VA_ARGS__) #define LogDebug(...) _Log(llarp::eLogDebug, LOG_TAG, __LINE__, __VA_ARGS__) #define LogInfo(...) _Log(llarp::eLogInfo, LOG_TAG, __LINE__, __VA_ARGS__) #define LogWarn(...) _Log(llarp::eLogWarn, LOG_TAG, __LINE__, __VA_ARGS__) #define LogError(...) _Log(llarp::eLogError, LOG_TAG, __LINE__, __VA_ARGS__) + +#define LogTraceTag(tag, ...) _Log(llarp::eLogTrace, tag, __LINE__, __VA_ARGS__) #define LogDebugTag(tag, ...) _Log(llarp::eLogDebug, tag, __LINE__, __VA_ARGS__) #define LogInfoTag(tag, ...) _Log(llarp::eLogInfo, tag, __LINE__, __VA_ARGS__) #define LogWarnTag(tag, ...) _Log(llarp::eLogWarn, tag, __LINE__, __VA_ARGS__) #define LogErrorTag(tag, ...) _Log(llarp::eLogError, tag, __LINE__, __VA_ARGS__) +#define LogTraceExplicit(tag, line, ...) \ + _Log(llarp::eLogTrace, tag, line, __VA_ARGS__) +#define LogDebugExplicit(tag, line, ...) \ + _Log(llarp::eLogDebug, tag, line, __VA_ARGS__) +#define LogInfoExplicit(tag, line, ...) \ + _Log(llarp::eLogInfo, tag, line __VA_ARGS__) +#define LogWarnExplicit(tag, line, ...) \ + _Log(llarp::eLogWarn, tag, line, __VA_ARGS__) +#define LogErrorExplicit(tag, line, ...) \ + _Log(llarp::eLogError, tag, line, __VA_ARGS__) + #ifndef LOG_TAG #define LOG_TAG "default" #endif diff --git a/llarp/util/logging/loglevel.cpp b/llarp/util/logging/loglevel.cpp index e01acaa8a..e2d972627 100644 --- a/llarp/util/logging/loglevel.cpp +++ b/llarp/util/logging/loglevel.cpp @@ -7,6 +7,8 @@ namespace llarp { switch(lvl) { + case eLogTrace: + return "TRC"; case eLogDebug: return "DBG"; case eLogInfo: diff --git a/llarp/util/logging/loglevel.hpp b/llarp/util/logging/loglevel.hpp index 4b9063fed..3bf7a7918 100644 --- a/llarp/util/logging/loglevel.hpp +++ b/llarp/util/logging/loglevel.hpp @@ -7,6 +7,7 @@ namespace llarp // probably will need to move out of llarp namespace for c api enum LogLevel { + eLogTrace, eLogDebug, eLogInfo, eLogWarn, diff --git a/llarp/util/logging/ostream_logger.cpp b/llarp/util/logging/ostream_logger.cpp index 233b99ed4..ba3b3d19e 100644 --- a/llarp/util/logging/ostream_logger.cpp +++ b/llarp/util/logging/ostream_logger.cpp @@ -18,7 +18,8 @@ namespace llarp switch(lvl) { case eLogNone: - break; + return; + case eLogTrace: case eLogDebug: ss << (char)27 << "[0m"; break; diff --git a/llarp/util/logging/syslog_logger.cpp b/llarp/util/logging/syslog_logger.cpp index 7ce3b533f..c9ff0c45b 100644 --- a/llarp/util/logging/syslog_logger.cpp +++ b/llarp/util/logging/syslog_logger.cpp @@ -23,6 +23,7 @@ namespace llarp { case eLogNone: return; + case eLogTrace: case eLogDebug: ::syslog(LOG_DEBUG, "%s", msg.c_str()); return; diff --git a/llarp/util/logging/win32_logger.cpp b/llarp/util/logging/win32_logger.cpp index 65e359804..e5e7eecac 100644 --- a/llarp/util/logging/win32_logger.cpp +++ b/llarp/util/logging/win32_logger.cpp @@ -34,6 +34,8 @@ namespace llarp { case eLogNone: break; + case eLogTrace: + ss << "[TRC] "; case eLogDebug: ss << "[DBG] "; break; diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index efb5de58a..ba53e7bd6 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -39,7 +39,8 @@ namespace llarp bool Logic::queue_job(struct llarp_thread_job job) { - return job.user && job.work && queue_func(std::bind(job.work, job.user)); + return job.user && job.work + && LogicCall(this, std::bind(job.work, job.user)); } void @@ -47,31 +48,50 @@ namespace llarp { llarp::LogDebug("logic thread stop"); // stop all timers from happening in the future - queue_func(std::bind(&llarp_timer_stop, m_Timer)); + LogicCall(this, std::bind(&llarp_timer_stop, m_Timer)); // stop all operations on threadpool llarp_threadpool_stop(m_Thread); } bool - Logic::queue_func(std::function< void(void) > func) + Logic::_traceLogicCall(std::function< void(void) > func, const char* tag, + int line) { +#define TAG (tag ? tag : LOG_TAG) +#define LINE (line ? line : __LINE__) // wrap the function so that we ensure that it's always calling stuff one at // a time - auto f = [self = this, func]() { self->m_Killer.TryAccess(func); }; + + LogTraceExplicit(TAG, LINE, "queue"); + + auto f = [self = this, func, tag, line]() { + LogTraceExplicit(TAG, LINE, "exec"); + self->m_Killer.TryAccess(func); + LogTraceExplicit(TAG, LINE, "return"); + }; if(m_Thread->LooksFull(5)) { - LogWarn( - "holy crap, we are trying to queue a job onto the logic thread but " - "it looks full"); + LogWarnExplicit(TAG, LINE, + "holy crap, we are trying to queue a job onto the logic " + "thread but " + "it looks full"); + if(can_flush()) { // we are calling in the logic thread and our queue looks full // defer call to a later time so we don't die like a little bitch - call_later(m_Thread->GuessJobLatency() / 2, f); + const auto delay = m_Thread->GuessJobLatency() / 2; + + LogWarnExplicit(TAG, LINE, "deferring call by ", delay, " ms"); + call_later(delay, f); return true; } } - return llarp_threadpool_queue_job(m_Thread, f); + auto ret = llarp_threadpool_queue_job(m_Thread, f); + LogTraceExplicit(TAG, LINE, "=="); + return ret; +#undef TAG +#undef LINE } void diff --git a/llarp/util/thread/logic.hpp b/llarp/util/thread/logic.hpp index 5a27386e0..d671a39ab 100644 --- a/llarp/util/thread/logic.hpp +++ b/llarp/util/thread/logic.hpp @@ -27,7 +27,8 @@ namespace llarp queue_job(struct llarp_thread_job job); bool - queue_func(std::function< void(void) > func); + _traceLogicCall(std::function< void(void) > func, const char* filename, + int lineo); uint32_t call_later(const llarp_timeout_job& job); @@ -53,4 +54,16 @@ namespace llarp }; } // namespace llarp +#ifndef LogicCall +#if defined(LOKINET_DEBUG) +#ifdef LOG_TAG +#define LogicCall(l, ...) l->_traceLogicCall(__VA_ARGS__, LOG_TAG, __LINE__) +#else +#define LogicCall(l, ...) l->_traceLogicCall(__VA_ARGS__, __FILE__, __LINE__) +#endif +#else +#define LogicCall(l, ...) l->_traceLogicCall(__VG_ARGS__, 0, 0) +#endif +#endif + #endif diff --git a/test/link/test_llarp_link.cpp b/test/link/test_llarp_link.cpp index 45a85965a..0d046f0df 100644 --- a/test/link/test_llarp_link.cpp +++ b/test/link/test_llarp_link.cpp @@ -127,7 +127,7 @@ struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium > Context Bob; bool success = false; - const bool shouldDebug = true; + const bool shouldDebug = false; llarp_ev_loop_ptr netLoop; std::shared_ptr< Logic > m_logic; @@ -144,7 +144,7 @@ struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium > { oldLevel = llarp::LogContext::Instance().minLevel; if(shouldDebug) - llarp::SetLogLevel(eLogDebug); + llarp::SetLogLevel(eLogTrace); oldRCLifetime = RouterContact::Lifetime; RouterContact::BlockBogons = false; RouterContact::Lifetime = 500; @@ -285,7 +285,7 @@ TEST_F(LinkLayerTest, TestIWP) ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort)); ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort)); - m_logic->queue_func([&]() { ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC())); }); + LogicCall(m_logic, [&]() { ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC())); }); RunMainloop(); ASSERT_TRUE(Alice.IsGucci()); From 1188763ece863641684dfedb64d18a66a1f49316 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 14 Nov 2019 18:24:12 -0500 Subject: [PATCH 05/58] typo fix in release --- llarp/util/thread/logic.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/util/thread/logic.hpp b/llarp/util/thread/logic.hpp index d671a39ab..7d3ed2bb2 100644 --- a/llarp/util/thread/logic.hpp +++ b/llarp/util/thread/logic.hpp @@ -62,7 +62,7 @@ namespace llarp #define LogicCall(l, ...) l->_traceLogicCall(__VA_ARGS__, __FILE__, __LINE__) #endif #else -#define LogicCall(l, ...) l->_traceLogicCall(__VG_ARGS__, 0, 0) +#define LogicCall(l, ...) l->_traceLogicCall(__VA_ARGS__, 0, 0) #endif #endif From fdbaaa8188d27bfd6ff3e70771468a562f40a4c5 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 15 Nov 2019 16:10:51 -0500 Subject: [PATCH 06/58] try fixing file log segfault --- llarp/util/logging/file_logger.cpp | 139 +++++++++++++++++------------ llarp/util/logging/file_logger.hpp | 5 +- 2 files changed, 85 insertions(+), 59 deletions(-) diff --git a/llarp/util/logging/file_logger.cpp b/llarp/util/logging/file_logger.cpp index b02d9c2a3..ed2676046 100644 --- a/llarp/util/logging/file_logger.cpp +++ b/llarp/util/logging/file_logger.cpp @@ -7,70 +7,93 @@ namespace llarp { namespace { + template < typename T > static void - Flush(std::deque< std::string > lines, FILE *const f) + Flush(T *lines, FILE *const f) { - for(const auto &line : lines) - fprintf(f, "%s\n", line.c_str()); - fflush(f); + bool wrote_stuff = false; + do + { + auto maybe_line = lines->tryPopFront(); + if(not maybe_line.has_value()) + break; + const auto &line = maybe_line.value(); + if(fprintf(f, "%s\n", line.c_str()) > 0) + wrote_stuff = true; + } while(true); + + if(wrote_stuff) + fflush(f); + } + // namespace + FileLogStream::FileLogStream(std::shared_ptr< thread::ThreadPool > disk, + FILE *f, llarp_time_t flushInterval, + bool closeFile) + : m_Lines(512) + , m_Disk(std::move(disk)) + , m_File(f) + , m_FlushInterval(flushInterval) + , m_Close(closeFile) + { + m_Lines.enable(); } - } // namespace - FileLogStream::FileLogStream(std::shared_ptr< thread::ThreadPool > disk, - FILE *f, llarp_time_t flushInterval, - bool closeFile) - : m_Disk(std::move(disk)) - , m_File(f) - , m_FlushInterval(flushInterval) - , m_Close(closeFile) - { - } - FileLogStream::~FileLogStream() - { - fflush(m_File); - if(m_Close) - fclose(m_File); - } + FileLogStream::~FileLogStream() + { + m_Lines.disable(); + do + { + auto line = m_Lines.tryPopFront(); + if(not line.has_value()) + break; + } while(true); + fflush(m_File); + if(m_Close) + fclose(m_File); + } - bool - FileLogStream::ShouldFlush(llarp_time_t now) const - { - if(m_LastFlush >= now) - return false; - const auto dlt = now - m_LastFlush; - return dlt >= m_FlushInterval; - } + bool + FileLogStream::ShouldFlush(llarp_time_t now) const + { + if(m_Lines.full()) + return true; + if(m_LastFlush >= now) + return false; + const auto dlt = now - m_LastFlush; + return dlt >= m_FlushInterval; + } - void - FileLogStream::PreLog(std::stringstream &ss, LogLevel lvl, const char *fname, - int lineno, const std::string &nodename) const - { - ss << "[" << LogLevelToString(lvl) << "] "; - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname - << ":" << lineno << "\t"; - } + void + FileLogStream::PreLog(std::stringstream &ss, LogLevel lvl, + const char *fname, int lineno, + const std::string &nodename) const + { + ss << "[" << LogLevelToString(lvl) << "] "; + ss << "[" << nodename << "]" + << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname + << ":" << lineno << "\t"; + } - void - FileLogStream::Print(LogLevel, const char *, const std::string &msg) - { - m_Lines.emplace_back(msg); - } + void + FileLogStream::Print(LogLevel, const char *, const std::string &msg) + { + m_Lines.pushBack(msg); + Tick(llarp::time_now_ms()); + } - void - FileLogStream::Tick(llarp_time_t now) - { - if(ShouldFlush(now)) - FlushLinesToDisk(now); - } + void + FileLogStream::Tick(llarp_time_t now) + { + if(ShouldFlush(now)) + FlushLinesToDisk(now); + } - void - FileLogStream::FlushLinesToDisk(llarp_time_t now) - { - FILE *const f = m_File; - std::deque< std::string > lines(m_Lines); - m_Disk->addJob([=]() { Flush(lines, f); }); - m_Lines.clear(); - m_LastFlush = now; - } -} // namespace llarp + void + FileLogStream::FlushLinesToDisk(llarp_time_t now) + { + FILE *const f = m_File; + auto lines = &m_Lines; + m_Disk->addJob([f, lines]() { Flush(lines, f); }); + m_LastFlush = now; + } + } // namespace diff --git a/llarp/util/logging/file_logger.hpp b/llarp/util/logging/file_logger.hpp index c8db68689..8cf55f19d 100644 --- a/llarp/util/logging/file_logger.hpp +++ b/llarp/util/logging/file_logger.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -33,8 +34,10 @@ namespace llarp { } + using Lines_t = thread::Queue< std::string >; + protected: - std::deque< std::string > m_Lines; + Lines_t m_Lines; private: bool From 1fa0a0aab2a615b3c633ee896802c9f68c6d20a5 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 15 Nov 2019 16:16:46 -0500 Subject: [PATCH 07/58] make it compile --- llarp/util/logging/file_logger.cpp | 168 +++++++++++++++-------------- llarp/util/logging/file_logger.hpp | 11 +- llarp/util/logging/json_logger.cpp | 2 +- 3 files changed, 95 insertions(+), 86 deletions(-) diff --git a/llarp/util/logging/file_logger.cpp b/llarp/util/logging/file_logger.cpp index ed2676046..7e055b27d 100644 --- a/llarp/util/logging/file_logger.cpp +++ b/llarp/util/logging/file_logger.cpp @@ -5,95 +5,99 @@ namespace llarp { - namespace + void + FileLogStream::Flush(Lines_t *lines, FILE *const f) { - template < typename T > - static void - Flush(T *lines, FILE *const f) + bool wrote_stuff = false; + do { - bool wrote_stuff = false; - do - { - auto maybe_line = lines->tryPopFront(); - if(not maybe_line.has_value()) - break; - const auto &line = maybe_line.value(); - if(fprintf(f, "%s\n", line.c_str()) > 0) - wrote_stuff = true; - } while(true); + auto maybe_line = lines->tryPopFront(); + if(not maybe_line.has_value()) + break; + const auto &line = maybe_line.value(); + if(fprintf(f, "%s\n", line.c_str()) >= 0) + wrote_stuff = true; + } while(true); - if(wrote_stuff) - fflush(f); - } - // namespace - FileLogStream::FileLogStream(std::shared_ptr< thread::ThreadPool > disk, - FILE *f, llarp_time_t flushInterval, - bool closeFile) - : m_Lines(512) - , m_Disk(std::move(disk)) - , m_File(f) - , m_FlushInterval(flushInterval) - , m_Close(closeFile) - { - m_Lines.enable(); - } + if(wrote_stuff) + fflush(f); + } - FileLogStream::~FileLogStream() - { - m_Lines.disable(); - do - { - auto line = m_Lines.tryPopFront(); - if(not line.has_value()) - break; - } while(true); - fflush(m_File); - if(m_Close) - fclose(m_File); - } + // namespace + FileLogStream::FileLogStream(std::shared_ptr< thread::ThreadPool > disk, + FILE *f, llarp_time_t flushInterval, + bool closeFile) + : m_Lines(1024 * 8) + , m_Disk(std::move(disk)) + , m_File(f) + , m_FlushInterval(flushInterval) + , m_Close(closeFile) + { + m_Lines.enable(); + } - bool - FileLogStream::ShouldFlush(llarp_time_t now) const + FileLogStream::~FileLogStream() + { + m_Lines.disable(); + do { - if(m_Lines.full()) - return true; - if(m_LastFlush >= now) - return false; - const auto dlt = now - m_LastFlush; - return dlt >= m_FlushInterval; - } + auto line = m_Lines.tryPopFront(); + if(not line.has_value()) + break; + } while(true); + fflush(m_File); + if(m_Close) + fclose(m_File); + } - void - FileLogStream::PreLog(std::stringstream &ss, LogLevel lvl, - const char *fname, int lineno, - const std::string &nodename) const - { - ss << "[" << LogLevelToString(lvl) << "] "; - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname - << ":" << lineno << "\t"; - } + bool + FileLogStream::ShouldFlush(llarp_time_t now) const + { + if(m_Lines.full()) + return true; + if(m_LastFlush >= now) + return false; + const auto dlt = now - m_LastFlush; + return dlt >= m_FlushInterval; + } - void - FileLogStream::Print(LogLevel, const char *, const std::string &msg) - { - m_Lines.pushBack(msg); - Tick(llarp::time_now_ms()); - } + void + FileLogStream::PreLog(std::stringstream &ss, LogLevel lvl, const char *fname, + int lineno, const std::string &nodename) const + { + ss << "[" << LogLevelToString(lvl) << "] "; + ss << "[" << nodename << "]" + << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname + << ":" << lineno << "\t"; + } - void - FileLogStream::Tick(llarp_time_t now) - { - if(ShouldFlush(now)) - FlushLinesToDisk(now); - } + void + FileLogStream::Print(LogLevel, const char *, const std::string &msg) + { + m_Lines.pushBack(msg); + } - void - FileLogStream::FlushLinesToDisk(llarp_time_t now) - { - FILE *const f = m_File; - auto lines = &m_Lines; - m_Disk->addJob([f, lines]() { Flush(lines, f); }); - m_LastFlush = now; - } - } // namespace + void + FileLogStream::AppendLog(LogLevel lvl, const char *fname, int lineno, + const std::string &nodename, const std::string msg) + { + ILogStream::AppendLog(lvl, fname, lineno, nodename, msg); + Tick(llarp::time_now_ms()); + } + + void + FileLogStream::Tick(llarp_time_t now) + { + if(ShouldFlush(now)) + FlushLinesToDisk(now); + } + + void + FileLogStream::FlushLinesToDisk(llarp_time_t now) + { + FILE *const f = m_File; + auto lines = &m_Lines; + m_Disk->addJob([f, lines]() { Flush(lines, f); }); + m_LastFlush = now; + } +} // namespace llarp diff --git a/llarp/util/logging/file_logger.hpp b/llarp/util/logging/file_logger.hpp index 8cf55f19d..117869295 100644 --- a/llarp/util/logging/file_logger.hpp +++ b/llarp/util/logging/file_logger.hpp @@ -30,9 +30,11 @@ namespace llarp Tick(llarp_time_t now) override; void - PostLog(std::stringstream&) const override - { - } + PostLog(std::stringstream&) const override{}; + + void + AppendLog(LogLevel lvl, const char* fname, int lineno, + const std::string& nodename, const std::string msg) override; using Lines_t = thread::Queue< std::string >; @@ -40,6 +42,9 @@ namespace llarp Lines_t m_Lines; private: + static void + Flush(Lines_t* const, FILE* const); + bool ShouldFlush(llarp_time_t now) const; diff --git a/llarp/util/logging/json_logger.cpp b/llarp/util/logging/json_logger.cpp index 71ed8bd99..8acb416b7 100644 --- a/llarp/util/logging/json_logger.cpp +++ b/llarp/util/logging/json_logger.cpp @@ -14,7 +14,7 @@ namespace llarp obj["line"] = lineno; obj["level"] = LogLevelToString(lvl); obj["message"] = msg; - m_Lines.emplace_back(obj.dump()); + m_Lines.pushBack(obj.dump()); } } // namespace llarp From d44d034775c747a0013cfa2d90e4c402131d1122 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 19 Nov 2019 14:16:22 -0500 Subject: [PATCH 08/58] make contention checker templated --- llarp/util/thread/threading.cpp | 8 -------- llarp/util/thread/threading.hpp | 7 ++++++- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/llarp/util/thread/threading.cpp b/llarp/util/thread/threading.cpp index 74d5c6652..359417a03 100644 --- a/llarp/util/thread/threading.cpp +++ b/llarp/util/thread/threading.cpp @@ -53,13 +53,5 @@ namespace llarp (void)name; #endif } - - void - ContentionKiller::TryAccess(std::function< void(void) > visit) const - { - NullLock lock(&__access); - visit(); - } - } // namespace util } // namespace llarp diff --git a/llarp/util/thread/threading.hpp b/llarp/util/thread/threading.hpp index a61b3d627..6e2ef8da2 100644 --- a/llarp/util/thread/threading.hpp +++ b/llarp/util/thread/threading.hpp @@ -160,8 +160,13 @@ namespace llarp // type for detecting contention on a resource struct ContentionKiller { + template < typename F > void - TryAccess(std::function< void(void) > visit) const; + TryAccess(F visit) const + { + NullLock lock(&__access); + visit(); + } private: mutable NullMutex __access; From b207db626f6e5b123d8c3e529781527bf214e99c Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 19 Nov 2019 15:30:51 -0500 Subject: [PATCH 09/58] please the gods of valgrind --- llarp/iwp/session.cpp | 10 ++++------ llarp/iwp/session.hpp | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index b5318c20e..e1f75a9d1 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -57,9 +57,10 @@ namespace llarp } void - Session::Send_LL(const llarp_buffer_t& pkt) + Session::Send_LL(const byte_t* buf, size_t sz) { - LogDebug("send ", pkt.sz, " to ", m_RemoteAddr); + LogDebug("send ", sz, " to ", m_RemoteAddr); + const llarp_buffer_t pkt(buf, sz); m_Parent->SendTo_LL(m_RemoteAddr, pkt); m_LastTX = time_now_ms(); } @@ -155,10 +156,7 @@ namespace llarp pktbuf.base = pkt.data() + HMACSIZE; pktbuf.sz = pkt.size() - HMACSIZE; CryptoManager::instance()->hmac(pkt.data(), pktbuf, m_SessionKey); - pktbuf.base = pkt.data(); - pktbuf.cur = pkt.data(); - pktbuf.sz = pkt.size(); - Send_LL(pktbuf); + Send_LL(pkt.data(), pkt.size()); } } diff --git a/llarp/iwp/session.hpp b/llarp/iwp/session.hpp index 7e19d43d5..2c6f5d301 100644 --- a/llarp/iwp/session.hpp +++ b/llarp/iwp/session.hpp @@ -62,7 +62,7 @@ namespace llarp CompletionHandler resultHandler) override; void - Send_LL(const llarp_buffer_t& pkt); + Send_LL(const byte_t* buf, size_t sz); void EncryptAndSend(ILinkSession::Packet_t); From 250cfea1e989a2efe200de0285bd06f9ef2c2325 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 19 Nov 2019 15:53:36 -0500 Subject: [PATCH 10/58] remove use of void * in godawful old code from a time before happyness --- llarp/crypto/encrypted_frame.hpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/llarp/crypto/encrypted_frame.hpp b/llarp/crypto/encrypted_frame.hpp index e1fccab5e..94585ebd3 100644 --- a/llarp/crypto/encrypted_frame.hpp +++ b/llarp/crypto/encrypted_frame.hpp @@ -58,20 +58,17 @@ namespace llarp using User_ptr = std::shared_ptr< User >; using DecryptHandler = std::function< void(llarp_buffer_t*, User_ptr) >; - static void - Decrypt(void* user) + void + Decrypt(User_ptr user) { - auto* ctx = static_cast< AsyncFrameDecrypter< User >* >(user); - - if(ctx->target.DecryptInPlace(ctx->seckey)) + if(target.DecryptInPlace(seckey)) { - auto buf = ctx->target.Buffer(); + auto buf = target.Buffer(); buf->cur = buf->base + EncryptedFrameOverheadSize; - ctx->result(buf, ctx->user); + result(buf, user); } else - ctx->result(nullptr, ctx->user); - ctx->user = nullptr; + result(nullptr, user); } AsyncFrameDecrypter(const SecretKey& secretkey, DecryptHandler h) @@ -80,7 +77,6 @@ namespace llarp } DecryptHandler result; - User_ptr user; const SecretKey& seckey; EncryptedFrame target; @@ -89,8 +85,7 @@ namespace llarp const EncryptedFrame& frame, User_ptr u) { target = frame; - user = u; - worker->addJob(std::bind(&Decrypt, this)); + worker->addJob(std::bind(&Decrypt, this, u)); } }; } // namespace llarp From b8f773eb73a9e389ddfaabe73a9f62cf15606822 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 20 Nov 2019 10:02:57 -0500 Subject: [PATCH 11/58] use lambda --- llarp/crypto/encrypted_frame.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/crypto/encrypted_frame.hpp b/llarp/crypto/encrypted_frame.hpp index 94585ebd3..0c4712905 100644 --- a/llarp/crypto/encrypted_frame.hpp +++ b/llarp/crypto/encrypted_frame.hpp @@ -85,7 +85,7 @@ namespace llarp const EncryptedFrame& frame, User_ptr u) { target = frame; - worker->addJob(std::bind(&Decrypt, this, u)); + worker->addJob([self = this, user = u]() { self->Decrypt(user); }); } }; } // namespace llarp From 065b022427688143fa7c304ee580edaf6a2cbe51 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 20 Nov 2019 10:09:10 -0500 Subject: [PATCH 12/58] std::move --- llarp/crypto/encrypted_frame.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llarp/crypto/encrypted_frame.hpp b/llarp/crypto/encrypted_frame.hpp index 0c4712905..0beb62736 100644 --- a/llarp/crypto/encrypted_frame.hpp +++ b/llarp/crypto/encrypted_frame.hpp @@ -85,7 +85,8 @@ namespace llarp const EncryptedFrame& frame, User_ptr u) { target = frame; - worker->addJob([self = this, user = u]() { self->Decrypt(user); }); + worker->addJob( + [self = this, user = std::move(u)]() { self->Decrypt(user); }); } }; } // namespace llarp From 0ec4e583d479d44d488171012570870b0959591d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 20 Nov 2019 10:30:47 -0500 Subject: [PATCH 13/58] initialize with zeros --- llarp/net/address_info.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/net/address_info.hpp b/llarp/net/address_info.hpp index 7bbeaf1b3..b528439e3 100644 --- a/llarp/net/address_info.hpp +++ b/llarp/net/address_info.hpp @@ -23,7 +23,7 @@ namespace llarp uint16_t rank; std::string dialect; llarp::PubKey pubkey; - struct in6_addr ip; + in6_addr ip = {0}; uint16_t port; uint64_t version = LLARP_PROTO_VERSION; From ac686a9329fc30d129e14e4178e65f5819b3dcaa Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 20 Nov 2019 11:10:52 -0500 Subject: [PATCH 14/58] remove valgrind access errors --- llarp/CMakeLists.txt | 1 - llarp/iwp/session.cpp | 61 ++++---- llarp/iwp/session.hpp | 5 +- llarp/net/exit_info.hpp | 4 +- llarp/net/net.cpp | 2 +- llarp/net/net.hpp | 1 - llarp/net/net_addr.cpp | 24 ++- llarp/net/net_addr.hpp | 2 +- llarp/net/net_inaddr.cpp | 228 ----------------------------- llarp/net/net_inaddr.hpp | 81 ---------- test/CMakeLists.txt | 1 - test/net/test_llarp_net.cpp | 1 - test/net/test_llarp_net_inaddr.cpp | 106 -------------- 13 files changed, 57 insertions(+), 460 deletions(-) delete mode 100644 llarp/net/net_inaddr.cpp delete mode 100644 llarp/net/net_inaddr.hpp delete mode 100644 test/net/test_llarp_net_inaddr.cpp diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 9acbf75c6..8e092160b 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -82,7 +82,6 @@ set(LIB_PLATFORM_SRC net/ip.cpp net/net.cpp net/net_addr.cpp - net/net_inaddr.cpp net/net_int.cpp # for android shim ${ANDROID_PLATFORM_SRC} diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index e1f75a9d1..7641bad92 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -28,14 +28,15 @@ namespace llarp return pkt; } - Session::Session(LinkLayer* p, RouterContact rc, AddressInfo ai) + Session::Session(LinkLayer* p, const RouterContact& rc, + const AddressInfo& ai) : m_State{State::Initial} , m_Inbound{false} - , m_Parent{p} + , m_Parent(p) , m_CreatedAt{p->Now()} - , m_RemoteAddr{ai} - , m_ChosenAI{std::move(ai)} - , m_RemoteRC{std::move(rc)} + , m_RemoteAddr(ai) + , m_ChosenAI(ai) + , m_RemoteRC(rc) { token.Zero(); GotLIM = util::memFn(&Session::GotOutboundLIM, this); @@ -43,12 +44,12 @@ namespace llarp llarp_buffer_t(rc.pubkey)); } - Session::Session(LinkLayer* p, Addr from) + Session::Session(LinkLayer* p, const Addr& from) : m_State{State::Initial} , m_Inbound{true} - , m_Parent{p} + , m_Parent(p) , m_CreatedAt{p->Now()} - , m_RemoteAddr{from} + , m_RemoteAddr(from) { token.Randomize(); GotLIM = util::memFn(&Session::GotInboundLIM, this); @@ -145,8 +146,10 @@ namespace llarp Session::EncryptWorker(CryptoQueue_ptr msgs) { LogDebug("encrypt worker ", msgs->size(), " messages"); - for(auto& pkt : *msgs) + auto itr = msgs->begin(); + while(itr != msgs->end()) { + Packet_t pkt = std::move(*itr); llarp_buffer_t pktbuf(pkt); const TunnelNonce nonce_ptr{pkt.data() + HMACSIZE}; pktbuf.base += PacketOverhead; @@ -157,6 +160,7 @@ namespace llarp pktbuf.sz = pkt.size() - HMACSIZE; CryptoManager::instance()->hmac(pkt.data(), pktbuf, m_SessionKey); Send_LL(pkt.data(), pkt.size()); + ++itr; } } @@ -359,24 +363,27 @@ namespace llarp { TunnelNonce N; N.Randomize(); - ILinkSession::Packet_t req(Introduction::SIZE + PacketOverhead); - const auto pk = m_Parent->GetOurRC().pubkey; - const auto e_pk = m_Parent->RouterEncryptionSecret().toPublic(); - auto itr = req.data() + PacketOverhead; - std::copy_n(pk.data(), pk.size(), itr); - itr += pk.size(); - std::copy_n(e_pk.data(), e_pk.size(), itr); - itr += e_pk.size(); - std::copy_n(N.data(), N.size(), itr); - Signature Z; - llarp_buffer_t signbuf(req.data() + PacketOverhead, - Introduction::SIZE - Signature::SIZE); - m_Parent->Sign(Z, signbuf); - std::copy_n( - Z.data(), Z.size(), - req.data() + PacketOverhead + (Introduction::SIZE - Signature::SIZE)); - CryptoManager::instance()->randbytes(req.data() + HMACSIZE, TUNNONCESIZE); - EncryptAndSend(std::move(req)); + { + ILinkSession::Packet_t req(Introduction::SIZE + PacketOverhead); + const auto pk = m_Parent->GetOurRC().pubkey; + const auto e_pk = m_Parent->RouterEncryptionSecret().toPublic(); + auto itr = req.data() + PacketOverhead; + std::copy_n(pk.data(), pk.size(), itr); + itr += pk.size(); + std::copy_n(e_pk.data(), e_pk.size(), itr); + itr += e_pk.size(); + std::copy_n(N.data(), N.size(), itr); + Signature Z; + llarp_buffer_t signbuf(req.data() + PacketOverhead, + Introduction::SIZE - Signature::SIZE); + m_Parent->Sign(Z, signbuf); + std::copy_n(Z.data(), Z.size(), + req.data() + PacketOverhead + + (Introduction::SIZE - Signature::SIZE)); + CryptoManager::instance()->randbytes(req.data() + HMACSIZE, + TUNNONCESIZE); + EncryptAndSend(std::move(req)); + } m_State = State::Introduction; if(not CryptoManager::instance()->transport_dh_client( m_SessionKey, m_ChosenAI.pubkey, diff --git a/llarp/iwp/session.hpp b/llarp/iwp/session.hpp index 2c6f5d301..67b4ef0bf 100644 --- a/llarp/iwp/session.hpp +++ b/llarp/iwp/session.hpp @@ -39,9 +39,10 @@ namespace llarp static constexpr std::size_t MaxACKSInMACK = 1024 / sizeof(uint64_t); /// outbound session - Session(LinkLayer* parent, RouterContact rc, AddressInfo ai); + Session(LinkLayer* parent, const RouterContact& rc, + const AddressInfo& ai); /// inbound session - Session(LinkLayer* parent, Addr from); + Session(LinkLayer* parent, const Addr& from); ~Session() = default; diff --git a/llarp/net/exit_info.hpp b/llarp/net/exit_info.hpp index c1fe6f678..9a69d88ff 100644 --- a/llarp/net/exit_info.hpp +++ b/llarp/net/exit_info.hpp @@ -18,8 +18,8 @@ namespace llarp { struct ExitInfo { - struct in6_addr address; - struct in6_addr netmask; + in6_addr address = {0}; + in6_addr netmask = {0}; PubKey pubkey; uint64_t version = LLARP_PROTO_VERSION; diff --git a/llarp/net/net.cpp b/llarp/net/net.cpp index f737980d7..a00d6d452 100644 --- a/llarp/net/net.cpp +++ b/llarp/net/net.cpp @@ -1078,7 +1078,7 @@ namespace llarp { char buf[INET6_ADDRSTRLEN + 1] = {0}; std::string str; - in6_addr inaddr; + in6_addr inaddr = {0}; size_t numset = 0; absl::uint128 bits = netmask_bits.h; while(bits) diff --git a/llarp/net/net.hpp b/llarp/net/net.hpp index b1b4e6d80..d11934f89 100644 --- a/llarp/net/net.hpp +++ b/llarp/net/net.hpp @@ -191,6 +191,5 @@ namespace llarp } // namespace llarp #include -#include #endif diff --git a/llarp/net/net_addr.cpp b/llarp/net/net_addr.cpp index bed44a9c6..6145c6cfd 100644 --- a/llarp/net/net_addr.cpp +++ b/llarp/net/net_addr.cpp @@ -16,7 +16,13 @@ namespace llarp { - Addr::Addr() = default; + Addr::Addr() + { + llarp::Zero(&_addr4, sizeof(_addr4)); + _addr4.sin_family = AF_INET; + llarp::Zero(&_addr, sizeof(_addr)); + _addr.sin6_family = AF_INET6; + } Addr::~Addr() = default; void @@ -53,18 +59,18 @@ namespace llarp return (const in_addr*)&_addr.sin6_addr.s6_addr[12]; } - Addr::Addr(string_view str) + Addr::Addr(string_view str) : Addr() { this->from_char_array(str); } - Addr::Addr(string_view str, const uint16_t p_port) + Addr::Addr(string_view str, const uint16_t p_port) : Addr() { this->from_char_array(str); this->port(p_port); } - Addr::Addr(string_view addr_str, string_view port_str) + Addr::Addr(string_view addr_str, string_view port_str) : Addr() { this->from_char_array(string_view_string(addr_str).c_str()); this->port(std::strtoul(string_view_string(port_str).c_str(), nullptr, 10)); @@ -174,18 +180,20 @@ namespace llarp Addr::Addr(const uint8_t one, const uint8_t two, const uint8_t three, const uint8_t four) + : Addr() { this->from_4int(one, two, three, four); } Addr::Addr(const uint8_t one, const uint8_t two, const uint8_t three, const uint8_t four, const uint16_t p_port) + : Addr() { this->from_4int(one, two, three, four); this->port(p_port); } - Addr::Addr(const AddressInfo& other) + Addr::Addr(const AddressInfo& other) : Addr() { memcpy(addr6(), other.ip.s6_addr, 16); _addr.sin6_port = htons(other.port); @@ -200,7 +208,7 @@ namespace llarp _addr.sin6_family = AF_INET6; } - Addr::Addr(const sockaddr_in& other) + Addr::Addr(const sockaddr_in& other) : Addr() { Zero(&_addr, sizeof(sockaddr_in6)); _addr.sin6_family = AF_INET; @@ -217,7 +225,7 @@ namespace llarp memcpy(&_addr4.sin_addr.s_addr, addr4(), sizeof(in_addr)); } - Addr::Addr(const sockaddr_in6& other) + Addr::Addr(const sockaddr_in6& other) : Addr() { memcpy(addr6(), other.sin6_addr.s6_addr, 16); _addr.sin6_port = htons(other.sin6_port); @@ -236,7 +244,7 @@ namespace llarp _addr.sin6_family = AF_INET6; } - Addr::Addr(const sockaddr& other) + Addr::Addr(const sockaddr& other) : Addr() { Zero(&_addr, sizeof(sockaddr_in6)); _addr.sin6_family = other.sa_family; diff --git a/llarp/net/net_addr.hpp b/llarp/net/net_addr.hpp index 75e137b87..62e6ff150 100644 --- a/llarp/net/net_addr.hpp +++ b/llarp/net/net_addr.hpp @@ -16,7 +16,7 @@ namespace llarp { // network order sockaddr_in6 _addr; - sockaddr_in _addr4; // why do we even have this? favor cpu over memory + sockaddr_in _addr4; ~Addr(); Addr(); diff --git a/llarp/net/net_inaddr.cpp b/llarp/net/net_inaddr.cpp deleted file mode 100644 index 1617bf3a3..000000000 --- a/llarp/net/net_inaddr.cpp +++ /dev/null @@ -1,228 +0,0 @@ -#include - -std::ostream& -operator<<(std::ostream& out, const llarp::inAddr& a) -{ - char tmp[128] = {0}; - if(a.isIPv6Mode()) - { - out << "["; - } - if(inet_ntop(a.isIPv4Mode() ? AF_INET : AF_INET6, (void*)&a._addr, tmp, - sizeof(tmp))) - { - out << tmp; - if(a.isIPv6Mode()) - out << "]"; - } - return out; -} - -namespace llarp -{ - void - inAddr::reset() - { - llarp::Zero(&this->_addr, sizeof(in6_addr)); - } - - bool - inAddr::from_char_array(const char* str) - { - this->reset(); - - // maybe refactor the family detection out - struct addrinfo hint, *res = nullptr; - int ret; - - memset(&hint, '\0', sizeof hint); - - hint.ai_family = PF_UNSPEC; - hint.ai_flags = AI_NUMERICHOST; - - ret = getaddrinfo(str, nullptr, &hint, &res); - if(ret) - { - llarp::LogError("failed to determine address family: ", str); - return false; - } - - if(res->ai_family != AF_INET && res->ai_family != AF_INET6) - { - llarp::LogError("Address family not supported yet", str); - return false; - } - - // convert detected-family (ipv4 or ipv6) str to in6_addr - - /* - if (res->ai_family == AF_INET) - { - freeaddrinfo(res); - // get IPv4 - struct in_addr addr; // basically a uint32_t network order - if(inet_aton(str, &addr) == 0) - { - llarp::LogError("failed to parse ", str); - return false; - } - nuint32_t result; - result.n = addr.s_addr; - this->fromN32(result); - return true; - } - */ - - ret = inet_pton(res->ai_family, str, &this->_addr); - // inet_pton won't set SIIT - // this->hexDebug(); - freeaddrinfo(res); - if(ret <= 0) - { - if(ret == 0) - { - llarp::LogWarn("Not in presentation format"); - return false; - } - - llarp::LogWarn("inet_pton failure"); - return false; - } - return true; - } - - void - inAddr::fromSIIT() - { - if(ipv6_is_siit(this->_addr)) - { - this->_addr.s6_addr[0] = this->_addr.s6_addr[12]; - this->_addr.s6_addr[1] = this->_addr.s6_addr[13]; - this->_addr.s6_addr[2] = this->_addr.s6_addr[14]; - this->_addr.s6_addr[3] = this->_addr.s6_addr[15]; - this->setIPv4Mode(); - } - } - - void - inAddr::toSIIT() - { - if(!ipv6_is_siit(this->_addr)) - { - this->_addr.s6_addr[10] = 0xff; - this->_addr.s6_addr[11] = 0xff; - this->_addr.s6_addr[12] = this->_addr.s6_addr[0]; - this->_addr.s6_addr[13] = this->_addr.s6_addr[1]; - this->_addr.s6_addr[14] = this->_addr.s6_addr[2]; - this->_addr.s6_addr[15] = this->_addr.s6_addr[3]; - llarp::Zero(&this->_addr, sizeof(in6_addr) - 6); - } - } - - inline bool - inAddr::isIPv6Mode() const - { - return !this->isIPv4Mode(); - } - - bool - inAddr::isIPv4Mode() const - { - return ipv6_is_siit(this->_addr) - || (this->_addr.s6_addr[4] == 0 && this->_addr.s6_addr[5] == 0 - && this->_addr.s6_addr[6] == 0 && this->_addr.s6_addr[7] == 0 - && this->_addr.s6_addr[8] == 0 && this->_addr.s6_addr[9] == 0 - && this->_addr.s6_addr[10] == 0 && this->_addr.s6_addr[11] == 0 - && this->_addr.s6_addr[12] == 0 && this->_addr.s6_addr[13] == 0 - && this->_addr.s6_addr[14] == 0 && this->_addr.s6_addr[15] == 0); - } - - void - inAddr::setIPv4Mode() - { - // keep first 4 - // llarp::Zero(&this->_addr + 4, sizeof(in6_addr) - 4); - this->_addr.s6_addr[4] = 0; - this->_addr.s6_addr[5] = 0; - this->_addr.s6_addr[6] = 0; - this->_addr.s6_addr[7] = 0; - this->_addr.s6_addr[8] = 0; - this->_addr.s6_addr[9] = 0; - this->_addr.s6_addr[10] = 0; - this->_addr.s6_addr[11] = 0; - this->_addr.s6_addr[12] = 0; - this->_addr.s6_addr[13] = 0; - this->_addr.s6_addr[14] = 0; - this->_addr.s6_addr[15] = 0; - } - - void - inAddr::hexDebug() - { - char hex_buffer[16 * 3 + 1]; - hex_buffer[16 * 3] = 0; - for(unsigned int j = 0; j < 16; j++) - sprintf(&hex_buffer[3 * j], "%02X ", this->_addr.s6_addr[j]); - printf("in6_addr: [%s]\n", hex_buffer); - } - - // - // IPv4 specific functions - // - - in_addr - inAddr::toIAddr() - { - in_addr res; - res.s_addr = toN32().n; - return res; - } - - void - inAddr::from4int(const uint8_t one, const uint8_t two, const uint8_t three, - const uint8_t four) - { - this->reset(); - this->setIPv4Mode(); - // Network byte order - this->_addr.s6_addr[0] = one; - this->_addr.s6_addr[1] = two; - this->_addr.s6_addr[2] = three; - this->_addr.s6_addr[3] = four; - } - - void - inAddr::fromN32(nuint32_t in) - { - this->reset(); - this->setIPv4Mode(); - memcpy(&this->_addr, &in.n, sizeof(uint32_t)); - } - void - inAddr::fromH32(huint32_t in) - { - this->fromN32(xhtonl(in)); - } - - nuint32_t - inAddr::toN32() - { - nuint32_t result; - result.n = 0; // return 0 for IPv6 - if(this->isIPv4Mode()) - { - memcpy(&result.n, &this->_addr, sizeof(uint32_t)); - } - return result; - } - huint32_t - inAddr::toH32() - { - return xntohl(this->toN32()); - } - - // - // IPv6 specific functions - // - -} // namespace llarp diff --git a/llarp/net/net_inaddr.hpp b/llarp/net/net_inaddr.hpp deleted file mode 100644 index 23155e391..000000000 --- a/llarp/net/net_inaddr.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef LLARP_NET_INADDR_HPP -#define LLARP_NET_INADDR_HPP - -#include - -namespace llarp -{ - /// IPv4 or IPv6 holder - struct inAddr - { - // unsigned char s6_addr[16]; - struct in6_addr _addr; // store in network order - - /// zero out - void - reset(); - - /// from char* - bool - from_char_array(const char* str); - - /// convert from SIIT to IPv4 Mode - void - fromSIIT(); - - /// convert from IPv4 Mode to SIIT - void - toSIIT(); - - /// not IPv4 Mode (an actual IPv6 address) - inline bool - isIPv6Mode() const; - - /// IPv4 mode (not SIIT) - bool - isIPv4Mode() const; - - /// clear out bytes 5-15 (Last 12 bytes) - /// This is how inet_pton works with IPv4 addresses - void - setIPv4Mode(); - - /// make debugging/testing easier - void - hexDebug(); - - // - // IPv4 specific functions - // - - /// make ipv4 in_addr struct - in_addr - toIAddr(); - - /// set an IPv4 addr - void - from4int(const uint8_t one, const uint8_t two, const uint8_t three, - const uint8_t four); - - /// set from an net-order uint32_t - void - fromN32(nuint32_t in); - /// set from an host-order uint32_t - void - fromH32(huint32_t in); - /// output as net-order uint32_t - nuint32_t - toN32(); - /// output as host-order uint32_t - huint32_t - toH32(); - - // - // IPv6 specific functions - // - // coming soon - }; - -} // namespace llarp - -#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b7feec249..37ebcec9f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,7 +18,6 @@ list(APPEND TEST_SRC exit/test_llarp_exit_context.cpp link/test_llarp_link.cpp llarp_test.cpp - net/test_llarp_net_inaddr.cpp net/test_llarp_net.cpp routing/llarp_routing_transfer_traffic.cpp routing/test_llarp_routing_obtainexitmessage.cpp diff --git a/test/net/test_llarp_net.cpp b/test/net/test_llarp_net.cpp index 564ae524c..44472d60a 100644 --- a/test/net/test_llarp_net.cpp +++ b/test/net/test_llarp_net.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/test/net/test_llarp_net_inaddr.cpp b/test/net/test_llarp_net_inaddr.cpp deleted file mode 100644 index 43c7387e5..000000000 --- a/test/net/test_llarp_net_inaddr.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include - -#include - -struct TestNetInAddr : public ::testing::Test -{ -}; - -TEST_F(TestNetInAddr, TestinAddrFrom4Int) -{ - llarp::inAddr test; - test.from4int(127, 0, 0, 1); - char str[INET6_ADDRSTRLEN]; - if(inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) - { - ASSERT_TRUE(false); - } - ASSERT_TRUE(strcmp("127.0.0.1", str) == 0); -} - -TEST_F(TestNetInAddr, TestinAddrFromStr) -{ - llarp::inAddr test; - test.from_char_array("127.0.0.1"); - char str[INET6_ADDRSTRLEN]; - if(inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) - { - ASSERT_TRUE(false); - } - ASSERT_TRUE(strcmp("127.0.0.1", str) == 0); -} - -TEST_F(TestNetInAddr, TestinAddrReset) -{ - llarp::inAddr test; - test.from_char_array("127.0.0.1"); - test.reset(); - char str[INET6_ADDRSTRLEN]; - if(inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) - { - ASSERT_TRUE(false); - } - ASSERT_TRUE(strcmp("0.0.0.0", str) == 0); -} - -TEST_F(TestNetInAddr, TestinAddrModeSet) -{ - llarp::inAddr test; - test.from_char_array("127.0.0.1"); - // test.hexDebug(); - ASSERT_TRUE(test.isIPv4Mode()); - - // corrupt it - test._addr.s6_addr[10] = 0xfe; - test._addr.s6_addr[11] = 0xfe; - - test.setIPv4Mode(); - // test.hexDebug(); - ASSERT_TRUE(test.isIPv4Mode()); -} - -TEST_F(TestNetInAddr, TestinAddrSIIT) -{ - llarp::inAddr test; - test.from_char_array("127.0.0.1"); - - test.toSIIT(); - // test.hexDebug(); - ASSERT_TRUE(llarp::ipv6_is_siit(test._addr)); - - test.fromSIIT(); - // test.hexDebug(); - ASSERT_TRUE(!llarp::ipv6_is_siit(test._addr)); -} - -TEST_F(TestNetInAddr, TestinAddrN32) -{ - llarp::inAddr test; - test.from_char_array("127.0.0.1"); - llarp::nuint32_t netOrder = test.toN32(); - llarp::inAddr test2; - test2.fromN32(netOrder); - char str[INET6_ADDRSTRLEN]; - if(inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL) - { - ASSERT_TRUE(false); - } - // printf("[%s]\n", str); - ASSERT_TRUE(strcmp("127.0.0.1", str) == 0); -} - -TEST_F(TestNetInAddr, TestinAddrH32) -{ - llarp::inAddr test; - test.from_char_array("127.0.0.1"); - llarp::huint32_t netOrder = test.toH32(); - llarp::inAddr test2; - test2.fromH32(netOrder); - char str[INET6_ADDRSTRLEN]; - if(inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL) - { - ASSERT_TRUE(false); - } - // printf("[%s]\n", str); - ASSERT_TRUE(strcmp("127.0.0.1", str) == 0); -} From 6f95fbfece1ba6a385cd4d71860c55707996067e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 20 Nov 2019 14:45:23 -0500 Subject: [PATCH 15/58] work in progress --- llarp/ev/ev_libuv.cpp | 34 ++++++++++++++++++++++--------- llarp/handlers/exit.cpp | 15 +++++++++++--- llarp/handlers/exit.hpp | 2 +- llarp/handlers/tun.cpp | 45 ++++++++++++++++++++++++----------------- llarp/handlers/tun.hpp | 3 +++ 5 files changed, 67 insertions(+), 32 deletions(-) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 2055126d0..49d725dc9 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -424,8 +424,11 @@ namespace libuv Close() override { uv_check_stop(&m_Ticker); - m_Ticker.data = nullptr; - delete this; + uv_close((uv_handle_t*)&m_Ticker, [](auto h) { + ticker_glue* self = (ticker_glue*)h->data; + h->data = nullptr; + delete self; + }); } uv_check_t m_Ticker; @@ -663,7 +666,7 @@ namespace libuv OnTick(uv_check_t* timer) { tun_glue* tun = static_cast< tun_glue* >(timer->data); - LoopCall(timer, std::bind(&tun_glue::Tick, tun)); + tun->Tick(); } static void @@ -682,7 +685,7 @@ namespace libuv if(sz > 0) { llarp::LogDebug("tun read ", sz); - llarp_buffer_t pkt(m_Buffer, sz); + const llarp_buffer_t pkt(m_Buffer, sz); if(m_Tun && m_Tun->recvpkt) m_Tun->recvpkt(m_Tun, pkt); } @@ -711,9 +714,14 @@ namespace libuv void Close() override { + if(m_Tun->impl == nullptr) + return; m_Tun->impl = nullptr; uv_check_stop(&m_Ticker); - uv_close((uv_handle_t*)&m_Handle, &OnClosed); + uv_close((uv_handle_t*)&m_Ticker, [](uv_handle_t* h) { + tun_glue* glue = static_cast< tun_glue* >(h->data); + uv_close((uv_handle_t*)&glue->m_Handle, &OnClosed); + }); } bool @@ -824,18 +832,24 @@ namespace libuv int Loop::tick(int ms) { - uv_timer_start(&m_TickTimer, &OnTickTimeout, ms, 0); - uv_run(&m_Impl, UV_RUN_ONCE); + if(m_Run) + { + uv_timer_start(&m_TickTimer, &OnTickTimeout, ms, 0); + uv_run(&m_Impl, UV_RUN_ONCE); + } return 0; } void Loop::stop() { - uv_stop(&m_Impl); - llarp::LogInfo("stopping event loop"); + if(m_Run) + { + llarp::LogInfo("stopping event loop"); + CloseAll(); + // uv_stop(&m_Impl); + } m_Run.store(false); - CloseAll(); } void diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index c8d5431c5..7c5c490d6 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -16,7 +16,13 @@ namespace llarp static void ExitHandlerRecvPkt(llarp_tun_io *tun, const llarp_buffer_t &buf) { - static_cast< ExitEndpoint * >(tun->user)->OnInetPacket(buf); + std::vector< byte_t > pkt; + pkt.resize(buf.sz); + std::copy_n(buf.base, buf.sz, pkt.data()); + auto self = static_cast< ExitEndpoint * >(tun->user); + LogicCall(self->GetRouter()->logic(), [self, pktbuf = std::move(pkt)]() { + self->OnInetPacket(std::move(pktbuf)); + }); } static void @@ -457,10 +463,13 @@ namespace llarp } void - ExitEndpoint::OnInetPacket(const llarp_buffer_t &buf) + ExitEndpoint::OnInetPacket(std::vector< byte_t > buf) { + const llarp_buffer_t buffer(buf); m_InetToNetwork.EmplaceIf( - [b = ManagedBuffer(buf)](Pkt_t &pkt) -> bool { return pkt.Load(b); }); + [b = ManagedBuffer(buffer)](Pkt_t &pkt) -> bool { + return pkt.Load(b); + }); } bool diff --git a/llarp/handlers/exit.hpp b/llarp/handlers/exit.hpp index 21a499160..170535fa5 100644 --- a/llarp/handlers/exit.hpp +++ b/llarp/handlers/exit.hpp @@ -57,7 +57,7 @@ namespace llarp /// handle ip packet from outside void - OnInetPacket(const llarp_buffer_t& buf); + OnInetPacket(std::vector< byte_t > buf); AbstractRouter* GetRouter(); diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index cdd538094..40e9e842f 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -32,11 +32,11 @@ namespace llarp m_NetworkToUserPktQueue.Process(send); } - static void - tunifTick(llarp_tun_io *tun) + void + TunEndpoint::tunifTick(llarp_tun_io *tun) { auto *self = static_cast< TunEndpoint * >(tun->user); - self->Flush(); + LogicCall(self->m_router->logic(), [self]() { self->Flush(); }); } TunEndpoint::TunEndpoint(const std::string &nickname, AbstractRouter *r, @@ -308,13 +308,20 @@ namespace llarp void TunEndpoint::Flush() { - auto self = shared_from_this(); - FlushSend(); - LogicCall(RouterLogic(), [=] { + static const auto func = [](auto self) { + self->FlushSend(); self->m_ExitMap.ForEachValue( [](const auto &exit) { exit->FlushUpstream(); }); self->Pump(self->Now()); - }); + }; + if(NetworkIsIsolated()) + { + LogicCall(RouterLogic(), std::bind(func, shared_from_this())); + } + else + { + func(this); + } } static bool @@ -749,13 +756,11 @@ namespace llarp void TunEndpoint::Tick(llarp_time_t now) { - LogicCall(EndpointLogic(), [&]() { - m_ExitMap.ForEachValue([&](const auto &exit) { - this->EnsureRouterIsKnown(exit->Endpoint()); - exit->Tick(now); - }); - Endpoint::Tick(now); + m_ExitMap.ForEachValue([&](const auto &exit) { + this->EnsureRouterIsKnown(exit->Endpoint()); + exit->Tick(now); }); + Endpoint::Tick(now); } bool @@ -983,8 +988,7 @@ namespace llarp return false; }; LogicCall(self->EndpointLogic(), - std::bind(&TunEndpoint::FlushToUser, self->shared_from_this(), - sendpkt)); + std::bind(&TunEndpoint::FlushToUser, self, sendpkt)); } void @@ -992,9 +996,14 @@ namespace llarp { // called for every packet read from user in isolated network thread auto *self = static_cast< TunEndpoint * >(tun->user); - const ManagedBuffer pkt(b); - self->m_UserToNetworkPktQueue.EmplaceIf( - [&pkt](net::IPPacket &p) -> bool { return p.Load(pkt); }); + std::vector< byte_t > pkt; + pkt.resize(b.sz); + std::copy_n(b.base, b.sz, pkt.data()); + LogicCall(self->RouterLogic(), [self, buffer = std::move(pkt)]() { + const llarp_buffer_t pbuf(buffer); + self->m_UserToNetworkPktQueue.EmplaceIf( + [&pbuf](net::IPPacket &p) -> bool { return p.Load(pbuf); }); + }); } TunEndpoint::~TunEndpoint() = default; diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index fc48ec547..2889e7a5d 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -56,6 +56,9 @@ namespace llarp void TickTun(llarp_time_t now); + static void + tunifTick(llarp_tun_io*); + bool MapAddress(const service::Address& remote, huint128_t ip, bool SNode); From 34bc3da0694e559e5413176f4df7af11309ac9da Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 21 Nov 2019 09:34:30 -0500 Subject: [PATCH 16/58] flush quues of other paths --- llarp/path/transit_hop.cpp | 8 ++++++++ llarp/path/transit_hop.hpp | 2 ++ 2 files changed, 10 insertions(+) diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index f207dd462..6e21bca9d 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -173,6 +173,11 @@ namespace llarp m_LastActivity = r->Now(); } FlushDownstream(r); + for(const auto& other : m_FlushOthers) + { + other->FlushUpstream(r); + } + m_FlushOthers.clear(); } else { @@ -410,7 +415,10 @@ namespace llarp buf.cur = buf.base; // send if(path->HandleDownstream(buf, msg.Y, r)) + { + m_FlushOthers.emplace(path); return true; + } return SendRoutingMessage(discarded, r); } diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 008ec7841..88e2ad432 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -222,6 +222,8 @@ namespace llarp void QueueDestroySelf(AbstractRouter* r); + + std::set< HopHandler_ptr, ComparePtr< HopHandler_Ptr > > m_FlushOthers; }; inline std::ostream& From c3858a56df9fe99c0f7305b45ef22dd11c36d212 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 21 Nov 2019 09:48:31 -0500 Subject: [PATCH 17/58] make it compile --- llarp/path/path_context.cpp | 4 ++-- llarp/path/path_context.hpp | 2 +- llarp/path/transit_hop.hpp | 11 ++++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp index e41de0e4b..addf663cd 100644 --- a/llarp/path/path_context.cpp +++ b/llarp/path/path_context.cpp @@ -239,10 +239,10 @@ namespace llarp return m_Router; } - HopHandler_ptr + TransitHop_ptr PathContext::GetPathForTransfer(const PathID_t& id) { - RouterID us(OurRouterID()); + const RouterID us(OurRouterID()); auto& map = m_TransitPaths; { SyncTransitMap_t::Lock_t lock(&map.first); diff --git a/llarp/path/path_context.hpp b/llarp/path/path_context.hpp index 8b7c48179..6b5b27ceb 100644 --- a/llarp/path/path_context.hpp +++ b/llarp/path/path_context.hpp @@ -67,7 +67,7 @@ namespace llarp bool TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r); - HopHandler_ptr + TransitHop_ptr GetPathForTransfer(const PathID_t& topath); HopHandler_ptr diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 88e2ad432..60300b541 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace llarp { @@ -96,6 +97,12 @@ namespace llarp bool destroy = false; + bool + operator<(const TransitHop& other) const + { + return info < other.info; + } + bool IsEndpoint(const RouterID& us) const { @@ -223,7 +230,9 @@ namespace llarp void QueueDestroySelf(AbstractRouter* r); - std::set< HopHandler_ptr, ComparePtr< HopHandler_Ptr > > m_FlushOthers; + std::set< std::shared_ptr< TransitHop >, + ComparePtr< std::shared_ptr< TransitHop > > > + m_FlushOthers; }; inline std::ostream& From cbb7196b3003be1175205495a0fae2dd4b84c311 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 25 Nov 2019 11:53:03 -0500 Subject: [PATCH 18/58] fix "zero hop" bug --- llarp/router/outbound_session_maker.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/llarp/router/outbound_session_maker.cpp b/llarp/router/outbound_session_maker.cpp index 4a536f81a..8c6ed024b 100644 --- a/llarp/router/outbound_session_maker.cpp +++ b/llarp/router/outbound_session_maker.cpp @@ -123,11 +123,6 @@ namespace llarp int remainingDesired = numDesired; _nodedb->visit([&](const RouterContact &other) -> bool { - // check if we really remainingDesired to - if(other.ExpiresSoon(now, 30000)) // TODO: make delta configurable - { - return remainingDesired > 0; - } if(!_rcLookup->RemoteIsAllowed(other.pubkey)) { return remainingDesired > 0; From 853108ce6ea908e137156509fa691bb59a3d2e98 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 25 Nov 2019 16:15:31 -0500 Subject: [PATCH 19/58] make logic job queue 8 times bigger --- llarp/util/thread/threadpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/util/thread/threadpool.h b/llarp/util/thread/threadpool.h index 43936222f..6581b1c66 100644 --- a/llarp/util/thread/threadpool.h +++ b/llarp/util/thread/threadpool.h @@ -19,7 +19,7 @@ struct llarp_threadpool std::unique_ptr< llarp::thread::ThreadPool > impl; llarp_threadpool(int workers, llarp::string_view name, - size_t queueLength = size_t{1024}) + size_t queueLength = size_t{1024 * 8}) : impl(std::make_unique< llarp::thread::ThreadPool >( workers, std::max(queueLength, size_t{32}), name)) { From dd48b149ca94b7870138c431b1e07c317c177d1a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 25 Nov 2019 16:30:34 -0500 Subject: [PATCH 20/58] make job queue size configurable --- llarp/config/config.cpp | 9 +++++++++ llarp/config/config.hpp | 3 +++ llarp/context.cpp | 5 ++++- llarp/util/thread/logic.cpp | 4 ++-- llarp/util/thread/logic.hpp | 2 +- llarp/util/thread/threadpool.cpp | 4 ++-- llarp/util/thread/threadpool.h | 2 +- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 0ba2b968b..5aa92b9b2 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -51,6 +51,15 @@ namespace llarp void RouterConfig::fromSection(string_view key, string_view val) { + if(key == "job-queue-size") + { + auto sval = svtoi(val); + if(sval >= 1024) + { + m_JobQueueSize = sval; + LogInfo("Set job queue size to ", m_JobQueueSize); + } + } if(key == "default-protocol") { m_DefaultLinkProto = tostr(val); diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 83d059df0..51dca57e3 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -121,10 +121,13 @@ namespace llarp int m_workerThreads = 1; int m_numNetThreads = 1; + size_t m_JobQueueSize = size_t{1024 * 8}; + std::string m_DefaultLinkProto = "iwp"; public: // clang-format off + size_t jobQueueSize() const { return fromEnv(m_JobQueueSize, "JOB_QUEUE_SIZE"); } 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"); } diff --git a/llarp/context.cpp b/llarp/context.cpp index 2e79d03bd..3e1c825e3 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -51,7 +51,6 @@ namespace llarp bool Context::Configure() { - logic = std::make_shared< Logic >(); // llarp::LogInfo("loading config at ", configfile); if(configfile.size()) { @@ -73,6 +72,10 @@ namespace llarp threads = 1; worker = std::make_shared< llarp::thread::ThreadPool >(threads, 1024, "llarp-worker"); + auto jobQueueSize = config->router.jobQueueSize(); + if(jobQueueSize < 1024) + jobQueueSize = 1024; + logic = std::make_shared< Logic >(jobQueueSize); nodedb_dir = config->netdb.nodedbDir(); diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index ba53e7bd6..6a960d6d6 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -13,8 +13,8 @@ namespace llarp llarp_timer_tick_all_async(m_Timer, m_Thread, now); } - Logic::Logic() - : m_Thread(llarp_init_threadpool(1, "llarp-logic")) + Logic::Logic(size_t sz) + : m_Thread(llarp_init_threadpool(1, "llarp-logic", sz)) , m_Timer(llarp_init_timer()) { llarp_threadpool_start(m_Thread); diff --git a/llarp/util/thread/logic.hpp b/llarp/util/thread/logic.hpp index 7d3ed2bb2..465b8e8b5 100644 --- a/llarp/util/thread/logic.hpp +++ b/llarp/util/thread/logic.hpp @@ -11,7 +11,7 @@ namespace llarp class Logic { public: - Logic(); + Logic(size_t queueLength = size_t{1024 * 8}); ~Logic(); diff --git a/llarp/util/thread/threadpool.cpp b/llarp/util/thread/threadpool.cpp index 715271cec..ead887723 100644 --- a/llarp/util/thread/threadpool.cpp +++ b/llarp/util/thread/threadpool.cpp @@ -8,11 +8,11 @@ #include struct llarp_threadpool * -llarp_init_threadpool(int workers, const char *name) +llarp_init_threadpool(int workers, const char *name, size_t queueLength) { if(workers <= 0) workers = 1; - return new llarp_threadpool(workers, name); + return new llarp_threadpool(workers, name, queueLength); } void diff --git a/llarp/util/thread/threadpool.h b/llarp/util/thread/threadpool.h index 6581b1c66..bc180a11f 100644 --- a/llarp/util/thread/threadpool.h +++ b/llarp/util/thread/threadpool.h @@ -48,7 +48,7 @@ struct llarp_threadpool #endif struct llarp_threadpool * -llarp_init_threadpool(int workers, const char *name); +llarp_init_threadpool(int workers, const char *name, size_t queueLength); void llarp_free_threadpool(struct llarp_threadpool **tp); From 3878ebd53492d4bf23a3c6b0241e7a409bea76dc Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 26 Nov 2019 16:58:20 -0500 Subject: [PATCH 21/58] use curl to fetch from lokid rpc the identity key --- CMakeLists.txt | 4 ++ llarp/CMakeLists.txt | 3 +- llarp/router/router.cpp | 93 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e22f4530..81b6b249c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,10 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) +if(NOT IOS AND NOT ANDROID) + find_package(CURL REQUIRED) +endif() + include(cmake/static_link_runtime.cmake) include(cmake/static_link.cmake) diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 8e092160b..4081dbbce 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -252,7 +252,8 @@ if(TESTNET) endif() add_library(${STATIC_LIB} STATIC ${LIB_SRC}) -target_link_libraries(${STATIC_LIB} PUBLIC cxxopts ${ABYSS_LIB} ${PLATFORM_LIB} ${UTIL_LIB} ${CRYPTOGRAPHY_LIB} ${FS_LIB}) +target_include_directories(${STATIC_LIB} PUBLIC ${CURL_INCLUDE_DIRS}) +target_link_libraries(${STATIC_LIB} PUBLIC cxxopts ${ABYSS_LIB} ${PLATFORM_LIB} ${UTIL_LIB} ${CRYPTOGRAPHY_LIB} ${FS_LIB} ${CURL_LIBRARIES}) if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") target_include_directories(${PLATFORM_LIB} SYSTEM PUBLIC /usr/local/include) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 17aacd206..f319cc637 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -28,8 +28,10 @@ #include #include #include -#if defined(RPI) || defined(ANDROID) +#if defined(ANDROID) || defined(IOS) #include +#else +#include #endif bool @@ -227,14 +229,97 @@ namespace llarp LogError(rcfile, " contains invalid RC"); } + static size_t + RecvIdentKey(char *ptr, size_t, size_t nmemb, void *userdata) + { + for(size_t idx = 0; idx < nmemb; idx++) + static_cast< std::vector< char > * >(userdata)->push_back(ptr[idx]); + return nmemb; + } + bool Router::EnsureIdentity() { if(!EnsureEncryptionKey()) return false; - if(usingSNSeed) - return llarp_loadServiceNodeIdentityKey(ident_keyfile, _identity); - + if(whitelistRouters) + { +#if defined(ANDROID) || defined(IOS) + LogError("running a service node on mobile device is not possible."); + return false; +#else + CURL *curl = curl_easy_init(); + if(curl) + { + CURLcode res; + std::stringstream ss; + ss << "http://" << lokidRPCAddr << "/json_rpc"; + const auto url = ss.str(); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY); + const auto auth = lokidRPCUser + ":" + lokidRPCPassword; + curl_easy_setopt(curl, CURLOPT_USERPWD, auth.c_str()); + curl_slist *list = nullptr; + list = curl_slist_append(list, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); + + nlohmann::json request = {{"id", "0"}, + {"jsonrpc", "2.0"}, + {"method", "get_service_node_privkey"}}; + const auto data = request.dump(); + std::vector< char > resp; + + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.size()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RecvIdentKey); + do + { + LogInfo("Getting Identity Keys from lokid..."); + res = curl_easy_perform(curl); + if(res == CURLE_OK) + { + try + { + auto j = nlohmann::json::parse(resp); + if(not j.is_object()) + continue; + + const auto itr = j.find("result"); + if(itr == j.end()) + continue; + if(not itr->is_object()) + continue; + const auto k = + (*itr)["service_node_ed25519_privkey"].get< std::string >(); + if(k.empty()) + continue; + if(not HexDecode(k.c_str(), _identity.data(), _identity.size())) + continue; + } + catch(nlohmann::json::exception &ex) + { + LogError("Bad response from lokid: ", ex.what()); + } + } + else + { + LogError("failed to get identity Keys"); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + } while(res != CURLE_OK); + curl_easy_cleanup(curl); + curl_slist_free_all(list); + LogInfo("Got Identity Keys from lokid"); + return true; + } + else + { + LogError("failed to init curl"); + return false; + } +#endif + } return llarp_findOrCreateIdentity(ident_keyfile, _identity); } From 61b75828f085bf1e170cf9f1ec27c788d1570eab Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 26 Nov 2019 17:03:45 -0500 Subject: [PATCH 22/58] sleep --- llarp/router/router.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index f319cc637..50938c634 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -300,6 +300,7 @@ namespace llarp catch(nlohmann::json::exception &ex) { LogError("Bad response from lokid: ", ex.what()); + std::this_thread::sleep_for(std::chrono::seconds(1)); } } else From d12c75ce1ecffc4f996d60f16ce9c57bf0c6d430 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 26 Nov 2019 17:04:52 -0500 Subject: [PATCH 23/58] move sleep --- llarp/router/router.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 50938c634..b504373be 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -275,6 +275,7 @@ namespace llarp curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RecvIdentKey); do { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); LogInfo("Getting Identity Keys from lokid..."); res = curl_easy_perform(curl); if(res == CURLE_OK) @@ -300,13 +301,11 @@ namespace llarp catch(nlohmann::json::exception &ex) { LogError("Bad response from lokid: ", ex.what()); - std::this_thread::sleep_for(std::chrono::seconds(1)); } } else { LogError("failed to get identity Keys"); - std::this_thread::sleep_for(std::chrono::seconds(1)); } } while(res != CURLE_OK); curl_easy_cleanup(curl); From d6850577544309749629760acb8ac0c9609aa54c Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 26 Nov 2019 17:11:13 -0500 Subject: [PATCH 24/58] update readme and disable curl on windows --- CMakeLists.txt | 2 +- llarp/router/router.cpp | 8 ++++++++ readme.md | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81b6b249c..341054289 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,7 +188,7 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) -if(NOT IOS AND NOT ANDROID) +if(NOT IOS AND NOT ANDROID AND NOT WIN32) find_package(CURL REQUIRED) endif() diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index b504373be..a7a0bfc2e 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -31,8 +31,11 @@ #if defined(ANDROID) || defined(IOS) #include #else +#if defined(_WIN32) +#else #include #endif +#endif bool llarp_loadServiceNodeIdentityKey(const fs::path &fpath, @@ -247,6 +250,10 @@ namespace llarp #if defined(ANDROID) || defined(IOS) LogError("running a service node on mobile device is not possible."); return false; +#else +#if defined(_WIN32) + LogError("running a service node on windows is not possible."); + return false; #else CURL *curl = curl_easy_init(); if(curl) @@ -318,6 +325,7 @@ namespace llarp LogError("failed to init curl"); return false; } +#endif #endif } return llarp_findOrCreateIdentity(ident_keyfile, _identity); diff --git a/readme.md b/readme.md index 82f8816db..54c0bdf1a 100644 --- a/readme.md +++ b/readme.md @@ -71,12 +71,13 @@ Build requirements: * gcovr (if generating test coverage with gcc) * libuv >= 1.27.0 * libsodium (A patch that removes `undocumented system call` from the Win32 build is in `llarp/win32`.) +* libcurl ### Linux build: - $ sudo apt install build-essential cmake git libcap-dev curl libuv1-dev libsodium-dev + $ sudo apt install build-essential cmake git libcap-dev curl libuv1-dev libsodium-dev libcurl-dev $ git clone https://github.com/loki-project/loki-network $ cd loki-network $ make From 5868a25fcc8be7ea59591981b190559f02e5e43c Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 26 Nov 2019 17:13:41 -0500 Subject: [PATCH 25/58] clear response between tries --- llarp/router/router.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index a7a0bfc2e..da742b57f 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -282,6 +282,7 @@ namespace llarp curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RecvIdentKey); do { + resp.clear(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); LogInfo("Getting Identity Keys from lokid..."); res = curl_easy_perform(curl); From 098915bb8e753346c7da4e99856325ec0f03318f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 26 Nov 2019 20:40:55 -0500 Subject: [PATCH 26/58] add check for identity key validity --- llarp/crypto/crypto.hpp | 3 +++ llarp/crypto/crypto_libsodium.cpp | 13 +++++++++ llarp/crypto/crypto_libsodium.hpp | 3 +++ llarp/crypto/crypto_noop.hpp | 6 +++++ llarp/router/router.cpp | 44 ++++++++++++++++++++++++------- test/crypto/mock_crypto.hpp | 2 ++ 6 files changed, 61 insertions(+), 10 deletions(-) diff --git a/llarp/crypto/crypto.hpp b/llarp/crypto/crypto.hpp index f97bdbfc7..432bd4782 100644 --- a/llarp/crypto/crypto.hpp +++ b/llarp/crypto/crypto.hpp @@ -87,6 +87,9 @@ namespace llarp /// post quantum encrypt (buffer, sharedkey_dst, pub) virtual bool pqe_encrypt(PQCipherBlock &, SharedSecret &, const PQPubKey &) = 0; + + virtual bool + check_identity_privkey(const SecretKey &) = 0; }; inline Crypto::~Crypto() = default; diff --git a/llarp/crypto/crypto_libsodium.cpp b/llarp/crypto/crypto_libsodium.cpp index 72378d182..1507312cf 100644 --- a/llarp/crypto/crypto_libsodium.cpp +++ b/llarp/crypto/crypto_libsodium.cpp @@ -214,6 +214,19 @@ namespace llarp (void)sk_pk; } + bool + CryptoLibSodium::check_identity_privkey(const llarp::SecretKey &keys) + { + AlignedBuffer< crypto_sign_SEEDBYTES > seed; + llarp::PubKey pk; + llarp::SecretKey sk; + if(crypto_sign_ed25519_sk_to_seed(seed.data(), keys.data()) == -1) + return false; + if(crypto_sign_seed_keypair(pk.data(), sk.data(), seed.data()) == -1) + return false; + return keys.toPublic() == pk && sk == keys; + } + void CryptoLibSodium::encryption_keygen(llarp::SecretKey &keys) { diff --git a/llarp/crypto/crypto_libsodium.hpp b/llarp/crypto/crypto_libsodium.hpp index 422747335..75ded5c32 100644 --- a/llarp/crypto/crypto_libsodium.hpp +++ b/llarp/crypto/crypto_libsodium.hpp @@ -79,6 +79,9 @@ namespace llarp /// post quantum encrypt (buffer, sharedkey_dst, pub) bool pqe_encrypt(PQCipherBlock &, SharedSecret &, const PQPubKey &) override; + + bool + check_identity_privkey(const SecretKey &) override; }; } // namespace sodium diff --git a/llarp/crypto/crypto_noop.hpp b/llarp/crypto/crypto_noop.hpp index 177515258..9a91e673d 100644 --- a/llarp/crypto/crypto_noop.hpp +++ b/llarp/crypto/crypto_noop.hpp @@ -180,6 +180,12 @@ namespace llarp std::copy_n(secret.begin(), SharedSecret::SIZE, block.begin()); return true; } + + bool + check_identity_privkey(const SecretKey &) override + { + return true; + } }; } // namespace llarp diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index da742b57f..20ed0edfa 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -258,7 +258,7 @@ namespace llarp CURL *curl = curl_easy_init(); if(curl) { - CURLcode res; + bool ret = false; std::stringstream ss; ss << "http://" << lokidRPCAddr << "/json_rpc"; const auto url = ss.str(); @@ -283,10 +283,8 @@ namespace llarp do { resp.clear(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); LogInfo("Getting Identity Keys from lokid..."); - res = curl_easy_perform(curl); - if(res == CURLE_OK) + if(curl_easy_perform(curl) == CURLE_OK) { try { @@ -301,10 +299,28 @@ namespace llarp continue; const auto k = (*itr)["service_node_ed25519_privkey"].get< std::string >(); - if(k.empty()) - continue; + if(k.size() != (_identity.size() * 2)) + { + if(k.empty()) + { + LogError("lokid gave no identity key"); + } + else + { + LogError("lokid gave invalid identity key"); + } + return false; + } if(not HexDecode(k.c_str(), _identity.data(), _identity.size())) continue; + if(CryptoManager::instance()->check_identity_privkey(_identity)) + { + ret = true; + } + else + { + LogError("lokid gave bogus identity key"); + } } catch(nlohmann::json::exception &ex) { @@ -313,13 +329,21 @@ namespace llarp } else { - LogError("failed to get identity Keys"); + LogError("failed to get identity keys"); + } + if(ret) + { + LogInfo("Got Identity Keys from lokid: ", RouterID(pubkey())); + break; + } + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - } while(res != CURLE_OK); + } while(true); curl_easy_cleanup(curl); curl_slist_free_all(list); - LogInfo("Got Identity Keys from lokid"); - return true; + return ret; } else { diff --git a/test/crypto/mock_crypto.hpp b/test/crypto/mock_crypto.hpp index be0151528..dee621502 100644 --- a/test/crypto/mock_crypto.hpp +++ b/test/crypto/mock_crypto.hpp @@ -69,6 +69,8 @@ namespace llarp MOCK_METHOD3(pqe_encrypt, bool(PQCipherBlock &, SharedSecret &, const PQPubKey &)); + + MOCK_METHOD1(check_identity_privkey, bool(const SecretKey&)); }; } // namespace test } // namespace llarp From d880eec1deec608ff72a84e1e9ccee6f4fb6aaac Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 27 Nov 2019 13:11:15 -0500 Subject: [PATCH 27/58] ping lokid rpc --- llarp/rpc/rpc.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/llarp/rpc/rpc.cpp b/llarp/rpc/rpc.cpp index f25487545..690d1906e 100644 --- a/llarp/rpc/rpc.cpp +++ b/llarp/rpc/rpc.cpp @@ -53,6 +53,48 @@ namespace llarp PopulateReqHeaders(abyss::http::Headers_t& hdr) override; }; + struct LokiPingHandler final : public CallerHandler + { + ~LokiPingHandler() override = default; + LokiPingHandler(::abyss::http::ConnImpl* impl, CallerImpl* parent) + : CallerHandler(impl, parent) + { + } + bool + HandleJSONResult(const nlohmann::json& result) override + { + if(not result.is_object()) + { + LogError("invalid result from lokid ping, not an object"); + return false; + } + const auto itr = result.find("status"); + if(itr == result.end()) + { + LogError("invalid result from lokid ping, no result"); + return false; + } + if(not itr->is_string()) + { + LogError("invalid result from lokid ping, status not an string"); + return false; + } + const auto status = itr->get< std::string >(); + if(status != "OK") + { + LogError("lokid ping failed: '", status, "'"); + return false; + } + LogInfo("lokid ping: '", status, "'"); + return true; + } + void + HandleError() override + { + LogError("Failed to ping lokid"); + } + }; + struct GetServiceNodeListHandler final : public CallerHandler { using PubkeyList_t = std::vector< RouterID >; @@ -120,7 +162,9 @@ namespace llarp { AbstractRouter* router; llarp_time_t m_NextKeyUpdate = 0; + llarp_time_t m_NextPing = 0; const llarp_time_t KeyUpdateInterval = 5000; + const llarp_time_t PingInterval = 60 * 5 * 1000; using PubkeyList_t = GetServiceNodeListHandler::PubkeyList_t; CallerImpl(AbstractRouter* r) : ::abyss::http::JSONRPC(), router(r) @@ -130,11 +174,18 @@ namespace llarp void Tick(llarp_time_t now) { + if(not router->IsRunning()) + return; if(now >= m_NextKeyUpdate) { AsyncUpdatePubkeyList(); m_NextKeyUpdate = now + KeyUpdateInterval; } + if(now >= m_NextPing) + { + AsyncLokiPing(); + m_NextPing = now + PingInterval; + } Flush(); } @@ -145,6 +196,20 @@ namespace llarp password = passwd; } + void + AsyncLokiPing() + { + LogInfo("Pinging Lokid"); + static nlohmann::json::number_unsigned_t major(atoi(LLARP_VERSION_MAJ)); + static nlohmann::json::number_unsigned_t minor(atoi(LLARP_VERSION_MIN)); + static nlohmann::json::number_unsigned_t patch( + atoi(LLARP_VERSION_PATCH)); + nlohmann::json params = { + {"version", nlohmann::json::array({major, minor, patch})}}; + QueueRPC("lokinet_ping", std::move(params), + util::memFn(&CallerImpl::NewLokinetPingConn, this)); + } + void AsyncUpdatePubkeyList() { @@ -162,6 +227,12 @@ namespace llarp return RunAsync(router->netloop(), remote); } + abyss::http::IRPCClientHandler* + NewLokinetPingConn(abyss::http::ConnImpl* impl) + { + return new LokiPingHandler(impl, this); + } + abyss::http::IRPCClientHandler* NewAsyncUpdatePubkeyListConn(abyss::http::ConnImpl* impl) { From ba0fd223d96b460b1218c7fc45502caa22c3d127 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 25 Nov 2019 08:18:24 -0500 Subject: [PATCH 28/58] reduce number of jobs we put onto the logic thread --- Makefile | 2 +- llarp/handlers/tun.cpp | 38 +++++++++++++++++++++----------------- llarp/handlers/tun.hpp | 3 +++ llarp/service/endpoint.cpp | 29 ++++++++++++++++++++--------- llarp/service/protocol.cpp | 7 ++----- 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index e2ab5cd34..a37be1e0b 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ BUILD_TYPE ?= Debug PYTHON ?= python PYTHON3 ?= python3 -FORMAT ?= clang-format +FORMAT ?= clang-format-8 SETCAP ?= which setcap && setcap cap_net_admin,cap_net_bind_service=+eip diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 40e9e842f..97fad6a0d 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -978,17 +978,25 @@ namespace llarp TunEndpoint::tunifBeforeWrite(llarp_tun_io *tun) { // called in the isolated network thread - auto *self = static_cast< TunEndpoint * >(tun->user); - auto sendpkt = [self, tun](net::IPPacket &pkt) -> bool { - if(!llarp_ev_tun_async_write(tun, pkt.Buffer())) + auto *self = static_cast< TunEndpoint * >(tun->user); + auto _pkts = std::move(self->m_TunPkts); + self->m_TunPkts = std::vector< net::IPPacket >(); + + LogicCall(self->EndpointLogic(), [tun, self, pkts = std::move(_pkts)]() { + for(auto &pkt : pkts) { - llarp::LogWarn(self->Name(), " packet dropped"); - return true; + self->m_UserToNetworkPktQueue.Emplace(pkt); } - return false; - }; - LogicCall(self->EndpointLogic(), - std::bind(&TunEndpoint::FlushToUser, self, sendpkt)); + self->Flush(); + self->FlushToUser([self, tun](net::IPPacket &pkt) -> bool { + if(!llarp_ev_tun_async_write(tun, pkt.Buffer())) + { + llarp::LogWarn(self->Name(), " packet dropped"); + return true; + } + return false; + }); + }); } void @@ -996,14 +1004,10 @@ namespace llarp { // called for every packet read from user in isolated network thread auto *self = static_cast< TunEndpoint * >(tun->user); - std::vector< byte_t > pkt; - pkt.resize(b.sz); - std::copy_n(b.base, b.sz, pkt.data()); - LogicCall(self->RouterLogic(), [self, buffer = std::move(pkt)]() { - const llarp_buffer_t pbuf(buffer); - self->m_UserToNetworkPktQueue.EmplaceIf( - [&pbuf](net::IPPacket &p) -> bool { return p.Load(pbuf); }); - }); + net::IPPacket pkt; + if(not pkt.Load(b)) + return; + self->m_TunPkts.emplace_back(pkt); } TunEndpoint::~TunEndpoint() = default; diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 2889e7a5d..1cf4d0c86 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -185,6 +185,9 @@ namespace llarp using PacketQueue_t = llarp::util::CoDelQueue< net::IPPacket, net::IPPacket::GetTime, net::IPPacket::PutTime, net::IPPacket::CompareOrder, net::IPPacket::GetNow >; + + /// queue packet for send on net thread from user + std::vector< net::IPPacket > m_TunPkts; /// queue for sending packets over the network from us PacketQueue_t m_UserToNetworkPktQueue; /// queue for sending packets to user from network diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 94c344f7c..97c799548 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1047,20 +1047,29 @@ namespace llarp const auto& sessions = m_state->m_SNodeSessions; auto& queue = m_state->m_InboundTrafficQueue; - LogicCall(EndpointLogic(), [&]() { + auto epPump = [&]() { // send downstream packets to user for snode for(const auto& item : sessions) item.second.first->FlushDownstream(); // send downstream traffic to user for hidden service util::Lock lock(&m_state->m_InboundTrafficQueueMutex); - while(queue.size()) + while(not queue.empty()) { const auto& msg = queue.top(); const llarp_buffer_t buf(msg->payload); HandleInboundPacket(msg->tag, buf, msg->proto); queue.pop(); } - }); + }; + + if(NetworkIsIsolated()) + { + LogicCall(EndpointLogic(), epPump); + } + else + { + epPump(); + } auto router = Router(); // TODO: locking on this container @@ -1069,14 +1078,16 @@ namespace llarp // TODO: locking on this container for(const auto& item : sessions) item.second.first->FlushUpstream(); - util::Lock lock(&m_state->m_SendQueueMutex); - // send outbound traffic - for(const auto& item : m_state->m_SendQueue) { - item.second->SendRoutingMessage(*item.first, router); - MarkConvoTagActive(item.first->T.T); + util::Lock lock(&m_state->m_SendQueueMutex); + // send outbound traffic + for(const auto& item : m_state->m_SendQueue) + { + item.second->SendRoutingMessage(*item.first, router); + MarkConvoTagActive(item.first->T.T); + } + m_state->m_SendQueue.clear(); } - m_state->m_SendQueue.clear(); router->PumpLL(); } diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index 236998848..d603b8015 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -407,11 +407,8 @@ namespace llarp LogError("convotag missmatch: ", T, " != ", msg->tag); return false; } - msg->handler = handler; - const PathID_t fromPath = F; - LogicCall(logic, [=]() { - ProtocolMessage::ProcessAsync(recvPath, fromPath, msg); - }); + msg->handler = handler; + ProtocolMessage::ProcessAsync(recvPath, F, msg); return true; } From 11d4760c3da5fbd1db173af1f4ff9e8ef1c3232b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 25 Nov 2019 09:46:45 -0500 Subject: [PATCH 29/58] add metrics tracking for logic jobs in debug mode --- llarp/util/thread/logic.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index 6a960d6d6..cd6929bb3 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -62,12 +63,21 @@ namespace llarp // wrap the function so that we ensure that it's always calling stuff one at // a time - LogTraceExplicit(TAG, LINE, "queue"); - +#if defined(LOKINET_DEBUG) +#define METRIC(action) \ + metrics::integerTick("logic", action, 1, "tag", TAG, "line", \ + std::to_string(LINE)) +#else +#define METRIC(action) \ + do \ + { \ + } while(false) +#endif + + METRIC("queue"); auto f = [self = this, func, tag, line]() { - LogTraceExplicit(TAG, LINE, "exec"); self->m_Killer.TryAccess(func); - LogTraceExplicit(TAG, LINE, "return"); + METRIC("called"); }; if(m_Thread->LooksFull(5)) { @@ -75,7 +85,7 @@ namespace llarp "holy crap, we are trying to queue a job onto the logic " "thread but " "it looks full"); - + METRIC("full"); if(can_flush()) { // we are calling in the logic thread and our queue looks full @@ -83,15 +93,20 @@ namespace llarp const auto delay = m_Thread->GuessJobLatency() / 2; LogWarnExplicit(TAG, LINE, "deferring call by ", delay, " ms"); + METRIC("defer"); call_later(delay, f); return true; } } auto ret = llarp_threadpool_queue_job(m_Thread, f); - LogTraceExplicit(TAG, LINE, "=="); + if(not ret) + { + METRIC("dropped"); + } return ret; #undef TAG #undef LINE +#undef METRIC } void From af663d8b10e596fac81a7bae57d8b3076b746c47 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 25 Nov 2019 10:01:57 -0500 Subject: [PATCH 30/58] prune members in timer context --- llarp/util/thread/timer.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/llarp/util/thread/timer.cpp b/llarp/util/thread/timer.cpp index ebf4e6d12..bcd4cb1ce 100644 --- a/llarp/util/thread/timer.cpp +++ b/llarp/util/thread/timer.cpp @@ -45,12 +45,6 @@ namespace llarp { static_cast< timer* >(user)->exec(); } - - bool - operator<(const timer& other) const - { - return (started + timeout) < (other.started + other.timeout); - } }; } // namespace llarp @@ -59,7 +53,6 @@ struct llarp_timer_context llarp::util::Mutex timersMutex; // protects timers std::unordered_map< uint32_t, std::unique_ptr< llarp::timer > > timers GUARDED_BY(timersMutex); - std::priority_queue< std::unique_ptr< llarp::timer > > calling; llarp::util::Mutex tickerMutex; std::unique_ptr< llarp::util::Condition > ticker; absl::Duration nextTickLen = absl::Milliseconds(100); @@ -230,14 +223,15 @@ llarp_timer_tick_all(struct llarp_timer_context* t) { if(!t->run()) return; - + const auto now = llarp::time_now_ms(); + t->m_Now = now; std::list< std::unique_ptr< llarp::timer > > hit; { llarp::util::Lock lock(&t->timersMutex); auto itr = t->timers.begin(); while(itr != t->timers.end()) { - if(t->m_Now - itr->second->started >= itr->second->timeout + if(now - itr->second->started >= itr->second->timeout || itr->second->canceled) { // timer hit @@ -253,14 +247,14 @@ llarp_timer_tick_all(struct llarp_timer_context* t) while(not hit.empty()) { const auto& h = hit.front(); - h->called_at = t->m_Now; + h->called_at = now; h->exec(); hit.pop_front(); } // reindex next tick info { llarp::util::Lock lock(&t->timersMutex); - t->m_Now = llarp::time_now_ms(); + t->m_Now = now; t->m_NextRequiredTickAt = std::numeric_limits< llarp_time_t >::max(); for(const auto& item : t->timers) { From a3a62c34f322328442d738590c3381223695e3e5 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 25 Nov 2019 12:39:21 -0500 Subject: [PATCH 31/58] use timer guard for all jobs in debug mode --- llarp/util/thread/logic.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index cd6929bb3..dd0155190 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -76,8 +76,11 @@ namespace llarp METRIC("queue"); auto f = [self = this, func, tag, line]() { +#if defined(LOKINET_DEBUG) + metrics::TimerGuard g("logic", + std::string(TAG) + ":" + std::to_string(LINE)); +#endif self->m_Killer.TryAccess(func); - METRIC("called"); }; if(m_Thread->LooksFull(5)) { From 285a9a1dd5e66edcc2328a3e66dc1ae31d45dc8f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 27 Nov 2019 10:59:36 -0500 Subject: [PATCH 32/58] prevent segfault --- llarp/service/async_key_exchange.cpp | 20 +++++++++++--------- llarp/service/async_key_exchange.hpp | 7 ++++--- llarp/service/outbound_context.cpp | 7 ++++--- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/llarp/service/async_key_exchange.cpp b/llarp/service/async_key_exchange.cpp index 1267cfa60..ed45ff256 100644 --- a/llarp/service/async_key_exchange.cpp +++ b/llarp/service/async_key_exchange.cpp @@ -17,7 +17,6 @@ namespace llarp : logic(std::move(l)) , m_remote(std::move(r)) , m_LocalIdentity(localident) - , frame(std::make_shared< ProtocolFrame >()) , introPubKey(introsetPubKey) , remoteIntro(remote) , handler(h) @@ -27,31 +26,33 @@ namespace llarp } void - AsyncKeyExchange::Result(std::shared_ptr< AsyncKeyExchange > self) + AsyncKeyExchange::Result(std::shared_ptr< AsyncKeyExchange > self, + std::shared_ptr< ProtocolFrame > frame) { // put values self->handler->PutSenderFor(self->msg.tag, self->m_remote, false); self->handler->PutCachedSessionKeyFor(self->msg.tag, self->sharedKey); self->handler->PutIntroFor(self->msg.tag, self->remoteIntro); self->handler->PutReplyIntroFor(self->msg.tag, self->msg.introReply); - self->hook(self->frame); + self->hook(frame); } void - AsyncKeyExchange::Encrypt(std::shared_ptr< AsyncKeyExchange > self) + AsyncKeyExchange::Encrypt(std::shared_ptr< AsyncKeyExchange > self, + std::shared_ptr< ProtocolFrame > frame) { // derive ntru session key component SharedSecret K; auto crypto = CryptoManager::instance(); - crypto->pqe_encrypt(self->frame->C, K, self->introPubKey); + crypto->pqe_encrypt(frame->C, K, self->introPubKey); // randomize Nonce - self->frame->N.Randomize(); + frame->N.Randomize(); // compure post handshake session key // PKE (A, B, N) SharedSecret sharedSecret; path_dh_func dh_client = util::memFn(&Crypto::dh_client, crypto); if(!self->m_LocalIdentity.KeyExchange(dh_client, sharedSecret, - self->m_remote, self->frame->N)) + self->m_remote, frame->N)) { LogError("failed to derive x25519 shared key component"); } @@ -68,8 +69,9 @@ namespace llarp // set version self->msg.version = LLARP_PROTO_VERSION; // encrypt and sign - if(self->frame->EncryptAndSign(self->msg, K, self->m_LocalIdentity)) - LogicCall(self->logic, std::bind(&AsyncKeyExchange::Result, self)); + if(frame->EncryptAndSign(self->msg, K, self->m_LocalIdentity)) + LogicCall(self->logic, + std::bind(&AsyncKeyExchange::Result, self, frame)); else { LogError("failed to encrypt and sign"); diff --git a/llarp/service/async_key_exchange.hpp b/llarp/service/async_key_exchange.hpp index b43ffd279..854047300 100644 --- a/llarp/service/async_key_exchange.hpp +++ b/llarp/service/async_key_exchange.hpp @@ -19,7 +19,6 @@ namespace llarp ServiceInfo m_remote; const Identity& m_LocalIdentity; ProtocolMessage msg; - std::shared_ptr< ProtocolFrame > frame; Introduction intro; const PQPubKey introPubKey; Introduction remoteIntro; @@ -34,11 +33,13 @@ namespace llarp const ConvoTag& t, ProtocolType proto); static void - Result(std::shared_ptr< AsyncKeyExchange > user); + Result(std::shared_ptr< AsyncKeyExchange > user, + std::shared_ptr< ProtocolFrame > frame); /// given protocol message make protocol frame static void - Encrypt(std::shared_ptr< AsyncKeyExchange > user); + Encrypt(std::shared_ptr< AsyncKeyExchange > user, + std::shared_ptr< ProtocolFrame > frame); }; } // namespace service diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 510678d7b..cccbe9838 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -193,7 +193,8 @@ namespace llarp return; } } - auto ex = std::make_shared< AsyncKeyExchange >( + auto frame = std::make_shared< ProtocolFrame >(); + auto ex = std::make_shared< AsyncKeyExchange >( m_Endpoint->RouterLogic(), remoteIdent, m_Endpoint->GetIdentity(), currentIntroSet.K, remoteIntro, m_DataHandler, currentConvoTag, t); @@ -202,9 +203,9 @@ namespace llarp ex->msg.PutBuffer(payload); ex->msg.introReply = path->intro; - ex->frame->F = ex->msg.introReply.pathID; + frame->F = ex->msg.introReply.pathID; m_Endpoint->CryptoWorker()->addJob( - std::bind(&AsyncKeyExchange::Encrypt, ex)); + std::bind(&AsyncKeyExchange::Encrypt, ex, frame)); } std::string From 6acf7bff7e9872a604d9df4801ee4241190c68a2 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Wed, 27 Nov 2019 21:35:59 -0500 Subject: [PATCH 33/58] Track and log UV event loop ticks in debug builds --- llarp/ev/ev_libuv.cpp | 18 +++++++++++++++++- llarp/ev/ev_libuv.hpp | 5 +++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 49d725dc9..cd66c2202 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -791,6 +791,12 @@ namespace libuv { if(uv_loop_init(&m_Impl) == -1) return false; + +#ifdef LOKINET_DEBUG + last_time = 0; + loop_run_count = 0; +#endif + m_Impl.data = this; uv_loop_configure(&m_Impl, UV_LOOP_BLOCK_SIGNAL, SIGPIPE); m_TickTimer.data = this; @@ -834,6 +840,16 @@ namespace libuv { if(m_Run) { +#ifdef LOKINET_DEBUG + if ((uv_now(&m_Impl) - last_time) > 1000) + { + llarp::LogInfo("UV EVENT LOOP TICKS LAST SECOND: ", loop_run_count); + loop_run_count = 0; + last_time = uv_now(&m_Impl); + } + loop_run_count++; +#endif + uv_timer_start(&m_TickTimer, &OnTickTimeout, ms, 0); uv_run(&m_Impl, UV_RUN_ONCE); } @@ -954,4 +970,4 @@ bool llarp_ev_udp_recvmany(struct llarp_udp_io* u, struct llarp_pkt_list* pkts) { return static_cast< libuv::udp_glue* >(u->impl)->RecvMany(pkts); -} \ No newline at end of file +} diff --git a/llarp/ev/ev_libuv.hpp b/llarp/ev/ev_libuv.hpp index f9e6336d4..01ca795c9 100644 --- a/llarp/ev/ev_libuv.hpp +++ b/llarp/ev/ev_libuv.hpp @@ -98,6 +98,11 @@ namespace libuv uv_loop_t m_Impl; uv_timer_t m_TickTimer; std::atomic< bool > m_Run; + +#ifdef LOKINET_DEBUG + uint64_t last_time; + uint64_t loop_run_count; +#endif }; } // namespace libuv From 6d506302dc9328c1acf62c137bfb72a45952d545 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Thu, 28 Nov 2019 18:33:50 -0500 Subject: [PATCH 34/58] Show number of logic thread jobs in debug builds --- llarp/ev/ev_libuv.cpp | 7 ++++--- llarp/util/thread/logic.hpp | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index cd66c2202..37bdfca46 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -841,11 +841,12 @@ namespace libuv if(m_Run) { #ifdef LOKINET_DEBUG - if ((uv_now(&m_Impl) - last_time) > 1000) + if((uv_now(&m_Impl) - last_time) > 1000) { - llarp::LogInfo("UV EVENT LOOP TICKS LAST SECOND: ", loop_run_count); + llarp::LogInfo("UV EVENT LOOP TICKS LAST SECOND: ", loop_run_count, + ", LOGIC THREAD JOBS: ", m_Logic->pendingThreadJobs()); loop_run_count = 0; - last_time = uv_now(&m_Impl); + last_time = uv_now(&m_Impl); } loop_run_count++; #endif diff --git a/llarp/util/thread/logic.hpp b/llarp/util/thread/logic.hpp index 465b8e8b5..d24df61f9 100644 --- a/llarp/util/thread/logic.hpp +++ b/llarp/util/thread/logic.hpp @@ -45,6 +45,14 @@ namespace llarp bool can_flush() const; +#ifdef LOKINET_DEBUG + size_t + pendingThreadJobs() const + { + return m_Thread->pendingJobs(); + } +#endif + private: using ID_t = std::thread::id; llarp_threadpool* const m_Thread; From d13a3d2b627e5872769bf6b7bba9c44f26c67d1e Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Thu, 28 Nov 2019 11:24:25 -0400 Subject: [PATCH 35/58] Don't flush here; we already have a tick flushing --- llarp/handlers/tun.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 97fad6a0d..94b0d007a 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -987,7 +987,6 @@ namespace llarp { self->m_UserToNetworkPktQueue.Emplace(pkt); } - self->Flush(); self->FlushToUser([self, tun](net::IPPacket &pkt) -> bool { if(!llarp_ev_tun_async_write(tun, pkt.Buffer())) { From 1a06da9c3ddb1f2412f2bee1aaef780b04cdfb0d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 15:41:02 -0500 Subject: [PATCH 36/58] reduce calls in link pump --- llarp/iwp/linklayer.cpp | 28 ---------------------------- llarp/iwp/linklayer.hpp | 3 --- llarp/link/server.cpp | 13 +++++++++++++ 3 files changed, 13 insertions(+), 31 deletions(-) diff --git a/llarp/iwp/linklayer.cpp b/llarp/iwp/linklayer.cpp index 907259b6b..bac509b60 100644 --- a/llarp/iwp/linklayer.cpp +++ b/llarp/iwp/linklayer.cpp @@ -20,34 +20,6 @@ namespace llarp LinkLayer::~LinkLayer() = default; - void - LinkLayer::Pump() - { - std::unordered_set< RouterID, RouterID::Hash > sessions; - { - ACQUIRE_LOCK(Lock_t l, m_AuthedLinksMutex); - auto itr = m_AuthedLinks.begin(); - while(itr != m_AuthedLinks.end()) - { - const RouterID r{itr->first}; - sessions.emplace(r); - ++itr; - } - } - ILinkLayer::Pump(); - { - ACQUIRE_LOCK(Lock_t l, m_AuthedLinksMutex); - for(const auto& pk : sessions) - { - if(m_AuthedLinks.count(pk) == 0) - { - // all sessions were removed - SessionClosed(pk); - } - } - } - } - const char* LinkLayer::Name() const { diff --git a/llarp/iwp/linklayer.hpp b/llarp/iwp/linklayer.hpp index 615917dda..a64f65eae 100644 --- a/llarp/iwp/linklayer.hpp +++ b/llarp/iwp/linklayer.hpp @@ -26,9 +26,6 @@ namespace llarp NewOutboundSession(const RouterContact &rc, const AddressInfo &ai) override; - void - Pump() override; - bool KeyGen(SecretKey &k) override; diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 87f7a0f33..dbdb1bcd0 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace llarp { @@ -125,6 +126,7 @@ namespace llarp void ILinkLayer::Pump() { + std::unordered_set< RouterID, RouterID::Hash > closedSessions; auto _now = Now(); { ACQUIRE_LOCK(Lock_t l, m_AuthedLinksMutex); @@ -141,6 +143,7 @@ namespace llarp llarp::LogInfo("session to ", RouterID(itr->second->GetPubKey()), " timed out"); itr->second->Close(); + closedSessions.emplace(itr->first); itr = m_AuthedLinks.erase(itr); } } @@ -169,6 +172,16 @@ namespace llarp } } } + { + ACQUIRE_LOCK(Lock_t l, m_AuthedLinksMutex); + for(const auto& r : closedSessions) + { + if(m_AuthedLinks.count(r) == 0) + { + SessionClosed(r); + } + } + } } bool From e2472d985de5e9cfbf0662866db54e647d1bd3f3 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 15:50:15 -0500 Subject: [PATCH 37/58] process transit hops on flush --- llarp/path/transit_hop.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 6e21bca9d..5f93798c2 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -213,6 +213,15 @@ namespace llarp std::move(m_UpstreamQueue), r)); m_UpstreamQueue = nullptr; + std::vector< RelayUpstreamMessage > msgs; + do + { + auto maybe = m_UpstreamGather.tryPopFront(); + if(not maybe.has_value()) + break; + msgs.emplace_back(maybe.value()); + } while(true); + HandleAllUpstream(std::move(msgs), r); } void @@ -223,6 +232,15 @@ namespace llarp shared_from_this(), std::move(m_DownstreamQueue), r)); m_DownstreamQueue = nullptr; + std::vector< RelayDownstreamMessage > msgs; + do + { + auto maybe = m_DownstreamGather.tryPopFront(); + if(not maybe.has_value()) + break; + msgs.emplace_back(maybe.value()); + } while(true); + HandleAllDownstream(std::move(msgs), r); } bool From d591394ad213727435610471bed602d45a284810 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 15:55:55 -0500 Subject: [PATCH 38/58] dont process empty queues --- llarp/path/transit_hop.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 5f93798c2..34ff3579f 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -221,6 +221,8 @@ namespace llarp break; msgs.emplace_back(maybe.value()); } while(true); + if(msgs.empty()) + return; HandleAllUpstream(std::move(msgs), r); } @@ -240,6 +242,8 @@ namespace llarp break; msgs.emplace_back(maybe.value()); } while(true); + if(msgs.empty()) + return; HandleAllDownstream(std::move(msgs), r); } From 9e305c5b30371c1f26626e6fc56647e11a1576de Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 10:52:10 -0500 Subject: [PATCH 39/58] use lockless queues to gather results of transit traffic work --- llarp/path/transit_hop.cpp | 52 +++++++++++++++++++++++++++----------- llarp/path/transit_hop.hpp | 2 ++ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 34ff3579f..fd1b370d9 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -32,7 +32,11 @@ namespace llarp return stream; } - TransitHop::TransitHop() = default; + TransitHop::TransitHop() : m_UpstreamGather(128), m_DownstreamGather(128) + { + m_UpstreamGather.enable(); + m_DownstreamGather.enable(); + } bool TransitHop::Expired(llarp_time_t now) const @@ -118,43 +122,61 @@ namespace llarp void TransitHop::DownstreamWork(TrafficQueue_ptr msgs, AbstractRouter* r) { - std::vector< RelayDownstreamMessage > sendmsgs(msgs->size()); - size_t idx = 0; for(auto& ev : *msgs) { + RelayDownstreamMessage msg; const llarp_buffer_t buf(ev.first); - auto& msg = sendmsgs[idx]; msg.pathid = info.rxID; msg.Y = ev.second ^ nonceXOR; CryptoManager::instance()->xchacha20(buf, pathKey, ev.second); msg.X = buf; llarp::LogDebug("relay ", msg.X.size(), " bytes downstream from ", info.upstream, " to ", info.downstream); - ++idx; + if(m_DownstreamGather.empty() || m_DownstreamGather.full()) + { + LogicCall(r->logic(), [self = shared_from_this(), r]() { + std::vector< RelayDownstreamMessage > msgs; + do + { + auto maybe = self->m_DownstreamGather.tryPopFront(); + if(not maybe.has_value()) + break; + msgs.emplace_back(maybe.value()); + } while(true); + self->HandleAllDownstream(std::move(msgs), r); + }); + } + m_DownstreamGather.pushBack(msg); } - LogicCall(r->logic(), - std::bind(&TransitHop::HandleAllDownstream, shared_from_this(), - std::move(sendmsgs), r)); } void TransitHop::UpstreamWork(TrafficQueue_ptr msgs, AbstractRouter* r) { - std::vector< RelayUpstreamMessage > sendmsgs(msgs->size()); - size_t idx = 0; for(auto& ev : *msgs) { const llarp_buffer_t buf(ev.first); - auto& msg = sendmsgs[idx]; + RelayUpstreamMessage msg; CryptoManager::instance()->xchacha20(buf, pathKey, ev.second); msg.pathid = info.txID; msg.Y = ev.second ^ nonceXOR; msg.X = buf; - ++idx; + if(m_UpstreamGather.empty() || m_UpstreamGather.full()) + { + LogicCall(r->logic(), [self = shared_from_this(), r]() { + std::vector< RelayUpstreamMessage > msgs; + do + { + auto maybe = self->m_UpstreamGather.tryPopFront(); + if(not maybe.has_value()) + break; + msgs.emplace_back(maybe.value()); + } while(true); + self->HandleAllUpstream(std::move(msgs), r); + }); + } + m_UpstreamGather.pushBack(msg); } - LogicCall(r->logic(), - std::bind(&TransitHop::HandleAllUpstream, shared_from_this(), - std::move(sendmsgs), r)); } void diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 60300b541..3e9648526 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -233,6 +233,8 @@ namespace llarp std::set< std::shared_ptr< TransitHop >, ComparePtr< std::shared_ptr< TransitHop > > > m_FlushOthers; + thread::Queue< RelayUpstreamMessage > m_UpstreamGather; + thread::Queue< RelayDownstreamMessage > m_DownstreamGather; }; inline std::ostream& From d823d6fa703cbe97c4d16e3d61d8767d565cb627 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 16:12:46 -0500 Subject: [PATCH 40/58] only flush when no other jobs are executing --- llarp/path/transit_hop.cpp | 82 +++++++++++++++++--------------------- llarp/path/transit_hop.hpp | 2 + 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index fd1b370d9..9d493ccd2 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -36,6 +36,8 @@ namespace llarp { m_UpstreamGather.enable(); m_DownstreamGather.enable(); + m_UpstreamWorkCounter = 0; + m_DownstreamWorkCounter = 0; } bool @@ -122,6 +124,18 @@ namespace llarp void TransitHop::DownstreamWork(TrafficQueue_ptr msgs, AbstractRouter* r) { + m_DownstreamWorkCounter++; + auto flushIt = [self = shared_from_this(), r]() { + std::vector< RelayDownstreamMessage > msgs; + do + { + auto maybe = self->m_DownstreamGather.tryPopFront(); + if(not maybe.has_value()) + break; + msgs.emplace_back(maybe.value()); + } while(true); + self->HandleAllDownstream(std::move(msgs), r); + }; for(auto& ev : *msgs) { RelayDownstreamMessage msg; @@ -132,27 +146,32 @@ namespace llarp msg.X = buf; llarp::LogDebug("relay ", msg.X.size(), " bytes downstream from ", info.upstream, " to ", info.downstream); - if(m_DownstreamGather.empty() || m_DownstreamGather.full()) + if(m_DownstreamGather.full()) { - LogicCall(r->logic(), [self = shared_from_this(), r]() { - std::vector< RelayDownstreamMessage > msgs; - do - { - auto maybe = self->m_DownstreamGather.tryPopFront(); - if(not maybe.has_value()) - break; - msgs.emplace_back(maybe.value()); - } while(true); - self->HandleAllDownstream(std::move(msgs), r); - }); + LogicCall(r->logic(), flushIt); } m_DownstreamGather.pushBack(msg); } + m_DownstreamWorkCounter--; + if(m_DownstreamWorkCounter == 0) + flushIt(); } void TransitHop::UpstreamWork(TrafficQueue_ptr msgs, AbstractRouter* r) { + m_UpstreamWorkCounter++; + auto flushIt = [self = shared_from_this(), r]() { + std::vector< RelayUpstreamMessage > msgs; + do + { + auto maybe = self->m_UpstreamGather.tryPopFront(); + if(not maybe.has_value()) + break; + msgs.emplace_back(maybe.value()); + } while(true); + self->HandleAllUpstream(std::move(msgs), r); + }; for(auto& ev : *msgs) { const llarp_buffer_t buf(ev.first); @@ -161,22 +180,15 @@ namespace llarp msg.pathid = info.txID; msg.Y = ev.second ^ nonceXOR; msg.X = buf; - if(m_UpstreamGather.empty() || m_UpstreamGather.full()) + if(m_UpstreamGather.full()) { - LogicCall(r->logic(), [self = shared_from_this(), r]() { - std::vector< RelayUpstreamMessage > msgs; - do - { - auto maybe = self->m_UpstreamGather.tryPopFront(); - if(not maybe.has_value()) - break; - msgs.emplace_back(maybe.value()); - } while(true); - self->HandleAllUpstream(std::move(msgs), r); - }); + LogicCall(r->logic(), flushIt); } m_UpstreamGather.pushBack(msg); } + m_UpstreamWorkCounter--; + if(m_UpstreamWorkCounter == 0) + flushIt(); } void @@ -235,17 +247,6 @@ namespace llarp std::move(m_UpstreamQueue), r)); m_UpstreamQueue = nullptr; - std::vector< RelayUpstreamMessage > msgs; - do - { - auto maybe = m_UpstreamGather.tryPopFront(); - if(not maybe.has_value()) - break; - msgs.emplace_back(maybe.value()); - } while(true); - if(msgs.empty()) - return; - HandleAllUpstream(std::move(msgs), r); } void @@ -256,17 +257,6 @@ namespace llarp shared_from_this(), std::move(m_DownstreamQueue), r)); m_DownstreamQueue = nullptr; - std::vector< RelayDownstreamMessage > msgs; - do - { - auto maybe = m_DownstreamGather.tryPopFront(); - if(not maybe.has_value()) - break; - msgs.emplace_back(maybe.value()); - } while(true); - if(msgs.empty()) - return; - HandleAllDownstream(std::move(msgs), r); } bool diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 3e9648526..1627bb24c 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -235,6 +235,8 @@ namespace llarp m_FlushOthers; thread::Queue< RelayUpstreamMessage > m_UpstreamGather; thread::Queue< RelayDownstreamMessage > m_DownstreamGather; + std::atomic< uint32_t > m_UpstreamWorkCounter; + std::atomic< uint32_t > m_DownstreamWorkCounter; }; inline std::ostream& From 2852601a28579d9671b1065957736df827191179 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 16:19:50 -0500 Subject: [PATCH 41/58] flush in logic --- llarp/path/transit_hop.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 9d493ccd2..c5a86f33f 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -154,7 +154,7 @@ namespace llarp } m_DownstreamWorkCounter--; if(m_DownstreamWorkCounter == 0) - flushIt(); + LogicCall(r->logic(), flushIt); } void @@ -188,7 +188,7 @@ namespace llarp } m_UpstreamWorkCounter--; if(m_UpstreamWorkCounter == 0) - flushIt(); + LogicCall(r->logic(), flushIt); } void From 8849173112e1fc708db272f6595c85cc36d0352a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 18:08:02 -0500 Subject: [PATCH 42/58] try async decrypt then verify --- llarp/service/endpoint.cpp | 30 +++++++++++++++++- llarp/service/endpoint.hpp | 7 +++++ llarp/service/handler.hpp | 11 +++++++ llarp/service/protocol.cpp | 62 ++++++++++++++++++++++++-------------- 4 files changed, 86 insertions(+), 24 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 97c799548..40bbb9e77 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -29,12 +29,15 @@ namespace llarp { Endpoint::Endpoint(const std::string& name, AbstractRouter* r, Context* parent) - : path::Builder(r, 3, path::default_len), context(parent) + : path::Builder(r, 3, path::default_len) + , context(parent) + , m_RecvQueue(128) { m_state = std::make_unique< EndpointState >(); m_state->m_Router = r; m_state->m_Name = name; m_state->m_Tag.Zero(); + m_RecvQueue.enable(); } bool @@ -805,6 +808,30 @@ namespace llarp return {{"LOKINET_ADDR", m_Identity.pub.Addr().ToString()}}; } + void + Endpoint::FlushRecvData() + { + do + { + auto maybe = m_RecvQueue.tryPopFront(); + if(not maybe.has_value()) + return; + auto ev = std::move(maybe.value()); + ProtocolMessage::ProcessAsync(ev.fromPath, ev.pathid, ev.msg); + } while(true); + } + + void + Endpoint::QueueRecvData(RecvDataEvent ev) + { + if(m_RecvQueue.full() || m_RecvQueue.empty()) + { + auto self = this; + LogicCall(m_router->logic(), [self]() { self->FlushRecvData(); }); + } + m_RecvQueue.pushBack(std::move(ev)); + } + bool Endpoint::HandleDataMessage(path::Path_ptr path, const PathID_t from, std::shared_ptr< ProtocolMessage > msg) @@ -1048,6 +1075,7 @@ namespace llarp auto& queue = m_state->m_InboundTrafficQueue; auto epPump = [&]() { + FlushRecvData(); // send downstream packets to user for snode for(const auto& item : sessions) item.second.first->FlushDownstream(); diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 0dd858cc7..359fd8498 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -78,6 +78,9 @@ namespace llarp bool IsReady() const; + void + QueueRecvData(RecvDataEvent ev) override; + /// return true if our introset has expired intros bool IntrosetIsStale() const; @@ -436,6 +439,9 @@ namespace llarp hooks::Backend_ptr m_OnReady; private: + void + FlushRecvData(); + friend struct EndpointUtil; // clang-format off @@ -448,6 +454,7 @@ namespace llarp // clang-format on std::unique_ptr< EndpointState > m_state; + thread::Queue< RecvDataEvent > m_RecvQueue; }; using Endpoint_ptr = std::shared_ptr< Endpoint >; diff --git a/llarp/service/handler.hpp b/llarp/service/handler.hpp index 3c20aea47..9fabb6b95 100644 --- a/llarp/service/handler.hpp +++ b/llarp/service/handler.hpp @@ -14,6 +14,14 @@ namespace llarp namespace service { using ConvoTag = AlignedBuffer< 16 >; + struct ProtocolMessage; + + struct RecvDataEvent + { + path::Path_ptr fromPath; + PathID_t pathid; + std::shared_ptr< ProtocolMessage > msg; + }; struct ProtocolMessage; struct IDataHandler @@ -63,6 +71,9 @@ namespace llarp virtual bool HasInboundConvo(const Address& addr) const = 0; + + virtual void + QueueRecvData(RecvDataEvent ev) = 0; }; } // namespace service } // namespace llarp diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index d603b8015..bf9af1a0a 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -364,13 +364,21 @@ namespace llarp return *this; } + struct AsyncDecrypt + { + ServiceInfo si; + SharedSecret shared; + ProtocolFrame frame; + }; + bool ProtocolFrame::AsyncDecryptAndVerify( std::shared_ptr< Logic > logic, path::Path_ptr recvPath, const std::shared_ptr< llarp::thread::ThreadPool >& worker, const Identity& localIdent, IDataHandler* handler) const { - auto msg = std::make_shared< ProtocolMessage >(); + auto msg = std::make_shared< ProtocolMessage >(); + msg->handler = handler; if(T.IsZero()) { LogInfo("Got protocol frame with new convo"); @@ -380,36 +388,44 @@ namespace llarp dh->path = recvPath; return worker->addJob(std::bind(&AsyncFrameDecrypt::Work, dh)); } - SharedSecret shared; - if(!handler->GetCachedSessionKeyFor(T, shared)) + + auto v = new AsyncDecrypt(); + + if(!handler->GetCachedSessionKeyFor(T, v->shared)) { LogError("No cached session for T=", T); + delete v; return false; } - ServiceInfo si; - if(!handler->GetSenderFor(T, si)) + + if(!handler->GetSenderFor(T, v->si)) { LogError("No sender for T=", T); + delete v; return false; } - if(!Verify(si)) - { - LogError("Signature failure from ", si.Addr()); - return false; - } - if(!DecryptPayloadInto(shared, *msg)) - { - 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; - ProtocolMessage::ProcessAsync(recvPath, F, msg); - return true; + v->frame = *this; + return worker->addJob( + [v, msg = std::move(msg), recvPath = std::move(recvPath)]() { + if(not v->frame.Verify(v->si)) + { + LogError("Signature failure from ", v->si.Addr()); + delete v; + return; + } + if(not v->frame.DecryptPayloadInto(v->shared, *msg)) + { + LogError("failed to decrypt message"); + delete v; + return; + } + RecvDataEvent ev; + ev.fromPath = std::move(recvPath); + ev.pathid = v->frame.F; + ev.msg = std::move(msg); + msg->handler->QueueRecvData(std::move(ev)); + delete v; + }); } bool From 5188873288dda31c5979f20ad1e6c438a914160d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 19:34:31 -0500 Subject: [PATCH 43/58] batch and flush --- llarp/handlers/tun.cpp | 5 +++-- llarp/path/transit_hop.cpp | 14 +++++++++++--- llarp/path/transit_hop.hpp | 3 +++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 94b0d007a..51acaf020 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -708,7 +708,7 @@ namespace llarp llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ", m_OurRange); - MapAddress(m_Identity.pub.Addr(), m_OurIP, IsSNode()); + MapAddress(m_Identity.pub.Addr(), GetIfAddr(), IsSNode()); if(m_OnUp) { m_OnUp->NotifyAsync(NotifyParams()); @@ -717,7 +717,8 @@ namespace llarp { vpnif->injected(vpnif, true); } - return true; + auto itr = m_IPToAddr.find(GetIFAddr()); + return itr != m_IPToAddr.end() && itr->second == m_Identity.pub.Addr(); } std::unordered_map< std::string, std::string > diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index c5a86f33f..d9d5f6b37 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -150,7 +150,8 @@ namespace llarp { LogicCall(r->logic(), flushIt); } - m_DownstreamGather.pushBack(msg); + if(not m_DownstreamGather.disabled()) + m_DownstreamGather.pushBack(msg); } m_DownstreamWorkCounter--; if(m_DownstreamWorkCounter == 0) @@ -184,7 +185,8 @@ namespace llarp { LogicCall(r->logic(), flushIt); } - m_UpstreamGather.pushBack(msg); + if(not m_UpstreamGather.disabled()) + m_UpstreamGather.pushBack(msg); } m_UpstreamWorkCounter--; if(m_UpstreamWorkCounter == 0) @@ -463,10 +465,16 @@ namespace llarp printer.printAttribute("TransitHop", info); printer.printAttribute("started", started); printer.printAttribute("lifetime", lifetime); - return stream; } + void + TransitHop::Stop() + { + m_UpstreamGather.disable(); + m_DownstreamGather.disable(); + } + void TransitHop::SetSelfDestruct() { diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 1627bb24c..fb7ecde58 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -95,6 +95,9 @@ namespace llarp llarp_proto_version_t version; llarp_time_t m_LastActivity = 0; + void + Stop(); + bool destroy = false; bool From 082830790601e644eb96bc59eb200ae4887f3b97 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 19:37:58 -0500 Subject: [PATCH 44/58] fix address mapping bug --- llarp/handlers/tun.cpp | 51 ++++++++++++++++++++++++++++++-------- llarp/handlers/tun.hpp | 19 ++++++++------ llarp/net/ip.cpp | 2 +- llarp/path/transit_hop.cpp | 4 +-- llarp/service/endpoint.cpp | 2 ++ 5 files changed, 57 insertions(+), 21 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 51acaf020..1ec13199f 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -336,6 +336,32 @@ namespace llarp return msg.questions[0].IsName("localhost.loki"); } + template <> + bool + TunEndpoint::FindAddrForIP(service::Address &addr, huint128_t ip) + { + auto itr = m_IPToAddr.find(ip); + if(itr != m_IPToAddr.end() and not m_SNodes[itr->second]) + { + addr = service::Address(itr->second.as_array()); + return true; + } + return false; + } + + template <> + bool + TunEndpoint::FindAddrForIP(RouterID &addr, huint128_t ip) + { + auto itr = m_IPToAddr.find(ip); + if(itr != m_IPToAddr.end() and m_SNodes[itr->second]) + { + addr = RouterID(itr->second.as_array()); + return true; + } + return false; + } + bool TunEndpoint::HandleHookedDNSMessage( dns::Message &&msg, std::function< void(dns::Message) > reply) @@ -479,18 +505,17 @@ namespace llarp reply(msg); return true; } - llarp::service::Address addr( - ObtainAddrForIP< llarp::service::Address >(ip, true)); - if(!addr.IsZero()) + RouterID snodeAddr; + if(FindAddrForIP(snodeAddr, ip)) { - msg.AddAReply(addr.ToString(".snode")); + msg.AddAReply(snodeAddr.ToString()); reply(msg); return true; } - addr = ObtainAddrForIP< llarp::service::Address >(ip, false); - if(!addr.IsZero()) + service::Address lokiAddr; + if(FindAddrForIP(lokiAddr, ip)) { - msg.AddAReply(addr.ToString(".loki")); + msg.AddAReply(lokiAddr.ToString()); reply(msg); return true; } @@ -708,7 +733,13 @@ namespace llarp llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ", m_OurRange); - MapAddress(m_Identity.pub.Addr(), GetIfAddr(), IsSNode()); + const service::Address ourAddr = m_Identity.pub.Addr(); + + if(not MapAddress(ourAddr, GetIfAddr(), false)) + { + return false; + } + if(m_OnUp) { m_OnUp->NotifyAsync(NotifyParams()); @@ -717,8 +748,8 @@ namespace llarp { vpnif->injected(vpnif, true); } - auto itr = m_IPToAddr.find(GetIFAddr()); - return itr != m_IPToAddr.end() && itr->second == m_Identity.pub.Addr(); + + return HasAddress(ourAddr); } std::unordered_map< std::string, std::string > diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 1cf4d0c86..0cc4edfcf 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -148,22 +148,24 @@ namespace llarp handleTickTun(void* u); /// get a key for ip address - template < typename Addr > - Addr + template < typename Addr_t > + Addr_t ObtainAddrForIP(huint128_t ip, bool isSNode) { + Addr_t addr; auto itr = m_IPToAddr.find(ip); - if(itr == m_IPToAddr.end() || m_SNodes[itr->second] != isSNode) + if(itr != m_IPToAddr.end() and m_SNodes[itr->second] == isSNode) { - // not found - Addr addr; - addr.Zero(); - return addr; + addr = Addr_t(itr->second); } // found - return Addr{itr->second}; + return addr; } + template < typename Addr_t > + bool + FindAddrForIP(Addr_t& addr, huint128_t ip); + bool HasAddress(const AlignedBuffer< 32 >& addr) const { @@ -314,6 +316,7 @@ namespace llarp void FlushToUser(std::function< bool(net::IPPacket&) > sendfunc); }; + } // namespace handlers } // namespace llarp diff --git a/llarp/net/ip.cpp b/llarp/net/ip.cpp index 8dba138d2..64eb0490b 100644 --- a/llarp/net/ip.cpp +++ b/llarp/net/ip.cpp @@ -87,7 +87,7 @@ namespace llarp bool IPPacket::Load(const llarp_buffer_t &pkt) { - if(pkt.sz > sizeof(buf)) + if(pkt.sz > sizeof(buf) or pkt.sz == 0) return false; sz = pkt.sz; std::copy_n(pkt.base, sz, buf); diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index d9d5f6b37..07a164b39 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -150,7 +150,7 @@ namespace llarp { LogicCall(r->logic(), flushIt); } - if(not m_DownstreamGather.disabled()) + if(m_DownstreamGather.enabled()) m_DownstreamGather.pushBack(msg); } m_DownstreamWorkCounter--; @@ -185,7 +185,7 @@ namespace llarp { LogicCall(r->logic(), flushIt); } - if(not m_UpstreamGather.disabled()) + if(m_UpstreamGather.enabled()) m_UpstreamGather.pushBack(msg); } m_UpstreamWorkCounter--; diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 40bbb9e77..1f9d3e306 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1136,6 +1136,8 @@ namespace llarp Endpoint::SendToServiceOrQueue(const service::Address& remote, const llarp_buffer_t& data, ProtocolType t) { + if(data.sz == 0) + return false; // inbound converstation const auto now = Now(); From 3489753d5a1da75a7f7271b4ddf0033735911843 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 19:52:11 -0500 Subject: [PATCH 45/58] remove jenky call to logic thread in link server --- llarp/link/server.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index dbdb1bcd0..23ecf65a2 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -127,6 +127,7 @@ namespace llarp ILinkLayer::Pump() { std::unordered_set< RouterID, RouterID::Hash > closedSessions; + std::unordered_set< RouterID, RouterID::Hash > closedPending; auto _now = Now(); { ACQUIRE_LOCK(Lock_t l, m_AuthedLinksMutex); @@ -163,11 +164,9 @@ namespace llarp { LogInfo("pending session at ", itr->first, " timed out"); // defer call so we can acquire mutexes later - auto self = itr->second->BorrowSelf(); - LogicCall(m_Logic, [&, self]() { - this->HandleTimeout(self.get()); - self->Close(); - }); + auto pk = itr->second->GetPubKey(); + if(not pk.IsZero()) + closedPending.emplace(pk); itr = m_Pending.erase(itr); } } @@ -182,6 +181,10 @@ namespace llarp } } } + for(const auto& pending : closedPending) + { + SessionClosed(pending); + } } bool From f5ede2d875ff4dc2e10ac996b36bf5cc7a79151a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 20:02:20 -0500 Subject: [PATCH 46/58] ammend previous commit --- llarp/link/server.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 23ecf65a2..9e7539618 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -127,7 +127,7 @@ namespace llarp ILinkLayer::Pump() { std::unordered_set< RouterID, RouterID::Hash > closedSessions; - std::unordered_set< RouterID, RouterID::Hash > closedPending; + std::vector< std::shared_ptr< ILinkSession > > closedPending; auto _now = Now(); { ACQUIRE_LOCK(Lock_t l, m_AuthedLinksMutex); @@ -164,9 +164,7 @@ namespace llarp { LogInfo("pending session at ", itr->first, " timed out"); // defer call so we can acquire mutexes later - auto pk = itr->second->GetPubKey(); - if(not pk.IsZero()) - closedPending.emplace(pk); + closedPending.emplace_back(std::move(itr->second)); itr = m_Pending.erase(itr); } } @@ -183,7 +181,7 @@ namespace llarp } for(const auto& pending : closedPending) { - SessionClosed(pending); + HandleTimeout(pending.get()); } } From fba1e47d1ccfaa8504ae50237d728a15808dc642 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 28 Nov 2019 20:08:57 -0500 Subject: [PATCH 47/58] call jobs in logic --- llarp/util/thread/logic.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index dd0155190..c766e6271 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -82,6 +82,12 @@ namespace llarp #endif self->m_Killer.TryAccess(func); }; + if(can_flush()) + { + METRIC("fired"); + f(); + return true; + } if(m_Thread->LooksFull(5)) { LogWarnExplicit(TAG, LINE, @@ -89,17 +95,6 @@ namespace llarp "thread but " "it looks full"); METRIC("full"); - if(can_flush()) - { - // we are calling in the logic thread and our queue looks full - // defer call to a later time so we don't die like a little bitch - const auto delay = m_Thread->GuessJobLatency() / 2; - - LogWarnExplicit(TAG, LINE, "deferring call by ", delay, " ms"); - METRIC("defer"); - call_later(delay, f); - return true; - } } auto ret = llarp_threadpool_queue_job(m_Thread, f); if(not ret) From 44e0e2c034aecab6537eca757cac11b3107d2fc0 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 29 Nov 2019 00:03:26 -0500 Subject: [PATCH 48/58] dont flood the logic queue --- llarp/service/sendcontext.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/llarp/service/sendcontext.cpp b/llarp/service/sendcontext.cpp index 6a2c107bc..1d36ec524 100644 --- a/llarp/service/sendcontext.cpp +++ b/llarp/service/sendcontext.cpp @@ -95,15 +95,12 @@ namespace llarp m->PutBuffer(payload); auto self = this; m_Endpoint->CryptoWorker()->addJob([f, m, shared, path, self]() { - if(!f->EncryptAndSign(*m, shared, self->m_Endpoint->GetIdentity())) + if(not f->EncryptAndSign(*m, shared, self->m_Endpoint->GetIdentity())) { LogError(self->m_Endpoint->Name(), " failed to sign message"); return; } - LogicCall(self->m_Endpoint->RouterLogic(), [self, f, path]() { - self->Send(f, path); - self->FlushUpstream(); - }); + self->Send(f, path); }); } From 28a2d471d6d66cfd18454fde8dcfaec6766969e6 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 29 Nov 2019 00:15:05 -0500 Subject: [PATCH 49/58] style nitch --- llarp/service/outbound_context.cpp | 4 +++- llarp/service/sendcontext.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index cccbe9838..cdc4214e6 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -62,7 +62,6 @@ namespace llarp if(intro.expiresAt > m_NextIntro.expiresAt) m_NextIntro = intro; } - currentConvoTag.Randomize(); } OutboundContext::~OutboundContext() = default; @@ -176,6 +175,8 @@ namespace llarp OutboundContext::AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t) { + if(not currentConvoTag.IsZero()) + return; if(remoteIntro.router.IsZero()) SwapIntros(); @@ -193,6 +194,7 @@ namespace llarp return; } } + currentConvoTag.Randomize(); auto frame = std::make_shared< ProtocolFrame >(); auto ex = std::make_shared< AsyncKeyExchange >( m_Endpoint->RouterLogic(), remoteIdent, m_Endpoint->GetIdentity(), diff --git a/llarp/service/sendcontext.cpp b/llarp/service/sendcontext.cpp index 1d36ec524..e47e1382a 100644 --- a/llarp/service/sendcontext.cpp +++ b/llarp/service/sendcontext.cpp @@ -108,7 +108,7 @@ namespace llarp SendContext::AsyncEncryptAndSendTo(const llarp_buffer_t& data, ProtocolType protocol) { - if(lastGoodSend) + if(lastGoodSend != 0) { EncryptAndSendTo(data, protocol); } From 740460318a076fe51908b056319ef432412ac4f8 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 29 Nov 2019 01:21:47 -0400 Subject: [PATCH 50/58] Die if job queue full If this happens it's a pretty serious error; if someone is hitting it occassionally it's better to know and update their queue size (and if it is a runaway situation lokinet doesn't come back anyway). --- llarp/util/thread/logic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index c766e6271..9a173ff78 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -90,11 +90,12 @@ namespace llarp } if(m_Thread->LooksFull(5)) { - LogWarnExplicit(TAG, LINE, + LogErrorExplicit(TAG, LINE, "holy crap, we are trying to queue a job onto the logic " "thread but " "it looks full"); METRIC("full"); + std::abort(); } auto ret = llarp_threadpool_queue_job(m_Thread, f); if(not ret) From 5d8f547d3353f64e95de5f40d20ae1e2883fef03 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 29 Nov 2019 01:40:50 -0400 Subject: [PATCH 51/58] Set tun to non-blocking If we can't write to it we want failure, not blocking. --- llarp/ev/ev_libuv.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 37bdfca46..1928ace1b 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -763,6 +763,9 @@ namespace libuv " has invalid fd: ", m_Device->tun_fd); return false; } + + tuntap_set_nonblocking(m_Device, 1); + if(uv_poll_init(loop, &m_Handle, m_Device->tun_fd) == -1) { llarp::LogError("failed to start polling on ", m_Tun->ifname); From 5924a2cec0253c2eeec71f62ba788ad86625cf49 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 29 Nov 2019 13:11:57 -0500 Subject: [PATCH 52/58] limit calls --- llarp/handlers/tun.cpp | 9 +++++++-- llarp/handlers/tun.hpp | 10 +++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 1ec13199f..35d769a7d 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -35,8 +35,13 @@ namespace llarp void TunEndpoint::tunifTick(llarp_tun_io *tun) { - auto *self = static_cast< TunEndpoint * >(tun->user); - LogicCall(self->m_router->logic(), [self]() { self->Flush(); }); + auto *self = static_cast< TunEndpoint * >(tun->user); + const auto now = self->Now(); + if(self->ShouldFlushNow(now)) + { + self->m_LastFlushAt = now; + LogicCall(self->m_router->logic(), [self]() { self->Flush(); }); + } } TunEndpoint::TunEndpoint(const std::string &nickname, AbstractRouter *r, diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 0cc4edfcf..6a2e7e7eb 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -184,7 +184,15 @@ namespace llarp ResetInternalState() override; protected: - using PacketQueue_t = llarp::util::CoDelQueue< + bool + ShouldFlushNow(llarp_time_t now) const + { + static constexpr llarp_time_t FlushInterval = 50; + return now >= m_LastFlushAt + FlushInterval; + } + + llarp_time_t m_LastFlushAt = 0; + using PacketQueue_t = llarp::util::CoDelQueue< net::IPPacket, net::IPPacket::GetTime, net::IPPacket::PutTime, net::IPPacket::CompareOrder, net::IPPacket::GetNow >; From a2fc35a7aac1de24bbe74c498f506192a8b89ccf Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 29 Nov 2019 13:37:19 -0500 Subject: [PATCH 53/58] lower limit to 25ms --- llarp/handlers/tun.cpp | 7 +++++++ llarp/handlers/tun.hpp | 6 +----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 35d769a7d..8baf61ff6 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -32,6 +32,13 @@ namespace llarp m_NetworkToUserPktQueue.Process(send); } + bool + TunEndpoint::ShouldFlushNow(llarp_time_t now) const + { + static constexpr llarp_time_t FlushInterval = 25; + return now >= m_LastFlushAt + FlushInterval; + } + void TunEndpoint::tunifTick(llarp_tun_io *tun) { diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 6a2e7e7eb..2203cbf2f 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -185,11 +185,7 @@ namespace llarp protected: bool - ShouldFlushNow(llarp_time_t now) const - { - static constexpr llarp_time_t FlushInterval = 50; - return now >= m_LastFlushAt + FlushInterval; - } + ShouldFlushNow(llarp_time_t now) const; llarp_time_t m_LastFlushAt = 0; using PacketQueue_t = llarp::util::CoDelQueue< From 3c85691f81ca5e76a48d9cbfeef01e251b41e2c1 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 29 Nov 2019 13:46:58 -0500 Subject: [PATCH 54/58] limit calls to pumpll such that it gets called fast enough but not too much under load --- llarp/ev/ev_libuv.cpp | 2 +- llarp/router/router.cpp | 10 +++++++++- llarp/router/router.hpp | 1 + llarp/util/thread/logic.cpp | 12 ++++++++---- llarp/util/thread/logic.hpp | 12 +++--------- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 1928ace1b..aa9c0f0ee 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -847,7 +847,7 @@ namespace libuv if((uv_now(&m_Impl) - last_time) > 1000) { llarp::LogInfo("UV EVENT LOOP TICKS LAST SECOND: ", loop_run_count, - ", LOGIC THREAD JOBS: ", m_Logic->pendingThreadJobs()); + ", LOGIC THREAD JOBS: ", m_Logic->numPendingJobs()); loop_run_count = 0; last_time = uv_now(&m_Impl); } diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 17aacd206..888d4857c 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -173,9 +173,17 @@ namespace llarp void Router::PumpLL() { + static constexpr size_t PumpJobThreshhold = 50; + static constexpr llarp_time_t PumpInterval = 25; + const auto now = Now(); if(_stopping.load()) return; - + if(_logic->numPendingJobs() >= PumpJobThreshhold + && _lastPump + PumpInterval >= now) + { + return; + } + _lastPump = now; paths.PumpDownstream(); paths.PumpUpstream(); diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 848e520d3..ec171fd79 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -60,6 +60,7 @@ namespace llarp { struct Router final : public AbstractRouter { + llarp_time_t _lastPump = 0; bool ready; // transient iwp encryption key fs::path transport_keyfile = "transport.key"; diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index 9a173ff78..55da1ec1a 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -37,6 +37,12 @@ namespace llarp llarp_free_timer(m_Timer); } + size_t + Logic::numPendingJobs() const + { + return m_Thread->pendingJobs(); + } + bool Logic::queue_job(struct llarp_thread_job job) { @@ -90,10 +96,8 @@ namespace llarp } if(m_Thread->LooksFull(5)) { - LogErrorExplicit(TAG, LINE, - "holy crap, we are trying to queue a job onto the logic " - "thread but " - "it looks full"); + LogErrorExplicit(TAG, LINE, "holy crap, we are trying to queue a job " + "onto the logic thread but it looks full"); METRIC("full"); std::abort(); } diff --git a/llarp/util/thread/logic.hpp b/llarp/util/thread/logic.hpp index d24df61f9..721922d6f 100644 --- a/llarp/util/thread/logic.hpp +++ b/llarp/util/thread/logic.hpp @@ -42,17 +42,12 @@ namespace llarp void remove_call(uint32_t id); + size_t + numPendingJobs() const; + bool can_flush() const; -#ifdef LOKINET_DEBUG - size_t - pendingThreadJobs() const - { - return m_Thread->pendingJobs(); - } -#endif - private: using ID_t = std::thread::id; llarp_threadpool* const m_Thread; @@ -73,5 +68,4 @@ namespace llarp #define LogicCall(l, ...) l->_traceLogicCall(__VA_ARGS__, 0, 0) #endif #endif - #endif From cf3469e11ab9c87d93e668c6a9dbc49cba280d00 Mon Sep 17 00:00:00 2001 From: Rick V Date: Fri, 15 Nov 2019 13:40:43 -0600 Subject: [PATCH 55/58] crash on wine, we support linux, ucb_unix, svr4 natively ffs. i tested this patch on wine 4.4 on fuckin Solaris 11 snv_151 --- daemon/main.cpp | 6 ++++++ llarp/CMakeLists.txt | 1 + llarp/config/config.cpp | 5 +++++ llarp/util/lokinet_init.c | 34 ++++++++++++++++++++++++++++++++++ llarp/util/lokinet_init.h | 24 ++++++++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 llarp/util/lokinet_init.c create mode 100644 llarp/util/lokinet_init.h diff --git a/daemon/main.cpp b/daemon/main.cpp index 1e7124731..9ad3cfab7 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -1,6 +1,7 @@ #include // for ensure_config #include #include +#include #include #include #include @@ -83,6 +84,11 @@ run_main_context(std::string conffname, llarp_main_runtime_opts opts) int main(int argc, char *argv[]) { + auto result = Lokinet_INIT(); + if(result) + { + return result; + } llarp_main_runtime_opts opts; const char *singleThreadVar = getenv("LLARP_SHADOW"); if(singleThreadVar && std::string(singleThreadVar) == "1") diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 8e092160b..b051ecc78 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -25,6 +25,7 @@ set(LIB_UTIL_SRC util/logging/ostream_logger.cpp util/logging/syslog_logger.cpp util/logging/win32_logger.cpp + util/lokinet_init.c util/mem.cpp util/meta/memfn_traits.cpp util/meta/memfn.cpp diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 5aa92b9b2..2bd89ef87 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -468,6 +469,8 @@ namespace llarp bool Config::parse(const ConfigParser &parser) { + if(Lokinet_INIT()) + return false; router = find_section< RouterConfig >(parser, "router"); network = find_section< NetworkConfig >(parser, "network"); connect = find_section< ConnectConfig >(parser, "connect"); @@ -509,6 +512,8 @@ extern "C" bool llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, bool asRouter) { + if(Lokinet_INIT()) + return false; std::error_code ec; if(fs::exists(fname, ec) && !overwrite) { diff --git a/llarp/util/lokinet_init.c b/llarp/util/lokinet_init.c new file mode 100644 index 000000000..a401f8144 --- /dev/null +++ b/llarp/util/lokinet_init.c @@ -0,0 +1,34 @@ +#include +#if defined(_WIN32) +#include +#include +#include + +int +Lokinet_INIT(void) +{ + static const char *(CDECL * pwine_get_version)(void); + HMODULE hntdll = GetModuleHandle("ntdll.dll"); + if(hntdll) + { + pwine_get_version = (void *)GetProcAddress(hntdll, "wine_get_version"); + if(pwine_get_version) + { + static const char *text = + "dont run lokinet in wine like wtf man we support linux and pretty " + "much every flavor of BSD.\nThis Program Will now crash lmao."; + static const char *title = "srsly fam wtf"; + MessageBoxA(NULL, text, title, MB_ICONEXCLAMATION | MB_OK); + abort(); + } + } + return 0; +} +#else +int +Lokinet_INIT(void) +{ + return 0; +} + +#endif \ No newline at end of file diff --git a/llarp/util/lokinet_init.h b/llarp/util/lokinet_init.h new file mode 100644 index 000000000..d63cdba2a --- /dev/null +++ b/llarp/util/lokinet_init.h @@ -0,0 +1,24 @@ +#ifndef LLARP_UTIL_LOKINET_INIT_H +#define LLARP_UTIL_LOKINET_INIT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef Lokinet_INIT +#if defined(_WIN32) +#define Lokinet_INIT \ + DieInCaseSomehowThisGetsRunInWineButLikeWTFThatShouldNotHappenButJustInCaseHandleItWithAPopupOrSomeShit +#else +#define Lokinet_INIT _lokinet_non_shit_platform_INIT +#endif +#endif + + int + Lokinet_INIT(void); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file From 44e8d07d47f5e87a2cb41265467c927b768eacc1 Mon Sep 17 00:00:00 2001 From: Rick V Date: Fri, 15 Nov 2019 13:51:45 -0600 Subject: [PATCH 56/58] fix error msg --- llarp/util/lokinet_init.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/llarp/util/lokinet_init.c b/llarp/util/lokinet_init.c index a401f8144..34be28086 100644 --- a/llarp/util/lokinet_init.c +++ b/llarp/util/lokinet_init.c @@ -16,9 +16,10 @@ Lokinet_INIT(void) { static const char *text = "dont run lokinet in wine like wtf man we support linux and pretty " - "much every flavor of BSD.\nThis Program Will now crash lmao."; + "much every flavour of BSD, and even some flavours of unix system " + "5.x.\nThis Program Will now crash lmao."; static const char *title = "srsly fam wtf"; - MessageBoxA(NULL, text, title, MB_ICONEXCLAMATION | MB_OK); + MessageBoxA(NULL, text, title, MB_ICONHAND); abort(); } } @@ -31,4 +32,4 @@ Lokinet_INIT(void) return 0; } -#endif \ No newline at end of file +#endif From 7e2df0283ae153cb3f46d28210f54d4519cff39b Mon Sep 17 00:00:00 2001 From: Rick V Date: Sun, 1 Dec 2019 20:14:24 -0600 Subject: [PATCH 57/58] set default bootstrap-uri for legacy ui --- ui-win32/Properties/AssemblyInfo.cs | 14 +- ui-win32/dlgBootstrap.Designer.cs | 120 +++--- ui-win32/dlgBootstrap.resx | 553 ++++++++++++++-------------- 3 files changed, 345 insertions(+), 342 deletions(-) diff --git a/ui-win32/Properties/AssemblyInfo.cs b/ui-win32/Properties/AssemblyInfo.cs index d09b6bde3..0d4c77e78 100644 --- a/ui-win32/Properties/AssemblyInfo.cs +++ b/ui-win32/Properties/AssemblyInfo.cs @@ -10,11 +10,11 @@ using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("LokiNET")] -[assembly: AssemblyDescription("LokiNET end-user UI")] +[assembly: AssemblyTitle("Lokinet for Windows")] +[assembly: AssemblyDescription("Lokinet end-user UI")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Loki Project")] -[assembly: AssemblyProduct("LokiNET Launcher")] +[assembly: AssemblyProduct("Lokinet Launcher")] [assembly: AssemblyCopyright("Copyright ©2018-2019 Loki Project. All rights reserved. See LICENSE for more details.")] [assembly: AssemblyTrademark("Loki, Loki Project, LokiNET are ™ & ©2018-2019 Loki Foundation")] [assembly: AssemblyCulture("")] @@ -37,10 +37,10 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.5.2")] -[assembly: AssemblyFileVersion("0.5.2")] +[assembly: AssemblyVersion("0.6.0")] +[assembly: AssemblyFileVersion("0.6.0")] #if DEBUG -[assembly: AssemblyInformationalVersion("0.5.2-dev-{chash:8}")] +[assembly: AssemblyInformationalVersion("0.6.0-dev-{chash:8}")] #else -[assembly: AssemblyInformationalVersion("0.5.2 (RELEASE_CODENAME)")] +[assembly: AssemblyInformationalVersion("0.6.0 (RELEASE_CODENAME)")] #endif \ No newline at end of file diff --git a/ui-win32/dlgBootstrap.Designer.cs b/ui-win32/dlgBootstrap.Designer.cs index fffb1caf9..af6f80780 100644 --- a/ui-win32/dlgBootstrap.Designer.cs +++ b/ui-win32/dlgBootstrap.Designer.cs @@ -28,66 +28,66 @@ /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(dlgBootstrap)); - this.label1 = new System.Windows.Forms.Label(); - this.uriBox = new System.Windows.Forms.TextBox(); - this.label2 = new System.Windows.Forms.Label(); - this.btnDownload = new System.Windows.Forms.Button(); - this.btnCancel = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // label1 - // - resources.ApplyResources(this.label1, "label1"); - this.label1.Name = "label1"; - // - // uriBox - // - resources.ApplyResources(this.uriBox, "uriBox"); - this.uriBox.Name = "uriBox"; - // - // label2 - // - resources.ApplyResources(this.label2, "label2"); - this.label2.Name = "label2"; - // - // btnDownload - // - resources.ApplyResources(this.btnDownload, "btnDownload"); - this.btnDownload.DialogResult = System.Windows.Forms.DialogResult.OK; - this.btnDownload.Name = "btnDownload"; - this.btnDownload.UseVisualStyleBackColor = true; - this.btnDownload.Click += new System.EventHandler(this.button1_Click); - // - // btnCancel - // - resources.ApplyResources(this.btnCancel, "btnCancel"); - this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Name = "btnCancel"; - this.btnCancel.UseVisualStyleBackColor = true; - this.btnCancel.Click += new System.EventHandler(this.button1_Click_1); - // - // bootstrap - // - this.AcceptButton = this.btnDownload; - resources.ApplyResources(this, "$this"); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.btnCancel; - this.ControlBox = false; - this.Controls.Add(this.btnCancel); - this.Controls.Add(this.btnDownload); - this.Controls.Add(this.label2); - this.Controls.Add(this.uriBox); - this.Controls.Add(this.label1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "bootstrap"; - this.ShowIcon = false; - this.ShowInTaskbar = false; - this.ResumeLayout(false); - this.PerformLayout(); - + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(dlgBootstrap)); + this.label1 = new System.Windows.Forms.Label(); + this.uriBox = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.btnDownload = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + resources.ApplyResources(this.label1, "label1"); + this.label1.Name = "label1"; + // + // uriBox + // + resources.ApplyResources(this.uriBox, "uriBox"); + this.uriBox.Name = "uriBox"; + // + // label2 + // + resources.ApplyResources(this.label2, "label2"); + this.label2.Name = "label2"; + // + // btnDownload + // + resources.ApplyResources(this.btnDownload, "btnDownload"); + this.btnDownload.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnDownload.Name = "btnDownload"; + this.btnDownload.UseVisualStyleBackColor = true; + this.btnDownload.Click += new System.EventHandler(this.button1_Click); + // + // btnCancel + // + resources.ApplyResources(this.btnCancel, "btnCancel"); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Name = "btnCancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.button1_Click_1); + // + // dlgBootstrap + // + this.AcceptButton = this.btnDownload; + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ControlBox = false; + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnDownload); + this.Controls.Add(this.label2); + this.Controls.Add(this.uriBox); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "dlgBootstrap"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.ResumeLayout(false); + this.PerformLayout(); + } #endregion diff --git a/ui-win32/dlgBootstrap.resx b/ui-win32/dlgBootstrap.resx index a686f5f4e..eab9d99c3 100644 --- a/ui-win32/dlgBootstrap.resx +++ b/ui-win32/dlgBootstrap.resx @@ -1,276 +1,279 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 13, 13 - - - 196, 13 - - - 0 - - - Enter a URI to a node to bootstrap from: - - - label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - - Left, Right - - - 12, 29 - - - 520, 20 - - - 1 - - - uriBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - 12, 52 - - - 347, 13 - - - 2 - - - This file is automatically saved as $APPDATA\.lokinet\bootstrap.signed. - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Bottom - - - 196, 75 - - - 75, 23 - - - 3 - - - OK - - - btnDownload - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Bottom - - - 278, 75 - - - 75, 23 - - - 4 - - - Cancel - - - btnCancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 6, 13 - - - 548, 111 - - - CenterParent - - - bootstrap from web... - - - bootstrap - - - System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + True + + + + 13, 13 + + + 196, 13 + + + 0 + + + Enter a URI to a node to bootstrap from: + + + label1 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 4 + + + + Left, Right + + + 12, 29 + + + 520, 20 + + + 1 + + + https://seed.lokinet.org/bootstrap.signed + + + uriBox + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + True + + + 12, 52 + + + 347, 13 + + + 2 + + + This file is automatically saved as $APPDATA\.lokinet\bootstrap.signed. + + + label2 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 + + + Bottom + + + 196, 75 + + + 75, 23 + + + 3 + + + OK + + + btnDownload + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + Bottom + + + 278, 75 + + + 75, 23 + + + 4 + + + Cancel + + + btnCancel + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + True + + + 6, 13 + + + 548, 111 + + + CenterParent + + + bootstrap from web... + + + dlgBootstrap + + + System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file From da8ee47370f55c2870590b2c3b07db39e13228ed Mon Sep 17 00:00:00 2001 From: Rick V Date: Tue, 3 Dec 2019 11:18:07 -0600 Subject: [PATCH 58/58] tick more often --- llarp/ev/ev_win32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/ev/ev_win32.cpp b/llarp/ev/ev_win32.cpp index 164d64326..18fa91c44 100644 --- a/llarp/ev/ev_win32.cpp +++ b/llarp/ev/ev_win32.cpp @@ -144,7 +144,7 @@ tun_ev_loop(void* unused) while(true) { alert = - GetQueuedCompletionStatus(tun_event_queue, &size, &listener, &ovl, 100); + GetQueuedCompletionStatus(tun_event_queue, &size, &listener, &ovl, EV_TICK_INTERVAL); if(!alert) {