mirror of https://github.com/oxen-io/lokinet
separate white/grey list for active/decommissioned nodes.
allow sessions to decommissioned nodes but not paths.
This commit is contained in:
parent
28ba0b7533
commit
95537804cd
|
@ -77,9 +77,8 @@ namespace llarp::consensus
|
|||
if (next_general_test > now)
|
||||
return std::nullopt;
|
||||
CSRNG rng;
|
||||
next_general_test = now
|
||||
+ std::chrono::duration_cast<time_point_t::duration>(
|
||||
fseconds(TESTING_INTERVAL(rng)));
|
||||
next_general_test =
|
||||
now + std::chrono::duration_cast<time_point_t::duration>(fseconds(TESTING_INTERVAL(rng)));
|
||||
|
||||
// Pull the next element off the queue, but skip ourself, any that are no longer registered, and
|
||||
// any that are currently known to be failing (those are queued for testing separately).
|
||||
|
|
|
@ -382,7 +382,7 @@ namespace llarp
|
|||
replies.emplace_back(new GotRouterMessage(requester, txid, {router->rc()}, false));
|
||||
return;
|
||||
}
|
||||
if (not GetRouter()->ConnectionToRouterAllowed(target.as_array()))
|
||||
if (not GetRouter()->SessionToRouterAllowed(target.as_array()))
|
||||
{
|
||||
// explicitly not allowed
|
||||
replies.emplace_back(new GotRouterMessage(requester, txid, {}, false));
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace llarp
|
|||
|
||||
Key_t peer;
|
||||
// check if we know this in our nodedb first
|
||||
if (not dht.GetRouter()->ConnectionToRouterAllowed(targetKey))
|
||||
if (not dht.GetRouter()->SessionToRouterAllowed(targetKey))
|
||||
{
|
||||
// explicitly disallowed by network
|
||||
replies.emplace_back(new GotRouterMessage(k, txid, {}, false));
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace llarp
|
|||
++itr;
|
||||
}
|
||||
|
||||
if (not m_Router->ConnectionToRouterAllowed(*rid))
|
||||
if (not m_Router->PathToRouterAllowed(*rid))
|
||||
return false;
|
||||
|
||||
ObtainSNodeSession(*rid, [data = payload.copy(), type](auto session) {
|
||||
|
@ -150,7 +150,7 @@ namespace llarp
|
|||
return false;
|
||||
if (auto* rid = std::get_if<RouterID>(&addr))
|
||||
{
|
||||
if (m_SNodeKeys.count(PubKey{*rid}) or m_Router->ConnectionToRouterAllowed(*rid))
|
||||
if (m_SNodeKeys.count(PubKey{*rid}) or m_Router->PathToRouterAllowed(*rid))
|
||||
{
|
||||
ObtainSNodeSession(
|
||||
*rid, [hook, routerID = *rid](std::shared_ptr<exit::BaseSession> session) {
|
||||
|
@ -338,7 +338,7 @@ namespace llarp
|
|||
void
|
||||
ExitEndpoint::ObtainSNodeSession(const RouterID& router, exit::SessionReadyFunc obtainCb)
|
||||
{
|
||||
if (not m_Router->rcLookupHandler().RemoteIsAllowed(router))
|
||||
if (not m_Router->rcLookupHandler().SessionIsAllowed(router))
|
||||
{
|
||||
obtainCb(nullptr);
|
||||
return;
|
||||
|
|
|
@ -279,7 +279,7 @@ namespace llarp
|
|||
#endif
|
||||
}
|
||||
|
||||
if (!self->context->Router()->ConnectionToRouterAllowed(self->hop->info.upstream))
|
||||
if (not self->context->Router()->PathToRouterAllowed(self->hop->info.upstream))
|
||||
{
|
||||
// we are not allowed to forward it ... now what?
|
||||
llarp::LogError(
|
||||
|
|
|
@ -284,7 +284,8 @@ namespace llarp
|
|||
|
||||
/// set router's service node whitelist
|
||||
virtual void
|
||||
SetRouterWhitelist(const std::vector<RouterID> routers) = 0;
|
||||
SetRouterWhitelist(
|
||||
const std::vector<RouterID> whitelist, const std::vector<RouterID> greylist) = 0;
|
||||
|
||||
virtual std::unordered_set<RouterID>
|
||||
GetRouterWhitelist() const = 0;
|
||||
|
@ -294,7 +295,10 @@ namespace llarp
|
|||
ForEachPeer(std::function<void(const ILinkSession*, bool)> visit, bool randomize) const = 0;
|
||||
|
||||
virtual bool
|
||||
ConnectionToRouterAllowed(const RouterID& router) const = 0;
|
||||
SessionToRouterAllowed(const RouterID& router) const = 0;
|
||||
|
||||
virtual bool
|
||||
PathToRouterAllowed(const RouterID& router) const = 0;
|
||||
|
||||
/// return true if we have an exit as a client
|
||||
virtual bool
|
||||
|
|
|
@ -33,13 +33,20 @@ namespace llarp
|
|||
RemoveValidRouter(const RouterID& router) = 0;
|
||||
|
||||
virtual void
|
||||
SetRouterWhitelist(const std::vector<RouterID>& routers) = 0;
|
||||
SetRouterWhitelist(
|
||||
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist) = 0;
|
||||
|
||||
virtual void
|
||||
GetRC(const RouterID& router, RCRequestCallback callback, bool forceLookup = false) = 0;
|
||||
|
||||
virtual bool
|
||||
RemoteIsAllowed(const RouterID& remote) const = 0;
|
||||
PathIsAllowed(const RouterID& remote) const = 0;
|
||||
|
||||
virtual bool
|
||||
SessionIsAllowed(const RouterID& remote) const = 0;
|
||||
|
||||
virtual bool
|
||||
IsGreylisted(const RouterID& remote) const = 0;
|
||||
|
||||
virtual bool
|
||||
CheckRC(const RouterContact& rc) const = 0;
|
||||
|
|
|
@ -26,12 +26,11 @@ namespace llarp
|
|||
const RouterID& remote, const ILinkMessage& msg, SendStatusHandler callback)
|
||||
{
|
||||
// if the destination is invalid, callback with failure and return
|
||||
if (not _linkManager->SessionIsClient(remote) and not _lookupHandler->RemoteIsAllowed(remote))
|
||||
if (not _linkManager->SessionIsClient(remote) and not _lookupHandler->SessionIsAllowed(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);
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace llarp
|
|||
LogInfo(
|
||||
"session with ", remoteType, " [", router, "] ", isOutbound ? "established" : "received");
|
||||
|
||||
if (not _rcLookup->RemoteIsAllowed(router))
|
||||
if (not _rcLookup->SessionIsAllowed(router))
|
||||
{
|
||||
FinalizeRequest(router, SessionResult::InvalidRouter);
|
||||
return false;
|
||||
|
@ -132,7 +132,7 @@ namespace llarp
|
|||
break;
|
||||
|
||||
exclude.insert(other.pubkey);
|
||||
if (not _rcLookup->RemoteIsAllowed(other.pubkey))
|
||||
if (not _rcLookup->SessionIsAllowed(other.pubkey))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ namespace llarp
|
|||
{
|
||||
_loop->call([this, router] { DoEstablish(router); });
|
||||
}
|
||||
else if(_linkManager->HasSessionTo(router))
|
||||
else if (_linkManager->HasSessionTo(router))
|
||||
{
|
||||
FinalizeRequest(router, SessionResult::Establish);
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ namespace llarp
|
|||
bool
|
||||
OutboundSessionMaker::ShouldConnectTo(const RouterID& router) const
|
||||
{
|
||||
if (router == us or not _rcLookup->RemoteIsAllowed(router))
|
||||
if (router == us or not _rcLookup->SessionIsAllowed(router))
|
||||
return false;
|
||||
size_t numPending = 0;
|
||||
{
|
||||
|
|
|
@ -33,17 +33,23 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
RCLookupHandler::SetRouterWhitelist(const std::vector<RouterID>& routers)
|
||||
RCLookupHandler::SetRouterWhitelist(
|
||||
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist)
|
||||
{
|
||||
if (routers.empty())
|
||||
if (whitelist.empty())
|
||||
return;
|
||||
util::Lock l(_mutex);
|
||||
|
||||
whitelistRouters.clear();
|
||||
for (auto& router : routers)
|
||||
greylistRouters.clear();
|
||||
for (auto& router : whitelist)
|
||||
{
|
||||
whitelistRouters.emplace(router);
|
||||
}
|
||||
for (auto& router : greylist)
|
||||
{
|
||||
greylistRouters.emplace(router);
|
||||
}
|
||||
|
||||
LogInfo("lokinet service node list now has ", whitelistRouters.size(), " routers");
|
||||
}
|
||||
|
@ -119,7 +125,24 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
RCLookupHandler::RemoteIsAllowed(const RouterID& remote) const
|
||||
RCLookupHandler::IsGreylisted(const RouterID& remote) const
|
||||
{
|
||||
if (_strictConnectPubkeys.size() && _strictConnectPubkeys.count(remote) == 0
|
||||
&& !RemoteInBootstrap(remote))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not useWhitelist)
|
||||
return false;
|
||||
|
||||
util::Lock lock{_mutex};
|
||||
|
||||
return greylistRouters.count(remote);
|
||||
}
|
||||
|
||||
bool
|
||||
RCLookupHandler::PathIsAllowed(const RouterID& remote) const
|
||||
{
|
||||
if (_strictConnectPubkeys.size() && _strictConnectPubkeys.count(remote) == 0
|
||||
&& !RemoteInBootstrap(remote))
|
||||
|
@ -135,10 +158,27 @@ namespace llarp
|
|||
return whitelistRouters.count(remote);
|
||||
}
|
||||
|
||||
bool
|
||||
RCLookupHandler::SessionIsAllowed(const RouterID& remote) const
|
||||
{
|
||||
if (_strictConnectPubkeys.size() && _strictConnectPubkeys.count(remote) == 0
|
||||
&& !RemoteInBootstrap(remote))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not useWhitelist)
|
||||
return true;
|
||||
|
||||
util::Lock lock{_mutex};
|
||||
|
||||
return whitelistRouters.count(remote) or greylistRouters.count(remote);
|
||||
}
|
||||
|
||||
bool
|
||||
RCLookupHandler::CheckRC(const RouterContact& rc) const
|
||||
{
|
||||
if (not RemoteIsAllowed(rc.pubkey))
|
||||
if (not SessionIsAllowed(rc.pubkey))
|
||||
{
|
||||
_dht->impl->DelRCNodeAsync(dht::Key_t{rc.pubkey});
|
||||
return false;
|
||||
|
@ -189,7 +229,7 @@ namespace llarp
|
|||
if (newrc.pubkey != oldrc.pubkey)
|
||||
return false;
|
||||
|
||||
if (!RemoteIsAllowed(newrc.pubkey))
|
||||
if (!SessionIsAllowed(newrc.pubkey))
|
||||
return false;
|
||||
|
||||
auto func = std::bind(&RCLookupHandler::CheckRC, this, newrc);
|
||||
|
@ -332,7 +372,7 @@ namespace llarp
|
|||
return;
|
||||
}
|
||||
|
||||
if (not RemoteIsAllowed(remote))
|
||||
if (not SessionIsAllowed(remote))
|
||||
{
|
||||
FinalizeRequest(remote, &results[0], RCRequestResult::InvalidRouter);
|
||||
return;
|
||||
|
|
|
@ -41,7 +41,9 @@ namespace llarp
|
|||
RemoveValidRouter(const RouterID& router) override EXCLUDES(_mutex);
|
||||
|
||||
void
|
||||
SetRouterWhitelist(const std::vector<RouterID>& routers) override EXCLUDES(_mutex);
|
||||
SetRouterWhitelist(
|
||||
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist) override
|
||||
EXCLUDES(_mutex);
|
||||
|
||||
bool
|
||||
HaveReceivedWhitelist() const override;
|
||||
|
@ -51,7 +53,13 @@ namespace llarp
|
|||
EXCLUDES(_mutex);
|
||||
|
||||
bool
|
||||
RemoteIsAllowed(const RouterID& remote) const override EXCLUDES(_mutex);
|
||||
PathIsAllowed(const RouterID& remote) const override EXCLUDES(_mutex);
|
||||
|
||||
bool
|
||||
SessionIsAllowed(const RouterID& remote) const override EXCLUDES(_mutex);
|
||||
|
||||
bool
|
||||
IsGreylisted(const RouterID& remote) const override EXCLUDES(_mutex);
|
||||
|
||||
bool
|
||||
CheckRC(const RouterContact& rc) const override;
|
||||
|
@ -127,6 +135,7 @@ namespace llarp
|
|||
bool isServiceNode = false;
|
||||
|
||||
std::unordered_set<RouterID> whitelistRouters GUARDED_BY(_mutex);
|
||||
std::unordered_set<RouterID> greylistRouters GUARDED_BY(_mutex);
|
||||
|
||||
using TimePoint = std::chrono::steady_clock::time_point;
|
||||
std::unordered_map<RouterID, TimePoint> _routerLookupTimes;
|
||||
|
|
|
@ -380,18 +380,24 @@ namespace llarp
|
|||
Router::LooksDeregistered() const
|
||||
{
|
||||
return IsServiceNode() and whitelistRouters and _rcLookupHandler.HaveReceivedWhitelist()
|
||||
and not _rcLookupHandler.RemoteIsAllowed(pubkey());
|
||||
and _rcLookupHandler.IsGreylisted(pubkey());
|
||||
}
|
||||
|
||||
bool
|
||||
Router::ConnectionToRouterAllowed(const RouterID& router) const
|
||||
Router::SessionToRouterAllowed(const RouterID& router) const
|
||||
{
|
||||
return _rcLookupHandler.SessionIsAllowed(router);
|
||||
}
|
||||
|
||||
bool
|
||||
Router::PathToRouterAllowed(const RouterID& router) const
|
||||
{
|
||||
if (LooksDeregistered())
|
||||
{
|
||||
// we are deregistered don't allow any connections outbound at all
|
||||
// we are deregistered don't allow any paths outbound at all
|
||||
return false;
|
||||
}
|
||||
return _rcLookupHandler.RemoteIsAllowed(router);
|
||||
return _rcLookupHandler.PathIsAllowed(router);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -817,7 +823,7 @@ namespace llarp
|
|||
// the whitelist enabled and we got the whitelist
|
||||
// check against the whitelist and remove if it's not
|
||||
// in the whitelist OR if there is no whitelist don't remove
|
||||
return not _rcLookupHandler.RemoteIsAllowed(rc.pubkey);
|
||||
return not _rcLookupHandler.SessionIsAllowed(rc.pubkey);
|
||||
});
|
||||
|
||||
// find all deregistered relays
|
||||
|
@ -829,7 +835,7 @@ namespace llarp
|
|||
if (not session)
|
||||
return;
|
||||
const auto pk = session->GetPubKey();
|
||||
if (session->IsRelay() and not _rcLookupHandler.RemoteIsAllowed(pk))
|
||||
if (session->IsRelay() and not _rcLookupHandler.SessionIsAllowed(pk))
|
||||
{
|
||||
closePeers.emplace(pk);
|
||||
}
|
||||
|
@ -1034,9 +1040,10 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
Router::SetRouterWhitelist(const std::vector<RouterID> routers)
|
||||
Router::SetRouterWhitelist(
|
||||
const std::vector<RouterID> whitelist, const std::vector<RouterID> greylist)
|
||||
{
|
||||
_rcLookupHandler.SetRouterWhitelist(routers);
|
||||
_rcLookupHandler.SetRouterWhitelist(whitelist, greylist);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1202,17 +1209,27 @@ namespace llarp
|
|||
// try to make a session to this random router
|
||||
// this will do a dht lookup if needed
|
||||
_outboundSessionMaker.CreateSessionTo(
|
||||
router, [previous_fails=fails, this](const auto& router, const auto result) {
|
||||
router, [previous_fails = fails, this](const auto& router, const auto result) {
|
||||
auto rpc = RpcClient();
|
||||
|
||||
if (result != SessionResult::Establish)
|
||||
{
|
||||
// failed connection mark it as so
|
||||
m_routerTesting.add_failing_node(router, previous_fails);
|
||||
LogInfo("FAILED SN connection test to ", router, " (", previous_fails + 1, " consecutive failures)");
|
||||
LogInfo(
|
||||
"FAILED SN connection test to ",
|
||||
router,
|
||||
" (",
|
||||
previous_fails + 1,
|
||||
" consecutive failures)");
|
||||
}
|
||||
else if (previous_fails > 0)
|
||||
LogInfo("Successful SN connection test to ", router, " after ", previous_fails, " failures");
|
||||
LogInfo(
|
||||
"Successful SN connection test to ",
|
||||
router,
|
||||
" after ",
|
||||
previous_fails,
|
||||
" failures");
|
||||
else
|
||||
LogDebug("Successful SN connection test to ", router);
|
||||
|
||||
|
@ -1358,7 +1375,7 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!_rcLookupHandler.RemoteIsAllowed(rc.pubkey))
|
||||
if (not _rcLookupHandler.SessionIsAllowed(rc.pubkey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,8 @@ namespace llarp
|
|||
ModifyOurRC(std::function<std::optional<RouterContact>(RouterContact)> modify) override;
|
||||
|
||||
void
|
||||
SetRouterWhitelist(const std::vector<RouterID> routers) override;
|
||||
SetRouterWhitelist(
|
||||
const std::vector<RouterID> whitelist, const std::vector<RouterID> greylist) override;
|
||||
|
||||
std::unordered_set<RouterID>
|
||||
GetRouterWhitelist() const override
|
||||
|
@ -398,7 +399,9 @@ namespace llarp
|
|||
EnsureEncryptionKey();
|
||||
|
||||
bool
|
||||
ConnectionToRouterAllowed(const RouterID& router) const override;
|
||||
SessionToRouterAllowed(const RouterID& router) const override;
|
||||
bool
|
||||
PathToRouterAllowed(const RouterID& router) const override;
|
||||
|
||||
void
|
||||
HandleSaveRC() const;
|
||||
|
|
|
@ -111,8 +111,9 @@ namespace llarp
|
|||
nlohmann::json request, fields;
|
||||
fields["pubkey_ed25519"] = true;
|
||||
fields["service_node_pubkey"] = true;
|
||||
fields["funded"] = true;
|
||||
fields["active"] = true;
|
||||
request["fields"] = fields;
|
||||
request["active_only"] = true;
|
||||
if (not topblock.empty())
|
||||
request["poll_block_hash"] = topblock;
|
||||
m_UpdatingList = true;
|
||||
|
@ -187,7 +188,7 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
std::unordered_map<RouterID, PubKey> keymap;
|
||||
std::vector<RouterID> nodeList;
|
||||
std::vector<RouterID> activeNodeList, nonActiveNodeList;
|
||||
{
|
||||
const auto itr = j.find("service_node_states");
|
||||
if (itr != j.end() and itr->is_array())
|
||||
|
@ -200,18 +201,33 @@ namespace llarp
|
|||
const auto svc_itr = j_itr->find("service_node_pubkey");
|
||||
if (svc_itr == j_itr->end() or not svc_itr->is_string())
|
||||
continue;
|
||||
const auto funded_itr = j_itr->find("funded");
|
||||
if (funded_itr == j_itr->end() or not funded_itr->is_boolean())
|
||||
continue;
|
||||
const auto active_itr = j_itr->find("active");
|
||||
if (active_itr == j_itr->end() or not active_itr->is_boolean())
|
||||
continue;
|
||||
const bool active = active_itr->get<bool>();
|
||||
const bool funded = funded_itr->get<bool>();
|
||||
|
||||
if (not funded)
|
||||
continue;
|
||||
|
||||
RouterID rid;
|
||||
PubKey pk;
|
||||
if (rid.FromHex(ed_itr->get<std::string>()) and pk.FromHex(svc_itr->get<std::string>()))
|
||||
{
|
||||
keymap[rid] = pk;
|
||||
nodeList.emplace_back(std::move(rid));
|
||||
if (active)
|
||||
activeNodeList.emplace_back(std::move(rid));
|
||||
else
|
||||
nonActiveNodeList.emplace_back(std::move(rid));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeList.empty())
|
||||
if (activeNodeList.empty())
|
||||
{
|
||||
LogWarn("got empty service node list, ignoring.");
|
||||
return;
|
||||
|
@ -219,12 +235,11 @@ namespace llarp
|
|||
// inform router about the new list
|
||||
if (auto router = m_Router.lock())
|
||||
{
|
||||
router->loop()->call(
|
||||
[this, nodeList = std::move(nodeList), keymap = std::move(keymap)]() mutable {
|
||||
m_KeyMap = std::move(keymap);
|
||||
if (auto router = m_Router.lock())
|
||||
router->SetRouterWhitelist(std::move(nodeList));
|
||||
});
|
||||
router->loop()->call([this, activeNodeList, nonActiveNodeList, keymap]() {
|
||||
m_KeyMap = keymap;
|
||||
if (auto router = m_Router.lock())
|
||||
router->SetRouterWhitelist(activeNodeList, nonActiveNodeList);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue