Merge remote-tracking branch 'origin/dev' into centos/8

pull/1770/head
glen 3 years ago
commit 684f15d112

1
.gitattributes vendored

@ -2,3 +2,4 @@ external/date/test export-ignore
external/nlohmann/doc export-ignore
external/nlohmann/test export-ignore
external/nlohmann/benchmarks/data export-ignore
*.signed binary

2
.gitignore vendored

@ -26,6 +26,8 @@ callgrind.*
*.sig
*.signed
!/contrib/bootstrap/mainnet.signed
!/contrib/bootstrap/testnet.signed
*.key
shadow.data

@ -51,7 +51,7 @@ option(EMBEDDED_CFG "optimise for older hardware or embedded systems" OFF)
option(BUILD_LIBLOKINET "build liblokinet.so" ON)
option(SHADOW "use shadow testing framework. linux only" OFF)
option(XSAN "use sanitiser, if your system has it (requires -DCMAKE_BUILD_TYPE=Debug)" OFF)
option(WITH_JEMALLOC "use jemalloc as allocator" OFF)
option(USE_JEMALLOC "Link to jemalloc for memory allocations, if found" ON)
option(TESTNET "testnet build" OFF)
option(WITH_COVERAGE "generate coverage data" OFF)
option(USE_SHELLHOOKS "enable shell hooks on compile time (dangerous)" OFF)
@ -299,7 +299,6 @@ endif()
add_subdirectory(external)
include_directories(SYSTEM external/sqlite_orm/include)
option(USE_JEMALLOC "Link to jemalloc for memory allocations, if found" ON)
if(USE_JEMALLOC AND NOT STATIC_LINK)
pkg_check_modules(JEMALLOC jemalloc IMPORTED_TARGET)
if(JEMALLOC_FOUND)

@ -388,6 +388,7 @@ foreach(curl_arch ${curl_arches})
--disable-progress-meter --without-brotli --with-zlib=${DEPS_DESTDIR} ${curl_ssl_opts}
--without-libmetalink --without-librtmp --disable-versioned-symbols --enable-hidden-symbols
--without-zsh-functions-dir --without-fish-functions-dir
--without-nghttp3 --without-zstd
"CC=${deps_cc}" "CFLAGS=${deps_noarch_CFLAGS}${cflags_extra}" ${curl_extra}
BUILD_COMMAND true
INSTALL_COMMAND ${_make} -C lib install && ${_make} -C include install

