From 51b7566a46b50224bbd9c1535981981b2f697a0d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 11 May 2021 09:10:16 -0400 Subject: [PATCH] if we look deregistered we will now: * not gossip our rc * not explore the network to prevent outbound session attempts * not establish sessions to other service nodes * close all open sessions we have to tell clients we don't want them * catch exceptions flushing peerdb in disk thread * don't connect out to non allowed routers * simplify logic in RCLookupHandler::RemoteIsAllowed() * add HaveReceivedWhitelist to I_RCLookupHandler base type * add LooksDeregistered to Router type that tells us if we think we are deregistered * don't allow building paths over us if we are deregistered --- llarp/router/i_rc_lookup_handler.hpp | 3 ++ llarp/router/outbound_session_maker.cpp | 2 +- llarp/router/rc_lookup_handler.cpp | 12 +++---- llarp/router/rc_lookup_handler.hpp | 2 +- llarp/router/router.cpp | 42 ++++++++++++++++++++++--- llarp/router/router.hpp | 4 +++ 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/llarp/router/i_rc_lookup_handler.hpp b/llarp/router/i_rc_lookup_handler.hpp index 42ad1f0ef..7883dd3b4 100644 --- a/llarp/router/i_rc_lookup_handler.hpp +++ b/llarp/router/i_rc_lookup_handler.hpp @@ -58,6 +58,9 @@ namespace llarp virtual size_t NumberOfStrictConnectRouters() const = 0; + + virtual bool + HaveReceivedWhitelist() const = 0; }; } // namespace llarp diff --git a/llarp/router/outbound_session_maker.cpp b/llarp/router/outbound_session_maker.cpp index c980ed592..8846a38ec 100644 --- a/llarp/router/outbound_session_maker.cpp +++ b/llarp/router/outbound_session_maker.cpp @@ -232,7 +232,7 @@ namespace llarp bool OutboundSessionMaker::ShouldConnectTo(const RouterID& router) const { - if (router == us) + if (router == us or not _rcLookup->RemoteIsAllowed(router)) return false; size_t numPending = 0; { diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index 12b8b1beb..76ae45053 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -49,7 +49,7 @@ namespace llarp } bool - RCLookupHandler::HaveReceivedWhitelist() + RCLookupHandler::HaveReceivedWhitelist() const { util::Lock l(_mutex); return not whitelistRouters.empty(); @@ -127,14 +127,12 @@ namespace llarp return false; } - util::Lock l(_mutex); + if (not useWhitelist) + return true; - if (useWhitelist && whitelistRouters.find(remote) == whitelistRouters.end()) - { - return false; - } + util::Lock lock{_mutex}; - return true; + return whitelistRouters.count(remote); } bool diff --git a/llarp/router/rc_lookup_handler.hpp b/llarp/router/rc_lookup_handler.hpp index a3b88e924..cc0bed223 100644 --- a/llarp/router/rc_lookup_handler.hpp +++ b/llarp/router/rc_lookup_handler.hpp @@ -44,7 +44,7 @@ namespace llarp SetRouterWhitelist(const std::vector& routers) override EXCLUDES(_mutex); bool - HaveReceivedWhitelist(); + HaveReceivedWhitelist() const override; void GetRC(const RouterID& router, RCRequestCallback callback, bool forceLookup = false) override diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 1f4151321..bff2aa155 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -374,9 +374,21 @@ namespace llarp return inbound_routing_msg_parser.ParseMessageBuffer(buf, h, rxid, this); } + bool + Router::LooksDeregistered() const + { + return IsServiceNode() and whitelistRouters and _rcLookupHandler.HaveReceivedWhitelist() + and not _rcLookupHandler.RemoteIsAllowed(pubkey()); + } + bool Router::ConnectionToRouterAllowed(const RouterID& router) const { + if (LooksDeregistered()) + { + // we are deregistered don't allow any connections outbound at all + return false; + } return _rcLookupHandler.RemoteIsAllowed(router); } @@ -766,7 +778,9 @@ namespace llarp _rcLookupHandler.PeriodicUpdate(now); + const bool gotWhitelist = _rcLookupHandler.HaveReceivedWhitelist(); const bool isSvcNode = IsServiceNode(); + const bool looksDeregistered = LooksDeregistered(); if (_rc.ExpiresSoon(now, std::chrono::milliseconds(randint() % 10000)) || (now - _rc.last_updated) > rcRegenInterval) @@ -775,11 +789,10 @@ namespace llarp if (!UpdateOurRC(false)) LogError("Failed to update our RC"); } - else + else if (not looksDeregistered) { GossipRCIfNeeded(_rc); } - const bool gotWhitelist = _rcLookupHandler.HaveReceivedWhitelist(); // remove RCs for nodes that are no longer allowed by network policy nodedb()->RemoveIf([&](const RouterContact& rc) -> bool { // don't purge bootstrap nodes from nodedb @@ -847,7 +860,7 @@ namespace llarp const int interval = isSvcNode ? 5 : 2; const auto timepoint_now = Clock_t::now(); - if (timepoint_now >= m_NextExploreAt) + if (timepoint_now >= m_NextExploreAt and not looksDeregistered) { _rcLookupHandler.ExploreNetwork(); m_NextExploreAt = timepoint_now + std::chrono::seconds(interval); @@ -859,7 +872,17 @@ namespace llarp connectToNum = strictConnect; } - if (connected < connectToNum) + if (looksDeregistered) + { + // kill all sessions that are open because we think we are deregistered + _linkManager.ForEachPeer([](auto* peer) { + if (peer) + peer->Close(); + }); + // complain about being deregistered + LogError("We are running as a service node but we seem to be decommissioned"); + } + else if (connected < connectToNum) { size_t dlt = connectToNum - connected; LogDebug("connecting to ", dlt, " random routers to keep alive"); @@ -886,7 +909,16 @@ namespace llarp if (m_peerDb->shouldFlush(now)) { LogDebug("Queing database flush..."); - QueueDiskIO([this]() { m_peerDb->flushDatabase(); }); + QueueDiskIO([this]() { + try + { + m_peerDb->flushDatabase(); + } + catch (std::exception& ex) + { + LogError("Could not flush peer stats database: ", ex.what()); + } + }); } } diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 697eb401d..188f2c0ee 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -181,6 +181,10 @@ namespace llarp void QueueDiskIO(std::function func) override; + /// return true if we look like we are a deregistered service node + bool + LooksDeregistered() const; + std::optional _ourAddress; EventLoop_ptr _loop;