Replace logging with oxen-logger

Replaces custom logging system with spdlog-based oxen logging.  This
commit mainly replaces the backend logging with the spdlog-based system,
but doesn't (yet) convert all the existing LogWarn, etc. to use the new
format-based logging.

New logging statements will look like:

    llarp::log::warning(cat, "blah: {}", val);

where `cat` should be set up in each .cpp or cluster of .cpp files, as
described in the oxen-logging README.

As part of spdlog we get fmt, which gives us nice format strings, where
are applied generously in this commit.

Making types printable now requires two steps:
- add a ToString() method
- add this specialization:

      template <>
      constexpr inline bool llarp::IsToStringFormattable<llarp::Whatever> = true;

This will then allow the type to be printed as a "{}" value in a
fmt::format string.  This is applied to all our printable types here,
and all of the `operator<<` are removed.

This commit also:
- replaces various uses of `operator<<` to ToString()
- replaces various uses of std::stringstream with either fmt::format or
  plain std::string
- Rename some to_string and toString() methods to ToString() for
  consistency (and to work with fmt)
- Replace `stringify(...)` and `make_exception` usage with fmt::format
  (and remove stringify/make_exception from util/str.hpp).
pull/1955/head
Jason Rhinelander 2 years ago
parent 43191ec100
commit b81f7025c9
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262

