fully deprecated old logging

pull/2212/head
dr7ana 6 months ago
parent bf2f367f83
commit d0af37aafc

@ -6,7 +6,6 @@
#include <llarp/address/ip_packet.hpp>
#include <llarp/config/config.hpp>
#include <llarp/constants/apple.hpp>
#include <llarp/ev/libuv.hpp>
#include <llarp/util/fs.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/logging/buffer.hpp>
@ -20,6 +19,8 @@
namespace
{
static auto logcat = oxen::log::Cat("apple.ctx_wrapper");
struct instance_data
{
llarp::apple::Context context;
@ -110,7 +111,7 @@ void* llarp_apple_init(llarp_apple_config* appleconf)
}
catch (const std::exception& e)
{
llarp::LogError("Failed to initialize lokinet from config: ", e.what());
oxen::log::error(logcat, "Failed to initialize lokinet from config: {}", e.what());
}
return nullptr;
}
@ -153,7 +154,7 @@ int llarp_apple_start(void* lokinet, void* callback_context)
}
catch (const std::exception& e)
{
llarp::LogError("Failed to initialize lokinet: ", e.what());
oxen::log::error(logcat, "Failed to initialize lokinet: {}", e.what());
return -1;
}
@ -183,7 +184,7 @@ int llarp_apple_incoming(void* lokinet, const llarp_incoming_packet* packets, si
if (iface->OfferReadPacket(buf))
count++;
else
llarp::LogError("invalid IP packet: ", llarp::buffer_printer(buf));
oxen::log::error(logcat, "invalid IP packet: {}", llarp::buffer_printer(buf));
}
iface->MaybeWakeUpperLayers();

