1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

flow layer wireup.

This commit is contained in:
Jeff Becker 2023-04-18 10:53:25 -04:00
parent 852d57169b
commit fe9766f26e
No known key found for this signature in database
GPG key ID: 025C02EE3A092F2D
21 changed files with 462 additions and 93 deletions

View file

@ -21,8 +21,8 @@ namespace llarp::layers::flow
decode_addr(std::string_view str)
{
llarp::AlignedBuffer<32>::Data data{};
if (auto sz = oxenc::to_base32z_size(str.size()); sz != data.size())
throw std::invalid_argument{"data decode size {} != {}"_format(sz, data.size())};
if (auto sz = oxenc::to_base32z_size(data.size()); sz != str.size())
throw std::invalid_argument{"data decode size {} != {}"_format(sz, str.size())};
oxenc::from_base32z(str.begin(), str.end(), data.begin());
return data;
}
@ -33,7 +33,7 @@ namespace llarp::layers::flow
{}
FlowAddr::FlowAddr(EndpointBase::AddressVariant_t addr)
: FlowAddr{var::visit([](auto&& a) { return a.ToString(); }, addr)}
: FlowAddr{var::visit([](auto&& a) -> std::string { return a.ToString(); }, addr)}
{}
std::string

View file

@ -3,6 +3,7 @@
#include <optional>
namespace llarp::layers::flow
{
static auto logcat = log::Cat("flow-layer");
FlowEstablish::FlowEstablish(
std::function<void(std::optional<FlowInfo>, std::string)> completiton_handler,
@ -12,10 +13,10 @@ namespace llarp::layers::flow
{}
void
FlowEstablish::fail(std::string name)
FlowEstablish::fail(std::string info)
{
_result = std::nullopt;
enter_phase(FlowAuthPhase::auth_nack, std::move(name));
enter_phase(FlowAuthPhase::auth_nack, std::move(info));
}
void

View file

@ -1,15 +1,21 @@
#include "flow_identity.hpp"
#include <oxenc/bt_serialize.h>
#include <chrono>
#include <llarp/crypto/crypto.hpp>
#include <llarp/router/abstractrouter.hpp>
#include <llarp/service/endpoint.hpp>
#include <llarp/util/logging.hpp>
#include <chrono>
#include <memory>
#include <stdexcept>
#include <variant>
namespace llarp::layers::flow
{
static auto logcat = log::Cat("flow-layer");
FlowIdentityPrivateKeys
FlowIdentityPrivateKeys::keygen()
{
@ -41,14 +47,11 @@ namespace llarp::layers::flow
}
FlowIdentity::FlowIdentity(
FlowLayer& parent,
FlowAddr remote_addr,
FlowTag flow_tag_,
const FlowIdentityPrivateKeys& privkeys)
FlowLayer& parent, FlowAddr remote_addr, const FlowIdentityPrivateKeys& privkeys)
: _parent{parent}
, _local_privkeys{privkeys}
, _state{}
, flow_info{privkeys.public_addr(), std::move(remote_addr), std::move(flow_tag_)}
, _state{nullptr}
, _flow_info{privkeys.public_addr(), std::move(remote_addr), FlowTag{}}
{}
bool
@ -74,33 +77,88 @@ namespace llarp::layers::flow
}
}
struct deprecated_path_ensure_handler
service::ProtocolType
to_proto_type(const FlowDataKind& kind)
{
FlowEstablish handshaker;
FlowInfo flow_info;
void
operator()(std::optional<service::ConvoTag> maybe_tag)
switch (kind)
{
if (not maybe_tag)
{
handshaker.fail("cannot establish flow");
return;
}
handshaker.ready(flow_info);
case FlowDataKind::exit_ip_unicast:
return service::ProtocolType::Exit;
case FlowDataKind::direct_ip_unicast:
// todo: change to direct after we swap to new
// route layer.
return service::ProtocolType::TrafficV4;
case FlowDataKind::stream_unicast:
return service::ProtocolType::QUIC;
case FlowDataKind::auth:
return service::ProtocolType::Auth;
default:
return service::ProtocolType::Control;
}
};
}
} // namespace
struct deprecated_path_ensure_handler
{
FlowIdentity& flow;
FlowEstablish handshaker;
void
operator()(std::optional<service::ConvoTag> maybe_tag)
{
if (not maybe_tag)
{
log::warning(logcat, "flow establish to {} failed", flow.flow_info.dst);
handshaker.fail("cannot establish flow");
return;
}
flow._flow_info.tag = FlowTag{maybe_tag->as_array()};
log::debug(logcat, "flow established: {}", flow.flow_info);
handshaker.ready(flow.flow_info);
}
};
void
FlowIdentity::async_ensure_flow(FlowEstablish handshaker)
{
handshaker.fail("not wired up");
const auto& ep = _parent.local_deprecated_loki_endpoint();
if (not ep)
{
log::error(logcat, "no deprecated endpoint");
handshaker.fail("no deprecated endpoint");
return;
}
_parent.wakeup_send->Trigger();
auto timeout = ep->PathAlignmentTimeout();
log::info(logcat, "ensure flow to {}", flow_info.dst);
ep->MarkAddressOutbound(to_addr_variant(flow_info.dst));
auto ok = ep->EnsurePathTo(
to_addr_variant(flow_info.dst), deprecated_path_ensure_handler{*this, handshaker}, timeout);
if (ok)
return;
log::info(
logcat,
"failed to establish flow to {}: llarp::service::EnsurePathTo() failed",
flow_info.dst);
handshaker.fail("service::EnsurePathTo() failed");
}
void
FlowIdentity::send_to_remote(std::vector<byte_t>, FlowDataKind)
{}
FlowIdentity::send_to_remote(std::vector<byte_t> data, FlowDataKind kind)
{
_parent.wakeup_send->Trigger();
auto sz = data.size();
log::trace(logcat, "send {} bytes of {} on {}", sz, kind, flow_info);
auto ok = _parent.local_deprecated_loki_endpoint()->send_to_or_queue(
to_addr_variant(flow_info.dst), std::move(data), to_proto_type(kind));
if (not ok)
log::warning(logcat, "failed to send {} bytes of {} on {}", sz, kind, flow_info);
}
} // namespace llarp::layers::flow