@ -16,7 +16,10 @@ local default_deps = ['g++'] + default_deps_nocxx;
local default_windows_deps = ['mingw-w64', 'zip', 'nsis'];
local docker_base = 'registry.oxen.rocks/lokinet-ci-';
local submodule_commands = ['git fetch --tags', 'git submodule update --init --recursive --depth=1 --jobs=4'];
local submodule_commands = [
'git fetch --tags',
'git submodule update --init --recursive --depth=1 --jobs=4',
];
local submodules = {
name: 'submodules',
image: 'drone/git',

6
.gitmodules vendored

@ -10,9 +10,6 @@
[submodule "test/Catch2"]
path = test/Catch2
url = https://github.com/catchorg/Catch2
[submodule "external/date"]
path = external/date
url = https://github.com/HowardHinnant/date.git
[submodule "external/pybind11"]
path = external/pybind11
url = https://github.com/pybind/pybind11
@ -36,3 +33,6 @@
[submodule "external/oxen-encoding"]
path = external/oxen-encoding
url = https://github.com/oxen-io/oxen-encoding.git
[submodule "external/oxen-logging"]
path = external/oxen-logging
url = https://github.com/oxen-io/oxen-logging.git

@ -96,7 +96,6 @@ set(CMAKE_C_EXTENSIONS OFF)
include(cmake/target_link_libraries_system.cmake)
include(cmake/add_import_library.cmake)
include(cmake/add_log_tag.cmake)
include(cmake/libatomic.cmake)
if (STATIC_LINK)

@ -1,7 +0,0 @@
function(add_log_tag target)
get_target_property(TARGET_SRCS ${target} SOURCES)
foreach(F ${TARGET_SRCS})
get_filename_component(fpath "${F}" ABSOLUTE)
set_property(SOURCE ${F} APPEND PROPERTY COMPILE_DEFINITIONS SOURCE_ROOT=\"${PROJECT_SOURCE_DIR}\")
endforeach()
endfunction()

@ -57,7 +57,6 @@ else()
endif()
enable_lto(lokinet-cryptography)
add_log_tag(lokinet-cryptography)
if (WARNINGS_AS_ERRORS)
target_compile_options(lokinet-cryptography PUBLIC -Wall -Wextra -Werror)

@ -58,7 +58,6 @@ foreach(exe ${exetargets})
target_link_libraries(${exe} PUBLIC liblokinet)
target_include_directories(${exe} PUBLIC "${PROJECT_SOURCE_DIR}")
target_compile_definitions(${exe} PRIVATE -DVERSIONTAG=${GIT_VERSION_REAL})
add_log_tag(${exe})
if(should_install)
if(APPLE)
install(TARGETS ${exe} BUNDLE DESTINATION "${PROJECT_BINARY_DIR}" COMPONENT lokinet)

@ -3,8 +3,6 @@
#include <llarp.hpp>
#include <llarp/util/lokinet_init.h>
#include <llarp/util/fs.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging/ostream_logger.hpp>
#include <llarp/util/str.hpp>
#ifdef _WIN32
@ -379,11 +377,14 @@ main(int argc, char* argv[])
int
lokinet_main(int argc, char* argv[])
{
auto result = Lokinet_INIT();
if (result)
{
if (auto result = Lokinet_INIT())
return result;
}
// Set up a default, stderr logging for very early logging; we'll replace this later once we read
// the desired log info from config.
llarp::log::add_sink(llarp::log::Type::Print, "stderr");
llarp::log::reset_level(llarp::log::Level::info);
llarp::RuntimeOptions opts;
#ifdef _WIN32
@ -410,7 +411,6 @@ lokinet_main(int argc, char* argv[])
("g,generate", "generate default configuration and exit", cxxopts::value<bool>())
("r,router", "run in routing mode instead of client only mode", cxxopts::value<bool>())
("f,force", "force writing config even if it already exists", cxxopts::value<bool>())
("c,colour", "colour output", cxxopts::value<bool>()->default_value("true"))
("config", "path to lokinet.ini configuration file", cxxopts::value<std::string>())
;
// clang-format on
@ -424,12 +424,6 @@ lokinet_main(int argc, char* argv[])
{
auto result = options.parse(argc, argv);
if (!result["colour"].as<bool>())
{
llarp::LogContext::Instance().logStream =
std::make_unique<llarp::OStreamLogStream>(false, std::cerr);
}
if (result.count("help"))
{
std::cout << options.help() << std::endl;
@ -554,6 +548,7 @@ lokinet_main(int argc, char* argv[])
// do periodic non lokinet related tasks here
if (ctx and ctx->IsUp() and not ctx->LooksAlive())
{
auto deadlock_cat = llarp::log::Cat("deadlock");
for (const auto& wtf :
{"you have been visited by the mascott of the deadlocked router.",
"⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⣀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠄⠄⠄⠄",
@ -575,8 +570,8 @@ lokinet_main(int argc, char* argv[])
"file a bug report now or be cursed with this "
"annoying image in your syslog for all time."})
{
llarp::LogError{wtf};
llarp::LogContext::Instance().ImmediateFlush();
llarp::log::critical(deadlock_cat, wtf);
llarp::log::flush();
}
#ifdef _WIN32
TellWindowsServiceStopped();
@ -604,7 +599,7 @@ lokinet_main(int argc, char* argv[])
code = 2;
}
llarp::LogContext::Instance().ImmediateFlush();
llarp::log::flush();
if (ctx)
{
ctx.reset();

@ -12,13 +12,23 @@ if(SUBMODULE_CHECK)
else()
message(FATAL_ERROR "Submodule 'external/${relative_path}' is not up-to-date. Please update with\ngit submodule update --init --recursive\nor run cmake with -DSUBMODULE_CHECK=OFF")
endif()
# Extra arguments check nested submodules
foreach(submod ${ARGN})
execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path}/${submod} OUTPUT_VARIABLE localHead)
execute_process(COMMAND git rev-parse "HEAD:${submod}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path} OUTPUT_VARIABLE checkedHead)
string(COMPARE EQUAL "${localHead}" "${checkedHead}" upToDate)
if (NOT upToDate)
message(FATAL_ERROR "Nested submodule '${relative_path}/${submod}' is not up-to-date. Please update with\ngit submodule update --init --recursive\nor run cmake with -DSUBMODULE_CHECK=OFF")
endif()
endforeach()
endfunction ()
message(STATUS "Checking submodules")
check_submodule(nlohmann)
check_submodule(cxxopts)
check_submodule(ghc-filesystem)
check_submodule(date)
check_submodule(oxen-logging fmt spdlog)
check_submodule(pybind11)
check_submodule(sqlite_orm)
check_submodule(oxen-mq)
@ -56,13 +66,17 @@ system_or_submodule(OXENMQ oxenmq liboxenmq>=1.2.12 oxen-mq)
set(JSON_BuildTests OFF CACHE INTERNAL "")
system_or_submodule(NLOHMANN nlohmann_json nlohmann_json>=3.7.0 nlohmann)
if (STATIC OR FORCE_SPDLOG_SUBMODULE OR FORCE_FMT_SUBMODULE)
set(OXEN_LOGGING_FORCE_SUBMODULES ON CACHE INTERNAL "")
endif()
set(OXEN_LOGGING_SOURCE_ROOT "${PROJECT_SOURCE_DIR}" CACHE INTERNAL "")
add_subdirectory(oxen-logging)
if(WITH_HIVE)
add_subdirectory(pybind11 EXCLUDE_FROM_ALL)
endif()
add_subdirectory(cxxopts EXCLUDE_FROM_ALL)
add_subdirectory(date EXCLUDE_FROM_ALL)
add_library(sqlite_orm INTERFACE)
target_include_directories(sqlite_orm SYSTEM INTERFACE sqlite_orm/include)

1
external/date vendored

@ -1 +0,0 @@
Subproject commit cac99da8dc88be719a728dc1b597b0ac307c1800

@ -0,0 +1 @@
Subproject commit 0fc1b3528a52475c4007d734a7861faa2212fe75

@ -7,7 +7,7 @@ extern "C"
/// change our network id globally across all contexts
void EXPORT
lokinet_set_netid(const char*);
lokinet_set_netid(const char* netid);
/// get our current netid
/// must be free()'d after use
@ -15,17 +15,27 @@ extern "C"
lokinet_get_netid();
/// set log level
/// possible values: trace, debug, info, warn, error, none
/// possible values: trace, debug, info, warn, error, critical, none
/// return 0 on success
/// return non zero on fail
int EXPORT
lokinet_log_level(const char*);
lokinet_log_level(const char* level);
typedef void (*lokinet_logger_func)(const char*, void*);
/// Function pointer to invoke with lokinet log messages
typedef void (*lokinet_logger_func)(const char* message, void* context);
/// set a custom logger function
/// Optional function to call when flushing lokinet log messages; can be NULL if flushing is not
/// meaningful for the logging system.
typedef void (*lokinet_logger_sync)(void* context);
/// set a custom logger function; it is safe (and often desirable) to call this before calling
/// initializing lokinet via lokinet_context_new.
void EXPORT
lokinet_set_syncing_logger(lokinet_logger_func func, lokinet_logger_sync sync, void* context);
/// shortcut for calling `lokinet_set_syncing_logger` with a NULL sync
void EXPORT
lokinet_set_logger(lokinet_logger_func func, void* user);
lokinet_set_logger(lokinet_logger_func func, void* context);
/// @brief take in hex and turn it into base32z
/// @return value must be free()'d later

@ -8,12 +8,6 @@ add_library(lokinet-util
util/fs.cpp
util/json.cpp
util/logging/buffer.cpp
util/logging/file_logger.cpp
util/logging/logger.cpp
util/logging/logger_internal.cpp
util/logging/loglevel.cpp
util/logging/ostream_logger.cpp
util/logging/syslog_logger.cpp
util/lokinet_init.c
util/mem.cpp
util/printer.cpp
@ -31,8 +25,8 @@ target_link_libraries(lokinet-util PUBLIC
lokinet-cryptography
nlohmann_json::nlohmann_json
filesystem
date::date
oxenc::oxenc
oxen::logging
)
if(ANDROID)
@ -213,7 +207,6 @@ add_library(liblokinet
service/name.cpp
service/outbound_context.cpp
service/protocol.cpp
service/protocol_type.cpp
service/router_lookup_job.cpp
service/sendcontext.cpp
service/session.cpp
@ -236,7 +229,15 @@ if(WITH_HIVE)
)
endif()
target_link_libraries(liblokinet PUBLIC cxxopts oxenc::oxenc lokinet-platform lokinet-util lokinet-cryptography sqlite_orm ngtcp2_static oxenmq::oxenmq)
target_link_libraries(liblokinet PUBLIC
cxxopts
oxenc::oxenc
lokinet-platform
lokinet-util
lokinet-cryptography
sqlite_orm
ngtcp2_static
oxenmq::oxenmq)
target_link_libraries(liblokinet PRIVATE libunbound)
pkg_check_modules(CRYPT libcrypt IMPORTED_TARGET)
if(CRYPT_FOUND AND NOT CMAKE_CROSSCOMPILING)
@ -262,17 +263,12 @@ if(BUILD_LIBLOKINET)
else()
install(TARGETS lokinet-shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT liblokinet)
endif()
add_log_tag(lokinet-shared)
endif()
if(APPLE)
add_subdirectory(apple)
endif()
foreach(lokinet_lib liblokinet lokinet-platform lokinet-util lokinet-cryptography)
add_log_tag(${lokinet_lib})
endforeach()
file(GLOB_RECURSE docs_SRC */*.hpp *.hpp)
set(DOCS_SRC ${docs_SRC} PARENT_SCOPE)

@ -1,25 +0,0 @@
#include "apple_logger.hpp"
namespace llarp::apple
{
void
NSLogStream::PreLog(
std::stringstream& ss,
LogLevel lvl,
std::string_view fname,
int lineno,
const std::string& nodename) const
{
ss << "[" << LogLevelToString(lvl) << "] ";
ss << "[" << nodename << "]"
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno
<< "\t";
}
void
NSLogStream::Print(LogLevel, std::string_view, const std::string& msg)
{
ns_logger(msg.c_str());
}
} // namespace llarp::apple

@ -1,40 +0,0 @@
#pragma once
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging/logstream.hpp>
namespace llarp::apple
{
struct NSLogStream : public ILogStream
{
using ns_logger_callback = void (*)(const char* log_this);
NSLogStream(ns_logger_callback logger) : ns_logger{logger}
{}
void
PreLog(
std::stringstream& s,
LogLevel lvl,
std::string_view fname,
int lineno,
const std::string& nodename) const override;
void
Print(LogLevel lvl, std::string_view tag, const std::string& msg) override;
void
PostLog(std::stringstream&) const override
{}
void
ImmediateFlush() override
{}
void Tick(llarp_time_t) override
{}
private:
ns_logger_callback ns_logger;
};
} // namespace llarp::apple

@ -6,10 +6,11 @@
#include <llarp/util/fs.hpp>
#include <llarp/util/logging/buffer.hpp>
#include <uvw/loop.h>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging/callback_sink.hpp>
#include "vpn_interface.hpp"
#include "context_wrapper.h"
#include "context.hpp"
#include "apple_logger.hpp"
namespace
{
@ -34,8 +35,10 @@ const uint16_t dns_trampoline_port = 1053;
void*
llarp_apple_init(llarp_apple_config* appleconf)
{
llarp::LogContext::Instance().logStream =
std::make_unique<llarp::apple::NSLogStream>(appleconf->ns_logger);
llarp::log::ReplaceLogger(std::make_shared<llarp::log::CallbackSink_mt>(
[](const char* msg, void* nslog) { reinterpret_cast<ns_logger_callback>(nslog)(msg); },
nullptr,
appleconf->ns_logger));
try
{
@ -43,7 +46,7 @@ llarp_apple_init(llarp_apple_config* appleconf)
auto config = std::make_shared<llarp::Config>(config_dir);
fs::path config_path = config_dir / "lokinet.ini";
if (!fs::exists(config_path))
llarp::ensureConfig(config_dir, config_path, /*overwrite=*/false, /*router=*/false);
llarp::ensureConfig(config_dir, config_path, /*overwrite=*/false, /*asRouter=*/false);
config->Load(config_path);
// If no range is specified then go look for a free one, set that in the config, and then return

@ -1,6 +1,6 @@
#include "bootstrap.hpp"
#include "util/bencode.hpp"
#include "util/logging/logger.hpp"
#include "util/logging.hpp"
#include "util/logging/buffer.hpp"
namespace llarp

@ -4,12 +4,15 @@
#include "config/definition.hpp"
#include "ini.hpp"
#include <llarp/constants/files.hpp>
#include <llarp/constants/platform.hpp>
#include <llarp/constants/version.hpp>
#include <llarp/net/net.hpp>
#include <llarp/net/ip.hpp>
#include <llarp/router_contact.hpp>
#include <stdexcept>
#include <llarp/util/fs.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/formattable.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/mem.hpp>
#include <llarp/util/str.hpp>
@ -19,7 +22,6 @@
#include <fstream>
#include <ios>
#include <iostream>
#include <llarp/constants/version.hpp>
namespace llarp
{
@ -58,8 +60,8 @@ namespace llarp
},
[this](std::string arg) {
if (arg.size() > NetID::size())
throw std::invalid_argument(
stringify("netid is too long, max length is ", NetID::size()));
throw std::invalid_argument{
fmt::format("netid is too long, max length is {}", NetID::size())};
m_netId = std::move(arg);
});
@ -75,7 +77,8 @@ namespace llarp
},
[=](int arg) {
if (arg < minConnections)
throw std::invalid_argument(stringify("min-connections must be >= ", minConnections));
throw std::invalid_argument{
fmt::format("min-connections must be >= {}", minConnections)};
m_minConnectedRouters = arg;
});
@ -91,7 +94,8 @@ namespace llarp
},
[=](int arg) {
if (arg < maxConnections)
throw std::invalid_argument(stringify("max-connections must be >= ", maxConnections));
throw std::invalid_argument{
fmt::format("max-connections must be >= {}", maxConnections)};
m_maxConnectedRouters = arg;
});
@ -110,8 +114,8 @@ namespace llarp
if (arg.empty())
throw std::invalid_argument("[router]:data-dir is empty");
if (not fs::exists(arg))
throw std::runtime_error(
stringify("Specified [router]:data-dir ", arg, " does not exist"));
throw std::runtime_error{
fmt::format("Specified [router]:data-dir {} does not exist", arg)};
m_dataDir = std::move(arg);
});
@ -130,11 +134,11 @@ namespace llarp
return;
nuint32_t addr{};
if (not addr.FromString(arg))
throw std::invalid_argument{stringify(arg, " is not a valid IPv4 address")};
throw std::invalid_argument{fmt::format("{} is not a valid IPv4 address", arg)};
if (IsIPv4Bogon(addr))
throw std::invalid_argument{
stringify(addr, " looks like it is not a publicly routable ip address")};
fmt::format("{} is not a publicly routable ip address", addr)};
m_PublicIP = addr;
});
@ -352,7 +356,7 @@ namespace llarp
[this](std::string arg) {
service::Address addr;
if (not addr.FromString(arg))
throw std::invalid_argument(stringify("bad loki address: ", arg));
throw std::invalid_argument{fmt::format("bad loki address: {}", arg)};
m_AuthWhitelist.emplace(std::move(addr));
});
@ -368,7 +372,7 @@ namespace llarp
[this](fs::path arg) {
if (not fs::exists(arg))
throw std::invalid_argument{
stringify("cannot load auth file ", arg, " as it does not seem to exist")};
fmt::format("cannot load auth file {}: file does not exist", arg)};
m_AuthFiles.emplace(std::move(arg));
});
conf.defineOption<std::string>(
@ -514,7 +518,7 @@ namespace llarp
if (arg != "null" and not exit.FromString(arg))
{
throw std::invalid_argument(stringify("[network]:exit-node bad address: ", arg));
throw std::invalid_argument{fmt::format("[network]:exit-node bad address: {}", arg)};
}
m_ExitMap.Insert(range, exit);
});
@ -603,7 +607,7 @@ namespace llarp
[this](std::string arg) {
if (not m_ifaddr.FromString(arg))
{
throw std::invalid_argument(stringify("[network]:ifaddr invalid value: '", arg, "'"));
throw std::invalid_argument{fmt::format("[network]:ifaddr invalid value: '{}'", arg)};
}
});
@ -630,8 +634,8 @@ namespace llarp
}
m_baseV6Address = huint128_t{};
if (not m_baseV6Address->FromString(arg))
throw std::invalid_argument(
stringify("[network]:ip6-range invalid value: '", arg, "'"));
throw std::invalid_argument{
fmt::format("[network]:ip6-range invalid value: '{}'", arg)};
});
// TODO: could be useful for snodes in the future, but currently only implemented for clients:
conf.defineOption<std::string>(
@ -653,7 +657,7 @@ namespace llarp
const auto pos = arg.find(":");
if (pos == std::string::npos)
{
throw std::invalid_argument(stringify("[endpoint]:mapaddr invalid entry: ", arg));
throw std::invalid_argument{fmt::format("[endpoint]:mapaddr invalid entry: {}", arg)};
}
std::string addrstr = arg.substr(0, pos);
std::string ipstr = arg.substr(pos + 1);
@ -662,18 +666,19 @@ namespace llarp
huint32_t ipv4;
if (not ipv4.FromString(ipstr))
{
throw std::invalid_argument(stringify("[endpoint]:mapaddr invalid ip: ", ipstr));
throw std::invalid_argument{fmt::format("[endpoint]:mapaddr invalid ip: {}", ipstr)};
}
ip = net::ExpandV4(ipv4);
}
if (not addr.FromString(addrstr))
{
throw std::invalid_argument(
stringify("[endpoint]:mapaddr invalid addresss: ", addrstr));
throw std::invalid_argument{
fmt::format("[endpoint]:mapaddr invalid addresss: {}", addrstr)};
}
if (m_mapAddrs.find(ip) != m_mapAddrs.end())
{
throw std::invalid_argument(stringify("[endpoint]:mapaddr ip already mapped: ", ipstr));
throw std::invalid_argument{
fmt::format("[endpoint]:mapaddr ip already mapped: {}", ipstr)};
}
m_mapAddrs[ip] = addr;
});
@ -690,11 +695,11 @@ namespace llarp
[this](std::string arg) {
RouterID id;
if (not id.FromString(arg))
throw std::invalid_argument(stringify("Invalid RouterID: ", arg));
throw std::invalid_argument{fmt::format("Invalid RouterID: {}", arg)};
auto itr = m_snodeBlacklist.emplace(std::move(id));
if (not itr.second)
throw std::invalid_argument(stringify("Duplicate blacklist-snode: ", arg));
throw std::invalid_argument{fmt::format("Duplicate blacklist-snode: {}", arg)};
});
// TODO: support SRV records for routers, but for now client only
@ -711,7 +716,7 @@ namespace llarp
[this](std::string arg) {
llarp::dns::SRVData newSRV;
if (not newSRV.fromString(arg))
throw std::invalid_argument(stringify("Invalid SRV Record string: ", arg));
throw std::invalid_argument{fmt::format("Invalid SRV Record string: {}", arg)};
m_SRVRecords.push_back(std::move(newSRV));
});
@ -817,7 +822,7 @@ namespace llarp
return;
if (not fs::exists(path))
throw std::invalid_argument{
stringify("cannot add hosts file ", path, " as it does not seem to exist")};
fmt::format("cannot add hosts file {} as it does not exist", path)};
m_hostfiles.emplace_back(std::move(path));
});
@ -897,7 +902,7 @@ namespace llarp
"if the 0.0.0.0 all-address IP is given then you must also specify the",
"public-ip= and public-port= settings in the [router] section with a public",
"address at which this router can be reached.",
""
"",
"Typically this section can be left blank: if no inbound bind addresses are",
"configured then lokinet will search for a local network interface with a public",
"IP address and use that (with port 1090).",
@ -932,8 +937,8 @@ namespace llarp
LinkInfo info = LinkInfoFromINIValues(name, value);
if (info.port <= 0)
throw std::invalid_argument(
stringify("Invalid [bind] port specified on interface", name));
throw std::invalid_argument{
fmt::format("Invalid [bind] port specified on interface {}", name)};
assert(name != "*"); // handled by defineOption("bind", "*", ...) above
@ -950,14 +955,11 @@ namespace llarp
"connect", [this](std::string_view section, std::string_view name, std::string_view value) {
fs::path file{value.begin(), value.end()};
if (not fs::exists(file))
throw std::runtime_error(stringify(
"Specified bootstrap file ",
throw std::runtime_error{fmt::format(
"Specified bootstrap file {} specified in [{}]:{} does not exist",
value,
"specified in [",
section,
"]:",
name,
" does not exist"));
name)};
routers.emplace_back(std::move(file));
return true;
@ -1088,7 +1090,8 @@ namespace llarp
{
(void)params;
constexpr Default DefaultLogType{"file"};
constexpr Default DefaultLogType{
platform::is_android or platform::is_apple ? "system" : "print"};
constexpr Default DefaultLogFile{""};
constexpr Default DefaultLogLevel{"warn"};
@ -1097,16 +1100,17 @@ namespace llarp
"type",
DefaultLogType,
[this](std::string arg) {
LogType type = LogTypeFromString(arg);
if (type == LogType::Unknown)
throw std::invalid_argument(stringify("invalid log type: ", arg));
auto type = log::type_from_string(arg);
if (type == log::Type::Unknown)
throw std::invalid_argument{fmt::format("invalid log type: {}", arg)};
m_logType = type;
},
Comment{
"Log type (format). Valid options are:",
" file - plaintext formatting",
" syslog - logs directed to syslog",
" print - print logs to standard output",
" system - logs directed to the system logger (syslog/eventlog/etc.)",
" file - plaintext formatting to a file",
});
conf.defineOption<std::string>(
@ -1114,9 +1118,9 @@ namespace llarp
"level",
DefaultLogLevel,
[this](std::string arg) {
std::optional<LogLevel> level = LogLevelFromString(arg);
std::optional<log::Level> level = log::level_from_string(arg);
if (not level)
throw std::invalid_argument(stringify("invalid log level value: ", arg));
throw std::invalid_argument{fmt::format("invalid log level value: {}", arg)};
m_logLevel = *level;
},
@ -1128,6 +1132,8 @@ namespace llarp
" info",
" warn",
" error",
" critical",
" none",
});
conf.defineOption<std::string>(
@ -1136,9 +1142,7 @@ namespace llarp
DefaultLogFile,
AssignmentAcceptor(m_logFile),
Comment{
"When using type=file this is the output filename. If given the value 'stdout' or",
"left empty then logging is printed as standard output rather than written to a",
"file.",
"When using type=file this is the output filename.",
});
}
@ -1390,7 +1394,7 @@ namespace llarp
// open a filestream
auto stream = llarp::util::OpenFileStream<std::ofstream>(confFile.c_str(), std::ios::binary);
if (not stream or not stream->is_open())
throw std::runtime_error(stringify("Failed to open file ", confFile, " for writing"));
throw std::runtime_error{fmt::format("Failed to open file {} for writing", confFile)};
*stream << confStr;
stream->flush();
@ -1495,7 +1499,7 @@ namespace llarp
{
auto config = std::make_shared<Config>(fs::path{});
config->Load();
config->logging.m_logLevel = eLogNone;
config->logging.m_logLevel = log::Level::off;
config->api.m_enableRPCServer = false;
config->network.m_endpointType = "null";
config->network.m_saveProfiles = false;

@ -6,6 +6,7 @@
#include <llarp/router_contact.hpp>
#include <llarp/util/fs.hpp>
#include <llarp/util/str.hpp>
#include <llarp/util/logging.hpp>
#include "ini.hpp"
#include "definition.hpp"
#include <llarp/constants/files.hpp>
@ -209,8 +210,8 @@ namespace llarp
struct LoggingConfig
{
LogType m_logType = LogType::Unknown;
LogLevel m_logLevel = eLogNone;
log::Type m_logType = log::Type::Unknown;
log::Level m_logLevel = log::Level::off;
std::string m_logFile;
void

@ -1,5 +1,5 @@
#include "definition.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <iterator>
#include <sstream>
@ -17,7 +17,7 @@ namespace llarp
else if (input == "true" || input == "on" || input == "1" || input == "yes")
return true;
else
throw std::invalid_argument(stringify(input, " is not a valid bool"));
throw std::invalid_argument{fmt::format("{} is not a valid bool", input)};
}
ConfigDefinition&
@ -53,8 +53,8 @@ namespace llarp
auto [it, added] = m_definitions[section].try_emplace(std::string{def->name}, std::move(def));
if (!added)
throw std::invalid_argument(
stringify("definition for [", def->section, "]:", def->name, " already exists"));
throw std::invalid_argument{
fmt::format("definition for [{}]:{} already exists", def->section, def->name)};
m_definitionOrdering[section].push_back(it->first);
@ -79,13 +79,10 @@ namespace llarp
{
// fallback to undeclared handler if available
if (not haveUndeclaredHandler)
throw std::invalid_argument(stringify("unrecognized section [", section, "]"));
else
{
auto& handler = undItr->second;
handler(section, name, value);
return *this;
}
throw std::invalid_argument{fmt::format("unrecognized section [{}]", section)};
auto& handler = undItr->second;
handler(section, name, value);
return *this;
}
// section was valid, get definition by name
@ -95,13 +92,10 @@ namespace llarp
if (defItr == sectionDefinitions.end())
{
if (not haveUndeclaredHandler)
throw std::invalid_argument(stringify("unrecognized option [", section, "]:", name));
else
{
auto& handler = undItr->second;
handler(section, name, value);
return *this;
}
throw std::invalid_argument{fmt::format("unrecognized option [{}]:{}", section, name)};
auto& handler = undItr->second;
handler(section, name, value);
return *this;
}
OptionDefinition_ptr& definition = defItr->second;
@ -115,7 +109,7 @@ namespace llarp
{
auto itr = m_undeclaredHandlers.find(section);
if (itr != m_undeclaredHandlers.end())
throw std::logic_error(stringify("section ", section, " already has a handler"));
throw std::logic_error{fmt::format("section {} already has a handler", section)};
m_undeclaredHandlers[section] = std::move(handler);
}
@ -135,8 +129,8 @@ namespace llarp
visitDefinitions(section, [&](const std::string&, const OptionDefinition_ptr& def) {
if (def->required and def->getNumberFound() < 1)
{
throw std::invalid_argument(
stringify("[", section, "]:", def->name, " is required but missing"));
throw std::invalid_argument{
fmt::format("[{}]:{} is required but missing", section, def->name)};
}
// should be handled earlier in OptionDefinition::parseValue()
@ -241,12 +235,13 @@ namespace llarp
{
const auto sectionItr = m_definitions.find(std::string(section));
if (sectionItr == m_definitions.end())
throw std::invalid_argument(stringify("No config section [", section, "]"));
throw std::invalid_argument{fmt::format("No config section [{}]", section)};
auto& sectionDefinitions = sectionItr->second;
const auto definitionItr = sectionDefinitions.find(std::string(name));
if (definitionItr == sectionDefinitions.end())
throw std::invalid_argument(stringify("No config item ", name, " within section ", section));
throw std::invalid_argument{
fmt::format("No config item {} within section {}", name, section)};
return definitionItr->second;
}

@ -1,5 +1,6 @@
#pragma once
#include <fmt/core.h>
#include <initializer_list>
#include <type_traits>
#include <llarp/util/str.hpp>
@ -259,8 +260,8 @@ namespace llarp
getValueAt(size_t index) const
{
if (index >= parsedValues.size())
throw std::range_error(
stringify("no value at index ", index, ", size: ", parsedValues.size()));
throw std::range_error{
fmt::format("no value at index {}, size: {}", index, parsedValues.size())};
return parsedValues[index];
}
@ -293,8 +294,8 @@ namespace llarp
{
if (not multiValued and parsedValues.size() > 0)
{
throw std::invalid_argument(
stringify("duplicate value for ", name, ", previous value: ", parsedValues[0]));
throw std::invalid_argument{
fmt::format("duplicate value for {}, previous value: {}", name, parsedValues[0])};
}
parsedValues.emplace_back(fromString(input));
@ -313,7 +314,7 @@ namespace llarp
T t;
iss >> t;
if (iss.fail())
throw std::invalid_argument(stringify(input, " is not a valid ", typeid(T).name()));
throw std::invalid_argument{fmt::format("{} is not a valid {}", input, typeid(T).name())};
else
return t;
}
@ -341,12 +342,10 @@ namespace llarp
{
if (required and parsedValues.size() == 0)
{
throw std::runtime_error(stringify(
"cannot call tryAccept() on [",
throw std::runtime_error{fmt::format(
"cannot call tryAccept() on [{}]:{} when required but no value available",
section,
"]:",
name,
" when required but no value available"));
name)};
}
// don't use default value if we are multi-valued and have no value
@ -472,8 +471,8 @@ namespace llarp
auto derived = dynamic_cast<const OptionDefinition<T>*>(definition.get());
if (not derived)
throw std::invalid_argument(
stringify("", typeid(T).name(), " is the incorrect type for [", section, "]:", name));
throw std::invalid_argument{
fmt::format("{} is the incorrect type for [{}]:{}", typeid(T).name(), section, name)};
return derived->getValue();
}

@ -1,6 +1,7 @@
#include "ini.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/formattable.hpp>
#include <llarp/util/str.hpp>
#include <cctype>

@ -1,7 +1,7 @@
#include "key_manager.hpp"
#include <system_error>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include "config.hpp"
#include <llarp/crypto/crypto.hpp>
#include <llarp/crypto/types.hpp>

@ -2,7 +2,7 @@
#include "reachability_testing.hpp"
#include <chrono>
#include <llarp/router/abstractrouter.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/crypto/crypto.hpp>
using std::chrono::steady_clock;

@ -10,7 +10,7 @@
#include "nodedb.hpp"
#include "router/router.hpp"
#include "service/context.hpp"
#include "util/logging/logger.hpp"
#include "util/logging.hpp"
#include <cxxopts.hpp>
#include <csignal>

@ -1,7 +1,7 @@
#include "encrypted_frame.hpp"
#include "crypto.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/mem.hpp>
namespace llarp

@ -35,7 +35,7 @@ namespace llarp
operator RouterID() const
{
return RouterID(as_array());
return {as_array()};
}
PubKey&
@ -46,12 +46,6 @@ namespace llarp
}
};
inline std::ostream&
operator<<(std::ostream& out, const PubKey& k)
{
return out << k.ToString();
}
inline bool
operator==(const PubKey& lhs, const PubKey& rhs)
{
@ -97,12 +91,10 @@ namespace llarp
bool
Recalculate();
std::ostream&
print(std::ostream& stream, int level, int spaces) const
std::string_view
ToString() const
{
Printer printer(stream, level, spaces);
printer.printValue("secretkey");
return stream;
return "[secretkey]";
}
PubKey
@ -123,14 +115,6 @@ namespace llarp
SaveToFile(const fs::path& fname) const;
};
inline std::ostream&
operator<<(std::ostream& out, const SecretKey&)
{
// return out << k.ToHex();
// make sure we never print out secret keys
return out << "[secretkey]";
}
/// PrivateKey is similar to SecretKey except that it only stores the private
/// key value and a hash, unlike SecretKey which stores the seed from which
/// the private key and hash value are generated. This is primarily intended
@ -162,12 +146,10 @@ namespace llarp
return data() + 32;
}
std::ostream&
print(std::ostream& stream, int level, int spaces) const
std::string_view
ToString() const
{
Printer printer(stream, level, spaces);
printer.printValue("privatekey");
return stream;
return "[privatekey]";
}
/// Computes the public key
@ -175,14 +157,6 @@ namespace llarp
toPublic(PubKey& pubkey) const;
};
inline std::ostream&
operator<<(std::ostream& out, const PrivateKey&)
{
// return out << k.ToHex();
// make sure we never print out private keys
return out << "[privatekey]";
}
/// IdentitySecret is a secret key from a service node secret seed
struct IdentitySecret final : public AlignedBuffer<32>
{
@ -197,14 +171,22 @@ namespace llarp
/// load service node seed from file
bool
LoadFromFile(const fs::path& fname);
std::string_view
ToString() const
{
return "[IdentitySecret]";
}
};
inline std::ostream&
operator<<(std::ostream& out, const IdentitySecret&)
{
// make sure we never print out secret keys
return out << "[IdentitySecret]";
}
template <>
constexpr inline bool IsToStringFormattable<PubKey> = true;
template <>
constexpr inline bool IsToStringFormattable<SecretKey> = true;
template <>
constexpr inline bool IsToStringFormattable<PrivateKey> = true;
template <>
constexpr inline bool IsToStringFormattable<IdentitySecret> = true;
using ShortHash = AlignedBuffer<SHORTHASHSIZE>;
using LongHash = AlignedBuffer<HASHSIZE>;

