Skip to content

Commit

Permalink
make lokinet client with strict-connect option provided explicitly co…
Browse files Browse the repository at this point in the history
…nnect out to snodes provided.

* create new component for selecting edge snodes as client (llarp::consensus::EdgeSelector)
* require llarp::AbstractRouter own a llarp::consensus::EdgeSelector
* make outbound_session_maker.cpp use llarp::consensus::EdgeSelector owned by llarp::AbstractRouter
  • Loading branch information
jeff committed May 11, 2023
1 parent a294c81 commit dea8ad2
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 26 deletions.
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

0 comments on commit dea8ad2

Please sign in to comment.