View file

@ -47,6 +47,8 @@ namespace llarp::layers::flow
mutable dht::Key_t _derived_pubkey;
};
struct deprecated_path_ensure_handler;
/// the local end of a one to one flow to a remote given a flow isolation metric (flow_tag)
/// flows do not change their source/destination address or their flow tag/convo tag.
/// note: historically path handovers were allowed, but going forward this is discontinued.
@ -54,23 +56,23 @@ namespace llarp::layers::flow
{
FlowLayer& _parent;
const FlowIdentityPrivateKeys& _local_privkeys;
/// internal state holder.
/// effectively a pimpl to abstract away .loki vs .snode codepaths.
std::unique_ptr<FlowState_Base> _state;
protected:
friend struct deprecated_path_ensure_handler;
FlowInfo _flow_info;
public:
/// holds the local/remote flow layer address and any flow isolation metric
const FlowInfo flow_info;
const FlowInfo& flow_info{_flow_info};
FlowIdentity(const FlowIdentity&) = delete;
FlowIdentity(FlowIdentity&&) = delete;
FlowIdentity(
FlowLayer& parent,
FlowAddr remote_addr,
FlowTag flow_tag,
const FlowIdentityPrivateKeys& local_keys);
FlowLayer& parent, FlowAddr remote_addr, const FlowIdentityPrivateKeys& local_keys);
/// ensure we have a flow to the remote endpoint.
/// pass in a handshaker to do any additional steps after establishment.

View file

@ -13,4 +13,10 @@ namespace llarp::layers::flow
{
return fmt::format("[flow src={} dst={} tag={} mtu={}]", src, dst, tag, int{mtu});
}
service::ConvoTag
FlowInfo::convo_tag() const
{
return service::ConvoTag{tag.as_array()};
}
} // namespace llarp::layers::flow

View file

@ -4,6 +4,8 @@
#include "flow_tag.hpp"
#include "flow_constants.hpp"
#include <llarp/service/convotag.hpp>
namespace llarp::layers::flow
{
@ -24,6 +26,9 @@ namespace llarp::layers::flow
std::string
ToString() const;
service::ConvoTag
convo_tag() const;
bool
operator==(const FlowInfo& other) const;
};

View file