@ -2,6 +2,7 @@
#include <llarp/util/aligned.hpp>
#include <llarp/router_id.hpp>
#include <llarp/util/formattable.hpp>
#include <array>

@ -6,7 +6,7 @@
#include <llarp/path/path_context.hpp>
#include <llarp/router/abstractrouter.hpp>
#include <llarp/routing/dht_message.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
namespace llarp
{

@ -5,7 +5,7 @@
#include <llarp/path/path_context.hpp>
#include <llarp/router/abstractrouter.hpp>
#include <llarp/routing/dht_message.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
namespace llarp
{

@ -3,7 +3,7 @@
#include "key.hpp"
#include "txowner.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/status.hpp>
#include <set>

@ -4,7 +4,7 @@
#include "dns.hpp"
#include "srv_data.hpp"
#include <llarp/util/buffer.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/printer.hpp>
#include <llarp/net/ip.hpp>

@ -96,6 +96,14 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
MsgID_t hdr_id;
Fields_t hdr_fields;
std::vector<Question> questions;
@ -103,12 +111,8 @@ namespace llarp
std::vector<ResourceRecord> authorities;
std::vector<ResourceRecord> additional;
};
inline std::ostream&
operator<<(std::ostream& out, const Message& msg)
{
msg.print(out, -1, -1);
return out;
}
} // namespace dns
template <>
constexpr inline bool IsToStringFormattable<llarp::dns::Message> = true;
} // namespace llarp

