Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make clients with strict-connect option explicitly connect to provided snode. #2174

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llarp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ add_library(lokinet-config
# lokinet-consensus is for deriving and tracking network consensus state for both service nodes and clients
add_library(lokinet-consensus
STATIC
consensus/edge_selector.cpp
consensus/reachability_testing.cpp
)

Expand Down
71 changes: 71 additions & 0 deletions llarp/consensus/edge_selector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "edge_selector.hpp"

#include <llarp/router/abstractrouter.hpp>
#include <llarp/crypto/crypto.hpp>
#include <llarp/nodedb.hpp>
#include <llarp/profiling.hpp>

namespace llarp::consensus
{

EdgeSelector::EdgeSelector(AbstractRouter& r) : _router{r}
{}

std::optional<RouterContact>
EdgeSelector::select_path_edge(const std::unordered_set<RouterID>& connected_now) const
{
auto conf = _router.GetConfig();
auto nodedb = _router.nodedb();

const auto& _keys = conf->network.m_strictConnect;
// no strict hops. select a random good snode.
if (_keys.empty())
{
return nodedb->GetRandom([&connected_now, this](const auto& rc) {
return connected_now.count(rc.pubkey) == 0
and not _router.routerProfiling().IsBadForConnect(rc.pubkey)
and not _router.IsBootstrapNode(rc.pubkey);
});
}

// select random from strict connections.
std::vector<RouterID> keys{_keys.begin(), _keys.end()};

std::shuffle(keys.begin(), keys.end(), llarp::CSRNG{});

for (const auto& pk : keys)
{
if (_router.routerProfiling().IsBadForConnect(pk))
continue;
if (connected_now.count(pk))
continue;
if (auto maybe = nodedb->Get(pk))
return maybe;
}
return std::nullopt;
}

std::optional<RouterContact>
EdgeSelector::select_bootstrap(const std::unordered_set<RouterID>& connected_now) const
{
auto conf = _router.GetConfig();
auto nodedb = _router.nodedb();
if (const auto& _keys = conf->network.m_strictConnect; not _keys.empty())
{
// try bootstrapping off strict connections first if we have any.
std::vector<RouterID> keys{_keys.begin(), _keys.end()};
std::shuffle(keys.begin(), keys.end(), llarp::CSRNG{});
for (const auto& pk : keys)
{
if (connected_now.count(pk))
continue;
if (auto maybe = nodedb->Get(pk))
return maybe;
}
}
// if we cant use a strict connection we'll just use one of our bootstrap nodes.
return nodedb->GetRandom([&connected_now, this](const auto& rc) {
return connected_now.count(rc.pubkey) == 0 and _router.IsBootstrapNode(rc.pubkey);
});
}
} // namespace llarp::consensus
35 changes: 35 additions & 0 deletions llarp/consensus/edge_selector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include <optional>
#include <unordered_set>
#include <llarp/router_id.hpp>

namespace llarp
{
struct AbstractRouter;
struct RouterContact;
} // namespace llarp

namespace llarp::consensus
{
/// when we want to connect to and edge when we are a client, an instance of EdgeSelector acts as
/// a stateless selection algorith for router contacts for each attempt at connecting out we make.
class EdgeSelector
{
AbstractRouter& _router;

public:
explicit EdgeSelector(AbstractRouter& router);

/// select a candidate for connecting out to the network when we need more connections to do a
/// path build. pass in an unordered set of the snode pubkeys we are currently connected to.
std::optional<RouterContact>
select_path_edge(const std::unordered_set<RouterID>& connected_now = {}) const;

/// get a router contact of a bootstrap snode to bootstrap with if we are in need of
/// bootstrapping more peers. pass in an unodereed set of bootstrap router pubkeys we are
/// currently connected to.
std::optional<RouterContact>
select_bootstrap(const std::unordered_set<RouterID>& connected_now = {}) const;
};
} // namespace llarp::consensus
8 changes: 8 additions & 0 deletions llarp/router/abstractrouter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ namespace llarp
struct I_RCLookupHandler;
struct RoutePoker;

namespace consensus
{
class EdgeSelector;
}

namespace dns
{
class I_SystemSettings;
Expand Down Expand Up @@ -130,6 +135,9 @@ namespace llarp
virtual const RouterContact&
rc() const = 0;

virtual const consensus::EdgeSelector&
edge_selector() const = 0;

/// modify our rc
/// modify returns nullopt if unmodified otherwise it returns the new rc to be sigend and
/// published out
Expand Down
34 changes: 14 additions & 20 deletions llarp/router/outbound_session_maker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <llarp/util/thread/threading.hpp>
#include <llarp/util/status.hpp>
#include <llarp/crypto/crypto.hpp>
#include <llarp/consensus/edge_selector.hpp>
#include <utility>

#include <llarp/rpc/lokid_rpc_client.hpp>
Expand Down Expand Up @@ -139,30 +140,23 @@ namespace llarp
OutboundSessionMaker::ConnectToRandomRouters(int numDesired)
{
int remainingDesired = numDesired;
std::set<RouterID> exclude;
std::unordered_set<RouterID> exclude;
for (const auto& item : pendingSessions)
exclude.emplace(item.first);
_linkManager->ForEachPeer([&exclude](auto* session) {
if (session and session->IsEstablished())
exclude.emplace(session->GetPubKey());
});
do
{
auto filter = [exclude](const auto& rc) -> bool { return exclude.count(rc.pubkey) == 0; };

RouterContact other;
if (const auto maybe = _nodedb->GetRandom(filter))
{
other = *maybe;
}
else
auto maybe_rc = _router->edge_selector().select_path_edge(exclude);
if (not maybe_rc)
break;

exclude.insert(other.pubkey);
if (not _rcLookup->SessionIsAllowed(other.pubkey))
{
continue;
}
if (not(_linkManager->HasSessionTo(other.pubkey) || HavePendingSessionTo(other.pubkey)))
{
CreateSessionTo(other, nullptr);
--remainingDesired;
}

const auto& rc = *maybe_rc;
exclude.insert(rc.pubkey);
CreateSessionTo(rc, nullptr);
--remainingDesired;
} while (remainingDesired > 0);
LogDebug(
"connecting to ", numDesired - remainingDesired, " out of ", numDesired, " random routers");
Expand Down
15 changes: 9 additions & 6 deletions llarp/router/router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace llarp
Router::Router(EventLoop_ptr loop, std::shared_ptr<vpn::Platform> vpnPlatform)
: ready{false}
, m_lmq{std::make_shared<oxenmq::OxenMQ>()}
, _edge_selector{*this}
, _loop{std::move(loop)}
, _vpnPlatform{std::move(vpnPlatform)}
, paths{this}
Expand Down Expand Up @@ -869,6 +870,12 @@ namespace llarp
m_LastStatsReport = now;
}

const consensus::EdgeSelector&
Router::edge_selector() const
{
return _edge_selector;
}

std::string
Router::status_line()
{
Expand Down Expand Up @@ -1059,12 +1066,8 @@ namespace llarp
_rcLookupHandler.ExploreNetwork();
m_NextExploreAt = timepoint_now + std::chrono::seconds(interval);
}
size_t connectToNum = _outboundSessionMaker.minConnectedRouters;
const auto strictConnect = _rcLookupHandler.NumberOfStrictConnectRouters();
if (strictConnect > 0 && connectToNum > strictConnect)
{
connectToNum = strictConnect;
}

size_t connectToNum = _outboundSessionMaker.maxConnectedRouters;

if (isSvcNode and now >= m_NextDecommissionWarn)
{
Expand Down
6 changes: 6 additions & 0 deletions llarp/router/router.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "abstractrouter.hpp"

#include <llarp/bootstrap.hpp>
#include <llarp/consensus/edge_selector.hpp>
#include <llarp/config/config.hpp>
#include <llarp/config/key_manager.hpp>
#include <llarp/constants/link_layer.hpp>
Expand Down Expand Up @@ -79,6 +80,8 @@ namespace llarp

std::shared_ptr<EventLoopWakeup> m_Pump;

consensus::EdgeSelector _edge_selector;

path::BuildLimiter&
pathBuildLimiter() override
{
Expand Down Expand Up @@ -148,6 +151,9 @@ namespace llarp
const std::vector<RouterID>& greylist,
const std::vector<RouterID>& unfunded) override;

const consensus::EdgeSelector&
edge_selector() const override;

std::unordered_set<RouterID>
GetRouterWhitelist() const override
{
Expand Down