ALPN verification

- laying the groundwork for functional client->service node connections. this requires ALPNs verification as a secondary method of identification to the remote key
- refactored btreq stream creation to use improved stream creation logic in libquic
pull/2232/head
dr7ana 5 months ago
parent 0e73605ffd
commit 3e9d5a97a8

@ -214,7 +214,7 @@ namespace llarp::exit
BaseSession::HandleTrafficDrop(llarp::path::Path_ptr p, const PathID_t& path, uint64_t s)
{
llarp::LogError("dropped traffic on exit ", exit_router, " S=", s, " P=", path);
p->EnterState(path::ePathIgnore, router->now());
p->EnterState(path::IGNORE, router->now());
return true;
}
@ -238,7 +238,7 @@ namespace llarp::exit
{
if (BuildCooldownHit(now))
return false;
if (IsReady() and NumInStatus(path::ePathBuilding) < numDesiredPaths)
if (IsReady() and NumInStatus(path::BUILDING) < numDesiredPaths)
return path::Builder::UrgentBuild(now);
return false;
}

@ -21,10 +21,16 @@ namespace llarp
{
namespace link
{
Endpoint::Endpoint(std::shared_ptr<oxen::quic::Endpoint> ep, LinkManager& lm)
: endpoint{std::move(ep)}
, link_manager{lm}
, _is_service_node{link_manager.is_service_node()}
{}
std::shared_ptr<link::Connection>
Endpoint::get_conn(const RemoteRC& rc) const
{
if (auto itr = active_conns.find(rc.router_id()); itr != active_conns.end())
if (auto itr = service_conns.find(rc.router_id()); itr != service_conns.end())
return itr->second;
// if (auto itr = pending_conns.find(rc.router_id()); itr != pending_conns.end())
@ -36,7 +42,7 @@ namespace llarp
std::shared_ptr<link::Connection>
Endpoint::get_conn(const RouterID& rid) const
{
if (auto itr = active_conns.find(rid); itr != active_conns.end())
if (auto itr = service_conns.find(rid); itr != service_conns.end())
return itr->second;
// if (auto itr = pending_conns.find(rid); itr != pending_conns.end())
@ -48,7 +54,7 @@ namespace llarp
bool
Endpoint::have_client_conn(const RouterID& remote) const
{
if (auto itr = active_conns.find(remote); itr != active_conns.end())
if (auto itr = service_conns.find(remote); itr != service_conns.end())
{
return not itr->second->remote_is_relay;
}
@ -64,7 +70,7 @@ namespace llarp
bool
Endpoint::have_conn(const RouterID& remote) const
{
return active_conns.count(remote) or pending_conns.count(remote);
return service_conns.count(remote) or pending_conns.count(remote);
}
std::pair<size_t, size_t>
@ -72,7 +78,7 @@ namespace llarp
{
size_t in{0}, out{0};
for (const auto& c : active_conns)
for (const auto& c : service_conns)
{
if (c.second->inbound)
++in;
@ -88,7 +94,7 @@ namespace llarp
{
size_t count = 0;
for (const auto& c : active_conns)
for (const auto& c : service_conns)
{
if (not(c.second->remote_is_relay and clients_only))
count += 1;
@ -100,9 +106,9 @@ namespace llarp
bool
Endpoint::get_random_connection(RemoteRC& router) const
{
if (const auto size = active_conns.size(); size)
if (const auto size = service_conns.size(); size)
{
auto itr = active_conns.begin();
auto itr = service_conns.begin();
std::advance(itr, randint() % size);
RouterID rid{itr->second->conn->remote_key()};
@ -123,7 +129,7 @@ namespace llarp
void
Endpoint::for_each_connection(std::function<void(link::Connection&)> func)
{
for (const auto& [rid, conn] : active_conns)
for (const auto& [rid, conn] : service_conns)
func(*conn);
}
@ -134,7 +140,7 @@ namespace llarp
link_manager._router.loop()->call([this, rid = _rid]() {
// deletion from pending_conns, pending_conn_msg_queue, active_conns, etc is taken care
// of by LinkManager::on_conn_closed
if (auto itr = active_conns.find(rid); itr != active_conns.end())
if (auto itr = service_conns.find(rid); itr != service_conns.end())
{
auto& conn = *itr->second->conn;
conn.close_connection();
@ -195,7 +201,7 @@ namespace llarp
_router.loop()->call([this, msg = std::move(m), func = std::move(func)]() mutable {
auto body = msg.body_str();
auto respond = [m = std::move(msg)](std::string response) mutable {
m.respond(std::move(response), not m);
m.respond(std::move(response), m.is_error());
};
std::invoke(func, this, body, std::move(respond));
});
@ -207,6 +213,7 @@ namespace llarp
LinkManager::LinkManager(Router& r)
: _router{r}
, _is_service_node{_router.is_service_node()}
, quic{std::make_unique<oxen::quic::Network>()}
, tls_creds{oxen::quic::GNUTLSCreds::make_from_ed_keys(
{reinterpret_cast<const char*>(_router.identity().data()), size_t{32}},
@ -239,20 +246,44 @@ namespace llarp
[this](oxen::quic::connection_interface& ci, uint64_t ec) {
return on_conn_closed(ci, ec);
},
[this](oxen::quic::dgram_interface& di, bstring dgram) { recv_data_message(di, dgram); });
tls_creds->set_key_verify_callback([this](const ustring_view& key, const ustring_view&) {
[this](oxen::quic::dgram_interface& di, bstring dgram) { recv_data_message(di, dgram); },
is_service_node() ? alpns::SERVICE_INBOUND : alpns::CLIENT_INBOUND,
is_service_node() ? alpns::SERVICE_OUTBOUND : alpns::CLIENT_OUTBOUND);
tls_creds->set_key_verify_callback([this](const ustring_view& key, const ustring_view& alpn) {
auto is_snode = is_service_node();
RouterID other{key.data()};
bool result = node_db->registered_routers().count(other);
auto us = router().is_bootstrap_seed() ? "Bootstrap seed node"s : "Service node"s;
log::critical(
logcat,
"{} node was {} to confirm remote (RID:{}) is registered; allowing connection!",
router().is_bootstrap_seed() ? "Bootstrap seed node" : "Service node",
result ? "able" : "unable",
other);
if (is_snode)
{
if (alpn == alpns::C_ALPNS)
{
log::critical(logcat, "{} node accepting client connection (remote ID:{})!", us, other);
return true;
}
if (alpn == alpns::SN_ALPNS)
{
// verify as service node!
bool result = node_db->registered_routers().count(other);
log::critical(
logcat,
"{} node was {} to confirm remote (RID:{}) is registered; allowing connection!",
us,
result ? "able" : "unable",
other);
return result;
}
return result;
log::critical(logcat, "{} node received unknown ALPN; rejecting connection!", us);
return false;
}
throw std::runtime_error{"Clients should not be validating inbound connections!"};
});
if (_router.is_service_node())
{
@ -266,18 +297,19 @@ namespace llarp
{
const auto& scid = ci.scid();
RouterID rid{ci.remote_key()};
ep.connid_map.emplace(scid, rid);
auto [itr, b] = ep.active_conns.emplace(rid, nullptr);
ep.service_connid_map.emplace(scid, rid);
auto [itr, b] = ep.service_conns.emplace(rid, nullptr);
log::critical(logcat, "Queueing BTStream to be opened...");
auto control_stream = ci.queue_stream<oxen::quic::BTRequestStream>([this, rid = rid](
oxen::quic::Stream&,
uint64_t error_code) {
log::warning(
logcat, "BTRequestStream closed unexpectedly (ec:{}); closing connection...", error_code);
ep.close_connection(rid);
});
auto control_stream = ci.queue_incoming_stream<oxen::quic::BTRequestStream>(
[this, rid = rid](oxen::quic::Stream&, uint64_t error_code) {
log::warning(
logcat,
"BTRequestStream closed unexpectedly (ec:{}); closing connection...",
error_code);
ep.close_connection(rid);
});
log::critical(logcat, "Queued BTStream to be opened ID:{}", control_stream->stream_id());
assert(control_stream->stream_id() == 0);
@ -307,8 +339,8 @@ namespace llarp
if (auto itr = ep.pending_conns.find(rid); itr != ep.pending_conns.end())
{
ep.connid_map.emplace(scid, rid);
auto [it, b] = ep.active_conns.emplace(rid, nullptr);
ep.service_connid_map.emplace(scid, rid);
auto [it, b] = ep.service_conns.emplace(rid, nullptr);
it->second = std::move(itr->second);
ep.pending_conns.erase(itr);
@ -338,7 +370,7 @@ namespace llarp
if (msg.is_control)
{
log::critical(logcat, "Dispatching {} request!", *msg.endpoint);
ep.active_conns[rid]->control_stream->command(
ep.service_conns[rid]->control_stream->command(
std::move(*msg.endpoint), std::move(msg.body), std::move(msg.func));
}
else
@ -373,15 +405,16 @@ namespace llarp
log::critical(quic_cat, "Pending quic connection CID:{} purged successfully", scid);
}
else if (const auto& c_itr = ep.connid_map.find(scid); c_itr != ep.connid_map.end())
else if (const auto& c_itr = ep.service_connid_map.find(scid);
c_itr != ep.service_connid_map.end())
{
const auto& rid = c_itr->second;
assert(_rid == rid); // this should hold true
if (auto m_itr = ep.active_conns.find(rid); m_itr != ep.active_conns.end())
ep.active_conns.erase(m_itr);
if (auto m_itr = ep.service_conns.find(rid); m_itr != ep.service_conns.end())
ep.service_conns.erase(m_itr);
ep.connid_map.erase(c_itr);
ep.service_connid_map.erase(c_itr);
log::critical(quic_cat, "Quic connection CID:{} purged successfully", scid);
}
@ -604,7 +637,7 @@ namespace llarp
bool
LinkManager::is_service_node() const
{
return _router.is_service_node();
return _is_service_node;
}
// TODO: this? perhaps no longer necessary in the same way?
@ -660,12 +693,12 @@ namespace llarp
}
void
LinkManager::gossip_rc(
const RouterID& gossip_src, const RouterID& last_sender, std::string serialized_rc)
LinkManager::gossip_rc(const RouterID& last_sender, const RemoteRC& rc)
{
int count = 0;
const auto& gossip_src = rc.router_id();
for (auto& [rid, conn] : ep.active_conns)
for (auto& [rid, conn] : ep.service_conns)
{
// don't send back to the gossip source or the last sender
if (rid == gossip_src or rid == last_sender)
@ -678,7 +711,7 @@ namespace llarp
send_control_message(
rid,
"gossip_rc"s,
GossipRCMessage::serialize(gossip_src, last_sender, serialized_rc),
GossipRCMessage::serialize(last_sender, rc),
[](oxen::quic::message) mutable {
log::critical(logcat, "PLACEHOLDER FOR GOSSIP RC RESPONSE HANDLER");
});
@ -704,7 +737,6 @@ namespace llarp
btdc.required("rc");
rc = RemoteRC{btdc.consume_dict_data()};
src.from_string(btdc.require<std::string>("sender"));
sender.from_string(btdc.require<std::string>("src"));
}
catch (const std::exception& e)
{
@ -715,7 +747,7 @@ namespace llarp
if (node_db->verify_store_gossip_rc(rc))
{
log::critical(link_cat, "Received updated RC, forwarding to relay peers.");
gossip_rc(src, _router.local_rid(), std::string{rc.view()});
gossip_rc(_router.local_rid(), rc);
}
else
log::critical(link_cat, "Received known or old RC, not storing or forwarding.");
@ -934,7 +966,7 @@ namespace llarp
"fetch_router_ids"s,
m.body_str(),
[source_rid = std::move(source), original = std::move(m)](oxen::quic::message m) mutable {
original.respond(m.body_str(), not m);
original.respond(m.body_str(), m.is_error());
});
return;
}
@ -994,9 +1026,9 @@ namespace llarp
void
LinkManager::handle_find_name_response(oxen::quic::message m)
{
if (not m)
if (m.timed_out)
{
log::info(link_cat, "FindNameMessage failed!");
log::info(link_cat, "FindNameMessage request timed out!");
return;
}
@ -1130,7 +1162,7 @@ namespace llarp
"publish_intro",
PublishIntroMessage::serialize(introset, relay_order, is_relayed),
[respond = std::move(respond)](oxen::quic::message m) {
if (not m)
if (m.timed_out)
return; // drop if timed out; requester will have timed out as well
respond(m.body_str());
});
@ -1165,10 +1197,13 @@ namespace llarp
addr);
}
// DISCUSS: I feel like ::handle_publish_intro_response should be the callback that handles the
// response to a relayed publish_intro (above line 1131-ish)
void
LinkManager::handle_publish_intro_response(oxen::quic::message m)
{
if (not m)
if (m.timed_out)
{
log::info(link_cat, "PublishIntroMessage timed out!");
return;
@ -1271,7 +1306,7 @@ namespace llarp
link_cat,
"Relayed FindIntroMessage returned successful response; transmitting to initial "
"requester");
else if (not relay_response)
else if (relay_response.timed_out)
log::critical(
link_cat, "Relayed FindIntroMessage timed out! Notifying initial requester");
else
@ -1298,7 +1333,7 @@ namespace llarp
void
LinkManager::handle_find_intro_response(oxen::quic::message m)
{
if (not m)
if (m.timed_out)
{
log::info(link_cat, "FindIntroMessage timed out!");
return;
@ -1491,12 +1526,12 @@ namespace llarp
"then relaying response");
_router.path_context().put_transit_hop(hop);
}
if (not m)
if (m.timed_out)
log::info(link_cat, "Upstream timed out on path build; relaying timeout");
else
log::info(link_cat, "Upstream returned path build failure; relaying response");
m.respond(m.body_str(), not m);
m.respond(m.body_str(), m.is_error());
});
}
catch (const std::exception& e)
@ -1608,12 +1643,12 @@ namespace llarp
void
LinkManager::handle_obtain_exit_response(oxen::quic::message m)
{
if (not m)
if (m.timed_out)
{
log::info(link_cat, "ObtainExitMessage timed out!");
return;
}
if (m.is_error)
if (m.is_error())
{
// TODO: what to do here
}
@ -1686,12 +1721,12 @@ namespace llarp
void
LinkManager::handle_update_exit_response(oxen::quic::message m)
{
if (not m)
if (m.timed_out)
{
log::info(link_cat, "UpdateExitMessage timed out!");
return;
}
if (m.is_error)
if (m.is_error())
{
// TODO: what to do here
}
@ -1771,12 +1806,12 @@ namespace llarp
void
LinkManager::handle_close_exit_response(oxen::quic::message m)
{
if (not m)
if (m.timed_out)
{
log::info(link_cat, "CloseExitMessage timed out!");
return;
}
if (m.is_error)
if (m.is_error())
{
// TODO: what to do here
}

@ -34,27 +34,42 @@ namespace llarp
using stream_closed_hook = oxen::quic::stream_close_callback;
using keep_alive = oxen::quic::opt::keep_alive;
using inbound_alpns = oxen::quic::opt::inbound_alpns;
using outbound_alpns = oxen::quic::opt::outbound_alpns;
inline const keep_alive ROUTER_KEEP_ALIVE{10s};
inline const keep_alive CLIENT_KEEP_ALIVE{0s};
namespace alpns
{
inline const auto SN_ALPNS = "SERVICE_NODE"_us;
inline const auto C_ALPNS = "CLIENT"_us;
inline const inbound_alpns SERVICE_INBOUND{{SN_ALPNS, C_ALPNS}};
inline const outbound_alpns SERVICE_OUTBOUND{{SN_ALPNS}};
inline const inbound_alpns CLIENT_INBOUND{};
inline const outbound_alpns CLIENT_OUTBOUND{{C_ALPNS}};
} // namespace alpns
namespace link
{
struct Connection;
struct Endpoint
{
Endpoint(std::shared_ptr<oxen::quic::Endpoint> ep, LinkManager& lm)
: endpoint{std::move(ep)}, link_manager{lm}
{}
Endpoint(std::shared_ptr<oxen::quic::Endpoint> ep, LinkManager& lm);
std::shared_ptr<oxen::quic::Endpoint> endpoint;
LinkManager& link_manager;
// for outgoing packets, we route via RouterID; map RouterID->Connection
// for incoming packets, we get a ConnectionID; map ConnectionID->RouterID
std::unordered_map<RouterID, std::shared_ptr<link::Connection>> active_conns;
std::unordered_map<oxen::quic::ConnectionID, RouterID> connid_map;
std::unordered_map<RouterID, std::shared_ptr<link::Connection>> service_conns;
std::unordered_map<oxen::quic::ConnectionID, RouterID> service_connid_map;
std::unordered_map<RouterID, std::shared_ptr<link::Connection>> client_conns;
std::unordered_map<oxen::quic::ConnectionID, RouterID> client_connid_map;
// for pending connections, cleared in LinkManager::on_conn_open
std::unordered_map<RouterID, std::shared_ptr<link::Connection>> pending_conns;
@ -93,6 +108,7 @@ namespace llarp
close_connection(RouterID rid);
private:
const bool _is_service_node;
};
} // namespace link
@ -198,6 +214,8 @@ namespace llarp
Router& _router;
const bool _is_service_node;
// FIXME: Lokinet currently expects to be able to kill all network functionality before
// finishing other shutdown things, including destroying this class, and that is all in
// Network's destructor, so we need to be able to destroy it before this class.
@ -228,7 +246,7 @@ namespace llarp
public:
const link::Endpoint&
endpoint()
endpoint() const
{
return ep;
}
@ -240,7 +258,7 @@ namespace llarp
}
void
gossip_rc(const RouterID& gossip_src, const RouterID& last_sender, std::string serialized_rc);
gossip_rc(const RouterID& last_sender, const RemoteRC& rc);
void
handle_gossip_rc(oxen::quic::message m);
@ -429,7 +447,7 @@ namespace llarp
// add to pending conns
auto [itr, b] = pending_conns.emplace(rid, nullptr);
auto control_stream = conn_interface->template get_new_stream<oxen::quic::BTRequestStream>(
auto control_stream = conn_interface->template open_stream<oxen::quic::BTRequestStream>(
[this, rid = rid](oxen::quic::Stream&, uint64_t error_code) {
log::warning(
logcat,

@ -9,15 +9,14 @@ namespace llarp
namespace GossipRCMessage
{
inline static std::string
serialize(const RouterID& gossip_src, const RouterID& last_sender, std::string rc)
serialize(const RouterID& last_sender, const RemoteRC& rc)
{
oxenc::bt_dict_producer btdp;
try
{
btdp.append_encoded("rc", rc);
btdp.append_encoded("rc", rc.view());
btdp.append("sender", last_sender.ToView());
btdp.append("src", gossip_src.ToView());
}
catch (...)
{

@ -369,21 +369,21 @@ namespace llarp
src,
FetchRCMessage::serialize(_router.last_rc_fetch, needed),
[this, src, initial](oxen::quic::message m) mutable {
if (not m)
if (m.timed_out)
{
log::info(logcat, "RC fetch to {} failed!", src);
fetch_rcs_result(initial, true);
log::info(logcat, "RC fetch to {} timed out!", src);
fetch_rcs_result(initial, m.timed_out);
return;
}
try
{
oxenc::bt_dict_consumer btdc{m.body()};
// TODO: fix this shit after removing ::timed_out from message type
if (not m)
// TODO: can this just combine with the above failure case...?
if (m.is_error())
{
auto reason = btdc.require<std::string_view>(messages::STATUS_KEY);
log::info(logcat, "RC fetch to {} returned error: {}", src, reason);
fetch_rcs_result(initial, true);
fetch_rcs_result(initial, m.is_error());
return;
}
@ -438,9 +438,11 @@ namespace llarp
src,
FetchRIDMessage::serialize(target),
[this, src, target, initial](oxen::quic::message m) mutable {
if (not m)
if (m.is_error())
{
log::info(link_cat, "RID fetch from {} via {} timed out", src, target);
auto err = "RID fetch from {} via {} {}"_format(
src, target, m.timed_out ? "timed out" : "failed");
log::info(link_cat, err);
ingest_rid_fetch_responses(target);
fetch_rids_result(initial);
return;
@ -796,15 +798,18 @@ namespace llarp
_registered_routers.insert(greylist.begin(), greylist.end());
_registered_routers.insert(greenlist.begin(), greenlist.end());
router_whitelist.clear();
router_whitelist.insert(whitelist.begin(), whitelist.end());
router_greylist.clear();
router_greylist.insert(greylist.begin(), greylist.end());
router_greenlist.clear();
router_greenlist.insert(greenlist.begin(), greenlist.end());
_router_whitelist.clear();
_router_whitelist.insert(whitelist.begin(), whitelist.end());
_router_greylist.clear();
_router_greylist.insert(greylist.begin(), greylist.end());
_router_greenlist.clear();
_router_greenlist.insert(greenlist.begin(), greenlist.end());
log::critical(
logcat, "Service node whitelist now has {} active router RIDs", router_whitelist.size());
logcat,
"Oxend provided {}:{} (whitelist:registered)",
_router_whitelist.size(),
_registered_routers.size());
}
std::optional<RouterID>
@ -812,7 +817,7 @@ namespace llarp
{
std::optional<RouterID> rand = std::nullopt;
std::sample(router_whitelist.begin(), router_whitelist.end(), &*rand, 1, csrng);
std::sample(_router_whitelist.begin(), _router_whitelist.end(), &*rand, 1, csrng);
return rand;
}
@ -826,7 +831,7 @@ namespace llarp
return false;
}
return known_rids.count(remote) or router_greylist.count(remote);
return known_rids.count(remote) or _router_greylist.count(remote);
}
bool

@ -146,9 +146,9 @@ namespace llarp
- gray: fully funded, but decommissioned routers
- green: registered, but not fully-staked routers
*/
std::set<RouterID> router_whitelist{};
std::set<RouterID> router_greylist{};
std::set<RouterID> router_greenlist{};
std::set<RouterID> _router_whitelist{};
std::set<RouterID> _router_greylist{};
std::set<RouterID> _router_greenlist{};
// All registered relays (service nodes)
std::set<RouterID> _registered_routers;
@ -346,13 +346,13 @@ namespace llarp
const std::set<RouterID>&
whitelist() const
{
return known_rids;
return _router_whitelist;
}
const std::set<RouterID>&
greylist() const
{
return router_greylist;
return _router_greylist;
}
std::set<RouterID>&

@ -44,7 +44,7 @@ namespace llarp::path
intro.router = hops[hsz - 1].rc.router_id();
intro.path_id = hops[hsz - 1].txID;
if (auto parent = m_PathSet.lock())
EnterState(ePathBuilding, parent->Now());
EnterState(BUILDING, parent->Now());
}
bool
@ -118,7 +118,7 @@ namespace llarp::path
if ((not self) or (not response_cb))
return;
if (not m)
if (m.timed_out)
{
response_cb(messages::TIMEOUT_RESPONSE);
return;
@ -186,7 +186,7 @@ namespace llarp::path
{
if (Expired(llarp::time_now_ms()))
return false;
return intro.latency > 0s && _status == ePathEstablished;
return intro.latency > 0s && _status == ESTABLISHED;
}
bool
@ -227,12 +227,12 @@ namespace llarp::path
if (now == 0s)
now = router.now();
if (st == ePathFailed)
if (st == FAILED)
{
_status = st;
return;
}
if (st == ePathExpired && _status == ePathBuilding)
if (st == EXPIRED && _status == BUILDING)
{
_status = st;
if (auto parent = m_PathSet.lock())
@ -240,16 +240,16 @@ namespace llarp::path
parent->HandlePathBuildTimeout(shared_from_this());
}
}
else if (st == ePathBuilding)
else if (st == BUILDING)
{
LogInfo("path ", name(), " is building");
buildStarted = now;
}
else if (st == ePathEstablished && _status == ePathBuilding)
else if (st == ESTABLISHED && _status == BUILDING)
{
LogInfo("path ", name(), " is built, took ", ToString(now - buildStarted));
}
else if (st == ePathTimeout && _status == ePathEstablished)
else if (st == TIMEOUT && _status == ESTABLISHED)
{
LogInfo("path ", name(), " died");
_status = st;
@ -258,11 +258,11 @@ namespace llarp::path
parent->HandlePathDied(shared_from_this());
}
}
else if (st == ePathEstablished && _status == ePathTimeout)
else if (st == ESTABLISHED && _status == TIMEOUT)
{
LogInfo("path ", name(), " reanimated");
}
else if (st == ePathIgnore)
else if (st == IGNORE)
{
LogInfo("path ", name(), " ignored");
}
@ -309,22 +309,22 @@ namespace llarp::path
switch (_status)
{
case ePathBuilding:
case BUILDING:
obj["status"] = "building";
break;
case ePathEstablished:
case ESTABLISHED:
obj["status"] = "established";
break;
case ePathTimeout:
case TIMEOUT:
obj["status"] = "timeout";
break;
case ePathExpired:
case EXPIRED:
obj["status"] = "expired";
break;
case ePathFailed:
case FAILED:
obj["status"] = "failed";
break;
case ePathIgnore:
case IGNORE:
obj["status"] = "ignored";
break;
default:
@ -385,7 +385,7 @@ namespace llarp::path
m_RXRate = 0;
m_TXRate = 0;
if (_status == ePathBuilding)
if (_status == BUILDING)
{
if (buildStarted == 0s)
return;
@ -396,13 +396,13 @@ namespace llarp::path
{
LogWarn(name(), " waited for ", ToString(dlt), " and no path was built");
r->router_profiling().MarkPathFail(this);
EnterState(ePathExpired, now);
EnterState(EXPIRED, now);
return;
}
}
}
// check to see if this path is dead
if (_status == ePathEstablished)
if (_status == ESTABLISHED)
{
auto dlt = now - m_LastLatencyTestTime;
if (dlt > path::LATENCY_INTERVAL && m_LastLatencyTestID == 0)
@ -420,13 +420,13 @@ namespace llarp::path
{
LogWarn(name(), " waited for ", ToString(dlt), " and path looks dead");
r->router_profiling().MarkPathFail(this);
EnterState(ePathTimeout, now);
EnterState(TIMEOUT, now);
}
}
if (_status == ePathIgnore and now - m_LastRecvMessage >= path::ALIVE_TIMEOUT)
if (_status == IGNORE and now - m_LastRecvMessage >= path::ALIVE_TIMEOUT)
{
// clean up this path as we dont use it anymore
EnterState(ePathExpired, now);
EnterState(EXPIRED, now);
}
}
@ -436,15 +436,15 @@ namespace llarp::path
bool
Path::Expired(llarp_time_t now) const
{
if (_status == ePathFailed)
if (_status == FAILED)
return true;
if (_status == ePathBuilding)
if (_status == BUILDING)
return false;
if (_status == ePathTimeout)
if (_status == TIMEOUT)
{
return now >= m_LastRecvMessage + PathReanimationTimeout;
}
if (_status == ePathEstablished or _status == ePathIgnore)
if (_status == ESTABLISHED or _status == IGNORE)
{
return now >= ExpireTime();
}

@ -122,7 +122,7 @@ namespace llarp::path
/// current number of paths we created in status
uint64_t
CurrentOwnedPaths(path::PathStatus status = path::PathStatus::ePathEstablished);
CurrentOwnedPaths(path::PathStatus status = path::PathStatus::ESTABLISHED);
Router*
router() const

@ -261,7 +261,7 @@ namespace llarp
const auto now = Now();
for (auto& item : m_Paths)
{
item.second->EnterState(ePathIgnore, now);
item.second->EnterState(IGNORE, now);
}
return true;
}
@ -275,7 +275,7 @@ namespace llarp
bool
Builder::ShouldRemove() const
{
return IsStopped() and NumInStatus(ePathEstablished) == 0;
return IsStopped() and NumInStatus(ESTABLISHED) == 0;
}
bool
@ -505,40 +505,40 @@ namespace llarp
// be worth doing sooner rather than later. Leaving some TODOs below where fail
// and success live.
auto response_cb = [path](oxen::quic::message m) {
if (m)
{
// TODO: inform success (what this means needs revisiting, badly)
path->EnterState(path::ESTABLISHED);
return;
}
try
{
if (m)
// TODO: inform failure (what this means needs revisiting, badly)
if (m.timed_out)
{
// TODO: inform success (what this means needs revisiting, badly)
path->EnterState(path::ePathEstablished);
return;
}
if (not m)
{
log::warning(path_cat, "Path build request failed!");
log::warning(path_cat, "Path build request timed out!");
path->EnterState(path::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);
}
}
catch (const std::exception& e)
{
log::warning(path_cat, "Failed parsing path build response.");
log::warning(path_cat, "Exception caught parsing path build response: {}", e.what());
}
// TODO: inform failure (what this means needs revisiting, badly)
path->EnterState(path::ePathFailed);
};
if (not router->send_control_message(
path->upstream(), "path_build", std::move(frames).str(), std::move(response_cb)))
{
log::warning(path_cat, "Error sending path_build control message");
// TODO: inform failure (what this means needs revisiting, badly)
path->EnterState(path::ePathFailed, router->now());
path->EnterState(path::FAILED, router->now());
}
}

@ -13,10 +13,10 @@ namespace llarp::path
PathSet::ShouldBuildMore(llarp_time_t now) const
{
(void)now;
const auto building = NumInStatus(ePathBuilding);
const auto building = NumInStatus(BUILDING);
if (building >= numDesiredPaths)
return false;
const auto established = NumInStatus(ePathEstablished);
const auto established = NumInStatus(ESTABLISHED);
return established < numDesiredPaths;
}
@ -255,7 +255,7 @@ namespace llarp::path
auto itr = m_Paths.begin();
while (itr != m_Paths.end())
{
if (itr->second->Status() == ePathEstablished && itr->second->SupportsAnyRoles(roles))
if (itr->second->Status() == ESTABLISHED && itr->second->SupportsAnyRoles(roles))
++count;
++itr;
}

@ -47,12 +47,12 @@ namespace llarp
/// status of a path
enum PathStatus
{
ePathBuilding,
ePathEstablished,
ePathTimeout,
ePathFailed,
ePathIgnore,
ePathExpired
BUILDING,
ESTABLISHED,
TIMEOUT,
FAILED,
IGNORE,
EXPIRED
};
/// Stats about all our path builds

@ -873,8 +873,7 @@ namespace llarp
router_contact.resign();
save_rc();
_link_manager->gossip_rc(
local_rid(), local_rid(), std::string{oxen::quic::to_sv(router_contact.view())});
_link_manager->gossip_rc(local_rid(), router_contact.to_remote());
last_rc_gossip = now_timepoint;

@ -299,7 +299,7 @@ namespace llarp::service
// expire convotags
EndpointUtil::ExpireConvoSessions(now, Sessions());
if (NumInStatus(path::ePathEstablished) > 1)
if (NumInStatus(path::ESTABLISHED) > 1)
{
for (const auto& item : _startup_ons_mappings)
{
@ -1539,7 +1539,7 @@ namespace llarp::service
if (BuildCooldownHit(now))
return false;
const auto requiredPaths = std::max(numDesiredPaths, path::MIN_INTRO_PATHS);
if (NumInStatus(path::ePathBuilding) >= requiredPaths)
if (NumInStatus(path::BUILDING) >= requiredPaths)
return false;
return NumPathsExistingAt(now + (path::DEFAULT_LIFETIME - path::INTRO_PATH_SPREAD))
< requiredPaths;

@ -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::ePathIgnore, Now());
p->EnterState(path::IGNORE, Now());
}
else if (p->Endpoint() == next_intro.router)
{
@ -375,7 +375,7 @@ namespace llarp::service
if (marked_bad or path::Builder::BuildCooldownHit(now))
return false;
if (NumInStatus(path::ePathBuilding) >= std::max(numDesiredPaths / size_t{2}, size_t{1}))
if (NumInStatus(path::BUILDING) >= std::max(numDesiredPaths / size_t{2}, size_t{1}))
return false;
size_t numValidPaths = 0;

@ -24,6 +24,11 @@ namespace llarp
using bstring = std::basic_string<std::byte>;
using bstring_view = std::basic_string_view<std::byte>;
inline ustring operator""_us(const char* str, size_t len) noexcept
{
return {reinterpret_cast<const unsigned char*>(str), len};
}
// Helper function to switch between string_view and ustring_view
inline ustring_view
to_usv(std::string_view v)

Loading…
Cancel
Save