@ -7,6 +7,8 @@
namespace llarp::apple
{
static auto logcat = log::Cat("apple.route_manager");
void RouteManager::check_trampoline(bool enable)
{
if (trampoline_active == enable)
@ -14,7 +16,7 @@ namespace llarp::apple
auto router = context.router;
if (!router)
{
LogError("Cannot reconfigure to use DNS trampoline: no router");
log::error(logcat, "Cannot reconfigure to use DNS trampoline: no router");
return;
}
@ -26,7 +28,7 @@ namespace llarp::apple
if (!tun)
{
LogError("Cannot reconfigure to use DNS trampoline: no tun endpoint found (!?)");
log::error(logcat, "Cannot reconfigure to use DNS trampoline: no tun endpoint found (!?)");
return;
}

@ -813,14 +813,14 @@ namespace llarp
_ip_to_addr.emplace(ip, loki->data());
_addr_to_ip.emplace(loki->data(), ip);
_is_snode_map[*loki] = false;
LogInfo(name(), " remapped ", ip, " to ", *loki);
log::info(logcat, "Remapping {} to {}", ip, *loki);
}
if (const auto* snode = std::get_if<RouterID>(&addr))
{
_ip_to_addr.emplace(ip, snode->data());
_addr_to_ip.emplace(snode->data(), ip);
_is_snode_map[*snode] = true;
LogInfo(name(), " remapped ", ip, " to ", *snode);
log::info(logcat, "Remapping {} to {}", ip, *snode);
}
if (_next_ip < ip)
_next_ip = ip;
@ -949,7 +949,7 @@ namespace llarp
"add-hosts",
ClientOnly,
Comment{"Add a hosts file to the dns resolver", "For use with client side dns filtering"},
[=](fs::path path) {
[=, this](fs::path path) {
if (path.empty())
return;
if (not fs::exists(path))
@ -1349,7 +1349,7 @@ namespace llarp
"unique-range-size",
DefaultUniqueCIDR,
ClientOnly,
[=](int arg) {
[=, this](int arg) {
if (arg > 32 or arg < 4)
throw std::invalid_argument{"[paths]:unique-range-size must be between 4 and 32"};
@ -1428,7 +1428,7 @@ namespace llarp
continue;
ConfigParser parser;
if (not parser.load_file(f.path()))
throw std::runtime_error{"cannot load '" + f.path().u8string() + "'"};
throw std::runtime_error{"cannot load file at path:{}"_format(f.path().string())};
parser.iter_all_sections([&](std::string_view section, const SectionValues& values) {
for (const auto& [k, v] : values)
@ -1539,7 +1539,7 @@ namespace llarp
// fail to overwrite if not instructed to do so
if (fs::exists(confFile) && !overwrite)
{
LogDebug("Not creating config file; it already exists.");
log::debug(logcat, "Config file already exists; NOT creating new config");
return;
}
@ -1551,7 +1551,11 @@ namespace llarp
fs::create_directory(parent);
}
llarp::LogInfo("Attempting to create config file for ", (asRouter ? "router" : "client"), " at ", confFile);
log::info(
logcat,
"Attempting to create config file for {} at file path:{}",
asRouter ? "router" : "client",
confFile);
llarp::Config config{dataDir};
std::string confStr;
@ -1570,7 +1574,7 @@ namespace llarp
throw std::runtime_error{fmt::format("Failed to write config data to {}: {}", confFile, e.what())};
}
llarp::LogInfo("Generated new config ", confFile);
log::info(logcat, "Generated new config (path: {})", confFile);
}
void generate_common_config_comments(ConfigDefinition& def)

@ -8,6 +8,8 @@
namespace llarp
{
static auto logcat = log::Cat("config.def");
template <>
bool OptionDefinition<bool>::from_string(const std::string& input)
{
@ -32,13 +34,13 @@ namespace llarp
Hidden,
[deprecated = def->deprecated, relay = relay, opt = "[" + def->section + "]:" + def->name](
std::string_view) {
LogWarn(
"*** WARNING: The config option ",
log::warning(
logcat,
"*** WARNING: The config option {} {} and has been ignored",
opt,
(deprecated ? " is deprecated"
: relay ? " is not valid in service node configuration files"
: " is not valid in client configuration files"),
" and has been ignored.");
: " is not valid in client configuration files"));
});
}

@ -10,6 +10,8 @@
namespace llarp
{
static auto logcat = log::Cat("config.ini");
bool ConfigParser::load_file(const fs::path& fname)
{
try
@ -111,7 +113,8 @@ namespace llarp
{
throw std::runtime_error(fmt::format("{} invalid line ({}): '{}'", _filename, lineno, line));
}
LogDebug(_filename, ": [", sectName, "]:", k, "=", v);
log::debug(logcat, "{}:[{}]:{}={}", _filename, sectName, k, v);
_config[std::string{sectName}].emplace(k, v);
}
else // malformed?
@ -177,7 +180,8 @@ namespace llarp
{
throw std::runtime_error(fmt::format("{} invalid line ({}): '{}'", _filename, lineno, line));
}
LogDebug(_filename, ": [", sectName, "]:", k, "=", v);
log::debug(logcat, "{}:[{}]:{}={}", _filename, sectName, k, v);
_config[std::string{sectName}].emplace(k, v);
}
else // malformed?

@ -65,7 +65,7 @@ namespace llarp
if (not gen_if_absent)
{
log::error(logcat, err);
log::error(logcat, "{}", err);
return false;
}
@ -138,29 +138,29 @@ namespace llarp
if (ec)
{
LogError("Could not determine status of file ", filepath, ": ", ec.message());
log::error(logcat, "Could not determine status of file (path:{}): {}", filepath, ec.message());
return false;
}
if (not exists)
{
LogInfo("File ", filepath, " doesn't exist; no backup needed");
log::info(logcat, "File (path:{}) does not exist; no backup needed", filepath);
return true;
}
fs::path newFilepath = findFreeBackupFilename(filepath);
if (newFilepath.empty())
{
LogWarn("Could not find an appropriate backup filename for", filepath);
log::warning(logcat, "Could not find an appropriate backup filename for file (path:{})", filepath);
return false;
}
LogInfo("Backing up (moving) key file ", filepath, " to ", newFilepath, "...");
log::info(logcat, "Backing up (moving) key file at {} to {}...", filepath, newFilepath);
fs::rename(filepath, newFilepath, ec);
if (ec)
{
LogError("Failed to move key file ", ec.message());
log::error(logcat, "Failed to move key file {}", ec.message());
return false;
}
@ -184,16 +184,17 @@ namespace llarp
{
if (not fs::exists(path))
{
LogInfo("Generating new key", path);
log::info(logcat, "Generating new key (path:{})", path);
keygen(key);
if (!key.write_to_file(path))
{
LogError("Failed to save new key");
log::error(logcat, "Failed to save new key!");
return false;
}
}
LogDebug("Loading key from file ", path);
log::debug(logcat, "Loading key from file (path:{})", path);
return key.load_from_file(path);
}

@ -9,6 +9,8 @@ using std::chrono::steady_clock;
namespace llarp::consensus
{
static auto logcat = log::Cat("reachability");
using fseconds = std::chrono::duration<float, std::chrono::seconds::period>;
using fminutes = std::chrono::duration<float, std::chrono::minutes::period>;
@ -30,26 +32,21 @@ namespace llarp::consensus
incoming.last_whine = now;
if (!failing)
{
LogInfo(name, " ping received; port is likely reachable again");
log::info(logcat, "{} received ping; port is likely reachable!", name);
}
else
{
if (incoming.last_test.time_since_epoch() == 0s)
{
LogWarn("Have NEVER received ", name, " pings!");
log::warning(logcat, "{} has NEVER received pings!", name);
}
else
{
LogWarn(
"Have not received ", name, " pings for a long time: ", fminutes{elapsed}.count(), " minutes");
log::warning(
logcat, "Have not received pings from {} in {} minutes", name, fminutes{elapsed}.count());
}
LogWarn(
"Please check your ",
name,
" port. Not being reachable "
"over ",
name,
" may result in a deregistration!");
log::warning(logcat, "Check {} port. Non-reachabibility may result in deregistration!", name);
}
}
}

@ -19,6 +19,8 @@
namespace llarp
{
static auto logcat = log::Cat("crypto");
static bool dh(
llarp::SharedSecret& out,
const PubKey& client_pk,
@ -68,7 +70,7 @@ namespace llarp
return crypto_generichash_blake2b(shared.data(), 32, n.data(), 32, dh_result.data(), 32) != -1;
}
llarp::LogWarn("crypto::dh_client - dh failed");
log::warning(logcat, "crypto::dh_client - dh failed");
return false;
}
@ -81,7 +83,7 @@ namespace llarp
return crypto_generichash_blake2b(shared.data(), 32, n.data(), n.size(), dh_result.data(), 32) != -1;
}
llarp::LogWarn("crypto::dh_server - dh failed");
log::warning(logcat, "crypto::dh_server - dh failed");
return false;
}
@ -94,7 +96,7 @@ namespace llarp
return crypto_generichash_blake2b(shared, 32, nonce, 24, dh_result.data(), 32) != -1;
}
llarp::LogWarn("crypto::dh_server - dh failed");
log::warning(logcat, "crypto::dh_server - dh failed");
return false;
}
@ -319,7 +321,7 @@ namespace llarp
h = *hash;
else if (not make_scalar(h, root_pubkey, key_n))
{
LogError("cannot make scalar");
log::error(logcat, "cannot make scalar");
return false;
}
@ -366,7 +368,7 @@ namespace llarp
h = *hash;
else if (not make_scalar(h, root_pubkey, key_n))
{
LogError("cannot make scalar");
log::error(logcat, "cannot make scalar");
return false;
}
@ -491,7 +493,7 @@ namespace llarp
{
if (sodium_init() == -1)
{
log::critical(log::Cat("initialization"), "sodium_init() failed, unable to continue!");
log::critical(logcat, "sodium_init() failed, unable to continue!");
std::abort();
}
char* avx2 = std::getenv("AVX2_FORCE_DISABLE");

@ -11,6 +11,8 @@
namespace llarp::dht
{
static auto logcat = log::Cat("dht.bucket");
template <typename Val_t>
struct Bucket
{
@ -87,7 +89,7 @@ namespace llarp::dht
{
if (nodes.size() < N || nodes.empty())
{
llarp::LogWarn("Not enough dht nodes, have ", nodes.size(), " want ", N);
log::warning(logcat, "Not enough DHT nodes (have:{}, want:{})", nodes.size(), N);
return false;
}
if (nodes.size() == N)

@ -1,44 +0,0 @@
#pragma once
#include "policy.hpp"
#include <llarp/handlers/exit.hpp>
#include <string>
#include <unordered_map>
namespace llarp::exit
{
/// owner of all the exit endpoints
struct Context
{
Context(Router* r);
~Context();
void Tick(llarp_time_t now);
void clear_all_endpoints();
util::StatusObject ExtractStatus() const;
/// send close to all exit sessions and remove all sessions
void stop();
void add_exit_endpoint(const std::string& name, const NetworkConfig& networkConfig, const DnsConfig& dnsConfig);
bool obtain_new_exit(const PubKey& remote, const PathID_t& path, bool permitInternet);
exit::Endpoint* find_endpoint_for_path(const PathID_t& path) const;
/// calculate (pk, tx, rx) for all exit traffic
using TrafficStats = std::unordered_map<PubKey, std::pair<uint64_t, uint64_t>>;
void calculate_exit_traffic(TrafficStats& stats);
std::shared_ptr<handlers::ExitEndpoint> get_exit_endpoint(std::string name) const;
private:
Router* router;
std::unordered_map<std::string, std::shared_ptr<handlers::ExitEndpoint>> _exits;
std::list<std::shared_ptr<handlers::ExitEndpoint>> _closed;
};
} // namespace llarp::exit

@ -1,809 +0,0 @@
#include "exit.hpp"
#include <llarp/dns/dns.hpp>
#include <llarp/net/net.hpp>
#include <llarp/nodedb.hpp>
#include <llarp/path/path_context.hpp>
#include <llarp/router/router.hpp>
#include <llarp/service/protocol_type.hpp>
#include <cassert>
namespace llarp::handlers
{
ExitEndpoint::ExitEndpoint(std::string name, Router* r) : router(r), name(std::move(name))
// , tunnel_manager{std::make_shared<link::TunnelManager>(*this)}
{
should_init_tun = true;
}
ExitEndpoint::~ExitEndpoint() = default;
void ExitEndpoint::lookup_name(std::string, std::function<void(std::string, bool)>)
{
// TODO: implement me (or does EndpointBase having this method as virtual even make sense?)
}
void ExitEndpoint::LookupServiceAsync(
std::string, std::string, std::function<void(std::vector<dns::SRVData>)> resultHandler)
{
// TODO: implement me
resultHandler({});
}
std::optional<EndpointBase::AddressVariant_t> ExitEndpoint::GetEndpointWithConvoTag(service::ConvoTag tag) const
{
for (const auto& [pathID, pk] : paths)
{
if (pathID.as_array() == tag.as_array())
return RouterID{pk.as_array()};
}
for (const auto& [rid, session] : snode_sessions)
{
PathID_t pathID{tag.as_array()};
if (session->GetPathByID(pathID))
return rid;
}
return std::nullopt;
}
std::optional<service::ConvoTag> ExitEndpoint::GetBestConvoTagFor(AddressVariant_t addr) const
{
if (auto* rid = std::get_if<RouterID>(&addr))
{
service::ConvoTag tag{};
auto visit = [&tag](exit::Endpoint* const ep) -> bool {
if (not ep)
return false;
if (auto path = ep->GetCurrentPath())
tag = service::ConvoTag{path->RXID().as_array()};
return true;
};
if (VisitEndpointsFor(PubKey{*rid}, visit) and not tag.IsZero())
return tag;
auto itr = snode_sessions.find(*rid);
if (itr == snode_sessions.end())
{
return std::nullopt;
}
if (auto path = itr->second->GetPathByRouter(*rid))
{
tag = service::ConvoTag{path->RXID().as_array()};
return tag;
}
return std::nullopt;
}
return std::nullopt;
}
const EventLoop_ptr& ExitEndpoint::Loop()
{
return router->loop();
}
bool ExitEndpoint::send_to(service::ConvoTag tag, std::string payload)
{
if (auto maybeAddr = GetEndpointWithConvoTag(tag))
{
if (std::holds_alternative<service::Address>(*maybeAddr))
return false;
if (auto* rid = std::get_if<RouterID>(&*maybeAddr))
{
for (auto [itr, end] = active_exits.equal_range(PubKey{*rid}); itr != end; ++itr)
{
if (not itr->second->LooksDead(Now()))
{
return router->send_data_message(itr->second->router_id(), std::move(payload));
}
}
if (not router->PathToRouterAllowed(*rid))
return false;
ObtainSNodeSession(
*rid, [pkt = std::move(payload)](std::shared_ptr<llarp::exit::BaseSession> session) mutable {
if (session and session->IsReady())
{
session->send_packet_to_remote(std::move(pkt));
}
});
}
return true;
}
return false;
}
bool ExitEndpoint::EnsurePathTo(
AddressVariant_t addr, std::function<void(std::optional<service::ConvoTag>)> hook, llarp_time_t)
{
if (std::holds_alternative<service::Address>(addr))
return false;
if (auto* rid = std::get_if<RouterID>(&addr))
{
if (snode_keys.count(PubKey{*rid}) or router->PathToRouterAllowed(*rid))
{
ObtainSNodeSession(*rid, [hook, routerID = *rid](std::shared_ptr<exit::BaseSession> session) {
if (session and session->IsReady())
{
if (auto path = session->GetPathByRouter(routerID))
{
hook(service::ConvoTag{path->RXID().as_array()});
}
else
hook(std::nullopt);
}
else
hook(std::nullopt);
});
}
else
{
// probably a client
hook(GetBestConvoTagFor(addr));
}
}
return true;
}
util::StatusObject ExitEndpoint::ExtractStatus() const
{
util::StatusObject obj{{"permitExit", permit_exit}, {"ip", if_addr.to_string()}};
util::StatusObject exitsObj{};
for (const auto& item : active_exits)
{
exitsObj[item.first.to_string()] = item.second->ExtractStatus();
}
obj["exits"] = exitsObj;
return obj;
}
bool ExitEndpoint::SupportsV6() const
{
return use_ipv6;
}
bool ExitEndpoint::ShouldHookDNSMessage(const dns::Message& msg) const
{
if (msg.questions.size() == 0)
return false;
// always hook ptr for ranges we own
if (msg.questions[0].qtype == dns::qTypePTR)
{
if (auto ip = dns::DecodePTR(msg.questions[0].qname))
return ip_range.Contains(*ip);
return false;
}
if (msg.questions[0].qtype == dns::qTypeA || msg.questions[0].qtype == dns::qTypeCNAME
|| msg.questions[0].qtype == dns::qTypeAAAA)
{
if (msg.questions[0].IsName("localhost.loki"))
return true;
if (msg.questions[0].HasTLD(".snode"))
return true;
}
return false;
}
bool ExitEndpoint::MaybeHookDNS(
std::shared_ptr<dns::PacketSource_Base> source,
const dns::Message& query,
const SockAddr& to,
const SockAddr& from)
{
if (not ShouldHookDNSMessage(query))
return false;
auto job = std::make_shared<dns::QueryJob>(source, query, to, from);
if (not HandleHookedDNSMessage(query, [job](auto msg) { job->SendReply(msg.ToBuffer()); }))
job->Cancel();
return true;
}
bool ExitEndpoint::HandleHookedDNSMessage(dns::Message msg, std::function<void(dns::Message)> reply)
{
if (msg.questions[0].qtype == dns::qTypePTR)
{
auto ip = dns::DecodePTR(msg.questions[0].qname);
if (not ip)
return false;
if (ip == if_addr)
{
RouterID us = GetRouter()->pubkey();
msg.AddAReply(us.to_string(), 300);
}
else
{
auto itr = ip_to_key.find(*ip);
if (itr != ip_to_key.end() && snode_keys.find(itr->second) != snode_keys.end())
{
RouterID them{itr->second.data()};
msg.AddAReply(them.to_string());
}
else
msg.AddNXReply();
}
}
else if (msg.questions[0].qtype == dns::qTypeCNAME)
{
if (msg.questions[0].IsName("random.snode"))
{
if (auto random = GetRouter()->GetRandomGoodRouter())
msg.AddCNAMEReply(random->to_string(), 1);
else
msg.AddNXReply();
}
else if (msg.questions[0].IsName("localhost.loki"))
{
RouterID us = router->pubkey();
msg.AddAReply(us.to_string(), 1);
}
else
msg.AddNXReply();
}
else if (msg.questions[0].qtype == dns::qTypeA || msg.questions[0].qtype == dns::qTypeAAAA)
{
const bool isV6 = msg.questions[0].qtype == dns::qTypeAAAA;
const bool isV4 = msg.questions[0].qtype == dns::qTypeA;
if (msg.questions[0].IsName("random.snode"))
{
if (auto random = GetRouter()->GetRandomGoodRouter())
{
msg.AddCNAMEReply(random->to_string(), 1);
auto ip = ObtainServiceNodeIP(*random);
msg.AddINReply(ip, false);
}
else
msg.AddNXReply();
reply(msg);
return true;
}
if (msg.questions[0].IsName("localhost.loki"))
{
msg.AddINReply(GetIfAddr(), isV6);
reply(msg);
return true;
}
// forward dns for snode
RouterID r;
if (r.from_string(msg.questions[0].Name()))
{
huint128_t ip;
PubKey pubKey(r);
if (isV4 && SupportsV6())
{
msg.hdr_fields |= dns::flags_QR | dns::flags_AA | dns::flags_RA;
}
else if (snode_keys.find(pubKey) == snode_keys.end())
{
// we do not have it mapped, async obtain it
ObtainSNodeSession(
r,
[&, msg = std::make_shared<dns::Message>(msg), reply](
std::shared_ptr<exit::BaseSession> session) {
if (session && session->IsReady())
{
msg->AddINReply(key_to_IP[pubKey], isV6);
}
else
{
msg->AddNXReply();
}
reply(*msg);
});
return true;
}
else
{
// we have it mapped already as a service node
auto itr = key_to_IP.find(pubKey);
if (itr != key_to_IP.end())
{
ip = itr->second;
msg.AddINReply(ip, isV6);
}
else // fallback case that should never happen (probably)
msg.AddNXReply();
}
}
else
msg.AddNXReply();
}
reply(msg);
return true;
}
void ExitEndpoint::ObtainSNodeSession(const RouterID& rid, exit::SessionReadyFunc obtain_cb)
{
if (not router->node_db()->is_connection_allowed(rid))
{
obtain_cb(nullptr);
return;
}
ObtainServiceNodeIP(rid);
snode_sessions[rid]->AddReadyHook(obtain_cb);
}
llarp_time_t ExitEndpoint::Now() const
{
return router->now();
}
bool ExitEndpoint::VisitEndpointsFor(const PubKey& pk, std::function<bool(exit::Endpoint* const)> visit) const
{
for (auto [itr, end] = active_exits.equal_range(pk); itr != end; ++itr)
{
if (not visit(itr->second.get()))
return true;
}
return false;
}
void ExitEndpoint::Flush()
{
while (not inet_to_network.empty())
{
auto& top = inet_to_network.top();
// get a session by public key
std::optional<PubKey> maybe_pk;
{
auto itr = ip_to_key.find(top.dstv6());
if (itr != ip_to_key.end())
maybe_pk = itr->second;
}
auto buf = const_cast<net::IPPacket&>(top);
inet_to_network.pop();
// we have no session for public key so drop
if (not maybe_pk)
continue; // we are in a while loop
const auto& pk = *maybe_pk;
// check if this key is a service node
if (snode_keys.count(pk))
{
// check if it's a service node session we made and queue it via our
// snode session that we made otherwise use an inbound session that
// was made by the other service node
auto itr = snode_sessions.find(RouterID{pk.data()});
if (itr != snode_sessions.end())
{
itr->second->send_packet_to_remote(buf.to_string());
// we are in a while loop
continue;
}
}
auto tryFlushingTraffic = [this, buf = std::move(buf), pk](exit::Endpoint* const ep) -> bool {
if (!ep->QueueInboundTraffic(buf._buf, service::ProtocolType::TrafficV4))
{
LogWarn(Name(), " dropped inbound traffic for session ", pk, " as we are overloaded (probably)");
// continue iteration
return true;
}
// break iteration
return false;
};
if (!VisitEndpointsFor(pk, tryFlushingTraffic))
{
// we may have all dead sessions, wtf now?
LogWarn(Name(), " dropped inbound traffic for session ", pk, " as we have no working endpoints");
}
}
for (auto& [pubkey, endpoint] : active_exits)
{
if (!endpoint->Flush())
{
LogWarn("exit session with ", pubkey, " dropped packets");
}
}
for (auto& [id, session] : snode_sessions)
{
session->FlushUpstream();
session->FlushDownstream();
}
}
bool ExitEndpoint::Start()
{
// map our address
const PubKey us(router->pubkey());
const huint128_t ip = GetIfAddr();
key_to_IP[us] = ip;
ip_to_key[ip] = us;
ip_activity[ip] = std::numeric_limits<llarp_time_t>::max();
snode_keys.insert(us);
if (should_init_tun)
{
vpn::InterfaceInfo info;
info.ifname = if_name;
info.addrs.emplace_back(ip_range);
if_net = GetRouter()->vpn_platform()->CreateInterface(std::move(info), router);
if (not if_net)
{
llarp::LogError("Could not create interface");
return false;
}
if (not GetRouter()->loop()->add_network_interface(
if_net, [this](net::IPPacket pkt) { OnInetPacket(std::move(pkt)); }))
{
llarp::LogWarn("Could not create tunnel for exit endpoint");
return false;
}
GetRouter()->loop()->add_ticker([this] { Flush(); });
#ifndef _WIN32
resolver = std::make_shared<dns::Server>(router->loop(), dns_conf, if_nametoindex(if_name.c_str()));
resolver->Start();
#endif
}
return true;
}
Router* ExitEndpoint::GetRouter()
{
return router;
}
huint128_t ExitEndpoint::GetIfAddr() const
{
return if_addr;
}
bool ExitEndpoint::Stop()
{
for (auto& item : snode_sessions)
item.second->Stop();
return true;
}
bool ExitEndpoint::ShouldRemove() const
{
for (auto& item : snode_sessions)
if (!item.second->ShouldRemove())
return false;
return true;
}
bool ExitEndpoint::HasLocalMappedAddrFor(const PubKey& pk) const
{
return key_to_IP.find(pk) != key_to_IP.end();
}
huint128_t ExitEndpoint::GetIPForIdent(const PubKey pk)
{
huint128_t found{};
if (!HasLocalMappedAddrFor(pk))
{
// allocate and map
found = AllocateNewAddress();
if (!key_to_IP.emplace(pk, found).second)
{
LogError(Name(), "failed to map ", pk, " to ", found);
return found;
}
if (!ip_to_key.emplace(found, pk).second)
{
LogError(Name(), "failed to map ", found, " to ", pk);
return found;
}
if (HasLocalMappedAddrFor(pk))
LogInfo(Name(), " mapping ", pk, " to ", found);
else
LogError(Name(), "failed to map ", pk, " to ", found);
}
else
found = key_to_IP[pk];
MarkIPActive(found);
key_to_IP.rehash(0);
assert(HasLocalMappedAddrFor(pk));
return found;
}
huint128_t ExitEndpoint::AllocateNewAddress()
{
if (next_addr < highest_addr)
return ++next_addr;
// find oldest activity ip address
huint128_t found = {0};
llarp_time_t min = std::numeric_limits<llarp_time_t>::max();
for (const auto& [addr, time] : ip_activity)
{
if (time < min)
{
found.h = addr.h;
min = time;
}
}
// kick old ident off exit
// TODO: DoS
PubKey pk = ip_to_key[found];
KickIdentOffExit(pk);
return found;
}
EndpointBase::AddressVariant_t ExitEndpoint::LocalAddress() const
{
return RouterID{router->pubkey()};
}
void ExitEndpoint::SRVRecordsChanged()
{
// TODO: Investigate the usage or the term exit RE: service nodes acting as exits
}
std::optional<EndpointBase::SendStat> ExitEndpoint::GetStatFor(AddressVariant_t) const
{
/// TODO: implement me
return std::nullopt;
}
std::unordered_set<EndpointBase::AddressVariant_t> ExitEndpoint::AllRemoteEndpoints() const
{
std::unordered_set<AddressVariant_t> remote;
for (const auto& [path, pubkey] : paths)
{
remote.insert(RouterID{pubkey.data()});
}
return remote;
}
bool ExitEndpoint::QueueOutboundTraffic(net::IPPacket pkt)
{
return if_net && if_net->WritePacket(std::move(pkt));
}
void ExitEndpoint::KickIdentOffExit(const PubKey& pk)
{
LogInfo(Name(), " kicking ", pk, " off exit");
huint128_t ip = key_to_IP[pk];
key_to_IP.erase(pk);
ip_to_key.erase(ip);
for (auto [exit_itr, end] = active_exits.equal_range(pk); exit_itr != end;)
exit_itr = active_exits.erase(exit_itr);
}
void ExitEndpoint::MarkIPActive(huint128_t ip)
{
ip_activity[ip] = GetRouter()->now();
}
void ExitEndpoint::OnInetPacket(net::IPPacket pkt)
{
inet_to_network.emplace(std::move(pkt));
}
bool ExitEndpoint::QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from)
{
net::IPPacket pkt{buf.view_all()};
if (pkt.empty())
return false;
// rewrite ip
if (use_ipv6)
pkt.UpdateIPv6Address(from, if_addr);
else
pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(from)), xhtonl(net::TruncateV6(if_addr)));
return if_net and if_net->WritePacket(std::move(pkt));
}
exit::Endpoint* ExitEndpoint::FindEndpointByPath(const PathID_t& path)
{
exit::Endpoint* endpoint = nullptr;
PubKey pk;
if (auto itr = paths.find(path); itr != paths.end())
pk = itr->second;
else
return nullptr;
if (auto itr = active_exits.find(pk); itr != active_exits.end())
{
if (itr->second->PubKey() == pk)
endpoint = itr->second.get();
}
return endpoint;
}
bool ExitEndpoint::UpdateEndpointPath(const PubKey& remote, const PathID_t& next)
{
// check if already mapped
if (auto itr = paths.find(next); itr != paths.end())
return false;
paths.emplace(next, remote);
return true;
}
void ExitEndpoint::Configure(const NetworkConfig& networkConfig, const DnsConfig& dnsConfig)
{
/*
* TODO: pre-config refactor, this was checking a couple things that were extremely vague
* these could have appeared on either [dns] or [network], but they weren't
documented
* anywhere
*
if (k == "type" && v == "null")
{
m_ShouldInitTun = false;
return true;
}
if (k == "exit")
{
m_PermitExit = IsTrueValue(v.c_str());
return true;
}
*/
dns_conf = dnsConfig;
if (networkConfig.endpoint_type == "null")
{
should_init_tun = false;
}
ip_range = networkConfig.if_addr;
if (!ip_range.addr.h)
{
const auto maybe = router->net().find_free_range();
if (not maybe.has_value())
throw std::runtime_error("cannot find free interface range");
ip_range = *maybe;
}
const auto host_str = ip_range.BaseAddressString();
// string, or just a plain char array?
if_addr = ip_range.addr;
next_addr = if_addr;
highest_addr = ip_range.HighestAddr();
use_ipv6 = not ip_range.IsV4();
if_name = networkConfig.if_name;
if (if_name.empty())
{
const auto maybe = router->net().FindFreeTun();
if (not maybe.has_value())
throw std::runtime_error("cannot find free interface name");
if_name = *maybe;
}
LogInfo(Name(), " set ifname to ", if_name);
// if (auto* quic = GetQUICTunnel())
// {
// quic->listen([ifaddr = net::TruncateV6(if_addr)](std::string_view, uint16_t port) {
// return llarp::SockAddr{ifaddr, huint16_t{port}};
// });
// }
}
huint128_t ExitEndpoint::ObtainServiceNodeIP(const RouterID& other) // "find router"
{
const PubKey pubKey{other};
const PubKey us{router->pubkey()};
// just in case
if (pubKey == us)
return if_addr;
huint128_t ip = GetIPForIdent(pubKey);
if (snode_keys.emplace(pubKey).second)
{
auto session = std::make_shared<exit::SNodeSession>(
other,
[this, ip](const auto& buf) { return QueueSNodePacket(buf, ip); },
GetRouter(),
2,
1,
true,
this);
// this is a new service node make an outbound session to them
snode_sessions[other] = session;
}
return ip;
}
link::TunnelManager* ExitEndpoint::GetQUICTunnel()
{
return nullptr;
// return tunnel_manager.get();
}
bool ExitEndpoint::AllocateNewExit(const PubKey pk, const PathID_t& path, bool wantInternet)
{
if (wantInternet && !permit_exit)
return false;
// TODO: is this getting a path or a transit hop or...somehow possibly either?
// 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);
if (GetRouter()->path_context().TransitHopPreviousIsRouter(path, pk.as_array()))
{
// we think this path belongs to a service node
// mark it as such so we don't make an outbound session to them
snode_keys.emplace(pk.as_array());
}
active_exits.emplace(pk, std::make_unique<exit::Endpoint>(pk, handler, !wantInternet, ip, this));
paths[path] = pk;
return HasLocalMappedAddrFor(pk);
}
std::string ExitEndpoint::Name() const
{
return name;
}
void ExitEndpoint::DelEndpointInfo(const PathID_t& path)
{
paths.erase(path);
}
void ExitEndpoint::RemoveExit(const exit::Endpoint* ep)
{
for (auto [itr, end] = active_exits.equal_range(ep->PubKey()); itr != end; ++itr)
{
if (itr->second->GetCurrentPath() == ep->GetCurrentPath())
{
active_exits.erase(itr);
// now ep is gone af
return;
}
}
}
void ExitEndpoint::Tick(llarp_time_t now)
{
{
auto itr = snode_sessions.begin();
while (itr != snode_sessions.end())
{
if (itr->second->IsExpired(now))
itr = snode_sessions.erase(itr);
else
{
itr->second->Tick(now);
++itr;
}
}
}
{
// expire
auto itr = active_exits.begin();
while (itr != active_exits.end())
{
if (itr->second->IsExpired(now))
itr = active_exits.erase(itr);
else
++itr;
}
// pick chosen exits and tick
chosen_exits.clear();
itr = active_exits.begin();
while (itr != active_exits.end())
{
// do we have an exit set for this key?
if (chosen_exits.find(itr->first) != chosen_exits.end())
{
// yes
if (chosen_exits[itr->first]->createdAt < itr->second->createdAt)
{
// if the iterators's exit is newer use it for the chosen exit for
// key
if (!itr->second->LooksDead(now))
chosen_exits[itr->first] = itr->second.get();
}
}
else if (!itr->second->LooksDead(now)) // set chosen exit if not dead for key that
// doesn't have one yet
chosen_exits[itr->first] = itr->second.get();
// tick which clears the tx rx counters
itr->second->Tick(now);
++itr;
}
}
}
} // namespace llarp::handlers

@ -1,194 +0,0 @@
#pragma once
#include "tun.hpp"
#include <llarp/dns/server.hpp>
#include <llarp/exit/endpoint.hpp>
#include <unordered_map>
namespace llarp
{
struct Router;
}
namespace llarp::handlers
{
struct ExitEndpoint : public dns::Resolver_Base, public EndpointBase
{
int Rank() const override
{
return 0;
};
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;
ExitEndpoint(std::string name, Router* r);
~ExitEndpoint() override;
std::optional<AddressVariant_t> GetEndpointWithConvoTag(service::ConvoTag tag) 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;
void lookup_name(std::string name, std::function<void(std::string, bool)> func) override;
const EventLoop_ptr& Loop() override;
std::unordered_set<EndpointBase::AddressVariant_t> AllRemoteEndpoints() const override;
void SRVRecordsChanged() override;
void MarkAddressOutbound(service::Address) override{};
bool send_to(service::ConvoTag tag, std::string payload) override;
void Tick(llarp_time_t now);
void Configure(const NetworkConfig& networkConfig, const DnsConfig& dnsConfig);
std::string Name() const;
bool VisitEndpointsFor(const PubKey& pk, std::function<bool(exit::Endpoint* const)> visit) const;
util::StatusObject ExtractStatus() const;
bool SupportsV6() const;
bool ShouldHookDNSMessage(const dns::Message& msg) const;
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;
bool AllocateNewExit(const PubKey pk, const PathID_t& path, bool permitInternet);
exit::Endpoint* FindEndpointByPath(const PathID_t& path);
exit::Endpoint* FindEndpointByIP(huint32_t ip);
bool UpdateEndpointPath(const PubKey& remote, const PathID_t& next);
/// handle ip packet from outside
void OnInetPacket(net::IPPacket buf);
Router* GetRouter();
llarp_time_t Now() const;
template <typename Stats>
void CalculateTrafficStats(Stats& stats)
{
for (auto& [pubkey, endpoint] : active_exits)
{
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 RemoveExit(const exit::Endpoint* ep);
bool QueueOutboundTraffic(net::IPPacket pkt);
AddressVariant_t LocalAddress() const override;
std::optional<SendStat> GetStatFor(AddressVariant_t remote) const override;
/// sets up networking and starts traffic
bool Start();
bool Stop();
bool ShouldRemove() const;
bool HasLocalMappedAddrFor(const PubKey& pk) const;
huint128_t GetIfAddr() const;
void Flush();
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);
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);
bool QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from);
void MarkIPActive(huint128_t ip);
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;
std::unordered_map<PubKey, exit::Endpoint*> chosen_exits;
std::unordered_multimap<PubKey, std::unique_ptr<exit::Endpoint>> active_exits;
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 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;
huint128_t if_addr;
huint128_t highest_addr;
huint128_t next_addr;
IPRange ip_range;
std::string if_name;
std::unordered_map<huint128_t, llarp_time_t> ip_activity;
std::shared_ptr<vpn::NetworkInterface> if_net;
SockAddr resolver_addr;
std::vector<SockAddr> upstream_resolvers;
// std::shared_ptr<link::TunnelManager> tunnel_manager;
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 llarp::handlers

@ -420,14 +420,14 @@ namespace llarp::handlers
// if (not ip.FromString(key))
// {
// LogWarn(name(), " malformed IP in addr map data: ", key);
// log::warning(logcat, "{} malformed IP in addr map data: {}", name(), key);
// continue;
// }
if (_local_ip == ip)
continue;
if (not _local_range.contains(ip))
{
LogWarn(name(), " out of range IP in addr map data: ", ip);
log::warning(logcat, "{} out of range IP in addr map data", name(), ip);
continue;
}
@ -441,13 +441,13 @@ namespace llarp::handlers
}
else
{
LogWarn(name(), " invalid address in addr map: ", *str);
log::warning(logcat, "{} invalid address in addr map: {}", name(), *str);
continue;
}
}
else
{
LogWarn(name(), " invalid first entry in addr map, not a string");
log::warning(logcat, "{} invalid first entry in addr map: not a string!", name());
continue;
}
if (const auto* loki = std::get_if<service::Address>(&addr))
@ -455,14 +455,16 @@ namespace llarp::handlers
_ip_to_addr.emplace(ip, loki->data());
_addr_to_ip.emplace(loki->data(), ip);
_is_snode_map[*loki] = false;
LogInfo(name(), " remapped ", ip, " to ", *loki);
log::info(logcat, "{} remapped {} to {}", name(), ip, *loki);
}
if (const auto* snode = std::get_if<RouterID>(&addr))
{
_ip_to_addr.emplace(ip, snode->data());
_addr_to_ip.emplace(snode->data(), ip);
_is_snode_map[*snode] = true;
LogInfo(name(), " remapped ", ip, " to ", *snode);
log::info(logcat, "{} remapped {} to {}", name(), ip, *snode);
}
if (_next_ip < ip)
_next_ip = ip;
@ -473,7 +475,7 @@ namespace llarp::handlers
}
else
{
LogInfo(name(), " skipping loading addr map at ", file, " as it does not currently exist");
log::info(logcat, "{} skipping loading addr map at {} as it does not currently exist", name(), file);
}
}
@ -622,7 +624,7 @@ namespace llarp::handlers
// }
// if (msg.questions.size() != 1)
// {
// llarp::LogWarn("bad number of dns questions: ", msg.questions.size());
// log::warning(logcat, "bad number of dns questions: {}", msg.questions.size());
// return false;
// }
// std::string qname = msg.questions[0].Name();
@ -947,10 +949,11 @@ namespace llarp::handlers
(void)SNode;
if (itr != _ip_to_addr.end())
{
llarp::LogWarn(ip, " already mapped to ", service::Address(itr->second.as_array()).to_string());
log::warning(logcat, "{} already mapped to {}", ip, itr->second);
return false;
}
llarp::LogInfo(name() + " map ", addr.to_string(), " to ", ip);
log::info(logcat, "{} mapping {} to {}", name(), addr.to_string(), ip);
// m_IPToAddr[ip] = addr;
// _addr_to_ip[addr] = ip;
@ -984,8 +987,8 @@ namespace llarp::handlers
{
_next_ip = _local_ip;
// _max_ip = _local_range.HighestAddr();
llarp::LogInfo(name(), " set ", _if_name, " to have address ", _local_ip);
llarp::LogInfo(name(), " allocated up to ", _max_ip, " on range ", _local_range);
log::info(logcat, "{} set {} to have address ", name(), _if_name, _local_ip);
log::info(logcat, "{} allocated up to {} on range ", name(), _max_ip, _local_range);
const service::Address ourAddr = _identity.pub.address();
@ -1005,7 +1008,7 @@ namespace llarp::handlers
info.ifname = _if_name;
LogInfo(name(), " setting up network...");
log::info(logcat, "{} setting up network...", name());
try
{
@ -1013,12 +1016,12 @@ namespace llarp::handlers
}
catch (std::exception& ex)
{
LogError(name(), " failed to set up network interface: ", ex.what());
log::error(logcat, "{} failed to set up network interface: ", name(), ex.what());
return false;
}
_if_name = _net_if->Info().ifname;
LogInfo(name(), " got network interface ", _if_name);
log::info(logcat, "{} got network interface:{}", name(), _if_name);
auto handle_packet = [netif = _net_if, pktrouter = _packet_router](UDPPacket pkt) {
// TODO: packets used to have reply hooks
@ -1067,7 +1070,7 @@ namespace llarp::handlers
bool TunEndpoint::setup_networking()
{
llarp::LogInfo("Set Up networking for ", name());
log::info(logcat, "Set Up networking for {}", name());
return setup_tun();
}
@ -1083,7 +1086,7 @@ namespace llarp::handlers
if (_persisting_addr_file and not platform::is_android)
{
const auto& file = *_persisting_addr_file;
LogInfo(name(), " saving address map to ", file);
log::info(logcat, "{} saving address map to {}", name(), file);
// if (auto maybe = util::OpenFileStream<fs::ofstream>(file, std::ios_base::binary))
// {
// std::map<std::string, std::string> addrmap;
@ -1213,7 +1216,7 @@ namespace llarp::handlers
// // router().TriggerPump();
// // return;
// // }
// // LogWarn("cannot ensure path to exit ", addr, " so we drop some packets");
// // log::warning(logcat, "cannot ensure path to exit {}; so we drop some packets", addr);
// // },
// // PathAlignmentTimeout());
// return;
@ -1264,7 +1267,7 @@ namespace llarp::handlers
// // {
// // var::visit(
// // [this](auto&& addr) {
// // LogWarn(name(), " failed to ensure path to ", addr, " no convo tag found");
// // Log Warn(name(), " failed to ensure path to ", addr, " no convo tag found");
// // },
// // to);
// // }
@ -1277,7 +1280,7 @@ namespace llarp::handlers
// // {
// // var::visit(
// // [this](auto&& addr) {
// // LogWarn(name(), " failed to send to ", addr, ", SendToOrQueue failed");
// // Log Warn(name(), " failed to send to ", addr, ", SendToOrQueue failed");
// // },
// // to);
// // }
@ -1303,15 +1306,15 @@ namespace llarp::handlers
// auto* quic = GetQUICTunnel();
// if (!quic)
// {
// LogWarn("incoming quic packet but this endpoint is not quic capable; dropping");
// Log Warn("incoming quic packet but this endpoint is not quic capable; dropping");
// return false;
// }
// if (buf.sz < 4)
// {
// LogWarn("invalid incoming quic packet, dropping");
// Log Warn("invalid incoming quic packet, dropping");
// return false;
// }
// LogInfo("tag active T=", tag);
// log::info(logcat, "tag active T={}", tag);
// // TODO:
// // quic->receive_packet(tag, buf);
@ -1471,9 +1474,8 @@ namespace llarp::handlers
// _addr_to_ip[ident] = nextIP;
// _ip_to_addr[nextIP] = ident;
// _is_snode_map[ident] = snode;
// var::visit([&](auto&& remote) { llarp::LogInfo(name(), " mapped ", remote, " to ", nextIP); }, addr);
// mark_ip_active(nextIP);
// return nextIP;
// var::visit([&](auto&& remote) { llarp::Log Info(name(), " mapped ", remote, " to ", nextIP); },
// addr); mark_ip_active(nextIP); return nextIP;
// }
}

@ -594,7 +594,7 @@ namespace llarp
return;
}
LogInfo("stopping links");
log::info(logcat, "stopping links");
is_stopping = true;
quic.reset();

@ -14,6 +14,8 @@
namespace llarp::quic
{
static auto logcat = log::Cat("tun");
namespace
{
// Takes data from the tcp connection and pushes it down the quic tunnel
@ -22,22 +24,25 @@ namespace llarp::quic
auto stream = client.data<Stream>();
assert(stream);
std::string_view data{event.data.get(), event.length};
auto peer = client.peer();
LogTrace(peer.ip, ":", peer.port, " → lokinet ", buffer_printer{data});
log::trace(logcat, "{}:{} -> lokinet {}", peer.ip, peer.port, buffer_printer{data});
// Steal the buffer from the DataEvent's unique_ptr<char[]>:
stream->append_buffer(reinterpret_cast<const std::byte*>(event.data.release()), event.length);
if (stream->used() >= tunnel::PAUSE_SIZE)
{
LogDebug(
"quic tunnel is congested (have ",
stream->used(),
" bytes in flight); pausing local tcp connection reads");
log::debug(
logcat,
"Quic tunnel is congested ({} bytes in flight); pausing local TCP connection reads",
stream->used());
client.stop();
stream->when_available([](Stream& s) {
auto client = s.data<uvw::TCPHandle>();
if (s.used() < tunnel::PAUSE_SIZE)
{
LogDebug("quic tunnel is no longer congested; resuming tcp connection reading");
log::debug(logcat, "Quic tunnel is no longer congested; resuming TCP connection reading!");
client->read();
return true;
}
@ -46,7 +51,7 @@ namespace llarp::quic
}
else
{
LogDebug("Queued ", event.length, " bytes");
log::debug(logcat, "Queued {} bytes", event.length);
}
}
@ -60,7 +65,8 @@ namespace llarp::quic
std::string_view data{reinterpret_cast<const char*>(bdata.data()), bdata.size()};
auto peer = tcp->peer();
LogTrace(peer.ip, ":", peer.port, " ← lokinet ", buffer_printer{data});
log::trace(logcat, "{}:{} -> lokinet {}", peer.ip, peer.port, buffer_printer{data});
if (data.empty())
return;
@ -82,7 +88,7 @@ namespace llarp::quic
{
if (auto tcp = st.data<uvw::TCPHandle>())
{
LogTrace("Closing TCP connection");
log::trace(logcat, "Closing TCP connection...");
tcp->close();
}
};
@ -99,7 +105,8 @@ namespace llarp::quic
// This fires sometime after we call `close()` to signal that the close is done.
if (auto stream = c.data<Stream>())
{
LogInfo("Local TCP connection closed, closing associated quic stream ", stream->id());
log::info(
logcat, "Local TCP connection closed, closing associated quic stream id:{}", stream->id());
stream->close();
stream->data(nullptr);
}
@ -108,20 +115,17 @@ namespace llarp::quic
tcp.on<uvw::EndEvent>([](auto&, uvw::TCPHandle& c) {
// This fires on eof, most likely because the other side of the TCP connection
// closed it.
LogInfo("EOF on connection to ", c.peer().ip, ":", c.peer().port);
log::info(logcat, "EOF on connection to {}:{}", c.peer().ip, c.peer().port);
c.close();
});
tcp.on<uvw::ErrorEvent>([](const uvw::ErrorEvent& e, uvw::TCPHandle& tcp) {
LogError(
"ErrorEvent[",
log::error(
logcat,
"Error: [{}:{}] on connection with {}:{}; shutting down quic stream",
e.name(),
": ",
e.what(),
"] on connection with ",
tcp.peer().ip,
":",
tcp.peer().port,
", shutting down quic stream");
tcp.peer().port);
if (auto stream = tcp.data<Stream>())
{
stream->close(tunnel::ERROR_TCP);
@ -143,7 +147,7 @@ namespace llarp::quic
// (and forward the rest of the data to it if we got more than just the single byte).
void initial_client_data_handler(uvw::TCPHandle& client, Stream& stream, bstring_view bdata)
{
LogTrace("initial client handler; data: ", buffer_printer{bdata});
log::trace(logcat, "Initial client handler -- data: {}", buffer_printer{bdata});
if (bdata.empty())
return;
client.clear(); // Clear these initial event handlers: we either set up the proper
@ -160,14 +164,15 @@ namespace llarp::quic
bdata.remove_prefix(1);
stream.data_callback(stream, std::move(bdata));
}
LogTrace("starting client reading");
log::trace(logcat, "Starting client read...");
}
else
{
LogWarn(
"Remote connection returned invalid initial byte (0x",
oxenc::to_hex(bdata.begin(), bdata.begin() + 1),
"); dropping connection");
log::warning(
logcat,
"Remote connection returned invalid initial byte (0x{}); dropping connection",
oxenc::to_hex(bdata.begin(), bdata.begin() + 1));
stream.close(tunnel::ERROR_BAD_INIT);
client.close();
}
@ -182,14 +187,14 @@ namespace llarp::quic
uvw::TCPHandle& client, Stream& /*stream*/, std::optional<uint64_t> error_code)
{
if (error_code && *error_code == tunnel::ERROR_CONNECT)
LogDebug("Remote TCP connection failed, closing local connection");
log::debug(logcat, "Remote TCP connection failed, closing local connection");
else
LogWarn(
"Stream connection closed ",
error_code ? "with error " + std::to_string(*error_code) : "gracefully",
"; closing local TCP connection.");
log::warning(
logcat,
"Stream connection closed {}; closing local TCP connection.",
error_code ? "with error " + std::to_string(*error_code) : "gracefully");
auto peer = client.peer();
LogDebug("Closing connection to ", peer.ip, ":", peer.port);
log::debug(logcat, "Closing connection to {}:{}", peer.ip, peer.port);
client.clear();
// TOFIX: this logic
// if (error_code)
@ -204,7 +209,7 @@ namespace llarp::quic
{
// Cleanup callback to clear out closed tunnel connections
service_endpoint_.Loop()->call_every(500ms, timer_keepalive_, [this] {
LogTrace("Checking quic tunnels for finished connections");
log::trace(logcat, "Checking quic tunnels for finished connections...");
for (auto ctit = client_tunnels_.begin(); ctit != client_tunnels_.end();)
{
// Clear any accepted connections that have been closed:
@ -217,7 +222,7 @@ namespace llarp::quic
// congested.
if (not *it or not(*it)->data())
{
LogDebug("Cleanup up closed outgoing tunnel on quic:", port);
log::debug(logcat, "Cleanup up closed outgoing tunnel on quic port: {}", port);
it = ct.conns.erase(it);
}
else
@ -228,13 +233,14 @@ namespace llarp::quic
// ones then destroy the whole thing.
if (ct.conns.empty() and (not ct.tcp or not ct.tcp->active()))
{
LogDebug("All sockets closed on quic:", port, ", destroying tunnel data");
log::debug(logcat, "All sockets closed on quic port:{},destroying tunnel data", port);
ctit = client_tunnels_.erase(ctit);
}
else
++ctit;
}
LogTrace("Done quic tunnel cleanup check");
log::trace(logcat, "Finished quic tunnel cleanup!");
});
}
@ -250,7 +256,7 @@ namespace llarp::quic
auto remote = service_endpoint_.GetEndpointWithConvoTag(conn.path.remote);
if (!remote)
{
LogWarn("Received new stream open from invalid/unknown convo tag, dropping stream");
log::warning(logcat, "Received new stream open from invalid/unknown convo tag, dropping stream");
return false;
}
@ -258,43 +264,42 @@ namespace llarp::quic
auto tunnel_to = allow_connection(lokinet_addr, port);
if (not tunnel_to)
return false;
LogInfo("quic stream from ", lokinet_addr, " to ", port, " tunnelling to ", *tunnel_to);
log::info(logcat, "Quic stream from {} to port:{} tunnelling to {}", lokinet_addr, port, *tunnel_to);
auto tcp = get_loop()->resource<uvw::TCPHandle>();
[[maybe_unused]] auto error_handler =
tcp->once<uvw::ErrorEvent>([&stream, to = *tunnel_to](const uvw::ErrorEvent&, uvw::TCPHandle&) {
LogWarn("Failed to connect to ", to, ", shutting down quic stream");
log::warning(logcat, "Failed to connect to {}; shutting down quic stream", to);
stream.close(tunnel::ERROR_CONNECT);
});
// As soon as we connect to the local tcp tunnel port we fire a CONNECT_INIT down the
// stream tunnel to let the other end know the connection was successful, then set up
// regular stream handling to handle any other to/from data.
tcp->once<uvw::ConnectEvent>(
[streamw = stream.weak_from_this()](const uvw::ConnectEvent&, uvw::TCPHandle& tcp) {
auto peer = tcp.peer();
auto stream = streamw.lock();
if (!stream)
{
LogWarn(
"Connected to TCP ",
peer.ip,
":",
peer.port,
" but quic stream has gone away; close/resetting local TCP connection");
tcp.close();
return;
}
LogDebug("Connected to ", peer.ip, ":", peer.port, " for quic ", stream->id());
// Set up the data stream forwarding (which also clears these initial handlers).
install_stream_forwarding(tcp, *stream);
assert(stream->used() == 0);
// Send the magic byte, and start reading from the tcp tunnel in the logic
// thread
stream->append_buffer(new std::byte[1]{tunnel::CONNECT_INIT}, 1);
tcp.read();
});
tcp->once<uvw::ConnectEvent>([streamw = stream.weak_from_this()](
const uvw::ConnectEvent&, uvw::TCPHandle& tcp) {
auto peer = tcp.peer();
auto stream = streamw.lock();
if (!stream)
{
log::warning(
logcat,
"Connected to TCP {}:{} but quic stream has gone away; close/resetting local TCP connection",
peer.ip,
peer.port);
tcp.close();
return;
}
log::debug(logcat, "Connected to {}:{} for quic stream ID:{}", peer.ip, peer.port, stream->id());
// Set up the data stream forwarding (which also clears these initial handlers).
install_stream_forwarding(tcp, *stream);
assert(stream->used() == 0);
// Send the magic byte, and start reading from the tcp tunnel in the logic
// thread
stream->append_buffer(new std::byte[1]{tunnel::CONNECT_INIT}, 1);
tcp.read();
});
tcp->connect(*tunnel_to->operator const sockaddr*());
@ -318,7 +323,7 @@ namespace llarp::quic
int TunnelManager::listen(SockAddr addr)
{
return listen([addr](std::string_view, uint16_t p) -> std::optional<SockAddr> {
LogInfo("try accepting ", addr.getPort());
log::info(logcat, "try accepting {}", addr.getPort());
if (p == addr.getPort())
return addr;
return std::nullopt;
@ -341,18 +346,13 @@ namespace llarp::quic
}
catch (const std::exception& e)
{
LogWarn(
"Incoming quic connection from ",
lokinet_addr,
" to ",
port,
" denied via exception (",
e.what(),
")");
log::warning(
logcat, "Incoming Quic connection from {} to port:{} denied:{}", lokinet_addr, port, e.what());
return std::nullopt;
}
}
LogWarn("Incoming quic connection from ", lokinet_addr, " to ", port, " declined by all handlers");
log::warning(logcat, "Incoming Quic connection from {} to port:{} denied by all handlers!", lokinet_addr, port);
return std::nullopt;
}
@ -398,12 +398,12 @@ namespace llarp::quic
auto it = client_tunnels_.find(pseudo_port);
if (it == client_tunnels_.end())
{
LogDebug("QUIC tunnel to ", addr, " closed before ", step_name, " finished");
log::debug(logcat, "Quic tunnel to {} closed before step (name:{}) finished!", addr, step_name);
return false;
}
if (!step_success)
{
LogWarn("QUIC tunnel to ", addr, " failed during ", step_name, "; aborting tunnel");
log::warning(logcat, "Quic tunnel to {} failed during step (name:{}); aborting tunnel!", addr, step_name);
it->second.tcp->close();
if (it->second.open_cb)
it->second.open_cb(false);
@ -476,7 +476,7 @@ namespace llarp::quic
throw std::runtime_error{"Unable to open an outgoing quic connection: too many existing connections"};
(next_pseudo_port_ = pport)++;
LogInfo("Bound TCP tunnel ", saddr, " for quic client :", pport);
log::info(logcat, "Bound TCP tunnel {} for quic client pseudo_port:{}", saddr, pport);
// We are emplacing into client_tunnels_ here: beyond this point we must not throw until we
// return (or if we do, make sure we remove this row from client_tunnels_ first).
@ -568,7 +568,7 @@ namespace llarp::quic
auto conn = tunnel.client->get_connection();
conn->on_stream_available = [this, id = row.first](Connection&) {
LogDebug("QUIC connection :", id, " established; streams now available");
log::debug(logcat, "Quic connection (id:{}) established; streams now available", id);
if (auto it = client_tunnels_.find(id); it != client_tunnels_.end())
flush_pending_incoming(it->second);
};
@ -602,11 +602,11 @@ namespace llarp::quic
}
catch (const std::exception& e)
{
LogWarn("Opening quic stream failed: ", e.what());
log::warning(logcat, "Opening quic stream failed: {}", e.what());
tcp_client->close();
}
LogTrace("Set up new stream");
log::trace(logcat, "Set up new stream!");
conn.io_ready();
}
}
@ -615,7 +615,7 @@ namespace llarp::quic
{
if (buf.sz <= 4)
{
LogWarn("invalid quic packet: packet size (", buf.sz, ") too small");
log::warning(logcat, "Invalid quic packet: packet size ({}) too small", buf.sz);
return;
}
auto type = static_cast<std::byte>(buf.base[0]);
@ -629,26 +629,26 @@ namespace llarp::quic
quic::Endpoint* ep = nullptr;
if (type == CLIENT_TO_SERVER)
{
LogTrace("packet is client-to-server from client pport ", pseudo_port);
log::trace(logcat, "Packet is client-to-server from client pseudo-port:{}", pseudo_port);
// Client-to-server: the header port is the return port
remote.setPort(pseudo_port);
if (!server_)
{
LogWarn("Dropping incoming quic packet to server: no listeners");
log::warning(logcat, "Dropping incoming quic packet to server: no listeners");
return;
}
ep = server_.get();
}
else if (type == SERVER_TO_CLIENT)
{
LogTrace("packet is server-to-client to client pport ", pseudo_port);
log::trace(logcat, "Packet is server-to-client to client pseudo-port:{}", pseudo_port);
// Server-to-client: the header port tells us which client tunnel this is going to
if (auto it = client_tunnels_.find(pseudo_port); it != client_tunnels_.end())
ep = it->second.client.get();
if (not ep)
{
LogWarn("Incoming quic packet to invalid/closed client; dropping");
log::warning(logcat, "Incoming quic packet to invalid/closed client; dropping");
return;
}
@ -657,17 +657,17 @@ namespace llarp::quic
if (auto conn = static_cast<quic::Client&>(*ep).get_connection())
{
remote.setPort(conn->path.remote.port());
LogTrace("remote port is ", remote.getPort());
log::trace(logcat, "Remoter port is {}", remote.getPort());
}
else
{
LogWarn("Incoming quic to a quic::Client without an active quic::Connection; dropping");
log::warning(logcat, "Incoming quic to a quic::Client without an active quic::Connection; dropping");
return;
}
}
else
{
LogWarn("Invalid incoming quic packet type ", type, "; dropping packet");
log::warning(logcat, "Invalid incoming quic packet type {}; dropping packet", type);
return;
}
ep->receive_packet(remote, ecn, data);

@ -22,6 +22,8 @@
namespace
{
static auto logcat = oxen::log::Cat("liblokinet");
struct Context : public llarp::Context
{
using llarp::Context::Context;
@ -426,7 +428,7 @@ extern "C"
}
catch (std::invalid_argument& e)
{
llarp::LogError(e.what());
oxen::log::error(logcat, "{}", e.what());
}
return -1;
}
@ -454,7 +456,7 @@ extern "C"
{
if (not ctx->config->bootstrap.routers.BDecode(&buf))
{
llarp::LogError("Cannot decode bootstrap list: ", llarp::buffer_printer{buf});
oxen::log::error(logcat, "Cannot decode bootstrap list: {}}", llarp::buffer_printer{buf});
return -1;
}
for (const auto& rc : ctx->config->bootstrap.routers)
@ -468,7 +470,7 @@ extern "C"
llarp::RouterContact rc{};
if (not rc.BDecode(&buf))
{
llarp::LogError("failed to decode signle RC: ", llarp::buffer_printer{buf});
oxen::log::error(logcat, "failed to decode signle RC: {}", llarp::buffer_printer{buf});
return -1;
}
if (not rc.Verify(llarp::time_now_ms()))
@ -910,7 +912,7 @@ extern "C"
auto lock = ctx->acquire();
if (ctx->impl->router->loop()->inEventLoop())
{
llarp::LogError("cannot call udp_establish from internal event loop");
oxen::log::error(logcat, "Cannot call udp_establish from internal event loop");
return EINVAL;
}
if (auto itr = ctx->udp_sockets.find(remote->socket_id); itr != ctx->udp_sockets.end())

@ -17,6 +17,8 @@
namespace llarp::net
{
static auto logcat = log::Cat("win32.net");
class Platform_Impl : public Platform
{
/// visit all adapters (not addresses). windows serves net info per adapter unlink posix
@ -50,7 +52,8 @@ namespace llarp::net
for (auto* addr = a->FirstUnicastAddress; addr; addr = addr->Next)
{
oxen::quic::Address saddr{*addr->Address.lpSockaddr};
LogDebug(fmt::format("'{}' has address '{}'", a->AdapterName, saddr));
log::debug(logcat, "'{}' has address '{}", a->AdapterName, saddr);
if (saddr.getIP() == ip)
return true;
}
@ -83,8 +86,13 @@ namespace llarp::net
if (found)
return;
LogDebug(fmt::format(
"visit adapter looking for '{}': '{}' idx={}", ip, adapter->AdapterName, adapter->IfIndex));
log::debug(
logcat,
"Visit adapter looking for '{}': '{} idx={}",
ip,
adapter->AdapterName,
adapter->IfIndex);
if (adapter_has_ip(adapter, ip))
{
found = adapter->IfIndex;
@ -149,7 +157,7 @@ namespace llarp::net
}
});
return IPRange::FindPrivateRange(currentRanges);
return IPRange::find_private_range(currentRanges);
}
std::string loopback_interface_name() const override
@ -160,7 +168,7 @@ namespace llarp::net
bool has_interface_address(ip ip) const override
{
return GetInterfaceIndex(ip) != std::nullopt;
return get_interface_index(ip) != std::nullopt;
}
std::vector<InterfaceInfo> all_network_interfaces() const override

@ -9,6 +9,8 @@
namespace llarp::path
{
static auto logcat = log::Cat("path");
Path::Path(Router& rtr, const std::vector<RemoteRC>& h, std::weak_ptr<PathHandler> pathset, std::string shortName)
: handler{std::move(pathset)}, _router{rtr}, _short_name{std::move(shortName)}
{
@ -144,7 +146,7 @@ namespace llarp::path
}
catch (const std::exception& e)
{
log::warning(path_cat, "Error parsing path control message response: {}", e.what());
log::warning(logcat, "Error parsing path control message response: {}", e.what());
response_cb(messages::ERROR_RESPONSE);
return;
}
@ -283,7 +285,7 @@ namespace llarp::path
for (const auto& hop : hops)
new_hops.emplace_back(hop.rc);
LogInfo(name(), " rebuilding on ", short_name());
log::info(logcat, "{} rebuilding on {}", name(), short_name());
parent->build(new_hops);
}
}
@ -412,7 +414,7 @@ namespace llarp::path
reinterpret_cast<unsigned char*>(buf.data()) + payload.size(), PAD_SIZE -
payload.size());
}
log::debug(path_cat, "Sending {}B routing message to {}", buf.size(), Endpoint());
log::debug(logcat, "Sending {}B routing message to {}", buf.size(), Endpoint());
// TODO: path relaying here

@ -38,6 +38,8 @@ static constexpr std::chrono::milliseconds ROUTER_TICK_INTERVAL = 250ms;
namespace llarp
{
static auto logcat = log::Cat("router");
Router::Router(std::shared_ptr<EventLoop> loop, std::shared_ptr<vpn::Platform> vpnPlatform)
: _route_poker{std::make_shared<RoutePoker>(*this)},
_next_explore_at{std::chrono::steady_clock::now()},
@ -216,11 +218,11 @@ namespace llarp
if (is_service_node())
{
#if defined(ANDROID) || defined(IOS)
LogError("running a service node on mobile device is not possible.");
log::error(logcat, "running a service node on mobile device is not possible.");
return false;
#else
#if defined(_WIN32)
LogError("running a service node on windows is not possible.");
log::error(logcat, "running a service node on windows is not possible.");
return false;
#endif
#endif
@ -233,19 +235,15 @@ namespace llarp
{
_identity = rpc_client()->obtain_identity_key();
const RouterID pk{pubkey()};
LogWarn("Obtained lokid identity key: ", pk);
log::warning(logcat, "Obtained lokid identity key: {}", pk);
rpc_client()->start_pings();
break;
}
catch (const std::exception& e)
{
LogWarn(
"Failed attempt ",
numTries,
" of ",
maxTries,
" to get lokid identity keys because: ",
e.what());
log::warning(
logcat, "Failed attempt {} of {} to get oxend id keys: ", numTries, maxTries, e.what());
if (numTries == maxTries)
throw;
@ -336,14 +334,14 @@ namespace llarp
if (not if_net)
{
auto err = "Could not create net interface"s;
log::error(logcat, err);
log::error(logcat, "{}", err);
throw std::runtime_error{err};
}
if (not loop()->add_network_interface(
if_net, [](UDPPacket pkt [[maybe_unused]]) { /* OnInetPacket(std::move(pkt)); */ }))
{
auto err = "Could not create tunnel for net interface"s;
log::error(logcat, err);
log::error(logcat, "{}", err);
throw std::runtime_error{err};
}
@ -412,7 +410,7 @@ namespace llarp
netid,
_testnet ? "Please ensure your local instance is configured to operate on testnet"
: "Local lokinet instance will attempt to run on the specified network");
log::critical(logcat, err);
log::critical(logcat, "{}", err);
}
log::debug(logcat, "Configuring router");
@ -429,7 +427,7 @@ namespace llarp
_node_db = std::move(nodedb);
log::debug(logcat, _is_service_node ? "Running as a relay (service node)" : "Running as a client");
log::debug(logcat, "{}", _is_service_node ? "Running as a relay (service node)" : "Running as a client");
log::debug(logcat, "Initializing key manager");
if (not _key_manager->initialize(*_config, true, _is_service_node))
@ -1098,7 +1096,8 @@ namespace llarp
_is_stopping.store(true);
if (log::get_level_default() != log::Level::off)
log::reset_level(log::Level::info);
LogWarn("stopping router hard");
log::warning(logcat, "Hard stopping router");
llarp::sys::service_manager->stopping();
stop_sessions();
close();

@ -10,6 +10,8 @@
namespace llarp::rpc
{
static auto logcat = log::Cat("rpc.client");
static constexpr oxenmq::LogLevel toLokiMQLogLevel(log::Level level)
{
switch (level)
@ -53,12 +55,15 @@ namespace llarp::rpc
{
throw std::runtime_error("we cannot talk to lokid while not a service node");
}
LogInfo("connecting to lokid via LMQ at ", url.full_address());
log::info(logcat, "Connecting to oxend at {}", url.full_address());
m_Connection = m_lokiMQ->connect_remote(
url,
[](oxenmq::ConnectionID) {},
[self = shared_from_this(), url](oxenmq::ConnectionID, std::string_view f) {
llarp::LogWarn("Failed to connect to lokid: ", f);
log::info(logcat, "Failed to connect to oxend at {}", f);
if (auto router = self->_router.lock())
{
router->loop()->call([self, url]() { self->connect_async(url); });
@ -69,7 +74,7 @@ namespace llarp::rpc
void LokidRpcClient::command(std::string_view cmd)
{
LogDebug("lokid command: ", cmd);
log::debug(logcat, "Oxend command: {}", cmd);
m_lokiMQ->send(*m_Connection, std::move(cmd));
}
@ -77,10 +82,11 @@ namespace llarp::rpc
{
if (msg.data.size() != 2)
{
LogError(
"we got an invalid new block notification with ",
msg.data.size(),
" parts instead of 2 parts so we will not update the list of service nodes");
log::error(
logcat,
"Received invalid new block notification with {} parts (expected 2); not updating service node list!",
msg.data.size());
return; // bail
}
try
@ -89,7 +95,8 @@ namespace llarp::rpc
}
catch (std::exception& ex)
{
LogError("bad block height: ", ex.what());
log::error(logcat, "Bad block height: {}", ex.what());
return; // bail
}
@ -121,9 +128,9 @@ namespace llarp::rpc
"rpc.get_service_nodes",
[self = shared_from_this()](bool success, std::vector<std::string> data) {
if (not success)
LogWarn("failed to update service node list");
log::warning(logcat, "Failed to update service node list");
else if (data.size() < 2)
LogWarn("oxend gave empty reply for service node list");
log::warning(logcat, "Oxend gave empty reply for service node list");
else
{
try
@ -144,7 +151,7 @@ namespace llarp::rpc
}
catch (const std::exception& ex)
{
LogError("failed to process service node list: ", ex.what());
log::error(logcat, "Failed to process service node list: {}", ex.what());
}
}
@ -184,7 +191,7 @@ namespace llarp::rpc
"admin.lokinet_ping",
[](bool success, std::vector<std::string> data) {
(void)data;
LogDebug("Received response for ping. Successful: ", success);
log::debug(logcat, "Received response for ping. Successful: {}", success);
},
payload.dump());
@ -192,10 +199,10 @@ namespace llarp::rpc
self->request("sub.block", [](bool success, std::vector<std::string> data) {
if (data.empty() or not success)
{
LogError("failed to subscribe to new blocks");
log::error(logcat, "Failed to subscribe to new blocks");
return;
}
LogDebug("subscribed to new blocks: ", data[0]);
log::debug(logcat, "Subscribed to new blocks: {}", data[0]);
});
// Trigger an update on a regular timer as well in case we missed a block notify for
// some reason (e.g. oxend restarts and loses the subscription); we poll using the last
@ -264,7 +271,7 @@ namespace llarp::rpc
});
}
else
LogWarn("Cannot update whitelist: router object has gone away");
log::warning(logcat, "Cannot update whitelist: router object has gone away");
}
void LokidRpcClient::inform_connection(RouterID router, bool success)
@ -281,10 +288,10 @@ namespace llarp::rpc
[self = shared_from_this()](bool success, std::vector<std::string>) {
if (not success)
{
LogError("Failed to report connection status to oxend");
log::error(logcat, "Failed to report connection status to oxend");
return;
}
LogDebug("reported connection status to core");
log::debug(logcat, "Reported connection status to core");
},
req.dump());
}
@ -301,33 +308,27 @@ namespace llarp::rpc
try
{
if (not success)
{
throw std::runtime_error(
"failed to get private key request "
"failed");
}
throw std::runtime_error("Failed to get private key request");
if (data.empty() or data.size() < 2)
{
throw std::runtime_error(
"failed to get private key request "
"data empty");
}
throw std::runtime_error("Failed to get private key request: data empty");
const auto j = nlohmann::json::parse(data[1]);
SecretKey k;
if (not k.FromHex(j.at("service_node_ed25519_privkey").get<std::string>()))
{
throw std::runtime_error("failed to parse private key");
}
promise.set_value(k);
}
catch (const std::exception& e)
{
LogWarn("Caught exception while trying to request admin keys: ", e.what());
log::warning(logcat, "Caught exception while trying to request admin keys: {}", e.what());
promise.set_exception(std::current_exception());
}
catch (...)
{
LogWarn("Caught non-standard exception while trying to request admin keys");
log::warning(logcat, "Caught non-standard exception while trying to request admin keys");
promise.set_exception(std::current_exception());
}
});
@ -338,7 +339,7 @@ namespace llarp::rpc
void LokidRpcClient::lookup_ons_hash(
std::string namehash, std::function<void(std::optional<service::EncryptedName>)> resultHandler)
{
LogDebug("Looking Up LNS NameHash ", namehash);
log::debug(logcat, "Looking Up ONS NameHash {}", namehash);
const nlohmann::json req{{"type", 2}, {"name_hash", oxenc::to_hex(namehash)}};
request(
"rpc.lns_resolve",
@ -363,7 +364,7 @@ namespace llarp::rpc
}
catch (std::exception& ex)
{
LogError("failed to parse response from lns lookup: ", ex.what());
log::error(logcat, "Failed to parse response from ONS lookup: {}", ex.what());
}
}
if (auto r = _router.lock())

