a soothing renomenclatura

- removed superfluous typedefs obfuscating what is actually happening
- Builder -> PathBuilder; next is moving PathSet into PathBuilder
- enum -> enum class where appropriate
- ran linter
pull/2232/head
dr7ana 4 months ago
parent fb19e148db
commit 9cc3efcfa7

@ -8,7 +8,7 @@ namespace llarp::exit
{
Endpoint::Endpoint(
const llarp::PubKey& remoteIdent,
const llarp::path::HopHandler_ptr& beginPath,
const std::shared_ptr<llarp::path::AbstractHopHandler>& beginPath,
bool rewriteIP,
huint128_t ip,
llarp::handlers::ExitEndpoint* parent)

@ -25,7 +25,7 @@ namespace llarp
explicit Endpoint(
const llarp::PubKey& remoteIdent,
const llarp::path::HopHandler_ptr& path,
const std::shared_ptr<llarp::path::AbstractHopHandler>& path,
bool rewriteIP,
huint128_t ip,
llarp::handlers::ExitEndpoint* parent);
@ -74,7 +74,7 @@ namespace llarp
bool
UpdateLocalPath(const llarp::PathID_t& nextPath);
llarp::path::HopHandler_ptr
std::shared_ptr<llarp::path::AbstractHopHandler>
GetCurrentPath() const
{
return current_path;
@ -115,7 +115,7 @@ namespace llarp
private:
llarp::handlers::ExitEndpoint* parent;
llarp::PubKey remote_signkey;
llarp::path::HopHandler_ptr current_path;
std::shared_ptr<llarp::path::AbstractHopHandler> current_path;
llarp::huint128_t IP;
uint64_t tx_rate, rx_rate;
llarp_time_t last_active;

@ -17,7 +17,7 @@ namespace llarp::exit
size_t numpaths,
size_t hoplen,
EndpointBase* parent)
: llarp::path::Builder{r, numpaths, hoplen}
: llarp::path::PathBuilder{r, numpaths, hoplen}
, exit_router{routerId}
, packet_write_func{std::move(writepkt)}
, _last_use{r->now()}
@ -30,7 +30,7 @@ namespace llarp::exit
BaseSession::~BaseSession() = default;
void
BaseSession::HandlePathDied(path::Path_ptr p)
BaseSession::HandlePathDied(std::shared_ptr<path::Path> p)
{
p->Rebuild();
}
@ -38,7 +38,7 @@ namespace llarp::exit
util::StatusObject
BaseSession::ExtractStatus() const
{
auto obj = path::Builder::ExtractStatus();
auto obj = path::PathBuilder::ExtractStatus();
obj["lastExitUse"] = to_json(_last_use);
auto pub = exit_key.toPublic();
obj["exitIdentity"] = pub.ToString();
@ -57,9 +57,9 @@ namespace llarp::exit
{
if (BuildCooldownHit(now))
return false;
const size_t expect = (1 + (numDesiredPaths / 2));
const size_t expect = (1 + (num_paths_desired / 2));
// check 30 seconds into the future and see if we need more paths
const llarp_time_t future = now + 30s + buildIntervalLimit;
const llarp_time_t future = now + 30s + build_interval_limit;
return NumPathsExistingAt(future) < expect;
}
@ -72,7 +72,7 @@ namespace llarp::exit
std::optional<std::vector<RemoteRC>>
BaseSession::GetHopsForBuild()
{
if (numHops == 1)
if (num_hops == 1)
{
if (auto maybe = router->node_db()->get_rc(exit_router))
return std::vector<RemoteRC>{*maybe};
@ -83,15 +83,15 @@ namespace llarp::exit
}
bool
BaseSession::CheckPathDead(path::Path_ptr, llarp_time_t dlt)
BaseSession::CheckPathDead(std::shared_ptr<path::Path>, llarp_time_t dlt)
{
return dlt >= path::ALIVE_TIMEOUT;
}
void
BaseSession::HandlePathBuilt(llarp::path::Path_ptr p)
BaseSession::HandlePathBuilt(std::shared_ptr<path::Path> p)
{
path::Builder::HandlePathBuilt(p);
path::PathBuilder::HandlePathBuilt(p);
// p->SetDropHandler(util::memFn(&BaseSession::HandleTrafficDrop, this));
// p->SetDeadChecker(util::memFn(&BaseSession::CheckPathDead, this));
// p->SetExitTrafficHandler(util::memFn(&BaseSession::HandleTraffic, this));
@ -108,16 +108,16 @@ namespace llarp::exit
void
BaseSession::AddReadyHook(SessionReadyFunc func)
{
m_PendingCallbacks.emplace_back(func);
_pending_callbacks.emplace_back(func);
}
bool
BaseSession::HandleGotExit(llarp::path::Path_ptr p, llarp_time_t b)
BaseSession::HandleGotExit(std::shared_ptr<path::Path> p, llarp_time_t b)
{
if (b == 0s)
{
llarp::LogInfo("obtained an exit via ", p->Endpoint());
m_CurrentPath = p->RXID();
_current_path = p->RXID();
CallPendingCallbacks(true);
}
return true;
@ -126,27 +126,27 @@ namespace llarp::exit
void
BaseSession::CallPendingCallbacks(bool success)
{
if (m_PendingCallbacks.empty())
if (_pending_callbacks.empty())
return;
if (success)
{
auto self = shared_from_this();
for (auto& f : m_PendingCallbacks)
for (auto& f : _pending_callbacks)
f(self);
}
else
{
for (auto& f : m_PendingCallbacks)
for (auto& f : _pending_callbacks)
f(nullptr);
}
m_PendingCallbacks.clear();
_pending_callbacks.clear();
}
void
BaseSession::ResetInternalState()
{
auto sendExitClose = [&](const llarp::path::Path_ptr p) {
auto sendExitClose = [&](const std::shared_ptr<path::Path> p) {
const static auto roles = llarp::path::ePathRoleExit | llarp::path::ePathRoleSVC;
if (p->SupportsAnyRoles(roles))
{
@ -159,14 +159,14 @@ namespace llarp::exit
};
ForEachPath(sendExitClose);
path::Builder::ResetInternalState();
path::PathBuilder::ResetInternalState();
}
bool
BaseSession::Stop()
{
CallPendingCallbacks(false);
auto sendExitClose = [&](const path::Path_ptr p) {
auto sendExitClose = [&](const std::shared_ptr<path::Path> p) {
if (p->SupportsAnyRoles(path::ePathRoleExit))
{
LogInfo(p->name(), " closing exit path");
@ -180,12 +180,12 @@ namespace llarp::exit
};
ForEachPath(sendExitClose);
router->path_context().RemovePathSet(shared_from_this());
return path::Builder::Stop();
return path::PathBuilder::Stop();
}
bool
BaseSession::HandleTraffic(
llarp::path::Path_ptr, const llarp_buffer_t&, uint64_t, service::ProtocolType)
std::shared_ptr<path::Path>, const llarp_buffer_t&, uint64_t, service::ProtocolType)
{
// const service::ConvoTag tag{path->RXID().as_array()};
@ -211,26 +211,26 @@ namespace llarp::exit
}
bool
BaseSession::HandleTrafficDrop(llarp::path::Path_ptr p, const PathID_t& path, uint64_t s)
BaseSession::HandleTrafficDrop(std::shared_ptr<path::Path> p, const PathID_t& path, uint64_t s)
{
llarp::LogError("dropped traffic on exit ", exit_router, " S=", s, " P=", path);
p->EnterState(path::IGNORE, router->now());
p->EnterState(path::PathStatus::IGNORE, router->now());
return true;
}
bool
BaseSession::IsReady() const
{
if (m_CurrentPath.IsZero())
if (_current_path.IsZero())
return false;
const size_t expect = (1 + (numDesiredPaths / 2));
const size_t expect = (1 + (num_paths_desired / 2));
return AvailablePaths(llarp::path::ePathRoleExit) >= expect;
}
bool
BaseSession::IsExpired(llarp_time_t now) const
{
return now > _last_use && now - _last_use > LifeSpan;
return now > _last_use && now - _last_use > path::DEFAULT_LIFETIME;
}
bool
@ -238,8 +238,8 @@ namespace llarp::exit
{
if (BuildCooldownHit(now))
return false;
if (IsReady() and NumInStatus(path::BUILDING) < numDesiredPaths)
return path::Builder::UrgentBuild(now);
if (IsReady() and NumInStatus(path::PathStatus::BUILDING) < num_paths_desired)
return path::PathBuilder::UrgentBuild(now);
return false;
}

@ -21,18 +21,12 @@ namespace llarp
{
struct BaseSession;
using BaseSession_ptr = std::shared_ptr<BaseSession>;
using SessionReadyFunc = std::function<void(BaseSession_ptr)>;
static constexpr auto LifeSpan = path::DEFAULT_LIFETIME;
using SessionReadyFunc = std::function<void(std::shared_ptr<BaseSession>)>;
/// a persisting exit session with an exit router
struct BaseSession : public llarp::path::Builder,
struct BaseSession : public llarp::path::PathBuilder,
public std::enable_shared_from_this<BaseSession>
{
static constexpr size_t MaxUpstreamQueueLength = 256;
BaseSession(
const llarp::RouterID& exitRouter,
std::function<bool(const llarp_buffer_t&)> writepkt,
@ -67,10 +61,10 @@ namespace llarp
bool UrgentBuild(llarp_time_t) const override;
void
HandlePathDied(llarp::path::Path_ptr p) override;
HandlePathDied(std::shared_ptr<path::Path> p) override;
bool
CheckPathDead(path::Path_ptr p, llarp_time_t dlt);
CheckPathDead(std::shared_ptr<path::Path> p, llarp_time_t dlt);
std::optional<std::vector<RemoteRC>>
GetHopsForBuild() override;
@ -79,7 +73,7 @@ namespace llarp
ShouldBuildMore(llarp_time_t now) const override;
void
HandlePathBuilt(llarp::path::Path_ptr p) override;
HandlePathBuilt(std::shared_ptr<path::Path> p) override;
/// flush upstream to exit via paths
bool
@ -111,9 +105,9 @@ namespace llarp
std::optional<PathID_t>
CurrentPath() const
{
if (m_CurrentPath.IsZero())
if (_current_path.IsZero())
return std::nullopt;
return m_CurrentPath;
return _current_path;
}
bool
@ -131,14 +125,14 @@ namespace llarp
std::function<bool(const llarp_buffer_t&)> packet_write_func;
bool
HandleTrafficDrop(llarp::path::Path_ptr p, const llarp::PathID_t& path, uint64_t s);
HandleTrafficDrop(std::shared_ptr<path::Path> p, const llarp::PathID_t& path, uint64_t s);
bool
HandleGotExit(llarp::path::Path_ptr p, llarp_time_t b);
HandleGotExit(std::shared_ptr<path::Path> p, llarp_time_t b);
bool
HandleTraffic(
llarp::path::Path_ptr p,
std::shared_ptr<path::Path> p,
const llarp_buffer_t& buf,
uint64_t seqno,
service::ProtocolType t);
@ -146,23 +140,12 @@ namespace llarp
private:
std::set<RouterID> snode_blacklist;
PathID_t m_CurrentPath;
using DownstreamPkt = std::pair<uint64_t, llarp::net::IPPacket>;
struct DownstreamPktSorter
{
bool
operator()(const DownstreamPkt& left, const DownstreamPkt& right) const
{
return left.first < right.first;
}
};
PathID_t _current_path;
// uint64_t _counter;
llarp_time_t _last_use;
std::vector<SessionReadyFunc> m_PendingCallbacks;
std::vector<SessionReadyFunc> _pending_callbacks;
// const bool _bundle_RC;
EndpointBase* const _parent;

@ -0,0 +1,7 @@
#pragma once
namespace llarp::handlers
{
struct AbstractHandler
{};
} // namespace llarp::handlers

@ -765,8 +765,9 @@ namespace llarp::handlers
if (wantInternet && !permit_exit)
return false;
// TODO: is this getting a path or a transit hop or...somehow possibly either?
// path::HopHandler_ptr handler = router->path_context().GetByUpstream(router->pubkey(), path);
path::HopHandler_ptr handler{};
// std::shared_ptr<path::AbstractHopHandler> handler =
// router->path_context().GetByUpstream(router->pubkey(), path);
std::shared_ptr<path::AbstractHopHandler> handler{};
if (handler == nullptr)
return false;
auto ip = GetIPForIdent(pk);

@ -10,233 +10,234 @@
namespace llarp
{
struct Router;
namespace handlers
}
namespace llarp::handlers
{
struct ExitEndpoint : public dns::Resolver_Base, public EndpointBase
{
struct ExitEndpoint : public dns::Resolver_Base, public EndpointBase
int
Rank() const override
{
int
Rank() const override
{
return 0;
};
return 0;
};
std::string_view
ResolverName() const override
{
return "snode";
}
std::string_view
ResolverName() const override
{
return "snode";
}
bool
MaybeHookDNS(
std::shared_ptr<dns::PacketSource_Base> source,
const dns::Message& query,
const SockAddr& to,
const SockAddr& from) override;
bool
MaybeHookDNS(
std::shared_ptr<dns::PacketSource_Base> source,
const dns::Message& query,
const SockAddr& to,
const SockAddr& from) override;
ExitEndpoint(std::string name, Router* r);
~ExitEndpoint() override;
ExitEndpoint(std::string name, Router* r);
~ExitEndpoint() override;
std::optional<AddressVariant_t>
GetEndpointWithConvoTag(service::ConvoTag tag) const override;
std::optional<AddressVariant_t>
GetEndpointWithConvoTag(service::ConvoTag tag) const override;
std::optional<service::ConvoTag>
GetBestConvoTagFor(AddressVariant_t addr) const override;
std::optional<service::ConvoTag>
GetBestConvoTagFor(AddressVariant_t addr) const override;
bool
EnsurePathTo(
AddressVariant_t addr,
std::function<void(std::optional<service::ConvoTag>)> hook,
llarp_time_t timeout) override;
bool
EnsurePathTo(
AddressVariant_t addr,
std::function<void(std::optional<service::ConvoTag>)> hook,
llarp_time_t timeout) override;
void
lookup_name(std::string name, std::function<void(std::string, bool)> func) override;
void
lookup_name(std::string name, std::function<void(std::string, bool)> func) override;
const EventLoop_ptr&
Loop() override;
const EventLoop_ptr&
Loop() override;
std::unordered_set<EndpointBase::AddressVariant_t>
AllRemoteEndpoints() const override;
std::unordered_set<EndpointBase::AddressVariant_t>
AllRemoteEndpoints() const override;
void
SRVRecordsChanged() override;
void
SRVRecordsChanged() override;
void MarkAddressOutbound(service::Address) override{};
void MarkAddressOutbound(service::Address) override{};
bool
send_to(service::ConvoTag tag, std::string payload) override;
bool
send_to(service::ConvoTag tag, std::string payload) override;
void
Tick(llarp_time_t now);
void
Tick(llarp_time_t now);
void
Configure(const NetworkConfig& networkConfig, const DnsConfig& dnsConfig);
void
Configure(const NetworkConfig& networkConfig, const DnsConfig& dnsConfig);
std::string
Name() const;
std::string
Name() const;
bool
VisitEndpointsFor(const PubKey& pk, std::function<bool(exit::Endpoint* const)> visit) const;
bool
VisitEndpointsFor(const PubKey& pk, std::function<bool(exit::Endpoint* const)> visit) const;
util::StatusObject
ExtractStatus() const;
util::StatusObject
ExtractStatus() const;
bool
SupportsV6() const;
bool
SupportsV6() const;
bool
ShouldHookDNSMessage(const dns::Message& msg) const;
bool
ShouldHookDNSMessage(const dns::Message& msg) const;
bool
HandleHookedDNSMessage(dns::Message msg, std::function<void(dns::Message)>);
bool
HandleHookedDNSMessage(dns::Message msg, std::function<void(dns::Message)>);
void
LookupServiceAsync(
std::string name,
std::string service,
std::function<void(std::vector<dns::SRVData>)> handler) override;
void
LookupServiceAsync(
std::string name,
std::string service,
std::function<void(std::vector<dns::SRVData>)> handler) override;
bool
AllocateNewExit(const PubKey pk, const PathID_t& path, bool permitInternet);
bool
AllocateNewExit(const PubKey pk, const PathID_t& path, bool permitInternet);
exit::Endpoint*
FindEndpointByPath(const PathID_t& path);
exit::Endpoint*
FindEndpointByPath(const PathID_t& path);
exit::Endpoint*
FindEndpointByIP(huint32_t ip);
exit::Endpoint*
FindEndpointByIP(huint32_t ip);
bool
UpdateEndpointPath(const PubKey& remote, const PathID_t& next);
bool
UpdateEndpointPath(const PubKey& remote, const PathID_t& next);
/// handle ip packet from outside
void
OnInetPacket(net::IPPacket buf);
/// handle ip packet from outside
void
OnInetPacket(net::IPPacket buf);
Router*
GetRouter();
Router*
GetRouter();
llarp_time_t
Now() const;
llarp_time_t
Now() const;
template <typename Stats>
void
CalculateTrafficStats(Stats& stats)
template <typename Stats>
void
CalculateTrafficStats(Stats& stats)
{
for (auto& [pubkey, endpoint] : active_exits)
{
for (auto& [pubkey, endpoint] : active_exits)
{
stats[pubkey].first += endpoint->TxRate();
stats[pubkey].second += endpoint->RxRate();
}
stats[pubkey].first += endpoint->TxRate();
stats[pubkey].second += endpoint->RxRate();
}
}
/// DO NOT CALL ME
void
DelEndpointInfo(const PathID_t& path);
/// DO NOT CALL ME
void
DelEndpointInfo(const PathID_t& path);
/// DO NOT CALL ME
void
RemoveExit(const exit::Endpoint* ep);
/// DO NOT CALL ME
void
RemoveExit(const exit::Endpoint* ep);
bool
QueueOutboundTraffic(net::IPPacket pkt);
bool
QueueOutboundTraffic(net::IPPacket pkt);
AddressVariant_t
LocalAddress() const override;
AddressVariant_t
LocalAddress() const override;
std::optional<SendStat>
GetStatFor(AddressVariant_t remote) const override;
std::optional<SendStat>
GetStatFor(AddressVariant_t remote) const override;
/// sets up networking and starts traffic
bool
Start();
/// sets up networking and starts traffic
bool
Start();
bool
Stop();
bool
Stop();
bool
ShouldRemove() const;
bool
ShouldRemove() const;
bool
HasLocalMappedAddrFor(const PubKey& pk) const;
bool
HasLocalMappedAddrFor(const PubKey& pk) const;
huint128_t
GetIfAddr() const;
huint128_t
GetIfAddr() const;
void
Flush();
void
Flush();
link::TunnelManager*
GetQUICTunnel() override;
link::TunnelManager*
GetQUICTunnel() override;
huint128_t
GetIPForIdent(const PubKey pk);
/// async obtain snode session and call callback when it's ready to send
void
ObtainSNodeSession(const RouterID& rid, exit::SessionReadyFunc obtain_cb);
huint128_t
GetIPForIdent(const PubKey pk);
/// async obtain snode session and call callback when it's ready to send
void
ObtainSNodeSession(const RouterID& rid, exit::SessionReadyFunc obtain_cb);
private:
huint128_t
AllocateNewAddress();
private:
huint128_t
AllocateNewAddress();
/// obtain ip for service node session, creates a new session if one does
/// not existing already
huint128_t
ObtainServiceNodeIP(const RouterID& router);
/// obtain ip for service node session, creates a new session if one does
/// not existing already
huint128_t
ObtainServiceNodeIP(const RouterID& router);
bool
QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from);
bool
QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from);
void
MarkIPActive(huint128_t ip);
void
MarkIPActive(huint128_t ip);
void
KickIdentOffExit(const PubKey& pk);
void
KickIdentOffExit(const PubKey& pk);
Router* router;
std::shared_ptr<dns::Server> resolver;
bool should_init_tun;
std::string name;
bool permit_exit;
std::unordered_map<PathID_t, PubKey> paths;
Router* router;
std::shared_ptr<dns::Server> resolver;
bool should_init_tun;
std::string name;
bool permit_exit;
std::unordered_map<PathID_t, PubKey> paths;
std::unordered_map<PubKey, exit::Endpoint*> chosen_exits;
std::unordered_map<PubKey, exit::Endpoint*> chosen_exits;
std::unordered_multimap<PubKey, std::unique_ptr<exit::Endpoint>> active_exits;
std::unordered_multimap<PubKey, std::unique_ptr<exit::Endpoint>> active_exits;
std::unordered_map<PubKey, huint128_t> key_to_IP;
std::unordered_map<PubKey, huint128_t> key_to_IP;
using SNodes_t = std::set<PubKey>;
/// set of pubkeys we treat as snodes
SNodes_t snode_keys;
using SNodes_t = std::set<PubKey>;
/// set of pubkeys we treat as snodes
SNodes_t snode_keys;
using SNodeSessions_t = std::unordered_map<RouterID, std::shared_ptr<exit::SNodeSession>>;
/// snode sessions we are talking to directly
SNodeSessions_t snode_sessions;
using SNodeSessions_t = std::unordered_map<RouterID, std::shared_ptr<exit::SNodeSession>>;
/// snode sessions we are talking to directly
SNodeSessions_t snode_sessions;
std::unordered_map<huint128_t, PubKey> ip_to_key;
std::unordered_map<huint128_t, PubKey> ip_to_key;
huint128_t if_addr;
huint128_t highest_addr;
huint128_t if_addr;
huint128_t highest_addr;
huint128_t next_addr;
IPRange ip_range;
std::string if_name;
huint128_t next_addr;
IPRange ip_range;
std::string if_name;
std::unordered_map<huint128_t, llarp_time_t> ip_activity;
std::unordered_map<huint128_t, llarp_time_t> ip_activity;
std::shared_ptr<vpn::NetworkInterface> if_net;
std::shared_ptr<vpn::NetworkInterface> if_net;
SockAddr resolver_addr;
std::vector<SockAddr> upstream_resolvers;
SockAddr resolver_addr;
std::vector<SockAddr> upstream_resolvers;
// std::shared_ptr<link::TunnelManager> tunnel_manager;
// std::shared_ptr<link::TunnelManager> tunnel_manager;
using PacketQueue_t = std::
priority_queue<net::IPPacket, std::vector<net::IPPacket>, net::IPPacket::CompareOrder>;
using PacketQueue_t =
std::priority_queue<net::IPPacket, std::vector<net::IPPacket>, net::IPPacket::CompareOrder>;
/// internet to llarp packet queue
PacketQueue_t inet_to_network;
bool use_ipv6;
DnsConfig dns_conf;
};
} // namespace handlers
} // namespace llarp
/// internet to llarp packet queue
PacketQueue_t inet_to_network;
bool use_ipv6;
DnsConfig dns_conf;
};
} // namespace llarp::handlers

@ -81,7 +81,7 @@ namespace llarp::handlers
return "";
}
path::PathSet_ptr
std::shared_ptr<path::PathSet>
GetSelf() override
{
return shared_from_this();

@ -505,7 +505,9 @@ namespace llarp::handlers
return EnsurePathToSNode(
snode,
[this, snode, msg, reply, isV6](
const RouterID&, exit::BaseSession_ptr s, [[maybe_unused]] service::ConvoTag tag) {
const RouterID&,
std::shared_ptr<exit::BaseSession> s,
[[maybe_unused]] service::ConvoTag tag) {
SendDNSReply(snode, s, msg, reply, isV6);
});
};

@ -50,7 +50,7 @@ namespace llarp::handlers
const SockAddr& to,
const SockAddr& from) override;
path::PathSet_ptr
std::shared_ptr<path::PathSet>
GetSelf() override
{
return shared_from_this();

@ -59,6 +59,7 @@ namespace llarp
virtual llarp_time_t
LastRemoteActivityAt() const = 0;
// TODO: remove this method after all commented out uses are deleted
uint64_t
NextSeqNo()
{
@ -69,6 +70,6 @@ namespace llarp
uint64_t m_SequenceNum = 0;
};
using HopHandler_ptr = std::shared_ptr<AbstractHopHandler>;
// using HopHandler_ptr = std::shared_ptr<AbstractHopHandler>;
} // namespace path
} // namespace llarp

@ -15,10 +15,10 @@ namespace llarp::path
std::weak_ptr<PathSet> pathset,
PathRole startingRoles,
std::string shortName)
: m_PathSet{std::move(pathset)}
: path_set{std::move(pathset)}
, router{*rtr}
, _role{startingRoles}
, m_shortName{std::move(shortName)}
, _short_name{std::move(shortName)}
{
hops.resize(h.size());
size_t hsz = h.size();
@ -43,8 +43,8 @@ namespace llarp::path
// initialize parts of the introduction
intro.router = hops[hsz - 1].rc.router_id();
intro.path_id = hops[hsz - 1].txID;
if (auto parent = m_PathSet.lock())
EnterState(BUILDING, parent->Now());
if (auto parent = path_set.lock())
EnterState(PathStatus::BUILDING, parent->Now());
}
bool
@ -186,7 +186,7 @@ namespace llarp::path
{
if (Expired(llarp::time_now_ms()))
return false;
return intro.latency > 0s && _status == ESTABLISHED;
return intro.latency > 0s && _status == PathStatus::ESTABLISHED;
}
bool
@ -202,9 +202,9 @@ namespace llarp::path
}
const std::string&
Path::ShortName() const
Path::short_name() const
{
return m_shortName;
return _short_name;
}
std::string
@ -227,42 +227,42 @@ namespace llarp::path
if (now == 0s)
now = router.now();
if (st == FAILED)
if (st == PathStatus::FAILED)
{
_status = st;
return;
}
if (st == EXPIRED && _status == BUILDING)
if (st == PathStatus::EXPIRED && _status == PathStatus::BUILDING)
{
_status = st;
if (auto parent = m_PathSet.lock())
if (auto parent = path_set.lock())
{
parent->HandlePathBuildTimeout(shared_from_this());
}
}
else if (st == BUILDING)
else if (st == PathStatus::BUILDING)
{
LogInfo("path ", name(), " is building");
buildStarted = now;
}
else if (st == ESTABLISHED && _status == BUILDING)
else if (st == PathStatus::ESTABLISHED && _status == PathStatus::BUILDING)
{
LogInfo("path ", name(), " is built, took ", ToString(now - buildStarted));
}
else if (st == TIMEOUT && _status == ESTABLISHED)
else if (st == PathStatus::TIMEOUT && _status == PathStatus::ESTABLISHED)
{
LogInfo("path ", name(), " died");
_status = st;
if (auto parent = m_PathSet.lock())
if (auto parent = path_set.lock())
{
parent->HandlePathDied(shared_from_this());
}
}
else if (st == ESTABLISHED && _status == TIMEOUT)
else if (st == PathStatus::ESTABLISHED && _status == PathStatus::TIMEOUT)
{
LogInfo("path ", name(), " reanimated");
}
else if (st == IGNORE)
else if (st == PathStatus::IGNORE)
{
LogInfo("path ", name(), " ignored");
}
@ -288,15 +288,15 @@ namespace llarp::path
util::StatusObject obj{
{"intro", intro.ExtractStatus()},
{"lastRecvMsg", to_json(m_LastRecvMessage)},
{"lastLatencyTest", to_json(m_LastLatencyTestTime)},
{"lastRecvMsg", to_json(last_recv_msg)},
{"lastLatencyTest", to_json(last_latency_test)},
{"buildStarted", to_json(buildStarted)},
{"expired", Expired(now)},
{"expiresSoon", ExpiresSoon(now)},
{"expiresAt", to_json(ExpireTime())},
{"ready", IsReady()},
{"txRateCurrent", m_LastTXRate},
{"rxRateCurrent", m_LastRXRate},
// {"txRateCurrent", m_LastTXRate},
// {"rxRateCurrent", m_LastRXRate},
{"hasExit", SupportsAnyRoles(ePathRoleExit)}};
std::vector<util::StatusObject> hopsObj;
@ -309,22 +309,22 @@ namespace llarp::path
switch (_status)
{
case BUILDING:
case PathStatus::BUILDING:
obj["status"] = "building";
break;
case ESTABLISHED:
case PathStatus::ESTABLISHED:
obj["status"] = "established";
break;
case TIMEOUT:
case PathStatus::TIMEOUT:
obj["status"] = "timeout";
break;
case EXPIRED:
case PathStatus::EXPIRED:
obj["status"] = "expired";
break;
case FAILED:
case PathStatus::FAILED:
obj["status"] = "failed";
break;
case IGNORE:
case PathStatus::IGNORE:
obj["status"] = "ignored";
break;
default:
@ -337,14 +337,14 @@ namespace llarp::path
void
Path::Rebuild()
{
if (auto parent = m_PathSet.lock())
if (auto parent = path_set.lock())
{
std::vector<RemoteRC> new_hops;
for (const auto& hop : hops)
new_hops.emplace_back(hop.rc);
LogInfo(name(), " rebuilding on ", ShortName());
LogInfo(name(), " rebuilding on ", short_name());
parent->Build(new_hops);
}
}
@ -379,13 +379,13 @@ namespace llarp::path
if (Expired(now))
return;
m_LastRXRate = m_RXRate;
m_LastTXRate = m_TXRate;
// m_LastRXRate = m_RXRate;
// m_LastTXRate = m_TXRate;
m_RXRate = 0;
m_TXRate = 0;
// m_RXRate = 0;
// m_TXRate = 0;
if (_status == BUILDING)
if (_status == PathStatus::BUILDING)
{
if (buildStarted == 0s)
return;
@ -396,37 +396,37 @@ namespace llarp::path
{
LogWarn(name(), " waited for ", ToString(dlt), " and no path was built");
r->router_profiling().MarkPathFail(this);
EnterState(EXPIRED, now);
EnterState(PathStatus::EXPIRED, now);
return;
}
}
}
// check to see if this path is dead
if (_status == ESTABLISHED)
if (_status == PathStatus::ESTABLISHED)
{
auto dlt = now - m_LastLatencyTestTime;
if (dlt > path::LATENCY_INTERVAL && m_LastLatencyTestID == 0)
auto dlt = now - last_latency_test;
if (dlt > path::LATENCY_INTERVAL && last_latency_test_id == 0)
{
SendLatencyMessage(r);
// latency test FEC
r->loop()->call_later(2s, [self = shared_from_this(), r]() {
if (self->m_LastLatencyTestID)
if (self->last_latency_test_id)
self->SendLatencyMessage(r);
});
return;
}
dlt = now - m_LastRecvMessage;
dlt = now - last_recv_msg;
if (dlt >= path::ALIVE_TIMEOUT)
{
LogWarn(name(), " waited for ", ToString(dlt), " and path looks dead");
r->router_profiling().MarkPathFail(this);
EnterState(TIMEOUT, now);
EnterState(PathStatus::TIMEOUT, now);
}
}
if (_status == IGNORE and now - m_LastRecvMessage >= path::ALIVE_TIMEOUT)
if (_status == PathStatus::IGNORE and now - last_recv_msg >= path::ALIVE_TIMEOUT)
{
// clean up this path as we dont use it anymore
EnterState(EXPIRED, now);
EnterState(PathStatus::EXPIRED, now);
}
}
@ -436,15 +436,15 @@ namespace llarp::path
bool
Path::Expired(llarp_time_t now) const
{
if (_status == FAILED)
if (_status == PathStatus::FAILED)
return true;
if (_status == BUILDING)
if (_status == PathStatus::BUILDING)
return false;
if (_status == TIMEOUT)
if (_status == PathStatus::TIMEOUT)
{
return now >= m_LastRecvMessage + PathReanimationTimeout;
return now >= last_recv_msg + PathReanimationTimeout;
}
if (_status == ESTABLISHED or _status == IGNORE)
if (_status == PathStatus::ESTABLISHED or _status == PathStatus::IGNORE)
{
return now >= ExpireTime();
}

@ -31,33 +31,15 @@ namespace llarp
struct TransitHopInfo;
struct PathHopConfig;
struct Ptr_hash;
struct Endpoint_Hash;
struct endpoint_comparator;
/// unordered set of paths with unique endpoints
using UniqueEndpointSet_t = std::unordered_set<Path_ptr, Endpoint_Hash, endpoint_comparator>;
/// A path we made
struct Path final : public AbstractHopHandler, public std::enable_shared_from_this<Path>
{
using BuildResultHookFunc = std::function<void(Path_ptr)>;
using CheckForDeadFunc = std::function<bool(Path_ptr, llarp_time_t)>;
using DropHandlerFunc = std::function<bool(Path_ptr, const PathID_t&, uint64_t)>;
using HopList = std::vector<PathHopConfig>;
// using DataHandlerFunc = std::function<bool(Path_ptr, const
// service::ProtocolFrameMessage&)>;
using ExitUpdatedFunc = std::function<bool(Path_ptr)>;
using ExitClosedFunc = std::function<bool(Path_ptr)>;
using ExitTrafficHandlerFunc =
std::function<bool(Path_ptr, const llarp_buffer_t&, uint64_t, service::ProtocolType)>;
/// (path, backoff) backoff is 0 on success
using ObtainedExitHandler = std::function<bool(Path_ptr, llarp_time_t)>;
HopList hops;
std::weak_ptr<PathSet> m_PathSet;
std::vector<PathHopConfig> hops;
std::weak_ptr<PathSet> path_set;
service::Introduction intro;
@ -88,7 +70,7 @@ namespace llarp
void
MarkActive(llarp_time_t now)
{
m_LastRecvMessage = std::max(now, m_LastRecvMessage);
last_recv_msg = std::max(now, last_recv_msg);
}
/// return true if ALL of the specified roles are supported
@ -119,7 +101,7 @@ namespace llarp
}
const std::string&
ShortName() const;
short_name() const;
std::string
HopsString() const;
@ -127,7 +109,7 @@ namespace llarp
llarp_time_t
LastRemoteActivityAt() const override
{
return m_LastRecvMessage;
return last_recv_msg;
}
void
@ -242,20 +224,12 @@ namespace llarp
InformExitResult(llarp_time_t b);
Router& router;
llarp_time_t m_LastRecvMessage = 0s;
llarp_time_t m_LastLatencyTestTime = 0s;
uint64_t m_LastLatencyTestID = 0;
uint64_t m_UpdateExitTX = 0;
uint64_t m_CloseExitTX = 0;
uint64_t m_ExitObtainTX = 0;
llarp_time_t last_recv_msg = 0s;
llarp_time_t last_latency_test = 0s;
uint64_t last_latency_test_id = 0;
PathStatus _status;
PathRole _role;
uint64_t m_LastRXRate = 0;
uint64_t m_RXRate = 0;
uint64_t m_LastTXRate = 0;
uint64_t m_TXRate = 0;
std::deque<llarp_time_t> m_LatencySamples;
const std::string m_shortName;
const std::string _short_name;
};
struct Hash
@ -275,23 +249,11 @@ namespace llarp
}
};
/// hash for std::shared_ptr<Path>
struct Ptr_Hash
{
size_t
operator()(const Path_ptr& p) const
{
if (p == nullptr)
return 0;
return Hash{}(*p);
}
};
/// hash for std::shared_ptr<Path> by path endpoint
struct Endpoint_Hash
{
size_t
operator()(const Path_ptr& p) const
operator()(const std::shared_ptr<Path>& p) const
{
if (p == nullptr)
return 0;
@ -303,7 +265,7 @@ namespace llarp
struct endpoint_comparator
{
bool
operator()(const Path_ptr& left, const Path_ptr& right) const
operator()(const std::shared_ptr<Path>& left, const std::shared_ptr<Path>& right) const
{
return left && right && left->Endpoint() == left->Endpoint();
}

@ -79,7 +79,7 @@ namespace llarp::path
}
void
PathContext::AddOwnPath(PathSet_ptr set, Path_ptr path)
PathContext::AddOwnPath(std::shared_ptr<PathSet> set, std::shared_ptr<Path> path)
{
set->AddPath(path);
own_paths[path->TXID()] = path;
@ -109,7 +109,7 @@ namespace llarp::path
return nullptr;
}
Path_ptr
std::shared_ptr<Path>
PathContext::get_path(const PathID_t& path_id)
{
if (auto itr = own_paths.find(path_id); itr != own_paths.end())
@ -124,12 +124,12 @@ namespace llarp::path
return transit_hops.count({otherRouter, path_id});
}
PathSet_ptr
std::shared_ptr<PathSet>
PathContext::GetLocalPathSet(const PathID_t& id)
{
if (auto itr = own_paths.find(id); itr != own_paths.end())
{
if (auto parent = itr->second->m_PathSet.lock())
if (auto parent = itr->second->path_set.lock())
return parent;
}
return nullptr;
@ -217,6 +217,6 @@ namespace llarp::path
}
void
PathContext::RemovePathSet(PathSet_ptr)
PathContext::RemovePathSet(std::shared_ptr<PathSet>)
{}
} // namespace llarp::path

@ -79,7 +79,7 @@ namespace llarp::path
void
put_transit_hop(std::shared_ptr<TransitHop> hop);
Path_ptr
std::shared_ptr<Path>
get_path(const PathID_t& path_id);
bool
@ -91,7 +91,7 @@ namespace llarp::path
std::shared_ptr<TransitHop>
GetTransitHop(const RouterID&, const PathID_t&);
PathSet_ptr
std::shared_ptr<PathSet>
GetLocalPathSet(const PathID_t& id);
/// get a set of all paths that we own who's endpoint is r
@ -102,10 +102,10 @@ namespace llarp::path
HopIsUs(const RouterID& k) const;
void
AddOwnPath(PathSet_ptr set, Path_ptr p);
AddOwnPath(std::shared_ptr<PathSet> set, std::shared_ptr<Path> p);
void
RemovePathSet(PathSet_ptr set);
RemovePathSet(std::shared_ptr<PathSet> set);
const EventLoop_ptr&
loop();
@ -134,7 +134,7 @@ namespace llarp::path
Router* _router;
std::unordered_map<TransitHopID, std::shared_ptr<TransitHop>> transit_hops;
std::unordered_map<PathID_t, Path_ptr> own_paths;
std::unordered_map<PathID_t, std::shared_ptr<Path>> own_paths;
bool m_AllowTransit;
util::DecayingHashSet<IpAddress> path_limits;
};