@ -66,12 +66,13 @@ namespace llarp::layers::flow
/// cycle.
struct flow_layer_waker
{
path::PathContext& paths;
FlowLayer& flow_layer;
void
operator()()
{
flow_layer.local_deprecated_loki_endpoint()->Pump(time_now_ms());
// take the things we need to send out on paths and send them out.
paths.PumpUpstream();
flow_layer.router.pathContext().PumpUpstream();
}
};
@ -80,7 +81,7 @@ namespace llarp::layers::flow
, _privkeys{FlowIdentityPrivateKeys::keygen()}
, _name_cache{}
, _deprecated_endpoint{std::make_shared<service::Endpoint>(r)}
, _wakeup_send{r.loop()->make_waker(flow_layer_waker{r.pathContext()})}
, _wakeup_send{r.loop()->make_waker(flow_layer_waker{*this})}
, _wakeup_recv{r.loop()->make_waker(platform_layer_waker{*this})}
, name_resolver{_name_cache, *this}
, router{r}
@ -118,12 +119,26 @@ namespace llarp::layers::flow
log::info(logcat, "flow layer up");
}
void
FlowLayer::tick()
{
if (_deprecated_endpoint)
{
log::trace(logcat, "tick");
_deprecated_endpoint->Tick(router.Now());
}
log::trace(logcat, "ticked");
}
void
FlowLayer::stop()
{
log::info(logcat, "flow layer stopping");
if (not _deprecated_endpoint->Stop())
throw std::runtime_error{"deprecated endpoint did not stop"};
if (_deprecated_endpoint)
{
if (not _deprecated_endpoint->Stop())
throw std::runtime_error{"deprecated endpoint did not stop"};
}
}
void
@ -202,12 +217,11 @@ namespace llarp::layers::flow
std::shared_ptr<FlowIdentity>
FlowLayer::flow_to(const FlowAddr& addr)
{
for (auto& local_flow : _local_flows)
for (const auto& local_flow : _local_flows)
{
if (local_flow->flow_info.dst == addr)
return local_flow;
}
return _local_flows.emplace_back(
std::make_shared<FlowIdentity>(*this, addr, unique_flow_tag(), _privkeys));
return _local_flows.emplace_back(std::make_shared<FlowIdentity>(*this, addr, _privkeys));
}
} // namespace llarp::layers::flow

View file

@ -104,6 +104,9 @@ namespace llarp::layers::flow
void
stop();
void
tick();
NameResolver name_resolver;
AbstractRouter& router;

View file