@ -98,7 +98,7 @@ namespace llarp::rpc
for (const auto& addr : r.config()->api.rpc_bind_addrs)
{
m_LMQ->listen_plain(addr.zmq_address());
LogInfo("Bound RPC server to ", addr.full_address());
log::info(logcat, "Bound RPC server to {}", addr.full_address());
}
AddCategories();

@ -51,7 +51,7 @@ namespace llarp::service
if (!self->m_LocalIdentity.KeyExchange(
crypto::dh_client, sharedSecret, self->m_remote, frame->nonce))
{
LogError("failed to derive x25519 shared key component");
log::error(logcat, "failed to derive x25519 shared key component");
}
auto buf = secret.bt_encode() + sharedSecret.bt_encode();
@ -67,7 +67,7 @@ namespace llarp::service
self->loop->call([self, frame] { AsyncKeyExchange::Result(self, frame); });
else
{
LogError("failed to encrypt and sign");
log::error(logcat, "failed to encrypt and sign");
}
*/
}

@ -573,7 +573,7 @@ namespace llarp::service
bool Endpoint::HandleDataDrop(std::shared_ptr<path::Path> p, const HopID& dst, uint64_t seq)
{
LogWarn(name(), " message ", seq, " dropped by endpoint ", p->pivot_router_id(), " via ", dst);
log::warning(logcat, "{} message (sqno:{}) dropped by pivot {} via {}", name(), seq, p->pivot_router_id(), dst);
return true;
}
@ -707,7 +707,7 @@ namespace llarp::service
{
if (not f.sign(_identity))
{
LogError("failed to sign auth reply result");
log::error(logcat, "Failed to sign auth reply result");
return;
}
}