@ -1,6 +1,6 @@
#include "question.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/printer.hpp>
#include <llarp/util/str.hpp>
#include "dns.hpp"
@ -117,10 +117,18 @@ namespace llarp
&& qname.rfind(tld) == (qname.size() - tld.size()) - 1;
}
std::string
Question::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
std::ostream&
Question::print(std::ostream& stream, int level, int spaces) const
{
Printer printer(stream, level, spaces);
std::ostringstream o;
Printer printer(o, level, spaces);
printer.printAttribute("qname", qname);
printer.printAttributeAsHex("qtype", qtype);
printer.printAttributeAsHex("qclass", qclass);

@ -25,6 +25,8 @@ namespace llarp
bool
Decode(llarp_buffer_t* buf) override;
std::string
ToString() const;
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
@ -65,12 +67,8 @@ namespace llarp
util::StatusObject
ToJSON() const override;
};
inline std::ostream&
operator<<(std::ostream& out, const Question& q)
{
q.print(out, -1, -1);
return out;
}
} // namespace dns
} // namespace llarp
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::dns::Question> = true;

@ -1,7 +1,7 @@
#include "rr.hpp"
#include "dns.hpp"
#include <llarp/util/mem.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/printer.hpp>
namespace llarp
@ -109,6 +109,14 @@ namespace llarp
return stream;
}
std::string
ResourceRecord::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
bool
ResourceRecord::HasCNameForTLD(const std::string& tld) const
{

@ -35,6 +35,8 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const;
bool
HasCNameForTLD(const std::string& tld) const;
@ -45,11 +47,8 @@ namespace llarp
RR_TTL_t ttl;
RR_RData_t rData;
};
inline std::ostream&
operator<<(std::ostream& out, const ResourceRecord& rr)
{
return rr.print(out, -1, -1);
}
} // namespace dns
} // namespace llarp
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::dns::ResourceRecord> = true;

@ -1,6 +1,6 @@
#include "srv_data.hpp"
#include <llarp/util/str.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <limits>

@ -186,7 +186,8 @@ namespace llarp::dns
const auto str = file.u8string();
if (auto ret = ub_ctx_hosts(unboundContext, str.c_str()))
{
throw std::runtime_error{stringify("Failed to add host file ", file, ": ", ub_strerror(ret))};
throw std::runtime_error{
fmt::format("Failed to add host file {}: {}", file, ub_strerror(ret))};
}
else
{

@ -111,9 +111,6 @@ namespace llarp::uv
{
llarp::LogTrace("ticking event loop.");
FlushLogic();
auto& log = llarp::LogContext::Instance();
if (log.logStream)
log.logStream->Tick(time_now());
}
Loop::Loop(size_t queue_size) : llarp::EventLoop{}, m_LogicCalls{queue_size}

@ -111,14 +111,14 @@ namespace llarp
const std::string& name, const NetworkConfig& networkConfig, const DnsConfig& dnsConfig)
{
if (m_Exits.find(name) != m_Exits.end())
throw std::invalid_argument(stringify("An exit with name ", name, " already exists"));
throw std::invalid_argument{fmt::format("An exit with name {} already exists", name)};
auto endpoint = std::make_unique<handlers::ExitEndpoint>(name, m_Router);
endpoint->Configure(networkConfig, dnsConfig);
// add endpoint
if (!endpoint->Start())
throw std::runtime_error(stringify("Failed to start endpoint ", name));
throw std::runtime_error{fmt::format("Failed to start endpoint {}", name)};
m_Exits.emplace(name, std::move(endpoint));
}

@ -1,4 +1,5 @@
#include <algorithm>
#include <iterator>
#include <variant>
#include "tun.hpp"
#include <sys/types.h>
@ -117,9 +118,9 @@ namespace llarp
obj["ifname"] = m_IfName;
std::vector<std::string> resolvers;
for (const auto& addr : m_UpstreamResolvers)
resolvers.emplace_back(addr.toString());
resolvers.emplace_back(addr.ToString());
obj["ustreamResolvers"] = resolvers;
obj["localResolver"] = m_LocalResolverAddr.toString();
obj["localResolver"] = m_LocalResolverAddr.ToString();
util::StatusObject ips{};
for (const auto& item : m_IPActivity)
{
@ -528,10 +529,10 @@ namespace llarp
}
else
{
std::stringstream ss;
std::string recs;
for (const auto& rc : found)
rc.ToTXTRecord(ss);
msg.AddTXTReply(ss.str());
recs += rc.ToTXTRecord();
msg.AddTXTReply(std::move(recs));
}
reply(msg);
});
@ -544,11 +545,11 @@ namespace llarp
{
if (HasExit())
{
std::stringstream ss;
m_ExitMap.ForEachEntry([&ss](const auto& range, const auto& exit) {
ss << range.ToString() << "=" << exit.ToString() << "; ";
std::string s;
m_ExitMap.ForEachEntry([&s](const auto& range, const auto& exit) {
fmt::format_to(std::back_inserter(s), "{}={}; ", range, exit);
});
msg.AddTXTReply(ss.str());
msg.AddTXTReply(std::move(s));
}
else
{
@ -557,9 +558,7 @@ namespace llarp
}
else if (subdomain == "netid")
{
std::stringstream ss;
ss << "netid=" << m_router->rc().netID.ToString() << ";";
msg.AddTXTReply(ss.str());
msg.AddTXTReply(fmt::format("netid={};", m_router->rc().netID));
}
else
{
@ -965,7 +964,7 @@ namespace llarp
env.emplace("IF_NAME", m_IfName);
std::string strictConnect;
for (const auto& addr : m_StrictConnectAddrs)
strictConnect += addr.toString() + " ";
strictConnect += addr.ToString() + " ";
env.emplace("STRICT_CONNECT_ADDRS", strictConnect);
return env;
}

@ -343,7 +343,7 @@ namespace llarp
{"replayFilter", m_ReplayFilter.size()},
{"txMsgQueueSize", m_TXMsgs.size()},
{"rxMsgQueueSize", m_RXMsgs.size()},
{"remoteAddr", m_RemoteAddr.toString()},
{"remoteAddr", m_RemoteAddr.ToString()},
{"remoteRC", m_RemoteRC.ExtractStatus()},
{"created", to_json(m_CreatedAt)},
{"uptime", to_json(now - m_CreatedAt)}};

@ -196,8 +196,7 @@ namespace llarp
}
catch (const std::exception& ex)
{
LogError(
stringify("Could not use ifname ", ifname, " to configure ILinkLayer: ", ex.what()));
LogError("Could not use ifname ", ifname, " to configure ILinkLayer: ", ex.what());
throw ex;
}
}
@ -344,7 +343,7 @@ namespace llarp
return {
{"name", Name()},
{"rank", uint64_t(Rank())},
{"addr", m_ourAddr.toString()},
{"addr", m_ourAddr.ToString()},
{"sessions", util::StatusObject{{"pending", pending}, {"established", established}}}};
}

@ -8,7 +8,9 @@
#include <llarp/quic/tunnel.hpp>
#include <llarp/nodedb.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/logging/buffer.hpp>
#include <llarp/util/logging/callback_sink.hpp>
#include <oxenc/base32z.h>
@ -22,34 +24,6 @@
namespace
{
struct Logger : public llarp::ILogStream
{
lokinet_logger_func func;
void* user;
explicit Logger(lokinet_logger_func _func, void* _user) : func{_func}, user{_user}
{}
void
PreLog(std::stringstream&, llarp::LogLevel, std::string_view, int, const std::string&)
const override
{}
void
Print(llarp::LogLevel, std::string_view, const std::string& msg) override
{
func(msg.c_str(), user);
}
void
PostLog(std::stringstream&) const override{};
void
ImmediateFlush() override{};
void Tick(llarp_time_t) override{};
};
struct Context : public llarp::Context
{
using llarp::Context::Context;
@ -132,7 +106,7 @@ namespace
, m_Recv{recv}
, m_Timeout{timeout}
, m_User{user}
, m_Endpoint{ep}
, m_Endpoint{std::move(ep)}
{}
void
@ -222,16 +196,12 @@ struct lokinet_context
{
std::mutex m_access;
std::shared_ptr<llarp::Context> impl;
std::shared_ptr<llarp::Config> config;
std::shared_ptr<llarp::Context> impl = std::make_shared<Context>();
std::shared_ptr<llarp::Config> config = llarp::Config::EmbeddedConfig();
std::unique_ptr<std::thread> runner;
int _socket_id;
lokinet_context()
: impl{std::make_shared<Context>()}, config{llarp::Config::EmbeddedConfig()}, _socket_id{0}
{}
int _socket_id = 0;
~lokinet_context()
{
@ -390,8 +360,7 @@ namespace
{
return {host, serv->s_port};
}
else
return {host, std::stoi(portStr)};
return {host, std::stoi(portStr)};
}
int
@ -457,8 +426,8 @@ struct lokinet_srv_lookup_private
void
IterateAll(std::function<void(lokinet_srv_record*)> visit)
{
for (size_t idx = 0; idx < results.size(); ++idx)
visit(&results[idx]);
for (auto& result : results)
visit(&result);
// null terminator
visit(nullptr);
}
@ -479,12 +448,15 @@ extern "C"
return strdup(netid.c_str());
}
static auto last_log_set = llarp::log::Level::info;
int EXPORT
lokinet_log_level(const char* level)
{
if (auto maybe = llarp::LogLevelFromString(level))
if (auto maybe = llarp::log::level_from_string(level))
{
llarp::SetLogLevel(*maybe);
last_log_set = *maybe;
llarp::log::reset_level(*maybe);
return 0;
}
return -1;
@ -561,7 +533,7 @@ extern "C"
return -1;
auto lock = ctx->acquire();
ctx->config->router.m_netId = lokinet_get_netid();
ctx->config->logging.m_logLevel = llarp::GetLogLevel();
ctx->config->logging.m_logLevel = last_log_set;
ctx->runner = std::make_unique<std::thread>([ctx]() {
llarp::util::SetThreadName("llarp-mainloop");
ctx->impl->Configure(ctx->config);
@ -719,7 +691,7 @@ extern "C"
{
auto [addr, id] = quic->open(
remotehost, remoteport, [](auto) {}, localAddr);
auto [host, port] = split_host_port(addr.toString());
auto [host, port] = split_host_port(addr.ToString());
ctx->outbound_stream(id);
stream_okay(result, host, port, id);
}
@ -826,17 +798,13 @@ extern "C"
if (not oxenc::is_hex(hexview))
return nullptr;
const size_t byte_len = hexview.size() / 2;
const size_t b32z_len = (byte_len * 8 + 4) / 5; // = ⌈N×8÷5⌉ because 5 bits per 32z char
const size_t b32z_len = oxenc::to_base32z_size(oxenc::from_hex_size(hexview.size()));
auto buf = std::make_unique<char[]>(b32z_len + 1);
char* end = buf.get() + b32z_len;
*end = 0; // null terminate
// Write the bytes into the *end* of the buffer so that when we rewrite the final b32z chars
// into the buffer we won't overwrite any byte values until after we've consumed them.
char* bytepos = end - byte_len;
oxenc::from_hex(hexview.begin(), hexview.end(), bytepos);
// In-place conversion into the buffer
oxenc::to_base32z(bytepos, end, buf.get());
buf[b32z_len] = '\0'; // null terminate
oxenc::hex_decoder decode{hexview.begin(), hexview.end()};
oxenc::base32z_encoder encode{decode, decode.end()};
std::copy(encode, encode.end(), buf.get());
return buf.release(); // leak the buffer to the caller
}
@ -1060,8 +1028,7 @@ extern "C"
itr->second->AddFlow(*maybe, *remote, flow_data, flow_timeoutseconds);
return 0;
}
else
return EADDRINUSE;
return EADDRINUSE;
}
}
else
@ -1070,9 +1037,16 @@ extern "C"
return EINVAL;
}
void EXPORT
lokinet_set_syncing_logger(lokinet_logger_func func, lokinet_logger_sync sync, void* user)
{
llarp::log::clear_sinks();
llarp::log::add_sink(std::make_shared<llarp::logging::CallbackSink_mt>(func, sync, user));
}
void EXPORT
lokinet_set_logger(lokinet_logger_func func, void* user)
{
llarp::LogContext::Instance().logStream.reset(new Logger{func, user});
lokinet_set_syncing_logger(func, nullptr, user);
}
}