@ -9,6 +9,8 @@
namespace llarp::layers::flow
{
static auto logcat = log::Cat("flow-layer");
NameResolver::NameResolver(NameCache& name_cache, FlowLayer& parent)
: _name_cache{name_cache}, _parent{parent}
{}
@ -18,7 +20,7 @@ namespace llarp::layers::flow
std::string name, std::function<void(std::optional<FlowAddr>)> result_handler)
{
_parent.local_deprecated_loki_endpoint()->LookupNameAsync(
name, [result_handler = std::move(result_handler)](auto maybe_addr) {
name, [result_handler = std::move(result_handler), name](auto maybe_addr) {
if (not maybe_addr)
{
result_handler(std::nullopt);

View file

@ -43,4 +43,23 @@ namespace llarp::layers
flow->stop();
onion->stop();
}
Layers::~Layers()
{
if (platform)
platform->stop();
if (flow)
flow->stop();
if (onion)
onion->stop();
}
util::StatusObject
Layers::deprecated_status() const
{
util::StatusObject obj{};
obj["exitMap"] = platform->addr_mapper.exit_map().ExtractStatus();
return obj;
}
} // namespace llarp::layers

View file

@ -4,7 +4,10 @@
#include <llarp/layers/flow/flow_layer.hpp>
#include <llarp/layers/route/route_layer.hpp>
#include <llarp/layers/onion/onion_layer.hpp>
#include <llarp/util/status.hpp>
#include <memory>
namespace llarp
{
// forward declare
@ -34,6 +37,12 @@ namespace llarp::layers
void
stop_all() const;
~Layers();
/// dump debug status.
util::StatusObject
deprecated_status() const;
};
/// this lets us hide which implementation we are using durring the refactor

View file

@ -7,16 +7,12 @@
#include <stdexcept>
#include <vector>
#include <llarp/layers/flow/flow_layer.hpp>
#include "llarp/layers/flow/flow_addr.hpp"
#include "llarp/layers/flow/flow_info.hpp"
#include "llarp/layers/platform/platform_addr.hpp"
#include "llarp/layers/platform/platform_layer.hpp"
#include "llarp/net/ip_range.hpp"
#include "llarp/net/net_int.hpp"
namespace llarp::layers::platform
{
static auto logcat = log::Cat("platform-layer");
AddressMapping&
AddressMappingEntry::access()
{
@ -52,6 +48,18 @@ namespace llarp::layers::platform
return std::find(owned_ranges.begin(), owned_ranges.end(), range) != std::end(owned_ranges);
}
bool
AddressMappingEntry::routes_addr(const PlatformAddr& dst) const
{
for (const auto& range : _entry.owned_ranges)
{
log::trace(logcat, "check range {} owns {}", range, dst);
if (range.Contains(dst.ip))
return true;
}
return false;
}
std::string
AddressMapping::ToString() const
{
@ -129,7 +137,8 @@ namespace llarp::layers::platform
{
for (auto& ent : _addrs)
{
if (ent.has_addr(src, dst))
log::trace(logcat, "check {}", ent.view());
if (ent.has_addr(src, dst) or ent.routes_addr(dst))
return ent.access();
}
return std::nullopt;
@ -140,7 +149,7 @@ namespace llarp::layers::platform
{
std::vector<AddressMapping> exits;
view_all_entries([&exits](const auto& ent) {
if (not ent.owned_ranges.empty())
if (ent.is_exit())
exits.emplace_back(ent);
return true;
});
@ -233,6 +242,12 @@ namespace llarp::layers::platform
return mappings;
}
bool
AddressMapping::is_exit() const
{
return not owned_ranges.empty();
}
} // namespace llarp::layers::platform
namespace llarp

View file

@ -33,6 +33,9 @@ namespace llarp::layers::platform
std::string
ToString() const;
bool
is_exit() const;
};
/// container that holds an addressmapping and extra metadata we need in the addrmapper.
@ -48,6 +51,10 @@ namespace llarp::layers::platform
bool
has_addr(const PlatformAddr& src, const PlatformAddr& dst) const;
/// return true if we can route to this destination address.
bool
routes_addr(const PlatformAddr& dst) const;
/// return true if this entry is for this flow info.
bool
has_flow_info(const flow::FlowInfo& flow_info) const;

View file

@ -1,11 +1,7 @@
#include "platform_layer.hpp"
#include "dns_bridge.hpp"
#include "llarp/layers/flow/flow_addr.hpp"
#include "llarp/layers/platform/addr_mapper.hpp"
#include "llarp/layers/platform/platform_addr.hpp"
#include "llarp/net/ip_packet.hpp"
#include "llarp/net/ip_range.hpp"
#include "oxen/log.hpp"
#include <llarp/config/config.hpp>
#include <llarp/ev/ev.hpp>
@ -22,6 +18,8 @@
#include <stdexcept>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
namespace llarp::layers::platform
@ -83,8 +81,9 @@ namespace llarp::layers::platform
OSTraffic_IO_Base::attach(
std::shared_ptr<vpn::NetworkInterface> netif, std::shared_ptr<EventLoopWakeup> wakeup_recv)
{
log::debug(logcat, "attach OSTraffic_IO_Base to {}", netif->Info().ifname);
_netif = std::move(netif);
log::debug(logcat, "attach OSTraffic_IO_Base to {}", _netif->Info().ifname);
_our_addr = PlatformAddr{_netif->Info().addrs[0].range.addr};
// set up event loop reader.
@ -278,6 +277,82 @@ namespace llarp::layers::platform
, addr_mapper{_netconf.ifaddr(router.Net())}
{}
/// a functor that will try to map exits that are not currently mapped.
struct map_initial_exits : std::enable_shared_from_this<map_initial_exits>
{
PlatformLayer& plat;
net::IPRangeMap<std::string> exits;
std::unordered_map<std::string, service::AuthInfo> auths;
std::unordered_set<std::string> pending;
explicit map_initial_exits(PlatformLayer& _plat)
: plat{_plat}, exits{_plat._netconf.m_LNSExitMap}, auths{_plat._netconf.m_LNSExitAuths}
{
const auto& netconf = _plat._netconf;
for (const auto& [addr, auth] : netconf.m_ExitAuths)
auths[fmt::format("{}", addr)] = auth;
netconf.m_ExitMap.ForEachEntry([this](const auto& range, const auto& addr) {
exits.Insert(range, fmt::format("{}", addr));
});
}
void
operator()()
{
if (exits.Empty() and pending.empty())
{
// die if we have nothing left to do.
_self.reset();
return;
}
exits.ForEachEntry([this](const auto& range, const auto& exit) {
const auto& auth = auths[exit];
auto [itr, inserted] = pending.emplace(exit);
if (inserted)
{
log::info(logcat, "map {} via {}", range, exit);
plat.map_exit(
exit,
auth.token,
std::vector{range},
[this, exit = exit, range = range](bool ok, auto msg) {
on_result(ok, msg, exit, range);
});
}
});
}
void
keep_alive()
{
_self = shared_from_this();
}
private:
void
on_result(bool ok, std::string msg, std::string exit, IPRange range)
{
pending.erase(exit);
if (ok)
{
log::info(logcat, "got exit from {}: {}", exit, msg);
exits.RemoveIf([entry = std::make_pair(range, exit)](auto itr) { return itr == entry; });
}
else
log::info(logcat, "failed to map exit {}: {}", exit, msg);
}
/// a copy of itself, cleared to destroy itself.
std::shared_ptr<map_initial_exits> _self;
};
void
PlatformLayer::start()
{
@ -303,6 +378,10 @@ namespace llarp::layers::platform
// attach vpn interface to dns and start it.
if (const auto& dns = _router.get_dns())
dns->Start(netif->Info().index);
auto mapper = std::make_shared<map_initial_exits>(*this);
_router.loop()->call_every(500ms, mapper, *mapper);
mapper->keep_alive();
}
void
@ -310,7 +389,8 @@ namespace llarp::layers::platform
{
log::info(logcat, "stop");
// stop all io operations on our end and detach from event loop.
_io->detach();
if (_io)
_io->detach();
}
/// handles when we have established a flow with a remote.
@ -323,7 +403,11 @@ namespace llarp::layers::platform
void
fail(std::string error_reason) const
{
result_handler(std::nullopt, "could not obtain flow to '{}': {}"_format(name, error_reason));
std::string msg{"could not obtain flow to '{}': {}"_format(name, error_reason)};
log::info(logcat, msg);
mapper.remove_if_mapping(
[this](const auto& other) { return entry.src == other.src and entry.dst == other.dst; });
result_handler(std::nullopt, msg);
}
void
@ -331,7 +415,7 @@ namespace llarp::layers::platform
{
entry.flow_info = flow_info;
mapper.put(std::move(entry));
log::info(logcat, "flow established on: {}", flow_info);
result_handler(flow_info, "");
}
@ -358,9 +442,12 @@ namespace llarp::layers::platform
{
if (not maybe_addr)
{
flow_establisher.fail("failed to resolve name");
std::string msg{"failed to resolve name '{}'"_format(name)};
log::info(logcat, msg);
flow_establisher.fail(msg);
return;
}
log::info(logcat, "resolved {} to {}", name, *maybe_addr);
// get a flow tag for this remote.
flow_layer.flow_to(*maybe_addr)->async_ensure_flow(std::move(flow_establisher));
}
@ -379,13 +466,12 @@ namespace llarp::layers::platform
result_handler(std::nullopt, "address map full");
return;
}
// reserve a mapping.
AddressMapping mapping = addr_mapper.allocate_mapping(src.value_or(_io->our_platform_addr()));
// reserve a mapping. dst is set even if it is an exit.
auto& mapping = addr_mapper.allocate_mapping(src);
mapping.owned_ranges = std::move(dst_ranges);
// call this when we got a flow to the guy
// it will wire up the mapping.
got_flow_handler got_flow{addr_mapper, std::move(mapping), name, std::move(result_handler)};
// call this when we got a flow to the remote.
got_flow_handler got_flow{addr_mapper, mapping, name, std::move(result_handler)};
// do any extra handshaking with a flow handshaker, then call the got flow handler
// todo: this really belongs in flow layer.
@ -422,19 +508,21 @@ namespace llarp::layers::platform
struct map_exit_handler
{
AbstractRouter& router;
std::function<void(bool, std::string)> result_handler;
void
operator()(std::optional<flow::FlowInfo> found, std::string msg) const
{
if (found)
{
// found the result, put firewall up.
log::info(logcat, "got exit {}: '{}'", found->dst, msg);
// found the result, put firewallup.
if (const auto& poker = router.routePoker())
poker->Up();
result_handler(true, std::move(msg));
return;
}
log::info(logcat, "exit not made: {}", msg);
result_handler(false, std::move(msg));
}
};
@ -446,6 +534,8 @@ namespace llarp::layers::platform
std::vector<IPRange> ranges,
std::function<void(bool, std::string)> result_handler)
{
log::info(logcat, "map exit {}", name);
map_remote(
std::move(name),
std::move(auth),
@ -457,6 +547,7 @@ namespace llarp::layers::platform
void
PlatformLayer::unmap_all_exits_on_range(IPRange range)
{
log::info(logcat, "unmap all on {}", range);
addr_mapper.remove_if_mapping(
[range](const auto& mapping) -> bool { return mapping.owns_range(range); });
}
@ -464,6 +555,12 @@ namespace llarp::layers::platform
void
PlatformLayer::unmap_exit(flow::FlowAddr addr, std::optional<IPRange> range)
{
std::optional<std::string> range_str;
if (range)
range_str = range->ToString();
log::info(logcat, "unmap {} via {}", addr, range_str.value_or("all"));
addr_mapper.remove_if_mapping([addr, range](const auto& mapping) -> bool {
return mapping.flow_info and mapping.flow_info->dst == addr
and (range ? mapping.owns_range(*range) : true);
@ -473,7 +570,13 @@ namespace llarp::layers::platform
PlatformStats
PlatformLayer::current_stats() const
{
return PlatformStats{};
PlatformStats st{};
addr_mapper.view_all_entries([&](const auto& ent) {
st.addrs.emplace_back(ent, _flow_layer);
return true;
});
return st;
}
DNSZone&

View file

@ -111,12 +111,14 @@ namespace llarp::layers::platform
};
struct platform_io_wakeup_handler;
struct map_initial_exits;
/// responsible for bridging the os and the flow layer.
class PlatformLayer
{
protected:
friend struct platform_io_wakeup_handler;
friend struct map_initial_exits;
AbstractRouter& _router;
flow::FlowLayer& _flow_layer;

View file

@ -1,4 +1,46 @@
#include "platform_stats.hpp"
#include "addr_mapper.hpp"
#include "llarp/layers/flow/flow_layer.hpp"
#include "platform_layer.hpp"
namespace llarp::layers::platform
{}
{
/// return true if we want to use an exit.
bool
PlatformStats::wants_client_exit() const
{
for (const auto& addr : addrs)
{
if (addr.is_exit())
return true;
}
return false;
}
/// return true if we want an exit and have one ready.
bool
PlatformStats::client_exit_ready() const
{
for (const auto& addr : addrs)
{
if (addr.is_exit() and addr.is_ready())
return true;
}
return false;
}
namespace stats
{
AddrInfo::AddrInfo(const AddressMapping& ent, const flow::FlowLayer& flow)
: addr{ent}, _flags{0}
{
if (ent.is_exit())
_flags |= _mask_exit;
if (ent.flow_info and flow.has_flow(*ent.flow_info))
_flags |= _mask_ready;
}
} // namespace stats
} // namespace llarp::layers::platform

View file

@ -1,12 +1,81 @@
#pragma once
#include <cstdint>
#include <unordered_set>
#include <llarp/layers/flow/flow_addr.hpp>
#include <llarp/net/ip_range_map.hpp>
#include "addr_mapper.hpp"
#include "platform_addr.hpp"
namespace llarp::layers::flow
{
class FlowLayer;
}
namespace llarp::layers::platform
{
namespace stats
{
struct AddrInfo
{
AddressMapping addr;
AddrInfo(const AddressMapping& ent, const flow::FlowLayer& flow_layer);
constexpr bool
is_exit() const
{
return flag(_mask_exit);
}
constexpr bool
is_ready() const
{
return flag(_mask_ready) and is_authenticated();
}
constexpr bool
is_authenticated() const
{
if (not flag(_mask_auth_required))
return true;
return flag(_mask_auth_ok);
}
private:
/// the underlying flow is ready to do io
static inline constexpr auto _mask_ready{1 << 0};
/// we are required to do auth with this remote.
static inline constexpr auto _mask_auth_required{1 << 1};
static inline constexpr auto _mask_auth_ok{1 << 2};
static inline constexpr auto _mask_inbound{1 << 3};
static inline constexpr auto _mask_exit{1 << 4};
constexpr bool
flag(int mask) const
{
return _flags & mask;
}
int _flags{};
};
} // namespace stats
struct PlatformStats
{};
{
/// flow addr / platform addr mappings that we have allocated.
std::vector<stats::AddrInfo> addrs;
/// return true if we want to use an exit.
bool
wants_client_exit() const;
/// return true if we want an exit and have one ready.
bool
client_exit_ready() const;
};
} // namespace llarp::layers::platform

View file

@ -327,6 +327,8 @@ namespace llarp
return false;
if (BuildCooldownHit(now))
return false;
if (m_router->NumberOfConnectedRouters() == 0)
return false;
return PathSet::ShouldBuildMore(now);
}

View file

@ -107,11 +107,15 @@ namespace llarp
if (not _running)
util::StatusObject{{"running", false}};
auto services = json::object();
services["default"] = get_layers()->deprecated_status();
return util::StatusObject{
{"running", true},
{"numNodesKnown", _nodedb->NumLoaded()},
{"dht", _dht->impl->ExtractStatus()},
{"services", json::object()},
{"services", std::move(services)},
{"exit", json::object()},
{"links", _linkManager.ExtractStatus()},
{"outboundMessages", _outboundMessageHandler.ExtractStatus()}};

View file

@ -100,10 +100,13 @@ namespace llarp
const auto itr = conf.m_LNSExitAuths.find(name);
if (itr != conf.m_LNSExitAuths.end())
auth = itr->second;
LogInfo("map ", range, " to ", name);
m_StartupLNSMappings[name] = std::make_pair(range, auth);
});
return m_state->Configure(conf);
if (not m_state->Configure(conf))
return false;
return LoadKeyFile();
}
bool
@ -440,21 +443,22 @@ namespace llarp
{
for (const auto& item : m_StartupLNSMappings)
{
LogInfo("look up ", item.first, " as exit");
LookupNameAsync(
item.first, [name = item.first, info = item.second, this](auto maybe_addr) {
if (maybe_addr.has_value())
{
const auto maybe_range = info.first;
const auto maybe_auth = info.second;
if (not maybe_addr)
return;
const auto maybe_range = info.first;
const auto maybe_auth = info.second;
m_StartupLNSMappings.erase(name);
if (auto* addr = std::get_if<service::Address>(&*maybe_addr))
{
if (maybe_range.has_value())
m_ExitMap.Insert(*maybe_range, *addr);
if (maybe_auth.has_value())
SetAuthInfoForEndpoint(*addr, *maybe_auth);
}
m_StartupLNSMappings.erase(name);
if (auto* addr = std::get_if<service::Address>(&*maybe_addr))
{
LogInfo(name, " resolved to ", addr->ToString());
if (maybe_range)
m_ExitMap.Insert(*maybe_range, *addr);
if (maybe_auth)
SetAuthInfoForEndpoint(*addr, *maybe_auth);
}
});
}
@ -1030,7 +1034,7 @@ namespace llarp
{
for (const auto& [name, info] : m_StartupLNSMappings)
{
if (info.first.has_value())
if (info.first)
return true;
}

View file

@ -17,6 +17,7 @@ namespace llarp::service
Exit = 3UL,
Auth = 4UL,
QUIC = 5UL,
DirectTraffic = 6UL,
};
@ -24,13 +25,14 @@ namespace llarp::service
ToString(ProtocolType t)
{
using namespace std::literals;
return t == ProtocolType::Control ? "Control"sv
: t == ProtocolType::TrafficV4 ? "TrafficV4"sv
: t == ProtocolType::TrafficV6 ? "TrafficV6"sv
: t == ProtocolType::Exit ? "Exit"sv
: t == ProtocolType::Auth ? "Auth"sv
: t == ProtocolType::QUIC ? "QUIC"sv
: "(unknown-protocol-type)"sv;
return t == ProtocolType::Control ? "Control"sv
: t == ProtocolType::DirectTraffic ? "Traffic"sv
: t == ProtocolType::TrafficV4 ? "TrafficV4"sv
: t == ProtocolType::TrafficV6 ? "TrafficV6"sv
: t == ProtocolType::Exit ? "Exit"sv
: t == ProtocolType::Auth ? "Auth"sv
: t == ProtocolType::QUIC ? "QUIC"sv
: "(unknown-protocol-type)"sv;
}
} // namespace llarp::service