@ -143,7 +143,8 @@ namespace llarp::service
if (not crypto::sign(sig, k, reinterpret_cast<uint8_t*>(bte.data()), bte.size()))
return false;
LogDebug("signed encrypted introset: ", *this);
log::debug(logcat, "Singed encrypted introset: {}", *this);
return true;
}

@ -203,23 +203,23 @@ namespace llarp
return _data.cend();
}
// TODO: move to .cpp file to add static logcat def
bool FromBytestring(llarp_buffer_t* buf)
{
if (buf->sz != sz)
{
llarp::LogError("bdecode buffer size mismatch ", buf->sz, "!=", sz);
// log::error(logcat, "bdecode buffer size mismatch {}!={}", buf->sz, sz);
return false;
}
memcpy(data(), buf->base, sz);
return true;
}
// TODO: move to .cpp file to add static logcat def
bool from_string(std::string_view b)
{
if (b.size() != sz)
{
log::error(logcat, "Error: buffer size mismatch in aligned buffer!");
// log::error(logcat, "Error: buffer size mismatch in aligned buffer!");
return false;
}

@ -18,6 +18,8 @@
namespace llarp::util
{
static auto logcat = log::Cat("util.file");
static std::streampos file_reader_impl(const fs::path& filename, fs::ifstream& in)
{
in.exceptions(std::ifstream::failbit | std::ifstream::badbit);
@ -87,7 +89,7 @@ namespace llarp::util
fs::permissions(pathname, perms, ec);
if (ec)
llarp::LogError("failed to set permissions on ", pathname);
log::error(logcat, "failed to set permissions on {}", pathname);
}
else // file is not there
{
@ -102,7 +104,7 @@ namespace llarp::util
#ifndef WIN32
if (ec)
llarp::LogError("failed to ensure ", str, ", ", ec.message());
log::error(logcat, "failed to ensure {}: {}", str, ec.message());
return ec;
#else
return {};

@ -12,107 +12,6 @@
namespace llarp
{
namespace log = oxen::log;
}
// Not ready to pollute these deprecation warnings everywhere yet
#if 0
#define LOKINET_LOG_DEPRECATED(Meth) [[deprecated("Use formatted log::" #Meth "(cat, fmt, args...) instead")]]
#else
#define LOKINET_LOG_DEPRECATED(Meth)
#endif
// Deprecated loggers (in the top-level llarp namespace):
namespace llarp
{
inline std::shared_ptr<log::RingBufferSink> logRingBuffer = nullptr;
namespace log_detail
{
inline log::CategoryLogger legacy_logger = log::Cat("");
template <typename>
struct concat_args_fmt_impl;
template <size_t... I>
struct concat_args_fmt_impl<std::integer_sequence<size_t, I...>>
{
static constexpr std::array<char, sizeof...(I)> format{(I % 2 == 0 ? '{' : '}')...};
};
template <size_t N>
constexpr std::string_view concat_args_fmt()
{
return std::string_view{concat_args_fmt_impl<std::make_index_sequence<2 * N>>::format.data(), 2 * N};
}
} // namespace log_detail
template <typename... T>
struct LOKINET_LOG_DEPRECATED(Trace) LogTrace : log::trace<T...>
{
LogTrace(T&&... args, const log::slns::source_location& location = log::slns::source_location::current())
: log::trace<T...>::trace{
log_detail::legacy_logger,
log_detail::concat_args_fmt<sizeof...(T)>(),
std::forward<T>(args)...,
location}
{}
};
template <typename... T>
struct LOKINET_LOG_DEPRECATED(Debug) LogDebug : log::debug<T...>
{
LogDebug(T&&... args, const log::slns::source_location& location = log::slns::source_location::current())
: log::debug<T...>::debug{
log_detail::legacy_logger,
log_detail::concat_args_fmt<sizeof...(T)>(),
std::forward<T>(args)...,
location}
{}
};
template <typename... T>
struct LOKINET_LOG_DEPRECATED(Info) LogInfo : log::info<T...>
{
LogInfo(T&&... args, const log::slns::source_location& location = log::slns::source_location::current())
: log::info<T...>::info{
log_detail::legacy_logger,
log_detail::concat_args_fmt<sizeof...(T)>(),
std::forward<T>(args)...,
location}
{}
};
template <typename... T>
struct LOKINET_LOG_DEPRECATED(Warning) LogWarn : log::warning<T...>
{
LogWarn(T&&... args, const log::slns::source_location& location = log::slns::source_location::current())
: log::warning<T...>::warning{
log_detail::legacy_logger,
log_detail::concat_args_fmt<sizeof...(T)>(),
std::forward<T>(args)...,
location}
{}
};
template <typename... T>
struct LOKINET_LOG_DEPRECATED(Error) LogError : log::error<T...>
{
LogError(T&&... args, const log::slns::source_location& location = log::slns::source_location::current())
: log::error<T...>::error{
log_detail::legacy_logger,
log_detail::concat_args_fmt<sizeof...(T)>(),
std::forward<T>(args)...,
location}
{}
};
template <typename... T>
LogTrace(T&&...) -> LogTrace<T...>;
template <typename... T>
LogDebug(T&&...) -> LogDebug<T...>;
template <typename... T>
LogInfo(T&&...) -> LogInfo<T...>;
template <typename... T>
LogWarn(T&&...) -> LogWarn<T...>;
template <typename... T>
LogError(T&&...) -> LogError<T...>;
} // namespace llarp

@ -16,38 +16,37 @@
extern "C" void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName);
#endif
namespace llarp
namespace llarp::util
{
namespace util
static auto logcat = log::Cat("util.threading");
void SetThreadName(const std::string& name)
{
void SetThreadName(const std::string& name)
{
#if defined(POSIX) || __MINGW32__
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
/* on bsd this function has void return type */
pthread_set_name_np(pthread_self(), name.c_str());
/* on bsd this function has void return type */
pthread_set_name_np(pthread_self(), name.c_str());
#else
#if defined(__MACH__)
const int rc = pthread_setname_np(name.c_str());
const int rc = pthread_setname_np(name.c_str());
// API present upstream since v2.11.3 and imported downstream
// in CR 8158 <https://www.illumos.org/issues/8158>
// We only use the native function on Microsoft C++ builds
#elif defined(__linux__) || defined(__sun) || __MINGW32__
const int rc = pthread_setname_np(pthread_self(), name.c_str());
const int rc = pthread_setname_np(pthread_self(), name.c_str());
#else
#error "unsupported platform"
#endif
if (rc)
{
LogError("Failed to set thread name to ", name, " errno = ", rc, " errstr = ", ::strerror(rc));
}
if (rc)
{
log::error(logcat, "Failed to set thread name to {} errno = {} errstr = {}", name, rc, ::strerror(rc));
}
#endif
#elif _MSC_VER
::SetThreadName(::GetCurrentThreadId(), name.c_str());
::SetThreadName(::GetCurrentThreadId(), name.c_str());
#else
LogInfo("Thread name setting not supported on this platform");
(void)name;
log::info(logcat, "Thread name setting not supported on this platform");
(void)name;
#endif
}
} // namespace util
} // namespace llarp
}
} // namespace llarp::util

@ -156,7 +156,8 @@ namespace llarp::win32
if (auto err = CreateUnicastIpAddressEntry(&AddressRow); err != ERROR_SUCCESS)
throw win32::error{err, fmt::format("cannot set address '{}'", addr.range)};
LogDebug(fmt::format("added address: '{}'", addr.range));
log::debug(logcat, "Added address: {}", addr.range);
}
}

Loading…
Cancel
Save