mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
remove rc_lookup_handler, relocating useful parts
RC "lookup" is being replaced with "gimme all recently updated RCs". As such, doing a lookup on a specific RC is going away, as is network exploration, so a lot of what RCLookupHandler was doing will no longer be relevant. Functionality from it which was kept has moved to NodeDB, as it makes sense for that functionality to live where the RCs live.
This commit is contained in:
parent
28047ae72f
commit
ad9d0b19c1
12 changed files with 247 additions and 643 deletions
|
@ -109,7 +109,6 @@ lokinet_add_library(lokinet-time-place
|
||||||
# lokinet-platform holds all platform specific code
|
# lokinet-platform holds all platform specific code
|
||||||
lokinet_add_library(lokinet-platform
|
lokinet_add_library(lokinet-platform
|
||||||
net/interface_info.cpp
|
net/interface_info.cpp
|
||||||
router/rc_lookup_handler.cpp
|
|
||||||
vpn/packet_router.cpp
|
vpn/packet_router.cpp
|
||||||
vpn/platform.cpp
|
vpn/platform.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
#include <llarp/dns/dns.hpp>
|
#include <llarp/dns/dns.hpp>
|
||||||
#include <llarp/net/net.hpp>
|
#include <llarp/net/net.hpp>
|
||||||
|
#include <llarp/nodedb.hpp>
|
||||||
#include <llarp/path/path_context.hpp>
|
#include <llarp/path/path_context.hpp>
|
||||||
#include <llarp/router/rc_lookup_handler.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
#include <llarp/router/router.hpp>
|
||||||
#include <llarp/service/protocol_type.hpp>
|
#include <llarp/service/protocol_type.hpp>
|
||||||
|
|
||||||
|
@ -243,9 +243,8 @@ namespace llarp::handlers
|
||||||
{
|
{
|
||||||
if (msg.questions[0].IsName("random.snode"))
|
if (msg.questions[0].IsName("random.snode"))
|
||||||
{
|
{
|
||||||
RouterID random;
|
if (auto random = GetRouter()->GetRandomGoodRouter())
|
||||||
if (GetRouter()->GetRandomGoodRouter(random))
|
msg.AddCNAMEReply(random->ToString(), 1);
|
||||||
msg.AddCNAMEReply(random.ToString(), 1);
|
|
||||||
else
|
else
|
||||||
msg.AddNXReply();
|
msg.AddNXReply();
|
||||||
}
|
}
|
||||||
|
@ -263,11 +262,10 @@ namespace llarp::handlers
|
||||||
const bool isV4 = msg.questions[0].qtype == dns::qTypeA;
|
const bool isV4 = msg.questions[0].qtype == dns::qTypeA;
|
||||||
if (msg.questions[0].IsName("random.snode"))
|
if (msg.questions[0].IsName("random.snode"))
|
||||||
{
|
{
|
||||||
RouterID random;
|
if (auto random = GetRouter()->GetRandomGoodRouter())
|
||||||
if (GetRouter()->GetRandomGoodRouter(random))
|
|
||||||
{
|
{
|
||||||
msg.AddCNAMEReply(random.ToString(), 1);
|
msg.AddCNAMEReply(random->ToString(), 1);
|
||||||
auto ip = ObtainServiceNodeIP(random);
|
auto ip = ObtainServiceNodeIP(*random);
|
||||||
msg.AddINReply(ip, false);
|
msg.AddINReply(ip, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -333,7 +331,7 @@ namespace llarp::handlers
|
||||||
void
|
void
|
||||||
ExitEndpoint::ObtainSNodeSession(const RouterID& rid, exit::SessionReadyFunc obtain_cb)
|
ExitEndpoint::ObtainSNodeSession(const RouterID& rid, exit::SessionReadyFunc obtain_cb)
|
||||||
{
|
{
|
||||||
if (not router->rc_lookup_handler().is_session_allowed(rid))
|
if (not router->node_db()->is_connection_allowed(rid))
|
||||||
{
|
{
|
||||||
obtain_cb(nullptr);
|
obtain_cb(nullptr);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -705,10 +705,9 @@ namespace llarp::handlers
|
||||||
{
|
{
|
||||||
if (is_random_snode(msg))
|
if (is_random_snode(msg))
|
||||||
{
|
{
|
||||||
RouterID random;
|
if (auto random = router()->GetRandomGoodRouter())
|
||||||
if (router()->GetRandomGoodRouter(random))
|
|
||||||
{
|
{
|
||||||
msg.AddCNAMEReply(random.ToString(), 1);
|
msg.AddCNAMEReply(random->ToString(), 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
msg.AddNXReply();
|
msg.AddNXReply();
|
||||||
|
@ -755,11 +754,10 @@ namespace llarp::handlers
|
||||||
// on MacOS this is a typeA query
|
// on MacOS this is a typeA query
|
||||||
else if (is_random_snode(msg))
|
else if (is_random_snode(msg))
|
||||||
{
|
{
|
||||||
RouterID random;
|
if (auto random = router()->GetRandomGoodRouter())
|
||||||
if (router()->GetRandomGoodRouter(random))
|
|
||||||
{
|
{
|
||||||
msg.AddCNAMEReply(random.ToString(), 1);
|
msg.AddCNAMEReply(random->ToString(), 1);
|
||||||
return ReplyToSNodeDNSWhenReady(random, std::make_shared<dns::Message>(msg), isV6);
|
return ReplyToSNodeDNSWhenReady(*random, std::make_shared<dns::Message>(msg), isV6);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.AddNXReply();
|
msg.AddNXReply();
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include <llarp/messages/path.hpp>
|
#include <llarp/messages/path.hpp>
|
||||||
#include <llarp/nodedb.hpp>
|
#include <llarp/nodedb.hpp>
|
||||||
#include <llarp/path/path.hpp>
|
#include <llarp/path/path.hpp>
|
||||||
#include <llarp/router/rc_lookup_handler.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
#include <llarp/router/router.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -243,21 +242,17 @@ namespace llarp
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_router.loop()->call([this, remote, endpoint, body, f = std::move(func)]() {
|
_router.loop()->call([this,
|
||||||
auto pending = PendingControlMessage(body, endpoint, f);
|
remote,
|
||||||
|
endpoint = std::move(endpoint),
|
||||||
|
body = std::move(body),
|
||||||
|
f = std::move(func)]() {
|
||||||
|
auto pending = PendingControlMessage(std::move(body), std::move(endpoint), f);
|
||||||
|
|
||||||
auto [itr, b] = pending_conn_msg_queue.emplace(remote, MessageQueue());
|
auto [itr, b] = pending_conn_msg_queue.emplace(remote, MessageQueue());
|
||||||
itr->second.push_back(std::move(pending));
|
itr->second.push_back(std::move(pending));
|
||||||
|
|
||||||
rc_lookup->get_rc(remote, [this]([[maybe_unused]] auto rid, auto rc, auto success) {
|
connect_to(remote);
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
_router.node_db()->put_rc_if_newer(*rc);
|
|
||||||
connect_to(*rc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log::warning(quic_cat, "Do something intelligent here for error handling");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -275,21 +270,13 @@ namespace llarp
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_router.loop()->call([&]() {
|
_router.loop()->call([this, body = std::move(body), remote]() {
|
||||||
auto pending = PendingDataMessage(body);
|
auto pending = PendingDataMessage(body);
|
||||||
|
|
||||||
auto [itr, b] = pending_conn_msg_queue.emplace(remote, MessageQueue());
|
auto [itr, b] = pending_conn_msg_queue.emplace(remote, MessageQueue());
|
||||||
itr->second.push_back(std::move(pending));
|
itr->second.push_back(std::move(pending));
|
||||||
|
|
||||||
rc_lookup->get_rc(remote, [this]([[maybe_unused]] auto rid, auto rc, auto success) {
|
connect_to(remote);
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
_router.node_db()->put_rc_if_newer(*rc);
|
|
||||||
connect_to(*rc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log::warning(quic_cat, "Do something intelligent here for error handling");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -304,15 +291,13 @@ namespace llarp
|
||||||
void
|
void
|
||||||
LinkManager::connect_to(const RouterID& rid)
|
LinkManager::connect_to(const RouterID& rid)
|
||||||
{
|
{
|
||||||
rc_lookup->get_rc(rid, [this]([[maybe_unused]] auto rid, auto rc, auto success) {
|
auto rc = node_db->get_rc(rid);
|
||||||
if (success)
|
if (rc)
|
||||||
{
|
{
|
||||||
_router.node_db()->put_rc_if_newer(*rc);
|
|
||||||
connect_to(*rc);
|
connect_to(*rc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log::warning(quic_cat, "Do something intelligent here for error handling");
|
log::warning(quic_cat, "Do something intelligent here for error handling");
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function assumes the RC has already had its signature verified and connection is allowed.
|
// This function assumes the RC has already had its signature verified and connection is allowed.
|
||||||
|
@ -400,6 +385,27 @@ namespace llarp
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LinkManager::gossip_rc(const RemoteRC& rc)
|
||||||
|
{
|
||||||
|
for (auto& [rid, conn] : ep.conns)
|
||||||
|
send_control_message(rid, "gossip_rc", std::string{rc.view()}, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LinkManager::handle_gossip_rc(oxen::quic::message m)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RemoteRC rc{m.body()};
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
log::info(link_cat, "Recieved invalid RC, dropping on the floor.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LinkManager::have_connection_to(const RouterID& remote, bool client_only) const
|
LinkManager::have_connection_to(const RouterID& remote, bool client_only) const
|
||||||
{
|
{
|
||||||
|
@ -486,10 +492,9 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LinkManager::init(RCLookupHandler* rcLookup)
|
LinkManager::init()
|
||||||
{
|
{
|
||||||
is_stopping = false;
|
is_stopping = false;
|
||||||
rc_lookup = rcLookup;
|
|
||||||
node_db = _router.node_db();
|
node_db = _router.node_db();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +514,7 @@ namespace llarp
|
||||||
{
|
{
|
||||||
exclude.insert(maybe_other->router_id());
|
exclude.insert(maybe_other->router_id());
|
||||||
|
|
||||||
if (not rc_lookup->is_session_allowed(maybe_other->router_id()))
|
if (not node_db->is_connection_allowed(maybe_other->router_id()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
connect_to(*maybe_other);
|
connect_to(*maybe_other);
|
||||||
|
@ -630,8 +635,9 @@ namespace llarp
|
||||||
{
|
{
|
||||||
std::string neighbors{};
|
std::string neighbors{};
|
||||||
|
|
||||||
const auto closest_rcs =
|
// TODO: constant replaced with 4 (what the constant it referred to was) for compilation,
|
||||||
_router.node_db()->find_many_closest_to(target_addr, RC_LOOKUP_STORAGE_REDUNDANCY);
|
// pending removal
|
||||||
|
const auto closest_rcs = _router.node_db()->find_many_closest_to(target_addr, 4);
|
||||||
|
|
||||||
for (const auto& rc : closest_rcs)
|
for (const auto& rc : closest_rcs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <llarp/crypto/crypto.hpp>
|
#include <llarp/crypto/crypto.hpp>
|
||||||
#include <llarp/messages/common.hpp>
|
#include <llarp/messages/common.hpp>
|
||||||
#include <llarp/path/transit_hop.hpp>
|
#include <llarp/path/transit_hop.hpp>
|
||||||
#include <llarp/router/rc_lookup_handler.hpp>
|
|
||||||
#include <llarp/router_contact.hpp>
|
#include <llarp/router_contact.hpp>
|
||||||
#include <llarp/util/compare_ptr.hpp>
|
#include <llarp/util/compare_ptr.hpp>
|
||||||
#include <llarp/util/decaying_hashset.hpp>
|
#include <llarp/util/decaying_hashset.hpp>
|
||||||
|
@ -27,6 +26,7 @@ namespace
|
||||||
namespace llarp
|
namespace llarp
|
||||||
{
|
{
|
||||||
struct LinkManager;
|
struct LinkManager;
|
||||||
|
struct NodeDB;
|
||||||
|
|
||||||
namespace link
|
namespace link
|
||||||
{
|
{
|
||||||
|
@ -176,7 +176,6 @@ namespace llarp
|
||||||
|
|
||||||
util::DecayingHashSet<RouterID> clients{path::DEFAULT_LIFETIME};
|
util::DecayingHashSet<RouterID> clients{path::DEFAULT_LIFETIME};
|
||||||
|
|
||||||
RCLookupHandler* rc_lookup;
|
|
||||||
std::shared_ptr<NodeDB> node_db;
|
std::shared_ptr<NodeDB> node_db;
|
||||||
|
|
||||||
oxen::quic::Address addr;
|
oxen::quic::Address addr;
|
||||||
|
@ -221,6 +220,12 @@ namespace llarp
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gossip_rc(const RemoteRC& rc);
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_gossip_rc(oxen::quic::message m);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
have_connection_to(const RouterID& remote, bool client_only = false) const;
|
have_connection_to(const RouterID& remote, bool client_only = false) const;
|
||||||
|
|
||||||
|
@ -261,7 +266,7 @@ namespace llarp
|
||||||
extract_status() const;
|
extract_status() const;
|
||||||
|
|
||||||
void
|
void
|
||||||
init(RCLookupHandler* rcLookup);
|
init();
|
||||||
|
|
||||||
void
|
void
|
||||||
for_each_connection(std::function<void(link::Connection&)> func);
|
for_each_connection(std::function<void(link::Connection&)> func);
|
||||||
|
|
|
@ -99,6 +99,73 @@ namespace llarp
|
||||||
return m_Root / skiplistDir / fname;
|
return m_Root / skiplistDir / fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NodeDB::set_bootstrap_routers(const std::set<RemoteRC>& rcs)
|
||||||
|
{
|
||||||
|
bootstraps.clear(); // this function really shouldn't be called more than once, but...
|
||||||
|
for (const auto& rc : rcs)
|
||||||
|
bootstraps.emplace(rc.router_id(), rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NodeDB::set_router_whitelist(
|
||||||
|
const std::vector<RouterID>& whitelist,
|
||||||
|
const std::vector<RouterID>& greylist,
|
||||||
|
const std::vector<RouterID>& greenlist)
|
||||||
|
{
|
||||||
|
if (whitelist.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
registered_routers.clear();
|
||||||
|
registered_routers.insert(whitelist.begin(), whitelist.end());
|
||||||
|
registered_routers.insert(greylist.begin(), greylist.end());
|
||||||
|
registered_routers.insert(greenlist.begin(), greenlist.end());
|
||||||
|
|
||||||
|
router_whitelist.clear();
|
||||||
|
router_whitelist.insert(whitelist.begin(), whitelist.end());
|
||||||
|
router_greylist.clear();
|
||||||
|
router_greylist.insert(greylist.begin(), greylist.end());
|
||||||
|
router_greenlist.clear();
|
||||||
|
router_greenlist.insert(greenlist.begin(), greenlist.end());
|
||||||
|
|
||||||
|
log::info(
|
||||||
|
logcat, "lokinet service node list now has ", router_whitelist.size(), " active routers");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<RouterID>
|
||||||
|
NodeDB::get_random_whitelist_router() const
|
||||||
|
{
|
||||||
|
const auto sz = router_whitelist.size();
|
||||||
|
if (sz == 0)
|
||||||
|
return std::nullopt;
|
||||||
|
auto itr = router_whitelist.begin();
|
||||||
|
if (sz > 1)
|
||||||
|
std::advance(itr, randint() % sz);
|
||||||
|
return *itr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NodeDB::is_connection_allowed(const RouterID& remote) const
|
||||||
|
{
|
||||||
|
if (pinned_edges.size() && pinned_edges.count(remote) == 0 && !bootstraps.count(remote))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not router.is_service_node())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return router_whitelist.count(remote) or router_greylist.count(remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NodeDB::is_first_hop_allowed(const RouterID& remote) const
|
||||||
|
{
|
||||||
|
if (pinned_edges.size() && pinned_edges.count(remote) == 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NodeDB::load_from_disk()
|
NodeDB::load_from_disk()
|
||||||
{
|
{
|
||||||
|
@ -180,14 +247,12 @@ namespace llarp
|
||||||
std::optional<RemoteRC>
|
std::optional<RemoteRC>
|
||||||
NodeDB::get_rc(RouterID pk) const
|
NodeDB::get_rc(RouterID pk) const
|
||||||
{
|
{
|
||||||
return router.loop()->call_get([this, pk]() -> std::optional<RemoteRC> {
|
|
||||||
const auto itr = entries.find(pk);
|
const auto itr = entries.find(pk);
|
||||||
|
|
||||||
if (itr == entries.end())
|
if (itr == entries.end())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
return itr->second.rc;
|
return itr->second.rc;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -49,7 +49,85 @@ namespace llarp
|
||||||
fs::path
|
fs::path
|
||||||
get_path_by_pubkey(RouterID pk) const;
|
get_path_by_pubkey(RouterID pk) const;
|
||||||
|
|
||||||
|
std::unordered_map<RouterID, RemoteRC> bootstraps;
|
||||||
|
|
||||||
|
// whitelist = active routers
|
||||||
|
std::unordered_set<RouterID> router_whitelist;
|
||||||
|
// greylist = fully funded, but decommissioned routers
|
||||||
|
std::unordered_set<RouterID> router_greylist;
|
||||||
|
// greenlist = registered but not fully-staked routers
|
||||||
|
std::unordered_set<RouterID> router_greenlist;
|
||||||
|
|
||||||
|
// all registered relays (snodes)
|
||||||
|
std::unordered_set<RouterID> registered_routers;
|
||||||
|
|
||||||
|
// only ever use to specific edges as path first-hops
|
||||||
|
std::unordered_set<RouterID> pinned_edges;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void
|
||||||
|
set_bootstrap_routers(const std::set<RemoteRC>& rcs);
|
||||||
|
|
||||||
|
const std::unordered_set<RouterID>&
|
||||||
|
whitelist() const
|
||||||
|
{
|
||||||
|
return router_whitelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unordered_set<RouterID>&
|
||||||
|
greylist() const
|
||||||
|
{
|
||||||
|
return router_greylist;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unordered_set<RouterID>&
|
||||||
|
get_registered_routers() const
|
||||||
|
{
|
||||||
|
return registered_routers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_router_whitelist(
|
||||||
|
const std::vector<RouterID>& whitelist,
|
||||||
|
const std::vector<RouterID>& greylist,
|
||||||
|
const std::vector<RouterID>& greenlist);
|
||||||
|
|
||||||
|
std::optional<RouterID>
|
||||||
|
get_random_whitelist_router() const;
|
||||||
|
|
||||||
|
// client:
|
||||||
|
// if pinned edges were specified, connections are allowed only to those and
|
||||||
|
// to the configured bootstrap nodes. otherwise, always allow.
|
||||||
|
//
|
||||||
|
// relay:
|
||||||
|
// outgoing connections are allowed only to other registered, funded relays
|
||||||
|
// (whitelist and greylist, respectively).
|
||||||
|
bool
|
||||||
|
is_connection_allowed(const RouterID& remote) const;
|
||||||
|
|
||||||
|
// client:
|
||||||
|
// same as is_connection_allowed
|
||||||
|
//
|
||||||
|
// server:
|
||||||
|
// we only build new paths through registered, not decommissioned relays
|
||||||
|
// (i.e. whitelist)
|
||||||
|
bool
|
||||||
|
is_path_allowed(const RouterID& remote) const
|
||||||
|
{
|
||||||
|
return router_whitelist.count(remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if pinned edges were specified, the remote must be in that set, else any remote
|
||||||
|
// is allowed as first hop.
|
||||||
|
bool
|
||||||
|
is_first_hop_allowed(const RouterID& remote) const;
|
||||||
|
|
||||||
|
const std::unordered_set<RouterID>&
|
||||||
|
get_pinned_edges() const
|
||||||
|
{
|
||||||
|
return pinned_edges;
|
||||||
|
}
|
||||||
|
|
||||||
explicit NodeDB(
|
explicit NodeDB(
|
||||||
fs::path rootdir, std::function<void(std::function<void()>)> diskCaller, Router* r);
|
fs::path rootdir, std::function<void(std::function<void()>)> diskCaller, Router* r);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <llarp/nodedb.hpp>
|
#include <llarp/nodedb.hpp>
|
||||||
#include <llarp/path/pathset.hpp>
|
#include <llarp/path/pathset.hpp>
|
||||||
#include <llarp/profiling.hpp>
|
#include <llarp/profiling.hpp>
|
||||||
#include <llarp/router/rc_lookup_handler.hpp>
|
|
||||||
#include <llarp/router/router.hpp>
|
#include <llarp/router/router.hpp>
|
||||||
#include <llarp/util/logging.hpp>
|
#include <llarp/util/logging.hpp>
|
||||||
|
|
||||||
|
@ -575,30 +574,6 @@ namespace llarp
|
||||||
router->router_profiling().MarkPathTimeout(p.get());
|
router->router_profiling().MarkPathTimeout(p.get());
|
||||||
PathSet::HandlePathBuildTimeout(p);
|
PathSet::HandlePathBuildTimeout(p);
|
||||||
DoPathBuildBackoff();
|
DoPathBuildBackoff();
|
||||||
for (const auto& hop : p->hops)
|
|
||||||
{
|
|
||||||
const auto& target = hop.rc.router_id();
|
|
||||||
// look up router and see if it's still on the network
|
|
||||||
log::info(path_cat, "Looking up RouterID {} due to path build timeout", target);
|
|
||||||
|
|
||||||
router->rc_lookup_handler().get_rc(
|
|
||||||
target,
|
|
||||||
[this](auto rid, auto rc, auto success) {
|
|
||||||
if (success && rc)
|
|
||||||
{
|
|
||||||
log::info(path_cat, "Refreshed RouterContact for {}", rid);
|
|
||||||
router->node_db()->put_rc_if_newer(*rc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// remove all connections to this router as it's probably not registered anymore
|
|
||||||
log::warning(path_cat, "Removing router {} due to path build timeout", rid);
|
|
||||||
router->link_manager().deregister_peer(rid);
|
|
||||||
router->node_db()->remove_router(rid);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,357 +0,0 @@
|
||||||
#include "rc_lookup_handler.hpp"
|
|
||||||
|
|
||||||
#include "router.hpp"
|
|
||||||
|
|
||||||
#include <llarp/crypto/crypto.hpp>
|
|
||||||
#include <llarp/link/contacts.hpp>
|
|
||||||
#include <llarp/link/link_manager.hpp>
|
|
||||||
#include <llarp/nodedb.hpp>
|
|
||||||
#include <llarp/router_contact.hpp>
|
|
||||||
#include <llarp/service/context.hpp>
|
|
||||||
#include <llarp/util/types.hpp>
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
void
|
|
||||||
RCLookupHandler::add_valid_router(const RouterID& rid)
|
|
||||||
{
|
|
||||||
router->loop()->call([this, rid]() { router_whitelist.insert(rid); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RCLookupHandler::remove_valid_router(const RouterID& rid)
|
|
||||||
{
|
|
||||||
router->loop()->call([this, rid]() { router_whitelist.erase(rid); });
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
loadColourList(std::unordered_set<RouterID>& beigelist, const std::vector<RouterID>& new_beige)
|
|
||||||
{
|
|
||||||
beigelist.clear();
|
|
||||||
beigelist.insert(new_beige.begin(), new_beige.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RCLookupHandler::set_router_whitelist(
|
|
||||||
const std::vector<RouterID>& whitelist,
|
|
||||||
const std::vector<RouterID>& greylist,
|
|
||||||
const std::vector<RouterID>& greenlist)
|
|
||||||
{
|
|
||||||
if (whitelist.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
router->loop()->call([this, whitelist, greylist, greenlist]() {
|
|
||||||
loadColourList(router_whitelist, whitelist);
|
|
||||||
loadColourList(router_greylist, greylist);
|
|
||||||
loadColourList(router_greenlist, greenlist);
|
|
||||||
LogInfo("lokinet service node list now has ", router_whitelist.size(), " active routers");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::has_received_whitelist() const
|
|
||||||
{
|
|
||||||
return router->loop()->call_get([this]() { return not router_whitelist.empty(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_set<RouterID>
|
|
||||||
RCLookupHandler::whitelist() const
|
|
||||||
{
|
|
||||||
return router->loop()->call_get([this]() { return router_whitelist; });
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RCLookupHandler::get_rc(const RouterID& rid, RCRequestCallback callback, bool forceLookup)
|
|
||||||
{
|
|
||||||
(void)rid;
|
|
||||||
(void)callback;
|
|
||||||
(void)forceLookup;
|
|
||||||
/* RC refactor pending, this will likely go away entirely
|
|
||||||
*
|
|
||||||
*
|
|
||||||
RemoteRC remoteRC;
|
|
||||||
|
|
||||||
if (not forceLookup)
|
|
||||||
{
|
|
||||||
if (const auto maybe = node_db->get_rc(rid); maybe.has_value())
|
|
||||||
{
|
|
||||||
remoteRC = *maybe;
|
|
||||||
|
|
||||||
if (callback)
|
|
||||||
{
|
|
||||||
callback(rid, remoteRC, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lookup_cb = [this, callback, rid](RemoteRC rc, bool success) mutable {
|
|
||||||
auto& r = link_manager->router();
|
|
||||||
|
|
||||||
if (not success)
|
|
||||||
{
|
|
||||||
if (callback)
|
|
||||||
callback(rid, std::nullopt, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
r.node_db()->put_rc_if_newer(rc);
|
|
||||||
if (callback)
|
|
||||||
callback(rc.router_id(), rc, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: RC fetching and gossiping in general is being refactored, and the old method
|
|
||||||
// of look it up over a path or directly but using the same method but called
|
|
||||||
// differently is going away. It's a mess. The below will do a lookup via a path,
|
|
||||||
// relays will need a different implementation TBD.
|
|
||||||
if (!isServiceNode)
|
|
||||||
hidden_service_context->GetDefault()->lookup_router(rid, std::move(lookup_cb));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::is_grey_listed(const RouterID& remote) const
|
|
||||||
{
|
|
||||||
if (strict_connect_pubkeys.size() && strict_connect_pubkeys.count(remote) == 0
|
|
||||||
&& !is_remote_in_bootstrap(remote))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not isServiceNode)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return router->loop()->call_get([this, remote]() { return router_greylist.count(remote); });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::is_green_listed(const RouterID& remote) const
|
|
||||||
{
|
|
||||||
return router->loop()->call_get([this, remote]() { return router_greenlist.count(remote); });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::is_registered(const RouterID& rid) const
|
|
||||||
{
|
|
||||||
return router->loop()->call_get([this, rid]() {
|
|
||||||
return router_whitelist.count(rid) || router_greylist.count(rid)
|
|
||||||
|| router_greenlist.count(rid);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::is_path_allowed(const RouterID& rid) const
|
|
||||||
{
|
|
||||||
return router->loop()->call_get([this, rid]() {
|
|
||||||
if (strict_connect_pubkeys.size() && strict_connect_pubkeys.count(rid) == 0
|
|
||||||
&& !is_remote_in_bootstrap(rid))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not isServiceNode)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return router_whitelist.count(rid) != 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::is_session_allowed(const RouterID& rid) const
|
|
||||||
{
|
|
||||||
return router->loop()->call_get([this, rid]() {
|
|
||||||
if (strict_connect_pubkeys.size() && strict_connect_pubkeys.count(rid) == 0
|
|
||||||
&& !is_remote_in_bootstrap(rid))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not isServiceNode)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return router_whitelist.count(rid) or router_greylist.count(rid);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::check_rc(const RemoteRC& rc) const
|
|
||||||
{
|
|
||||||
if (not is_session_allowed(rc.router_id()))
|
|
||||||
{
|
|
||||||
contacts->delete_rc_node_async(dht::Key_t{rc.router_id()});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not rc.verify())
|
|
||||||
{
|
|
||||||
log::info(link_cat, "Invalid RC (rid: {})", rc.router_id());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update nodedb if required
|
|
||||||
if (rc.is_public_router())
|
|
||||||
{
|
|
||||||
log::info(link_cat, "Adding or updating RC (rid: {}) to nodeDB and DHT", rc.router_id());
|
|
||||||
node_db->put_rc_if_newer(rc);
|
|
||||||
contacts->put_rc_node_async(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
RCLookupHandler::num_strict_connect_routers() const
|
|
||||||
{
|
|
||||||
return strict_connect_pubkeys.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::get_random_whitelist_router(RouterID& rid) const
|
|
||||||
{
|
|
||||||
return router->loop()->call_get([this, rid]() mutable {
|
|
||||||
const auto sz = router_whitelist.size();
|
|
||||||
auto itr = router_whitelist.begin();
|
|
||||||
if (sz == 0)
|
|
||||||
return false;
|
|
||||||
if (sz > 1)
|
|
||||||
std::advance(itr, randint() % sz);
|
|
||||||
rid = *itr;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RCLookupHandler::periodic_update(llarp_time_t now)
|
|
||||||
{
|
|
||||||
// try looking up stale routers
|
|
||||||
std::unordered_set<RouterID> routersToLookUp;
|
|
||||||
|
|
||||||
node_db->VisitInsertedBefore(
|
|
||||||
[&](const RouterContact& rc) { routersToLookUp.insert(rc.router_id()); },
|
|
||||||
now - RouterContact::REPUBLISH);
|
|
||||||
|
|
||||||
for (const auto& router : routersToLookUp)
|
|
||||||
{
|
|
||||||
get_rc(router, nullptr, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
node_db->remove_stale_rcs(boostrap_rid_list, now - RouterContact::STALE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RCLookupHandler::explore_network()
|
|
||||||
{
|
|
||||||
const size_t known = node_db->num_loaded();
|
|
||||||
if (bootstrap_rc_list.empty() && known == 0)
|
|
||||||
{
|
|
||||||
LogError("we have no bootstrap nodes specified");
|
|
||||||
}
|
|
||||||
else if (known <= bootstrap_rc_list.size())
|
|
||||||
{
|
|
||||||
for (const auto& rc : bootstrap_rc_list)
|
|
||||||
{
|
|
||||||
const auto& rid = rc.router_id();
|
|
||||||
log::info(link_cat, "Doing explore via bootstrap node: {}", rid);
|
|
||||||
|
|
||||||
// TODO: replace this concept
|
|
||||||
// dht->ExploreNetworkVia(dht::Key_t{rc.pubkey});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isServiceNode)
|
|
||||||
{
|
|
||||||
static constexpr size_t LookupPerTick = 5;
|
|
||||||
|
|
||||||
std::vector<RouterID> lookup_routers = router->loop()->call_get([this]() {
|
|
||||||
std::vector<RouterID> lookups;
|
|
||||||
lookups.reserve(LookupPerTick);
|
|
||||||
|
|
||||||
for (const auto& r : router_whitelist)
|
|
||||||
{
|
|
||||||
if (not node_db->has_router(r))
|
|
||||||
lookups.emplace_back(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
return lookups;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (lookup_routers.size() > LookupPerTick)
|
|
||||||
{
|
|
||||||
std::shuffle(lookup_routers.begin(), lookup_routers.end(), llarp::csrng);
|
|
||||||
lookup_routers.resize(LookupPerTick);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& r : lookup_routers)
|
|
||||||
get_rc(r, nullptr, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// service nodes gossip, not explore
|
|
||||||
if (contacts->router()->is_service_node())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// explore via every connected peer
|
|
||||||
/*
|
|
||||||
* TODO: DHT explore via libquic
|
|
||||||
*
|
|
||||||
_linkManager->ForEachPeer([&](ILinkSession* s) {
|
|
||||||
if (!s->IsEstablished())
|
|
||||||
return;
|
|
||||||
const RouterContact rc = s->GetRemoteRC();
|
|
||||||
if (rc.IsPublicRouter() && (_bootstrapRCList.find(rc) == _bootstrapRCList.end()))
|
|
||||||
{
|
|
||||||
LogDebug("Doing explore via public node: ", RouterID(rc.pubkey));
|
|
||||||
_dht->impl->ExploreNetworkVia(dht::Key_t{rc.pubkey});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RCLookupHandler::init(
|
|
||||||
std::shared_ptr<Contacts> c,
|
|
||||||
std::shared_ptr<NodeDB> nodedb,
|
|
||||||
EventLoop_ptr l,
|
|
||||||
std::function<void(std::function<void()>)> dowork,
|
|
||||||
LinkManager* linkManager,
|
|
||||||
service::Context* hiddenServiceContext,
|
|
||||||
const std::unordered_set<RouterID>& strictConnectPubkeys,
|
|
||||||
const std::set<RemoteRC>& bootstrapRCList,
|
|
||||||
bool isServiceNode_arg)
|
|
||||||
{
|
|
||||||
contacts = c;
|
|
||||||
node_db = std::move(nodedb);
|
|
||||||
loop = std::move(l);
|
|
||||||
work_func = std::move(dowork);
|
|
||||||
hidden_service_context = hiddenServiceContext;
|
|
||||||
strict_connect_pubkeys = strictConnectPubkeys;
|
|
||||||
bootstrap_rc_list = bootstrapRCList;
|
|
||||||
link_manager = linkManager;
|
|
||||||
router = &link_manager->router();
|
|
||||||
isServiceNode = isServiceNode_arg;
|
|
||||||
|
|
||||||
for (const auto& rc : bootstrap_rc_list)
|
|
||||||
{
|
|
||||||
boostrap_rid_list.insert(rc.router_id());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
RCLookupHandler::is_remote_in_bootstrap(const RouterID& remote) const
|
|
||||||
{
|
|
||||||
for (const auto& rc : bootstrap_rc_list)
|
|
||||||
{
|
|
||||||
if (rc.router_id() == remote)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace llarp
|
|
|
@ -1,143 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <llarp/router_contact.hpp>
|
|
||||||
#include <llarp/router_id.hpp>
|
|
||||||
#include <llarp/util/thread/threading.hpp>
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
struct llarp_dht_context;
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
class NodeDB;
|
|
||||||
struct Router;
|
|
||||||
class EventLoop;
|
|
||||||
|
|
||||||
namespace service
|
|
||||||
{
|
|
||||||
struct Context;
|
|
||||||
} // namespace service
|
|
||||||
|
|
||||||
struct Contacts;
|
|
||||||
struct LinkManager;
|
|
||||||
|
|
||||||
enum class RCRequestResult
|
|
||||||
{
|
|
||||||
Success,
|
|
||||||
InvalidRouter,
|
|
||||||
RouterNotFound,
|
|
||||||
BadRC
|
|
||||||
};
|
|
||||||
|
|
||||||
using RCRequestCallback =
|
|
||||||
std::function<void(const RouterID&, std::optional<RemoteRC>, bool success)>;
|
|
||||||
|
|
||||||
struct RCLookupHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~RCLookupHandler() = default;
|
|
||||||
|
|
||||||
void
|
|
||||||
add_valid_router(const RouterID& router);
|
|
||||||
|
|
||||||
void
|
|
||||||
remove_valid_router(const RouterID& router);
|
|
||||||
|
|
||||||
void
|
|
||||||
set_router_whitelist(
|
|
||||||
const std::vector<RouterID>& whitelist,
|
|
||||||
const std::vector<RouterID>& greylist,
|
|
||||||
const std::vector<RouterID>& greenlist);
|
|
||||||
|
|
||||||
bool
|
|
||||||
has_received_whitelist() const;
|
|
||||||
|
|
||||||
void
|
|
||||||
get_rc(const RouterID& router, RCRequestCallback callback, bool forceLookup = false);
|
|
||||||
|
|
||||||
bool
|
|
||||||
is_path_allowed(const RouterID& remote) const;
|
|
||||||
|
|
||||||
bool
|
|
||||||
is_session_allowed(const RouterID& remote) const;
|
|
||||||
|
|
||||||
bool
|
|
||||||
is_grey_listed(const RouterID& remote) const;
|
|
||||||
|
|
||||||
// "greenlist" = new routers (i.e. "green") that aren't fully funded yet
|
|
||||||
bool
|
|
||||||
is_green_listed(const RouterID& remote) const;
|
|
||||||
|
|
||||||
// registered just means that there is at least an operator stake, but doesn't require the node
|
|
||||||
// be fully funded, active, or not decommed. (In other words: it is any of the white, grey, or
|
|
||||||
// green list).
|
|
||||||
bool
|
|
||||||
is_registered(const RouterID& remote) const;
|
|
||||||
|
|
||||||
bool
|
|
||||||
check_rc(const RemoteRC& rc) const;
|
|
||||||
|
|
||||||
bool
|
|
||||||
get_random_whitelist_router(RouterID& router) const;
|
|
||||||
|
|
||||||
void
|
|
||||||
periodic_update(llarp_time_t now);
|
|
||||||
|
|
||||||
void
|
|
||||||
explore_network();
|
|
||||||
|
|
||||||
size_t
|
|
||||||
num_strict_connect_routers() const;
|
|
||||||
|
|
||||||
void
|
|
||||||
init(
|
|
||||||
std::shared_ptr<Contacts> contacts,
|
|
||||||
std::shared_ptr<NodeDB> nodedb,
|
|
||||||
std::shared_ptr<EventLoop> loop,
|
|
||||||
std::function<void(std::function<void()>)> dowork,
|
|
||||||
LinkManager* linkManager,
|
|
||||||
service::Context* hiddenServiceContext,
|
|
||||||
const std::unordered_set<RouterID>& strictConnectPubkeys,
|
|
||||||
const std::set<RemoteRC>& bootstrapRCList,
|
|
||||||
bool isServiceNode_arg);
|
|
||||||
|
|
||||||
std::unordered_set<RouterID>
|
|
||||||
whitelist() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool
|
|
||||||
is_remote_in_bootstrap(const RouterID& remote) const;
|
|
||||||
|
|
||||||
std::shared_ptr<Contacts> contacts = nullptr;
|
|
||||||
std::shared_ptr<NodeDB> node_db;
|
|
||||||
std::shared_ptr<EventLoop> loop;
|
|
||||||
std::function<void(std::function<void()>)> work_func = nullptr;
|
|
||||||
service::Context* hidden_service_context = nullptr;
|
|
||||||
LinkManager* link_manager = nullptr;
|
|
||||||
Router* router;
|
|
||||||
|
|
||||||
/// explicit whitelist of routers we will connect to directly (not for
|
|
||||||
/// service nodes)
|
|
||||||
std::unordered_set<RouterID> strict_connect_pubkeys;
|
|
||||||
|
|
||||||
std::set<RemoteRC> bootstrap_rc_list;
|
|
||||||
std::unordered_set<RouterID> boostrap_rid_list;
|
|
||||||
|
|
||||||
// Now that all calls are made through the event loop, any access to these
|
|
||||||
// booleans is not guarded by a mutex
|
|
||||||
std::atomic<bool> isServiceNode = false;
|
|
||||||
|
|
||||||
// whitelist = active routers
|
|
||||||
std::unordered_set<RouterID> router_whitelist;
|
|
||||||
// greylist = fully funded, but decommissioned routers
|
|
||||||
std::unordered_set<RouterID> router_greylist;
|
|
||||||
// greenlist = registered but not fully-staked routers
|
|
||||||
std::unordered_set<RouterID> router_greenlist;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace llarp
|
|
|
@ -239,20 +239,19 @@ namespace llarp
|
||||||
_rcGossiper.GossipRC(rc);
|
_rcGossiper.GossipRC(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
std::optional<RouterID>
|
||||||
Router::GetRandomGoodRouter(RouterID& router)
|
Router::GetRandomGoodRouter()
|
||||||
{
|
{
|
||||||
if (is_service_node())
|
if (is_service_node())
|
||||||
{
|
{
|
||||||
return _rc_lookup_handler.get_random_whitelist_router(router);
|
return node_db()->get_random_whitelist_router();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto maybe = node_db()->GetRandom([](const auto&) -> bool { return true; }))
|
if (auto maybe = node_db()->GetRandom([](const auto&) -> bool { return true; }))
|
||||||
{
|
{
|
||||||
router = maybe->router_id();
|
return maybe->router_id();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -479,25 +478,25 @@ namespace llarp
|
||||||
bool
|
bool
|
||||||
Router::have_snode_whitelist() const
|
Router::have_snode_whitelist() const
|
||||||
{
|
{
|
||||||
return is_service_node() and _rc_lookup_handler.has_received_whitelist();
|
return whitelist_received;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Router::appears_decommed() const
|
Router::appears_decommed() const
|
||||||
{
|
{
|
||||||
return have_snode_whitelist() and _rc_lookup_handler.is_grey_listed(pubkey());
|
return have_snode_whitelist() and node_db()->greylist().count(pubkey());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Router::appears_funded() const
|
Router::appears_funded() const
|
||||||
{
|
{
|
||||||
return have_snode_whitelist() and _rc_lookup_handler.is_session_allowed(pubkey());
|
return have_snode_whitelist() and node_db()->is_connection_allowed(pubkey());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Router::appears_registered() const
|
Router::appears_registered() const
|
||||||
{
|
{
|
||||||
return have_snode_whitelist() and _rc_lookup_handler.is_registered(pubkey());
|
return have_snode_whitelist() and node_db()->get_registered_routers().count(pubkey());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -509,7 +508,7 @@ namespace llarp
|
||||||
bool
|
bool
|
||||||
Router::SessionToRouterAllowed(const RouterID& router) const
|
Router::SessionToRouterAllowed(const RouterID& router) const
|
||||||
{
|
{
|
||||||
return _rc_lookup_handler.is_session_allowed(router);
|
return node_db()->is_connection_allowed(router);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -520,7 +519,7 @@ namespace llarp
|
||||||
// we are decom'd don't allow any paths outbound at all
|
// we are decom'd don't allow any paths outbound at all
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return _rc_lookup_handler.is_path_allowed(router);
|
return node_db()->is_path_allowed(router);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
@ -679,23 +678,15 @@ namespace llarp
|
||||||
it = bootstrap_rc_list.erase(it);
|
it = bootstrap_rc_list.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_db()->set_bootstrap_routers(bootstrap_rc_list);
|
||||||
|
|
||||||
if (conf.bootstrap.seednode)
|
if (conf.bootstrap.seednode)
|
||||||
LogInfo("we are a seed node");
|
LogInfo("we are a seed node");
|
||||||
else
|
else
|
||||||
LogInfo("Loaded ", bootstrap_rc_list.size(), " bootstrap routers");
|
LogInfo("Loaded ", bootstrap_rc_list.size(), " bootstrap routers");
|
||||||
|
|
||||||
// Init components after relevant config settings loaded
|
// Init components after relevant config settings loaded
|
||||||
_link_manager.init(&_rc_lookup_handler);
|
_link_manager.init();
|
||||||
_rc_lookup_handler.init(
|
|
||||||
_contacts,
|
|
||||||
_node_db,
|
|
||||||
_loop,
|
|
||||||
[this](std::function<void(void)> work) { queue_work(std::move(work)); },
|
|
||||||
&_link_manager,
|
|
||||||
&_hidden_service_context,
|
|
||||||
strictConnectPubkeys,
|
|
||||||
bootstrap_rc_list,
|
|
||||||
_is_service_node);
|
|
||||||
|
|
||||||
// FIXME: kludge for now, will be part of larger cleanup effort.
|
// FIXME: kludge for now, will be part of larger cleanup effort.
|
||||||
if (_is_service_node)
|
if (_is_service_node)
|
||||||
|
@ -856,9 +847,6 @@ namespace llarp
|
||||||
|
|
||||||
_rcGossiper.Decay(now);
|
_rcGossiper.Decay(now);
|
||||||
|
|
||||||
_rc_lookup_handler.periodic_update(now);
|
|
||||||
|
|
||||||
const bool has_whitelist = _rc_lookup_handler.has_received_whitelist();
|
|
||||||
const bool is_snode = is_service_node();
|
const bool is_snode = is_service_node();
|
||||||
const bool is_decommed = appears_decommed();
|
const bool is_decommed = appears_decommed();
|
||||||
bool should_gossip = appears_funded();
|
bool should_gossip = appears_funded();
|
||||||
|
@ -915,7 +903,7 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we don't have the whitelist yet don't remove the entry
|
// if we don't have the whitelist yet don't remove the entry
|
||||||
if (not has_whitelist)
|
if (not whitelist_received)
|
||||||
{
|
{
|
||||||
log::debug(logcat, "Skipping check on {}: don't have whitelist yet", rc.router_id());
|
log::debug(logcat, "Skipping check on {}: don't have whitelist yet", rc.router_id());
|
||||||
return false;
|
return false;
|
||||||
|
@ -924,7 +912,7 @@ namespace llarp
|
||||||
// the whitelist enabled and we got the whitelist
|
// the whitelist enabled and we got the whitelist
|
||||||
// check against the whitelist and remove if it's not
|
// check against the whitelist and remove if it's not
|
||||||
// in the whitelist OR if there is no whitelist don't remove
|
// in the whitelist OR if there is no whitelist don't remove
|
||||||
if (has_whitelist and not _rc_lookup_handler.is_session_allowed(rc.router_id()))
|
if (not node_db()->is_connection_allowed(rc.router_id()))
|
||||||
{
|
{
|
||||||
log::debug(logcat, "Removing {}: not a valid router", rc.router_id());
|
log::debug(logcat, "Removing {}: not a valid router", rc.router_id());
|
||||||
return true;
|
return true;
|
||||||
|
@ -932,7 +920,9 @@ namespace llarp
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (not is_snode or not has_whitelist)
|
/* TODO: this behavior seems incorrect, but fixing it will require discussion
|
||||||
|
*
|
||||||
|
if (not is_snode or not whitelist_received)
|
||||||
{
|
{
|
||||||
// find all deregistered relays
|
// find all deregistered relays
|
||||||
std::unordered_set<RouterID> close_peers;
|
std::unordered_set<RouterID> close_peers;
|
||||||
|
@ -948,23 +938,18 @@ namespace llarp
|
||||||
for (auto& peer : close_peers)
|
for (auto& peer : close_peers)
|
||||||
_link_manager.deregister_peer(peer);
|
_link_manager.deregister_peer(peer);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
_link_manager.check_persisting_conns(now);
|
_link_manager.check_persisting_conns(now);
|
||||||
|
|
||||||
size_t connected = NumberOfConnectedRouters();
|
size_t connected = NumberOfConnectedRouters();
|
||||||
|
|
||||||
const int interval = is_snode ? 5 : 2;
|
|
||||||
const auto timepoint_now = std::chrono::steady_clock::now();
|
|
||||||
if (timepoint_now >= _next_explore_at and not is_decommed)
|
|
||||||
{
|
|
||||||
_rc_lookup_handler.explore_network();
|
|
||||||
_next_explore_at = timepoint_now + std::chrono::seconds(interval);
|
|
||||||
}
|
|
||||||
size_t connectToNum = _link_manager.min_connected_routers;
|
size_t connectToNum = _link_manager.min_connected_routers;
|
||||||
const auto strictConnect = _rc_lookup_handler.num_strict_connect_routers();
|
const auto& pinned_edges = _node_db->get_pinned_edges();
|
||||||
if (strictConnect > 0 && connectToNum > strictConnect)
|
const auto pinned_count = pinned_edges.size();
|
||||||
|
if (pinned_count > 0 && connectToNum > pinned_count)
|
||||||
{
|
{
|
||||||
connectToNum = strictConnect;
|
connectToNum = pinned_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_snode and now >= _next_decomm_warning)
|
if (is_snode and now >= _next_decomm_warning)
|
||||||
|
@ -1032,13 +1017,20 @@ namespace llarp
|
||||||
return _link_manager.get_random_connected(result);
|
return _link_manager.get_random_connected(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_set<RouterID>
|
||||||
|
Router::router_whitelist() const
|
||||||
|
{
|
||||||
|
return _node_db->whitelist();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Router::set_router_whitelist(
|
Router::set_router_whitelist(
|
||||||
const std::vector<RouterID>& whitelist,
|
const std::vector<RouterID>& whitelist,
|
||||||
const std::vector<RouterID>& greylist,
|
const std::vector<RouterID>& greylist,
|
||||||
const std::vector<RouterID>& unfundedlist)
|
const std::vector<RouterID>& unfundedlist)
|
||||||
{
|
{
|
||||||
_rc_lookup_handler.set_router_whitelist(whitelist, greylist, unfundedlist);
|
node_db()->set_router_whitelist(whitelist, greylist, unfundedlist);
|
||||||
|
whitelist_received = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "rc_gossiper.hpp"
|
#include "rc_gossiper.hpp"
|
||||||
#include "rc_lookup_handler.hpp"
|
|
||||||
#include "route_poker.hpp"
|
#include "route_poker.hpp"
|
||||||
|
|
||||||
#include <llarp/bootstrap.hpp>
|
#include <llarp/bootstrap.hpp>
|
||||||
|
@ -59,8 +58,6 @@ namespace llarp
|
||||||
static constexpr size_t INTROSET_STORAGE_REDUNDANCY =
|
static constexpr size_t INTROSET_STORAGE_REDUNDANCY =
|
||||||
(INTROSET_RELAY_REDUNDANCY * INTROSET_REQS_PER_RELAY);
|
(INTROSET_RELAY_REDUNDANCY * INTROSET_REQS_PER_RELAY);
|
||||||
|
|
||||||
static constexpr size_t RC_LOOKUP_STORAGE_REDUNDANCY{4};
|
|
||||||
|
|
||||||
struct Contacts;
|
struct Contacts;
|
||||||
|
|
||||||
struct Router : std::enable_shared_from_this<Router>
|
struct Router : std::enable_shared_from_this<Router>
|
||||||
|
@ -122,12 +119,12 @@ namespace llarp
|
||||||
const llarp_time_t _randomStartDelay;
|
const llarp_time_t _randomStartDelay;
|
||||||
|
|
||||||
std::shared_ptr<rpc::LokidRpcClient> _rpc_client;
|
std::shared_ptr<rpc::LokidRpcClient> _rpc_client;
|
||||||
|
bool whitelist_received{false};
|
||||||
|
|
||||||
oxenmq::address rpc_addr;
|
oxenmq::address rpc_addr;
|
||||||
Profiling _router_profiling;
|
Profiling _router_profiling;
|
||||||
fs::path _profile_file;
|
fs::path _profile_file;
|
||||||
LinkManager _link_manager{*this};
|
LinkManager _link_manager{*this};
|
||||||
RCLookupHandler _rc_lookup_handler;
|
|
||||||
RCGossiper _rcGossiper;
|
RCGossiper _rcGossiper;
|
||||||
|
|
||||||
/// how often do we resign our RC? milliseconds.
|
/// how often do we resign our RC? milliseconds.
|
||||||
|
@ -211,12 +208,6 @@ namespace llarp
|
||||||
return _link_manager;
|
return _link_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
RCLookupHandler&
|
|
||||||
rc_lookup_handler()
|
|
||||||
{
|
|
||||||
return _rc_lookup_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
outbound_udp_socket() const
|
outbound_udp_socket() const
|
||||||
{
|
{
|
||||||
|
@ -293,10 +284,7 @@ namespace llarp
|
||||||
ExtractSummaryStatus() const;
|
ExtractSummaryStatus() const;
|
||||||
|
|
||||||
std::unordered_set<RouterID>
|
std::unordered_set<RouterID>
|
||||||
router_whitelist() const
|
router_whitelist() const;
|
||||||
{
|
|
||||||
return _rc_lookup_handler.whitelist();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
set_router_whitelist(
|
set_router_whitelist(
|
||||||
|
@ -389,8 +377,8 @@ namespace llarp
|
||||||
void
|
void
|
||||||
InitOutboundLinks();
|
InitOutboundLinks();
|
||||||
|
|
||||||
bool
|
std::optional<RouterID>
|
||||||
GetRandomGoodRouter(RouterID& r);
|
GetRandomGoodRouter();
|
||||||
|
|
||||||
/// initialize us as a service node
|
/// initialize us as a service node
|
||||||
/// return true on success
|
/// return true on success
|
||||||
|
|
Loading…
Reference in a new issue