@ -2,7 +2,6 @@ function(add_log_tag target)
get_target_property(TARGET_SRCS ${target} SOURCES)
foreach(F ${TARGET_SRCS})
get_filename_component(fpath "${F}" ABSOLUTE)
string(REPLACE "${PROJECT_SOURCE_DIR}/" "" logtag "${fpath}")
set_property(SOURCE ${F} APPEND PROPERTY COMPILE_DEFINITIONS LOG_TAG=\"${logtag}\")
set_property(SOURCE ${F} APPEND PROPERTY COMPILE_DEFINITIONS SOURCE_ROOT=\"${PROJECT_SOURCE_DIR}\")
endforeach()
endfunction()

@ -0,0 +1,52 @@
# ngtcp2's top-level CMakeLists.txt loads a bunch of crap we don't want (examples, a conflicting
# 'check' target, etc.); instead we directly include it's lib subdirectory to build just the
# library, but we have to set up a couple things to make that work:
function(add_ngtcp2_lib)
file(STRINGS ngtcp2/CMakeLists.txt ngtcp2_project_line REGEX "^project\\(ngtcp2 ")
if(NOT ngtcp2_project_line MATCHES "^project\\(ngtcp2 VERSION ([0-9]+)\\.([0-9]+)\\.([0-9]+)\\)$")
message(FATAL_ERROR "Unable to extract ngtcp2 version from ngtcp2/CMakeLists.txt (found '${ngtcp2_project_line}')")
endif()
set(PACKAGE_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
include(ngtcp2/cmake/Version.cmake)
HexVersion(PACKAGE_VERSION_NUM ${CMAKE_MATCH_1} ${CMAKE_MATCH_2} ${CMAKE_MATCH_3})
configure_file("ngtcp2/lib/includes/ngtcp2/version.h.in" "ngtcp2/lib/includes/ngtcp2/version.h" @ONLY)
set(BUILD_SHARED_LIBS OFF)
# Checks for header files.
include(CheckIncludeFile)
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file("stddef.h" HAVE_STDDEF_H)
check_include_file("stdint.h" HAVE_STDINT_H)
check_include_file("stdlib.h" HAVE_STDLIB_H)
check_include_file("string.h" HAVE_STRING_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
check_include_file("sys/endian.h" HAVE_SYS_ENDIAN_H)
check_include_file("endian.h" HAVE_ENDIAN_H)
check_include_file("byteswap.h" HAVE_BYTESWAP_H)
include(CheckTypeSize)
check_type_size("ssize_t" SIZEOF_SSIZE_T)
if(SIZEOF_SSIZE_T STREQUAL "")
set(ssize_t ptrdiff_t)
endif()
include(CheckSymbolExists)
if(HAVE_ENDIAN_H)
check_symbol_exists(be64toh "endian.h" HAVE_BE64TOH)
endif()
if(NOT HAVE_BE64TO AND HAVE_SYS_ENDIAN_H)
check_symbol_exists(be64toh "sys/endian.h" HAVE_BE64TOH)
endif()
check_symbol_exists(bswap_64 "byteswap.h" HAVE_BSWAP_64)
configure_file(ngtcp2/cmakeconfig.h.in ngtcp2/config.h)
include_directories("${CMAKE_CURRENT_BINARY_DIR}/ngtcp2") # for config.h
add_subdirectory(ngtcp2/lib EXCLUDE_FROM_ALL)
target_compile_definitions(ngtcp2 PRIVATE -DHAVE_CONFIG_H -D_GNU_SOURCE)
endfunction()

@ -7,15 +7,6 @@ endif()
include(CheckCXXSourceCompiles)
include(CheckLibraryExists)
if(WITH_JEMALLOC)
find_package(Jemalloc REQUIRED)
if(NOT JEMALLOC_FOUND)
message(FATAL_ERROR "did not find jemalloc")
endif()
add_definitions(-DUSE_JEMALLOC)
message(STATUS "using jemalloc")
endif()
add_definitions(-DUNIX)
add_definitions(-DPOSIX)

@ -5,17 +5,12 @@ endif()
set(TUNTAP_URL "https://build.openvpn.net/downloads/releases/latest/tap-windows-latest-stable.exe")
set(TUNTAP_EXE "${CMAKE_BINARY_DIR}/tuntap-install.exe")
set(BOOTSTRAP_URL "https://seed.lokinet.org/lokinet.signed")
set(BOOTSTRAP_FILE "${CMAKE_BINARY_DIR}/bootstrap.signed")
set(BOOTSTRAP_FILE "${PROJECT_SOURCE_DIR}/contrib/bootstrap/mainnet.signed")
file(DOWNLOAD
${TUNTAP_URL}
${TUNTAP_EXE})
file(DOWNLOAD
${BOOTSTRAP_URL}
${BOOTSTRAP_FILE})
file(DOWNLOAD
${GUI_ZIP_URL}
${CMAKE_BINARY_DIR}/lokinet-gui.zip
@ -26,7 +21,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_BINARY_DIR}/lokinet-g
install(DIRECTORY ${CMAKE_BINARY_DIR}/gui DESTINATION share COMPONENT gui)
install(PROGRAMS ${TUNTAP_EXE} DESTINATION bin COMPONENT tuntap)
install(FILES ${BOOTSTRAP_FILE} DESTINATION share COMPONENT lokinet)
install(FILES ${BOOTSTRAP_FILE} DESTINATION share COMPONENT lokinet RENAME bootstrap.signed)
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Lokinet")
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/win32-setup/lokinet.ico")

Binary file not shown.

@ -0,0 +1 @@
d1:ald1:ci2e1:d3:iwp1:e32:9ãxÚsX«l%ìû€ê<,sØ›•©÷ïå_1:i21:::ffff:144.76.164.2021:pi1666e1:vi0eee1:i5:gamma1:k32:ÞÊðòm=o„ZÐ1ÿßmcŒ%»¸ÿû¾™SĹ1:p32:!EÏâéz˜ý:Š‹úý… /0¡Ú„ Ãݪ„µNçB1:rli0ei0ei8ei3ee1:ui1614788310454e1:vi0e1:xle1:z64:Œ¤u G¿”D“=Œxµ¢{ïÌ51þ`í߀ùEâw m)q2Øg¯±˜øš ï³À)˜TÑP•´ò³ö—Á1e

@ -1,3 +1,8 @@
set(DEFAULT_WITH_BOOTSTRAP ON)
if(APPLE)
set(DEFAULT_WITH_BOOTSTRAP OFF)
endif()
option(WITH_BOOTSTRAP "build lokinet-bootstrap tool" ${DEFAULT_WITH_BOOTSTRAP})
add_executable(lokinet-vpn lokinet-vpn.cpp)
if(APPLE)
@ -5,8 +10,12 @@ if(APPLE)
enable_lto(lokinet)
else()
add_executable(lokinet lokinet.cpp)
add_executable(lokinet-bootstrap lokinet-bootstrap.cpp)
enable_lto(lokinet lokinet-vpn lokinet-bootstrap)
enable_lto(lokinet lokinet-vpn)
if(WITH_BOOTSTRAP)
add_executable(lokinet-bootstrap lokinet-bootstrap.cpp)
enable_lto(lokinet-bootstrap)
endif()
endif()
@ -30,7 +39,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
endif()
endif()
if(NOT APPLE)
if(WITH_BOOTSTRAP)
target_link_libraries(lokinet-bootstrap PUBLIC cpr::cpr)
if(NOT WIN32)
find_package(OpenSSL REQUIRED)
@ -40,7 +49,7 @@ if(NOT APPLE)
endif()
set(exetargets lokinet lokinet-vpn)
if(NOT APPLE)
if(WITH_BOOTSTRAP)
list(APPEND exetargets lokinet-bootstrap)
endif()
@ -53,9 +62,6 @@ foreach(exe ${exetargets})
target_link_directories(${exe} PRIVATE /usr/local/lib)
endif()
target_link_libraries(${exe} PUBLIC liblokinet)
if(WITH_JEMALLOC)
target_link_libraries(${exe} PUBLIC jemalloc)
endif()
target_include_directories(${exe} PUBLIC "${PROJECT_SOURCE_DIR}")
target_compile_definitions(${exe} PRIVATE -DVERSIONTAG=${GIT_VERSION_REAL})
add_log_tag(${exe})
@ -79,10 +85,9 @@ if(APPLE)
DEPENDS ${PROJECT_SOURCE_DIR}/contrib/lokinet.svg ${PROJECT_SOURCE_DIR}/contrib/macos/mk-icns.sh)
add_custom_target(icons DEPENDS ${mac_icon})
add_dependencies(lokinet icons lokinet-extension)
file(DOWNLOAD "https://seed.lokinet.org/lokinet.signed" ${CMAKE_CURRENT_BINARY_DIR}/bootstrap.signed)
add_custom_command(TARGET lokinet
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/bootstrap.signed
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/contrib/bootstrap/mainnet.signed
$<TARGET_BUNDLE_DIR:lokinet-extension>/Contents/Resources/bootstrap.signed
COMMAND mkdir -p $<TARGET_BUNDLE_DIR:lokinet>/Contents/PlugIns
COMMAND cp -a $<TARGET_BUNDLE_DIR:lokinet-extension> $<TARGET_BUNDLE_DIR:lokinet>/Contents/PlugIns/

@ -18,32 +18,6 @@
#include <iostream>
#include <future>
#ifdef USE_JEMALLOC
#include <new>
#include <jemalloc/jemalloc.h>
void*
operator new(std::size_t sz)
{
void* ptr = malloc(sz);
if (ptr)
return ptr;
else
throw std::bad_alloc{};
}
void
operator delete(void* ptr) noexcept
{
free(ptr);
}
void
operator delete(void* ptr, size_t) noexcept
{
free(ptr);
}
#endif
int
lokinet_main(int, char**);
@ -259,7 +233,7 @@ run_main_context(std::optional<fs::path> confFile, const llarp::RuntimeOptions o
try
{
std::shared_ptr<llarp::Config> conf;
if (confFile.has_value())
if (confFile)
{
llarp::LogInfo("Using config file: ", *confFile);
conf = std::make_shared<llarp::Config>(confFile->parent_path());
@ -268,8 +242,12 @@ run_main_context(std::optional<fs::path> confFile, const llarp::RuntimeOptions o
{
conf = std::make_shared<llarp::Config>(llarp::GetDefaultDataDir());
}
if (!conf->Load(confFile, opts.isSNode))
throw std::runtime_error{"Config file parsing failed"};
if (not conf->Load(confFile, opts.isSNode))
{
llarp::LogError("failed to parse configuration");
exit_code.set_value(1);
return;
}
ctx = std::make_shared<llarp::Context>();
ctx->Configure(std::move(conf));
@ -281,7 +259,17 @@ run_main_context(std::optional<fs::path> confFile, const llarp::RuntimeOptions o
signal(SIGUSR1, handle_signal);
#endif
ctx->Setup(opts);
try
{
ctx->Setup(opts);
}
catch (std::exception& ex)
{
llarp::LogError(
"failed to set up lokinet: ", ex.what(), ", is lokinet already running? 🤔");
exit_code.set_value(1);
return;
}
llarp::util::SetThreadName("llarp-mainloop");
@ -522,7 +510,7 @@ lokinet_main(int argc, char* argv[])
}
catch (std::exception& ex)
{
LogError("cannot generate config at ", *configFile, ": ", ex.what());
llarp::LogError("cannot generate config at ", *configFile, ": ", ex.what());
return 1;
}
}
@ -538,7 +526,7 @@ lokinet_main(int argc, char* argv[])
}
catch (std::exception& ex)
{
LogError("cannot check if ", *configFile, " exists: ", ex.what());
llarp::LogError("cannot check if ", *configFile, " exists: ", ex.what());
return 1;
}
}
@ -600,7 +588,7 @@ lokinet_main(int argc, char* argv[])
"file a bug report now or be cursed with this "
"annoying image in your syslog for all time."})
{
LogError(wtf);
llarp::LogError{wtf};
llarp::LogContext::Instance().ImmediateFlush();
}
#ifdef _WIN32

@ -10,7 +10,7 @@ to configure lokinet to be an exit add into `lokinet.ini`:
keyfile=/var/lib/lokinet/exit.private
reachable=1
ifaddr=10.0.0.1/16
hops=1
hops=2
paths=8

@ -50,15 +50,9 @@ add_library(uvw INTERFACE)
target_include_directories(uvw INTERFACE uvw/src)
target_link_libraries(uvw INTERFACE libuv)
# We don't need any of these as we don't use the ssl crypto helper code at all:
set(ENABLE_GNUTLS OFF CACHE BOOL "Disable gnutls for ngtcp2")
set(ENABLE_OPENSSL OFF CACHE BOOL "Disable openssl for ngtcp2")
set(ENABLE_BORINGSSL OFF CACHE BOOL "Disable boringssl for ngtcp2")
add_definitions(-D_GNU_SOURCE)
add_subdirectory(ngtcp2 EXCLUDE_FROM_ALL)
# ngtcp2 needs some massaging to build nicely:
include(ngtcp2_lib)
add_ngtcp2_lib()
# cpr configuration. Ideally we'd just do this via add_subdirectory, but cpr's cmake requires
# 3.15+, and we target lower than that (and this is fairly simple to build).

@ -1,6 +1,7 @@
include(Version)
add_library(lokinet-util
STATIC
${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp
util/bencode.cpp
util/buffer.cpp
@ -9,7 +10,6 @@ add_library(lokinet-util
util/logging/android_logger.cpp
util/logging/buffer.cpp
util/logging/file_logger.cpp
util/logging/json_logger.cpp
util/logging/logger.cpp
util/logging/logger_internal.cpp
util/logging/loglevel.cpp

@ -6,7 +6,7 @@ namespace llarp::apple
NSLogStream::PreLog(
std::stringstream& ss,
LogLevel lvl,
const char* fname,
std::string_view fname,
int lineno,
const std::string& nodename) const
{
@ -17,7 +17,7 @@ namespace llarp::apple
}
void
NSLogStream::Print(LogLevel, const char*, const std::string& msg)
NSLogStream::Print(LogLevel, std::string_view, const std::string& msg)
{
ns_logger(msg.c_str());
}

@ -16,15 +16,15 @@ namespace llarp::apple
PreLog(
std::stringstream& s,
LogLevel lvl,
const char* fname,
std::string_view fname,
int lineno,
const std::string& nodename) const override;
void
Print(LogLevel lvl, const char* tag, const std::string& msg) override;
Print(LogLevel lvl, std::string_view tag, const std::string& msg) override;
void
PostLog(std::stringstream& ss) const override
PostLog(std::stringstream&) const override
{}
void

@ -105,7 +105,7 @@ llarp_apple_init(llarp_apple_config* appleconf)
}
catch (const std::exception& e)
{
LogError("Failed to initialize lokinet from config: ", e.what());
llarp::LogError("Failed to initialize lokinet from config: ", e.what());
}
return nullptr;
}
@ -149,7 +149,7 @@ llarp_apple_start(void* lokinet, void* callback_context)
}
catch (const std::exception& e)
{
LogError("Failed to initialize lokinet: ", e.what());
llarp::LogError("Failed to initialize lokinet: ", e.what());
return -1;
}
@ -178,7 +178,7 @@ llarp_apple_incoming(void* lokinet, const void* bytes, size_t size)
if (iface->OfferReadPacket(buf))
return 0;
LogError("invalid IP packet: ", llarp::buffer_printer(buf));
llarp::LogError("invalid IP packet: ", llarp::buffer_printer(buf));
return -1;
}

@ -569,7 +569,13 @@ namespace llarp
IP6RangeDefault,
[this](std::string arg) {
if (arg.empty())
{
LogError(
"!!! Disabling ipv6 tunneling when you have ipv6 routes WILL lead to "
"de-anonymization as lokinet will no longer carry your ipv6 traffic !!!");
m_baseV6Address = std::nullopt;
return;
}
m_baseV6Address = huint128_t{};
if (not m_baseV6Address->FromString(arg))
throw std::invalid_argument(
@ -1048,7 +1054,6 @@ namespace llarp
Comment{
"Log type (format). Valid options are:",
" file - plaintext formatting",
" json - json-formatted log statements",
" syslog - logs directed to syslog",
});

@ -117,16 +117,16 @@ namespace llarp
{
if (!qd.Decode(buf))
{
llarp::LogError("failed to decode question");
LogError("failed to decode question");
return false;
}
llarp::LogDebug(qd);
LogDebug("dns question: ", qd);
}
for (auto& an : answers)
{
if (not an.Decode(buf))
{
llarp::LogDebug("failed to decode answer");
LogDebug("failed to decode answer");
return false;
}
}

@ -110,7 +110,7 @@ namespace llarp
llarp_time_t
Now() const override;
void
virtual void
Tick(llarp_time_t now) override;
void

@ -21,7 +21,7 @@ namespace llarp::quic
class Address
{
sockaddr_in6 saddr{};
ngtcp2_addr a{sizeof(saddr), reinterpret_cast<sockaddr*>(&saddr), nullptr};
ngtcp2_addr a{sizeof(saddr), reinterpret_cast<sockaddr*>(&saddr)};
public:
Address() = default;
@ -102,8 +102,7 @@ namespace llarp::quic
Address local_, remote_;
public:
ngtcp2_path path{
{local_.sockaddr_size(), local_, nullptr}, {remote_.sockaddr_size(), remote_, nullptr}};
ngtcp2_path path{{local_.sockaddr_size(), local_}, {remote_.sockaddr_size(), remote_}, nullptr};
// Public accessors are const:
const Address& local = local_;

@ -244,6 +244,7 @@ namespace llarp::quic
int
stream_close_cb(
ngtcp2_conn* conn,
uint32_t flags,
int64_t stream_id,
uint64_t app_error_code,
void* user_data,
@ -275,17 +276,13 @@ namespace llarp::quic
return 0;
}
int
rand(
uint8_t* dest,
size_t destlen,
const ngtcp2_rand_ctx* rand_ctx,
[[maybe_unused]] ngtcp2_rand_usage usage)
void
rand(uint8_t* dest, size_t destlen, const ngtcp2_rand_ctx* rand_ctx)
{
LogTrace("######################", __func__);
randombytes_buf(dest, destlen);
return 0;
}
int
get_new_connection_id(
ngtcp2_conn* conn_, ngtcp2_cid* cid_, uint8_t* token, size_t cidlen, void* user_data)
@ -340,7 +337,7 @@ namespace llarp::quic
va_start(ap, fmt);
if (char* msg; vasprintf(&msg, fmt, ap) >= 0)
{
LogTraceExplicit("external/ngtcp2/*.c", 0, msg);
LogTrace{msg};
std::free(msg);
}
va_end(ap);
@ -406,7 +403,7 @@ namespace llarp::quic
settings.initial_ts = get_timestamp();
// FIXME: IPv6
settings.max_udp_payload_size = NGTCP2_MAX_PKTLEN_IPV4;
settings.max_udp_payload_size = Endpoint::max_pkt_size_v4;
settings.cc_algo = NGTCP2_CC_ALGO_CUBIC;
// settings.initial_rtt = ???; # NGTCP2's default is 333ms
@ -1185,8 +1182,7 @@ namespace llarp::quic
ngtcp2_conn_get_local_transport_params(*this, &tparams);
assert(conn_buffer.empty());
static_assert(NGTCP2_MAX_PKTLEN_IPV4 > NGTCP2_MAX_PKTLEN_IPV6);
conn_buffer.resize(NGTCP2_MAX_PKTLEN_IPV4);
conn_buffer.resize(Endpoint::max_pkt_size_v4);
auto* buf = u8data(conn_buffer);
auto* bufend = buf + conn_buffer.size();

@ -123,7 +123,7 @@ namespace llarp::quic
};
// Packet data storage for a packet we are currently sending
std::array<std::byte, NGTCP2_MAX_PKTLEN_IPV4> send_buffer{};
std::array<std::byte, NGTCP2_MAX_UDP_PAYLOAD_SIZE> send_buffer{};
size_t send_buffer_size = 0;
ngtcp2_pkt_info send_pkt_info{};

@ -199,7 +199,7 @@ namespace llarp::quic
void
Endpoint::send_version_negotiation(const version_info& vi, const Address& source)
{
std::array<std::byte, NGTCP2_MAX_PKTLEN_IPV4> buf;
std::array<std::byte, Endpoint::max_pkt_size_v4> buf;
std::array<uint32_t, NGTCP2_PROTO_VER_MAX - NGTCP2_PROTO_VER_MIN + 2> versions;
std::iota(versions.begin() + 1, versions.end(), NGTCP2_PROTO_VER_MIN);
// we're supposed to send some 0x?a?a?a?a version to trigger version negotiation
@ -234,11 +234,13 @@ namespace llarp::quic
Path path;
ngtcp2_pkt_info pi;
auto write_close_func =
application ? ngtcp2_conn_write_application_close : ngtcp2_conn_write_connection_close;
auto write_close_func = application ? ngtcp2_conn_write_application_close_versioned
: ngtcp2_conn_write_connection_close_versioned;
auto written = write_close_func(
conn,
path,
NGTCP2_PKT_INFO_VERSION,
&pi,
u8data(conn.conn_buffer),
conn.conn_buffer.size(),

@ -64,8 +64,8 @@ namespace llarp::quic
// Max theoretical size of a UDP packet is 2^16-1 minus IP/UDP header overhead
static constexpr size_t max_buf_size = 64 * 1024;
// Max size of a UDP packet that we'll send
static constexpr size_t max_pkt_size_v4 = NGTCP2_MAX_PKTLEN_IPV4;
static constexpr size_t max_pkt_size_v6 = NGTCP2_MAX_PKTLEN_IPV6;
static constexpr size_t max_pkt_size_v4 = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
static constexpr size_t max_pkt_size_v6 = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
using primary_conn_ptr = std::shared_ptr<Connection>;
using alias_conn_ptr = std::weak_ptr<Connection>;

@ -324,6 +324,9 @@ namespace llarp
virtual util::StatusObject
ExtractStatus() const = 0;
virtual util::StatusObject
ExtractSummaryStatus() const = 0;
/// gossip an rc if required
virtual void
GossipRCIfNeeded(const RouterContact rc) = 0;

@ -15,7 +15,6 @@
#include <stdexcept>
#include <llarp/util/buffer.hpp>
#include <llarp/util/logging/file_logger.hpp>
#include <llarp/util/logging/json_logger.hpp>
#include <llarp/util/logging/logger_syslog.hpp>
#include <llarp/util/logging/logger.hpp>
#include <llarp/util/meta/memfn.hpp>
@ -97,6 +96,77 @@ namespace llarp
}
}
util::StatusObject
Router::ExtractSummaryStatus() const
{
if (!_running)
return util::StatusObject{{"running", false}};
auto services = _hiddenServiceContext.ExtractStatus();
auto link_types = _linkManager.ExtractStatus();
uint64_t tx_rate = 0;
uint64_t rx_rate = 0;
uint64_t peers = 0;
for (const auto& links : link_types)
{
for (const auto& link : links)
{
if (link.empty())
continue;
for (const auto& peer : link["sessions"]["established"])
{
tx_rate += peer["tx"].get<uint64_t>();
rx_rate += peer["rx"].get<uint64_t>();
peers++;
}
}
}
// Compute all stats on all path builders on the default endpoint
// Merge snodeSessions, remoteSessions and default into a single array
std::vector<nlohmann::json> builders;
auto snode_sessions = services["default"]["snodeSessions"];
for (const auto& session : snode_sessions)
builders.push_back(session["buildStats"]);
auto remote_sessions = services["default"]["remoteSessions"];
for (const auto& session : remote_sessions)
builders.push_back(session["buildStats"]);
builders.push_back(services["default"]["buildStats"]);
// Iterate over all items on this array to build the global pathStats
uint64_t paths = 0;
uint64_t success = 0;
uint64_t attempts = 0;
for (const auto& builder : builders)
{
if (builder.is_null())
continue;
if (builder["length"].is_number())
paths += builder["length"].get<uint64_t>();
if (builder["success"].is_number())
success += builder["success"].get<uint64_t>();
if (builder["attempts"].is_number())
attempts += builder["attempts"].get<uint64_t>();
}
double ratio = static_cast<double>(success) / (attempts + 1);
return util::StatusObject{
{"running", true},
{"authCodes", services["default"]["authCodes"]},
{"exitMap", services["default"]["exitMap"]},
{"lokiAddress", services["default"]["identity"]},
{"numPathsBuilt", paths},
{"numPeersConnected", peers},
{"numRoutersKnown", _nodedb->NumLoaded()},
{"ratio", ratio},
{"txRate", tx_rate},
{"rxRate", rx_rate},
};
}
bool
Router::HandleRecvLinkMessageBuffer(ILinkSession* session, const llarp_buffer_t& buf)
{

@ -103,6 +103,9 @@ namespace llarp
util::StatusObject
ExtractStatus() const override;
util::StatusObject
ExtractSummaryStatus() const override;
const std::shared_ptr<NodeDB>&
nodedb() const override
{

@ -87,46 +87,84 @@ namespace llarp
{
// This passing address by bytes and using two separate calls for ipv4/ipv6 is gross, but the
// alternative is to build up a bunch of crap with va_args, which is slightly more gross.
const bool isStandardDNSPort = dns.getPort() == 53;
if (dns.isIPv6())
{
auto ipv6 = dns.getIPv6();
static_assert(sizeof(ipv6) == 16);
auto* a = reinterpret_cast<const uint8_t*>(&ipv6);
resolved_call(
bus,
"SetLinkDNSEx",
"ia(iayqs)",
(int32_t)if_ndx,
(int)1, // number of "iayqs"s we are passing
(int32_t)AF_INET6, // network address type
(int)16, // network addr byte size
// clang-format off
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], // yuck
// clang-format on
(uint16_t)dns.getPort(),
nullptr // dns server name (for TLS SNI which we don't care about)
);
if (isStandardDNSPort)
{
resolved_call(
bus,
"SetLinkDNS",
"ia(iay)",
(int32_t)if_ndx,
(int)1, // number of "iayqs"s we are passing
(int32_t)AF_INET6, // network address type
(int)16, // network addr byte size
// clang-format off
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15] // yuck
// clang-format on
);
}
else
{
resolved_call(
bus,
"SetLinkDNSEx",
"ia(iayqs)",
(int32_t)if_ndx,
(int)1, // number of "iayqs"s we are passing
(int32_t)AF_INET6, // network address type
(int)16, // network addr byte size
// clang-format off
a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], // yuck
// clang-format on
(uint16_t)dns.getPort(),
nullptr // dns server name (for TLS SNI which we don't care about)
);
}
}
else
{
auto ipv4 = dns.getIPv4();
static_assert(sizeof(ipv4) == 4);
auto* a = reinterpret_cast<const uint8_t*>(&ipv4);
resolved_call(
bus,
"SetLinkDNSEx",
"ia(iayqs)",
(int32_t)if_ndx,
(int)1, // number of "iayqs"s we are passing
(int32_t)AF_INET, // network address type
(int)4, // network addr byte size
// clang-format off
a[0], a[1], a[2], a[3], // yuck
// clang-format on
(uint16_t)dns.getPort(),
nullptr // dns server name (for TLS SNI which we don't care about)
);
if (isStandardDNSPort)
{
resolved_call(
bus,
"SetLinkDNS",
"ia(iay)",
(int32_t)if_ndx,
(int)1, // number of "iayqs"s we are passing
(int32_t)AF_INET, // network address type
(int)4, // network addr byte size
// clang-format off
a[0], a[1], a[2], a[3] // yuck
// clang-format on
);
}
else
{
resolved_call(
bus,
"SetLinkDNSEx",
"ia(iayqs)",
(int32_t)if_ndx,
(int)1, // number of "iayqs"s we are passing
(int32_t)AF_INET, // network address type
(int)4, // network addr byte size
// clang-format off
a[0], a[1], a[2], a[3], // yuck
// clang-format on
(uint16_t)dns.getPort(),
nullptr // dns server name (for TLS SNI which we don't care about)
);
}
}
if (global)

@ -133,6 +133,13 @@ namespace llarp::rpc
defer.reply(data);
});
})
.add_request_command(
"get_status",
[&](oxenmq::Message& msg) {
m_Router->loop()->call([defer = msg.send_later(), r = m_Router]() {
defer.reply(CreateJSONResponse(r->ExtractSummaryStatus()));
});
})
.add_request_command(
"quic_connect",
[&](oxenmq::Message& msg) {

@ -470,6 +470,7 @@ namespace llarp
if (itr == Sessions().end())
return false;
si = itr->second.remote;
si.UpdateAddr();
return true;
}
@ -1100,13 +1101,14 @@ namespace llarp
bool
Endpoint::HandleDataMessage(
path::Path_ptr, const PathID_t from, std::shared_ptr<ProtocolMessage> msg)
path::Path_ptr p, const PathID_t from, std::shared_ptr<ProtocolMessage> msg)
{
PutSenderFor(msg->tag, msg->sender, true);
Introduction intro = msg->introReply;
if (HasInboundConvo(msg->sender.Addr()))
{
intro.pathID = from;
intro.router = p->Endpoint();
}
PutReplyIntroFor(msg->tag, intro);
ConvoTagRX(msg->tag);

@ -13,7 +13,7 @@ namespace llarp
{
struct Introduction
{
PubKey router;
RouterID router;
PathID_t pathID;
llarp_time_t latency = 0s;
llarp_time_t expiresAt = 0s;

@ -54,7 +54,7 @@ namespace llarp
return true;
}
constexpr auto OutboundContextNumPaths = 2;
constexpr auto OutboundContextNumPaths = 4;
OutboundContext::OutboundContext(const IntroSet& introset, Endpoint* parent)
: path::Builder{parent->Router(), OutboundContextNumPaths, parent->numHops}
@ -64,12 +64,17 @@ namespace llarp
, currentIntroSet{introset}
{
assert(not introset.intros.empty());
updatingIntroSet = false;
for (const auto& intro : introset.intros)
// pick random first intro
auto it = introset.intros.begin();
if (introset.intros.size() > 1)
{
if (m_NextIntro.latency == 0s or m_NextIntro.latency > intro.latency)
m_NextIntro = intro;
CSRNG rng{};
it += std::uniform_int_distribution<size_t>{0, introset.intros.size() - 1}(rng);
}
m_NextIntro = *it;
currentConvoTag.Randomize();
lastShift = Now();
// add send and connect timeouts to the parent endpoints path alignment timeout
@ -333,6 +338,7 @@ namespace llarp
Encrypted<64> tmp;
tmp.Randomize();
SendPacketToRemote(tmp, ProtocolType::Control);
m_LastKeepAliveAt = Now();
}
bool
@ -348,7 +354,10 @@ namespace llarp
// expunge
SharedSecret discardme;
if (not m_DataHandler->GetCachedSessionKeyFor(currentConvoTag, discardme))
{
LogError(Name(), " no cached key after sending intro, we are in a fugged state, oh no");
return true;
}
}
if (m_GotInboundTraffic and m_LastInboundTraffic + sendTimeout <= now)
@ -404,21 +413,33 @@ namespace llarp
m_ReadyHooks.clear();
}
if (m_LastInboundTraffic > 0s and lastGoodSend > 0s
and now >= sendTimeout + m_LastInboundTraffic)
return true;
const auto timeout = std::max(lastGoodSend, m_LastInboundTraffic);
if (lastGoodSend > 0s and now >= timeout + (sendTimeout / 2))
{
// send a keep alive to keep this session alive
KeepAlive();
if (markedBad)
{
LogWarn(Name(), " keepalive timeout hit");
return true;
}
}
// check for half open state where we can send but we get nothing back
if (m_LastInboundTraffic == 0s and now - createdAt > connectTimeout)
{
LogWarn(Name(), " half open state, we can send but we got nothing back");
return true;
}
// if we are dead return true so we are removed
return timeout > 0s ? (now >= timeout && now - timeout > sendTimeout)
: (now >= createdAt && now - createdAt > connectTimeout);
const bool removeIt = timeout > 0s ? (now >= timeout && now - timeout > sendTimeout)
: (now >= createdAt && now - createdAt > connectTimeout);
if (removeIt)
{
LogInfo(Name(), " session is stale");
return true;
}
return false;
}
void
@ -584,6 +605,25 @@ namespace llarp
}
}
bool
OutboundContext::ShouldKeepAlive(llarp_time_t now) const
{
const auto SendKeepAliveInterval = sendTimeout / 2;
if (not m_GotInboundTraffic)
return false;
if (m_LastInboundTraffic == 0s)
return false;
return (now - m_LastKeepAliveAt) >= SendKeepAliveInterval;
}
void
OutboundContext::Tick(llarp_time_t now)
{
path::Builder::Tick(now);
if (ShouldKeepAlive(now))
KeepAlive();
}
bool
OutboundContext::HandleHiddenServiceFrame(path::Path_ptr p, const ProtocolFrame& frame)
{

@ -23,6 +23,9 @@ namespace llarp
~OutboundContext() override;
void
Tick(llarp_time_t now) override;
util::StatusObject
ExtractStatus() const;
@ -129,6 +132,9 @@ namespace llarp
void
KeepAlive();
bool
ShouldKeepAlive(llarp_time_t now) const;
const IntroSet&
GetCurrentIntroSet() const
{
@ -170,6 +176,7 @@ namespace llarp
bool sentIntro = false;
std::vector<std::function<void(OutboundContext*)>> m_ReadyHooks;
llarp_time_t m_LastIntrosetUpdateAt = 0s;
llarp_time_t m_LastKeepAliveAt = 0s;
};
} // namespace service

@ -45,7 +45,7 @@ namespace llarp
llarp_time_t lastGoodSend = 0s;
const llarp_time_t createdAt;
llarp_time_t sendTimeout = path::build_timeout;
llarp_time_t connectTimeout = path::build_timeout;
llarp_time_t connectTimeout = path::build_timeout * 2;
llarp_time_t shiftTimeout = (path::build_timeout * 5) / 2;
llarp_time_t estimatedRTT = 0s;
bool markedBad = false;

@ -75,7 +75,7 @@ namespace llarp
{
if (!item.BDecode(buf))
{
llarp::LogWarnTag("llarp/bencode.hpp", "failed to decode key ", k, " for entry in dict");
llarp::LogWarn("failed to decode key ", k, " for entry in dict");
return false;
}
@ -94,7 +94,7 @@ namespace llarp
uint64_t read_i;
if (!bencode_read_integer(buf, &read_i))
{
llarp::LogWarnTag("llarp/BEncode.hpp", "failed to decode key ", k, " for integer in dict");
llarp::LogWarn("failed to decode key ", k, " for integer in dict");
return false;
}
@ -210,8 +210,7 @@ namespace llarp
return true;
if (sink.DecodeKey(*key, buffer))
return true;
llarp::LogWarnTag(
"llarp/bencode.hpp", "undefined key '", *key->cur, "' for entry in dict");
llarp::LogWarn("undefined key '", *key->cur, "' for entry in dict");
return false;
},

@ -1,12 +1,7 @@
#pragma once
#include <functional>
#if defined(WIN32) || defined(_WIN32)
#define PATH_SEP "\\"
#else
#define PATH_SEP "/"
#endif
#include <set>
#ifdef USE_GHC_FILESYSTEM
#include <ghc/filesystem.hpp>
@ -61,36 +56,31 @@ namespace llarp
return std::make_optional<T>(pathname, mode);
}
using PathVisitor = std::function<bool(const fs::path&)>;
using PathIter = std::function<void(const fs::path&, PathVisitor)>;
static PathIter IterDir = [](const fs::path& path, PathVisitor visit) {
#ifdef _MSC_VER
for (auto& p : fs::directory_iterator(path))
{
if (!visit(p.path()))
{
break;
}
}
#else
template <typename PathVisitor>
static void
IterDir(const fs::path& path, PathVisitor visit)
{
DIR* d = opendir(path.string().c_str());
if (d == nullptr)
return;
struct dirent* ent = nullptr;
std::set<fs::path> entries;
do
{
ent = readdir(d);
if (!ent)
if (not ent)
break;
if (ent->d_name[0] == '.')
continue;
fs::path p = path / fs::path(ent->d_name);
if (!visit(p))
break;
entries.emplace(path / fs::path{ent->d_name});
} while (ent);
closedir(d);
#endif
for (const auto& p : entries)
{
if (not visit(p))
return;
}
};
} // namespace util
} // namespace llarp

@ -8,7 +8,8 @@ namespace llarp
{
void
AndroidLogStream::PreLog(
std::stringstream& ss, LogLevel lvl, const char* fname, int lineno, const std::string&) const
std::stringstream& ss, LogLevel lvl, std::string_view fname, int lineno, const std::string&)
const
{
switch (lvl)
{
@ -43,7 +44,7 @@ namespace llarp
{}
void
AndroidLogStream::Print(LogLevel lvl, const char* tag, const std::string& msg)
AndroidLogStream::Print(LogLevel lvl, std::string_view tag, const std::string& msg)
{
std::string str("lokinet|");
str += tag;
@ -62,6 +63,8 @@ namespace llarp
case eLogError:
__android_log_write(ANDROID_LOG_ERROR, str.c_str(), msg.c_str());
return;
default:
return;
}
} // namespace llarp

@ -12,12 +12,12 @@ namespace llarp
PreLog(
std::stringstream& s,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const override;
void
Print(LogLevel lvl, const char* filename, const std::string& msg) override;
Print(LogLevel lvl, std::string_view filename, const std::string& msg) override;
void
PostLog(std::stringstream&) const override;

@ -65,18 +65,18 @@ namespace llarp
FileLogStream::PreLog(
std::stringstream& ss,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const
{
ss << "[" << LogLevelToString(lvl) << "] ";
ss << "[" << nodename << "]"
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno
<< "\t";
}
void
FileLogStream::Print(LogLevel, const char*, const std::string& msg)
FileLogStream::Print(LogLevel, std::string_view, const std::string& msg)
{
m_Lines.pushBack(msg);
}
@ -84,12 +84,12 @@ namespace llarp
void
FileLogStream::AppendLog(
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename,
const std::string msg)
{
ILogStream::AppendLog(lvl, fname, lineno, nodename, msg);
ILogStream::AppendLog(lvl, filename, lineno, nodename, msg);
Tick(llarp::time_now_ms());
}

@ -23,12 +23,12 @@ namespace llarp
PreLog(
std::stringstream& out,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const override;
void
Print(LogLevel, const char*, const std::string& msg) override;
Print(LogLevel, std::string_view filename, const std::string& msg) override;
void
Tick(llarp_time_t now) override;
@ -39,7 +39,7 @@ namespace llarp
void
AppendLog(
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename,
const std::string msg) override;

@ -1,24 +0,0 @@
#include "json_logger.hpp"
#include <llarp/util/json.hpp>
namespace llarp
{
void
JSONLogStream::AppendLog(
LogLevel lvl,
const char* fname,
int lineno,
const std::string& nodename,
const std::string msg)
{
json::Object obj;
obj["time"] = to_json(llarp::time_now_ms());
obj["nickname"] = nodename;
obj["file"] = std::string(fname);
obj["line"] = lineno;
obj["level"] = LogLevelToString(lvl);
obj["message"] = msg;
m_Lines.pushBack(obj.dump());
}
} // namespace llarp

@ -1,28 +0,0 @@
#ifndef LLARP_UTIL_JSON_LOGGER
#define LLARP_UTIL_JSON_LOGGER
#include "file_logger.hpp"
namespace llarp
{
struct JSONLogStream : public FileLogStream
{
JSONLogStream(
std::function<void(FileLogStream::Work_t)> disk,
FILE* f,
llarp_time_t flushInterval,
bool closeFile)
: FileLogStream(std::move(disk), f, flushInterval, closeFile)
{}
void
AppendLog(
LogLevel lvl,
const char* fname,
int lineno,
const std::string& nodename,
const std::string msg) override;
};
} // namespace llarp
#endif

@ -2,7 +2,6 @@
#include "ostream_logger.hpp"
#include "logger_syslog.hpp"
#include "file_logger.hpp"
#include "json_logger.hpp"
#if defined(_WIN32)
#include "win32_logger.hpp"
#endif
@ -36,8 +35,6 @@ namespace llarp
return LogType::Unknown;
else if (str == "file")
return LogType::File;
else if (str == "json")
return LogType::Json;
else if (str == "syslog")
return LogType::Syslog;
@ -111,7 +108,7 @@ namespace llarp
{
logfile = stdout;
}
else
else if (type != LogType::Syslog)
{
logfile = ::fopen(file.c_str(), "a");
if (not logfile)
@ -141,26 +138,10 @@ namespace llarp
}
break;
case LogType::Json:
LogInfo("Switching logger to JSON with file: ", file);
std::cout << std::flush;
LogContext::Instance().logStream =
std::make_unique<JSONLogStream>(io, logfile, 100ms, logfile != stdout);
break;
case LogType::Syslog:
if (logfile)
{
// TODO: this logic should be handled in Config
// TODO: this won't even work because of default value for 'file' (== "stdout")
::fclose(logfile);
throw std::invalid_argument("Cannot mix log type=syslog and file=*");
}
#if defined(_WIN32)
throw std::runtime_error("syslog not supported on win32");
#else
LogInfo("Switching logger to syslog");
std::cout << std::flush;
LogContext::Instance().logStream = std::make_unique<SysLogStream>();
#endif
break;

@ -1,9 +1,11 @@
#pragma once
#include <memory>
#include <llarp/util/str.hpp>
#include <llarp/util/time.hpp>
#include "logstream.hpp"
#include "logger_internal.hpp"
#include "source_location.hpp"
namespace llarp
{
@ -11,7 +13,6 @@ namespace llarp
{
Unknown = 0,
File,
Json,
Syslog,
};
LogType
@ -77,52 +78,91 @@ namespace llarp
LogLevel
GetLogLevel();
/** internal */
template <typename... TArgs>
inline static void
_log(LogLevel lvl, const char* fname, int lineno, TArgs&&... args) noexcept
namespace
{
auto& log = LogContext::Instance();
if (log.curLevel > lvl || log.logStream == nullptr)
return;
std::ostringstream ss;
if constexpr (sizeof...(args) > 0)
LogAppend(ss, std::forward<TArgs>(args)...);
log.logStream->AppendLog(lvl, fname, lineno, log.nodeName, ss.str());
}
inline void
_log_noop() noexcept
{}
/** internal */
template <typename... TArgs>
inline static void
_log(LogLevel lvl, const slns::source_location& location, TArgs&&... args) noexcept
{
auto& log = LogContext::Instance();
if (log.curLevel > lvl || log.logStream == nullptr)
return;
std::ostringstream ss;
if constexpr (sizeof...(args) > 0)
LogAppend(ss, std::forward<TArgs>(args)...);
log.logStream->AppendLog(
lvl,
strip_prefix(location.file_name(), SOURCE_ROOT),
location.line(),
log.nodeName,
ss.str());
}
} // namespace
template <typename... T>
struct LogTrace
{
LogTrace(T... args, const slns::source_location& location = slns::source_location::current())
{
#ifdef NDEBUG
((void)args, ...);
(void)location;
#else
_log(eLogTrace, location, std::forward<T>(args)...);
#endif
}
};
} // namespace llarp
template <typename... T>
LogTrace(T&&...) -> LogTrace<T...>;
#define LogDebug(...) _log(llarp::eLogDebug, LOG_TAG, __LINE__, __VA_ARGS__)
#define LogInfo(...) _log(llarp::eLogInfo, LOG_TAG, __LINE__, __VA_ARGS__)
#define LogWarn(...) _log(llarp::eLogWarn, LOG_TAG, __LINE__, __VA_ARGS__)
#define LogError(...) _log(llarp::eLogError, LOG_TAG, __LINE__, __VA_ARGS__)
template <typename... T>
struct LogDebug
{
LogDebug(T... args, const slns::source_location& location = slns::source_location::current())
{
_log(eLogDebug, location, std::forward<T>(args)...);
}
};
#define LogDebugTag(tag, ...) _log(llarp::eLogDebug, tag, __LINE__, __VA_ARGS__)
#define LogInfoTag(tag, ...) _log(llarp::eLogInfo, tag, __LINE__, __VA_ARGS__)
#define LogWarnTag(tag, ...) _log(llarp::eLogWarn, tag, __LINE__, __VA_ARGS__)
#define LogErrorTag(tag, ...) _log(llarp::eLogError, tag, __LINE__, __VA_ARGS__)
template <typename... T>
LogDebug(T&&...) -> LogDebug<T...>;
#define LogDebugExplicit(tag, line, ...) _log(llarp::eLogDebug, tag, line, __VA_ARGS__)
#define LogInfoExplicit(tag, line, ...) _log(llarp::eLogInfo, tag, line __VA_ARGS__)
#define LogWarnExplicit(tag, line, ...) _log(llarp::eLogWarn, tag, line, __VA_ARGS__)
#define LogErrorExplicit(tag, line, ...) _log(llarp::eLogError, tag, line, __VA_ARGS__)
template <typename... T>
struct LogInfo
{
LogInfo(T... args, const slns::source_location& location = slns::source_location::current())
{
_log(eLogInfo, location, std::forward<T>(args)...);
}
};
// null-op Trace logging if this is a release build
#ifdef NDEBUG
#define LogTrace(...) _log_noop()
#define LogTraceTag(tag, ...) _log_noop()
#define LogTraceExplicit(tag, line, ...) _log_noop()
#else
#define LogTrace(...) _log(llarp::eLogTrace, LOG_TAG, __LINE__, __VA_ARGS__)
#define LogTraceTag(tag, ...) _log(llarp::eLogTrace, tag, __LINE__, __VA_ARGS__)
#define LogTraceExplicit(tag, line, ...) _log(llarp::eLogTrace, tag, line, __VA_ARGS__)
#endif
template <typename... T>
LogInfo(T&&...) -> LogInfo<T...>;
#ifndef LOG_TAG
#define LOG_TAG "default"
#endif
template <typename... T>
struct LogWarn
{
LogWarn(T... args, const slns::source_location& location = slns::source_location::current())
{
_log(eLogWarn, location, std::forward<T>(args)...);
}
};
template <typename... T>
LogWarn(T&&...) -> LogWarn<T...>;
template <typename... T>
struct LogError
{
LogError(T... args, const slns::source_location& location = slns::source_location::current())
{
_log(eLogError, location, std::forward<T>(args)...);
}
};
template <typename... T>
LogError(T&&...) -> LogError<T...>;
} // namespace llarp

@ -11,12 +11,12 @@ namespace llarp
PreLog(
std::stringstream& s,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const override;
void
Print(LogLevel lvl, const char* tag, const std::string& msg) override;
Print(LogLevel lvl, std::string_view tag, const std::string& msg) override;
void
PostLog(std::stringstream& ss) const override;

@ -6,6 +6,7 @@
#include <memory>
#include <string>
#include <sstream>
#include <string_view>
namespace llarp
{
@ -18,12 +19,12 @@ namespace llarp
PreLog(
std::stringstream& out,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const = 0;
virtual void
Print(LogLevel lvl, const char* filename, const std::string& msg) = 0;
Print(LogLevel lvl, std::string_view filename, const std::string& msg) = 0;
virtual void
PostLog(std::stringstream& out) const = 0;
@ -31,16 +32,16 @@ namespace llarp
virtual void
AppendLog(
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename,
const std::string msg)
{
std::stringstream ss;
PreLog(ss, lvl, fname, lineno, nodename);
PreLog(ss, lvl, filename, lineno, nodename);
ss << msg;
PostLog(ss);
Print(lvl, fname, ss.str());
Print(lvl, filename, ss.str());
}
/// A blocking call to flush to disk. Should only be called in rare circumstances.

@ -11,7 +11,7 @@ namespace llarp
OStreamLogStream::PreLog(
std::stringstream& ss,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const
{
@ -38,7 +38,7 @@ namespace llarp
}
ss << "[" << LogLevelToString(lvl) << "] ";
ss << "[" << nodename << "]"
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno
<< "\t";
}
@ -51,7 +51,7 @@ namespace llarp
}
void
OStreamLogStream::Print(LogLevel, const char*, const std::string& msg)
OStreamLogStream::Print(LogLevel, std::string_view, const std::string& msg)
{
m_Out << msg << std::flush;
}

@ -15,12 +15,12 @@ namespace llarp
PreLog(
std::stringstream& s,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const override;
virtual void
Print(LogLevel lvl, const char* tag, const std::string& msg) override;
Print(LogLevel lvl, std::string_view tag, const std::string& msg) override;
void
PostLog(std::stringstream& ss) const override;

@ -0,0 +1,53 @@
#pragma once
#ifdef __cpp_lib_source_location
#include <source_location>
namespace slns = std;
#else
namespace slns
{
struct source_location
{
public:
static constexpr source_location
current(
const char* fileName = __builtin_FILE(),
const char* functionName = __builtin_FUNCTION(),
const uint_least32_t lineNumber = __builtin_LINE()) noexcept
{
return source_location{fileName, functionName, lineNumber};
}
source_location(const source_location&) = default;
source_location(source_location&&) = default;
constexpr const char*
file_name() const noexcept
{
return fileName;
}
constexpr const char*
function_name() const noexcept
{
return functionName;
}
constexpr uint_least32_t
line() const noexcept
{
return lineNumber;
}
private:
constexpr explicit source_location(
const char* fileName, const char* functionName, const uint_least32_t lineNumber) noexcept
: fileName(fileName), functionName(functionName), lineNumber(lineNumber)
{}
const char* const fileName;
const char* const functionName;
const uint_least32_t lineNumber;
};
} // namespace slns
#endif

@ -10,18 +10,18 @@ namespace llarp
SysLogStream::PreLog(
std::stringstream& ss,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const
{
ss << "[" << LogLevelToString(lvl) << "] ";
ss << "[" << nodename << "]"
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno
<< "\t";
}
void
SysLogStream::Print(LogLevel lvl, const char*, const std::string& msg)
SysLogStream::Print(LogLevel lvl, std::string_view, const std::string& msg)
{
switch (lvl)
{

@ -27,7 +27,7 @@ namespace llarp
Win32LogStream::PreLog(
std::stringstream& ss,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const
{
@ -54,11 +54,11 @@ namespace llarp
break;
}
ss << "[" << nodename << "]"
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno
<< "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno
<< "\t";
}
else
OStreamLogStream::PreLog(ss, lvl, fname, lineno, nodename);
OStreamLogStream::PreLog(ss, lvl, filename, lineno, nodename);
}
void
@ -71,7 +71,7 @@ namespace llarp
}
void
Win32LogStream::Print(LogLevel lvl, const char*, const std::string& msg)
Win32LogStream::Print(LogLevel lvl, std::string_view, const std::string& msg)
{
if (!isConsoleModern)
{

@ -14,7 +14,7 @@ namespace llarp
PreLog(
std::stringstream& s,
LogLevel lvl,
const char* fname,
std::string_view filename,
int lineno,
const std::string& nodename) const override;
@ -24,7 +24,7 @@ namespace llarp
void Tick(llarp_time_t) override{};
void
Print(LogLevel lvl, const char*, const std::string& msg) override;
Print(LogLevel lvl, std::string_view, const std::string& msg) override;
private:
std::ostream& m_Out;

@ -70,6 +70,15 @@ namespace llarp
return str.size() >= suffix.size() && str.substr(str.size() - suffix.size()) == suffix;
}
/// removes a prefix from a string if it exists
inline std::string_view
strip_prefix(std::string_view str, std::string_view prefix)
{
if (starts_with(str, prefix))
return str.substr(prefix.size());
return str;
}
/// Splits a string on some delimiter string and returns a vector of string_view's pointing into
/// the pieces of the original string. The pieces are valid only as long as the original string
/// remains valid. Leading and trailing empty substrings are not removed. If delim is empty you

@ -57,7 +57,6 @@ namespace llarp::vpn
control.ioctl(SIOCGIFINDEX, &ifr);
const int ifindex = ifr.ifr_ifindex;
IOCTL control6{AF_INET6};
for (const auto& ifaddr : m_Info.addrs)
{
if (ifaddr.fam == AF_INET)
@ -78,9 +77,9 @@ namespace llarp::vpn
ifr6.ifindex = ifindex;
try
{
control6.ioctl(SIOCSIFADDR, &ifr6);
IOCTL{AF_INET6}.ioctl(SIOCSIFADDR, &ifr6);
}
catch (permission_error& ex)
catch (std::exception& ex)
{
LogError("we are not allowed to use IPv6 on this system: ", ex.what());
}

@ -205,7 +205,7 @@ namespace llarp::vpn
NetSH(std::string commands)
{
commands = NetSHCommand() + " interface IPv6 " + commands;
LogInfo(commands);
LogInfo("exec: ", commands);
::system(commands.c_str());
}
@ -500,7 +500,7 @@ namespace llarp::vpn
void
Execute(std::string cmd) const
{
LogInfo(cmd);
llarp::LogInfo("exec: ", cmd);
::system(cmd.c_str());
}

@ -18,4 +18,4 @@ pybind11_add_module(pyllarp MODULE
)
target_link_libraries(pyllarp PUBLIC liblokinet)
target_include_directories(pyllarp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
add_log_tag(pyllarp)

@ -26,6 +26,7 @@ Build requirements:
* libcurl (for lokinet-bootstrap)
* libunbound
* libzmq
* cppzmq
* sqlite3
### Linux
@ -42,12 +43,17 @@ You can install these using:
If you are not on a platform supported by the debian packages or if you want to build a dev build, this is the most "portable" way to do it:
$ sudo apt install build-essential cmake git libcap-dev pkg-config automake libtool
$ sudo apt install build-essential cmake git libcap-dev pkg-config automake libtool libuv1-dev libsodium-dev libzmq3-dev libcurl4-openssl-dev libevent-dev nettle-dev libunbound-dev libsqlite3-dev
$ git clone --recursive https://github.com/oxen-io/lokinet
$ cd lokinet
$ mkdir build
$ cd build
$ cmake .. -DBUILD_STATIC_DEPS=ON -DBUILD_SHARED_LIBS=OFF -DSTATIC_LINK=ON
$ cmake .. -DBUILD_STATIC_DEPS=ON -DBUILD_SHARED_LIBS=OFF -DSTATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release
$ make -j$(nproc)
If you dont want to do a static build install the dependancies and run:
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
$ make -j$(nproc)
install:
@ -56,13 +62,9 @@ install:
### macOS
You can get the latest stable macos relase from https://lokinet.org/ or check the releases page on github.
Lokinet ~~is~~ will be available on the Apple App store.
alternatively you can build from source, make sure you have cmake, libuv and xcode command line tools installed:
$ git clone --recursive https://github.com/oxen-io/lokinet
$ cd lokinet
$ ./contrib/mac.sh -DCODESIGN_KEY='insert your key identity here' -DCODESIGN_TEAM_ID='team id here'
Source code compilation of Lokinet by end users is not supported or permitted by apple on their platforms, see [this](contrib/macos/README.txt) for more information. If you find this disagreeable consider using a platform that permits compiling from source.
### Windows
@ -77,7 +79,7 @@ additional build requirements:
setup:
$ sudo apt install build-essential cmake git pkg-config mingw-w64 nsis ninja-build
$ sudo apt install build-essential cmake git pkg-config mingw-w64 nsis cpack automake libtool
building:
@ -85,30 +87,6 @@ building:
$ cd lokinet
$ ./contrib/windows.sh
### Solaris 2.10+
NOTE: Oracle Solaris users need to download/compile the TAP driver from http://www.whiteboard.ne.jp/~admin2/tuntap/
The generated binaries _may_ work on Solaris 2.10 or earlier, you're on your own. (Recommended: `-static-libstdc++ -static-libgcc`, and the TAP driver if not already installed on the target system.)
Building on a v2.10 or earlier system is unsupported, and may not even work; recent GCC releases have progressively dropped support for older system releases.
build:
$ sudo pkg install build-essential gcc8 wget tuntap cmake (optional: ninja ccache - from omnios extra) (OmniOS CE)
$ sudo pkg install base-developer-utilities developer-gnu developer-studio-utilities gcc-7 wget cmake (Oracle Solaris, see note)
$ sudo pkg install build-essential wget gcc-8 documentation/tuntap header-tun tun (optional: ninja ccache) (all other SunOS)
$ git clone --recursive https://github.com/oxen-io/lokinet
$ cd lokinet
$ mkdir build
$ cd build
$ cmake ..
$ make -j$(nproc)
install:
$ sudo make install
### FreeBSD
build:
@ -131,24 +109,16 @@ install (root):
When running from debian package the following steps are not needed as it is already ready to use.
## Create default config
to configure as client:
## Running on Linux (without debs)
$ lokinet -g
$ lokinet-bootstrap
**DO NOT RUN AS ROOT**, run as normal user.
to configure as relay:
set up the initial configs:
$ lokinet -r -g
$ lokinet -g
$ lokinet-bootstrap
## Running on Linux
**DO NOT RUN AS ROOT**, run as normal user.
to run, after you create default config:
after you create default config, run it:
$ lokinet

@ -73,6 +73,7 @@ Requerimientos de compilación:
* libsodium >= 1.0.18
* libunbound
* libzmq
* cppzmq
* sqlite3
### Linux

@ -64,6 +64,7 @@ Lokinet - реализация LLARP (протокол анонимной мар
* libsodium >= 1.0.18
* libunbound
* libzmq
* cppzmq
* sqlite3
### Linux

@ -53,7 +53,7 @@ add_executable(testAll
target_link_libraries(testAll PUBLIC liblokinet Catch2::Catch2)
target_include_directories(testAll PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
add_log_tag(testAll)
if(WIN32)
target_sources(testAll PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/win32/test.rc")
target_link_libraries(testAll PUBLIC ws2_32 iphlpapi shlwapi)

@ -57,7 +57,7 @@ TEST_CASE("BEncode", "[RouterVersion]")
CHECK(v1235.BEncode(&buf));
std::string s((const char*)buf.begin(), (buf.end() - buf.begin()));
LogInfo("bencoded: ", buf.begin());
llarp::LogInfo("bencoded: ", buf.begin());
CHECK_THAT((const char*)buf.begin(), Equals("li5ei1ei2ei3ee"));
}

Loading…
Cancel
Save