From 4a10868f85d03caf042b55379179fc757b919e04 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 31 May 2022 15:23:36 -0400 Subject: [PATCH 001/298] add additional fallback case --- llarp/link/server.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 44ac8b4a3..528b9d37b 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -159,6 +159,11 @@ namespace llarp // we do not have our claimed ip, nat or something? m_ourAddr = *maybe; } + else if (auto maybe = net::AllInterfaces(SockAddr{"0.0.0.0"})) + { + // one last fallback + m_ourAddr = *maybe; + } else return false; // the ultimate failure case } From 523a8a74ca45d201cb3f7fbd4777054d1966fc16 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Mon, 30 May 2022 22:01:03 -0300 Subject: [PATCH 002/298] Clean up system-or-submodule handling Fixes a bug on older cmake linking against oxenmq (older cmake hates the direct oxenmq::oxenmq -> PkgConfig::OXENMQ alias), and also makes it easier to handle things like nlohmann::json (which we can use from the system *or* submodule). Borrowed from oxen-ss/oxen-core. --- CMakeLists.txt | 33 --------------------------------- external/CMakeLists.txt | 30 ++++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf5e6cabd..c2a903f79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,39 +175,6 @@ if(NOT TARGET sodium) export(TARGETS sodium NAMESPACE sodium:: FILE sodium-exports.cmake) endif() -option(FORCE_OXENC_SUBMODULE "force using oxen-encoding submodule" OFF) -if(NOT FORCE_OXENC_SUBMODULE) - pkg_check_modules(OXENC liboxenc>=1.0.3 IMPORTED_TARGET) -endif() - -if(OXENC_FOUND) - if(NOT TARGET PkgConfig::OXENC AND CMAKE_VERSION VERSION_LESS "3.21") - # Work around cmake bug 22180 (PkgConfig::OXENC not set if no flags needed): - add_library(_empty_oxenc INTERFACE) - add_library(oxenc::oxenc ALIAS _empty_oxenc) - else() - add_library(oxenc::oxenc ALIAS PkgConfig::OXENC) - endif() - message(STATUS "Found system liboxenc ${OXENC_VERSION}") -else() - message(STATUS "using oxen-encoding submodule") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/oxen-encoding) - add_library(oxenc::oxenc ALIAS oxenc) -endif() - -option(FORCE_OXENMQ_SUBMODULE "force using oxenmq submodule" OFF) -if(NOT FORCE_OXENMQ_SUBMODULE) - pkg_check_modules(OXENMQ liboxenmq>=1.2.12 IMPORTED_TARGET) -endif() -if(OXENMQ_FOUND) - add_library(oxenmq::oxenmq ALIAS PkgConfig::OXENMQ) - message(STATUS "Found system liboxenmq ${OXENMQ_VERSION}") -else() - message(STATUS "using oxenmq submodule") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/oxen-mq) -endif() - - if(NOT APPLE) add_compile_options(-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -Wall -Wextra -Wno-unknown-pragmas -Wno-unused-function -Wno-deprecated-declarations -Werror=vla) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 0f935161b..b851ff986 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -29,12 +29,38 @@ if(SUBMODULE_CHECK) endif() endif() +macro(system_or_submodule BIGNAME smallname pkgconf subdir) + option(FORCE_${BIGNAME}_SUBMODULE "force using ${smallname} submodule" OFF) + if(NOT STATIC AND NOT FORCE_${BIGNAME}_SUBMODULE) + pkg_check_modules(${BIGNAME} ${pkgconf} IMPORTED_TARGET) + endif() + if(${BIGNAME}_FOUND) + add_library(${smallname} INTERFACE) + if(NOT TARGET PkgConfig::${BIGNAME} AND CMAKE_VERSION VERSION_LESS "3.21") + # Work around cmake bug 22180 (PkgConfig::THING not set if no flags needed) + else() + target_link_libraries(${smallname} INTERFACE PkgConfig::${BIGNAME}) + endif() + message(STATUS "Found system ${smallname} ${${BIGNAME}_VERSION}") + else() + message(STATUS "using ${smallname} submodule") + add_subdirectory(${subdir}) + endif() + if(NOT TARGET ${smallname}::${smallname}) + add_library(${smallname}::${smallname} ALIAS ${smallname}) + endif() +endmacro() + +system_or_submodule(OXENC oxenc liboxenc>=1.0.3 oxen-encoding) +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(WITH_HIVE) add_subdirectory(pybind11 EXCLUDE_FROM_ALL) endif() -set(JSON_BuildTests OFF CACHE INTERNAL "") -add_subdirectory(nlohmann EXCLUDE_FROM_ALL) add_subdirectory(cxxopts EXCLUDE_FROM_ALL) add_subdirectory(date EXCLUDE_FROM_ALL) From 9db192079b45fa81c09d88b3c5a9723015642f2a Mon Sep 17 00:00:00 2001 From: Pebu Date: Mon, 6 Jun 2022 10:00:20 -0400 Subject: [PATCH 003/298] Update error message Message is paths must be >= 2 but condition is checking for < 3 --- llarp/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 6bff96112..dde090362 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -425,7 +425,7 @@ namespace llarp }, [this](int arg) { if (arg < 3 or arg > 8) - throw std::invalid_argument("[endpoint]:paths must be >= 2 and <= 8"); + throw std::invalid_argument("[endpoint]:paths must be >= 3 and <= 8"); m_Paths = arg; }); From 83fe9867495707b2c591915b4e7183e96270f9ac Mon Sep 17 00:00:00 2001 From: majestrate Date: Tue, 7 Jun 2022 16:45:35 -0400 Subject: [PATCH 004/298] add french readme this translation was provided from a session user --- readme_fr.md | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 readme_fr.md diff --git a/readme_fr.md b/readme_fr.md new file mode 100644 index 000000000..fc9b91c8e --- /dev/null +++ b/readme_fr.md @@ -0,0 +1,189 @@ +# Lokinet + +[Español](readme_es.md) [Русский](readme_ru.md) [Français](readme_fr.md) + +Lokinet est l'implementation de référence du LLARP (Low Latency Anonymous Routing Protocol, protocole de routage anonyme à latence faible), un protocole de routage en oignon de couche 3. + +Vous pouvez en savoir plus sur le haut niveau de conception du LLARP [ici](docs/) + +[![Build Status](https://ci.oxen.rocks/api/badges/oxen-io/lokinet/status.svg?ref=refs/heads/dev)](https://ci.oxen.rocks/oxen-io/lokinet) + +## Installer + +Si vous souhaitez simplement installer Lokinet sans avoir à le compiler vous-même, nous vous proposons plusieurs options de plates-formes d'exécution : + +Tier 1: + +* [Linux](#linux-install) +* [Android](#apk-install) + +Tier 2: + +* [Windows](#windows-install) +* [MacOS](#mac-install) +* [FreeBSD](#freebsd-install) + +Plateformes actuellement non supportées : (des mainteneurs sont les bienvenus) + +* Apple iPhone +* Homebrew +* \[Insérez ici le gestionnaire de paquets Windows à la mode ce mois-ci.\] + +## Construction + +Packets necessaires pour construire: + +* Git +* CMake +* C++ 17 capable C++ compilateur +* libuv >= 1.27.0 +* libsodium >= 1.0.18 +* libssl (pour lokinet-bootstrap) +* libcurl (fpour lokinet-bootstrap) +* libunbound +* libzmq +* cppzmq +* sqlite3 + +### Linux + +Vous n'avez pas besoin de construire les paquets à partir des sources si vous êtes sous debian ou ubuntu car nous avons des dépôts apt avec des paquets lokinet pré-construits sur `deb.oxen.io` ou `rpm.oxen.io`. + +Vous pouvez installer les paquets debian en utilisant : + + $ sudo curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg + $ echo "deb https://deb.oxen.io $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/oxen.list + $ sudo apt update + $ sudo apt install lokinet + +Si vous voulez construire lokinet à partir des sources : + + $ 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 libssl-dev nlohmann-json3-dev + $ git clone --recursive https://github.com/oxen-io/lokinet + $ cd lokinet + $ mkdir build + $ cd build + $ cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF + $ make -j$(nproc) + $ sudo make install + +#### Arch Linux + +En raison de [circonstances indépendantes de notre volonté](https://github.com/oxen-io/lokinet/discussions/1823) un `PKGBUILD` fonctionnel peut être trouvé [ici](https://raw.githubusercontent.com/oxen-io/lokinet/makepkg/contrib/archlinux/PKGBUILD). + +#### Compilation croisée pour Linux + +les autres architectures actuellement supportées : + +* aarch64-linux-gnu +* arm-linux-gnueabihf +* mips-linux-gnu +* mips64-linux-gnuabi64 +* mipsel-linux-gnu +* powerpc64le-linux-gnu + +installer la chaîne d'outils (la suivante est pour `aarch64-linux-gnu`, vous pouvez fournir votre propre chaîne d'outils si vous voulez) + + $ sudo apt install g{cc,++}-aarch64-linux-gnu + +construire pour une ou plusieurs architectures : + + $ ./contrib/cross.sh arch_1 arch_2 ... arch_n + +### MacOS + +Lokinet ~~est~~ sera disponible sur l'App store d'Apple. + +La compilation du code source de Lokinet par les utilisateurs finaux n'est pas supportée ou autorisée par apple sur leurs plateformes, voir [ceci](contrib/macos/README.txt) pour plus d'informations. Si vous trouvez cela désagréable, envisagez d'utiliser une plateforme qui permet la compilation à partir des sources. + +### Windows + +Vous pouvez obtenir la dernière version stable de Windows à l'adresse https://lokinet.org/ ou consulter la [page des versions sur github] (https://github.com/oxen-io/lokinet/releases). + + +les compilation automatique de nuit pour les courageux ou les impatients peuvent être trouvées à partir de notre pipeline CI [ici](https://oxen.rocks/oxen-io/lokinet/) + +#### Construire les paquets sur Windows + +les compilations Windows sont des compilations croisées à partir de debian/ubuntu linux + +exigences de construction supplémentaires: + +* nsis +* cpack + +configuration: + + $ sudo apt install build-essential cmake git pkg-config mingw-w64 nsis cpack automake libtool + $ sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix + $ sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix + +building: + + $ git clone --recursive https://github.com/oxen-io/lokinet + $ cd lokinet + $ ./contrib/windows.sh + +### FreeBSD + +Currently has no VPN Platform code, see #1513 + +construction: + + $ pkg install cmake git pkgconf + $ git clone --recursive https://github.com/oxen-io/lokinet + $ cd lokinet + $ mkdir build + $ cd build + $ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DSTATIC_LINK=ON -DBUILD_STATIC_DEPS=ON .. + $ make + +installation (root): + + # make install + +### Android + +Nous avons un APK Android pour le VPN lokinet via l'API VPN android. + +A venir sur F-Droid quand cela arrivera. [[issue]](https://github.com/oxen-io/lokinet-flutter-app/issues/8) + +* [code source](https://github.com/oxen-io/lokinet-flutter-app) +* [CI builds](https://oxen.rocks/oxen-io/lokinet/) + +## Usage + +### Debian / Ubuntu paquets + +Lorsque vous installez le paquet debian, les étapes suivantes ne sont pas nécessaires car il est déjà en cours d'exécution et prêt à être utilisé. +prêt à être utilisé. Vous pouvez l'arrêter/démarrer/redémarrer en utilisant `systemctl start lokinet`, `systemctl stop +lokinet`, etc. + +### Exécution sur Linux (sans debs) + +**NE PAS EXECUTER EN TANT QUE ROOT**, exécutez en tant qu'utilisateur normal. + +mettre en place les configurations initiales: + + $ lokinet -g + $ lokinet-bootstrap + +après avoir créé la configuration par défaut, exécutez-la: + + $ lokinet + +Cela nécessite que le binaire ait les capacités appropriées, ce qui est généralement défini par `make install` sur le binaire. Si vous avez des erreurs concernant les permissions d'ouvrir une nouvelle interface, cela peut être résolu en utilisant : + + $ sudo setcap cap_net_admin,cap_net_bind_service=+eip /usr/local/bin/lokinet + + +---- + +# License + +Ce programme est un logiciel libre : vous pouvez le redistribuer et/ou le modifier selon les termes de la Licence Publique Générale GNU telle que publiée par la Free Software Foundation, soit la version 3 de la Licence, soit (au choix) toute version ultérieure. + +``` +Copyright © 2018-2022 The Oxen Project +Copyright © 2018-2022 Jeff Becker +Copyright © 2018-2020 Rick V. (Historical Windows NT port and portions) From 10db0a0d2d61b959c161e7cf993057474908d44b Mon Sep 17 00:00:00 2001 From: majestrate Date: Tue, 7 Jun 2022 16:45:56 -0400 Subject: [PATCH 005/298] link to french readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index cbded271b..0a5c4ced0 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # Lokinet -[Español](readme_es.md) [Русский](readme_ru.md) +[Español](readme_es.md) [Русский](readme_ru.md) [Français](readme_fr.md) Lokinet is the reference implementation of LLARP (low latency anonymous routing protocol), a layer 3 onion routing protocol. From 1de7b070d1839e909ccb88ea18e133d470e9c586 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Mon, 30 May 2022 22:07:36 -0300 Subject: [PATCH 006/298] Add -DLOKINET_VERSIONTAG to override version tag Currently I maintain a patch in the debs to do the same thing here, but it fails to apply often enough; this change makes the behaviour consistent with oxen-core/oxen-ss and will let me drop that patch and just pass in the cmake option. (Recommend ignore-whitespace for viewing the diff) --- cmake/Version.cmake | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/cmake/Version.cmake b/cmake/Version.cmake index a017995eb..9b786ce85 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -1,26 +1,31 @@ # We do this via a custom command that re-invokes a cmake script because we need the DEPENDS on .git/index so that we will re-run it (to regenerate the commit tag in the version) whenever the current commit changes. If we used a configure_file directly here, it would only re-run when something else causes cmake to re-run. -set(VERSIONTAG "${GIT_VERSION}") -set(GIT_INDEX_FILE "${PROJECT_SOURCE_DIR}/.git/index") -find_package(Git) -if(EXISTS "${GIT_INDEX_FILE}" AND ( GIT_FOUND OR Git_FOUND) ) - message(STATUS "Found Git: ${GIT_EXECUTABLE}") - set(genversion_args "-DGIT=${GIT_EXECUTABLE}") - foreach(v lokinet_VERSION lokinet_VERSION_MAJOR lokinet_VERSION_MINOR lokinet_VERSION_PATCH RELEASE_MOTTO) - list(APPEND genversion_args "-D${v}=${${v}}") - endforeach() - - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" - COMMAND "${CMAKE_COMMAND}" - ${genversion_args} - "-D" "SRC=${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" - "-D" "DEST=${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" - "-P" "${CMAKE_CURRENT_LIST_DIR}/GenVersion.cmake" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" - "${GIT_INDEX_FILE}") -else() +if(LOKINET_VERSIONTAG) + set(VERSIONTAG "${LOKINET_VERSIONTAG}") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" @ONLY) +else() + set(VERSIONTAG "${GIT_VERSION}") + set(GIT_INDEX_FILE "${PROJECT_SOURCE_DIR}/.git/index") + find_package(Git) + if(EXISTS "${GIT_INDEX_FILE}" AND ( GIT_FOUND OR Git_FOUND) ) + message(STATUS "Found Git: ${GIT_EXECUTABLE}") + set(genversion_args "-DGIT=${GIT_EXECUTABLE}") + foreach(v lokinet_VERSION lokinet_VERSION_MAJOR lokinet_VERSION_MINOR lokinet_VERSION_PATCH RELEASE_MOTTO) + list(APPEND genversion_args "-D${v}=${${v}}") + endforeach() + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" + COMMAND "${CMAKE_COMMAND}" + ${genversion_args} + "-D" "SRC=${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" + "-D" "DEST=${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" + "-P" "${CMAKE_CURRENT_LIST_DIR}/GenVersion.cmake" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" + "${GIT_INDEX_FILE}") + else() + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/constants/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/constants/version.cpp" @ONLY) + endif() endif() From 3cd699fa7fdd2d04f755b746f4b6d7ad8f6e1244 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 15 Jun 2022 21:23:15 -0300 Subject: [PATCH 007/298] Show router pubkey at startup --- llarp/router/router.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index b6ca5c6ba..1680e086c 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -345,7 +345,8 @@ namespace llarp try { _identity = RpcClient()->ObtainIdentityKey(); - LogWarn("Obtained lokid identity keys"); + const RouterID pk{pubkey()}; + LogWarn("Obtained lokid identity key: ", pk); break; } catch (const std::exception& e) From 8c3d1b3281336bf86cbd41e7811735e86a395704 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 15 Jun 2022 16:51:55 -0300 Subject: [PATCH 008/298] Don't build empty cpp files We shouldn't be compiling these .cpp files at all on other platforms, rather than compiling empty .cpp files (which later results in "... has no symbols" warnings). --- llarp/CMakeLists.txt | 5 +++-- llarp/util/logging/android_logger.cpp | 3 --- llarp/util/logging/win32_logger.cpp | 2 -- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 40786322b..4d8f4106e 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -7,7 +7,6 @@ add_library(lokinet-util util/buffer.cpp util/fs.cpp util/json.cpp - util/logging/android_logger.cpp util/logging/buffer.cpp util/logging/file_logger.cpp util/logging/logger.cpp @@ -15,7 +14,6 @@ add_library(lokinet-util util/logging/loglevel.cpp util/logging/ostream_logger.cpp util/logging/syslog_logger.cpp - util/logging/win32_logger.cpp util/lokinet_init.c util/mem.cpp util/printer.cpp @@ -38,7 +36,10 @@ target_link_libraries(lokinet-util PUBLIC ) if(ANDROID) + target_sources(lokinet-util PRIVATE util/logging/android_logger.cpp) target_link_libraries(lokinet-util PUBLIC log) +elseif(WIN32) + target_sources(lokinet-util PRIVATE util/logging/win32_logger.cpp) endif() add_library(lokinet-platform diff --git a/llarp/util/logging/android_logger.cpp b/llarp/util/logging/android_logger.cpp index 3cf9343cb..ae4bdb793 100644 --- a/llarp/util/logging/android_logger.cpp +++ b/llarp/util/logging/android_logger.cpp @@ -1,5 +1,3 @@ -#if defined(ANDROID) - #include "android_logger.hpp" #include "logger_internal.hpp" @@ -69,4 +67,3 @@ namespace llarp } // namespace llarp } // namespace llarp -#endif diff --git a/llarp/util/logging/win32_logger.cpp b/llarp/util/logging/win32_logger.cpp index 2e0448c63..0792f8d92 100644 --- a/llarp/util/logging/win32_logger.cpp +++ b/llarp/util/logging/win32_logger.cpp @@ -1,4 +1,3 @@ -#if defined(_WIN32) #include "win32_logger.hpp" #include "logger_internal.hpp" @@ -113,4 +112,3 @@ namespace llarp } } // namespace llarp -#endif From 4a4f16e5c88231083a7d78d2078dda0888ab025e Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Tue, 21 Jun 2022 18:56:25 -0300 Subject: [PATCH 009/298] Remove dead code: netns, shell hooks These haven't been activated in a long time and aren't worth resuscitating. --- CMakeLists.txt | 23 --- llarp/CMakeLists.txt | 3 - llarp/handlers/tun.cpp | 4 - llarp/hook/ihook.hpp | 30 --- llarp/hook/shell.cpp | 157 --------------- llarp/hook/shell.hpp | 13 -- llarp/linux/netns.cpp | 319 ------------------------------- llarp/linux/netns.hpp | 15 -- llarp/service/endpoint.cpp | 16 -- llarp/service/endpoint.hpp | 6 +- llarp/service/endpoint_state.cpp | 28 --- llarp/service/endpoint_state.hpp | 5 - 12 files changed, 1 insertion(+), 618 deletions(-) delete mode 100644 llarp/hook/ihook.hpp delete mode 100644 llarp/hook/shell.cpp delete mode 100644 llarp/hook/shell.hpp delete mode 100644 llarp/linux/netns.cpp delete mode 100644 llarp/linux/netns.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c2a903f79..ac2067e0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,9 +56,7 @@ option(XSAN "use sanitiser, if your system has it (requires -DCMAKE_BUILD_TYPE=D 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) option(WARNINGS_AS_ERRORS "treat all warnings as errors. turn off for development, on for release" OFF) -option(TRACY_ROOT "include tracy profiler source" OFF) option(WITH_TESTS "build unit tests" OFF) option(WITH_HIVE "build simulation stubs" OFF) option(BUILD_PACKAGE "builds extra components for making an installer (with 'make package')" OFF) @@ -107,8 +105,6 @@ if (STATIC_LINK) message(STATUS "setting static library suffix search") endif() -add_definitions(-D${CMAKE_SYSTEM_NAME}) - include(cmake/solaris.cmake) include(cmake/win32.cmake) @@ -198,15 +194,6 @@ if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]") add_definitions(-DLOKINET_DEBUG=1) endif() -if(WITH_SHELLHOOKS) - add_definitions(-DENABLE_SHELLHOOKS) -endif() - -if(TRACY_ROOT) - include_directories(${TRACY_ROOT}) - add_definitions(-DTRACY_ENABLE) -endif() - include(cmake/coverage.cmake) @@ -236,12 +223,6 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) -if(USE_NETNS) - add_definitions(-DNETNS=1) -else() - add_definitions(-DNETNS=0) -endif() - if(TESTNET) add_definitions(-DTESTNET=1) # 5 times slower than realtime @@ -306,10 +287,6 @@ if(ANDROID) set(ANDROID_PLATFORM_SRC android/ifaddrs.c) endif() -if(TRACY_ROOT) - target_link_libraries(base_libs INTERFACE dl) -endif() - if(WITH_HIVE) add_definitions(-DLOKINET_HIVE=1) endif() diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 40786322b..f91a0dee2 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -66,8 +66,6 @@ if (ANDROID) endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") - target_sources(lokinet-platform PRIVATE linux/netns.cpp) - if(NON_PC_TARGET) add_import_library(rt) target_link_libraries(lokinet-platform PUBLIC rt) @@ -139,7 +137,6 @@ add_library(liblokinet exit/session.cpp handlers/exit.cpp handlers/tun.cpp - hook/shell.cpp iwp/iwp.cpp iwp/linklayer.cpp iwp/message_buffer.cpp diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index c31a300e6..3b13e1d16 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -953,10 +953,6 @@ namespace llarp m_LocalResolverAddr.createSockAddr(), false /* just .loki/.snode DNS initially */); - if (m_OnUp) - { - m_OnUp->NotifyAsync(NotifyParams()); - } return HasAddress(ourAddr); } diff --git a/llarp/hook/ihook.hpp b/llarp/hook/ihook.hpp deleted file mode 100644 index 0f132ba45..000000000 --- a/llarp/hook/ihook.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include -#include -#include - -namespace llarp -{ - namespace hooks - { - /// base type for event hook handlers - struct IBackend - { - virtual ~IBackend() = 0; - virtual void - NotifyAsync(std::unordered_map params) = 0; - - /// start backend - virtual bool - Start() = 0; - - /// stop backend - virtual bool - Stop() = 0; - }; - - using Backend_ptr = std::shared_ptr; - - inline IBackend::~IBackend() = default; - } // namespace hooks -} // namespace llarp diff --git a/llarp/hook/shell.cpp b/llarp/hook/shell.cpp deleted file mode 100644 index 2a740ea14..000000000 --- a/llarp/hook/shell.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "shell.hpp" - -#if defined(ENABLE_SHELLHOOKS) -#include -#include -#include -#include -#if !defined(__linux__) || !defined(_GNU_SOURCE) -// Not all systems declare this variable -extern char** environ; -#endif -#if defined(Darwin) -#include -#endif -#endif - -namespace llarp -{ - namespace hooks - { -#if defined(ENABLE_SHELLHOOKS) - struct ExecShellHookBackend : public IBackend, - public std::enable_shared_from_this - { - thread::ThreadPool m_ThreadPool; - - std::vector _args; - std::vector args; - - ExecShellHookBackend(std::string script) : m_ThreadPool(1, 1000, "exechook") - { - do - { - const auto idx = script.find_first_of(' '); - std::string sub; - if (idx == std::string::npos) - sub = script; - else - sub = script.substr(0, idx); - _args.emplace_back(std::move(sub)); - args.push_back((char*)_args.back().c_str()); - script = script.substr(idx + 1); - } while (script.find_first_of(' ') != std::string::npos); - args.push_back(nullptr); - LogInfo("make hook ", args.size()); - } - - ~ExecShellHookBackend() - { - m_ThreadPool.shutdown(); - } - - bool - Start() override - { - m_ThreadPool.start(); - return true; - } - - bool - Stop() override - { - m_ThreadPool.stop(); - return true; - } - - char* - Exe() const - { - return args[0]; - } - - char* const* - Args() const - { - return args.data(); - } - - void - NotifyAsync(std::unordered_map params) override; - }; - - struct ExecShellHookJob - { - std::vector m_env; - std::vector _m_env; - std::shared_ptr m_Parent; - - ExecShellHookJob( - std::shared_ptr b, - const std::unordered_map env) - : m_Parent(b) - { -#if defined(Darwin) - char** ptr = *_NSGetEnviron(); -#else - char** ptr = environ; -#endif - do - { - m_env.emplace_back(*ptr); - ++ptr; - } while (ptr && *ptr); - for (const auto& item : env) - m_env.emplace_back(item.first + "=" + item.second); - for (const auto& item : m_env) - _m_env.push_back((char*)item.c_str()); - _m_env.push_back(nullptr); - } - - char* const* - Env() - { - return _m_env.data(); - } - - void - Exec() - { - std::thread t([&]() { - int result = 0; - const pid_t child = ::fork(); - if (child == -1) - return; - if (child) - ::waitpid(child, &result, 0); - else - ::execve(m_Parent->Exe(), m_Parent->Args(), Env()); - }); - t.join(); - } - }; - - void - ExecShellHookBackend::NotifyAsync(std::unordered_map params) - { - auto job = std::make_shared(shared_from_this(), std::move(params)); - - m_ThreadPool.addJob([job = std::move(job)] { job->Exec(); }); - } - - Backend_ptr - ExecShellBackend(std::string execFilePath) - { - Backend_ptr ptr = std::make_shared(execFilePath); - if (!ptr->Start()) - return nullptr; - return ptr; - } -#else - Backend_ptr ExecShellBackend(std::string) - { - return nullptr; - } -#endif - } // namespace hooks -} // namespace llarp diff --git a/llarp/hook/shell.hpp b/llarp/hook/shell.hpp deleted file mode 100644 index 32695542f..000000000 --- a/llarp/hook/shell.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ihook.hpp" - -namespace llarp -{ - namespace hooks - { - /// exec file based hook notifier - Backend_ptr - ExecShellBackend(std::string execFilePath); - } // namespace hooks -} // namespace llarp diff --git a/llarp/linux/netns.cpp b/llarp/linux/netns.cpp deleted file mode 100644 index a40dbf768..000000000 --- a/llarp/linux/netns.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#if defined(ANDROID) || NETNS == 0 - -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "netns.hpp" -#include -#ifndef MS_REC -#define MS_REC (16384) -#endif -#include - -namespace llarp -{ - namespace GNULinux - { - static const char netns_rundir[] = "/var/run/netns"; - static const char netns_etcdir[] = "/etc/netns"; - - static bool - GetCGroups2MountPoint(fs::path& cgroups2_mount) - { - std::string mountpoint; - std::ifstream inf; - inf.open("/proc/mounts"); - if (!inf.is_open()) - { - llarp::LogError("failed to open /proc/mounts"); - return false; - } - std::string line; - while (std::getline(inf, line)) - { - std::string part; - std::stringstream parts; - parts.str(line); - // discard - std::getline(parts, part); - // mount point - std::getline(parts, part); - mountpoint = part; - // type - std::getline(parts, part); - if (part == "cgroup2") - { - // found cgroup2 mountpoint - cgroups2_mount = mountpoint; - return true; - } - } - llarp::LogError("cannot find cgroups2 in /proc/mounts"); - return false; - } - - static bool - GetNetNS(std::string& netns) - { - auto nfd = open("/proc/self/ns/net", O_RDONLY); - if (nfd < 0) - { - llarp::LogError("Failed to get our own netns, could not open /proc/self/ns/net"); - return false; - } - struct stat netst; - if (::fstat(nfd, &netst) < 0) - { - close(nfd); - llarp::LogError("stat of netns failed: ", strerror(errno)); - return false; - } - close(nfd); - fs::path run_dir = netns_rundir; - bool foundIt = false; - // find corrosponding file for netns - llarp::util::IterDir(run_dir, [&](const fs::path& f) -> bool { - struct stat fst; - if (::stat(f.string().c_str(), &fst) >= 0) - { - if (fst.st_dev == netst.st_dev && fst.st_ino == netst.st_ino) - { - // found it - foundIt = true; - netns = f.filename().string(); - // break iteration - return false; - } - } - // continue iteration - return true; - }); - return foundIt; - } - - static bool - GetVRFPath(std::string& path) - { - char p[256] = {0}; - snprintf(p, sizeof(p), "/proc/%d/cgroup", getpid()); - std::ifstream inf; - inf.open(p); - if (!inf.is_open()) - { - llarp::LogError("could not open '", p, "': ", strerror(errno)); - return false; - } - path = ""; - std::string line; - while (std::getline(inf, line)) - { - auto pos = line.find("::/"); - if (pos != std::string::npos) - { - line = line.substr(pos + 2); - pos = line.find("/vrf"); - if (pos != std::string::npos) - { - path = line.substr(pos); - if (path == "/") - path = ""; - } - break; - } - } - return true; - } - - static bool - ResetVRF() - { - fs::path cgroups2_mount; - if (!GetCGroups2MountPoint(cgroups2_mount)) - { - llarp::LogError("could not find cgroup2 mount point, is it mounted?"); - return false; - } - std::string netns; - if (!GetNetNS(netns)) - { - llarp::LogError("could not get our netns: ", strerror(errno)); - return false; - } - std::string vrfpath; - if (!GetVRFPath(vrfpath)) - { - llarp::LogError("could not determine vrf cgroup path: ", strerror(errno)); - return false; - } - fs::path cgroup_path = cgroups2_mount / vrfpath / netns / "vrf" / "default"; - std::error_code ec; - if (!fs::exists(cgroup_path, ec)) - { - if (!fs::create_directories(cgroup_path, ec)) - { - llarp::LogError("could not create '", cgroup_path.string(), "': ", ec); - return false; - } - } - else if (ec) - { - llarp::LogError("Could not check '", cgroup_path.string(), "': ", ec); - return false; - } - cgroup_path /= "cgroup.procs"; - auto fd = open(cgroup_path.string().c_str(), O_RDWR | O_APPEND); - if (fd < 0) - { - llarp::LogError("could not open '", cgroup_path.string(), "': ", strerror(errno)); - return false; - } - bool success = true; - std::string pid = std::to_string(getpid()); - if (write(fd, pid.c_str(), pid.size()) < 0) - { - llarp::LogError("failed to join cgroup"); - success = false; - } - close(fd); - return success; - } - - /// bind network namespace paths into /etc/ - static bool - BindNetworkNS(const char* name) - { - fs::path etc_dir = netns_etcdir; - etc_dir /= name; - std::error_code ec; - if (!fs::exists(etc_dir, ec)) - { - errno = 0; - llarp::LogInfo(etc_dir, " does not exist, skipping"); - return true; - } - bool didFail = false; - llarp::util::IterDir(etc_dir, [&](const fs::path& f) -> bool { - if (fs::is_regular_file(f)) - { - fs::path netns_path = "/etc"; - netns_path /= f.filename(); - if (mount(f.string().c_str(), netns_path.string().c_str(), "none", MS_BIND, nullptr) < 0) - { - llarp::LogError( - "failed to bind '", - f.string(), - "' to '", - netns_path.string(), - "': ", - strerror(errno)); - didFail = true; - } - } - // continue iteration - return true; - }); - return !didFail; - } - - static void - DropCap() - { - if (getuid() != 0 && geteuid() != 0) - { - cap_t capabilities; - cap_value_t net_admin = CAP_NET_ADMIN; - cap_flag_t inheritable = CAP_INHERITABLE; - cap_flag_value_t is_set; - - capabilities = cap_get_proc(); - if (!capabilities) - exit(EXIT_FAILURE); - if (cap_get_flag(capabilities, net_admin, inheritable, &is_set) != 0) - exit(EXIT_FAILURE); - - if (is_set == CAP_CLEAR) - { - if (cap_clear(capabilities) != 0) - exit(EXIT_FAILURE); - if (cap_set_proc(capabilities) != 0) - exit(EXIT_FAILURE); - } - cap_free(capabilities); - } - } - - bool - NetNSSwitch(const char* name) - { - fs::path netns_path = netns_rundir; - netns_path /= name; - auto nsfd = open(netns_path.string().c_str(), O_RDONLY | O_CLOEXEC); - if (nsfd < 0) - { - llarp::LogError("Failed to open network namespace '", name, "': ", strerror(errno)); - return false; - } - if (setns(nsfd, CLONE_NEWNET) < 0) - { - llarp::LogError("Failed to enter network namespace '", name, "': ", strerror(errno)); - close(nsfd); - return false; - } - close(nsfd); - if (unshare(CLONE_NEWNS) < 0) - { - llarp::LogError("unshare failed: ", strerror(errno)); - return false; - } - // dont let any mount points prop back to parent - // iproute2 source does this - if (mount("", "/", "none", MS_SLAVE | MS_REC, nullptr)) - { - llarp::LogError("mount --make-rslave failed: ", strerror(errno)); - return false; - } - unsigned long mountflags = 0; - // ensaure /sys not mounted - if (umount2("/sys", MNT_DETACH) < 0) - { - struct statvfs fsstat; - if (statvfs("/sys", &fsstat) == 0) - { - if (fsstat.f_flag & ST_RDONLY) - mountflags = MS_RDONLY; - } - } - // mount sysfs for our namespace - if (mount(name, "/sys", "sysfs", mountflags, nullptr) < 0) - { - llarp::LogError("failed to mount sysfs: ", strerror(errno)); - return false; - } - if (!BindNetworkNS(name)) - { - llarp::LogError("failed to bind namespace directories"); - return false; - } - if (!ResetVRF()) - { - llarp::LogError("failed to reset vrf"); - return false; - } - DropCap(); - return true; - } - } // namespace GNULinux -} // namespace llarp - -#endif diff --git a/llarp/linux/netns.hpp b/llarp/linux/netns.hpp deleted file mode 100644 index 8b7ddd56b..000000000 --- a/llarp/linux/netns.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#ifdef __linux__ -namespace llarp -{ - namespace GNULinux - { - /// switch current process to use network namepsace by name - /// returns true if successfully switched otherwise returns false - bool - NetNSSwitch(const char* name); - } // namespace GNULinux -} // namespace llarp -#else -#error "Don't include this file" -#endif diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 18e7876df..3c266c247 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -341,8 +340,6 @@ namespace llarp EndpointUtil::StopRemoteSessions(m_state->m_RemoteSessions); // stop snode sessions EndpointUtil::StopSnodeSessions(m_state->m_SNodeSessions); - if (m_OnDown) - m_OnDown->NotifyAsync(NotifyParams()); return path::Builder::Stop(); } @@ -590,16 +587,6 @@ namespace llarp return true; } - Endpoint::~Endpoint() - { - if (m_OnUp) - m_OnUp->Stop(); - if (m_OnDown) - m_OnDown->Stop(); - if (m_OnReady) - m_OnReady->Stop(); - } - bool Endpoint::PublishIntroSet(const EncryptedIntroSet& introset, AbstractRouter* r) { @@ -762,9 +749,6 @@ namespace llarp LogDebug(Name(), " Additional IntroSet publish confirmed"); m_state->m_LastPublish = now; - if (m_OnReady) - m_OnReady->NotifyAsync(NotifyParams()); - m_OnReady = nullptr; } std::optional> diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index e7364d1f3..296f107af 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -7,6 +7,7 @@ #include #include #include "address.hpp" +#include "endpoint_state.hpp" #include "handler.hpp" #include "identity.hpp" #include "pendingbuffer.hpp" @@ -15,7 +16,6 @@ #include "service/protocol_type.hpp" #include "session.hpp" #include "lookup.hpp" -#include #include #include #include @@ -62,7 +62,6 @@ namespace llarp public EndpointBase { Endpoint(AbstractRouter* r, Context* parent); - ~Endpoint() override; /// return true if we are ready to recv packets from the void bool @@ -516,9 +515,6 @@ namespace llarp IDataHandler* m_DataHandler = nullptr; Identity m_Identity; net::IPRangeMap m_ExitMap; - hooks::Backend_ptr m_OnUp; - hooks::Backend_ptr m_OnDown; - hooks::Backend_ptr m_OnReady; bool m_PublishIntroSet = true; std::unique_ptr m_state; std::shared_ptr m_AuthPolicy; diff --git a/llarp/service/endpoint_state.cpp b/llarp/service/endpoint_state.cpp index 383519dc9..95f013a27 100644 --- a/llarp/service/endpoint_state.cpp +++ b/llarp/service/endpoint_state.cpp @@ -1,7 +1,6 @@ #include "endpoint_state.hpp" #include -#include #include "endpoint.hpp" #include "outbound_context.hpp" #include @@ -23,33 +22,6 @@ namespace llarp m_IntroSet.SRVs.push_back(record.toTuple()); } - // TODO: - /* - if (k == "on-up") - { - m_OnUp = hooks::ExecShellBackend(v); - if (m_OnUp) - LogInfo(name, " added on up script: ", v); - else - LogError(name, " failed to add on up script"); - } - if (k == "on-down") - { - m_OnDown = hooks::ExecShellBackend(v); - if (m_OnDown) - LogInfo(name, " added on down script: ", v); - else - LogError(name, " failed to add on down script"); - } - if (k == "on-ready") - { - m_OnReady = hooks::ExecShellBackend(v); - if (m_OnReady) - LogInfo(name, " added on ready script: ", v); - else - LogError(name, " failed to add on ready script"); - } - */ return true; } diff --git a/llarp/service/endpoint_state.hpp b/llarp/service/endpoint_state.hpp index c256acf88..7cbae0894 100644 --- a/llarp/service/endpoint_state.hpp +++ b/llarp/service/endpoint_state.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "address.hpp" #include "pendingbuffer.hpp" @@ -25,10 +24,6 @@ namespace llarp { struct EndpointState { - hooks::Backend_ptr m_OnUp; - hooks::Backend_ptr m_OnDown; - hooks::Backend_ptr m_OnReady; - std::set m_SnodeBlacklist; AbstractRouter* m_Router; From 0edb4435d479cf94bf857e8fa3261d49d4775f25 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Tue, 21 Jun 2022 18:57:36 -0300 Subject: [PATCH 010/298] Cmake cleanup: remove unneeded =1 from definitions We only check for definedness, not truth, in the code so make the cmake definitions agree with that. This also avoids warnings when building on macos (because swift only allowed defined/undefined but not values) --- CMakeLists.txt | 6 +++--- cmake/shadow.cmake | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac2067e0d..a5309126a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,7 +191,7 @@ if(XSAN) endif() if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]") - add_definitions(-DLOKINET_DEBUG=1) + add_definitions(-DLOKINET_DEBUG) endif() @@ -224,7 +224,7 @@ set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) if(TESTNET) - add_definitions(-DTESTNET=1) + add_definitions(-DTESTNET) # 5 times slower than realtime # add_definitions(-DTESTNET_SPEED=5) endif() @@ -288,7 +288,7 @@ if(ANDROID) endif() if(WITH_HIVE) - add_definitions(-DLOKINET_HIVE=1) + add_definitions(-DLOKINET_HIVE) endif() add_subdirectory(crypto) diff --git a/cmake/shadow.cmake b/cmake/shadow.cmake index deed362b1..6eac1a28e 100644 --- a/cmake/shadow.cmake +++ b/cmake/shadow.cmake @@ -9,10 +9,13 @@ else() message(FATAL_ERROR "SHADOW_ROOT path does not exist: '${SHADOW_ROOT}'") endif(EXISTS "${SHADOW_ROOT}") +if(NOT TESTNET) + message(FATAL_ERROR "shadow testing framework requires a testnet build") +endif() + set(CMAKE_MODULE_PATH "${SHADOW_ROOT}/share/cmake/Modules") include_directories(${CMAKE_MODULE_PATH}) include(ShadowTools) add_compile_options(-fno-inline -fno-strict-aliasing ) -add_definitions(-DTESTNET=1) add_definitions(-DLOKINET_SHADOW) include_directories(${SHADOW_ROOT}/include) From c37d6ea43b2dfed71c9b20f86bbc3214ff966533 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 22 Jun 2022 11:08:07 -0300 Subject: [PATCH 011/298] Remove shadow testing framework Bitrotten and apparently doesn't work with libuv event loop. --- CMakeLists.txt | 21 +++++---------------- cmake/shadow.cmake | 21 --------------------- llarp/CMakeLists.txt | 4 ---- llarp/testnet.c | 6 ------ 4 files changed, 5 insertions(+), 47 deletions(-) delete mode 100644 cmake/shadow.cmake delete mode 100644 llarp/testnet.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a5309126a..83f6d3e41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,6 @@ option(USE_NETNS "enable networking namespace support. Linux only" OFF) option(NATIVE_BUILD "optimise for host system and FPU" ON) 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(USE_JEMALLOC "Link to jemalloc for memory allocations, if found" ON) option(TESTNET "testnet build" OFF) @@ -178,10 +177,6 @@ if(NOT APPLE) endif() endif() -if (NOT CMAKE_SYSTEM_NAME MATCHES "Linux" AND SHADOW) - message( FATAL_ERROR "shadow-framework is Linux only" ) -endif() - if(XSAN) string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fsanitize=${XSAN} -fno-omit-frame-pointer -fno-sanitize-recover") foreach(type EXE MODULE SHARED STATIC) @@ -229,10 +224,6 @@ if(TESTNET) # add_definitions(-DTESTNET_SPEED=5) endif() -if(SHADOW) - include(cmake/shadow.cmake) -endif() - unset(GIT_VERSION) unset(GIT_VERSION_REAL) @@ -300,13 +291,11 @@ endif() if(WITH_HIVE) add_subdirectory(pybind) endif() -if (NOT SHADOW) - if(WITH_TESTS OR WITH_HIVE) - add_subdirectory(test) - endif() - if(ANDROID) - add_subdirectory(jni) - endif() +if(WITH_TESTS OR WITH_HIVE) + add_subdirectory(test) +endif() +if(ANDROID) + add_subdirectory(jni) endif() add_subdirectory(docs) diff --git a/cmake/shadow.cmake b/cmake/shadow.cmake deleted file mode 100644 index 6eac1a28e..000000000 --- a/cmake/shadow.cmake +++ /dev/null @@ -1,21 +0,0 @@ -set(WITH_STATIC OFF) -set(WITH_SHARED ON) -if("${SHADOW_ROOT}" STREQUAL "") - set(SHADOW_ROOT "$ENV{HOME}/.shadow") -endif("${SHADOW_ROOT}" STREQUAL "") -if(EXISTS "${SHADOW_ROOT}") - message(STATUS "SHADOW_ROOT = ${SHADOW_ROOT}") -else() - message(FATAL_ERROR "SHADOW_ROOT path does not exist: '${SHADOW_ROOT}'") -endif(EXISTS "${SHADOW_ROOT}") - -if(NOT TESTNET) - message(FATAL_ERROR "shadow testing framework requires a testnet build") -endif() - -set(CMAKE_MODULE_PATH "${SHADOW_ROOT}/share/cmake/Modules") -include_directories(${CMAKE_MODULE_PATH}) -include(ShadowTools) -add_compile_options(-fno-inline -fno-strict-aliasing ) -add_definitions(-DLOKINET_SHADOW) -include_directories(${SHADOW_ROOT}/include) diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index f91a0dee2..d512e2290 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -227,10 +227,6 @@ if(TRACY_ROOT) target_sources(liblokinet PRIVATE ${TRACY_ROOT}/TracyClient.cpp) endif() -if(TESTNET) - target_sources(liblokinet PRIVATE testnet.c) -endif() - if(WITH_HIVE) target_sources(liblokinet PRIVATE tooling/router_hive.cpp diff --git a/llarp/testnet.c b/llarp/testnet.c deleted file mode 100644 index 7825445be..000000000 --- a/llarp/testnet.c +++ /dev/null @@ -1,6 +0,0 @@ -#ifdef LOKINET_SHADOW -#include - -/** insert shadow test network specific code here */ - -#endif From 81f05d63c1a4ae484129b9b890ac8e35c2ddd54c Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 22 Jun 2022 14:48:45 -0300 Subject: [PATCH 012/298] Move destructor back to .cpp file Having it there (even defaulted, like this) means endpoint.hpp doesn't have to include endpoint_state.hpp (which it otherwise would need, because of the std::unique_ptr default deleter requirements). --- llarp/service/endpoint.cpp | 4 ++++ llarp/service/endpoint.hpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 3c266c247..84c10f2e8 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -587,6 +587,10 @@ namespace llarp return true; } + // Keep this here (rather than the header) so that we don't need to include endpoint_state.hpp + // in endpoint.hpp for the unique_ptr member destructor. + Endpoint::~Endpoint() = default; + bool Endpoint::PublishIntroSet(const EncryptedIntroSet& introset, AbstractRouter* r) { diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 296f107af..a90752961 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -7,7 +7,6 @@ #include #include #include "address.hpp" -#include "endpoint_state.hpp" #include "handler.hpp" #include "identity.hpp" #include "pendingbuffer.hpp" @@ -62,6 +61,7 @@ namespace llarp public EndpointBase { Endpoint(AbstractRouter* r, Context* parent); + ~Endpoint() override; /// return true if we are ready to recv packets from the void bool From a3725284e407032bdd7008fcce6231aed63e67a1 Mon Sep 17 00:00:00 2001 From: Jeff Date: Sun, 26 Jun 2022 10:02:23 -0400 Subject: [PATCH 013/298] simple keygen script --- contrib/keygen.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 contrib/keygen.py diff --git a/contrib/keygen.py b/contrib/keygen.py new file mode 100755 index 000000000..44891d1bf --- /dev/null +++ b/contrib/keygen.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# .loki secret key generator script +# makes keyfile contents +# +# usage: python3 keygen.py out.private +# python3 keygen.py > /some/where/over/the/rainbow +# +from nacl.bindings import crypto_sign_keypair +import sys + +out = sys.stdout + +close_out = lambda : None +args = sys.argv[1:] + +if args and args[0] != '-': + out = open(args[0], 'wb') + close_out = out.close + +pk, sk = crypto_sign_keypair() +out.write(b'64:') +out.write(sk) +out.flush() +close_out() + From 03b37b31e2ca1a4d71ea93e7972e1581a1b6c8b2 Mon Sep 17 00:00:00 2001 From: necro-nemesis Date: Wed, 13 Jul 2022 18:23:05 -0400 Subject: [PATCH 014/298] Update .drone.jsonnet --- .drone.jsonnet | 1 + 1 file changed, 1 insertion(+) diff --git a/.drone.jsonnet b/.drone.jsonnet index b1c6222a6..0c25edb82 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -1,3 +1,4 @@ +// force change distro change local distro = "fedora-36"; local distro_name = 'Fedora 36'; local distro_docker = 'fedora:36'; From 60a40a160ca2c73fc4340f28616967dfb7d8b47a Mon Sep 17 00:00:00 2001 From: necro-nemesis Date: Wed, 13 Jul 2022 19:13:54 -0400 Subject: [PATCH 015/298] Update .drone.jsonnet --- .drone.jsonnet | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.drone.jsonnet b/.drone.jsonnet index 0c25edb82..512059040 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -1,4 +1,5 @@ // force change distro change +// jobs < 4 (3) local distro = "fedora-36"; local distro_name = 'Fedora 36'; local distro_docker = 'fedora:36'; @@ -43,5 +44,5 @@ local rpm_pipeline(image, buildarch='amd64', rpmarch='x86_64', jobs=6) = { [ rpm_pipeline(distro_docker), - rpm_pipeline("arm64v8/" + distro_docker, buildarch='arm64', rpmarch="aarch64", jobs=4) + rpm_pipeline("arm64v8/" + distro_docker, buildarch='arm64', rpmarch="aarch64", jobs=3) ] From 43191ec1006120f2aefc53c6053ffcdcfadc049f Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Thu, 2 Jun 2022 16:05:57 -0300 Subject: [PATCH 016/298] Add missing header Needed for uint_least32_t. --- llarp/util/logging/source_location.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llarp/util/logging/source_location.hpp b/llarp/util/logging/source_location.hpp index 35f5cc7fc..39b707a30 100644 --- a/llarp/util/logging/source_location.hpp +++ b/llarp/util/logging/source_location.hpp @@ -4,6 +4,7 @@ #include namespace slns = std; #else +#include namespace slns { struct source_location From b81f7025c9a619409bb1c3f39e0c56e2084fd7be Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 15 Jul 2022 21:41:14 -0300 Subject: [PATCH 017/298] 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 = 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). --- .drone.jsonnet | 5 +- .gitmodules | 6 +- CMakeLists.txt | 1 - cmake/add_log_tag.cmake | 7 - crypto/CMakeLists.txt | 1 - daemon/CMakeLists.txt | 1 - daemon/lokinet.cpp | 27 ++-- external/CMakeLists.txt | 18 ++- external/date | 1 - external/oxen-logging | 1 + include/lokinet/lokinet_misc.h | 22 ++- llarp/CMakeLists.txt | 24 ++-- llarp/apple/apple_logger.cpp | 25 ---- llarp/apple/apple_logger.hpp | 40 ------ llarp/apple/context_wrapper.cpp | 11 +- llarp/bootstrap.cpp | 2 +- llarp/config/config.cpp | 98 +++++++------ llarp/config/config.hpp | 5 +- llarp/config/definition.cpp | 41 +++--- llarp/config/definition.hpp | 23 ++- llarp/config/ini.cpp | 3 +- llarp/config/key_manager.cpp | 2 +- llarp/consensus/reachability_testing.cpp | 2 +- llarp/context.cpp | 2 +- llarp/crypto/encrypted_frame.cpp | 2 +- llarp/crypto/types.hpp | 60 +++----- llarp/dht/key.hpp | 1 + llarp/dht/localrouterlookup.cpp | 2 +- llarp/dht/localserviceaddresslookup.cpp | 2 +- llarp/dht/tx.hpp | 2 +- llarp/dns/message.cpp | 2 +- llarp/dns/message.hpp | 18 ++- llarp/dns/question.cpp | 12 +- llarp/dns/question.hpp | 12 +- llarp/dns/rr.cpp | 10 +- llarp/dns/rr.hpp | 11 +- llarp/dns/srv_data.cpp | 2 +- llarp/dns/unbound_resolver.cpp | 3 +- llarp/ev/ev_libuv.cpp | 3 - llarp/exit/context.cpp | 4 +- llarp/handlers/tun.cpp | 25 ++-- llarp/iwp/session.cpp | 2 +- llarp/link/server.cpp | 5 +- llarp/lokinet_shared.cpp | 88 ++++-------- llarp/messages/link_intro.cpp | 2 +- llarp/messages/link_message_parser.cpp | 2 +- llarp/messages/relay_commit.cpp | 2 +- llarp/messages/relay_status.cpp | 39 ++--- llarp/net/address_info.cpp | 10 +- llarp/net/address_info.hpp | 12 +- llarp/net/exit_info.cpp | 12 +- llarp/net/exit_info.hpp | 11 +- llarp/net/ip_address.cpp | 16 +-- llarp/net/ip_address.hpp | 10 +- llarp/net/ip_range.hpp | 9 +- llarp/net/net.cpp | 8 +- llarp/net/net_int.hpp | 20 ++- llarp/net/sock_addr.cpp | 20 +-- llarp/net/sock_addr.hpp | 13 +- llarp/nodedb.cpp | 5 +- llarp/path/path.cpp | 15 +- llarp/path/pathbuilder.cpp | 8 +- llarp/path/pathset.cpp | 14 +- llarp/path/pathset.hpp | 10 +- llarp/path/transit_hop.cpp | 16 +++ llarp/path/transit_hop.hpp | 23 ++- llarp/peerstats/orm.hpp | 4 +- llarp/peerstats/peer_db.cpp | 6 +- llarp/pow.cpp | 8 ++ llarp/pow.hpp | 11 +- llarp/quic/address.cpp | 13 +- llarp/quic/address.hpp | 34 +++-- llarp/quic/client.cpp | 2 +- llarp/quic/connection.cpp | 8 +- llarp/quic/connection.hpp | 9 +- llarp/quic/null_crypto.cpp | 2 +- llarp/quic/server.cpp | 3 +- llarp/quic/stream.cpp | 8 +- llarp/quic/stream.hpp | 11 +- llarp/quic/tunnel.cpp | 7 +- llarp/router/i_outbound_session_maker.hpp | 32 ++--- llarp/router/outbound_message_handler.cpp | 2 +- llarp/router/router.cpp | 99 +++++++------ llarp/router/systemd_resolved.cpp | 2 +- llarp/router_contact.cpp | 31 ++-- llarp/router_contact.hpp | 32 +---- llarp/router_id.hpp | 9 +- llarp/router_version.hpp | 8 +- llarp/rpc/endpoint_rpc.cpp | 2 +- llarp/rpc/lokid_rpc_client.cpp | 25 ++-- llarp/rpc/rpc_server.cpp | 10 +- llarp/service/address.hpp | 9 +- llarp/service/context.cpp | 5 +- llarp/service/endpoint_util.cpp | 2 +- llarp/service/identity.cpp | 6 +- llarp/service/info.cpp | 8 ++ llarp/service/info.hpp | 12 +- llarp/service/intro.cpp | 10 ++ llarp/service/intro.hpp | 11 +- llarp/service/intro_set.cpp | 22 ++- llarp/service/intro_set.hpp | 21 ++- llarp/service/protocol_type.cpp | 18 --- llarp/service/protocol_type.hpp | 18 ++- llarp/util/aligned.hpp | 44 +++++- llarp/util/bencode.cpp | 1 - llarp/util/bencode.hpp | 2 +- llarp/util/formattable.hpp | 81 +++++++++++ llarp/util/fs.cpp | 52 +------ llarp/util/logging.hpp | 102 +++++++++++++ llarp/util/logging/android_logger.cpp | 69 --------- llarp/util/logging/android_logger.hpp | 30 ---- llarp/util/logging/buffer.cpp | 37 +++-- llarp/util/logging/buffer.hpp | 13 +- llarp/util/logging/callback_sink.hpp | 46 ++++++ llarp/util/logging/file_logger.cpp | 118 --------------- llarp/util/logging/file_logger.hpp | 71 --------- llarp/util/logging/logger.cpp | 162 --------------------- llarp/util/logging/logger.hpp | 168 ---------------------- llarp/util/logging/logger_internal.cpp | 14 -- llarp/util/logging/logger_internal.hpp | 64 --------- llarp/util/logging/logger_syslog.hpp | 31 ---- llarp/util/logging/loglevel.cpp | 68 --------- llarp/util/logging/loglevel.hpp | 27 ---- llarp/util/logging/logstream.hpp | 58 -------- llarp/util/logging/ostream_logger.cpp | 65 --------- llarp/util/logging/ostream_logger.hpp | 38 ----- llarp/util/logging/source_location.hpp | 54 ------- llarp/util/logging/syslog_logger.cpp | 51 ------- llarp/util/logging/win32_logger.cpp | 114 --------------- llarp/util/logging/win32_logger.hpp | 37 ----- llarp/util/str.hpp | 26 +--- llarp/util/thread/queue_manager.hpp | 20 ++- llarp/util/thread/threading.cpp | 2 +- llarp/util/time.cpp | 36 ----- llarp/util/time.hpp | 78 +++++++--- 135 files changed, 1062 insertions(+), 2148 deletions(-) delete mode 100644 cmake/add_log_tag.cmake delete mode 160000 external/date create mode 160000 external/oxen-logging delete mode 100644 llarp/apple/apple_logger.cpp delete mode 100644 llarp/apple/apple_logger.hpp delete mode 100644 llarp/service/protocol_type.cpp create mode 100644 llarp/util/formattable.hpp create mode 100644 llarp/util/logging.hpp delete mode 100644 llarp/util/logging/android_logger.cpp delete mode 100644 llarp/util/logging/android_logger.hpp create mode 100644 llarp/util/logging/callback_sink.hpp delete mode 100644 llarp/util/logging/file_logger.cpp delete mode 100644 llarp/util/logging/file_logger.hpp delete mode 100644 llarp/util/logging/logger.cpp delete mode 100644 llarp/util/logging/logger.hpp delete mode 100644 llarp/util/logging/logger_internal.cpp delete mode 100644 llarp/util/logging/logger_internal.hpp delete mode 100644 llarp/util/logging/logger_syslog.hpp delete mode 100644 llarp/util/logging/loglevel.cpp delete mode 100644 llarp/util/logging/loglevel.hpp delete mode 100644 llarp/util/logging/logstream.hpp delete mode 100644 llarp/util/logging/ostream_logger.cpp delete mode 100644 llarp/util/logging/ostream_logger.hpp delete mode 100644 llarp/util/logging/source_location.hpp delete mode 100644 llarp/util/logging/syslog_logger.cpp delete mode 100644 llarp/util/logging/win32_logger.cpp delete mode 100644 llarp/util/logging/win32_logger.hpp diff --git a/.drone.jsonnet b/.drone.jsonnet index 87aaf71ff..684841501 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -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', diff --git a/.gitmodules b/.gitmodules index 60d5d9621..005334d4b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 83f6d3e41..0758f6c1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/cmake/add_log_tag.cmake b/cmake/add_log_tag.cmake deleted file mode 100644 index b86ab5717..000000000 --- a/cmake/add_log_tag.cmake +++ /dev/null @@ -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() diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 083d6bfb6..e4cedd9b6 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -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) diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 233c436ce..5f3d91aa9 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -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) diff --git a/daemon/lokinet.cpp b/daemon/lokinet.cpp index ebddf84e1..dbdb6be59 100644 --- a/daemon/lokinet.cpp +++ b/daemon/lokinet.cpp @@ -3,8 +3,6 @@ #include #include #include -#include -#include #include #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()) ("r,router", "run in routing mode instead of client only mode", cxxopts::value()) ("f,force", "force writing config even if it already exists", cxxopts::value()) - ("c,colour", "colour output", cxxopts::value()->default_value("true")) ("config", "path to lokinet.ini configuration file", cxxopts::value()) ; // clang-format on @@ -424,12 +424,6 @@ lokinet_main(int argc, char* argv[]) { auto result = options.parse(argc, argv); - if (!result["colour"].as()) - { - llarp::LogContext::Instance().logStream = - std::make_unique(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(); diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index b851ff986..0ea284a78 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -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) diff --git a/external/date b/external/date deleted file mode 160000 index cac99da8d..000000000 --- a/external/date +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cac99da8dc88be719a728dc1b597b0ac307c1800 diff --git a/external/oxen-logging b/external/oxen-logging new file mode 160000 index 000000000..0fc1b3528 --- /dev/null +++ b/external/oxen-logging @@ -0,0 +1 @@ +Subproject commit 0fc1b3528a52475c4007d734a7861faa2212fe75 diff --git a/include/lokinet/lokinet_misc.h b/include/lokinet/lokinet_misc.h index b09b20e2c..cc928a0a8 100644 --- a/include/lokinet/lokinet_misc.h +++ b/include/lokinet/lokinet_misc.h @@ -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 diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 8be49a236..0cd9edd9c 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -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) diff --git a/llarp/apple/apple_logger.cpp b/llarp/apple/apple_logger.cpp deleted file mode 100644 index 6dca15fa3..000000000 --- a/llarp/apple/apple_logger.cpp +++ /dev/null @@ -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 diff --git a/llarp/apple/apple_logger.hpp b/llarp/apple/apple_logger.hpp deleted file mode 100644 index 954d5b402..000000000 --- a/llarp/apple/apple_logger.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include - -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 diff --git a/llarp/apple/context_wrapper.cpp b/llarp/apple/context_wrapper.cpp index fd662967c..31768f3f3 100644 --- a/llarp/apple/context_wrapper.cpp +++ b/llarp/apple/context_wrapper.cpp @@ -6,10 +6,11 @@ #include #include #include +#include +#include #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(appleconf->ns_logger); + llarp::log::ReplaceLogger(std::make_shared( + [](const char* msg, void* nslog) { reinterpret_cast(nslog)(msg); }, + nullptr, + appleconf->ns_logger)); try { @@ -43,7 +46,7 @@ llarp_apple_init(llarp_apple_config* appleconf) auto config = std::make_shared(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 diff --git a/llarp/bootstrap.cpp b/llarp/bootstrap.cpp index 32f273de4..56731257f 100644 --- a/llarp/bootstrap.cpp +++ b/llarp/bootstrap.cpp @@ -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 diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index dde090362..3ea4d970b 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -4,12 +4,15 @@ #include "config/definition.hpp" #include "ini.hpp" #include +#include +#include #include #include #include #include #include -#include +#include +#include #include #include @@ -19,7 +22,6 @@ #include #include #include -#include 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( @@ -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( @@ -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( @@ -1114,9 +1118,9 @@ namespace llarp "level", DefaultLogLevel, [this](std::string arg) { - std::optional level = LogLevelFromString(arg); + std::optional 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( @@ -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(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(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; diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 975a8ac99..8d96ab71b 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "ini.hpp" #include "definition.hpp" #include @@ -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 diff --git a/llarp/config/definition.cpp b/llarp/config/definition.cpp index 217cd77d3..9156acaee 100644 --- a/llarp/config/definition.cpp +++ b/llarp/config/definition.cpp @@ -1,5 +1,5 @@ #include "definition.hpp" -#include +#include #include #include @@ -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; } diff --git a/llarp/config/definition.hpp b/llarp/config/definition.hpp index 0e3d638b2..07e448c01 100644 --- a/llarp/config/definition.hpp +++ b/llarp/config/definition.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -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*>(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(); } diff --git a/llarp/config/ini.cpp b/llarp/config/ini.cpp index beb4c6c96..dbacc412b 100644 --- a/llarp/config/ini.cpp +++ b/llarp/config/ini.cpp @@ -1,6 +1,7 @@ #include "ini.hpp" -#include +#include +#include #include #include diff --git a/llarp/config/key_manager.cpp b/llarp/config/key_manager.cpp index 4e17c0ef4..8268d089f 100644 --- a/llarp/config/key_manager.cpp +++ b/llarp/config/key_manager.cpp @@ -1,7 +1,7 @@ #include "key_manager.hpp" #include -#include +#include #include "config.hpp" #include #include diff --git a/llarp/consensus/reachability_testing.cpp b/llarp/consensus/reachability_testing.cpp index dd3b2a5ef..f238907d0 100644 --- a/llarp/consensus/reachability_testing.cpp +++ b/llarp/consensus/reachability_testing.cpp @@ -2,7 +2,7 @@ #include "reachability_testing.hpp" #include #include -#include +#include #include using std::chrono::steady_clock; diff --git a/llarp/context.cpp b/llarp/context.cpp index ecba8ee09..6bc5a3c3e 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -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 #include diff --git a/llarp/crypto/encrypted_frame.cpp b/llarp/crypto/encrypted_frame.cpp index 79d89bbda..210f0e1dc 100644 --- a/llarp/crypto/encrypted_frame.cpp +++ b/llarp/crypto/encrypted_frame.cpp @@ -1,7 +1,7 @@ #include "encrypted_frame.hpp" #include "crypto.hpp" -#include +#include #include namespace llarp diff --git a/llarp/crypto/types.hpp b/llarp/crypto/types.hpp index 225be8278..bc4b6e2a2 100644 --- a/llarp/crypto/types.hpp +++ b/llarp/crypto/types.hpp @@ -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 = true; + template <> + constexpr inline bool IsToStringFormattable = true; + template <> + constexpr inline bool IsToStringFormattable = true; + template <> + constexpr inline bool IsToStringFormattable = true; using ShortHash = AlignedBuffer; using LongHash = AlignedBuffer; diff --git a/llarp/dht/key.hpp b/llarp/dht/key.hpp index 242c783df..a9c815717 100644 --- a/llarp/dht/key.hpp +++ b/llarp/dht/key.hpp @@ -2,6 +2,7 @@ #include #include +#include #include diff --git a/llarp/dht/localrouterlookup.cpp b/llarp/dht/localrouterlookup.cpp index e45c9cf64..a70edd923 100644 --- a/llarp/dht/localrouterlookup.cpp +++ b/llarp/dht/localrouterlookup.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include namespace llarp { diff --git a/llarp/dht/localserviceaddresslookup.cpp b/llarp/dht/localserviceaddresslookup.cpp index fda3260db..177294cf4 100644 --- a/llarp/dht/localserviceaddresslookup.cpp +++ b/llarp/dht/localserviceaddresslookup.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include namespace llarp { diff --git a/llarp/dht/tx.hpp b/llarp/dht/tx.hpp index f50fe3d8e..43ac5c077 100644 --- a/llarp/dht/tx.hpp +++ b/llarp/dht/tx.hpp @@ -3,7 +3,7 @@ #include "key.hpp" #include "txowner.hpp" -#include +#include #include #include diff --git a/llarp/dns/message.cpp b/llarp/dns/message.cpp index 65b30c78d..a6957116f 100644 --- a/llarp/dns/message.cpp +++ b/llarp/dns/message.cpp @@ -4,7 +4,7 @@ #include "dns.hpp" #include "srv_data.hpp" #include -#include +#include #include #include diff --git a/llarp/dns/message.hpp b/llarp/dns/message.hpp index 937c37d97..9ba58ed1e 100644 --- a/llarp/dns/message.hpp +++ b/llarp/dns/message.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 questions; @@ -103,12 +111,8 @@ namespace llarp std::vector authorities; std::vector 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 = true; } // namespace llarp diff --git a/llarp/dns/question.cpp b/llarp/dns/question.cpp index a8c60c260..aef0d1e01 100644 --- a/llarp/dns/question.cpp +++ b/llarp/dns/question.cpp @@ -1,6 +1,6 @@ #include "question.hpp" -#include +#include #include #include #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); diff --git a/llarp/dns/question.hpp b/llarp/dns/question.hpp index 5434bbcdd..38eef2963 100644 --- a/llarp/dns/question.hpp +++ b/llarp/dns/question.hpp @@ -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 = true; diff --git a/llarp/dns/rr.cpp b/llarp/dns/rr.cpp index 82ed20470..7bb8c417b 100644 --- a/llarp/dns/rr.cpp +++ b/llarp/dns/rr.cpp @@ -1,7 +1,7 @@ #include "rr.hpp" #include "dns.hpp" #include -#include +#include #include 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 { diff --git a/llarp/dns/rr.hpp b/llarp/dns/rr.hpp index e9fa72c27..9f3e5d9f1 100644 --- a/llarp/dns/rr.hpp +++ b/llarp/dns/rr.hpp @@ -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 = true; diff --git a/llarp/dns/srv_data.cpp b/llarp/dns/srv_data.cpp index e46b90732..9528d7e39 100644 --- a/llarp/dns/srv_data.cpp +++ b/llarp/dns/srv_data.cpp @@ -1,6 +1,6 @@ #include "srv_data.hpp" #include -#include +#include #include diff --git a/llarp/dns/unbound_resolver.cpp b/llarp/dns/unbound_resolver.cpp index 82022cce0..a65728285 100644 --- a/llarp/dns/unbound_resolver.cpp +++ b/llarp/dns/unbound_resolver.cpp @@ -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 { diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index c7356f432..1fd2476ca 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -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} diff --git a/llarp/exit/context.cpp b/llarp/exit/context.cpp index ab360ec15..e229262ba 100644 --- a/llarp/exit/context.cpp +++ b/llarp/exit/context.cpp @@ -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(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)); } diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 3b13e1d16..66dcee92b 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "tun.hpp" #include @@ -117,9 +118,9 @@ namespace llarp obj["ifname"] = m_IfName; std::vector 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; } diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index 9aa88d01a..382e75c64 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -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)}}; diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index 528b9d37b..c22b0b863 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -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}}}}; } diff --git a/llarp/lokinet_shared.cpp b/llarp/lokinet_shared.cpp index 2075ba421..2452686ed 100644 --- a/llarp/lokinet_shared.cpp +++ b/llarp/lokinet_shared.cpp @@ -8,7 +8,9 @@ #include #include +#include #include +#include #include @@ -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 impl; - std::shared_ptr config; + std::shared_ptr impl = std::make_shared(); + std::shared_ptr config = llarp::Config::EmbeddedConfig(); std::unique_ptr runner; - int _socket_id; - - lokinet_context() - : impl{std::make_shared()}, 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 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([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(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(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); } } diff --git a/llarp/messages/link_intro.cpp b/llarp/messages/link_intro.cpp index 9144baf20..88d1af2d1 100644 --- a/llarp/messages/link_intro.cpp +++ b/llarp/messages/link_intro.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include namespace llarp { diff --git a/llarp/messages/link_message_parser.cpp b/llarp/messages/link_message_parser.cpp index bd47ac67a..971af9a6d 100644 --- a/llarp/messages/link_message_parser.cpp +++ b/llarp/messages/link_message_parser.cpp @@ -9,7 +9,7 @@ #include "relay.hpp" #include #include -#include +#include #include diff --git a/llarp/messages/relay_commit.cpp b/llarp/messages/relay_commit.cpp index 3dc67d7a5..74b5ecc35 100644 --- a/llarp/messages/relay_commit.cpp +++ b/llarp/messages/relay_commit.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/llarp/messages/relay_status.cpp b/llarp/messages/relay_status.cpp index 67dcb3294..8d0732059 100644 --- a/llarp/messages/relay_status.cpp +++ b/llarp/messages/relay_status.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -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 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 diff --git a/llarp/net/address_info.cpp b/llarp/net/address_info.cpp index d4b8cd398..5c18e276f 100644 --- a/llarp/net/address_info.cpp +++ b/llarp/net/address_info.cpp @@ -166,7 +166,7 @@ namespace llarp void AddressInfo::fromSockAddr(const SockAddr& addr) { - const sockaddr_in6* addr6 = addr; + const auto* addr6 = static_cast(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) { diff --git a/llarp/net/address_info.hpp b/llarp/net/address_info.hpp index a66f77112..f9982b36b 100644 --- a/llarp/net/address_info.hpp +++ b/llarp/net/address_info.hpp @@ -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 = true; + } // namespace llarp namespace std diff --git a/llarp/net/exit_info.cpp b/llarp/net/exit_info.cpp index e001c915a..46f9cb92e 100644 --- a/llarp/net/exit_info.cpp +++ b/llarp/net/exit_info.cpp @@ -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(exitaddr); SockAddr netmaskaddr = netmask.createSockAddr(); - const sockaddr_in6* netmaskaddr6 = netmaskaddr; + const auto* netmaskaddr6 = static_cast(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 diff --git a/llarp/net/exit_info.hpp b/llarp/net/exit_info.hpp index b3727c4f5..bad9c0ba8 100644 --- a/llarp/net/exit_info.hpp +++ b/llarp/net/exit_info.hpp @@ -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 = true; + } // namespace llarp diff --git a/llarp/net/ip_address.cpp b/llarp/net/ip_address.cpp index 62fb2f428..818df7ac8 100644 --- a/llarp/net/ip_address.cpp +++ b/llarp/net/ip_address.cpp @@ -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(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 diff --git a/llarp/net/ip_address.hpp b/llarp/net/ip_address.hpp index 2414f4f8e..d86c77314 100644 --- a/llarp/net/ip_address.hpp +++ b/llarp/net/ip_address.hpp @@ -8,6 +8,8 @@ #include "net_int.hpp" +#include + 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 m_port = std::nullopt; }; - std::ostream& - operator<<(std::ostream& out, const IpAddress& address); + template <> + constexpr inline bool IsToStringFormattable = true; } // namespace llarp @@ -160,7 +162,7 @@ namespace std std::size_t operator()(const llarp::IpAddress& address) const noexcept { - return std::hash{}(address.toString()); + return std::hash{}(address.ToString()); } }; } // namespace std diff --git a/llarp/net/ip_range.hpp b/llarp/net/ip_range.hpp index 1a9b98683..31aee44d6 100644 --- a/llarp/net/ip_range.hpp +++ b/llarp/net/ip_range.hpp @@ -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 = true; + } // namespace llarp namespace std diff --git a/llarp/net/net.cpp b/llarp/net/net.cpp index 0c73e3167..09877e944 100644 --- a/llarp/net/net.cpp +++ b/llarp/net/net.cpp @@ -16,7 +16,7 @@ #include "ip.hpp" #include "ip_range.hpp" -#include +#include #include #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(af, " is not a valid address family"); + throw std::invalid_argument{fmt::format("{} is not a valid address family", af)}; } } // namespace diff --git a/llarp/net/net_int.hpp b/llarp/net/net_int.hpp index b5ec0e7cb..051d8c665 100644 --- a/llarp/net/net_int.hpp +++ b/llarp/net/net_int.hpp @@ -17,6 +17,8 @@ #include #include +#include + #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; @@ -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 + inline constexpr bool IsToStringFormattable> = true; + + template + inline constexpr bool IsToStringFormattable> = true; + using nuint32_t = nuint_t; using nuint16_t = nuint_t; using nuint128_t = nuint_t; diff --git a/llarp/net/sock_addr.cpp b/llarp/net/sock_addr.cpp index dbb1734a2..b0ed8f2eb 100644 --- a/llarp/net/sock_addr.cpp +++ b/llarp/net/sock_addr.cpp @@ -3,7 +3,7 @@ #include "ip.hpp" #include "net_bits.hpp" #include -#include +#include #include #include @@ -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 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 diff --git a/llarp/net/sock_addr.hpp b/llarp/net/sock_addr.hpp index a51379b13..df9838ac0 100644 --- a/llarp/net/sock_addr.hpp +++ b/llarp/net/sock_addr.hpp @@ -13,6 +13,7 @@ #include #include "net_int.hpp" #include +#include 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 = true; } // namespace llarp diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 22feb80f3..78a313ca7 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -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) { diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 1e0540f0f..516a6d02d 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -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 diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index c401965aa..eaefcf40c 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -4,6 +4,7 @@ #include #include #include "path_context.hpp" +#include "util/logging.hpp" #include #include #include @@ -15,6 +16,11 @@ namespace llarp { + namespace + { + auto log_path = log::Cat("path"); + } + struct AsyncPathKeyExchangeContext : std::enable_shared_from_this { using WorkFunc_t = std::function; @@ -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); diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index 50a40ef75..c3ba852d6 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -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 diff --git a/llarp/path/pathset.hpp b/llarp/path/pathset.hpp index 5bef0a643..734b5b26b 100644 --- a/llarp/path/pathset.hpp +++ b/llarp/path/pathset.hpp @@ -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 = true; + } // namespace llarp diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index e52251996..a3b2cb19d 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -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() { diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 798c2d063..86080a330 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -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 @@ -109,6 +106,8 @@ namespace llarp HandleLRSM( uint64_t status, std::array& 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 m_UpstreamWorkCounter; std::atomic 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 = true; + template <> + constexpr inline bool IsToStringFormattable = true; + } // namespace llarp namespace std diff --git a/llarp/peerstats/orm.hpp b/llarp/peerstats/orm.hpp index bd60c5d20..0c0df851b 100644 --- a/llarp/peerstats/orm.hpp +++ b/llarp/peerstats/orm.hpp @@ -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()); } }; diff --git a/llarp/peerstats/peer_db.cpp b/llarp/peerstats/peer_db.cpp index 6e1ff7d6a..78e904137 100644 --- a/llarp/peerstats/peer_db.cpp +++ b/llarp/peerstats/peer_db.cpp @@ -1,6 +1,6 @@ #include "peer_db.hpp" -#include +#include #include #include @@ -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); diff --git a/llarp/pow.cpp b/llarp/pow.cpp index 0a5b7993d..48158f6b4 100644 --- a/llarp/pow.cpp +++ b/llarp/pow.cpp @@ -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 diff --git a/llarp/pow.hpp b/llarp/pow.hpp index be075ca6c..0a01bc85c 100644 --- a/llarp/pow.hpp +++ b/llarp/pow.hpp @@ -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 = true; + } // namespace llarp diff --git a/llarp/quic/address.cpp b/llarp/quic/address.cpp index 48dd05261..89e171104 100644 --- a/llarp/quic/address.cpp +++ b/llarp/quic/address.cpp @@ -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 diff --git a/llarp/quic/address.hpp b/llarp/quic/address.hpp index a6b56a243..793713e62 100644 --- a/llarp/quic/address.hpp +++ b/llarp/quic/address.hpp @@ -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 , int> = 0> + operator T*() { return reinterpret_cast(&saddr); } - operator const sockaddr*() const + template , int> = 0> + operator const T*() const { return reinterpret_cast(&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 , int> = 0> + operator T*() { return &path; } - operator const ngtcp2_path*() const + template , 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 = true; +template <> +constexpr inline bool llarp::IsToStringFormattable = true; diff --git a/llarp/quic/client.cpp b/llarp/quic/client.cpp index a2a081edf..8cf9d7f80 100644 --- a/llarp/quic/client.cpp +++ b/llarp/quic/client.cpp @@ -1,7 +1,7 @@ #include "client.hpp" #include "tunnel.hpp" #include -#include +#include #include #include diff --git a/llarp/quic/connection.cpp b/llarp/quic/connection.cpp index fed88401e..71b84cfd4 100644 --- a/llarp/quic/connection.cpp +++ b/llarp/quic/connection.cpp @@ -2,7 +2,7 @@ #include "client.hpp" #include "server.hpp" #include -#include +#include #include #include @@ -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 diff --git a/llarp/quic/connection.hpp b/llarp/quic/connection.hpp index be8eb715c..0f2b4cc46 100644 --- a/llarp/quic/connection.hpp +++ b/llarp/quic/connection.hpp @@ -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 = true; + namespace std { template <> diff --git a/llarp/quic/null_crypto.cpp b/llarp/quic/null_crypto.cpp index 49623dfac..5043fcf8a 100644 --- a/llarp/quic/null_crypto.cpp +++ b/llarp/quic/null_crypto.cpp @@ -1,5 +1,5 @@ #include "null_crypto.hpp" -#include +#include #include diff --git a/llarp/quic/server.cpp b/llarp/quic/server.cpp index 690a97fac..ebda2bd40 100644 --- a/llarp/quic/server.cpp +++ b/llarp/quic/server.cpp @@ -1,6 +1,6 @@ #include "server.hpp" +#include #include -#include #include #include @@ -55,7 +55,6 @@ namespace llarp::quic { auto connptr = std::make_shared(*this, it->first, hd, p.path); it->second = connptr; - LogDebug("Created local Connection ", it->first, " for incoming connection"); return connptr; } } diff --git a/llarp/quic/stream.cpp b/llarp/quic/stream.cpp index a990372be..93f297068 100644 --- a/llarp/quic/stream.cpp +++ b/llarp/quic/stream.cpp @@ -1,7 +1,7 @@ #include "stream.hpp" #include "connection.hpp" #include "endpoint.hpp" -#include +#include #include #include @@ -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( diff --git a/llarp/quic/stream.hpp b/llarp/quic/stream.hpp index 176a2ab84..bed6f483a 100644 --- a/llarp/quic/stream.hpp +++ b/llarp/quic/stream.hpp @@ -12,6 +12,8 @@ #include #include +#include + 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 = true; + namespace std { template <> diff --git a/llarp/quic/tunnel.cpp b/llarp/quic/tunnel.cpp index 6954e20f4..480d14177 100644 --- a/llarp/quic/tunnel.cpp +++ b/llarp/quic/tunnel.cpp @@ -4,8 +4,8 @@ #include "service/name.hpp" #include "stream.hpp" #include +#include #include -#include #include #include #include @@ -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(); diff --git a/llarp/router/i_outbound_session_maker.hpp b/llarp/router/i_outbound_session_maker.hpp index 76ef6ddbd..97dd0aed9 100644 --- a/llarp/router/i_outbound_session_maker.hpp +++ b/llarp/router/i_outbound_session_maker.hpp @@ -2,6 +2,9 @@ #include #include +#include + +#include #include @@ -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 = true; using RouterCallback = std::function; diff --git a/llarp/router/outbound_message_handler.cpp b/llarp/router/outbound_message_handler.cpp index 1abbb8c05..0a793b2ff 100644 --- a/llarp/router/outbound_message_handler.cpp +++ b/llarp/router/outbound_message_handler.cpp @@ -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 diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 1680e086c..c59e8aea0 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -15,9 +15,7 @@ #include #include #include -#include -#include -#include +#include #include #include #include @@ -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{_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{_rcGossiper.NextGossipAt()}); if (auto maybe = _rcGossiper.LastGossipAt()) - { - ss << time_delta{*maybe}; - } + out = fmt::format_to(out, "{}", time_delta{*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 diff --git a/llarp/router/systemd_resolved.cpp b/llarp/router/systemd_resolved.cpp index 5f1e40813..61d9ef930 100644 --- a/llarp/router/systemd_resolved.cpp +++ b/llarp/router/systemd_resolved.cpp @@ -1,5 +1,5 @@ #include "systemd_resolved.hpp" -#include +#include #ifndef WITH_SYSTEMD diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 76dac45fa..b1266145d 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -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 diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 53f29bd38..33ed5f4d7 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -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 = true; + template <> + constexpr inline bool IsToStringFormattable = true; using RouterLookupHandler = std::function&)>; } // namespace llarp diff --git a/llarp/router_id.hpp b/llarp/router_id.hpp index 70c4dfbc3..273460f91 100644 --- a/llarp/router_id.hpp +++ b/llarp/router_id.hpp @@ -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 = true; + } // namespace llarp namespace std diff --git a/llarp/router_version.hpp b/llarp/router_version.hpp index 0df69a7d1..30429483b 100644 --- a/llarp/router_version.hpp +++ b/llarp/router_version.hpp @@ -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 = true; static constexpr int64_t INVALID_VERSION = -1; static const RouterVersion emptyRouterVersion({0, 0, 0}, INVALID_VERSION); diff --git a/llarp/rpc/endpoint_rpc.cpp b/llarp/rpc/endpoint_rpc.cpp index 8fa90bf95..a5edd2c34 100644 --- a/llarp/rpc/endpoint_rpc.cpp +++ b/llarp/rpc/endpoint_rpc.cpp @@ -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); diff --git a/llarp/rpc/lokid_rpc_client.cpp b/llarp/rpc/lokid_rpc_client.cpp index 44e5c9520..be448c4eb 100644 --- a/llarp/rpc/lokid_rpc_client.cpp +++ b/llarp/rpc/lokid_rpc_client.cpp @@ -1,7 +1,7 @@ #include "lokid_rpc_client.hpp" #include -#include +#include #include @@ -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()); 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()); diff --git a/llarp/rpc/rpc_server.cpp b/llarp/rpc/rpc_server.cpp index 7bc2f3f42..957bba6db 100644 --- a/llarp/rpc/rpc_server.cpp +++ b/llarp/rpc/rpc_server.cpp @@ -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()); diff --git a/llarp/service/address.hpp b/llarp/service/address.hpp index bddfc822a..fd437b76b 100644 --- a/llarp/service/address.hpp +++ b/llarp/service/address.hpp @@ -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 = true; } // namespace llarp namespace std diff --git a/llarp/service/context.cpp b/llarp/service/context.cpp index a376b14b5..60d23a916 100644 --- a/llarp/service/context.cpp +++ b/llarp/service/context.cpp @@ -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); diff --git a/llarp/service/endpoint_util.cpp b/llarp/service/endpoint_util.cpp index a77bc9feb..06dec211f 100644 --- a/llarp/service/endpoint_util.cpp +++ b/llarp/service/endpoint_util.cpp @@ -3,7 +3,7 @@ #include #include "outbound_context.hpp" #include "lookup.hpp" -#include +#include namespace llarp { diff --git a/llarp/service/identity.cpp b/llarp/service/identity.cpp index d91da7411..0d106c24a 100644 --- a/llarp/service/identity.cpp +++ b/llarp/service/identity.cpp @@ -104,16 +104,16 @@ namespace llarp // write auto optional_f = util::OpenFileStream(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 diff --git a/llarp/service/info.cpp b/llarp/service/info.cpp index 3e2d15fd4..a969e8284 100644 --- a/llarp/service/info.cpp +++ b/llarp/service/info.cpp @@ -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 diff --git a/llarp/service/info.hpp b/llarp/service/info.hpp index 1a56f13bf..bd8f5e58f 100644 --- a/llarp/service/info.hpp +++ b/llarp/service/info.hpp @@ -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 = true; diff --git a/llarp/service/intro.cpp b/llarp/service/intro.cpp index b7fde5556..41d15aaaa 100644 --- a/llarp/service/intro.cpp +++ b/llarp/service/intro.cpp @@ -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 diff --git a/llarp/service/intro.hpp b/llarp/service/intro.hpp index 36ea34c2a..2495957b4 100644 --- a/llarp/service/intro.hpp +++ b/llarp/service/intro.hpp @@ -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 = true; + namespace std { template <> diff --git a/llarp/service/intro_set.cpp b/llarp/service/intro_set.cpp index e0deda9e4..431f9dbfe 100644 --- a/llarp/service/intro_set.cpp +++ b/llarp/service/intro_set.cpp @@ -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 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 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 diff --git a/llarp/service/intro_set.hpp b/llarp/service/intro_set.hpp index c39a08404..71a19288e 100644 --- a/llarp/service/intro_set.hpp +++ b/llarp/service/intro_set.hpp @@ -59,6 +59,8 @@ namespace llarp std::ostream& print(std::ostream& stream, int level, int spaces) const; + std::string + ToString() const; llarp_time_t GetNewestIntroExpiration() const; @@ -131,12 +133,6 @@ namespace llarp return !(lhs == rhs); } - inline std::ostream& - operator<<(std::ostream& out, const IntroSet& i) - { - return i.print(out, -1, -1); - } - /// public version of the introset that is encrypted struct EncryptedIntroSet { @@ -176,6 +172,8 @@ namespace llarp std::ostream& print(std::ostream& stream, int level, int spaces) const; + std::string + ToString() const; util::StatusObject ExtractStatus() const; @@ -184,12 +182,6 @@ namespace llarp MaybeDecrypt(const PubKey& rootKey) const; }; - inline std::ostream& - operator<<(std::ostream& out, const EncryptedIntroSet& i) - { - return i.print(out, -1, -1); - } - inline bool operator<(const EncryptedIntroSet& lhs, const EncryptedIntroSet& rhs) { @@ -215,3 +207,8 @@ namespace llarp } // namespace service } // namespace llarp + +template <> +constexpr inline bool llarp::IsToStringFormattable = true; +template <> +constexpr inline bool llarp::IsToStringFormattable = true; diff --git a/llarp/service/protocol_type.cpp b/llarp/service/protocol_type.cpp deleted file mode 100644 index 4a6861681..000000000 --- a/llarp/service/protocol_type.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "protocol_type.hpp" - -namespace llarp::service -{ - std::ostream& - operator<<(std::ostream& o, ProtocolType t) - { - return o - << (t == ProtocolType::Control ? "Control" - : t == ProtocolType::TrafficV4 ? "TrafficV4" - : t == ProtocolType::TrafficV6 ? "TrafficV6" - : t == ProtocolType::Exit ? "Exit" - : t == ProtocolType::Auth ? "Auth" - : t == ProtocolType::QUIC ? "QUIC" - : "(unknown-protocol-type)"); - } - -} // namespace llarp::service diff --git a/llarp/service/protocol_type.hpp b/llarp/service/protocol_type.hpp index 8af8614a8..3864717be 100644 --- a/llarp/service/protocol_type.hpp +++ b/llarp/service/protocol_type.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace llarp::service { @@ -19,7 +20,20 @@ namespace llarp::service }; - std::ostream& - operator<<(std::ostream& o, ProtocolType t); + constexpr std::string_view + ToString(ProtocolType t) + { + using namespace std::literals; + return t == ProtocolType::Control ? "Control"sv + : t == ProtocolType::TrafficV4 ? "TrafficV4"sv + : t == ProtocolType::TrafficV6 ? "TrafficV6"sv + : t == ProtocolType::Exit ? "Exit"sv + : t == ProtocolType::Auth ? "Auth"sv + : t == ProtocolType::QUIC ? "QUIC"sv + : "(unknown-protocol-type)"sv; + } } // namespace llarp::service + +template <> +constexpr inline bool llarp::IsToStringFormattable = true; diff --git a/llarp/util/aligned.hpp b/llarp/util/aligned.hpp index 713220614..d41fff48f 100644 --- a/llarp/util/aligned.hpp +++ b/llarp/util/aligned.hpp @@ -1,8 +1,9 @@ #pragma once #include "bencode.h" -#include +#include #include +#include #include "printer.hpp" #include @@ -69,12 +70,6 @@ namespace llarp return *this; } - friend std::ostream& - operator<<(std::ostream& out, const AlignedBuffer& self) - { - return out << oxenc::to_hex(self.begin(), self.end()); - } - /// bitwise NOT AlignedBuffer operator~() const @@ -300,8 +295,43 @@ namespace llarp private: Data m_data; }; + + namespace detail + { + template + static std::true_type + is_aligned_buffer_impl(AlignedBuffer*); + + static std::false_type + is_aligned_buffer_impl(...); + } // namespace detail + // True if T is or is derived from AlignedBuffer for any N + template + constexpr inline bool is_aligned_buffer = + decltype(detail::is_aligned_buffer_impl(static_cast(nullptr)))::value; + } // namespace llarp +namespace fmt +{ + // Any AlignedBuffer (or subclass) gets hex formatted when output: + template + struct formatter< + T, + char, + std::enable_if_t && !llarp::IsToStringFormattable>> + : formatter + { + template + auto + format(const T& val, FormatContext& ctx) + { + auto it = oxenc::hex_encoder{val.begin(), val.end()}; + return std::copy(it, it.end(), ctx.out()); + } + }; +} // namespace fmt + namespace std { template diff --git a/llarp/util/bencode.cpp b/llarp/util/bencode.cpp index 2ff9bc567..73966291b 100644 --- a/llarp/util/bencode.cpp +++ b/llarp/util/bencode.cpp @@ -1,5 +1,4 @@ #include "bencode.hpp" -#include #include #include #include diff --git a/llarp/util/bencode.hpp b/llarp/util/bencode.hpp index 7ccabdcab..c02453f58 100644 --- a/llarp/util/bencode.hpp +++ b/llarp/util/bencode.hpp @@ -3,7 +3,7 @@ #include "buffer.hpp" #include "bencode.h" #include "fs.hpp" -#include +#include #include "mem.hpp" #include diff --git a/llarp/util/formattable.hpp b/llarp/util/formattable.hpp new file mode 100644 index 000000000..edc4285e3 --- /dev/null +++ b/llarp/util/formattable.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include +#include + +// Formattable types can specialize this to true and will get automatic fmt formattering support via +// their .ToString() method. + +namespace llarp +{ + // Types can opt-in to being formatting via .ToString() by specializing this to true. This also + // allows scoped enums by instead looking for a call to `ToString(val)` (and so there should be a + // ToString function in the same namespace as the scoped enum to pick it up via ADL). + template + constexpr bool IsToStringFormattable = false; + + // e.g.: + // template <> inline constexpr bool IsToStringFormattable = true; + +#ifdef __cpp_lib_is_scoped_enum + using std::is_scoped_enum; + using std::is_scoped_enum_v; +#else + template > + struct is_scoped_enum : std::false_type + {}; + + template + struct is_scoped_enum + : std::bool_constant>> + {}; + + template + constexpr bool is_scoped_enum_v = is_scoped_enum::value; +#endif + +} // namespace llarp + +#if !defined(USE_GHC_FILESYSTEM) && FMT_VERSION >= 80102 + +// Native support in fmt added after fmt 8.1.1 +#include + +#else + +#include + +namespace fmt +{ + template <> + struct formatter : formatter + { + template + auto + format(const fs::path& p, FormatContext& ctx) + { + return formatter::format(p.string(), ctx); + } + }; +} // namespace fmt + +#endif + +namespace fmt +{ + template + struct formatter>> + : formatter + { + template + auto + format(const T& val, FormatContext& ctx) + { + if constexpr (llarp::is_scoped_enum_v) + return formatter::format(ToString(val), ctx); + else + return formatter::format(val.ToString(), ctx); + } + }; + +} // namespace fmt diff --git a/llarp/util/fs.cpp b/llarp/util/fs.cpp index 187ea2228..95b345a58 100644 --- a/llarp/util/fs.cpp +++ b/llarp/util/fs.cpp @@ -1,6 +1,7 @@ #include "fs.hpp" -#include +#include +#include #include #include @@ -13,55 +14,6 @@ #include #endif -namespace cpp17 -{ - namespace filesystem - { -#ifdef LOKINET_USE_CPPBACKPORT - const fs::perms active_bits( - fs::perms::all | fs::perms::set_uid | fs::perms::set_gid | fs::perms::sticky_bit); - inline mode_t - mode_cast(fs::perms prms) - { - return prms & active_bits; - } - - void - permissions(const fs::path& p, fs::perms prms, std::error_code& ec) - { - std::error_code local_ec; - - // OS X <10.10, iOS <8.0 and some other platforms don't support - // fchmodat(). Solaris (SunPro and gcc) only support fchmodat() on - // Solaris 11 and higher, and a runtime check is too much trouble. Linux - // does not support permissions on symbolic links and has no plans to - // support them in the future. The chmod() code is thus more practical, - // rather than always hitting ENOTSUP when sending in - // AT_SYMLINK_NO_FOLLOW. - // - See the 3rd paragraph of - // "Symbolic link ownership, permissions, and timestamps" at: - // "http://man7.org/linux/man-pages/man7/symlink.7.html" - // - See the fchmodat() Linux man page: - // "http://man7.org/linux/man-pages/man2/fchmodat.2.html" -#if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) \ - && !(defined(__SUNPRO_CC) || defined(__sun) || defined(sun)) \ - && !(defined(linux) || defined(__linux) || defined(__linux__)) \ - && !(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000) \ - && !(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 80000) \ - && !(defined(__QNX__) && (_NTO_VERSION <= 700)) - if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms), 0)) -#else // fallback if fchmodat() not supported - if (::chmod(p.c_str(), mode_cast(prms))) -#endif - { - const int err = errno; - ec.assign(err, std::generic_category()); - } - } -#endif - } // namespace filesystem -} // namespace cpp17 - namespace llarp { namespace util diff --git a/llarp/util/logging.hpp b/llarp/util/logging.hpp new file mode 100644 index 000000000..9c9cd27c4 --- /dev/null +++ b/llarp/util/logging.hpp @@ -0,0 +1,102 @@ +#pragma once + +// Header for making actual log statements such as llarp::log::Info and so on work. + +#include +#include + +#include + +namespace llarp +{ + namespace log = oxen::log; +} + +// Not ready to pollute these deprecation warnings everywhere yet +#if 0 +#define LOKINET_LOG_DEPRECATED(Meth) \ + [[deprecated("Use formatted log::" #Meth "(cat, fmt, args...) instead")]] +#else +#define LOKINET_LOG_DEPRECATED(Meth) +#endif + +// Deprecated loggers (in the top-level llarp namespace): +namespace llarp +{ + namespace log_detail + { + inline log::CategoryLogger legacy_logger = log::Cat(""); + + template + struct concat_args_fmt_impl; + template + struct concat_args_fmt_impl> + { + constexpr static std::array format{(I % 2 == 0 ? '{' : '}')...}; + }; + template + constexpr std::string_view + concat_args_fmt() + { + return std::string_view{ + concat_args_fmt_impl>::format.data(), 2 * N}; + } + + template + struct LegacyLeveledLogger : log::detail::LeveledLogger + { + LegacyLeveledLogger( + T&&... args, const slns::source_location& location = slns::source_location::current()) + : log::detail::LeveledLogger::LeveledLogger{ + legacy_logger, concat_args_fmt(), std::forward(args)..., location} + {} + }; + } // namespace log_detail + + template + struct LOKINET_LOG_DEPRECATED(Trace) LogTrace + : log_detail::LegacyLeveledLogger + { + using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + }; + template + struct LOKINET_LOG_DEPRECATED(Debug) LogDebug + : log_detail::LegacyLeveledLogger + { + using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + }; + template + struct LOKINET_LOG_DEPRECATED(Info) LogInfo + : log_detail::LegacyLeveledLogger + { + using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + }; + template + struct LOKINET_LOG_DEPRECATED(Warning) LogWarn + : log_detail::LegacyLeveledLogger + { + using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + }; + template + struct LOKINET_LOG_DEPRECATED(Error) LogError + : log_detail::LegacyLeveledLogger + { + using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + }; + + template + LogTrace(T&&...) -> LogTrace; + + template + LogDebug(T&&...) -> LogDebug; + + template + LogInfo(T&&...) -> LogInfo; + + template + LogWarn(T&&...) -> LogWarn; + + template + LogError(T&&...) -> LogError; + +} // namespace llarp diff --git a/llarp/util/logging/android_logger.cpp b/llarp/util/logging/android_logger.cpp deleted file mode 100644 index ae4bdb793..000000000 --- a/llarp/util/logging/android_logger.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "android_logger.hpp" -#include "logger_internal.hpp" - -#include -namespace llarp -{ - void - AndroidLogStream::PreLog( - std::stringstream& ss, LogLevel lvl, std::string_view fname, int lineno, const std::string&) - const - { - switch (lvl) - { - case eLogNone: - return; - case eLogTrace: - ss << "[TRC] "; - break; - case eLogDebug: - ss << "[DBG] "; - break; - case eLogInfo: - ss << "[NFO] "; - break; - case eLogWarn: - ss << "[WRN] "; - break; - case eLogError: - ss << "[ERR] "; - break; - } - - ss << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno - << "\t"; - } - - void - AndroidLogStream::PostLog(std::stringstream&) const - {} - - void AndroidLogStream::Tick(llarp_time_t) - {} - - void - AndroidLogStream::Print(LogLevel lvl, std::string_view tag, const std::string& msg) - { - std::string str("lokinet|"); - str += tag; - switch (lvl) - { - case eLogTrace: - case eLogDebug: - __android_log_write(ANDROID_LOG_DEBUG, str.c_str(), msg.c_str()); - return; - case eLogInfo: - __android_log_write(ANDROID_LOG_INFO, str.c_str(), msg.c_str()); - return; - case eLogWarn: - __android_log_write(ANDROID_LOG_WARN, str.c_str(), msg.c_str()); - return; - case eLogError: - __android_log_write(ANDROID_LOG_ERROR, str.c_str(), msg.c_str()); - return; - default: - return; - } - - } // namespace llarp -} // namespace llarp diff --git a/llarp/util/logging/android_logger.hpp b/llarp/util/logging/android_logger.hpp deleted file mode 100644 index e42989910..000000000 --- a/llarp/util/logging/android_logger.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "logstream.hpp" - -#include - -namespace llarp -{ - struct AndroidLogStream : public ILogStream - { - void - PreLog( - std::stringstream& s, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const override; - - void - Print(LogLevel lvl, std::string_view filename, const std::string& msg) override; - - void - PostLog(std::stringstream&) const override; - - void Tick(llarp_time_t) override; - - void - ImmediateFlush() override{}; - }; -} // namespace llarp diff --git a/llarp/util/logging/buffer.cpp b/llarp/util/logging/buffer.cpp index 284bf8633..a3dfd347c 100644 --- a/llarp/util/logging/buffer.cpp +++ b/llarp/util/logging/buffer.cpp @@ -4,43 +4,42 @@ namespace llarp { - std::ostream& - operator<<(std::ostream& o, const buffer_printer& bp) + std::string + buffer_printer::ToString() const { - auto& b = bp.buf; - auto oldfill = o.fill(); - o.fill('0'); - o << "Buffer[" << b.size() << "/0x" << std::hex << b.size() << " bytes]:"; + auto& b = buf; + std::string out; + auto ins = std::back_inserter(out); + fmt::format_to(ins, "Buffer[{}/{:#x} bytes]:", b.size(), b.size()); + for (size_t i = 0; i < b.size(); i += 32) { - o << "\n" << std::setw(4) << i << " "; + fmt::format_to(ins, "\n{:04x} ", i); size_t stop = std::min(b.size(), i + 32); for (size_t j = 0; j < 32; j++) { auto k = i + j; if (j % 4 == 0) - o << ' '; - if (k >= stop) - o << " "; + out.push_back(' '); + if (j >= stop) + out.append(" "); else - o << std::setw(2) << std::to_integer(b[k]); + fmt::format_to(ins, "{:02x}", std::to_integer(b[k])); } - o << u8" ┃"; + out.append(u8" ┃"); for (size_t j = i; j < stop; j++) { auto c = std::to_integer(b[j]); if (c == 0x00) - o << u8"∅"; + out.append(u8"∅"); else if (c < 0x20 || c > 0x7e) - o << u8"·"; + out.append(u8"·"); else - o << c; + out.push_back(c); } - o << u8"┃"; + out.append(u8"┃"); } - o << std::dec; - o.fill(oldfill); - return o; + return out; } } // namespace llarp diff --git a/llarp/util/logging/buffer.hpp b/llarp/util/logging/buffer.hpp index e9cc2db75..c228927d2 100644 --- a/llarp/util/logging/buffer.hpp +++ b/llarp/util/logging/buffer.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -13,7 +14,9 @@ namespace llarp // visual representation of the data for logging purposes. Wraps the string data with a object // that prints the buffer format during output; use as: // - // out << buffer_printer(my_buffer); + // fmt::print("{}", buffer_printer(my_buffer)); + // + // or similarly in a log statement. // struct buffer_printer { @@ -48,7 +51,11 @@ namespace llarp explicit buffer_printer(const llarp_buffer_t& buf) : buffer_printer(std::basic_string_view{buf.base, buf.sz}) {} + + std::string + ToString() const; }; - std::ostream& - operator<<(std::ostream& o, const buffer_printer& bp); + + template <> + constexpr inline bool IsToStringFormattable = true; } // namespace llarp diff --git a/llarp/util/logging/callback_sink.hpp b/llarp/util/logging/callback_sink.hpp new file mode 100644 index 000000000..9b5538562 --- /dev/null +++ b/llarp/util/logging/callback_sink.hpp @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +namespace llarp::logging +{ + // Logger that calls a C function with the formatted log message + template + class CallbackSink : public spdlog::sinks::base_sink + { + private: + lokinet_logger_func log_; + lokinet_logger_sync sync_; + void* ctx_; + + public: + explicit CallbackSink( + lokinet_logger_func log, lokinet_logger_sync sync = nullptr, void* context = nullptr) + : log_{log}, sync_{sync}, ctx_{context} + {} + + protected: + void + sink_it_(const spdlog::details::log_msg& msg) override + { + if (!log_) + return; + spdlog::memory_buf_t formatted; + spdlog::sinks::base_sink::formatter_->format(msg, formatted); + log_(fmt::to_string(formatted).c_str(), ctx_); + } + + void + flush_() override + { + if (sync_) + sync_(ctx_); + } + }; + + // Convenience aliases with or without thread safety + using CallbackSink_mt = CallbackSink; + using CallbackSink_st = CallbackSink; + +} // namespace llarp::logging diff --git a/llarp/util/logging/file_logger.cpp b/llarp/util/logging/file_logger.cpp deleted file mode 100644 index c41d092e8..000000000 --- a/llarp/util/logging/file_logger.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include "file_logger.hpp" -#include "logger_internal.hpp" -#include - -#include - -namespace llarp -{ - void - FileLogStream::Flush(Lines_t* lines, FILE* const f) - { - bool wrote_stuff = false; - do - { - auto maybe_line = lines->tryPopFront(); - if (not maybe_line) - break; - if (fprintf(f, "%s\n", maybe_line->c_str()) >= 0) - wrote_stuff = true; - } while (true); - - if (wrote_stuff) - fflush(f); - } - - // namespace - FileLogStream::FileLogStream( - std::function disk, FILE* f, llarp_time_t flushInterval, bool closeFile) - : m_Lines(1024 * 8) - , m_Disk(std::move(disk)) - , m_File(f) - , m_FlushInterval(flushInterval) - , m_Close(closeFile) - { - m_Lines.enable(); - } - - FileLogStream::~FileLogStream() - { - m_Lines.disable(); - do - { - auto line = m_Lines.tryPopFront(); - if (not line) - break; - } while (true); - fflush(m_File); - if (m_Close) - fclose(m_File); - } - - bool - FileLogStream::ShouldFlush(llarp_time_t now) const - { - if (m_Lines.full()) - return true; - if (m_LastFlush >= now) - return false; - const auto dlt = now - m_LastFlush; - return dlt >= m_FlushInterval; - } - - void - FileLogStream::PreLog( - std::stringstream& ss, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const - { - ss << "[" << LogLevelToString(lvl) << "] "; - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno - << "\t"; - } - - void - FileLogStream::Print(LogLevel, std::string_view, const std::string& msg) - { - m_Lines.pushBack(msg); - } - - void - FileLogStream::AppendLog( - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename, - const std::string msg) - { - ILogStream::AppendLog(lvl, filename, lineno, nodename, msg); - Tick(llarp::time_now_ms()); - } - - void - FileLogStream::ImmediateFlush() - { - Flush(&m_Lines, m_File); - m_LastFlush = time_now_ms(); - } - - void - FileLogStream::Tick(llarp_time_t now) - { - if (ShouldFlush(now)) - FlushLinesToDisk(now); - } - - void - FileLogStream::FlushLinesToDisk(llarp_time_t now) - { - FILE* const f = m_File; - auto lines = &m_Lines; - m_Disk([f, lines]() { Flush(lines, f); }); - m_LastFlush = now; - } -} // namespace llarp diff --git a/llarp/util/logging/file_logger.hpp b/llarp/util/logging/file_logger.hpp deleted file mode 100644 index 07af96102..000000000 --- a/llarp/util/logging/file_logger.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include "logstream.hpp" - -#include -#include - -#include - -namespace llarp -{ - /// flushable file based log stream - struct FileLogStream : public ILogStream - { - using Work_t = std::function; - - FileLogStream( - std::function io, FILE* f, llarp_time_t flushInterval, bool closefile = true); - - ~FileLogStream() override; - - void - PreLog( - std::stringstream& out, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const override; - - void - Print(LogLevel, std::string_view filename, const std::string& msg) override; - - void - Tick(llarp_time_t now) override; - - void - PostLog(std::stringstream&) const override{}; - - void - AppendLog( - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename, - const std::string msg) override; - - virtual void - ImmediateFlush() override; - - using Lines_t = thread::Queue; - - protected: - Lines_t m_Lines; - - private: - static void - Flush(Lines_t* const, FILE* const); - - bool - ShouldFlush(llarp_time_t now) const; - - void - FlushLinesToDisk(llarp_time_t now); - - const std::function m_Disk; - FILE* const m_File; - const llarp_time_t m_FlushInterval; - llarp_time_t m_LastFlush = 0s; - const bool m_Close; - }; -} // namespace llarp diff --git a/llarp/util/logging/logger.cpp b/llarp/util/logging/logger.cpp deleted file mode 100644 index 3357ab291..000000000 --- a/llarp/util/logging/logger.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "logger.hpp" -#include "ostream_logger.hpp" -#include "logger_syslog.hpp" -#include "file_logger.hpp" -#if defined(_WIN32) -#include "win32_logger.hpp" -#endif -#if defined(ANDROID) -#include "android_logger.hpp" -#endif - -#include - -#include - -namespace llarp -{ -#if defined(_WIN32) - using Stream_t = Win32LogStream; -#define _LOGSTREAM_INIT std::cout -#else -#if defined(ANDROID) - using Stream_t = AndroidLogStream; -#define _LOGSTREAM_INIT -#else - using Stream_t = OStreamLogStream; -#define _LOGSTREAM_INIT true, std::cout -#endif -#endif - - LogType - LogTypeFromString(const std::string& str) - { - if (str == "unknown") - return LogType::Unknown; - else if (str == "file") - return LogType::File; - else if (str == "syslog") - return LogType::Syslog; - - return LogType::Unknown; - } - - LogContext::LogContext() : logStream{std::make_unique(_LOGSTREAM_INIT)} - {} - - LogContext& - LogContext::Instance() - { - static LogContext ctx; - return ctx; - } - - void - LogContext::DropToRuntimeLevel() - { - curLevel = runtimeLevel; - } - - void - LogContext::RevertRuntimeLevel() - { - curLevel = startupLevel; - } - - log_timestamp::log_timestamp() : log_timestamp("%c %Z") - {} - - log_timestamp::log_timestamp(const char* fmt) - : format{fmt}, now{llarp::time_now_ms()}, delta{llarp::uptime()} - {} - - void - SetLogLevel(LogLevel lvl) - { - LogContext::Instance().curLevel = lvl; - LogContext::Instance().runtimeLevel = lvl; - } - - LogLevel - GetLogLevel() - { - return LogContext::Instance().curLevel; - } - - void - LogContext::ImmediateFlush() - { - logStream->ImmediateFlush(); - } - - void - LogContext::Initialize( - LogLevel level, - LogType type, - const std::string& file, - const std::string& nickname, - std::function io) - { - SetLogLevel(level); - if (level == eLogTrace) - LogTrace("Set log level to trace."); - - nodeName = nickname; - - FILE* logfile = nullptr; - if (file == "stdout" or file == "-" or file.empty()) - { - logfile = stdout; - } - else if (type != LogType::Syslog) - { - logfile = ::fopen(file.c_str(), "a"); - if (not logfile) - { - throw std::runtime_error( - stringify("could not open logfile ", file, ", errno: ", strerror(errno))); - } - } - - switch (type) - { - case LogType::Unknown: - // tolerate as fallback to LogType::File - - case LogType::File: - if (logfile != stdout) - { - LogInfo("Switching logger to file ", file); - std::cout << std::flush; - - LogContext::Instance().logStream = - std::make_unique(io, logfile, 100ms, true); - } - else - { - LogInfo("Logger remains stdout"); - } - - break; - case LogType::Syslog: -#if defined(_WIN32) - throw std::runtime_error("syslog not supported on win32"); -#else - LogContext::Instance().logStream = std::make_unique(); -#endif - break; - } - } - - LogSilencer::LogSilencer() : LogSilencer(LogContext::Instance()) - {} - - LogSilencer::LogSilencer(LogContext& ctx) : parent(ctx), stream(std::move(ctx.logStream)) - {} - - LogSilencer::~LogSilencer() - { - parent.logStream = std::move(stream); - } - -} // namespace llarp diff --git a/llarp/util/logging/logger.hpp b/llarp/util/logging/logger.hpp deleted file mode 100644 index fd5b6ef60..000000000 --- a/llarp/util/logging/logger.hpp +++ /dev/null @@ -1,168 +0,0 @@ -#pragma once - -#include -#include -#include -#include "logstream.hpp" -#include "logger_internal.hpp" -#include "source_location.hpp" - -namespace llarp -{ - enum class LogType - { - Unknown = 0, - File, - Syslog, - }; - LogType - LogTypeFromString(const std::string&); - - struct LogContext - { - using IOFunc_t = std::function; - - LogContext(); - LogLevel curLevel = eLogInfo; - LogLevel startupLevel = eLogInfo; - LogLevel runtimeLevel = eLogWarn; - ILogStream_ptr logStream; - std::string nodeName = "lokinet"; - - static LogContext& - Instance(); - - void - DropToRuntimeLevel(); - - void - RevertRuntimeLevel(); - - /// A blocking call that will not return until any existing log functions have flushed. - /// Should only be called in rare circumstances, such as when the program is about to exit. - void - ImmediateFlush(); - - /// Initialize the logging system. - /// - /// @param level is the new log level (below which log statements will be ignored) - /// @param type is the type of logger to set up - /// @param file is the file to log to (relevant for types File and Json) - /// @param nickname is a tag to add to each log statement - /// @param io is a callable that queues work that does io, async - void - Initialize( - LogLevel level, - LogType type, - const std::string& file, - const std::string& nickname, - std::function io); - }; - - /// RAII type to turn logging off - /// logging is suppressed as long as the silencer is in scope - struct LogSilencer - { - LogSilencer(); - ~LogSilencer(); - explicit LogSilencer(LogContext& ctx); - - private: - LogContext& parent; - ILogStream_ptr stream; - }; - - void - SetLogLevel(LogLevel lvl); - - LogLevel - GetLogLevel(); - - namespace - { - /** internal */ - template - 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(args)...); - log.logStream->AppendLog( - lvl, - strip_prefix(location.file_name(), SOURCE_ROOT), - location.line(), - log.nodeName, - ss.str()); - } - } // namespace - - template - 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(args)...); -#endif - } - }; - - template - LogTrace(T&&...) -> LogTrace; - - template - struct LogDebug - { - LogDebug(T... args, const slns::source_location& location = slns::source_location::current()) - { - _log(eLogDebug, location, std::forward(args)...); - } - }; - - template - LogDebug(T&&...) -> LogDebug; - - template - struct LogInfo - { - LogInfo(T... args, const slns::source_location& location = slns::source_location::current()) - { - _log(eLogInfo, location, std::forward(args)...); - } - }; - - template - LogInfo(T&&...) -> LogInfo; - - template - struct LogWarn - { - LogWarn(T... args, const slns::source_location& location = slns::source_location::current()) - { - _log(eLogWarn, location, std::forward(args)...); - } - }; - - template - LogWarn(T&&...) -> LogWarn; - - template - struct LogError - { - LogError(T... args, const slns::source_location& location = slns::source_location::current()) - { - _log(eLogError, location, std::forward(args)...); - } - }; - - template - LogError(T&&...) -> LogError; - -} // namespace llarp diff --git a/llarp/util/logging/logger_internal.cpp b/llarp/util/logging/logger_internal.cpp deleted file mode 100644 index 2cff1a9a1..000000000 --- a/llarp/util/logging/logger_internal.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "logger_internal.hpp" - -#include - -namespace llarp -{ - std::ostream& - operator<<(std::ostream& out, const log_timestamp& ts) - { - std::chrono::time_point now{ - std::chrono::milliseconds{ts.now}}; - return date::operator<<(out, now) << " GMT [+" << ts.delta << "]"; - } -} // namespace llarp diff --git a/llarp/util/logging/logger_internal.hpp b/llarp/util/logging/logger_internal.hpp deleted file mode 100644 index 06f0ac9b9..000000000 --- a/llarp/util/logging/logger_internal.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -namespace llarp -{ - /** internal */ - - // true if T is the same as any of V... - template - constexpr bool is_same_any_v = (std::is_same_v || ...); - - template - void - LogAppend(std::ostringstream& ss, TArg&& arg, TArgs&&... args) noexcept - { - // If you are logging a char/unsigned char/uint8_t then promote it to an integer so that we - // print numeric values rather than std::ostream's default of printing it as a raw char. - using PlainT = std::remove_reference_t; - if constexpr (is_same_any_v) - ss << +std::forward(arg); // Promote to int - else if constexpr (std::is_same_v) - ss << std::to_integer(arg); - else - ss << std::forward(arg); - if constexpr (sizeof...(TArgs) > 0) - LogAppend(ss, std::forward(args)...); - } - - inline std::string - thread_id_string() - { - auto tid = std::this_thread::get_id(); - std::hash h; - uint16_t id = h(tid) % 1000; -#if defined(ANDROID) - char buff[8] = {0}; - snprintf(buff, sizeof(buff), "%u", id); - return buff; -#else - return std::to_string(id); -#endif - } - - struct log_timestamp - { - const char* format; - const Duration_t now; - const Duration_t delta; - - log_timestamp(); - - explicit log_timestamp(const char* fmt); - }; - - std::ostream& - operator<<(std::ostream& out, const log_timestamp& ts); - -} // namespace llarp diff --git a/llarp/util/logging/logger_syslog.hpp b/llarp/util/logging/logger_syslog.hpp deleted file mode 100644 index dee7523de..000000000 --- a/llarp/util/logging/logger_syslog.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "logstream.hpp" -#include - -namespace llarp -{ - struct SysLogStream : public ILogStream - { - void - PreLog( - std::stringstream& s, - LogLevel lvl, - std::string_view filename, - 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& ss) const override; - - virtual void - ImmediateFlush() override - {} - - void Tick(llarp_time_t) override - {} - }; -} // namespace llarp diff --git a/llarp/util/logging/loglevel.cpp b/llarp/util/logging/loglevel.cpp deleted file mode 100644 index 4faf02d19..000000000 --- a/llarp/util/logging/loglevel.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "loglevel.hpp" -#include -#include - -namespace llarp -{ - std::string - LogLevelToString(LogLevel lvl) - { - switch (lvl) - { - case eLogTrace: - return "TRC"; - case eLogDebug: - return "DBG"; - case eLogInfo: - return "NFO"; - case eLogWarn: - return "WRN"; - case eLogError: - return "ERR"; - default: - return "???"; - } - } - - std::string - LogLevelToName(LogLevel lvl) - { - switch (lvl) - { - case eLogTrace: - return "Trace"; - case eLogDebug: - return "Debug"; - case eLogInfo: - return "Info"; - case eLogWarn: - return "Warn"; - case eLogError: - return "Error"; - case eLogNone: - return "None"; - default: - return "???"; - } - } - - std::optional - LogLevelFromString(std::string level) - { - std::transform(level.begin(), level.end(), level.begin(), [](const unsigned char ch) -> char { - return std::tolower(ch); - }); - static const std::unordered_map levels = { - {"trace", eLogTrace}, - {"debug", eLogDebug}, - {"info", eLogInfo}, - {"warn", eLogWarn}, - {"error", eLogError}, - {"none", eLogNone}}; - - const auto itr = levels.find(level); - if (itr == levels.end()) - return {}; - return itr->second; - } -} // namespace llarp diff --git a/llarp/util/logging/loglevel.hpp b/llarp/util/logging/loglevel.hpp deleted file mode 100644 index adf99f313..000000000 --- a/llarp/util/logging/loglevel.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include -#include - -namespace llarp -{ - // probably will need to move out of llarp namespace for c api - enum LogLevel - { - eLogTrace, - eLogDebug, - eLogInfo, - eLogWarn, - eLogError, - eLogNone - }; - - std::string - LogLevelToString(LogLevel level); - - std::string - LogLevelToName(LogLevel lvl); - - std::optional - LogLevelFromString(std::string level); - -} // namespace llarp diff --git a/llarp/util/logging/logstream.hpp b/llarp/util/logging/logstream.hpp deleted file mode 100644 index d5e00d90d..000000000 --- a/llarp/util/logging/logstream.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once -#include "loglevel.hpp" - -#include - -#include -#include -#include -#include - -namespace llarp -{ - /// logger stream interface - struct ILogStream - { - virtual ~ILogStream() = default; - - virtual void - PreLog( - std::stringstream& out, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const = 0; - - virtual void - Print(LogLevel lvl, std::string_view filename, const std::string& msg) = 0; - - virtual void - PostLog(std::stringstream& out) const = 0; - - virtual void - AppendLog( - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename, - const std::string msg) - { - std::stringstream ss; - PreLog(ss, lvl, filename, lineno, nodename); - ss << msg; - PostLog(ss); - Print(lvl, filename, ss.str()); - } - - /// A blocking call to flush to disk. Should only be called in rare circumstances. - virtual void - ImmediateFlush() = 0; - - /// called every end of event loop tick - virtual void - Tick(llarp_time_t now) = 0; - }; - - using ILogStream_ptr = std::unique_ptr; - -} // namespace llarp diff --git a/llarp/util/logging/ostream_logger.cpp b/llarp/util/logging/ostream_logger.cpp deleted file mode 100644 index 15078e870..000000000 --- a/llarp/util/logging/ostream_logger.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "ostream_logger.hpp" -#include "logger_internal.hpp" - -namespace llarp -{ - OStreamLogStream::OStreamLogStream(bool withColours, std::ostream& out) - : m_withColours(withColours), m_Out(out) - {} - - void - OStreamLogStream::PreLog( - std::stringstream& ss, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const - { - if (m_withColours) - { - switch (lvl) - { - case eLogNone: - return; - case eLogTrace: - case eLogDebug: - ss << (char)27 << "[0m"; - break; - case eLogInfo: - ss << (char)27 << "[1m"; - break; - case eLogWarn: - ss << (char)27 << "[1;33m"; - break; - case eLogError: - ss << (char)27 << "[1;31m"; - break; - } - } - ss << "[" << LogLevelToString(lvl) << "] "; - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno - << "\t"; - } - - void - OStreamLogStream::PostLog(std::stringstream& ss) const - { - if (m_withColours) - ss << (char)27 << "[0;0m"; - ss << std::endl; - } - - void - OStreamLogStream::Print(LogLevel, std::string_view, const std::string& msg) - { - m_Out << msg << std::flush; - } - - void - OStreamLogStream::ImmediateFlush() - { - m_Out << std::flush; - } - -} // namespace llarp diff --git a/llarp/util/logging/ostream_logger.hpp b/llarp/util/logging/ostream_logger.hpp deleted file mode 100644 index 5961447e4..000000000 --- a/llarp/util/logging/ostream_logger.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "logstream.hpp" -#include - -namespace llarp -{ - struct OStreamLogStream : public ILogStream - { - OStreamLogStream(bool withColours, std::ostream& out); - - ~OStreamLogStream() override = default; - - void - PreLog( - std::stringstream& s, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const override; - - virtual void - Print(LogLevel lvl, std::string_view tag, const std::string& msg) override; - - void - PostLog(std::stringstream& ss) const override; - - virtual void - ImmediateFlush() override; - - void Tick(llarp_time_t) override - {} - - private: - bool m_withColours; - std::ostream& m_Out; - }; -} // namespace llarp diff --git a/llarp/util/logging/source_location.hpp b/llarp/util/logging/source_location.hpp deleted file mode 100644 index 39b707a30..000000000 --- a/llarp/util/logging/source_location.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#ifdef __cpp_lib_source_location -#include -namespace slns = std; -#else -#include -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 diff --git a/llarp/util/logging/syslog_logger.cpp b/llarp/util/logging/syslog_logger.cpp deleted file mode 100644 index feb124806..000000000 --- a/llarp/util/logging/syslog_logger.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _WIN32 -#include "logger_syslog.hpp" - -#include "logger_internal.hpp" - -#include -namespace llarp -{ - void - SysLogStream::PreLog( - std::stringstream& ss, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const - { - ss << "[" << LogLevelToString(lvl) << "] "; - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno - << "\t"; - } - - void - SysLogStream::Print(LogLevel lvl, std::string_view, const std::string& msg) - { - switch (lvl) - { - case eLogNone: - return; - case eLogTrace: - case eLogDebug: - ::syslog(LOG_DEBUG, "%s", msg.c_str()); - return; - case eLogInfo: - ::syslog(LOG_INFO, "%s", msg.c_str()); - return; - case eLogWarn: - ::syslog(LOG_WARNING, "%s", msg.c_str()); - return; - case eLogError: - ::syslog(LOG_ERR, "%s", msg.c_str()); - return; - } - } - - void - SysLogStream::PostLog(std::stringstream&) const - {} - -} // namespace llarp -#endif diff --git a/llarp/util/logging/win32_logger.cpp b/llarp/util/logging/win32_logger.cpp deleted file mode 100644 index 0792f8d92..000000000 --- a/llarp/util/logging/win32_logger.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "win32_logger.hpp" -#include "logger_internal.hpp" - -static CONSOLE_SCREEN_BUFFER_INFO consoleInfo; -static short old_attrs; - -namespace llarp -{ - Win32LogStream::Win32LogStream(std::ostream& out) : OStreamLogStream(true, out), m_Out(out) - { - // Attempt to use ANSI escapes directly - // if the modern console is active. - DWORD mode_flags; - - GetConsoleMode(fd1, &mode_flags); - // since release SDKs don't have ANSI escape support yet - // we get all or nothing: if we can't get it, then we wouldn't - // be able to get any of them individually - mode_flags |= 0x0004 | 0x0008; - BOOL t = SetConsoleMode(fd1, mode_flags); - if (!t) - this->isConsoleModern = false; // fall back to setting colours manually - } - - void - Win32LogStream::PreLog( - std::stringstream& ss, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const - { - if (!isConsoleModern) - { - switch (lvl) - { - case eLogNone: - break; - case eLogTrace: - ss << "[TRC] "; - break; - case eLogDebug: - ss << "[DBG] "; - break; - case eLogInfo: - ss << "[NFO] "; - break; - case eLogWarn: - ss << "[WRN] "; - break; - case eLogError: - ss << "[ERR] "; - break; - } - ss << "[" << nodename << "]" - << "(" << thread_id_string() << ") " << log_timestamp() << " " << filename << ":" << lineno - << "\t"; - } - else - OStreamLogStream::PreLog(ss, lvl, filename, lineno, nodename); - } - - void - Win32LogStream::PostLog(std::stringstream& ss) const - { - if (!isConsoleModern) - ss << std::endl; - else - OStreamLogStream::PostLog(ss); - } - - void - Win32LogStream::Print(LogLevel lvl, std::string_view, const std::string& msg) - { - if (!isConsoleModern) - { - GetConsoleScreenBufferInfo(fd1, &consoleInfo); - old_attrs = consoleInfo.wAttributes; - switch (lvl) - { - case eLogNone: - break; - case eLogTrace: - case eLogDebug: - SetConsoleTextAttribute( - fd1, - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); // low white on black - break; - case eLogInfo: - SetConsoleTextAttribute( - fd1, - FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN - | FOREGROUND_BLUE); // high white on black - break; - case eLogWarn: - SetConsoleTextAttribute( - fd1, - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); // bright yellow - break; - case eLogError: - SetConsoleTextAttribute(fd1, FOREGROUND_RED | FOREGROUND_INTENSITY); // bright red - break; - } - } - - m_Out << msg << std::flush; - - if (!isConsoleModern) - { - SetConsoleTextAttribute(fd1, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - } - } - -} // namespace llarp diff --git a/llarp/util/logging/win32_logger.hpp b/llarp/util/logging/win32_logger.hpp deleted file mode 100644 index 2be5e5609..000000000 --- a/llarp/util/logging/win32_logger.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#if defined(_WIN32) -#include "ostream_logger.hpp" -#define VC_EXTRALEAN -#include - -namespace llarp -{ - struct Win32LogStream : public OStreamLogStream - { - Win32LogStream(std::ostream& out); - - void - PreLog( - std::stringstream& s, - LogLevel lvl, - std::string_view filename, - int lineno, - const std::string& nodename) const override; - - void - PostLog(std::stringstream& s) const override; - - void Tick(llarp_time_t) override{}; - - void - Print(LogLevel lvl, std::string_view, const std::string& msg) override; - - private: - std::ostream& m_Out; - - bool isConsoleModern = true; // qol fix so oldfag clients don't see ugly escapes - - HANDLE fd1 = GetStdHandle(STD_OUTPUT_HANDLE); - }; -} // namespace llarp -#endif diff --git a/llarp/util/str.hpp b/llarp/util/str.hpp index 1e564b6cf..ce330dac1 100644 --- a/llarp/util/str.hpp +++ b/llarp/util/str.hpp @@ -26,26 +26,6 @@ namespace llarp [[nodiscard]] std::string_view TrimWhitespace(std::string_view str); - template - std::string - stringify(T&&... stuff) - { - std::ostringstream o; - (o << ... << std::forward(stuff)); - return o.str(); - } - - /// util for constructing an exception with a message constructed from a set of whatever passed - /// into stringify - /// E must be derived from std::exception here - template - E - make_exception(T&&... stuff) - { - static_assert(std::is_base_of_v); - return E{stringify(std::forward(stuff)...)}; - } - using namespace std::literals; /// Returns true if the first string is equal to the second string, compared case-insensitively. @@ -68,21 +48,21 @@ namespace llarp } /// Returns true if the first argument begins with the second argument - inline bool + inline constexpr bool starts_with(std::string_view str, std::string_view prefix) { return str.substr(0, prefix.size()) == prefix; } /// Returns true if the first argument ends with the second argument - inline bool + inline constexpr bool ends_with(std::string_view str, std::string_view suffix) { 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 + inline constexpr std::string_view strip_prefix(std::string_view str, std::string_view prefix) { if (starts_with(str, prefix)) diff --git a/llarp/util/thread/queue_manager.hpp b/llarp/util/thread/queue_manager.hpp index 9761b1012..f202b4ad9 100644 --- a/llarp/util/thread/queue_manager.hpp +++ b/llarp/util/thread/queue_manager.hpp @@ -28,26 +28,22 @@ namespace llarp QueueFull }; - inline std::ostream& - operator<<(std::ostream& os, QueueReturn val) + constexpr std::string_view + ToString(QueueReturn val) { + using namespace std::literals; switch (val) { case QueueReturn::Success: - os << "Success"; - break; + return "Success"sv; case QueueReturn::QueueDisabled: - os << "QueueDisabled"; - break; + return "QueueDisabled"sv; case QueueReturn::QueueEmpty: - os << "QueueEmpty"; - break; + return "QueueEmpty"sv; case QueueReturn::QueueFull: - os << "QueueFull"; - break; + return "QueueFull"sv; } - - return os; + return "(queue-return-unknown)"sv; } class QueueManager diff --git a/llarp/util/thread/threading.cpp b/llarp/util/thread/threading.cpp index 826177ef9..84710e9d0 100644 --- a/llarp/util/thread/threading.cpp +++ b/llarp/util/thread/threading.cpp @@ -1,6 +1,6 @@ #include "threading.hpp" -#include +#include #include #ifdef POSIX diff --git a/llarp/util/time.cpp b/llarp/util/time.cpp index cd6a3b4fd..46d9a5fa4 100644 --- a/llarp/util/time.cpp +++ b/llarp/util/time.cpp @@ -49,40 +49,4 @@ namespace llarp { return ToMS(t); } - - std::ostream& - operator<<(std::ostream& out, const Duration_t& t) - { - std::chrono::milliseconds amount{ToMS(t)}; - auto h = std::chrono::duration_cast(amount); - amount -= h; - auto m = std::chrono::duration_cast(amount); - amount -= m; - auto s = std::chrono::duration_cast(amount); - amount -= s; - auto ms = amount; - auto old_fill = out.fill('0'); - if (h > 0h) - { - out << h.count() << 'h'; - out.width(2); // 0-fill minutes if we have hours - } - if (h > 0h || m > 0min) - { - out << m.count() << 'm'; - out.width(2); // 0-fill seconds if we have minutes - } - out << s.count() << '.'; - out.width(3); - out << ms.count(); - out.fill(old_fill); - return out << "s"; - } - - std::ostream& - operator<<(std::ostream& out, const TimePoint_t& tp) - { - auto t = TimePoint_t::clock::to_time_t(tp); - return out << std::put_time(std::localtime(&t), "%c %Z"); - } } // namespace llarp diff --git a/llarp/util/time.hpp b/llarp/util/time.hpp index abd725f05..fbf999773 100644 --- a/llarp/util/time.hpp +++ b/llarp/util/time.hpp @@ -3,6 +3,8 @@ #include "types.hpp" #include #include +#include +#include using namespace std::chrono_literals; @@ -20,42 +22,72 @@ namespace llarp uint64_t ToMS(Duration_t duration); - std::ostream& - operator<<(std::ostream& out, const Duration_t& t); - nlohmann::json to_json(const Duration_t& t); - std::ostream& - operator<<(std::ostream& out, const TimePoint_t& t); - template struct time_delta { const TimePoint_t at; + }; +} // namespace llarp - std::ostream& - operator()(std::ostream& out) const +namespace fmt +{ + template + struct formatter> : formatter + { + template + auto + format(const llarp::time_delta& td, FormatContext& ctx) { - const auto dlt = std::chrono::duration_cast(TimePoint_t::clock::now() - at); + const auto dlt = + std::chrono::duration_cast(llarp::TimePoint_t::clock::now() - td.at); + using Parent = formatter; if (dlt > 0s) - return out << std::chrono::duration_cast(dlt) << " ago "; - else if (dlt < 0s) - return out << "in " << std::chrono::duration_cast(-dlt); - else - return out << "now"; + return Parent::format(fmt::format("{} ago", dlt), ctx); + if (dlt < 0s) + return Parent::format(fmt::format("in {}", -dlt), ctx); + return Parent::format("now", ctx); } }; - inline std::ostream& - operator<<(std::ostream& out, const time_delta& td) + template <> + struct formatter : formatter { - return td(out); - } + template + auto + format(llarp::Duration_t elapsed, FormatContext& ctx) + { + bool neg = elapsed < 0s; + if (neg) + elapsed = -elapsed; + const auto hours = std::chrono::duration_cast(elapsed).count(); + const auto mins = (std::chrono::duration_cast(elapsed) % 1h).count(); + const auto secs = (std::chrono::duration_cast(elapsed) % 1min).count(); + const auto ms = (std::chrono::duration_cast(elapsed) % 1s).count(); + return formatter::format( + fmt::format( + elapsed >= 1h ? "{0}{1:d}h{2:02d}m{3:02d}.{4:03d}s" + : elapsed >= 1min ? "{0}{2:d}m{3:02d}.{4:03d}s" + : "{0}{3:d}.{4:03d}s", + neg ? "-" : "", + hours, + mins, + secs, + ms), + ctx); + } + }; - inline std::ostream& - operator<<(std::ostream& out, const time_delta& td) + template <> + struct formatter : formatter { - return td(out); - } -} // namespace llarp + template + auto + format(const llarp::TimePoint_t& tp, FormatContext& ctx) + { + return formatter::format(fmt::format("{:%c %Z}", tp), ctx); + } + }; +} // namespace fmt From c82ade2d81b1d3f63ecf906d56e8941e47f41d46 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Mon, 18 Jul 2022 12:59:13 -0300 Subject: [PATCH 018/298] Make test code work with new logging --- llarp/router/router.cpp | 12 +++-- llarp/util/logging.hpp | 1 + test/CMakeLists.txt | 1 - test/check_main.cpp | 4 +- test/crypto/test_llarp_crypto_types.cpp | 4 ++ test/net/test_sock_addr.cpp | 24 ++++----- test/peerstats/test_peer_db.cpp | 8 +-- test/regress/2020-06-08-key-backup-bug.cpp | 1 - test/router/test_llarp_router_version.cpp | 3 -- test/service/test_llarp_service_identity.cpp | 1 - test/test_llarp_router_contact.cpp | 1 + test/util/test_llarp_util_aligned.cpp | 15 +++--- test/util/test_llarp_util_log_level.cpp | 56 +++++++++----------- 13 files changed, 61 insertions(+), 70 deletions(-) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index c59e8aea0..c74a25b5e 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -801,7 +801,8 @@ namespace llarp || conf.logging.m_logFile.empty())) log_type = log::Type::Print; - log::reset_level(conf.logging.m_logLevel); + if (log::get_level_default() != log::Level::off) + log::reset_level(conf.logging.m_logLevel); log::add_sink(log_type, conf.logging.m_logFile); return true; @@ -1419,7 +1420,8 @@ namespace llarp } }); } - log::reset_level(log::Level::warn); + if (log::get_level_default() != log::Level::off) + log::reset_level(log::Level::warn); return _running; } @@ -1468,7 +1470,8 @@ namespace llarp return; _stopping.store(true); - log::reset_level(log::Level::info); + if (log::get_level_default() != log::Level::off) + log::reset_level(log::Level::info); LogWarn("stopping router hard"); #if defined(WITH_SYSTEMD) sd_notify(0, "STOPPING=1\nSTATUS=Shutting down HARD"); @@ -1488,7 +1491,8 @@ namespace llarp return; _stopping.store(true); - log::reset_level(log::Level::info); + if (log::get_level_default() != log::Level::off) + log::reset_level(log::Level::info); LogInfo("stopping router"); #if defined(WITH_SYSTEMD) sd_notify(0, "STOPPING=1\nSTATUS=Shutting down"); diff --git a/llarp/util/logging.hpp b/llarp/util/logging.hpp index 9c9cd27c4..d549dcb8c 100644 --- a/llarp/util/logging.hpp +++ b/llarp/util/logging.hpp @@ -6,6 +6,7 @@ #include #include +#include "oxen/log/internal.hpp" namespace llarp { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8ac70868a..c19d82ac4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -52,7 +52,6 @@ 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) diff --git a/test/check_main.cpp b/test/check_main.cpp index 011ced716..e98bdcbfb 100644 --- a/test/check_main.cpp +++ b/test/check_main.cpp @@ -1,7 +1,7 @@ #define CATCH_CONFIG_RUNNER #include -#include +#include #ifdef _WIN32 #include @@ -23,7 +23,7 @@ startWinsock() int main(int argc, char* argv[]) { - llarp::LogSilencer shutup{}; + llarp::log::reset_level(llarp::log::Level::off); #ifdef _WIN32 if (startWinsock()) diff --git a/test/crypto/test_llarp_crypto_types.cpp b/test/crypto/test_llarp_crypto_types.cpp index 0110fa216..8477352f7 100644 --- a/test/crypto/test_llarp_crypto_types.cpp +++ b/test/crypto/test_llarp_crypto_types.cpp @@ -6,6 +6,10 @@ #include #include +extern "C" { +#include +} + // This used to be implied via the headers above *shrug* #ifdef _WIN32 #include diff --git a/test/net/test_sock_addr.cpp b/test/net/test_sock_addr.cpp index c0b666745..9d13b48a4 100644 --- a/test/net/test_sock_addr.cpp +++ b/test/net/test_sock_addr.cpp @@ -1,14 +1,14 @@ #include #include #include -#include +#include #include TEST_CASE("SockAddr from IPv4", "[SockAddr]") { llarp::SockAddr addr(1, 2, 3, 4); - CHECK(addr.toString() == "1.2.3.4:0"); + CHECK(addr.ToString() == "1.2.3.4:0"); } TEST_CASE("SockAddr test port", "[SockAddr]") @@ -22,16 +22,16 @@ TEST_CASE("SockAddr fromString", "[SockAddr]") { llarp::SockAddr addr; CHECK_NOTHROW(addr.fromString("1.2.3.4")); - CHECK(addr.toString() == "1.2.3.4:0"); + CHECK(addr.ToString() == "1.2.3.4:0"); - CHECK(llarp::SockAddr("1.3.5.7").toString() == "1.3.5.7:0"); + CHECK(llarp::SockAddr("1.3.5.7").ToString() == "1.3.5.7:0"); - CHECK(llarp::SockAddr("0.0.0.0").toString() == "0.0.0.0:0"); - CHECK(llarp::SockAddr("0.0.0.0:0").toString() == "0.0.0.0:0"); - CHECK(llarp::SockAddr("255.255.255.255").toString() == "255.255.255.255:0"); - CHECK(llarp::SockAddr("255.255.255.255:255").toString() == "255.255.255.255:255"); - CHECK(llarp::SockAddr("255.255.255.255:65535").toString() == "255.255.255.255:65535"); - CHECK(llarp::SockAddr("5.6.7.8", llarp::huint16_t{5678}).toString() == "5.6.7.8:5678"); + CHECK(llarp::SockAddr("0.0.0.0").ToString() == "0.0.0.0:0"); + CHECK(llarp::SockAddr("0.0.0.0:0").ToString() == "0.0.0.0:0"); + CHECK(llarp::SockAddr("255.255.255.255").ToString() == "255.255.255.255:0"); + CHECK(llarp::SockAddr("255.255.255.255:255").ToString() == "255.255.255.255:255"); + CHECK(llarp::SockAddr("255.255.255.255:65535").ToString() == "255.255.255.255:65535"); + CHECK(llarp::SockAddr("5.6.7.8", llarp::huint16_t{5678}).ToString() == "5.6.7.8:5678"); CHECK_THROWS_WITH(llarp::SockAddr("abcd"), "abcd is not a valid IPv4 address"); @@ -79,7 +79,7 @@ TEST_CASE("SockAddr from sockaddr_in", "[SockAddr]") llarp::SockAddr addr(sin4); - CHECK(addr.toString() == "127.0.0.1:1234"); + CHECK(addr.ToString() == "127.0.0.1:1234"); } TEST_CASE("SockAddr from sockaddr_in6", "[SockAddr]") @@ -93,5 +93,5 @@ TEST_CASE("SockAddr from sockaddr_in6", "[SockAddr]") llarp::SockAddr addr(sin6); - CHECK(addr.toString() == "127.0.0.1:53"); + CHECK(addr.ToString() == "127.0.0.1:53"); } diff --git a/test/peerstats/test_peer_db.cpp b/test/peerstats/test_peer_db.cpp index 3a70d8411..52889514c 100644 --- a/test/peerstats/test_peer_db.cpp +++ b/test/peerstats/test_peer_db.cpp @@ -5,7 +5,7 @@ #include #include "peerstats/types.hpp" #include "router_contact.hpp" -#include "util/logging/logger.hpp" +#include "util/logging.hpp" #include "util/time.hpp" TEST_CASE("Test PeerDb PeerStats memory storage", "[PeerDb]") @@ -41,7 +41,6 @@ TEST_CASE("Test PeerDb flush before load", "[PeerDb]") TEST_CASE("Test PeerDb load twice", "[PeerDb]") { - llarp::LogSilencer shutup; llarp::PeerDb db; CHECK_NOTHROW(db.loadDatabase(std::nullopt)); CHECK_THROWS_WITH(db.loadDatabase(std::nullopt), "Reloading database not supported"); @@ -49,7 +48,6 @@ TEST_CASE("Test PeerDb load twice", "[PeerDb]") TEST_CASE("Test PeerDb nukes stats on load", "[PeerDb]") { - llarp::LogSilencer shutup; const llarp::RouterID id = llarp::test::makeBuf(0x01); llarp::PeerDb db; @@ -67,7 +65,6 @@ TEST_CASE("Test PeerDb nukes stats on load", "[PeerDb]") TEST_CASE("Test PeerDb file-backed database reloads properly", "[PeerDb]") { - llarp::LogSilencer shutup; const std::string filename = "/tmp/peerdb_test_tmp2.db.sqlite"; const llarp::RouterID id = llarp::test::makeBuf(0x02); @@ -97,7 +94,6 @@ TEST_CASE("Test PeerDb file-backed database reloads properly", "[PeerDb]") TEST_CASE("Test PeerDb modifyPeerStats", "[PeerDb]") { - llarp::LogSilencer shutup; const llarp::RouterID id = llarp::test::makeBuf(0xF2); int numTimesCalled = 0; @@ -122,7 +118,6 @@ TEST_CASE("Test PeerDb modifyPeerStats", "[PeerDb]") TEST_CASE("Test PeerDb handleGossipedRC", "[PeerDb]") { - llarp::LogSilencer shutup; const llarp::RouterID id = llarp::test::makeBuf(0xCA); auto rcLifetime = llarp::RouterContact::Lifetime; @@ -162,7 +157,6 @@ TEST_CASE("Test PeerDb handleGossipedRC", "[PeerDb]") TEST_CASE("Test PeerDb handleGossipedRC expiry calcs", "[PeerDb]") { - llarp::LogSilencer shutup; const llarp::RouterID id = llarp::test::makeBuf(0xF9); // see comments in peer_db.cpp above PeerDb::handleGossipedRC() for some context around these diff --git a/test/regress/2020-06-08-key-backup-bug.cpp b/test/regress/2020-06-08-key-backup-bug.cpp index e4ebfaa97..669c1aca8 100644 --- a/test/regress/2020-06-08-key-backup-bug.cpp +++ b/test/regress/2020-06-08-key-backup-bug.cpp @@ -27,7 +27,6 @@ make_context(std::optional keyfile) TEST_CASE("key backup bug regression test", "[regress]") { // kill logging, this code is noisy - llarp::LogSilencer shutup; // test 2 explicitly provided keyfiles, empty keyfile and no keyfile for (std::optional path : {std::optional{"regress-1.private"}, std::optional{"regress-2.private"}, diff --git a/test/router/test_llarp_router_version.cpp b/test/router/test_llarp_router_version.cpp index 57e436347..260a16198 100644 --- a/test/router/test_llarp_router_version.cpp +++ b/test/router/test_llarp_router_version.cpp @@ -56,9 +56,6 @@ TEST_CASE("BEncode", "[RouterVersion]") CHECK(v1235.BEncode(&buf)); - std::string s((const char*)buf.begin(), (buf.end() - buf.begin())); - llarp::LogInfo("bencoded: ", buf.begin()); - CHECK_THAT((const char*)buf.begin(), Equals("li5ei1ei2ei3ee")); } diff --git a/test/service/test_llarp_service_identity.cpp b/test/service/test_llarp_service_identity.cpp index dc271fcd5..f375ebc6b 100644 --- a/test/service/test_llarp_service_identity.cpp +++ b/test/service/test_llarp_service_identity.cpp @@ -203,7 +203,6 @@ TEST_CASE("Test signing with derived key", "[crypto]") TEST_CASE("Test sign and encrypt introset", "[crypto]") { - llarp::LogSilencer shutup; CryptoManager manager(new sodium::CryptoLibSodium()); service::Identity ident; diff --git a/test/test_llarp_router_contact.cpp b/test/test_llarp_router_contact.cpp index 4f3f6afaa..eac96f332 100644 --- a/test/test_llarp_router_contact.cpp +++ b/test/test_llarp_router_contact.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace { diff --git a/test/util/test_llarp_util_aligned.cpp b/test/util/test_llarp_util_aligned.cpp index 8cda24eff..970a676d5 100644 --- a/test/util/test_llarp_util_aligned.cpp +++ b/test/util/test_llarp_util_aligned.cpp @@ -66,20 +66,17 @@ TEMPLATE_LIST_TEST_CASE("AlignedBuffer", "[AlignedBuffer]", TestSizes) CHECK_FALSE(d.IsZero()); } - SECTION("StreamOut") + SECTION("FmtOut") { - std::stringstream stream; + std::string out; + out = fmt::format("{}", b); - stream << b; - - CHECK(stream.str() == std::string(TestType::value * 2, '0')); - - stream.str(""); + CHECK(out == std::string(TestType::value * 2, '0')); b.Fill(255); - stream << b; + out = fmt::format("{}", b); - CHECK(stream.str() == std::string(TestType::value * 2, 'f')); + CHECK(out == std::string(TestType::value * 2, 'f')); } SECTION("BitwiseNot") diff --git a/test/util/test_llarp_util_log_level.cpp b/test/util/test_llarp_util_log_level.cpp index b69929a7f..7a67d9419 100644 --- a/test/util/test_llarp_util_log_level.cpp +++ b/test/util/test_llarp_util_log_level.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include #include using TestString = std::string; @@ -8,7 +7,7 @@ using TestString = std::string; struct TestParseLog { TestString input; - std::optional level; + std::optional level; }; std::vector testParseLog{// bad cases @@ -16,41 +15,38 @@ std::vector testParseLog{// bad cases {"BOGUS", {}}, {"", {}}, {" ", {}}, + {"infogarbage", {}}, + {"notcritical", {}}, // good cases - {"info", llarp::eLogInfo}, - {"infO", llarp::eLogInfo}, - {"iNfO", llarp::eLogInfo}, - {"InfO", llarp::eLogInfo}, - {"INFO", llarp::eLogInfo}, - {"debug", llarp::eLogDebug}, - {"warn", llarp::eLogWarn}, - {"error", llarp::eLogError}, - {"none", llarp::eLogNone}}; + {"info", llarp::log::Level::info}, + {"infO", llarp::log::Level::info}, + {"iNfO", llarp::log::Level::info}, + {"InfO", llarp::log::Level::info}, + {"INFO", llarp::log::Level::info}, + {"trace", llarp::log::Level::trace}, + {"debug", llarp::log::Level::debug}, + {"warn", llarp::log::Level::warn}, + {"warning", llarp::log::Level::warn}, + {"error", llarp::log::Level::err}, + {"err", llarp::log::Level::err}, + {"Critical", llarp::log::Level::critical}, + {"off", llarp::log::Level::off}, + {"none", llarp::log::Level::off}}; TEST_CASE("parseLevel") { const auto data = GENERATE(from_range(testParseLog)); - const auto maybe = llarp::LogLevelFromString(data.input); + const auto maybe = llarp::log::level_from_string(data.input); CHECK(maybe == data.level); } -TEST_CASE("TestLogLevelToName") -{ - CHECK("Trace" == LogLevelToName(llarp::eLogTrace)); - CHECK("Debug" == LogLevelToName(llarp::eLogDebug)); - CHECK("Info" == LogLevelToName(llarp::eLogInfo)); - CHECK("Warn" == LogLevelToName(llarp::eLogWarn)); - CHECK("Error" == LogLevelToName(llarp::eLogError)); - CHECK("None" == LogLevelToName(llarp::eLogNone)); - CHECK("???" == LogLevelToName((llarp::LogLevel)99999)); -} - TEST_CASE("TestLogLevelToString") { - CHECK("TRC" == LogLevelToString(llarp::eLogTrace)); - CHECK("DBG" == LogLevelToString(llarp::eLogDebug)); - CHECK("NFO" == LogLevelToString(llarp::eLogInfo)); - CHECK("WRN" == LogLevelToString(llarp::eLogWarn)); - CHECK("ERR" == LogLevelToString(llarp::eLogError)); - CHECK("???" == LogLevelToString(llarp::eLogNone)); + CHECK("trace" == llarp::log::to_string(llarp::log::Level::trace)); + CHECK("debug" == llarp::log::to_string(llarp::log::Level::debug)); + CHECK("info" == llarp::log::to_string(llarp::log::Level::info)); + CHECK("warning" == llarp::log::to_string(llarp::log::Level::warn)); + CHECK("error" == llarp::log::to_string(llarp::log::Level::err)); + CHECK("critical" == llarp::log::to_string(llarp::log::Level::critical)); + CHECK("off" == llarp::log::to_string(llarp::log::Level::off)); } From 2f9e182b20addad728fadd9f7507807d63d63923 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Mon, 18 Jul 2022 13:07:33 -0300 Subject: [PATCH 019/298] Avoid ctor inheritance to make diagnostics better Using constructor inheritance DRYs the code, but unfortunately confuses GCC as to where the proper "required from here" location is, which makes debugging formatting errors very difficult. Avoid it (and update oxen-logging to avoid it there as well). --- external/oxen-logging | 2 +- llarp/util/logging.hpp | 75 ++++++++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/external/oxen-logging b/external/oxen-logging index 0fc1b3528..9d65a01ca 160000 --- a/external/oxen-logging +++ b/external/oxen-logging @@ -1 +1 @@ -Subproject commit 0fc1b3528a52475c4007d734a7861faa2212fe75 +Subproject commit 9d65a01ca73a944cd22e3a2966da2eaa76296456 diff --git a/llarp/util/logging.hpp b/llarp/util/logging.hpp index d549dcb8c..7d1407390 100644 --- a/llarp/util/logging.hpp +++ b/llarp/util/logging.hpp @@ -42,47 +42,72 @@ namespace llarp return std::string_view{ concat_args_fmt_impl>::format.data(), 2 * N}; } - - template - struct LegacyLeveledLogger : log::detail::LeveledLogger - { - LegacyLeveledLogger( - T&&... args, const slns::source_location& location = slns::source_location::current()) - : log::detail::LeveledLogger::LeveledLogger{ - legacy_logger, concat_args_fmt(), std::forward(args)..., location} - {} - }; } // namespace log_detail template - struct LOKINET_LOG_DEPRECATED(Trace) LogTrace - : log_detail::LegacyLeveledLogger + struct LOKINET_LOG_DEPRECATED(Trace) LogTrace : log::trace { - using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + LogTrace( + T&&... args, + const log::slns::source_location& location = log::slns::source_location::current()) + : log::trace::trace{ + log_detail::legacy_logger, + log_detail::concat_args_fmt(), + std::forward(args)..., + location} + {} }; template - struct LOKINET_LOG_DEPRECATED(Debug) LogDebug - : log_detail::LegacyLeveledLogger + struct LOKINET_LOG_DEPRECATED(Debug) LogDebug : log::debug { - using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + LogDebug( + T&&... args, + const log::slns::source_location& location = log::slns::source_location::current()) + : log::debug::debug{ + log_detail::legacy_logger, + log_detail::concat_args_fmt(), + std::forward(args)..., + location} + {} }; template - struct LOKINET_LOG_DEPRECATED(Info) LogInfo - : log_detail::LegacyLeveledLogger + struct LOKINET_LOG_DEPRECATED(Info) LogInfo : log::info { - using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + LogInfo( + T&&... args, + const log::slns::source_location& location = log::slns::source_location::current()) + : log::info::info{ + log_detail::legacy_logger, + log_detail::concat_args_fmt(), + std::forward(args)..., + location} + {} }; template - struct LOKINET_LOG_DEPRECATED(Warning) LogWarn - : log_detail::LegacyLeveledLogger + struct LOKINET_LOG_DEPRECATED(Warning) LogWarn : log::warning { - using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + LogWarn( + T&&... args, + const log::slns::source_location& location = log::slns::source_location::current()) + : log::warning::warning{ + log_detail::legacy_logger, + log_detail::concat_args_fmt(), + std::forward(args)..., + location} + {} }; template - struct LOKINET_LOG_DEPRECATED(Error) LogError - : log_detail::LegacyLeveledLogger + struct LOKINET_LOG_DEPRECATED(Error) LogError : log::error { - using log_detail::LegacyLeveledLogger::LegacyLeveledLogger; + LogError( + T&&... args, + const log::slns::source_location& location = log::slns::source_location::current()) + : log::error::error{ + log_detail::legacy_logger, + log_detail::concat_args_fmt(), + std::forward(args)..., + location} + {} }; template From eec8244a6cf120d78496947221a6c7bbe70d34eb Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Mon, 18 Jul 2022 14:56:09 -0300 Subject: [PATCH 020/298] Remote util::Printer and related cruft --- llarp/CMakeLists.txt | 1 - llarp/dns/message.cpp | 24 +- llarp/dns/message.hpp | 10 +- llarp/dns/question.cpp | 16 +- llarp/dns/question.hpp | 2 - llarp/dns/rr.cpp | 25 +- llarp/dns/rr.hpp | 2 - llarp/net/address_info.cpp | 20 +- llarp/net/address_info.hpp | 3 - llarp/net/exit_info.cpp | 14 +- llarp/net/exit_info.hpp | 3 - llarp/net/uint128.hpp | 2 - llarp/path/transit_hop.cpp | 36 +- llarp/path/transit_hop.hpp | 5 - llarp/pow.cpp | 20 +- llarp/pow.hpp | 3 - llarp/router_contact.cpp | 28 +- llarp/router_contact.hpp | 3 - llarp/service/info.cpp | 16 +- llarp/service/info.hpp | 3 - llarp/service/intro.cpp | 24 +- llarp/service/intro.hpp | 2 - llarp/service/intro_set.cpp | 61 +-- llarp/service/intro_set.hpp | 4 - llarp/util/aligned.hpp | 11 - llarp/util/formattable.hpp | 4 +- llarp/util/meta/traits.hpp | 209 -------- llarp/util/printer.cpp | 197 -------- llarp/util/printer.hpp | 583 ---------------------- test/CMakeLists.txt | 2 - test/util/meta/test_llarp_util_traits.cpp | 139 ------ test/util/test_llarp_util_printer.cpp | 94 ---- 32 files changed, 75 insertions(+), 1491 deletions(-) delete mode 100644 llarp/util/meta/traits.hpp delete mode 100644 llarp/util/printer.cpp delete mode 100644 llarp/util/printer.hpp delete mode 100644 test/util/meta/test_llarp_util_traits.cpp delete mode 100644 test/util/test_llarp_util_printer.cpp diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 0cd9edd9c..cf4bcb786 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -10,7 +10,6 @@ add_library(lokinet-util util/logging/buffer.cpp util/lokinet_init.c util/mem.cpp - util/printer.cpp util/str.cpp util/thread/queue_manager.cpp util/thread/threading.cpp diff --git a/llarp/dns/message.cpp b/llarp/dns/message.cpp index a6957116f..4519e0457 100644 --- a/llarp/dns/message.cpp +++ b/llarp/dns/message.cpp @@ -5,7 +5,6 @@ #include "srv_data.hpp" #include #include -#include #include #include @@ -401,19 +400,18 @@ namespace llarp } } - std::ostream& - Message::print(std::ostream& stream, int level, int spaces) const + std::string + Message::ToString() const { - Printer printer(stream, level, spaces); - - printer.printAttributeAsHex("dns message id", hdr_id); - printer.printAttributeAsHex("fields", hdr_fields); - printer.printAttribute("questions", questions); - printer.printAttribute("answers", answers); - printer.printAttribute("nameserer", authorities); - printer.printAttribute("additional", additional); - - return stream; + return fmt::format( + "[DNSMessage id={:x} fields={:x} questions={{{}}} answers={{{}}} authorities={{{}}} " + "additional={{{}}}]", + hdr_id, + hdr_fields, + fmt::format("{}", fmt::join(questions, ",")), + fmt::format("{}", fmt::join(answers, ",")), + fmt::format("{}", fmt::join(authorities, ",")), + fmt::format("{}", fmt::join(additional, ","))); } } // namespace dns diff --git a/llarp/dns/message.hpp b/llarp/dns/message.hpp index 9ba58ed1e..5d10e2901 100644 --- a/llarp/dns/message.hpp +++ b/llarp/dns/message.hpp @@ -93,16 +93,8 @@ namespace llarp [[nodiscard]] OwnedBuffer ToBuffer() const; - 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(); - } + ToString() const; MsgID_t hdr_id; Fields_t hdr_fields; diff --git a/llarp/dns/question.cpp b/llarp/dns/question.cpp index aef0d1e01..a3ea0e886 100644 --- a/llarp/dns/question.cpp +++ b/llarp/dns/question.cpp @@ -1,7 +1,6 @@ #include "question.hpp" #include -#include #include #include "dns.hpp" @@ -120,20 +119,7 @@ namespace llarp 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 - { - std::ostringstream o; - Printer printer(o, level, spaces); - printer.printAttribute("qname", qname); - printer.printAttributeAsHex("qtype", qtype); - printer.printAttributeAsHex("qclass", qclass); - - return stream; + return fmt::format("[DNSQuestion qname={} qtype={:x} qclass={:x}]", qname, qtype, qclass); } } // namespace dns } // namespace llarp diff --git a/llarp/dns/question.hpp b/llarp/dns/question.hpp index 38eef2963..ae5b9cd10 100644 --- a/llarp/dns/question.hpp +++ b/llarp/dns/question.hpp @@ -27,8 +27,6 @@ namespace llarp std::string ToString() const; - std::ostream& - print(std::ostream& stream, int level, int spaces) const; bool operator==(const Question& other) const diff --git a/llarp/dns/rr.cpp b/llarp/dns/rr.cpp index 7bb8c417b..332ff68a2 100644 --- a/llarp/dns/rr.cpp +++ b/llarp/dns/rr.cpp @@ -1,8 +1,8 @@ #include "rr.hpp" #include "dns.hpp" +#include "util/formattable.hpp" #include #include -#include namespace llarp { @@ -96,25 +96,16 @@ namespace llarp {"rdata", std::string{reinterpret_cast(rData.data()), rData.size()}}}; } - std::ostream& - ResourceRecord::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("name", rr_name); - printer.printAttribute("type", rr_type); - printer.printAttribute("class", rr_class); - printer.printAttribute("ttl", ttl); - printer.printAttribute("rdata", rData.size()); - - return stream; - } - std::string ResourceRecord::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[RR name={} type={} class={} ttl={} rdata-size={}]", + rr_name, + rr_type, + rr_class, + ttl, + rData.size()); } bool diff --git a/llarp/dns/rr.hpp b/llarp/dns/rr.hpp index 9f3e5d9f1..7f27594e9 100644 --- a/llarp/dns/rr.hpp +++ b/llarp/dns/rr.hpp @@ -33,8 +33,6 @@ namespace llarp util::StatusObject ToJSON() const override; - std::ostream& - print(std::ostream& stream, int level, int spaces) const; std::string ToString() const; diff --git a/llarp/net/address_info.cpp b/llarp/net/address_info.cpp index 5c18e276f..70788b258 100644 --- a/llarp/net/address_info.cpp +++ b/llarp/net/address_info.cpp @@ -7,7 +7,6 @@ #include "net.hpp" #include #include -#include #include @@ -171,25 +170,12 @@ namespace llarp port = addr.getPort(); } - std::ostream& - AddressInfo::print(std::ostream& stream, int level, int spaces) const - { - char tmp[128] = {0}; - inet_ntop(AF_INET6, (void*)&ip, tmp, sizeof(tmp)); - - Printer printer(stream, level, spaces); - printer.printAttribute("ip", tmp); - printer.printAttribute("port", port); - - return stream; - } - std::string AddressInfo::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + char tmp[INET6_ADDRSTRLEN] = {0}; + inet_ntop(AF_INET6, (void*)&ip, tmp, sizeof(tmp)); + return fmt::format("[{}]:{}", tmp, port); } void diff --git a/llarp/net/address_info.hpp b/llarp/net/address_info.hpp index f9982b36b..cd5698886 100644 --- a/llarp/net/address_info.hpp +++ b/llarp/net/address_info.hpp @@ -53,9 +53,6 @@ namespace llarp std::variant IP() const; - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - std::string ToString() const; }; diff --git a/llarp/net/exit_info.cpp b/llarp/net/exit_info.cpp index 46f9cb92e..2af7c707f 100644 --- a/llarp/net/exit_info.cpp +++ b/llarp/net/exit_info.cpp @@ -91,9 +91,8 @@ namespace llarp return read; } - std::ostream& - ExitInfo::print( - std::ostream& stream, [[maybe_unused]] int level, [[maybe_unused]] int spaces) const + std::string + ExitInfo::ToString() const { /* // TODO: derive these from ipAdress @@ -119,14 +118,7 @@ namespace llarp #endif printer.printValue(ss.str()); */ - stream << ipAddress.ToString(); - return stream; - } - - std::string - ExitInfo::ToString() const - { - return ipAddress.ToString(); + return fmt::format("[Exit {}]", ipAddress.ToString()); } } // namespace llarp diff --git a/llarp/net/exit_info.hpp b/llarp/net/exit_info.hpp index bad9c0ba8..1db07aef3 100644 --- a/llarp/net/exit_info.hpp +++ b/llarp/net/exit_info.hpp @@ -40,9 +40,6 @@ namespace llarp bool DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* buf); - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - std::string ToString() const; }; diff --git a/llarp/net/uint128.hpp b/llarp/net/uint128.hpp index 8340000b2..4bc39f53c 100644 --- a/llarp/net/uint128.hpp +++ b/llarp/net/uint128.hpp @@ -4,8 +4,6 @@ #include #include -#include "../util/meta/traits.hpp" - #include namespace llarp diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index a3b2cb19d..903326260 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -21,24 +21,15 @@ namespace llarp { namespace path { - std::ostream& - TransitHopInfo::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("tx", txID); - printer.printAttribute("rx", rxID); - printer.printAttribute("upstream", upstream); - printer.printAttribute("downstream", downstream); - - return stream; - } - std::string TransitHopInfo::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[TransitHopInfo tx={} rx={} upstream={} downstream={}]", + txID, + rxID, + upstream, + downstream); } TransitHop::TransitHop() @@ -440,22 +431,11 @@ namespace llarp return SendRoutingMessage(discarded, r); } - std::ostream& - TransitHop::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("TransitHop", info); - printer.printAttribute("started", started.count()); - printer.printAttribute("lifetime", lifetime.count()); - return stream; - } - std::string TransitHop::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[TransitHop {} started={} lifetime={}", info, started.count(), lifetime.count()); } void diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 86080a330..eb828af9b 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -28,9 +28,6 @@ namespace llarp RouterID upstream; RouterID downstream; - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - std::string ToString() const; }; @@ -108,8 +105,6 @@ namespace llarp std::string ToString() const; - std::ostream& - print(std::ostream& stream, int level, int spaces) const; bool Expired(llarp_time_t now) const override; diff --git a/llarp/pow.cpp b/llarp/pow.cpp index 48158f6b4..3de707111 100644 --- a/llarp/pow.cpp +++ b/llarp/pow.cpp @@ -53,24 +53,14 @@ namespace llarp return true; } - std::ostream& - PoW::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - - printer.printAttribute("pow timestamp", timestamp.count()); - printer.printAttribute("lifetime", extendedLifetime.count()); - printer.printAttribute("nonce", nonce); - - return stream; - } - std::string PoW::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[PoW timestamp={} lifetime={} nonce={}]", + timestamp.count(), + extendedLifetime.count(), + nonce); } } // namespace llarp diff --git a/llarp/pow.hpp b/llarp/pow.hpp index 0a01bc85c..79ff75e8b 100644 --- a/llarp/pow.hpp +++ b/llarp/pow.hpp @@ -38,9 +38,6 @@ namespace llarp return !(*this == other); } - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - std::string ToString() const; }; diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index b1266145d..e1d319232 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -7,7 +7,6 @@ #include "util/buffer.hpp" #include "util/logging.hpp" #include "util/mem.hpp" -#include "util/printer.hpp" #include "util/time.hpp" #include @@ -573,27 +572,18 @@ namespace llarp return BDecode(&buf); } - std::ostream& - RouterContact::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("k", pubkey); - printer.printAttribute("updated", last_updated.count()); - printer.printAttribute("netid", netID); - printer.printAttribute("v", version); - printer.printAttribute("ai", addrs); - printer.printAttribute("e", enckey); - printer.printAttribute("z", signature); - - return stream; - } - std::string RouterContact::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[RC k={} updated={} netid={} v={} ai={{{}}} e={} z={}]", + pubkey, + last_updated.count(), + netID, + version, + fmt::format("{}", fmt::join(addrs, ",")), + enckey, + signature); } } // namespace llarp diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 33ed5f4d7..e328192e8 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -192,9 +192,6 @@ namespace llarp return last_updated < other.last_updated; } - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - bool Read(const fs::path& fname); diff --git a/llarp/service/info.cpp b/llarp/service/info.cpp index a969e8284..b9f5ee618 100644 --- a/llarp/service/info.cpp +++ b/llarp/service/info.cpp @@ -95,24 +95,10 @@ namespace llarp return true; } - std::ostream& - ServiceInfo::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("e", enckey); - printer.printAttribute("s", signkey); - printer.printAttribute("v", version); - printer.printAttribute("x", vanity); - - return stream; - } - std::string ServiceInfo::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format("[ServiceInfo e={} s={} v={} x={}]", enckey, signkey, version, vanity); } } // namespace service diff --git a/llarp/service/info.hpp b/llarp/service/info.hpp index bd8f5e58f..8244f6db9 100644 --- a/llarp/service/info.hpp +++ b/llarp/service/info.hpp @@ -63,9 +63,6 @@ namespace llarp return Addr() < other.Addr(); } - std::ostream& - print(std::ostream& stream, int level, int spaces) const; - std::string ToString() const; diff --git a/llarp/service/intro.cpp b/llarp/service/intro.cpp index 41d15aaaa..54de28805 100644 --- a/llarp/service/intro.cpp +++ b/llarp/service/intro.cpp @@ -65,26 +65,16 @@ namespace llarp expiresAt = 0s; } - std::ostream& - Introduction::print(std::ostream& stream, int level, int spaces) const - { - const RouterID r{router}; - Printer printer(stream, level, spaces); - printer.printAttribute("k", r.ToString()); - printer.printAttribute("l", latency.count()); - printer.printAttribute("p", pathID); - printer.printAttribute("v", version); - printer.printAttribute("x", expiresAt.count()); - - return stream; - } - std::string Introduction::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[Intro k={} l={} p={} v={} x={}]", + RouterID{router}, + latency.count(), + pathID, + version, + expiresAt.count()); } } // namespace service diff --git a/llarp/service/intro.hpp b/llarp/service/intro.hpp index 2495957b4..c1c431eb0 100644 --- a/llarp/service/intro.hpp +++ b/llarp/service/intro.hpp @@ -34,8 +34,6 @@ namespace llarp return IsExpired(now + dlt); } - std::ostream& - print(std::ostream& stream, int level, int spaces) const; std::string ToString() const; diff --git a/llarp/service/intro_set.cpp b/llarp/service/intro_set.cpp index 431f9dbfe..5141256db 100644 --- a/llarp/service/intro_set.cpp +++ b/llarp/service/intro_set.cpp @@ -69,24 +69,16 @@ namespace llarp::service return signedAt < other.signedAt; } - std::ostream& - EncryptedIntroSet::print(std::ostream& out, int levels, int spaces) const - { - Printer printer(out, levels, spaces); - printer.printAttribute("d", derivedSigningKey); - printer.printAttribute("n", nounce); - printer.printAttribute("s", signedAt.count()); - printer.printAttribute("x", "[" + std::to_string(introsetPayload.size()) + " bytes]"); - printer.printAttribute("z", sig); - return out; - } - std::string EncryptedIntroSet::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[EncIntroSet d={} n={} s={} x=[{} bytes] z={}]", + derivedSigningKey, + nounce, + signedAt.count(), + introsetPayload.size(), + sig); } std::optional @@ -427,38 +419,17 @@ namespace llarp::service return maxTime; } - std::ostream& - IntroSet::print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printAttribute("addressKeys", addressKeys); - printer.printAttribute("intros", intros); - printer.printAttribute("sntrupKey", sntrupKey); - - std::string _topic = topic.ToString(); - - if (!_topic.empty()) - { - printer.printAttribute("topic", _topic); - } - else - { - printer.printAttribute("topic", topic); - } - - printer.printAttribute("signedAt", timestampSignedAt.count()); - - printer.printAttribute("version", version); - printer.printAttribute("sig", signature); - - return stream; - } - std::string IntroSet::ToString() const { - std::ostringstream o; - print(o, -1, -1); - return o.str(); + return fmt::format( + "[IntroSet addressKeys={} intros={{{}}} sntrupKey={} topic={} signedAt={} v={} sig={}]", + addressKeys, + fmt::format("{}", fmt::join(intros, ",")), + sntrupKey, + topic, + timestampSignedAt.count(), + version, + signature); } } // namespace llarp::service diff --git a/llarp/service/intro_set.hpp b/llarp/service/intro_set.hpp index 71a19288e..fdeec0126 100644 --- a/llarp/service/intro_set.hpp +++ b/llarp/service/intro_set.hpp @@ -57,8 +57,6 @@ namespace llarp return timestampSignedAt < other.timestampSignedAt; } - std::ostream& - print(std::ostream& stream, int level, int spaces) const; std::string ToString() const; @@ -170,8 +168,6 @@ namespace llarp bool Verify(llarp_time_t now) const; - std::ostream& - print(std::ostream& stream, int level, int spaces) const; std::string ToString() const; diff --git a/llarp/util/aligned.hpp b/llarp/util/aligned.hpp index d41fff48f..92dcf38a4 100644 --- a/llarp/util/aligned.hpp +++ b/llarp/util/aligned.hpp @@ -2,9 +2,7 @@ #include "bencode.h" #include -#include #include -#include "printer.hpp" #include @@ -283,15 +281,6 @@ namespace llarp return true; } - std::ostream& - print(std::ostream& stream, int level, int spaces) const - { - Printer printer(stream, level, spaces); - printer.printValue(ToHex()); - - return stream; - } - private: Data m_data; }; diff --git a/llarp/util/formattable.hpp b/llarp/util/formattable.hpp index edc4285e3..a2b1e8a37 100644 --- a/llarp/util/formattable.hpp +++ b/llarp/util/formattable.hpp @@ -52,7 +52,7 @@ namespace fmt { template auto - format(const fs::path& p, FormatContext& ctx) + format(const fs::path& p, FormatContext& ctx) const { return formatter::format(p.string(), ctx); } @@ -69,7 +69,7 @@ namespace fmt { template auto - format(const T& val, FormatContext& ctx) + format(const T& val, FormatContext& ctx) const { if constexpr (llarp::is_scoped_enum_v) return formatter::format(ToString(val), ctx); diff --git a/llarp/util/meta/traits.hpp b/llarp/util/meta/traits.hpp deleted file mode 100644 index 240ec277a..000000000 --- a/llarp/util/meta/traits.hpp +++ /dev/null @@ -1,209 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace llarp -{ - namespace traits - { - /// Represents the empty type - struct Bottom - {}; - - /// Int tag - template - struct Tag - { - char arr[N + 1]; - }; - - /// Type trait representing whether a type is pointer-like - template - struct is_pointy : public std::false_type - {}; - - // We take the following things: - // - has element_type typedef - // - has dereference operator - // - has arrow operator - template - struct is_pointy())>, void>> - : public std::true_type - {}; - - /// Type trait representing whether a type is an STL-style container - template - struct is_container : public std::false_type - {}; - - // We take that the container has begin, end and size methods to be a - // container. - // clang-format off - template < typename T > - struct is_container< - T, - std::conditional_t< - false, - std::void_t< typename T::value_type, - typename T::size_type, - typename T::iterator, - typename T::const_iterator, - decltype(std::declval().size()), - decltype(std::declval().begin()), - decltype(std::declval().end()), - decltype(std::declval().cbegin()), - decltype(std::declval().cend()) >, - void > > : public std::true_type - { - }; - // clang-format on - - namespace Switch - { - template - struct Switch - { - using Type = Bottom; - }; - - template - struct Switch<0u, T, Types...> - { - using Type = T; - }; - - template - struct Switch - { - using Type = typename Switch::Type; - }; - - } // namespace Switch - - namespace select - { - /// This provides a way to do a compile-type dispatch based on type traits - - /// meta function which always returns false - template - class False : public std::false_type - {}; - - /// a case in the selection - template