@ -4,7 +4,7 @@
#include <llarp/router_contact.hpp>
#include <llarp/router/abstractrouter.hpp>
#include <llarp/util/bencode.h>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
namespace llarp
{

@ -9,7 +9,7 @@
#include "relay.hpp"
#include <llarp/router_contact.hpp>
#include <llarp/util/buffer.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <memory>

@ -10,7 +10,7 @@
#include <llarp/routing/path_confirm_message.hpp>
#include <llarp/util/bencode.hpp>
#include <llarp/util/buffer.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/meta/memfn.hpp>
#include <llarp/tooling/path_event.hpp>

@ -7,7 +7,7 @@
#include <llarp/routing/path_confirm_message.hpp>
#include <llarp/util/bencode.hpp>
#include <llarp/util/buffer.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/meta/memfn.hpp>
#include <llarp/tooling/path_event.hpp>
@ -289,32 +289,33 @@ namespace llarp
return status == other.status;
}
using namespace std::literals;
static constexpr std::array code_strings = {
std::make_pair(LR_StatusRecord::SUCCESS, "success"sv),
std::make_pair(LR_StatusRecord::FAIL_TIMEOUT, "timeout"sv),
std::make_pair(LR_StatusRecord::FAIL_CONGESTION, "congestion"sv),
std::make_pair(LR_StatusRecord::FAIL_DEST_UNKNOWN, "destination unknown"sv),
std::make_pair(LR_StatusRecord::FAIL_DECRYPT_ERROR, "decrypt error"sv),
std::make_pair(LR_StatusRecord::FAIL_MALFORMED_RECORD, "malformed record"sv),
std::make_pair(LR_StatusRecord::FAIL_DEST_INVALID, "destination invalid"sv),
std::make_pair(LR_StatusRecord::FAIL_CANNOT_CONNECT, "cannot connect"sv),
std::make_pair(LR_StatusRecord::FAIL_DUPLICATE_HOP, "duplicate hop"sv)};
std::string
LRStatusCodeToString(uint64_t status)
{
std::map<uint64_t, std::string> codes = {
{LR_StatusRecord::SUCCESS, "success"},
{LR_StatusRecord::FAIL_TIMEOUT, "timeout"},
{LR_StatusRecord::FAIL_CONGESTION, "congestion"},
{LR_StatusRecord::FAIL_DEST_UNKNOWN, "destination unknown"},
{LR_StatusRecord::FAIL_DECRYPT_ERROR, "decrypt error"},
{LR_StatusRecord::FAIL_MALFORMED_RECORD, "malformed record"},
{LR_StatusRecord::FAIL_DEST_INVALID, "destination invalid"},
{LR_StatusRecord::FAIL_CANNOT_CONNECT, "cannot connect"},
{LR_StatusRecord::FAIL_DUPLICATE_HOP, "duplicate hop"}};
std::stringstream ss;
ss << "[";
bool found = false;
for (const auto& [val, message] : codes)
std::string s = "[";
for (const auto& [val, message] : code_strings)
{
if ((status & val) == val)
{
ss << (found ? ", " : "") << message;
found = true;
if (s.size() > 1)
s += ", ";
s += message;
}
}
ss << "]";
return ss.str();
s += ']';
return s;
}
} // namespace llarp

@ -166,7 +166,7 @@ namespace llarp
void
AddressInfo::fromSockAddr(const SockAddr& addr)
{
const sockaddr_in6* addr6 = addr;
const auto* addr6 = static_cast<const sockaddr_in6*>(addr);
memcpy(ip.s6_addr, addr6->sin6_addr.s6_addr, sizeof(ip.s6_addr));
port = addr.getPort();
}
@ -184,6 +184,14 @@ namespace llarp
return stream;
}
std::string
AddressInfo::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
void
to_json(nlohmann::json& j, const AddressInfo& a)
{

@ -55,23 +55,23 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const;
};
void
to_json(nlohmann::json& j, const AddressInfo& a);
inline std::ostream&
operator<<(std::ostream& out, const AddressInfo& a)
{
return a.print(out, -1, -1);
}
bool
operator==(const AddressInfo& lhs, const AddressInfo& rhs);
bool
operator<(const AddressInfo& lhs, const AddressInfo& rhs);
template <>
constexpr inline bool IsToStringFormattable<AddressInfo> = true;
} // namespace llarp
namespace std

@ -17,10 +17,10 @@ namespace llarp
ExitInfo::BEncode(llarp_buffer_t* buf) const
{
SockAddr exitaddr = ipAddress.createSockAddr();
const sockaddr_in6* exitaddr6 = exitaddr;
const auto* exitaddr6 = static_cast<const sockaddr_in6*>(exitaddr);
SockAddr netmaskaddr = netmask.createSockAddr();
const sockaddr_in6* netmaskaddr6 = netmaskaddr;
const auto* netmaskaddr6 = static_cast<const sockaddr_in6*>(netmaskaddr);
char tmp[128] = {0};
if (!bencode_start_dict(buf))
@ -119,8 +119,14 @@ namespace llarp
#endif
printer.printValue(ss.str());
*/
stream << ipAddress.toString();
stream << ipAddress.ToString();
return stream;
}
std::string
ExitInfo::ToString() const
{
return ipAddress.ToString();
}
} // namespace llarp

@ -42,11 +42,12 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const;
};
inline std::ostream&
operator<<(std::ostream& out, const ExitInfo& xi)
{
return xi.print(out, -1, -1);
}
template <>
constexpr inline bool IsToStringFormattable<ExitInfo> = true;
} // namespace llarp

@ -20,7 +20,7 @@ namespace llarp
IpAddress::IpAddress(const SockAddr& addr)
{
m_ipAddress = addr.toString();
m_ipAddress = addr.ToString();
uint16_t port = addr.getPort();
if (port > 0)
m_port = port;
@ -43,7 +43,7 @@ namespace llarp
{
SockAddr addr(other);
m_ipAddress = addr.toString();
m_ipAddress = addr.ToString();
uint16_t port = addr.getPort();
if (port > 0)
m_port = port;
@ -125,13 +125,13 @@ namespace llarp
IpAddress::isBogon() const
{
SockAddr addr(m_ipAddress);
const sockaddr_in6* addr6 = addr;
const auto* addr6 = static_cast<const sockaddr_in6*>(addr);
const uint8_t* raw = addr6->sin6_addr.s6_addr;
return IsIPv4Bogon(ipaddr_ipv4_bits(raw[12], raw[13], raw[14], raw[15]));
}
std::string
IpAddress::toString() const
IpAddress::ToString() const
{
return m_ipAddress; // TODO: port
}
@ -180,12 +180,4 @@ namespace llarp
{
return createSockAddr() == other.createSockAddr();
}
std::ostream&
operator<<(std::ostream& out, const IpAddress& address)
{
out << address.toString();
return out;
}
} // namespace llarp

@ -8,6 +8,8 @@
#include "net_int.hpp"
#include <llarp/util/formattable.hpp>
namespace llarp
{
/// A struct that can represent either an IPv4 or IPv6 address. It is meant for representation
@ -118,7 +120,7 @@ namespace llarp
///
/// @return string representation of this IpAddress
std::string
toString() const;
ToString() const;
std::string
toHost() const;
@ -147,8 +149,8 @@ namespace llarp
std::optional<uint16_t> m_port = std::nullopt;
};
std::ostream&
operator<<(std::ostream& out, const IpAddress& address);
template <>
constexpr inline bool IsToStringFormattable<IpAddress> = true;
} // namespace llarp
@ -160,7 +162,7 @@ namespace std
std::size_t
operator()(const llarp::IpAddress& address) const noexcept
{
return std::hash<std::string>{}(address.toString());
return std::hash<std::string>{}(address.ToString());
}
};
} // namespace std

@ -101,12 +101,6 @@ namespace llarp
return Contains(net::ExpandV4(ip));
}
friend std::ostream&
operator<<(std::ostream& out, const IPRange& a)
{
return out << a.ToString();
}
/// get the highest address on this range
constexpr huint128_t
HighestAddr() const
@ -147,6 +141,9 @@ namespace llarp
BDecode(llarp_buffer_t* buf);
};
template <>
constexpr inline bool IsToStringFormattable<IPRange> = true;
} // namespace llarp
namespace std

@ -16,7 +16,7 @@
#include "ip.hpp"
#include "ip_range.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/str.hpp>
#ifdef ANDROID
@ -540,9 +540,7 @@ namespace llarp
int num = 0;
while (num < 255)
{
std::stringstream ifname_ss;
ifname_ss << "lokitun" << num;
std::string iftestname = ifname_ss.str();
std::string iftestname = fmt::format("lokitun{}", num);
bool found = llarp_getifaddr(iftestname.c_str(), AF_INET, nullptr);
if (!found)
{
@ -599,7 +597,7 @@ namespace llarp
addr6.sin6_addr = IN6ADDR_ANY_INIT;
return SockAddr{addr6};
}
throw llarp::make_exception<std::invalid_argument>(af, " is not a valid address family");
throw std::invalid_argument{fmt::format("{} is not a valid address family", af)};
}
} // namespace

@ -17,6 +17,8 @@
#include <iostream>
#include <vector>
#include <llarp/util/formattable.hpp>
#include "uint128.hpp"
namespace llarp
@ -111,12 +113,6 @@ namespace llarp
bool
FromString(const std::string&);
friend std::ostream&
operator<<(std::ostream& out, const huint_t& i)
{
return out << i.ToString();
}
};
using huint32_t = huint_t<uint32_t>;
@ -193,14 +189,14 @@ namespace llarp
*this = ToNet(x);
return true;
}
friend std::ostream&
operator<<(std::ostream& out, const nuint_t& i)
{
return out << i.ToString();
}
};
template <typename UInt_t>
inline constexpr bool IsToStringFormattable<huint_t<UInt_t>> = true;
template <typename UInt_t>
inline constexpr bool IsToStringFormattable<nuint_t<UInt_t>> = true;
using nuint32_t = nuint_t<uint32_t>;
using nuint16_t = nuint_t<uint16_t>;
using nuint128_t = nuint_t<llarp::uint128_t>;