@ -26,23 +26,23 @@ namespace llarp
bool
BuildLimiter::Attempt(const RouterID& router)
{
return m_EdgeLimiter.Insert(router);
return _edge_limiter.Insert(router);
}
void
BuildLimiter::Decay(llarp_time_t now)
{
m_EdgeLimiter.Decay(now);
_edge_limiter.Decay(now);
}
bool
BuildLimiter::Limited(const RouterID& router) const
{
return m_EdgeLimiter.Contains(router);
return _edge_limiter.Contains(router);
}
Builder::Builder(Router* p_router, size_t pathNum, size_t hops)
: path::PathSet{pathNum}, _run{true}, router{p_router}, numHops{hops}
PathBuilder::PathBuilder(Router* p_router, size_t pathNum, size_t hops)
: path::PathSet{pathNum}, _run{true}, router{p_router}, num_hops{hops}
{}
/* - For each hop:
@ -78,7 +78,7 @@ namespace llarp
*/
void
Builder::setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop)
PathBuilder::setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop)
{
// generate key
crypto::encryption_keygen(hop.commkey);
@ -100,7 +100,7 @@ namespace llarp
}
std::string
Builder::create_hop_info_frame(const path::PathHopConfig& hop)
PathBuilder::create_hop_info_frame(const path::PathHopConfig& hop)
{
std::string hop_info;
@ -173,14 +173,14 @@ namespace llarp
}
void
Builder::ResetInternalState()
PathBuilder::ResetInternalState()
{
buildIntervalLimit = PATH_BUILD_RATE;
lastBuild = 0s;
build_interval_limit = PATH_BUILD_RATE;
_last_build = 0s;
}
void
Builder::Tick(llarp_time_t now)
PathBuilder::Tick(llarp_time_t now)
{
PathSet::Tick(now);
now = llarp::time_now_ms();
@ -190,33 +190,33 @@ namespace llarp
if (ShouldBuildMore(now))
BuildOne();
TickPaths(router);
if (m_BuildStats.attempts > 50)
if (build_stats.attempts > 50)
{
if (m_BuildStats.SuccessRatio() <= BuildStats::MinGoodRatio && now - m_LastWarn > 5s)
if (build_stats.SuccessRatio() <= BuildStats::MinGoodRatio && now - last_warn_time > 5s)
{
LogWarn(Name(), " has a low path build success. ", m_BuildStats);
m_LastWarn = now;
LogWarn(Name(), " has a low path build success. ", build_stats);
last_warn_time = now;
}
}
}
util::StatusObject
Builder::ExtractStatus() const
PathBuilder::ExtractStatus() const
{
util::StatusObject obj{
{"buildStats", m_BuildStats.ExtractStatus()},
{"numHops", uint64_t{numHops}},
{"numPaths", uint64_t{numDesiredPaths}}};
{"buildStats", build_stats.ExtractStatus()},
{"numHops", uint64_t{num_hops}},
{"numPaths", uint64_t{num_paths_desired}}};
std::transform(
m_Paths.begin(),
m_Paths.end(),
_paths.begin(),
_paths.end(),
std::back_inserter(obj["paths"]),
[](const auto& item) -> util::StatusObject { return item.second->ExtractStatus(); });
return obj;
}
std::optional<RemoteRC>
Builder::SelectFirstHop(const std::set<RouterID>& exclude) const
PathBuilder::SelectFirstHop(const std::set<RouterID>& exclude) const
{
std::optional<RemoteRC> found = std::nullopt;
router->for_each_connection([&](link::Connection& conn) {
@ -241,7 +241,7 @@ namespace llarp
}
std::optional<std::vector<RemoteRC>>
Builder::GetHopsForBuild()
PathBuilder::GetHopsForBuild()
{
auto filter = [r = router](const RemoteRC& rc) -> bool {
return not r->router_profiling().IsBadForPath(rc.router_id(), 1);
@ -254,44 +254,44 @@ namespace llarp
}
bool
Builder::Stop()
PathBuilder::Stop()
{
_run = false;
// tell all our paths that they are to be ignored
const auto now = Now();
for (auto& item : m_Paths)
for (auto& item : _paths)
{
item.second->EnterState(IGNORE, now);
item.second->EnterState(PathStatus::IGNORE, now);
}
return true;
}
bool
Builder::IsStopped() const
PathBuilder::IsStopped() const
{
return !_run.load();
}
bool
Builder::ShouldRemove() const
PathBuilder::ShouldRemove() const
{
return IsStopped() and NumInStatus(ESTABLISHED) == 0;
return IsStopped() and NumInStatus(PathStatus::ESTABLISHED) == 0;
}
bool
Builder::BuildCooldownHit(RouterID edge) const
PathBuilder::BuildCooldownHit(RouterID edge) const
{
return router->pathbuild_limiter().Limited(edge);
}
bool
Builder::BuildCooldownHit(llarp_time_t now) const
PathBuilder::BuildCooldownHit(llarp_time_t now) const
{
return now < lastBuild + buildIntervalLimit;
return now < _last_build + build_interval_limit;
}
bool
Builder::ShouldBuildMore(llarp_time_t now) const
PathBuilder::ShouldBuildMore(llarp_time_t now) const
{
if (IsStopped())
return false;
@ -301,20 +301,20 @@ namespace llarp
}
void
Builder::BuildOne(PathRole roles)
PathBuilder::BuildOne(PathRole roles)
{
if (const auto maybe = GetHopsForBuild())
Build(*maybe, roles);
}
bool
Builder::UrgentBuild(llarp_time_t) const
PathBuilder::UrgentBuild(llarp_time_t) const
{
return buildIntervalLimit > MIN_PATH_BUILD_INTERVAL * 4;
return build_interval_limit > MIN_PATH_BUILD_INTERVAL * 4;
}
std::optional<std::vector<RemoteRC>>
Builder::GetHopsAlignedToForBuild(RouterID endpoint, const std::set<RouterID>& exclude)
PathBuilder::GetHopsAlignedToForBuild(RouterID endpoint, const std::set<RouterID>& exclude)
{
const auto pathConfig = router->config()->paths;
@ -337,9 +337,9 @@ namespace llarp
else
return std::nullopt;
for (size_t idx = hops.size(); idx < numHops; ++idx)
for (size_t idx = hops.size(); idx < num_hops; ++idx)
{
if (idx + 1 == numHops)
if (idx + 1 == num_hops)
{
hops.emplace_back(endpointRC);
}
@ -383,7 +383,7 @@ namespace llarp
}
bool
Builder::BuildOneAlignedTo(const RouterID remote)
PathBuilder::BuildOneAlignedTo(const RouterID remote)
{
if (const auto maybe = GetHopsAlignedToForBuild(remote); maybe.has_value())
{
@ -395,13 +395,13 @@ namespace llarp
}
llarp_time_t
Builder::Now() const
PathBuilder::Now() const
{
return router->now();
}
void
Builder::Build(std::vector<RemoteRC> hops, PathRole roles)
PathBuilder::Build(std::vector<RemoteRC> hops, PathRole roles)
{
if (IsStopped())
{
@ -409,7 +409,7 @@ namespace llarp
return;
}
lastBuild = llarp::time_now_ms();
_last_build = llarp::time_now_ms();
const auto& edge = hops[0].router_id();
if (not router->pathbuild_limiter().Attempt(edge))
@ -425,7 +425,7 @@ namespace llarp
std::make_shared<path::Path>(router, hops, GetWeak(), roles, std::move(path_shortName));
log::info(
path_cat, "{} building path -> {} : {}", Name(), path->ShortName(), path->HopsString());
path_cat, "{} building path -> {} : {}", Name(), path->short_name(), path->HopsString());
oxenc::bt_list_producer frames;
std::vector<std::string> frame_str(path::MAX_LEN);
@ -508,7 +508,7 @@ namespace llarp
if (m)
{
// TODO: inform success (what this means needs revisiting, badly)
path->EnterState(path::ESTABLISHED);
path->EnterState(path::PathStatus::ESTABLISHED);
return;
}
@ -518,14 +518,14 @@ namespace llarp
if (m.timed_out)
{
log::warning(path_cat, "Path build request timed out!");
path->EnterState(path::TIMEOUT);
path->EnterState(path::PathStatus::TIMEOUT);
}
else
{
oxenc::bt_dict_consumer d{m.body()};
auto status = d.require<std::string_view>(messages::STATUS_KEY);
log::warning(path_cat, "Path build returned failure status: {}", status);
path->EnterState(path::FAILED);
path->EnterState(path::PathStatus::FAILED);
}
}
catch (const std::exception& e)
@ -538,38 +538,38 @@ namespace llarp
path->upstream(), "path_build", std::move(frames).str(), std::move(response_cb)))
{
log::warning(path_cat, "Error sending path_build control message");
path->EnterState(path::FAILED, router->now());
path->EnterState(path::PathStatus::FAILED, router->now());
}
}
void
Builder::HandlePathBuilt(Path_ptr p)
PathBuilder::HandlePathBuilt(std::shared_ptr<Path> p)
{
buildIntervalLimit = PATH_BUILD_RATE;
build_interval_limit = PATH_BUILD_RATE;
router->router_profiling().MarkPathSuccess(p.get());
LogInfo(p->name(), " built latency=", ToString(p->intro.latency));
m_BuildStats.success++;
build_stats.success++;
}
void
Builder::HandlePathBuildFailedAt(Path_ptr p, RouterID edge)
PathBuilder::HandlePathBuildFailedAt(std::shared_ptr<Path> p, RouterID edge)
{
PathSet::HandlePathBuildFailedAt(p, edge);
DoPathBuildBackoff();
}
void
Builder::DoPathBuildBackoff()
PathBuilder::DoPathBuildBackoff()
{
static constexpr std::chrono::milliseconds MaxBuildInterval = 30s;
// linear backoff
buildIntervalLimit = std::min(PATH_BUILD_RATE + buildIntervalLimit, MaxBuildInterval);
LogWarn(Name(), " build interval is now ", ToString(buildIntervalLimit));
build_interval_limit = std::min(PATH_BUILD_RATE + build_interval_limit, MaxBuildInterval);
LogWarn(Name(), " build interval is now ", ToString(build_interval_limit));
}
void
Builder::HandlePathBuildTimeout(Path_ptr p)
PathBuilder::HandlePathBuildTimeout(std::shared_ptr<Path> p)
{
router->router_profiling().MarkPathTimeout(p.get());
PathSet::HandlePathBuildTimeout(p);
@ -577,7 +577,7 @@ namespace llarp
}
void
Builder::ManualRebuild(size_t num, PathRole roles)
PathBuilder::ManualRebuild(size_t num, PathRole roles)
{
LogDebug(Name(), " manual rebuild ", num);
while (num--)

@ -10,11 +10,14 @@
namespace llarp::path
{
// maximum number of paths a path-set can maintain
inline constexpr size_t MAX_PATHS{32};
/// limiter for path builds
/// prevents overload and such
class BuildLimiter
{
util::DecayingHashSet<RouterID> m_EdgeLimiter;
util::DecayingHashSet<RouterID> _edge_limiter;
public:
/// attempt a build
@ -31,15 +34,18 @@ namespace llarp::path
Limited(const RouterID& router) const;
};
struct Builder : public PathSet
struct PathBuilder : public PathSet
{
private:
llarp_time_t m_LastWarn = 0s;
llarp_time_t last_warn_time = 0s;
// size_t _num_paths_desired;
protected:
/// flag for PathSet::Stop()
std::atomic<bool> _run;
BuildStats _build_stats;
virtual bool
UrgentBuild(llarp_time_t now) const;
@ -59,14 +65,14 @@ namespace llarp::path
public:
Router* const router;
size_t numHops;
llarp_time_t lastBuild = 0s;
llarp_time_t buildIntervalLimit = MIN_PATH_BUILD_INTERVAL;
size_t num_hops;
llarp_time_t _last_build = 0s;
llarp_time_t build_interval_limit = MIN_PATH_BUILD_INTERVAL;
/// construct
Builder(Router* p_router, size_t numDesiredPaths, size_t numHops);
PathBuilder(Router* p_router, size_t numDesiredPaths, size_t numHops);
virtual ~Builder() = default;
virtual ~PathBuilder() = default;
util::StatusObject
ExtractStatus() const;
@ -91,7 +97,7 @@ namespace llarp::path
BuildStats
CurrentBuildStats() const
{
return m_BuildStats;
return build_stats;
}
bool
@ -132,15 +138,12 @@ namespace llarp::path
ManualRebuild(size_t N, PathRole roles = ePathRoleAny);
void
HandlePathBuilt(Path_ptr p) override;
HandlePathBuilt(std::shared_ptr<Path> p) override;
void
HandlePathBuildTimeout(Path_ptr p) override;
HandlePathBuildTimeout(std::shared_ptr<Path> p) override;
void
HandlePathBuildFailedAt(Path_ptr p, RouterID hop) override;
HandlePathBuildFailedAt(std::shared_ptr<Path> p, RouterID hop) override;
};
using Builder_ptr = std::shared_ptr<Builder>;
} // namespace llarp::path

@ -6,50 +6,50 @@
namespace llarp::path
{
PathSet::PathSet(size_t num) : numDesiredPaths(num)
PathSet::PathSet(size_t num) : num_paths_desired(num)
{}
bool
PathSet::ShouldBuildMore(llarp_time_t now) const
{
(void)now;
const auto building = NumInStatus(BUILDING);
if (building >= numDesiredPaths)
const auto building = NumInStatus(PathStatus::BUILDING);
if (building >= num_paths_desired)
return false;
const auto established = NumInStatus(ESTABLISHED);
return established < numDesiredPaths;
const auto established = NumInStatus(PathStatus::ESTABLISHED);
return established < num_paths_desired;
}
bool
PathSet::ShouldBuildMoreForRoles(llarp_time_t now, PathRole roles) const
{
Lock_t l(m_PathsMutex);
const size_t required = MinRequiredForRoles(roles);
size_t has = 0;
for (const auto& item : m_Paths)
{
if (item.second->SupportsAnyRoles(roles))
{
if (!item.second->ExpiresSoon(now))
++has;
}
}
return has < required;
}
size_t
PathSet::MinRequiredForRoles(PathRole roles) const
{
(void)roles;
return 0;
}
// bool
// PathSet::ShouldBuildMoreForRoles(llarp_time_t now, PathRole roles) const
// {
// Lock_t l(paths_mutex);
// const size_t required = MinRequiredForRoles(roles);
// size_t has = 0;
// for (const auto& item : _paths)
// {
// if (item.second->SupportsAnyRoles(roles))
// {
// if (!item.second->ExpiresSoon(now))
// ++has;
// }
// }
// return has < required;
// }
// size_t
// PathSet::MinRequiredForRoles(PathRole roles) const
// {
// (void)roles;
// return 0;
// }
size_t
PathSet::NumPathsExistingAt(llarp_time_t futureTime) const
{
size_t num = 0;
Lock_t l(m_PathsMutex);
for (const auto& item : m_Paths)
Lock_t l(paths_mutex);
for (const auto& item : _paths)
{
if (item.second->IsReady() && !item.second->Expired(futureTime))
++num;
@ -61,8 +61,8 @@ namespace llarp::path
PathSet::TickPaths(Router* r)
{
const auto now = llarp::time_now_ms();
Lock_t l{m_PathsMutex};
for (auto& item : m_Paths)
Lock_t l{paths_mutex};
for (auto& item : _paths)
{
item.second->Tick(now, r);
}
@ -72,17 +72,17 @@ namespace llarp::path
PathSet::Tick(llarp_time_t)
{
std::unordered_set<RouterID> endpoints;
for (auto& item : m_Paths)
for (auto& item : _paths)
{
endpoints.emplace(item.second->Endpoint());
}
m_PathCache.clear();
path_cache.clear();
for (const auto& ep : endpoints)
{
if (auto path = GetPathByRouter(ep))
{
m_PathCache[ep] = path->weak_from_this();
path_cache[ep] = path->weak_from_this();
}
}
}
@ -90,11 +90,11 @@ namespace llarp::path
void
PathSet::ExpirePaths(llarp_time_t now, [[maybe_unused]] Router* router)
{
Lock_t l(m_PathsMutex);
if (m_Paths.size() == 0)
Lock_t l(paths_mutex);
if (_paths.size() == 0)
return;
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->Expired(now))
{
@ -103,23 +103,23 @@ namespace llarp::path
// router->outboundMessageHandler().RemovePath(std::move(txid));
PathID_t rxid = itr->second->RXID();
// router->outboundMessageHandler().RemovePath(std::move(rxid));
itr = m_Paths.erase(itr);
itr = _paths.erase(itr);
}
else
++itr;
}
}
Path_ptr
std::shared_ptr<Path>
PathSet::GetEstablishedPathClosestTo(
RouterID id, std::unordered_set<RouterID> excluding, PathRole roles) const
{
Lock_t l{m_PathsMutex};
Path_ptr path = nullptr;
Lock_t l{paths_mutex};
std::shared_ptr<Path> path = nullptr;
AlignedBuffer<32> dist;
AlignedBuffer<32> to = id;
dist.Fill(0xff);
for (const auto& item : m_Paths)
for (const auto& item : _paths)
{
if (!item.second->IsReady())
continue;
@ -137,13 +137,13 @@ namespace llarp::path
return path;
}
Path_ptr
std::shared_ptr<Path>
PathSet::GetNewestPathByRouter(RouterID id, PathRole roles) const
{
Lock_t l(m_PathsMutex);
Path_ptr chosen = nullptr;
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
Lock_t l(paths_mutex);
std::shared_ptr<Path> chosen = nullptr;
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
{
@ -162,20 +162,20 @@ namespace llarp::path
return chosen;
}
Path_ptr
std::shared_ptr<Path>
PathSet::GetPathByRouter(RouterID id, PathRole roles) const
{
Lock_t l(m_PathsMutex);
Path_ptr chosen = nullptr;
Lock_t l(paths_mutex);
std::shared_ptr<Path> chosen = nullptr;
if (roles == ePathRoleAny)
{
if (auto itr = m_PathCache.find(id); itr != m_PathCache.end())
if (auto itr = path_cache.find(id); itr != path_cache.end())
{
return itr->second.lock();
}
}
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
{
@ -195,13 +195,13 @@ namespace llarp::path
return chosen;
}
Path_ptr
std::shared_ptr<Path>
PathSet::GetRandomPathByRouter(RouterID id, PathRole roles) const
{
Lock_t l(m_PathsMutex);
std::vector<Path_ptr> chosen;
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
Lock_t l(paths_mutex);
std::vector<std::shared_ptr<Path>> chosen;
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
{
@ -217,12 +217,12 @@ namespace llarp::path
return chosen[std::uniform_int_distribution<size_t>{0, chosen.size() - 1}(llarp::csrng)];
}
Path_ptr
std::shared_ptr<Path>
PathSet::GetByEndpointWithID(RouterID ep, PathID_t id) const
{
Lock_t l(m_PathsMutex);
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
Lock_t l(paths_mutex);
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->is_endpoint(ep, id))
{
@ -233,12 +233,12 @@ namespace llarp::path
return nullptr;
}
Path_ptr
std::shared_ptr<Path>
PathSet::GetPathByID(PathID_t id) const
{
Lock_t l(m_PathsMutex);
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
Lock_t l(paths_mutex);
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->RXID() == id)
return itr->second;
@ -250,12 +250,12 @@ namespace llarp::path
size_t
PathSet::AvailablePaths(PathRole roles) const
{
Lock_t l(m_PathsMutex);
Lock_t l(paths_mutex);
size_t count = 0;
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->Status() == ESTABLISHED && itr->second->SupportsAnyRoles(roles))
if (itr->second->Status() == PathStatus::ESTABLISHED && itr->second->SupportsAnyRoles(roles))
++count;
++itr;
}
@ -265,10 +265,10 @@ namespace llarp::path
size_t
PathSet::NumInStatus(PathStatus st) const
{
Lock_t l(m_PathsMutex);
Lock_t l(paths_mutex);
size_t count = 0;
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->Status() == st)
++count;
@ -278,12 +278,12 @@ namespace llarp::path
}
void
PathSet::AddPath(Path_ptr path)
PathSet::AddPath(std::shared_ptr<Path> path)
{
Lock_t l(m_PathsMutex);
Lock_t l(paths_mutex);
const auto upstream = path->upstream(); // RouterID
const auto RXID = path->RXID(); // PathID
if (not m_Paths.emplace(std::make_pair(upstream, RXID), path).second)
if (not _paths.emplace(std::make_pair(upstream, RXID), path).second)
{
LogError(
Name(),
@ -294,12 +294,12 @@ namespace llarp::path
}
}
Path_ptr
std::shared_ptr<Path>
PathSet::GetByUpstream(RouterID remote, PathID_t rxid) const
{
Lock_t l(m_PathsMutex);
auto itr = m_Paths.find({remote, rxid});
if (itr == m_Paths.end())
Lock_t l(paths_mutex);
auto itr = _paths.find({remote, rxid});
if (itr == _paths.end())
return nullptr;
return itr->second;
}
@ -309,9 +309,9 @@ namespace llarp::path
std::function<bool(const service::Introduction&)> filter) const
{
std::set<service::Introduction> intros;
Lock_t l{m_PathsMutex};
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
Lock_t l{paths_mutex};
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->IsReady() and filter(itr->second->intro))
{
@ -325,30 +325,30 @@ namespace llarp::path
}
void
PathSet::HandlePathBuildTimeout(Path_ptr p)
PathSet::HandlePathBuildTimeout(std::shared_ptr<Path> p)
{
LogWarn(Name(), " path build ", p->ShortName(), " timed out");
m_BuildStats.timeouts++;
LogWarn(Name(), " path build ", p->short_name(), " timed out");
build_stats.timeouts++;
}
void
PathSet::HandlePathBuildFailedAt(Path_ptr p, RouterID hop)
PathSet::HandlePathBuildFailedAt(std::shared_ptr<Path> p, RouterID hop)
{
LogWarn(Name(), " path build ", p->ShortName(), " failed at ", hop);
m_BuildStats.fails++;
LogWarn(Name(), " path build ", p->short_name(), " failed at ", hop);
build_stats.fails++;
}
void
PathSet::HandlePathDied(Path_ptr p)
PathSet::HandlePathDied(std::shared_ptr<Path> p)
{
LogWarn(Name(), " path ", p->ShortName(), " died");
LogWarn(Name(), " path ", p->short_name(), " died");
}
void
PathSet::PathBuildStarted(Path_ptr p)
PathSet::PathBuildStarted(std::shared_ptr<Path> p)
{
LogInfo(Name(), " path build ", p->ShortName(), " started");
m_BuildStats.attempts++;
LogInfo(Name(), " path build ", p->short_name(), " started");
build_stats.attempts++;
}
util::StatusObject
@ -383,9 +383,9 @@ namespace llarp::path
{
intro.Clear();
bool found = false;
Lock_t l(m_PathsMutex);
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
Lock_t l(paths_mutex);
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->IsReady() && itr->second->intro.expiry > intro.expiry)
{
@ -397,13 +397,13 @@ namespace llarp::path
return found;
}
Path_ptr
std::shared_ptr<Path>
PathSet::PickRandomEstablishedPath(PathRole roles) const
{
std::vector<Path_ptr> established;
Lock_t l(m_PathsMutex);
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
std::vector<std::shared_ptr<Path>> established;
Lock_t l(paths_mutex);
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
established.push_back(itr->second);
@ -418,19 +418,19 @@ namespace llarp::path
return nullptr;
}
Path_ptr
std::shared_ptr<Path>
PathSet::PickEstablishedPath(PathRole roles) const
{
std::vector<Path_ptr> established;
Lock_t l(m_PathsMutex);
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
std::vector<std::shared_ptr<Path>> established;
Lock_t l(paths_mutex);
auto itr = _paths.begin();
while (itr != _paths.end())
{
if (itr->second->IsReady() && itr->second->SupportsAnyRoles(roles))
established.push_back(itr->second);
++itr;
}
Path_ptr chosen = nullptr;
std::shared_ptr<Path> chosen = nullptr;
llarp_time_t minLatency = 30s;
for (const auto& path : established)
{

@ -35,17 +35,10 @@ namespace llarp
struct RouterContact;
class NodeDB;
namespace dht
{
struct GotIntroMessage;
struct GotRouterMessage;
struct GotNameMessage;
} // namespace dht
namespace path
{
/// status of a path
enum PathStatus
enum class PathStatus
{
BUILDING,
ESTABLISHED,
@ -76,41 +69,36 @@ namespace llarp
};
/// the role of this path can fulfill
enum class Path_Role
{
ANY = 0,
EXIT = 1 << 1,
SERVICE = 1 << 2
};
using PathRole = int;
/// capable of any role
constexpr PathRole ePathRoleAny = 0;
/// outbound hs traffic capable
constexpr PathRole ePathRoleOutboundHS = (1 << 0);
/// inbound hs traffic capable
constexpr PathRole ePathRoleInboundHS = (1 << 1);
/// exit traffic capable
constexpr PathRole ePathRoleExit = (1 << 2);
constexpr PathRole ePathRoleExit = (1 << 1);
/// service node capable
constexpr PathRole ePathRoleSVC = (1 << 3);
/// dht message capable
constexpr PathRole ePathRoleDHT = (1 << 4);
constexpr PathRole ePathRoleSVC = (1 << 2);
// forward declare
struct Path;
using Path_ptr = std::shared_ptr<Path>;
struct PathSet;
using PathSet_ptr = std::shared_ptr<PathSet>;
/// a set of paths owned by an entity
struct PathSet
{
/// maximum number of paths a path set can maintain
static constexpr size_t max_paths = 32;
// static constexpr size_t max_paths = 32;
/// construct
/// @params numDesiredPaths the number of paths to maintain
PathSet(size_t numDesiredPaths);
/// get a shared_ptr of ourself
virtual PathSet_ptr
virtual std::shared_ptr<PathSet>
GetSelf() = 0;
/// get a weak_ptr of ourself
@ -133,28 +121,28 @@ namespace llarp
NumPathsExistingAt(llarp_time_t futureTime) const;
virtual void
HandlePathBuilt(Path_ptr path) = 0;
HandlePathBuilt(std::shared_ptr<Path> path) = 0;
virtual void
HandlePathBuildTimeout(Path_ptr path);
HandlePathBuildTimeout(std::shared_ptr<Path> path);
virtual void
HandlePathBuildFailedAt(Path_ptr path, RouterID hop);
HandlePathBuildFailedAt(std::shared_ptr<Path> path, RouterID hop);
void
PathBuildStarted(Path_ptr path);
PathBuildStarted(std::shared_ptr<Path> path);
/// a path died now what?
virtual void
HandlePathDied(Path_ptr path);
HandlePathDied(std::shared_ptr<Path> path);
bool
GetNewestIntro(service::Introduction& intro) const;
void
AddPath(Path_ptr path);
AddPath(std::shared_ptr<Path> path);
Path_ptr
std::shared_ptr<Path>
GetByUpstream(RouterID remote, PathID_t rxid) const;
void
@ -194,12 +182,12 @@ namespace llarp
ShouldBuildMore(llarp_time_t now) const;
/// return true if we need another path with the given path roles
virtual bool
ShouldBuildMoreForRoles(llarp_time_t now, PathRole roles) const;
// virtual bool
// ShouldBuildMoreForRoles(llarp_time_t now, PathRole roles) const;
/// return the minimum number of paths we want for given roles
virtual size_t
MinRequiredForRoles(PathRole roles) const;
// virtual size_t
// MinRequiredForRoles(PathRole roles) const;
/// return true if we should publish a new hidden service descriptor
virtual bool
@ -211,31 +199,31 @@ namespace llarp
virtual void
BlacklistSNode(const RouterID) = 0;
Path_ptr
std::shared_ptr<Path>
GetEstablishedPathClosestTo(
RouterID router,
std::unordered_set<RouterID> excluding = {},
PathRole roles = ePathRoleAny) const;
Path_ptr
std::shared_ptr<Path>
PickEstablishedPath(PathRole roles = ePathRoleAny) const;
Path_ptr
std::shared_ptr<Path>
PickRandomEstablishedPath(PathRole roles = ePathRoleAny) const;
Path_ptr
std::shared_ptr<Path>
GetPathByRouter(RouterID router, PathRole roles = ePathRoleAny) const;
Path_ptr
std::shared_ptr<Path>
GetNewestPathByRouter(RouterID router, PathRole roles = ePathRoleAny) const;
Path_ptr
std::shared_ptr<Path>
GetRandomPathByRouter(RouterID router, PathRole roles = ePathRoleAny) const;
Path_ptr
std::shared_ptr<Path>
GetPathByID(PathID_t id) const;
Path_ptr
std::shared_ptr<Path>
GetByEndpointWithID(RouterID router, PathID_t id) const;
std::optional<std::set<service::Introduction>>
@ -256,11 +244,11 @@ namespace llarp
GetHopsForBuild() = 0;
void
ForEachPath(std::function<void(const Path_ptr&)> visit) const
ForEachPath(std::function<void(const std::shared_ptr<Path>&)> visit) const
{
Lock_t lock(m_PathsMutex);
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
Lock_t lock(paths_mutex);
auto itr = _paths.begin();
while (itr != _paths.end())
{
visit(itr->second);
++itr;
@ -273,22 +261,22 @@ namespace llarp
void
DownstreamFlush(Router* r);
size_t numDesiredPaths;
size_t num_paths_desired;
protected:
BuildStats m_BuildStats;
BuildStats build_stats;
void
TickPaths(Router* r);
using Mtx_t = util::NullMutex;
using Lock_t = util::NullLock;
using PathMap_t = std::unordered_map<std::pair<RouterID, PathID_t>, Path_ptr>;
mutable Mtx_t m_PathsMutex;
PathMap_t m_Paths;
mutable Mtx_t paths_mutex;
std::unordered_map<std::pair<RouterID, PathID_t>, std::shared_ptr<Path>> _paths;
private:
std::unordered_map<RouterID, std::weak_ptr<path::Path>> m_PathCache;
std::unordered_map<RouterID, std::weak_ptr<path::Path>> path_cache;
};
} // namespace path

@ -9,11 +9,6 @@
namespace llarp
{
namespace dht
{
struct GotIntroMessage;
}
namespace path
{
struct TransitHopInfo
@ -60,7 +55,7 @@ namespace llarp
// 10 minutes default
llarp_time_t lifetime = DEFAULT_LIFETIME;
llarp_proto_version_t version;
llarp_time_t m_LastActivity = 0s;
llarp_time_t last_activity = 0s;
bool terminal_hop{false};
// If randomize is given, first randomizes `nonce`
@ -108,7 +103,7 @@ namespace llarp
llarp_time_t
LastRemoteActivityAt() const override
{
return m_LastActivity;
return last_activity;
}
std::string

@ -12,7 +12,8 @@ namespace llarp::service
static auto logcat = log::Cat("service");
namespace
{
using EndpointConstructor = std::function<service::Endpoint_ptr(Router*, service::Context*)>;
using EndpointConstructor =
std::function<std::shared_ptr<Endpoint>(Router*, service::Context*)>;
using EndpointConstructors = std::map<std::string, EndpointConstructor>;
static EndpointConstructors endpointConstructors = {
@ -159,7 +160,7 @@ namespace llarp::service
return true;
}
Endpoint_ptr
std::shared_ptr<Endpoint>
Context::GetEndpointByName(const std::string& name) const
{
auto itr = m_Endpoints.find(name);

@ -38,7 +38,8 @@ namespace llarp::service
/// function visitor returns false to prematurely break iteration
void
ForEachService(std::function<bool(const std::string&, const Endpoint_ptr&)> visit) const;
ForEachService(
std::function<bool(const std::string&, const std::shared_ptr<Endpoint>&)> visit) const;
/// Pumps the hidden service endpoints, called during Router::PumpLL
void
@ -57,10 +58,10 @@ namespace llarp::service
bool
RemoveEndpoint(const std::string& name);
Endpoint_ptr
std::shared_ptr<Endpoint>
GetEndpointByName(const std::string& name) const;
Endpoint_ptr
std::shared_ptr<Endpoint>
GetDefault() const
{
return GetEndpointByName("default");

@ -31,7 +31,7 @@ namespace llarp::service
static auto logcat = log::Cat("endpoint");
Endpoint::Endpoint(Router* r, Context* parent)
: path::Builder{r, 3, path::DEFAULT_LEN}
: path::PathBuilder{r, 3, path::DEFAULT_LEN}
, context{parent}
, _inbound_queue{512}
, _send_queue{512}
@ -51,10 +51,10 @@ namespace llarp::service
Endpoint::Configure(const NetworkConfig& conf, [[maybe_unused]] const DnsConfig& dnsConf)
{
if (conf.paths.has_value())
numDesiredPaths = *conf.paths;
num_paths_desired = *conf.paths;
if (conf.hops.has_value())
numHops = *conf.hops;
num_hops = *conf.hops;
conf.exit_map.ForEachEntry(
[&](const IPRange& range, const service::Address& addr) { MapExitRange(range, addr); });
@ -257,7 +257,7 @@ namespace llarp::service
util::StatusObject
Endpoint::ExtractStatus() const
{
auto obj = path::Builder::ExtractStatus();
auto obj = path::PathBuilder::ExtractStatus();
obj["exitMap"] = _exit_map.ExtractStatus();
obj["identity"] = _identity.pub.Addr().ToString();
obj["networkReady"] = ReadyForNetwork();
@ -276,7 +276,7 @@ namespace llarp::service
Endpoint::Tick(llarp_time_t)
{
const auto now = llarp::time_now_ms();
path::Builder::Tick(now);
path::PathBuilder::Tick(now);
// publish descriptors
if (ShouldPublishDescriptors(now))
{
@ -299,7 +299,7 @@ namespace llarp::service
// expire convotags
EndpointUtil::ExpireConvoSessions(now, Sessions());
if (NumInStatus(path::ESTABLISHED) > 1)
if (NumInStatus(path::PathStatus::ESTABLISHED) > 1)
{
for (const auto& item : _startup_ons_mappings)
{
@ -337,7 +337,7 @@ namespace llarp::service
log::debug(logcat, "Endpoint stopping snode sessions.");
EndpointUtil::StopSnodeSessions(_state->snode_sessions);
log::debug(logcat, "Endpoint stopping its path builder.");
return path::Builder::Stop();
return path::PathBuilder::Stop();
}
uint64_t
@ -603,7 +603,7 @@ namespace llarp::service
intro_set().intros.clear();
for (auto& intro : intros)
{
if (intro_set().intros.size() < numDesiredPaths)
if (intro_set().intros.size() < num_paths_desired)
intro_set().intros.emplace_back(std::move(intro));
}
if (intro_set().intros.empty())
@ -667,7 +667,7 @@ namespace llarp::service
void
Endpoint::ResetInternalState()
{
path::Builder::ResetInternalState();
path::PathBuilder::ResetInternalState();
static auto resetState = [](auto& container, auto getter) {
std::for_each(container.begin(), container.end(), [getter](auto& item) {
getter(item)->ResetInternalState();
@ -712,7 +712,7 @@ namespace llarp::service
std::optional<std::vector<RemoteRC>>
Endpoint::GetHopsForBuildWithEndpoint(RouterID endpoint)
{
return path::Builder::GetHopsAlignedToForBuild(endpoint, SnodeBlacklist());
return path::PathBuilder::GetHopsAlignedToForBuild(endpoint, SnodeBlacklist());
}
constexpr auto MaxOutboundContextPerRemote = 1;
@ -754,7 +754,8 @@ namespace llarp::service
auto
Endpoint::GetUniqueEndpointsForLookup() const
{
path::UniqueEndpointSet_t paths;
std::unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator>
paths;
ForEachPath([&paths](auto path) {
if (path and path->IsReady())
@ -813,7 +814,7 @@ namespace llarp::service
// }
// pick up to max_unique_lns_endpoints random paths to do lookups from
std::vector<path::Path_ptr> chosenpaths;
std::vector<std::shared_ptr<path::Path>> chosenpaths;
chosenpaths.insert(chosenpaths.begin(), paths.begin(), paths.end());
std::shuffle(chosenpaths.begin(), chosenpaths.end(), llarp::csrng);
chosenpaths.resize(std::min(paths.size(), MAX_ONS_LOOKUP_ENDPOINTS));
@ -849,16 +850,16 @@ namespace llarp::service
}
void
Endpoint::HandlePathBuilt(path::Path_ptr p)
Endpoint::HandlePathBuilt(std::shared_ptr<path::Path> p)
{
// p->SetDataHandler(util::memFn(&Endpoint::HandleHiddenServiceFrame, this));
// p->SetDropHandler(util::memFn(&Endpoint::HandleDataDrop, this));
// p->SetDeadChecker(util::memFn(&Endpoint::CheckPathIsDead, this));
path::Builder::HandlePathBuilt(p);
path::PathBuilder::HandlePathBuilt(p);
}
bool
Endpoint::HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t seq)
Endpoint::HandleDataDrop(std::shared_ptr<path::Path> p, const PathID_t& dst, uint64_t seq)
{
LogWarn(Name(), " message ", seq, " dropped by endpoint ", p->Endpoint(), " via ", dst);
return true;
@ -889,7 +890,7 @@ namespace llarp::service
bool
Endpoint::HandleDataMessage(
path::Path_ptr p, const PathID_t from, std::shared_ptr<ProtocolMessage> msg)
std::shared_ptr<path::Path> p, const PathID_t from, std::shared_ptr<ProtocolMessage> msg)
{
PutSenderFor(msg->tag, msg->sender, true);
Introduction intro = msg->introReply;
@ -990,7 +991,11 @@ namespace llarp::service
void
Endpoint::SendAuthResult(
path::Path_ptr path, PathID_t /* replyPath */, ConvoTag tag, std::string result, bool success)
std::shared_ptr<path::Path> path,
PathID_t /* replyPath */,
ConvoTag tag,
std::string result,
bool success)
{
// not applicable because we are not an exit or don't have an endpoint auth policy
if ((not _state->is_exit_enabled) or _auth_policy == nullptr)
@ -1054,7 +1059,7 @@ namespace llarp::service
}
void
Endpoint::ResetConvoTag(ConvoTag tag, path::Path_ptr p, PathID_t /* from */)
Endpoint::ResetConvoTag(ConvoTag tag, std::shared_ptr<path::Path> p, PathID_t /* from */)
{
// send reset convo tag message
ProtocolFrameMessage f{};
@ -1072,7 +1077,8 @@ namespace llarp::service
}
bool
Endpoint::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrameMessage& frame)
Endpoint::HandleHiddenServiceFrame(
std::shared_ptr<path::Path> p, const ProtocolFrameMessage& frame)
{
if (frame.flag)
{
@ -1096,16 +1102,16 @@ namespace llarp::service
}
void
Endpoint::HandlePathDied(path::Path_ptr p)
Endpoint::HandlePathDied(std::shared_ptr<path::Path> p)
{
router()->router_profiling().MarkPathTimeout(p.get());
ManualRebuild(1);
path::Builder::HandlePathDied(p);
path::PathBuilder::HandlePathDied(p);
regen_and_publish_introset();
}
bool
Endpoint::CheckPathIsDead(path::Path_ptr, llarp_time_t dlt)
Endpoint::CheckPathIsDead(std::shared_ptr<path::Path>, llarp_time_t dlt)
{
return dlt > path::ALIVE_TIMEOUT;
}
@ -1198,7 +1204,7 @@ namespace llarp::service
bool
Endpoint::EnsurePathToSNode(
const RouterID snode,
std::function<void(const RouterID, exit::BaseSession_ptr, ConvoTag)> hook)
std::function<void(const RouterID, std::shared_ptr<exit::BaseSession>, ConvoTag)> hook)
{
auto& nodeSessions = _state->snode_sessions;
@ -1226,7 +1232,7 @@ namespace llarp::service
},
router(),
1,
numHops,
num_hops,
false,
this);
_state->snode_sessions[snode] = session;
@ -1538,8 +1544,8 @@ namespace llarp::service
{
if (BuildCooldownHit(now))
return false;
const auto requiredPaths = std::max(numDesiredPaths, path::MIN_INTRO_PATHS);
if (NumInStatus(path::BUILDING) >= requiredPaths)
const auto requiredPaths = std::max(num_paths_desired, path::MIN_INTRO_PATHS);
if (NumInStatus(path::PathStatus::BUILDING) >= requiredPaths)
return false;
return NumPathsExistingAt(now + (path::DEFAULT_LIFETIME - path::INTRO_PATH_SPREAD))
< requiredPaths;

@ -27,503 +27,503 @@
#ifndef MIN_SHIFT_INTERVAL
#define MIN_SHIFT_INTERVAL 5s
#endif
namespace llarp::quic
{
class TunnelManager;
}
namespace llarp
namespace llarp::service
{
namespace quic
{
class TunnelManager;
}
struct AsyncKeyExchange;
namespace service
{
struct AsyncKeyExchange;
struct Context;
struct EndpointState;
struct OutboundContext;
struct Context;
struct EndpointState;
struct OutboundContext;
/// minimum interval for publishing introsets
inline constexpr auto IntrosetPublishInterval = path::INTRO_PATH_SPREAD / 2;
/// minimum interval for publishing introsets
inline constexpr auto IntrosetPublishInterval = path::INTRO_PATH_SPREAD / 2;
/// how agressively should we retry publishing introset on failure
inline constexpr auto IntrosetPublishRetryCooldown = 1s;
/// how agressively should we retry publishing introset on failure
inline constexpr auto IntrosetPublishRetryCooldown = 1s;
/// how aggressively should we retry looking up introsets
inline constexpr auto IntrosetLookupCooldown = 250ms;
/// how aggressively should we retry looking up introsets
inline constexpr auto IntrosetLookupCooldown = 250ms;
/// number of unique snodes we want to talk to do to ons lookups
inline constexpr size_t MIN_ONS_LOOKUP_ENDPOINTS = 2;
/// number of unique snodes we want to talk to do to ons lookups
inline constexpr size_t MIN_ONS_LOOKUP_ENDPOINTS = 2;
inline constexpr size_t MAX_ONS_LOOKUP_ENDPOINTS = 7;
inline constexpr size_t MAX_ONS_LOOKUP_ENDPOINTS = 7;
// TODO: delete this, it is copied from the late llarp/service/handler.hpp
struct RecvDataEvent
{
std::shared_ptr<path::Path> fromPath;
PathID_t pathid;
std::shared_ptr<ProtocolMessage> msg;
};
// TODO: delete this, it is copied from the late llarp/service/handler.hpp
struct RecvDataEvent
{
path::Path_ptr fromPath;
PathID_t pathid;
std::shared_ptr<ProtocolMessage> msg;
};
struct Endpoint : public path::PathBuilder, public EndpointBase
// public std::enable_shared_from_this<Endpoint>
{
Endpoint(Router* r, Context* parent);
~Endpoint() override;
struct Endpoint : public path::Builder, public EndpointBase
// public std::enable_shared_from_this<Endpoint>
{
Endpoint(Router* r, Context* parent);
~Endpoint() override;
/// return true if we are ready to recv packets from the void.
/// really should be ReadyForInboundTraffic() but the diff is HUGE and we need to rewrite this
/// component anyways.
bool
is_ready() const;
/// return true if we are ready to recv packets from the void.
/// really should be ReadyForInboundTraffic() but the diff is HUGE and we need to rewrite this
/// component anyways.
bool
is_ready() const;
void
QueueRecvData(RecvDataEvent ev);
void
QueueRecvData(RecvDataEvent ev);
/// return true if our introset has expired intros
bool
IntrosetIsStale() const;
/// return true if our introset has expired intros
bool
IntrosetIsStale() const;
/// construct parameters for notify hooks
virtual std::unordered_map<std::string, std::string>
NotifyParams() const;
virtual util::StatusObject
ExtractStatus() const;
/// construct parameters for notify hooks
virtual std::unordered_map<std::string, std::string>
NotifyParams() const;
virtual bool
Configure(const NetworkConfig& conf, const DnsConfig& dnsConf);
virtual util::StatusObject
ExtractStatus() const;
void
Tick(llarp_time_t now) override;
virtual bool
Configure(const NetworkConfig& conf, const DnsConfig& dnsConf);
/// return true if we have a resolvable ip address
virtual bool
HasIfAddr() const
{
return false;
}
void
Tick(llarp_time_t now) override;
virtual std::string
GetIfName() const = 0;
/// return true if we have a resolvable ip address
virtual bool
HasIfAddr() const
{
return false;
}
std::optional<ConvoTag>
GetBestConvoTagFor(std::variant<Address, RouterID> addr) const override;
virtual std::string
GetIfName() const = 0;
/// get our ifaddr if it is set
virtual huint128_t
GetIfAddr() const
{
return {0};
}
std::optional<ConvoTag>
GetBestConvoTagFor(std::variant<Address, RouterID> addr) const override;
/// get the exit policy for our exit if we have one
/// override me
virtual std::optional<net::TrafficPolicy>
GetExitPolicy() const
{
return std::nullopt;
};
/// get our ifaddr if it is set
virtual huint128_t
GetIfAddr() const
{
return {0};
}
/// get the ip ranges we claim to own
/// override me
virtual std::set<IPRange>
GetOwnedRanges() const
{
return {};
};
/// get the exit policy for our exit if we have one
/// override me
virtual std::optional<net::TrafficPolicy>
GetExitPolicy() const
{
return std::nullopt;
};
virtual void
Thaw(){};
/// get the ip ranges we claim to own
/// override me
virtual std::set<IPRange>
GetOwnedRanges() const
{
return {};
};
void
ResetInternalState() override;
virtual void
Thaw(){};
/// loop (via router)
/// use when sending any data on a path
const EventLoop_ptr&
Loop() override;
void
ResetInternalState() override;
Router*
router();
/// loop (via router)
/// use when sending any data on a path
const EventLoop_ptr&
Loop() override;
virtual bool
LoadKeyFile();
Router*
router();
virtual bool
Start();
std::string
Name() const override;
AddressVariant_t
LocalAddress() const override;
virtual bool
LoadKeyFile();
std::optional<SendStat>
GetStatFor(AddressVariant_t remote) const override;
virtual bool
Start();
std::unordered_set<AddressVariant_t>
AllRemoteEndpoints() const override;
std::string
Name() const override;
bool
ShouldPublishDescriptors(llarp_time_t now) const override;
void
SRVRecordsChanged() override;
AddressVariant_t
LocalAddress() const override;
void
HandlePathDied(path::Path_ptr p) override;
std::optional<SendStat>
GetStatFor(AddressVariant_t remote) const override;
virtual vpn::EgresPacketRouter*
EgresPacketRouter()
{
return nullptr;
}
std::unordered_set<AddressVariant_t>
AllRemoteEndpoints() const override;
virtual vpn::NetworkInterface*
GetVPNInterface()
{
return nullptr;
}
bool
ShouldPublishDescriptors(llarp_time_t now) const override;
bool
publish_introset(const EncryptedIntroSet& i);
void
SRVRecordsChanged() override;
bool
HandleHiddenServiceFrame(path::Path_ptr p, const service::ProtocolFrameMessage& msg);
void
HandlePathDied(std::shared_ptr<path::Path> p) override;
void
SetEndpointAuth(std::shared_ptr<IAuthPolicy> policy);
virtual vpn::EgresPacketRouter*
EgresPacketRouter()
{
return nullptr;
}
/// sets how we authenticate with remote address
void
SetAuthInfoForEndpoint(Address remote, AuthInfo info);
virtual vpn::NetworkInterface*
GetVPNInterface()
{
return nullptr;
}
virtual huint128_t ObtainIPForAddr(std::variant<Address, RouterID>) = 0;
bool
publish_introset(const EncryptedIntroSet& i);
/// get a key for ip address
virtual std::optional<std::variant<service::Address, RouterID>>
ObtainAddrForIP(huint128_t ip) const = 0;
bool
HandleHiddenServiceFrame(
std::shared_ptr<path::Path> p, const service::ProtocolFrameMessage& msg);
// virtual bool
// HasServiceAddress(const AlignedBuffer< 32 >& addr) const = 0;
void
SetEndpointAuth(std::shared_ptr<IAuthPolicy> policy);
/// return true if we have a pending job to build to a hidden service but
/// it's not done yet
bool
HasPendingPathToService(const Address& remote) const;
/// sets how we authenticate with remote address
void
SetAuthInfoForEndpoint(Address remote, AuthInfo info);
bool
HandleDataMessage(
path::Path_ptr path, const PathID_t from, std::shared_ptr<ProtocolMessage> msg);
virtual huint128_t ObtainIPForAddr(std::variant<Address, RouterID>) = 0;
/// handle packet io from service node or hidden service to frontend
virtual bool
HandleInboundPacket(
const ConvoTag tag, const llarp_buffer_t& pkt, ProtocolType t, uint64_t seqno) = 0;
/// get a key for ip address
virtual std::optional<std::variant<service::Address, RouterID>>
ObtainAddrForIP(huint128_t ip) const = 0;
// virtual bool
// HandleWriteIPPacket(const llarp_buffer_t& pkt,
// std::function< huint128_t(void) > getFromIP) = 0;
// virtual bool
// HasServiceAddress(const AlignedBuffer< 32 >& addr) const = 0;
bool
ProcessDataMessage(std::shared_ptr<ProtocolMessage> msg);
/// return true if we have a pending job to build to a hidden service but
/// it's not done yet
bool
HasPendingPathToService(const Address& remote) const;
// "find name"
void
lookup_name(std::string name, std::function<void(std::string, bool)> func = nullptr) override;
bool
HandleDataMessage(
std::shared_ptr<path::Path> path,
const PathID_t from,
std::shared_ptr<ProtocolMessage> msg);
// "find introset?"
void
LookupServiceAsync(
std::string name,
std::string service,
std::function<void(std::vector<dns::SRVData>)> resultHandler) override;
/// handle packet io from service node or hidden service to frontend
virtual bool
HandleInboundPacket(
const ConvoTag tag, const llarp_buffer_t& pkt, ProtocolType t, uint64_t seqno) = 0;
/// called on event loop pump
virtual void
Pump(llarp_time_t now);
// virtual bool
// HandleWriteIPPacket(const llarp_buffer_t& pkt,
// std::function< huint128_t(void) > getFromIP) = 0;
/// stop this endpoint
bool
Stop() override;
bool
ProcessDataMessage(std::shared_ptr<ProtocolMessage> msg);
const Identity&
GetIdentity() const
{
return _identity;
}
// "find name"
void
lookup_name(std::string name, std::function<void(std::string, bool)> func = nullptr) override;
void
MapExitRange(IPRange range, service::Address exit);
// "find introset?"
void
LookupServiceAsync(
std::string name,
std::string service,
std::function<void(std::vector<dns::SRVData>)> resultHandler) override;
void
UnmapExitRange(IPRange range);
/// called on event loop pump
virtual void
Pump(llarp_time_t now);
void
UnmapRangeByExit(IPRange range, std::string exit);
/// stop this endpoint
bool
Stop() override;
void
map_exit(
std::string name,
std::string token,
std::vector<IPRange> ranges,
std::function<void(bool, std::string)> result);
const Identity&
GetIdentity() const
{
return _identity;
}
void
HandlePathBuilt(path::Path_ptr path) override;
void
MapExitRange(IPRange range, service::Address exit);
bool
HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t s);
void
UnmapExitRange(IPRange range);
bool
CheckPathIsDead(path::Path_ptr p, llarp_time_t latency);
void
UnmapRangeByExit(IPRange range, std::string exit);
using PendingBufferQueue = std::deque<PendingBuffer>;
void
map_exit(
std::string name,
std::string token,
std::vector<IPRange> ranges,
std::function<void(bool, std::string)> result);
size_t
RemoveAllConvoTagsFor(service::Address remote);
void
HandlePathBuilt(std::shared_ptr<path::Path> path) override;
bool
WantsOutboundSession(const Address&) const;
bool
HandleDataDrop(std::shared_ptr<path::Path> p, const PathID_t& dst, uint64_t s);
/// this MUST be called if you want to call EnsurePathTo on the given address
void MarkAddressOutbound(service::Address) override;
bool
CheckPathIsDead(std::shared_ptr<path::Path> p, llarp_time_t latency);
void
BlacklistSNode(const RouterID snode) override;
using PendingBufferQueue = std::deque<PendingBuffer>;
/// maybe get an endpoint variant given its convo tag
std::optional<std::variant<Address, RouterID>>
GetEndpointWithConvoTag(ConvoTag t) const override;
size_t
RemoveAllConvoTagsFor(service::Address remote);
bool
HasConvoTag(const ConvoTag& t) const;
bool
WantsOutboundSession(const Address&) const;
bool
ShouldBuildMore(llarp_time_t now) const override;
/// this MUST be called if you want to call EnsurePathTo on the given address
void MarkAddressOutbound(service::Address) override;
virtual llarp_time_t
PathAlignmentTimeout() const
{
constexpr auto DefaultPathAlignmentTimeout = 30s;
return DefaultPathAlignmentTimeout;
}
void
BlacklistSNode(const RouterID snode) override;
bool
EnsurePathTo(
std::variant<Address, RouterID> addr,
std::function<void(std::optional<ConvoTag>)> hook,
llarp_time_t timeout) override;
/// maybe get an endpoint variant given its convo tag
std::optional<std::variant<Address, RouterID>>
GetEndpointWithConvoTag(ConvoTag t) const override;
static constexpr auto DefaultPathEnsureTimeout = 2s;
bool
HasConvoTag(const ConvoTag& t) const;
/// return false if we have already called this function before for this
/// address
bool
EnsurePathToService(
const Address remote,
std::function<void(Address, OutboundContext*)> h,
llarp_time_t timeoutMS = DefaultPathEnsureTimeout);
bool
ShouldBuildMore(llarp_time_t now) const override;
void
InformPathToService(const Address remote, OutboundContext* ctx);
virtual llarp_time_t
PathAlignmentTimeout() const
{
constexpr auto DefaultPathAlignmentTimeout = 30s;
return DefaultPathAlignmentTimeout;
}
/// ensure a path to a service node by public key
bool
EnsurePathToSNode(
const RouterID remote,
std::function<void(const RouterID, exit::BaseSession_ptr, ConvoTag)> h);
bool
EnsurePathTo(
std::variant<Address, RouterID> addr,
std::function<void(std::optional<ConvoTag>)> hook,
llarp_time_t timeout) override;
/// return true if this endpoint is trying to lookup this router right now
bool
HasPendingRouterLookup(const RouterID remote) const;
static constexpr auto DefaultPathEnsureTimeout = 2s;
bool
HasPathToSNode(const RouterID remote) const;
/// return false if we have already called this function before for this
/// address
bool
EnsurePathToService(
const Address remote,
std::function<void(Address, OutboundContext*)> h,
llarp_time_t timeoutMS = DefaultPathEnsureTimeout);
bool
HasFlowToService(const Address remote) const;
void
InformPathToService(const Address remote, OutboundContext* ctx);
void
PutSenderFor(const ConvoTag& tag, const ServiceInfo& info, bool inbound);
/// ensure a path to a service node by public key
bool
EnsurePathToSNode(
const RouterID remote,
std::function<void(const RouterID, std::shared_ptr<exit::BaseSession>, ConvoTag)> h);
bool
HasInboundConvo(const Address& addr) const;
/// return true if this endpoint is trying to lookup this router right now
bool
HasPendingRouterLookup(const RouterID remote) const;
bool
HasOutboundConvo(const Address& addr) const;
bool
HasPathToSNode(const RouterID remote) const;
bool
GetCachedSessionKeyFor(const ConvoTag& remote, SharedSecret& secret) const;
bool
HasFlowToService(const Address remote) const;
void
PutCachedSessionKeyFor(const ConvoTag& remote, const SharedSecret& secret);
void
PutSenderFor(const ConvoTag& tag, const ServiceInfo& info, bool inbound);
bool
GetSenderFor(const ConvoTag& remote, ServiceInfo& si) const;
bool
HasInboundConvo(const Address& addr) const;
void
PutIntroFor(const ConvoTag& remote, const Introduction& intro);
bool
HasOutboundConvo(const Address& addr) const;
bool
GetIntroFor(const ConvoTag& remote, Introduction& intro) const;
bool
GetCachedSessionKeyFor(const ConvoTag& remote, SharedSecret& secret) const;
void
RemoveConvoTag(const ConvoTag& remote);
void
PutCachedSessionKeyFor(const ConvoTag& remote, const SharedSecret& secret);
void
ConvoTagTX(const ConvoTag& remote);
bool
GetSenderFor(const ConvoTag& remote, ServiceInfo& si) const;
void
ConvoTagRX(const ConvoTag& remote);
void
PutIntroFor(const ConvoTag& remote, const Introduction& intro);
void
PutReplyIntroFor(const ConvoTag& remote, const Introduction& intro);
bool
GetIntroFor(const ConvoTag& remote, Introduction& intro) const;
bool
GetReplyIntroFor(const ConvoTag& remote, Introduction& intro) const;
void
RemoveConvoTag(const ConvoTag& remote);
bool
GetConvoTagsForService(const Address& si, std::set<ConvoTag>& tag) const;
void
ConvoTagTX(const ConvoTag& remote);
void
PutNewOutboundContext(const IntroSet& introset, llarp_time_t timeLeftToAlign);
void
ConvoTagRX(const ConvoTag& remote);
std::optional<uint64_t>
GetSeqNoForConvo(const ConvoTag& tag);
void
PutReplyIntroFor(const ConvoTag& remote, const Introduction& intro);
/// count unique endpoints we are talking to
size_t
UniqueEndpoints() const;
bool
GetReplyIntroFor(const ConvoTag& remote, Introduction& intro) const;
bool
HasExit() const;
bool
GetConvoTagsForService(const Address& si, std::set<ConvoTag>& tag) const;
std::optional<std::vector<RemoteRC>>
GetHopsForBuild() override;
void
PutNewOutboundContext(const IntroSet& introset, llarp_time_t timeLeftToAlign);
std::optional<std::vector<RemoteRC>>
GetHopsForBuildWithEndpoint(RouterID endpoint);
std::optional<uint64_t>
GetSeqNoForConvo(const ConvoTag& tag);
void
AsyncProcessAuthMessage(
std::shared_ptr<ProtocolMessage> msg, std::function<void(std::string, bool)> hook);
/// count unique endpoints we are talking to
size_t
UniqueEndpoints() const;
void
SendAuthResult(
path::Path_ptr path, PathID_t replyPath, ConvoTag tag, std::string result, bool success);
bool
HasExit() const;
uint64_t
GenTXID();
std::optional<std::vector<RemoteRC>>
GetHopsForBuild() override;
void
ResetConvoTag(ConvoTag tag, path::Path_ptr path, PathID_t from);
std::optional<std::vector<RemoteRC>>
GetHopsForBuildWithEndpoint(RouterID endpoint);
const std::set<RouterID>&
SnodeBlacklist() const;
void
AsyncProcessAuthMessage(
std::shared_ptr<ProtocolMessage> msg, std::function<void(std::string, bool)> hook);
// Looks up the ConvoTag and, if it exists, calls SendToOrQueue to send it to a remote client
// or a snode (or nothing, if the convo tag is unknown).
bool
send_to(ConvoTag tag, std::string payload) override;
void
SendAuthResult(
std::shared_ptr<path::Path> path,
PathID_t replyPath,
ConvoTag tag,
std::string result,
bool success);
std::optional<AuthInfo>
MaybeGetAuthInfoForEndpoint(service::Address addr);
uint64_t
GenTXID();
/// Returns a pointer to the quic::Tunnel object handling quic connections for this endpoint.
/// Returns nullptr if quic is not supported.
link::TunnelManager*
GetQUICTunnel() override;
void
ResetConvoTag(ConvoTag tag, std::shared_ptr<path::Path> path, PathID_t from);
protected:
/// parent context that owns this endpoint
Context* const context;
const std::set<RouterID>&
SnodeBlacklist() const;
virtual bool
SupportsV6() const = 0;
// Looks up the ConvoTag and, if it exists, calls SendToOrQueue to send it to a remote client
// or a snode (or nothing, if the convo tag is unknown).
bool
send_to(ConvoTag tag, std::string payload) override;
void
regen_and_publish_introset();
std::optional<AuthInfo>
MaybeGetAuthInfoForEndpoint(service::Address addr);
IServiceLookup*
GenerateLookupByTag(const Tag& tag);
/// Returns a pointer to the quic::Tunnel object handling quic connections for this endpoint.
/// Returns nullptr if quic is not supported.
link::TunnelManager*
GetQUICTunnel() override;
void
PrefetchServicesByTag(const Tag& tag);
protected:
/// parent context that owns this endpoint
Context* const context;
private:
bool
DoNetworkIsolation(bool failed);
virtual bool
SupportsV6() const = 0;
virtual bool
SetupNetworking()
{
// XXX: override me
return true;
}
void
regen_and_publish_introset();
virtual bool
IsolationFailed()
{
// XXX: override me
return false;
}
IServiceLookup*
GenerateLookupByTag(const Tag& tag);
/// return true if we are ready to do outbound and inbound traffic
bool
ReadyForNetwork() const;
void
PrefetchServicesByTag(const Tag& tag);
protected:
bool
ReadyToDoLookup(size_t num_paths) const;
private:
bool
DoNetworkIsolation(bool failed);
auto
GetUniqueEndpointsForLookup() const;
virtual bool
SetupNetworking()
{
// XXX: override me
return true;
}
Identity _identity;
net::IPRangeMap<service::Address> _exit_map;
bool _publish_introset = true;
std::unique_ptr<EndpointState> _state;
std::shared_ptr<IAuthPolicy> _auth_policy;
std::unordered_map<Address, AuthInfo> _remote_auth_infos;
std::unique_ptr<link::TunnelManager> _tunnel_manager;
virtual bool
IsolationFailed()
{
// XXX: override me
return false;
}
/// (ons name, optional exit range, optional auth info) for looking up on startup
std::unordered_map<std::string, std::pair<std::optional<IPRange>, std::optional<AuthInfo>>>
_startup_ons_mappings;
/// return true if we are ready to do outbound and inbound traffic
bool
ReadyForNetwork() const;
RecvPacketQueue_t _inbound_queue;
protected:
bool
ReadyToDoLookup(size_t num_paths) const;
public:
SendMessageEventQueue _send_queue;
auto
GetUniqueEndpointsForLookup() const;
private:
llarp_time_t _last_introset_regen_attempt = 0s;
Identity _identity;
net::IPRangeMap<service::Address> _exit_map;
bool _publish_introset = true;
std::unique_ptr<EndpointState> _state;
std::shared_ptr<IAuthPolicy> _auth_policy;
std::unordered_map<Address, AuthInfo> _remote_auth_infos;
std::unique_ptr<link::TunnelManager> _tunnel_manager;
protected:
void
FlushRecvData();
/// (ons name, optional exit range, optional auth info) for looking up on startup
std::unordered_map<std::string, std::pair<std::optional<IPRange>, std::optional<AuthInfo>>>
_startup_ons_mappings;
friend struct EndpointUtil;
RecvPacketQueue_t _inbound_queue;
const IntroSet&
intro_set() const;
IntroSet&
intro_set();
public:
SendMessageEventQueue _send_queue;
const std::unordered_map<ConvoTag, Session>&
Sessions() const;
std::unordered_map<ConvoTag, Session>&
Sessions();
private:
llarp_time_t _last_introset_regen_attempt = 0s;
thread::Queue<RecvDataEvent> _recv_event_queue;
protected:
void
FlushRecvData();
/// for rate limiting introset lookups
util::DecayingHashSet<Address> _introset_lookup_filter;
};
friend struct EndpointUtil;
const IntroSet&
intro_set() const;
IntroSet&
intro_set();
const std::unordered_map<ConvoTag, Session>&
Sessions() const;
std::unordered_map<ConvoTag, Session>&
Sessions();
using Endpoint_ptr = std::shared_ptr<Endpoint>;
thread::Queue<RecvDataEvent> _recv_event_queue;
} // namespace service
} // namespace llarp
/// for rate limiting introset lookups
util::DecayingHashSet<Address> _introset_lookup_filter;
};
} // namespace llarp::service

@ -16,7 +16,7 @@ namespace llarp
{
// clang-format off
namespace exit { struct BaseSession; }
namespace path { struct Path; using Path_ptr = std::shared_ptr< Path >; }
namespace path { struct Path; }
namespace routing { struct PathTransferMessage; }
// clang-format on
@ -27,7 +27,7 @@ namespace llarp
using Msg_ptr = std::shared_ptr<routing::PathTransferMessage>;
using SendEvent = std::pair<Msg_ptr, path::Path_ptr>;
using SendEvent = std::pair<Msg_ptr, std::shared_ptr<path::Path>>;
using SendMessageEventQueue = thread::Queue<SendEvent>;
using PendingBufferDeque = std::deque<PendingBuffer>;

@ -42,19 +42,21 @@ namespace llarp::service
};
template <typename Endpoint_t>
static std::unordered_set<path::Path_ptr, path::Endpoint_Hash, path::endpoint_comparator>
GetManyPathsWithUniqueEndpoints(
Endpoint_t* ep,
size_t N,
std::optional<dht::Key_t> maybeLocation = std::nullopt,
size_t tries = 10)
static std::
unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator>
GetManyPathsWithUniqueEndpoints(
Endpoint_t* ep,
size_t N,
std::optional<dht::Key_t> maybeLocation = std::nullopt,
size_t tries = 10)
{
std::unordered_set<RouterID> exclude;
path::UniqueEndpointSet_t paths;
std::unordered_set<std::shared_ptr<path::Path>, path::Endpoint_Hash, path::endpoint_comparator>
paths;
do
{
--tries;
path::Path_ptr path;
std::shared_ptr<path::Path> path;
if (maybeLocation)
{
path = ep->GetEstablishedPathClosestTo(RouterID{maybeLocation->as_array()}, exclude);

@ -17,7 +17,7 @@ namespace llarp::service
OutboundContext::Stop()
{
marked_bad = true;
return path::Builder::Stop();
return path::PathBuilder::Stop();
}
bool
@ -30,7 +30,7 @@ namespace llarp::service
constexpr auto OutboundContextNumPaths = 4;
OutboundContext::OutboundContext(const IntroSet& introset, Endpoint* parent)
: path::Builder{parent->router(), OutboundContextNumPaths, parent->numHops}
: path::PathBuilder{parent->router(), OutboundContextNumPaths, parent->num_hops}
, ep{*parent}
, current_intro{introset}
, location{current_intro.address_keys.Addr().ToKey()}
@ -108,27 +108,27 @@ namespace llarp::service
}
void
OutboundContext::HandlePathBuildTimeout(path::Path_ptr p)
OutboundContext::HandlePathBuildTimeout(std::shared_ptr<path::Path> p)
{
ShiftIntroRouter(p->Endpoint());
path::Builder::HandlePathBuildTimeout(p);
path::PathBuilder::HandlePathBuildTimeout(p);
}
void
OutboundContext::HandlePathBuildFailedAt(path::Path_ptr p, RouterID hop)
OutboundContext::HandlePathBuildFailedAt(std::shared_ptr<path::Path> p, RouterID hop)
{
if (p->Endpoint() == hop)
{
// shift intro when we fail at the pivot
ShiftIntroRouter(p->Endpoint());
}
path::Builder::HandlePathBuildFailedAt(p, hop);
path::PathBuilder::HandlePathBuildFailedAt(p, hop);
}
void
OutboundContext::HandlePathBuilt(path::Path_ptr p)
OutboundContext::HandlePathBuilt(std::shared_ptr<path::Path> p)
{
path::Builder::HandlePathBuilt(p);
path::PathBuilder::HandlePathBuilt(p);
// p->SetDataHandler([self = weak_from_this()](auto path, auto frame) {
// if (auto ptr = self.lock())
// return ptr->HandleHiddenServiceFrame(path, frame);
@ -143,7 +143,7 @@ namespace llarp::service
{
// ignore new path if we are marked dead
LogInfo(Name(), " marked bad, ignoring new path");
p->EnterState(path::IGNORE, Now());
p->EnterState(path::PathStatus::IGNORE, Now());
}
else if (p->Endpoint() == next_intro.router)
{
@ -236,7 +236,7 @@ namespace llarp::service
util::StatusObject
OutboundContext::ExtractStatus() const
{
auto obj = path::Builder::ExtractStatus();
auto obj = path::PathBuilder::ExtractStatus();
obj["current_tag"] = current_tag.ToHex();
obj["remote_intro"] = remote_intro.ExtractStatus();
obj["session_created"] = to_json(created_at);
@ -372,25 +372,27 @@ namespace llarp::service
bool
OutboundContext::ShouldBuildMore(std::chrono::milliseconds now) const
{
if (marked_bad or path::Builder::BuildCooldownHit(now))
if (marked_bad or path::PathBuilder::BuildCooldownHit(now))
return false;
if (NumInStatus(path::BUILDING) >= std::max(numDesiredPaths / size_t{2}, size_t{1}))
if (NumInStatus(path::PathStatus::BUILDING)
>= std::max(num_paths_desired / size_t{2}, size_t{1}))
return false;
size_t numValidPaths = 0;
bool havePathToNextIntro = false;
ForEachPath([now, this, &havePathToNextIntro, &numValidPaths](path::Path_ptr path) {
if (not path->IsReady())
return;
if (not path->intro.ExpiresSoon(now, path::DEFAULT_LIFETIME - path::INTRO_PATH_SPREAD))
{
numValidPaths++;
if (path->intro.router == next_intro.router)
havePathToNextIntro = true;
}
});
return numValidPaths < numDesiredPaths or not havePathToNextIntro;
ForEachPath(
[now, this, &havePathToNextIntro, &numValidPaths](std::shared_ptr<path::Path> path) {
if (not path->IsReady())
return;
if (not path->intro.ExpiresSoon(now, path::DEFAULT_LIFETIME - path::INTRO_PATH_SPREAD))
{
numValidPaths++;
if (path->intro.router == next_intro.router)
havePathToNextIntro = true;
}
});
return numValidPaths < num_paths_desired or not havePathToNextIntro;
}
bool
@ -468,7 +470,7 @@ namespace llarp::service
}
void
OutboundContext::HandlePathDied(path::Path_ptr path)
OutboundContext::HandlePathDied(std::shared_ptr<path::Path> path)
{
// unconditionally update introset
UpdateIntroSet();
@ -478,7 +480,7 @@ namespace llarp::service
{
// figure out how many paths to this router we have
size_t num = 0;
ForEachPath([&](const path::Path_ptr& p) {
ForEachPath([&](const std::shared_ptr<path::Path>& p) {
if (p->Endpoint() == endpoint && p->IsReady())
++num;
});
@ -509,7 +511,7 @@ namespace llarp::service
void
OutboundContext::Tick(llarp_time_t now)
{
path::Builder::Tick(now);
path::PathBuilder::Tick(now);
if (ShouldKeepAlive(now))
KeepAlive();

@ -15,7 +15,7 @@ namespace llarp::service
struct Endpoint;
/// context needed to initiate an outbound hidden service session
struct OutboundContext : public llarp::path::Builder,
struct OutboundContext : public llarp::path::PathBuilder,
public std::enable_shared_from_this<OutboundContext>
{
private:
@ -87,7 +87,7 @@ namespace llarp::service
void
BlacklistSNode(const RouterID) override{};
path::PathSet_ptr
std::shared_ptr<path::PathSet>
GetSelf() override
{
return shared_from_this();
@ -106,7 +106,7 @@ namespace llarp::service
Stop() override;
void
HandlePathDied(path::Path_ptr p) override;
HandlePathDied(std::shared_ptr<path::Path> p) override;
/// set to true if we are updating the remote introset right now
bool updatingIntroSet;
@ -137,20 +137,20 @@ namespace llarp::service
IsDone(std::chrono::milliseconds now) const;
bool
CheckPathIsDead(path::Path_ptr p, std::chrono::milliseconds dlt);
CheckPathIsDead(std::shared_ptr<path::Path> p, std::chrono::milliseconds dlt);
/// issues a lookup to find the current intro set of the remote service
void
UpdateIntroSet();
void
HandlePathBuilt(path::Path_ptr path) override;
HandlePathBuilt(std::shared_ptr<path::Path> path) override;
void
HandlePathBuildTimeout(path::Path_ptr path) override;
HandlePathBuildTimeout(std::shared_ptr<path::Path> path) override;
void
HandlePathBuildFailedAt(path::Path_ptr path, RouterID hop) override;
HandlePathBuildFailedAt(std::shared_ptr<path::Path> path, RouterID hop) override;
std::optional<std::vector<RemoteRC>>
GetHopsForBuild() override;

@ -29,7 +29,7 @@ namespace llarp::service
void
ProtocolMessage::ProcessAsync(
path::Path_ptr path, PathID_t from, std::shared_ptr<ProtocolMessage> self)
std::shared_ptr<path::Path> path, PathID_t from, std::shared_ptr<ProtocolMessage> self)
{
if (!self->handler->HandleDataMessage(path, from, self))
LogWarn("failed to handle data message from ", path->name());
@ -225,7 +225,7 @@ namespace llarp::service
struct AsyncFrameDecrypt
{
path::Path_ptr path;
std::shared_ptr<path::Path> path;
EventLoop_ptr loop;
std::shared_ptr<ProtocolMessage> msg;
const Identity& m_LocalIdentity;
@ -322,7 +322,7 @@ namespace llarp::service
crypto::shorthash(shared_key, tmp.data(), tmp.size());
std::shared_ptr<ProtocolMessage> msg = std::move(self->msg);
path::Path_ptr path = std::move(self->path);
std::shared_ptr<path::Path> path = std::move(self->path);
const PathID_t from = self->frame.path_id;
msg->handler = self->handler;
self->handler->AsyncProcessAuthMessage(
@ -367,7 +367,7 @@ namespace llarp::service
bool
ProtocolFrameMessage::AsyncDecryptAndVerify(
EventLoop_ptr loop,
path::Path_ptr recvPath,
std::shared_ptr<path::Path> recvPath,
const Identity& localIdent,
Endpoint* handler,
std::function<void(std::shared_ptr<ProtocolMessage>)> hook) const

@ -60,7 +60,8 @@ namespace llarp
put_buffer(std::string buf);
static void
ProcessAsync(path::Path_ptr p, PathID_t from, std::shared_ptr<ProtocolMessage> self);
ProcessAsync(
std::shared_ptr<path::Path> p, PathID_t from, std::shared_ptr<ProtocolMessage> self);
bool
operator>(const ProtocolMessage& other) const
@ -111,7 +112,7 @@ namespace llarp
bool
AsyncDecryptAndVerify(
EventLoop_ptr loop,
path::Path_ptr fromPath,
std::shared_ptr<path::Path> fromPath,
const Identity& localIdent,
Endpoint* handler,
std::function<void(std::shared_ptr<ProtocolMessage>)> hook = nullptr) const;

@ -49,7 +49,7 @@ namespace llarp
return true;
}
path::PathSet_ptr
std::shared_ptr<path::PathSet>
GetSelf() override
{
return shared_from_this();

Loading…
Cancel
Save