try to handle router deregistrations on the network better (#1461)

* don't send messages to de-registered relays but allow traffic to clients

* actively close sessions to de-registered relays
pull/1465/head
Jeff 4 years ago committed by GitHub
parent 4eb275324d
commit a0ed303d7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -150,6 +150,7 @@ add_library(liblokinet
iwp/message_buffer.cpp
iwp/session.cpp
link/link_manager.cpp
link/session.cpp
link/server.cpp
messages/dht_immediate.cpp
messages/link_intro.cpp

@ -7,6 +7,7 @@
#include <peerstats/peer_db.hpp>
#include <functional>
#include <optional>
struct llarp_buffer_t;
@ -38,6 +39,12 @@ namespace llarp
virtual bool
HasSessionTo(const RouterID& remote) const = 0;
/// return true if the session with this pubkey is a client
/// return false if the session with this pubkey is a router
/// return std::nullopt we have no session with this pubkey
virtual std::optional<bool>
SessionIsClient(RouterID remote) const = 0;
virtual void
PumpLinks() = 0;
@ -63,6 +70,11 @@ namespace llarp
virtual void
ForEachInboundLink(std::function<void(LinkLayer_ptr)> visit) const = 0;
/// close all connections to this peer
/// remove all link layer commits
virtual void
DeregisterPeer(RouterID remote) = 0;
virtual size_t
NumberOfConnectedRouters() const = 0;

@ -60,6 +60,38 @@ namespace llarp
return GetLinkWithSessionTo(remote) != nullptr;
}
std::optional<bool>
LinkManager::SessionIsClient(RouterID remote) const
{
for (const auto& link : inboundLinks)
{
const auto session = link->FindSessionByPubkey(remote);
if (session)
return not session->IsRelay();
}
for (const auto& link : outboundLinks)
{
if (link->HasSessionTo(remote))
return false;
}
return std::nullopt;
}
void
LinkManager::DeregisterPeer(RouterID remote)
{
m_PersistingSessions.erase(remote);
for (const auto& link : inboundLinks)
{
link->CloseSessionTo(remote);
}
for (const auto& link : outboundLinks)
{
link->CloseSessionTo(remote);
}
LogInfo(remote, " has been de-registered");
}
void
LinkManager::PumpLinks()
{

@ -34,6 +34,12 @@ namespace llarp
bool
HasSessionTo(const RouterID& remote) const override;
std::optional<bool>
SessionIsClient(RouterID remote) const override;
void
DeregisterPeer(RouterID remote) override;
void
PumpLinks() override;

@ -48,6 +48,16 @@ namespace llarp
return m_AuthedLinks.find(id) != m_AuthedLinks.end();
}
std::shared_ptr<ILinkSession>
ILinkLayer::FindSessionByPubkey(RouterID id)
{
Lock_t l(m_AuthedLinksMutex);
auto itr = m_AuthedLinks.find(id);
if (itr == m_AuthedLinks.end())
return nullptr;
return itr->second;
}
void
ILinkLayer::ForEachSession(std::function<void(const ILinkSession*)> visit, bool randomize) const
{

@ -121,6 +121,10 @@ namespace llarp
virtual std::shared_ptr<ILinkSession>
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) = 0;
/// fetch a session by the identity pubkey it claims
std::shared_ptr<ILinkSession>
FindSessionByPubkey(RouterID pk);
virtual void
Pump();

@ -0,0 +1,11 @@
#include <link/session.hpp>
namespace llarp
{
bool
ILinkSession::IsRelay() const
{
return GetRemoteRC().IsPublicRouter();
}
} // namespace llarp

@ -102,6 +102,10 @@ namespace llarp
virtual RouterContact
GetRemoteRC() const = 0;
/// is this session a session to a relay?
bool
IsRelay() const;
/// handle a valid LIM
std::function<bool(const LinkIntroMessage* msg)> GotLIM;

@ -2,6 +2,7 @@
#include <messages/link_message.hpp>
#include <router/i_outbound_session_maker.hpp>
#include <router/i_rc_lookup_handler.hpp>
#include <link/i_link_manager.hpp>
#include <constants/link_layer.hpp>
#include <util/meta/memfn.hpp>
@ -22,6 +23,12 @@ namespace llarp
OutboundMessageHandler::QueueMessage(
const RouterID& remote, const ILinkMessage* msg, SendStatusHandler callback)
{
if (not _linkManager->SessionIsClient(remote) and not _lookupHandler->RemoteIsAllowed(remote))
{
DoCallback(callback, SendStatus::InvalidRouter);
return true;
}
const uint16_t priority = msg->Priority();
std::array<byte_t, MAX_LINK_MSG_SIZE> linkmsg_buffer;
llarp_buffer_t buf(linkmsg_buffer);
@ -105,9 +112,11 @@ namespace llarp
}
void
OutboundMessageHandler::Init(ILinkManager* linkManager, std::shared_ptr<Logic> logic)
OutboundMessageHandler::Init(
ILinkManager* linkManager, I_RCLookupHandler* lookupHandler, std::shared_ptr<Logic> logic)
{
_linkManager = linkManager;
_lookupHandler = lookupHandler;
_logic = logic;
outboundMessageQueues.emplace(zeroID, MessageQueue());

@ -18,6 +18,7 @@ struct llarp_buffer_t;
namespace llarp
{
struct ILinkManager;
struct I_RCLookupHandler;
class Logic;
enum class SessionResult;
@ -42,7 +43,7 @@ namespace llarp
ExtractStatus() const override;
void
Init(ILinkManager* linkManager, std::shared_ptr<Logic> logic);
Init(ILinkManager* linkManager, I_RCLookupHandler* lookupHandler, std::shared_ptr<Logic> logic);
private:
using Message = std::pair<std::vector<byte_t>, SendStatusHandler>;
@ -137,6 +138,7 @@ namespace llarp
std::queue<PathID_t> roundRobinOrder;
ILinkManager* _linkManager;
I_RCLookupHandler* _lookupHandler;
std::shared_ptr<Logic> _logic;
util::ContentionKiller m_Killer;

@ -551,7 +551,7 @@ namespace llarp
LogInfo("Loaded ", bootstrapRCList.size(), " bootstrap routers");
// Init components after relevant config settings loaded
_outboundMessageHandler.Init(&_linkManager, _logic);
_outboundMessageHandler.Init(&_linkManager, &_rcLookupHandler, _logic);
_outboundSessionMaker.Init(
this,
&_linkManager,
@ -784,6 +784,25 @@ namespace llarp
return not _rcLookupHandler.RemoteIsAllowed(rc.pubkey);
});
// find all deregistered relays
std::unordered_set<PubKey, PubKey::Hash> closePeers;
_linkManager.ForEachPeer([&](auto session) {
if (whitelistRouters and not gotWhitelist)
return;
if (not session)
return;
const auto pk = session->GetPubKey();
if (session->IsRelay() and not _rcLookupHandler.RemoteIsAllowed(pk))
{
closePeers.emplace(pk);
}
});
// mark peers as de-registered
for (auto& peer : closePeers)
_linkManager.DeregisterPeer(std::move(peer));
_linkManager.CheckPersistingSessions(now);
if (HasClientExit())

Loading…
Cancel
Save