@ -3,7 +3,7 @@
#include "ip.hpp"
#include "net_bits.hpp"
#include <llarp/util/str.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/mem.hpp>
#include <charconv>
@ -262,21 +262,22 @@ namespace llarp
// splits[0] should be dot-separated IPv4
auto ipSplits = split(splits[0], ".");
if (ipSplits.size() != 4)
throw std::invalid_argument(stringify(str, " is not a valid IPv4 address"));
throw std::invalid_argument(fmt::format("{} is not a valid IPv4 address", str));
std::array<uint8_t, 4> ipBytes;
for (int i = 0; i < 4; ++i)
if (not parse_int(ipSplits[i], ipBytes[i]))
throw std::runtime_error(stringify(str, " contains invalid numeric value"));
throw std::runtime_error(fmt::format("{} contains invalid numeric value", str));
// attempt port before setting IPv4 bytes
if (splits.size() == 2)
{
if (not allow_port)
throw std::runtime_error{stringify("invalid ip address (port not allowed here): ", str)};
throw std::runtime_error{
fmt::format("invalid ip address (port not allowed here): {}", str)};
uint16_t port;
if (not parse_int(splits[1], port))
throw std::runtime_error{stringify(splits[1], " is not a valid port")};
throw std::runtime_error{fmt::format("{} is not a valid port", splits[1])};
setPort(port);
}
@ -284,7 +285,7 @@ namespace llarp
}
std::string
SockAddr::toString() const
SockAddr::ToString() const
{
// TODO: review
if (isEmpty())
@ -435,11 +436,4 @@ namespace llarp
return ntohs(m_addr.sin6_port);
}
std::ostream&
operator<<(std::ostream& out, const SockAddr& address)
{
out << address.toString();
return out;
}
} // namespace llarp

@ -13,6 +13,7 @@
#include <string>
#include "net_int.hpp"
#include <oxenc/variant.h>
#include <llarp/util/formattable.hpp>
namespace llarp
{
@ -60,9 +61,9 @@ namespace llarp
SockAddr&
operator=(const in6_addr& addr);
operator const sockaddr*() const;
operator const sockaddr_in*() const;
operator const sockaddr_in6*() const;
explicit operator const sockaddr*() const;
explicit operator const sockaddr_in*() const;
explicit operator const sockaddr_in6*() const;
size_t
sockaddr_len() const;
@ -77,7 +78,7 @@ namespace llarp
fromString(std::string_view str, bool allow_port = true);
std::string
toString() const;
ToString() const;
std::string
hostString() const;
@ -163,8 +164,8 @@ namespace llarp
applyIPv4MapBytes();
};
std::ostream&
operator<<(std::ostream& out, const SockAddr& address);
template <>
inline constexpr bool IsToStringFormattable<SockAddr> = true;
} // namespace llarp

@ -5,7 +5,8 @@
#include "router_contact.hpp"
#include "util/buffer.hpp"
#include "util/fs.hpp"
#include "util/logging/logger.hpp"
#include "util/logging.hpp"
#include "util/time.hpp"
#include "util/mem.hpp"
#include "util/str.hpp"
#include "dht/kademlia.hpp"
@ -38,7 +39,7 @@ namespace llarp
}
if (not fs::is_directory(nodedbDir))
throw std::runtime_error(llarp::stringify("nodedb ", nodedbDir, " is not a directory"));
throw std::runtime_error{fmt::format("nodedb {} is not a directory", nodedbDir)};
for (const char& ch : skiplist_subdirs)
{

@ -135,10 +135,15 @@ namespace llarp
std::string
Path::HopsString() const
{
std::stringstream ss;
std::string hops_str;
hops_str.reserve(hops.size() * 62); // 52 for the pkey, 6 for .snode, 4 for the ' -> ' joiner
for (const auto& hop : hops)
ss << RouterID(hop.rc.pubkey) << " -> ";
return ss.str();
{
if (!hops.empty())
hops_str += " -> ";
hops_str += RouterID(hop.rc.pubkey).ToString();
}
return hops_str;
}
bool
@ -568,9 +573,7 @@ namespace llarp
std::string
Path::Name() const
{
std::stringstream ss;
ss << "TX=" << TXID() << " RX=" << RXID();
return ss.str();
return fmt::format("TX={} RX={}", TXID(), RXID());
}
void

@ -4,6 +4,7 @@
#include <llarp/messages/relay_commit.hpp>
#include <llarp/nodedb.hpp>
#include "path_context.hpp"
#include "util/logging.hpp"
#include <llarp/profiling.hpp>
#include <llarp/router/abstractrouter.hpp>
#include <llarp/router/i_rc_lookup_handler.hpp>
@ -15,6 +16,11 @@
namespace llarp
{
namespace
{
auto log_path = log::Cat("path");
}
struct AsyncPathKeyExchangeContext : std::enable_shared_from_this<AsyncPathKeyExchangeContext>
{
using WorkFunc_t = std::function<void(void)>;
@ -344,7 +350,7 @@ namespace llarp
const auto maybe = SelectFirstHop(exclude);
if (not maybe.has_value())
{
LogWarn(Name(), " has no first hop candidate");
log::warning(log_path, "{} has no first hop candidate", Name());
return std::nullopt;
}
hops.emplace_back(*maybe);

@ -365,13 +365,13 @@ namespace llarp
std::string
BuildStats::ToString() const
{
std::stringstream ss;
ss << (SuccessRatio() * 100.0) << " percent success ";
ss << "(success=" << success << " ";
ss << "attempts=" << attempts << " ";
ss << "timeouts=" << timeouts << " ";
ss << "fails=" << fails << ")";
return ss.str();
return fmt::format(
"{:.2f} percent success (success={} attempts={} timeouts={} fails={})",
SuccessRatio() * 100.0,
success,
attempts,
timeouts,
fails);
}
double

@ -71,12 +71,6 @@ namespace llarp
std::string
ToString() const;
friend std::ostream&
operator<<(std::ostream& o, const BuildStats& st)
{
return o << st.ToString();
}
};
/// the role of this path can fulfill
@ -326,4 +320,8 @@ namespace llarp
};
} // namespace path
template <>
constexpr inline bool IsToStringFormattable<path::BuildStats> = true;
} // namespace llarp

@ -33,6 +33,14 @@ namespace llarp
return stream;
}
std::string
TransitHopInfo::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
TransitHop::TransitHop()
: m_UpstreamGather(transit_hop_queue_size), m_DownstreamGather(transit_hop_queue_size)
{
@ -442,6 +450,14 @@ namespace llarp
return stream;
}
std::string
TransitHop::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
void
TransitHop::Stop()
{

@ -30,6 +30,9 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const;
};
inline bool
@ -52,12 +55,6 @@ namespace llarp
< std::tie(rhs.txID, rhs.rxID, rhs.upstream, rhs.downstream);
}
inline std::ostream&
operator<<(std::ostream& out, const TransitHopInfo& info)
{
return info.print(out, -1, -1);
}
struct TransitHop : public IHopHandler,
public routing::IMessageHandler,
std::enable_shared_from_this<TransitHop>
@ -109,6 +106,8 @@ namespace llarp
HandleLRSM(
uint64_t status, std::array<EncryptedFrame, 8>& frames, AbstractRouter* r) override;
std::string
ToString() const;
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
@ -211,13 +210,13 @@ namespace llarp
std::atomic<uint32_t> m_UpstreamWorkCounter;
std::atomic<uint32_t> m_DownstreamWorkCounter;
};
inline std::ostream&
operator<<(std::ostream& out, const TransitHop& h)
{
return h.print(out, -1, -1);
}
} // namespace path
template <>
constexpr inline bool IsToStringFormattable<path::TransitHop> = true;
template <>
constexpr inline bool IsToStringFormattable<path::TransitHopInfo> = true;
} // namespace llarp
namespace std

@ -62,9 +62,7 @@ namespace sqlite_orm
std::string
operator()(const llarp_time_t& value) const
{
std::stringstream stream;
stream << value.count();
return stream.str();
return fmt::format("{}", value.count());
}
};

@ -1,6 +1,6 @@
#include "peer_db.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/status.hpp>
#include <llarp/util/str.hpp>
@ -105,8 +105,8 @@ namespace llarp
PeerDb::accumulatePeerStats(const RouterID& routerId, const PeerStats& delta)
{
if (routerId != delta.routerId)
throw std::invalid_argument(
stringify("routerId ", routerId, " doesn't match ", delta.routerId));
throw std::invalid_argument{
fmt::format("routerId {} doesn't match {}", routerId, delta.routerId)};
std::lock_guard guard(m_statsLock);
auto itr = m_peerStats.find(routerId);

@ -65,4 +65,12 @@ namespace llarp
return stream;
}
std::string
PoW::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
} // namespace llarp

@ -40,11 +40,12 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const;
};
inline std::ostream&
operator<<(std::ostream& out, const PoW& p)
{
return p.print(out, -1, -1);
}
template <>
constexpr inline bool IsToStringFormattable<PoW> = true;
} // namespace llarp

@ -25,7 +25,7 @@ namespace llarp::quic
}
std::string
Address::to_string() const
Address::ToString() const
{
if (a.addrlen != sizeof(sockaddr_in6))
return "(unknown-addr)";
@ -39,15 +39,10 @@ namespace llarp::quic
return result;
}
std::ostream&
operator<<(std::ostream& o, const Address& a)
{
return o << a.to_string();
}
std::ostream&
operator<<(std::ostream& o, const Path& p)
std::string
Path::ToString() const
{
return o << p.local << "<-" << p.remote;
return local.ToString() + "<-" + remote.ToString();
}
} // namespace llarp::quic

@ -36,13 +36,16 @@ namespace llarp::quic
operator=(const Address&);
// Implicit conversion to sockaddr* and ngtcp2_addr& so that an Address can be passed wherever
// one of those is expected.
operator sockaddr*()
// one of those is expected. Templatized so that implicit conversion to other things doesn't
// happen.
template <typename T, std::enable_if_t<std::is_same_v<T, sockaddr>, int> = 0>
operator T*()
{
return reinterpret_cast<sockaddr*>(&saddr);
}
operator const sockaddr*() const
template <typename T, std::enable_if_t<std::is_same_v<T, sockaddr>, int> = 0>
operator const T*() const
{
return reinterpret_cast<const sockaddr*>(&saddr);
}
@ -90,7 +93,7 @@ namespace llarp::quic
}
std::string
to_string() const;
ToString() const;
};
// Wraps an ngtcp2_path (which is basically just and address pair) with remote/local components.
@ -124,24 +127,25 @@ namespace llarp::quic
}
// Equivalent to `&obj.path`, but slightly more convenient for passing into ngtcp2 functions
// taking a ngtcp2_path pointer.
operator ngtcp2_path*()
// taking a ngtcp2_path pointer. Templatized to prevent implicit conversion to other type of
// pointers/ints.
template <typename T, std::enable_if_t<std::is_same_v<T, ngtcp2_path>, int> = 0>
operator T*()
{
return &path;
}
operator const ngtcp2_path*() const
template <typename T, std::enable_if_t<std::is_same_v<T, ngtcp2_path>, int> = 0>
operator const T*() const
{
return &path;
}
std::string
to_string() const;
ToString() const;
};
std::ostream&
operator<<(std::ostream& o, const Address& a);
std::ostream&
operator<<(std::ostream& o, const Path& p);
} // namespace llarp::quic
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::quic::Address> = true;
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::quic::Path> = true;

@ -1,7 +1,7 @@
#include "client.hpp"
#include "tunnel.hpp"
#include <llarp/util/logging/buffer.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <oxenc/variant.h>
#include <llarp/service/address.hpp>

@ -2,7 +2,7 @@
#include "client.hpp"
#include "server.hpp"
#include <limits>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/logging/buffer.hpp>
#include <cassert>
@ -32,10 +32,10 @@ namespace llarp::quic
std::memmove(data, cid, datalen);
}
std::ostream&
operator<<(std::ostream& o, const ConnectionID& c)
std::string
ConnectionID::ToString() const
{
return o << oxenc::to_hex(c.data, c.data + c.datalen);
return oxenc::to_hex(data, data + datalen);
}
ConnectionID

@ -72,11 +72,16 @@ namespace llarp::quic
static ConnectionID
random(size_t size = ConnectionID::max_size());
std::string
ToString() const;
};
std::ostream&
operator<<(std::ostream& o, const ConnectionID& c);
} // namespace llarp::quic
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::quic::ConnectionID> = true;
namespace std
{
template <>

@ -1,5 +1,5 @@
#include "null_crypto.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <limits>

@ -1,6 +1,6 @@
#include "server.hpp"
#include <llarp/util/logging.hpp>
#include <llarp/util/logging/buffer.hpp>
#include <llarp/util/logging/logger.hpp>
#include <oxenc/variant.h>
#include <uvw/loop.h>
@ -55,7 +55,6 @@ namespace llarp::quic
{
auto connptr = std::make_shared<Connection>(*this, it->first, hd, p.path);
it->second = connptr;
LogDebug("Created local Connection ", it->first, " for incoming connection");
return connptr;
}
}

@ -1,7 +1,7 @@
#include "stream.hpp"
#include "connection.hpp"
#include "endpoint.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <cassert>
#include <iostream>
@ -43,10 +43,10 @@
namespace llarp::quic
{
std::ostream&
operator<<(std::ostream& o, const StreamID& s)
std::string
StreamID::ToString() const
{
return o << u8"Str❰" << s.id << u8"";
return fmt::format(u8"Str❰{}❱", id);
}
Stream::Stream(

@ -12,6 +12,8 @@
#include <optional>
#include <uvw/async.h>
#include <llarp/util/formattable.hpp>
namespace llarp::quic
{
class Connection;
@ -70,6 +72,9 @@ namespace llarp::quic
{
return s.id >= id;
}
std::string
ToString() const;
};
// Application error code we close with if the data handle throws
@ -78,11 +83,11 @@ namespace llarp::quic
// Error code we send to a stream close callback if the stream's connection expires; this is *not*
// sent over quic, hence using a value >= 2^62 (quic's maximum serializable integer).
inline constexpr uint64_t STREAM_ERROR_CONNECTION_EXPIRED = (1ULL << 62) + 1;
std::ostream&
operator<<(std::ostream& o, const StreamID& s);
} // namespace llarp::quic
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::quic::StreamID> = true;
namespace std
{
template <>

@ -4,8 +4,8 @@
#include "service/name.hpp"
#include "stream.hpp"
#include <limits>
#include <llarp/util/logging.hpp>
#include <llarp/util/logging/buffer.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/str.hpp>
#include <llarp/ev/ev_libuv.hpp>
#include <memory>
@ -479,9 +479,8 @@ namespace llarp::quic
if (failed)
{
tcp_tunnel->close();
throw std::runtime_error{
"Failed to bind/listen local TCP tunnel socket on " + bind_addr.toString() + ": "
+ failed};
throw std::runtime_error{fmt::format(
"Failed to bind/listen local TCP tunnel socket on {}: {}", bind_addr, failed)};
}
auto bound = tcp_tunnel->sock();

@ -2,6 +2,9 @@
#include <llarp/util/status.hpp>
#include <llarp/util/types.hpp>
#include <llarp/util/formattable.hpp>
#include <fmt/format.h>
#include <functional>
@ -21,26 +24,19 @@ namespace llarp
EstablishFail
};
inline std::ostream&
operator<<(std::ostream& out, const SessionResult& st)
constexpr std::string_view
ToString(SessionResult sr)
{
switch (st)
{
case SessionResult::Establish:
return out << "success";
case SessionResult::Timeout:
return out << "timeout";
case SessionResult::NoLink:
return out << "no link";
case SessionResult::InvalidRouter:
return out << "invalid router";
case SessionResult::RouterNotFound:
return out << "not found";
case SessionResult::EstablishFail:
return out << "establish failed";
}
return out << "???";
return sr == llarp::SessionResult::Establish ? "success"sv
: sr == llarp::SessionResult::Timeout ? "timeout"sv
: sr == llarp::SessionResult::NoLink ? "no link"sv
: sr == llarp::SessionResult::InvalidRouter ? "invalid router"sv
: sr == llarp::SessionResult::RouterNotFound ? "not found"sv
: sr == llarp::SessionResult::EstablishFail ? "establish failed"sv
: "???"sv;
}
template <>
constexpr inline bool IsToStringFormattable<SessionResult> = true;
using RouterCallback = std::function<void(const RouterID&, const SessionResult)>;

@ -152,7 +152,7 @@ namespace llarp
return SendStatus::NoLink;
}
throw std::invalid_argument{
stringify("SessionResult ", result, " has no corrispoding SendStatus when transforming")};
fmt::format("SessionResult {} has no corresponding SendStatus when transforming", result)};
}
void

@ -15,9 +15,7 @@
#include <llarp/net/net.hpp>
#include <stdexcept>
#include <llarp/util/buffer.hpp>
#include <llarp/util/logging/file_logger.hpp>
#include <llarp/util/logging/logger_syslog.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/util/meta/memfn.hpp>
#include <llarp/util/str.hpp>
#include <llarp/ev/ev.hpp>
@ -658,7 +656,7 @@ namespace llarp
{
if (not BDecodeReadFile(router, b_list))
{
throw std::runtime_error(stringify("failed to read bootstrap list file '", router, "'"));
throw std::runtime_error{fmt::format("failed to read bootstrap list file '{}'", router)};
}
}
else
@ -666,8 +664,8 @@ namespace llarp
RouterContact rc;
if (not rc.Read(router))
{
throw std::runtime_error(
stringify("failed to decode bootstrap RC, file='", router, "' rc=", rc));
throw std::runtime_error{
fmt::format("failed to decode bootstrap RC, file='{}', rc={}", router, rc)};
}
b_list.insert(rc);
}
@ -759,7 +757,8 @@ namespace llarp
uint16_t port = serverConfig.port;
if (!server->Configure(this, key, af, port))
{
throw std::runtime_error(stringify("failed to bind inbound link on ", key, " port ", port));
throw std::runtime_error{
fmt::format("failed to bind inbound link on {} port {}", key, port)};
}
_linkManager.AddLink(std::move(server), true);
}
@ -794,12 +793,16 @@ namespace llarp
}
// Logging config
LogContext::Instance().Initialize(
conf.logging.m_logLevel,
conf.logging.m_logType,
conf.logging.m_logFile,
conf.router.m_nickname,
util::memFn(&AbstractRouter::QueueDiskIO, this));
// Backwards compat: before 0.9.10 we used `type=file` with `file=|-|stdout` for print mode
auto log_type = conf.logging.m_logType;
if (log_type == log::Type::File
&& (conf.logging.m_logFile == "stdout" || conf.logging.m_logFile == "-"
|| conf.logging.m_logFile.empty()))
log_type = log::Type::Print;
log::reset_level(conf.logging.m_logLevel);
log::add_sink(log_type, conf.logging.m_logFile);
return true;
}
@ -861,42 +864,54 @@ namespace llarp
#if defined(WITH_SYSTEMD)
{
std::stringstream ss;
ss << "WATCHDOG=1\nSTATUS=v" << llarp::VERSION_STR;
std::string status;
auto out = std::back_inserter(status);
out = fmt::format_to(out, "WATCHDOG=1\nSTATUS=v{}", llarp::VERSION_STR);
if (IsServiceNode())
{
ss << " snode | known/svc/clients: " << nodedb()->NumLoaded() << "/"
<< NumberOfConnectedRouters() << "/" << NumberOfConnectedClients() << " | "
<< pathContext().CurrentTransitPaths() << " active paths | "
<< "block " << (m_lokidRpcClient ? m_lokidRpcClient->BlockHeight() : 0) << " | gossip: "
<< "(next/last) " << time_delta<std::chrono::seconds>{_rcGossiper.NextGossipAt()}
<< " / ";
out = fmt::format_to(
out,
" snode | known/svc/clients: {}/{}/{}",
nodedb()->NumLoaded(),
NumberOfConnectedRouters(),
NumberOfConnectedClients());
out = fmt::format_to(
out,
" | {} active paths | block {} ",
pathContext().CurrentTransitPaths(),
(m_lokidRpcClient ? m_lokidRpcClient->BlockHeight() : 0));
out = fmt::format_to(
out,
" | gossip: (next/last) {} / ",
time_delta<std::chrono::seconds>{_rcGossiper.NextGossipAt()});
if (auto maybe = _rcGossiper.LastGossipAt())
{
ss << time_delta<std::chrono::seconds>{*maybe};
}
out = fmt::format_to(out, "{}", time_delta<std::chrono::seconds>{*maybe});
else
{
ss << "never";
}
out = fmt::format_to(out, "never");
}
else
{
ss << " client | known/connected: " << nodedb()->NumLoaded() << "/"
<< NumberOfConnectedRouters();
out = fmt::format_to(
out,
" client | known/connected: {}/{}",
nodedb()->NumLoaded(),
NumberOfConnectedRouters());
if (auto ep = hiddenServiceContext().GetDefault())
{
ss << " | paths/endpoints " << pathContext().CurrentOwnedPaths() << "/"
<< ep->UniqueEndpoints();
auto success_rate = ep->CurrentBuildStats().SuccessRatio();
if (success_rate < 0.5)
out = fmt::format_to(
out,
" | paths/endpoints {}/{}",
pathContext().CurrentOwnedPaths(),
ep->UniqueEndpoints());
if (auto success_rate = ep->CurrentBuildStats().SuccessRatio(); success_rate < 0.5)
{
ss << " [ !!! Low Build Success Rate (" << std::setprecision(4)
<< (100.0 * success_rate) << "%) !!! ] ";
out = fmt::format_to(
out, " [ !!! Low Build Success Rate ({:.1f}%) !!! ]", (100.0 * success_rate));
}
};
}
const auto status = ss.str();
::sd_notify(0, status.c_str());
}
#endif
@ -1194,7 +1209,7 @@ namespace llarp
if (enableRPCServer)
{
m_RPCServer->AsyncServeRPC(rpcBindAddr);
LogInfo("Bound RPC server to ", rpcBindAddr);
LogInfo("Bound RPC server to ", rpcBindAddr.full_address());
}
return true;
@ -1404,7 +1419,7 @@ namespace llarp
}
});
}
LogContext::Instance().DropToRuntimeLevel();
log::reset_level(log::Level::warn);
return _running;
}
@ -1453,7 +1468,7 @@ namespace llarp
return;
_stopping.store(true);
LogContext::Instance().RevertRuntimeLevel();
log::reset_level(log::Level::info);
LogWarn("stopping router hard");
#if defined(WITH_SYSTEMD)
sd_notify(0, "STOPPING=1\nSTATUS=Shutting down HARD");
@ -1473,7 +1488,7 @@ namespace llarp
return;
_stopping.store(true);
LogContext::Instance().RevertRuntimeLevel();
log::reset_level(log::Level::info);
LogInfo("stopping router");
#if defined(WITH_SYSTEMD)
sd_notify(0, "STOPPING=1\nSTATUS=Shutting down");
@ -1623,8 +1638,8 @@ namespace llarp
_linkManager.AddLink(std::move(link), false);
return true;
}
throw std::runtime_error(
stringify("Failed to init AF_INET and AF_INET6 on port ", m_OutboundPort));
throw std::runtime_error{
fmt::format("Failed to init AF_INET and AF_INET6 on port {}", m_OutboundPort)};
}
void

@ -1,5 +1,5 @@
#include "systemd_resolved.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#ifndef WITH_SYSTEMD

@ -5,7 +5,7 @@
#include "net/net.hpp"
#include "util/bencode.hpp"
#include "util/buffer.hpp"
#include "util/logging/logger.hpp"
#include "util/logging.hpp"
#include "util/mem.hpp"
#include "util/printer.hpp"
#include "util/time.hpp"
@ -56,8 +56,7 @@ namespace llarp
std::string
NetID::ToString() const
{
auto term = std::find(begin(), end(), '\0');
return std::string(begin(), term);
return {begin(), std::find(begin(), end(), '\0')};
}
bool
@ -105,19 +104,17 @@ namespace llarp
return false;
}
std::ostream&
RouterContact::ToTXTRecord(std::ostream& out) const
std::string
RouterContact::ToTXTRecord() const
{
std::string result;
auto out = std::back_inserter(result);
for (const auto& addr : addrs)
{
out << "ai_addr=" << addr.toIpAddress() << "; ";
out << "ai_pk=" << addr.pubkey.ToHex() << "; ";
}
out << "updated=" << last_updated.count() << "; ";
out << "onion_pk=" << enckey.ToHex() << "; ";
out = fmt::format_to(out, "ai_addr={}; ai_pk={}; ", addr.toIpAddress(), addr.pubkey);
out = fmt::format_to(out, "updated={}; onion_pk={}; ", last_updated.count(), enckey.ToHex());
if (routerVersion.has_value())
out << "router_version=" << routerVersion->ToString() << "; ";
return out;
out = fmt::format_to(out, "router_version={}; ", *routerVersion);
return result;
}
bool
@ -591,4 +588,12 @@ namespace llarp
return stream;
}
std::string
RouterContact::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
} // namespace llarp

@ -48,14 +48,6 @@ namespace llarp
return !(*this == other);
}
std::ostream&
print(std::ostream& stream, int level, int spaces) const
{
Printer printer(stream, level, spaces);
printer.printValue(ToString());
return stream;
}
std::string
ToString() const;
@ -66,12 +58,6 @@ namespace llarp
BEncode(llarp_buffer_t* buf) const;
};
inline std::ostream&
operator<<(std::ostream& out, const NetID& id)
{
return id.print(out, -1, -1);
}
/// RouterContact
struct RouterContact
{
@ -120,10 +106,7 @@ namespace llarp
}
std::string
ToString() const
{
return ToJson().dump();
}
ToString() const;
bool
BEncode(llarp_buffer_t* buf) const;
@ -131,8 +114,8 @@ namespace llarp
bool
BEncodeSignedSection(llarp_buffer_t* buf) const;
std::ostream&
ToTXTRecord(std::ostream& out) const;
std::string
ToTXTRecord() const;
bool
operator==(const RouterContact& other) const
@ -229,11 +212,10 @@ namespace llarp
DecodeVersion_1(oxenc::bt_list_consumer& btlist);
};
inline std::ostream&
operator<<(std::ostream& out, const RouterContact& rc)
{
return rc.print(out, -1, -1);
}
template <>
constexpr inline bool IsToStringFormattable<NetID> = true;
template <>
constexpr inline bool IsToStringFormattable<RouterContact> = true;
using RouterLookupHandler = std::function<void(const std::vector<RouterContact>&)>;
} // namespace llarp

@ -37,12 +37,6 @@ namespace llarp
std::copy(ptr, ptr + SIZE, begin());
return *this;
}
friend std::ostream&
operator<<(std::ostream& out, const RouterID& id)
{
return out << id.ToString();
}
};
inline bool
@ -51,6 +45,9 @@ namespace llarp
return lhs.as_array() == rhs.as_array();
}
template <>
constexpr inline bool IsToStringFormattable<RouterID> = true;
} // namespace llarp
namespace std

@ -4,6 +4,7 @@
#include "util/bencode.hpp"
#include "constants/version.hpp"
#include "constants/proto.hpp"
#include "util/formattable.hpp"
namespace llarp
{
@ -60,11 +61,8 @@ namespace llarp
int64_t m_ProtoVersion = llarp::constants::proto_version;
};
inline std::ostream&
operator<<(std::ostream& out, const RouterVersion& rv)
{
return out << rv.ToString();
}
template <>
constexpr inline bool IsToStringFormattable<RouterVersion> = true;
static constexpr int64_t INVALID_VERSION = -1;
static const RouterVersion emptyRouterVersion({0, 0, 0}, INVALID_VERSION);

@ -27,7 +27,7 @@ namespace llarp::rpc
oxenmq::address{m_AuthURL},
[self = shared_from_this()](oxenmq::ConnectionID c) {
self->m_Conn = std::move(c);
LogInfo("connected to endpoint auth server via ", *self->m_Conn);
LogInfo("connected to endpoint auth server");
},
[self = shared_from_this()](oxenmq::ConnectionID, std::string_view fail) {
LogWarn("failed to connect to endpoint auth server: ", fail);

@ -1,7 +1,7 @@
#include "lokid_rpc_client.hpp"
#include <stdexcept>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
#include <llarp/router/abstractrouter.hpp>
@ -14,20 +14,23 @@ namespace llarp
{
namespace rpc
{
static oxenmq::LogLevel
toLokiMQLogLevel(llarp::LogLevel level)
static constexpr oxenmq::LogLevel
toLokiMQLogLevel(log::Level level)
{
switch (level)
{
case eLogError:
case log::Level::critical:
return oxenmq::LogLevel::fatal;
case log::Level::err:
return oxenmq::LogLevel::error;
case eLogWarn:
case log::Level::warn:
return oxenmq::LogLevel::warn;
case eLogInfo:
case log::Level::info:
return oxenmq::LogLevel::info;
case eLogDebug:
case log::Level::debug:
return oxenmq::LogLevel::debug;
case eLogNone:
case log::Level::trace:
case log::Level::off:
default:
return oxenmq::LogLevel::trace;
}
@ -58,7 +61,7 @@ namespace llarp
{
throw std::runtime_error("we cannot talk to lokid while not a service node");
}
LogInfo("connecting to lokid via LMQ at ", url);
LogInfo("connecting to lokid via LMQ at ", url.full_address());
m_Connection = m_lokiMQ->connect_remote(
url,
[self = shared_from_this()](oxenmq::ConnectionID) { self->Connected(); },
@ -344,8 +347,8 @@ namespace llarp
const auto nonce = oxenc::from_hex(j["nonce"].get<std::string>());
if (nonce.size() != result.nonce.size())
{
throw std::invalid_argument(stringify(
"nonce size mismatch: ", nonce.size(), " != ", result.nonce.size()));
throw std::invalid_argument{fmt::format(
"nonce size mismatch: {} != {}", nonce.size(), result.nonce.size())};
}
std::copy_n(nonce.data(), nonce.size(), result.nonce.data());

@ -203,7 +203,7 @@ namespace llarp::rpc
auto [addr, id] = quic->open(
remoteHost, port, [](auto&&) {}, laddr);
util::StatusObject status;
status["addr"] = addr.toString();
status["addr"] = addr.ToString();
status["id"] = id;
reply(CreateJSONResponse(status));
}
@ -632,7 +632,7 @@ namespace llarp::rpc
{
if (not itr->is_object())
{
reply(CreateJSONError(stringify("override is not an object")));
reply(CreateJSONError("override is not an object"));
return;
}
for (const auto& [section, value] : itr->items())
@ -640,15 +640,15 @@ namespace llarp::rpc
if (not value.is_object())
{
reply(CreateJSONError(
stringify("failed to set [", section, "] section is not an object")));
fmt::format("failed to set [{}]: section is not an object", section)));
return;
}
for (const auto& [key, value] : value.items())
{
if (not value.is_string())
{
reply(CreateJSONError(stringify(
"failed to set [", section, "]:", key, " value is not a string")));
reply(CreateJSONError(fmt::format(
"failed to set [{}]:{}: value is not a string", section, key)));
return;
}
r->GetConfig()->Override(section, key, value.get<std::string>());

@ -61,12 +61,6 @@ namespace llarp
return as_array() < other.as_array();
}
friend std::ostream&
operator<<(std::ostream& out, const Address& self)
{
return out << self.ToString();
}
bool
operator==(const Address& other) const
{
@ -96,6 +90,9 @@ namespace llarp
ParseAddress(std::string_view lokinet_addr);
} // namespace service
template <>
constexpr inline bool IsToStringFormattable<service::Address> = true;
} // namespace llarp
namespace std

@ -190,11 +190,12 @@ namespace llarp
// use factory to create endpoint
const auto itr = endpointConstructors.find(endpointType);
if (itr == endpointConstructors.end())
throw std::invalid_argument(stringify("Endpoint type ", endpointType, " does not exist"));
throw std::invalid_argument{fmt::format("Endpoint type {} does not exist", endpointType)};
auto service = itr->second(m_Router, this);
if (not service)
throw std::runtime_error(stringify("Failed to construct endpoint of type ", endpointType));
throw std::runtime_error{
fmt::format("Failed to construct endpoint of type {}", endpointType)};
// pass conf to service
service->Configure(conf.network, conf.dns);

@ -3,7 +3,7 @@
#include <llarp/exit/session.hpp>
#include "outbound_context.hpp"
#include "lookup.hpp"
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/logging.hpp>
namespace llarp
{

@ -104,16 +104,16 @@ namespace llarp
// write
auto optional_f = util::OpenFileStream<std::ofstream>(fname, std::ios::binary);
if (!optional_f)
throw std::runtime_error(stringify("can not open ", fname));
throw std::runtime_error{fmt::format("can not open {}", fname)};
auto& f = *optional_f;
if (!f.is_open())
throw std::runtime_error(stringify("did not open ", fname));
throw std::runtime_error{fmt::format("did not open {}", fname)};
f.write((char*)buf.cur, buf.sz);
}
if (not fs::is_regular_file(fname))
{
throw std::invalid_argument(stringify(fname, " is not a regular file"));
throw std::invalid_argument{fmt::format("{} is not a regular file", fname)};
}
// read file

@ -107,5 +107,13 @@ namespace llarp
return stream;
}
std::string
ServiceInfo::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
} // namespace service
} // namespace llarp

@ -66,6 +66,9 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const;
/// .loki address
std::string
Name() const;
@ -101,11 +104,8 @@ namespace llarp
bool
DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf);
};
inline std::ostream&
operator<<(std::ostream& out, const ServiceInfo& i)
{
return i.print(out, -1, -1);
}
} // namespace service
} // namespace llarp
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::service::ServiceInfo> = true;

@ -1,4 +1,5 @@
#include "intro.hpp"
#include "util/time.hpp"
namespace llarp
{
@ -77,5 +78,14 @@ namespace llarp
return stream;
}
std::string
Introduction::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
} // namespace service
} // namespace llarp

@ -36,6 +36,8 @@ namespace llarp
std::ostream&
print(std::ostream& stream, int level, int spaces) const;
std::string
ToString() const;
bool
BEncode(llarp_buffer_t* buf) const;
@ -72,12 +74,6 @@ namespace llarp
}
};
inline std::ostream&
operator<<(std::ostream& out, const Introduction& i)
{
return i.print(out, -1, -1);
}
/// comparator for introset timestamp
struct CompareIntroTimestamp
{
@ -90,6 +86,9 @@ namespace llarp
} // namespace service
} // namespace llarp
template <>
constexpr inline bool llarp::IsToStringFormattable<llarp::service::Introduction> = true;
namespace std
{
template <>

@ -81,6 +81,14 @@ namespace llarp::service
return out;
}
std::string
EncryptedIntroSet::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
std::optional<IntroSet>
EncryptedIntroSet::MaybeDecrypt(const PubKey& root) const
{
@ -155,11 +163,7 @@ namespace llarp::service
supportedProtocols.begin(),
supportedProtocols.end(),
std::back_inserter(protocols),
[](const auto& proto) -> util::StatusObject {
std::stringstream ss;
ss << proto;
return ss.str();
});
[](const auto& proto) -> util::StatusObject { return service::ToString(proto); });
obj["protos"] = protocols;
std::vector<util::StatusObject> ranges;
std::transform(
@ -449,4 +453,12 @@ namespace llarp::service
return stream;
}
std::string
IntroSet::ToString() const
{
std::ostringstream o;
print(o, -1, -1);
return o.str();
}
} // namespace llarp::service

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save