Merge remote-tracking branch 'origin/dev' into debian/bookworm

debian/bookworm
Jason Rhinelander 2 years ago
commit 358ff282e5
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262

@ -11,25 +11,25 @@ set(OPENSSL_SOURCE openssl-${OPENSSL_VERSION}.tar.gz)
set(OPENSSL_HASH SHA256=aa7d8d9bef71ad6525c55ba11e5f4397889ce49c2c9349dcea6d3e4f0b024a7a
CACHE STRING "openssl source hash")
set(EXPAT_VERSION 2.4.8 CACHE STRING "expat version")
set(EXPAT_VERSION 2.4.9 CACHE STRING "expat version")
string(REPLACE "." "_" EXPAT_TAG "R_${EXPAT_VERSION}")
set(EXPAT_MIRROR ${LOCAL_MIRROR} https://github.com/libexpat/libexpat/releases/download/${EXPAT_TAG}
CACHE STRING "expat download mirror(s)")
set(EXPAT_SOURCE expat-${EXPAT_VERSION}.tar.xz)
set(EXPAT_HASH SHA256=f79b8f904b749e3e0d20afeadecf8249c55b2e32d4ebb089ae378df479dcaf25
set(EXPAT_HASH SHA512=8508379b4915d84d50f3638678a90792179c98247d1cb5e6e6387d117af4dc148ac7031c1debea8b96e7b710ef436cf0dd5da91f3d22b8186a00cfafe1201169
CACHE STRING "expat source hash")
set(UNBOUND_VERSION 1.16.2 CACHE STRING "unbound version")
set(UNBOUND_VERSION 1.17.0 CACHE STRING "unbound version")
set(UNBOUND_MIRROR ${LOCAL_MIRROR} https://nlnetlabs.nl/downloads/unbound CACHE STRING "unbound download mirror(s)")
set(UNBOUND_SOURCE unbound-${UNBOUND_VERSION}.tar.gz)
set(UNBOUND_HASH SHA512=0ea65ea63265be677441bd2a28df12098ec5e86c3372240c2874f9bd13752b8b818da81ae6076cf02cbeba3d36e397698a4c2b50570be1a6a8e47f57a0251572
set(UNBOUND_HASH SHA512=f6b9f279330fb19b5feca09524959940aad8c4e064528aa82b369c726d77e9e8e5ca23f366f6e9edcf2c061b96f482ed7a2c26ac70fc15ae5762b3d7e36a5284
CACHE STRING "unbound source hash")
set(SQLITE3_VERSION 3380500 CACHE STRING "sqlite3 version")
set(SQLITE3_VERSION 3390400 CACHE STRING "sqlite3 version")
set(SQLITE3_MIRROR ${LOCAL_MIRROR} https://www.sqlite.org/2022
CACHE STRING "sqlite3 download mirror(s)")
set(SQLITE3_SOURCE sqlite-autoconf-${SQLITE3_VERSION}.tar.gz)
set(SQLITE3_HASH SHA3_256=ab649fea76f49a6ec7f907f001d87b8bd76dec0679c783e3992284c5a882a98c
set(SQLITE3_HASH SHA3_256=431328e30d12c551da9ba7ef2122b269076058512014afa799caaf62ca567090
CACHE STRING "sqlite3 source hash")
set(SODIUM_VERSION 1.0.18 CACHE STRING "libsodium version")
@ -48,25 +48,25 @@ set(ZMQ_SOURCE zeromq-${ZMQ_VERSION}.tar.gz)
set(ZMQ_HASH SHA512=e198ef9f82d392754caadd547537666d4fba0afd7d027749b3adae450516bcf284d241d4616cad3cb4ad9af8c10373d456de92dc6d115b037941659f141e7c0e
CACHE STRING "libzmq source hash")
set(LIBUV_VERSION 1.44.1 CACHE STRING "libuv version")
set(LIBUV_VERSION 1.44.2 CACHE STRING "libuv version")
set(LIBUV_MIRROR ${LOCAL_MIRROR} https://dist.libuv.org/dist/v${LIBUV_VERSION}
CACHE STRING "libuv mirror(s)")
set(LIBUV_SOURCE libuv-v${LIBUV_VERSION}.tar.gz)
set(LIBUV_HASH SHA512=b4f8944e2c79e3a6a31ded6cccbe4c0eeada50db6bc8a448d7015642795012a4b80ffeef7ca455bb093c59a8950d0e1430566c3c2fa87b73f82699098162d834
set(LIBUV_HASH SHA512=91197ff9303112567bbb915bbb88058050e2ad1c048815a3b57c054635d5dc7df458b956089d785475290132236cb0edcfae830f5d749de29a9a3213eeaf0b20
CACHE STRING "libuv source hash")
set(ZLIB_VERSION 1.2.12 CACHE STRING "zlib version")
set(ZLIB_VERSION 1.2.13 CACHE STRING "zlib version")
set(ZLIB_MIRROR ${LOCAL_MIRROR} https://zlib.net
CACHE STRING "zlib mirror(s)")
set(ZLIB_SOURCE zlib-${ZLIB_VERSION}.tar.gz)
set(ZLIB_HASH SHA256=91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9
set(ZLIB_SOURCE zlib-${ZLIB_VERSION}.tar.xz)
set(ZLIB_HASH SHA256=d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98
CACHE STRING "zlib source hash")
set(CURL_VERSION 7.83.1 CACHE STRING "curl version")
set(CURL_VERSION 7.85.0 CACHE STRING "curl version")
set(CURL_MIRROR ${LOCAL_MIRROR} https://curl.haxx.se/download https://curl.askapache.com
CACHE STRING "curl mirror(s)")
set(CURL_SOURCE curl-${CURL_VERSION}.tar.xz)
set(CURL_HASH SHA256=2cb9c2356e7263a1272fd1435ef7cdebf2cd21400ec287b068396deb705c22c4
set(CURL_HASH SHA512=b57cc31649a4f47cc4b482f56a85c86c8e8aaeaf01bc1b51b065fdb9145a9092bc52535e52a85a66432eb163605b2edbf5bc5c33ea6e40e50f26a69ad1365cbd
CACHE STRING "curl source hash")
include(ExternalProject)
@ -167,6 +167,11 @@ if(APPLE)
set(deps_CXXFLAGS "${deps_CXXFLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
if(_winver)
set(deps_CFLAGS "${deps_CFLAGS} -D_WIN32_WINNT=${_winver}")
set(deps_CXXFLAGS "${deps_CXXFLAGS} -D_WIN32_WINNT=${_winver}")
endif()
if("${CMAKE_GENERATOR}" STREQUAL "Unix Makefiles")
set(_make $(MAKE))

@ -13,9 +13,6 @@ option(WITH_WINDOWS_32 "build 32 bit windows" OFF)
# GNU ld sees fit to merge *all* the .ident sections in object files
# to .r[o]data section one after the other!
add_compile_options(-fno-ident -Wa,-mbig-obj)
# the minimum windows version, set to 6 rn because supporting older windows is hell
set(_winver 0x0600)
add_definitions(-D_WIN32_WINNT=${_winver})
if(EMBEDDED_CFG)
link_libatomic()

@ -8,7 +8,7 @@ set -o errexit
bad=
if [ "$DRONE_STAGE_OS" == "darwin" ]; then
if otool -L llarp/apple/org.lokinet.network-extension.systemextension/Contents/MacOS/org.lokinet.network-extension | \
grep -Ev '^llarp/apple:|^\t(/usr/lib/lib(System\.|c\+\+|objc)|/System/Library/Frameworks/(CoreFoundation|NetworkExtension|Foundation|Network)\.framework'; then
grep -Ev '^llarp/apple:|^\t(/usr/lib/lib(System\.|c\+\+|objc))|/System/Library/Frameworks/(CoreFoundation|NetworkExtension|Foundation|Network)\.framework'; then
bad=1
fi
elif [ "$DRONE_STAGE_OS" == "linux" ]; then

@ -1,6 +1,9 @@
#!/usr/bin/env bash
test "x$IGNORE" != "x" && exit 0
. $(dirname $0)/../format-version.sh
repo=$(readlink -e $(dirname $0)/../../)
clang-format-11 -i $(find $repo/jni $repo/daemon $repo/llarp $repo/include $repo/pybind | grep -E '\.[hc](pp)?$')
$CLANG_FORMAT -i $(find $repo/jni $repo/daemon $repo/llarp $repo/include $repo/pybind | grep -E '\.[hc](pp)?$')
jsonnetfmt -i $repo/.drone.jsonnet
git --no-pager diff --exit-code --color || (echo -ne '\n\n\e[31;1mLint check failed; please run ./contrib/format.sh\e[0m\n\n' ; exit 1)

@ -19,9 +19,15 @@ set -o xtrace # Don't start tracing until *after* we write the ssh key
chmod 600 ssh_key
os="${UPLOAD_OS:-$DRONE_STAGE_OS-$DRONE_STAGE_ARCH}"
if [ -n "$WINDOWS_BUILD_NAME" ]; then
os="windows-$WINDOWS_BUILD_NAME"
os="$UPLOAD_OS"
if [ -z "$os" ]; then
if [ "$DRONE_STAGE_OS" == "darwin" ]; then
os="macos-$DRONE_STAGE_ARCH"
elif [ -n "$WINDOWS_BUILD_NAME" ]; then
os="windows-$WINDOWS_BUILD_NAME"
else
os="$DRONE_STAGE_OS-$DRONE_STAGE_ARCH"
fi
fi
if [ -n "$DRONE_TAG" ]; then
@ -55,8 +61,8 @@ elif [ -e build-mac ]; then
mv build-mac/Lokinet*/ "$base"
tar cJvf "$archive" "$base"
else
cp -av daemon/lokinet daemon/lokinet-vpn "$base"
cp -av ../contrib/bootstrap/mainnet.signed "$base/bootstrap.signed"
cp -av build/daemon/lokinet{,-vpn} "$base"
cp -av contrib/bootstrap/mainnet.signed "$base/bootstrap.signed"
# tar dat shiz up yo
archive="$base.tar.xz"
tar cJvf "$archive" "$base"

@ -1,4 +1,8 @@
set(CMAKE_SYSTEM_VERSION 5.0)
set(CMAKE_SYSTEM_VERSION 6.0)
# the minimum windows version, set to 6 rn because supporting older windows is hell
set(_winver 0x0600)
add_definitions(-D_WIN32_WINNT=${_winver})
# target environment on the build host system
# second one is for non-root installs

@ -0,0 +1,19 @@
CLANG_FORMAT_DESIRED_VERSION=14
CLANG_FORMAT=$(command -v clang-format-$CLANG_FORMAT_DESIRED_VERSION 2>/dev/null)
if [ $? -ne 0 ]; then
CLANG_FORMAT=$(command -v clang-format-mp-$CLANG_FORMAT_DESIRED_VERSION 2>/dev/null)
fi
if [ $? -ne 0 ]; then
CLANG_FORMAT=$(command -v clang-format 2>/dev/null)
if [ $? -ne 0 ]; then
echo "Please install clang-format version $CLANG_FORMAT_DESIRED_VERSION and re-run this script."
exit 1
fi
version=$(clang-format --version)
if [[ ! $version == *"clang-format version $CLANG_FORMAT_DESIRED_VERSION"* ]]; then
echo "Please install clang-format version $CLANG_FORMAT_DESIRED_VERSION and re-run this script."
exit 1
fi
fi

@ -1,31 +1,15 @@
#!/usr/bin/env bash
CLANG_FORMAT_DESIRED_VERSION=11
binary=$(command -v clang-format-$CLANG_FORMAT_DESIRED_VERSION 2>/dev/null)
if [ $? -ne 0 ]; then
binary=$(command -v clang-format-mp-$CLANG_FORMAT_DESIRED_VERSION 2>/dev/null)
fi
if [ $? -ne 0 ]; then
binary=$(command -v clang-format 2>/dev/null)
if [ $? -ne 0 ]; then
echo "Please install clang-format version $CLANG_FORMAT_DESIRED_VERSION and re-run this script."
exit 1
fi
version=$(clang-format --version)
if [[ ! $version == *"clang-format version $CLANG_FORMAT_DESIRED_VERSION"* ]]; then
echo "Please install clang-format version $CLANG_FORMAT_DESIRED_VERSION and re-run this script."
exit 1
fi
fi
. $(dirname $0)/format-version.sh
cd "$(dirname $0)/../"
if [ "$1" = "verify" ] ; then
if [ $($binary --output-replacements-xml $(find jni daemon llarp include pybind | grep -E '\.([hc](pp)?|m(m)?)$' | grep -v '#') | grep '</replacement>' | wc -l) -ne 0 ] ; then
if [ $($CLANG_FORMAT --output-replacements-xml $(find jni daemon llarp include pybind | grep -E '\.([hc](pp)?|m(m)?)$' | grep -v '#') | grep '</replacement>' | wc -l) -ne 0 ] ; then
exit 2
fi
else
$binary -i $(find jni daemon llarp include pybind | grep -E '\.([hc](pp)?|m(m)?)$' | grep -v '#') &> /dev/null
$CLANG_FORMAT -i $(find jni daemon llarp include pybind | grep -E '\.([hc](pp)?|m(m)?)$' | grep -v '#') &> /dev/null
fi
swift_format=$(command -v swiftformat 2>/dev/null)

@ -329,9 +329,8 @@ class WindowsServiceStopped
LONG
GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
const auto flags = (MINIDUMP_TYPE)(
MiniDumpWithFullMemory | MiniDumpWithFullMemoryInfo | MiniDumpWithHandleData
| MiniDumpWithUnloadedModules | MiniDumpWithThreadInfo);
const auto flags =
(MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithFullMemoryInfo | MiniDumpWithHandleData | MiniDumpWithUnloadedModules | MiniDumpWithThreadInfo);
std::stringstream ss;
ss << "C:\\ProgramData\\lokinet\\crash-" << llarp::time_now_ms().count() << ".dmp";

@ -124,4 +124,19 @@ if(WITH_BOOTSTRAP)
target_include_directories(cpr PUBLIC cpr/include)
target_compile_definitions(cpr PUBLIC CPR_CURL_NOSIGNAL)
add_library(cpr::cpr ALIAS cpr)
file(READ cpr/CMakeLists.txt cpr_cmake_head LIMIT 1000)
if(cpr_cmake_head MATCHES "project\\(cpr VERSION ([0-9]+)\.([0-9]+)\.([0-9]+) LANGUAGES CXX\\)")
set(cpr_VERSION_MAJOR ${CMAKE_MATCH_1})
set(cpr_VERSION_MINOR ${CMAKE_MATCH_2})
set(cpr_VERSION_PATCH ${CMAKE_MATCH_3})
set(cpr_VERSION "${cpr_VERSION_MAJOR}.${cpr_VERSION_MINOR}.${cpr_VERSION_PATCH}")
set(cpr_VERSION_NUM "(${cpr_VERSION_MAJOR} * 0x10000 + ${cpr_VERSION_MINOR} * 0x100 + ${cpr_VERSION_PATCH})")
configure_file(cpr/cmake/cprver.h.in "${CMAKE_CURRENT_BINARY_DIR}/cpr_generated_includes/cpr/cprver.h")
target_include_directories(cpr PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/cpr_generated_includes")
else()
message(FATAL_ERROR "Could not identify cpr submodule version!")
endif()
endif()

2
external/cpr vendored

@ -1 +1 @@
Subproject commit aac5058a15e9ad5ad393973dc6fe44d7614a7f55
Subproject commit f88fd7737de3e640c61703eb57a0fa0ce00c60cd

2
external/cxxopts vendored

@ -1 +1 @@
Subproject commit 6fa46a748838d5544ff8e9ab058906ba2c4bc0f3
Subproject commit c74846a891b3cc3bfa992d588b1295f528d43039

@ -1 +1 @@
Subproject commit 2a8b380f8d4e77b389c42a194ab9c70d8e3a0f1e
Subproject commit cd6805e94dd5d6346be1b75a54cdc27787319dd2

2
external/nlohmann vendored

@ -1 +1 @@
Subproject commit db78ac1d7716f56fc9f1b030b715f872f93964e4
Subproject commit bc889afb4c5bf1c0d8ee29ef35eaaf4c8bef8a5d

2
external/pybind11 vendored

@ -1 +1 @@
Subproject commit 8de7772cc72daca8e947b79b83fea46214931604
Subproject commit aa304c9c7d725ffb9d10af08a3b34cb372307020

@ -1 +1 @@
Subproject commit 4c6a46bd4dcfba14a650e0fafb86331526878587
Subproject commit fdcc1da46fbd90feb886c0588462a62d29eb5a06

@ -15,10 +15,12 @@ namespace llarp::apple
/// These are called for poking route holes, but we don't have to do that at all on macos
/// because the appex isn't subject to its own rules.
void AddRoute(net::ipaddr_t /*ip*/, net::ipaddr_t /*gateway*/) override
void
AddRoute(net::ipaddr_t /*ip*/, net::ipaddr_t /*gateway*/) override
{}
void DelRoute(net::ipaddr_t /*ip*/, net::ipaddr_t /*gateway*/) override
void
DelRoute(net::ipaddr_t /*ip*/, net::ipaddr_t /*gateway*/) override
{}
void

@ -300,9 +300,9 @@ namespace llarp
throw std::invalid_argument{"duplicate strict connect snode: " + value};
},
Comment{
"Public key of a router which will act as a pinned first-hop. This may be used to",
"Public keys of routers which will act as pinned first-hops. This may be used to",
"provide a trusted router (consider that you are not fully anonymous with your",
"first hop).",
"first hop). This REQUIRES two or more nodes to be specified.",
});
conf.defineOption<std::string>(
@ -459,9 +459,8 @@ namespace llarp
"owned-range",
MultiValue,
Comment{
"When in exit mode announce we allow a private range in our introset"
"exmaple:",
"owned-range=10.0.0.0/24",
"When in exit mode announce we allow a private range in our introset. For example:",
" owned-range=10.0.0.0/24",
},
[this](std::string arg) {
IPRange range;
@ -475,12 +474,17 @@ namespace llarp
"traffic-whitelist",
MultiValue,
Comment{
"List of ip traffic whitelist, anything not specified will be dropped by us."
"examples:",
"tcp for all tcp traffic regardless of port",
"0x69 for all packets using ip protocol 0x69"
"udp/53 for udp port 53",
"tcp/smtp for smtp port",
"Adds an IP traffic type whitelist; can be specified multiple times. If any are",
"specified then only matched traffic will be allowed and all other traffic will be",
"dropped. Examples:",
" traffic-whitelist=tcp",
"would allow all TCP/IP packets (regardless of port);",
" traffic-whitelist=0x69",
"would allow IP traffic with IP protocol 0x69;",
" traffic-whitelist=udp/53",
"would allow UDP port 53; and",
" traffic-whitelist=tcp/smtp",
"would allow TCP traffic on the standard smtp port (21).",
},
[this](std::string arg) {
if (not m_TrafficPolicy)
@ -497,9 +501,12 @@ namespace llarp
MultiValue,
Comment{
"Specify a `.loki` address and an optional ip range to use as an exit broker.",
"Example:",
"exit-node=whatever.loki # maps all exit traffic to whatever.loki",
"exit-node=stuff.loki:100.0.0.0/24 # maps 100.0.0.0/24 to stuff.loki",
"Examples:",
" exit-node=whatever.loki",
"would map all exit traffic through whatever.loki; and",
" exit-node=stuff.loki:100.0.0.0/24",
"would map the IP range 100.0.0.0/24 through stuff.loki.",
"This option can be specified multiple times (to map different IP ranges).",
},
[this](std::string arg) {
if (arg.empty())
@ -580,10 +587,10 @@ namespace llarp
Default{true},
Comment{
"Enable / disable automatic route configuration.",
"When this is enabled and an exit is used Lokinet will automatically configure "
"operating system routes to route traffic through the exit node.",
"This is enabled by default, but can be disabled to perform advanced exit routing "
"configuration manually."},
"When this is enabled and an exit is used Lokinet will automatically configure the",
"operating system routes to route public internet traffic through the exit node.",
"This is enabled by default, but can be disabled if advanced/manual exit routing",
"configuration is desired."},
AssignmentAcceptor(m_EnableRoutePoker));
conf.defineOption<bool>(
@ -593,8 +600,8 @@ namespace llarp
Default{true},
Comment{
"Enable / disable route configuration blackholes.",
"When enabled lokinet will drop ip4 and ip6 not included in exit config.",
"Enabled by default."},
"When enabled lokinet will drop IPv4 and IPv6 traffic (when in exit mode) that is not",
"handled in the exit configuration. Enabled by default."},
AssignmentAcceptor(m_BlackholeRoutes));
conf.defineOption<std::string>(
@ -602,7 +609,7 @@ namespace llarp
"ifname",
Comment{
"Interface name for lokinet traffic. If unset lokinet will look for a free name",
"lokinetN, starting at 0 (e.g. lokinet0, lokinet1, ...).",
"matching 'lokinetN', starting at N=0 (e.g. lokinet0, lokinet1, ...).",
},
AssignmentAcceptor(m_ifname));
@ -626,10 +633,10 @@ namespace llarp
"ip6-range",
ClientOnly,
Comment{
"For all ipv6 exit traffic you will use this as the base address bitwised or'd with "
"For all IPv6 exit traffic you will use this as the base address bitwised or'd with ",
"the v4 address in use.",
"To disable ipv6 set this to an empty value.",
"!!! WARNING !!! Disabling ipv6 tunneling when you have ipv6 routes WILL lead to "
"!!! WARNING !!! Disabling ipv6 tunneling when you have ipv6 routes WILL lead to ",
"de-anonymization as lokinet will no longer carry your ipv6 traffic.",
},
IP6RangeDefault,
@ -720,9 +727,13 @@ namespace llarp
ClientOnly,
MultiValue,
Comment{
"Specify SRV Records for services hosted on the SNApp",
"for more info see https://docs.loki.network/Lokinet/Guides/HostingSNApps/",
"srv=_service._protocol priority weight port target.loki",
"Specify SRV Records for services hosted on the SNApp for protocols that use SRV",
"records for service discovery. Each line specifies a single SRV record as:",
" srv=_service._protocol priority weight port target.loki",
"and can be specified multiple times as needed.",
"For more info see",
"https://docs.oxen.io/products-built-on-oxen/lokinet/snapps/hosting-snapps",
"and general description of DNS SRV record configuration.",
},
[this](std::string arg) {
llarp::dns::SRVData newSRV;
@ -737,8 +748,8 @@ namespace llarp
"path-alignment-timeout",
ClientOnly,
Comment{
"time in seconds how long to wait for a path to align to pivot routers",
"if not provided a sensible default will be used",
"How long to wait (in seconds) for a path to align to a pivot router when establishing",
"a path through the network to a remote .loki address.",
},
[this](int val) {
if (val <= 0)
@ -753,9 +764,10 @@ namespace llarp
ClientOnly,
Default{fs::path{params.defaultDataDir / "addrmap.dat"}},
Comment{
"persist mapped ephemeral addresses to a file",
"on restart the mappings will be loaded so that ip addresses will not be mapped to a "
"different address",
"If given this specifies a file in which to record mapped local tunnel addresses so",
"the same local address will be used for the same lokinet address on reboot. If this",
"is not specified then the local IP of remote lokinet targets will not persist across",
"restarts of lokinet.",
},
[this](fs::path arg) {
if (arg.empty())
@ -879,7 +891,7 @@ namespace llarp
"on systems which use resolveconf)",
});
// forwad the rest to libunbound
// forward the rest to libunbound
conf.addUndeclaredHandler("dns", [this](auto, std::string_view key, std::string_view val) {
m_ExtraOpts.emplace(key, val);
});
@ -1150,7 +1162,7 @@ namespace llarp
RelayOnly,
Default{true},
Comment{
"Whether or not we should talk to lokid. Must be enabled for staked routers.",
"Whether or not we should talk to oxend. Must be enabled for staked routers.",
},
AssignmentAcceptor(whitelistRouters));
@ -1159,8 +1171,8 @@ namespace llarp
return;
throw std::invalid_argument(
"the [lokid]:jsonrpc option is no longer supported; please use the [lokid]:rpc config "
"option instead with lokid's lmq-local-control address -- typically a value such as "
"rpc=ipc:///var/lib/loki/lokid.sock or rpc=ipc:///home/snode/.loki/lokid.sock");
"option instead with oxend's lmq-local-control address -- typically a value such as "
"rpc=ipc:///var/lib/oxen/oxend.sock or rpc=ipc:///home/snode/.oxen/oxend.sock");
});
conf.defineOption<std::string>(
@ -1168,12 +1180,12 @@ namespace llarp
"rpc",
RelayOnly,
Comment{
"lokimq control address for for communicating with lokid. Depends on lokid's",
"oxenmq control address for for communicating with oxend. Depends on oxend's",
"lmq-local-control configuration option. By default this value should be",
"ipc://LOKID-DATA-DIRECTORY/lokid.sock, such as:",
" rpc=ipc:///var/lib/loki/lokid.sock",
" rpc=ipc:///home/USER/.loki/lokid.sock",
"but can use (non-default) TCP if lokid is configured that way:",
"ipc://OXEND-DATA-DIRECTORY/oxend.sock, such as:",
" rpc=ipc:///var/lib/oxen/oxend.sock",
" rpc=ipc:///home/USER/.oxen/oxend.sock",
"but can use (non-default) TCP if oxend is configured that way:",
" rpc=tcp://127.0.0.1:5678",
},
[this](std::string arg) { lokidRPCAddr = oxenmq::address(arg); });
@ -1202,7 +1214,7 @@ namespace llarp
"add-node",
MultiValue,
Comment{
"Specify a bootstrap file containing a signed RouterContact of a service node",
"Specify a bootstrap file containing a list of signed RouterContacts of service nodes",
"which can act as a bootstrap. Can be specified multiple times.",
},
[this](std::string arg) {
@ -1292,9 +1304,9 @@ namespace llarp
m_UniqueHopsNetmaskSize = arg;
},
Comment{
"Netmask for router path selection; each router must be from a distinct IP subnet "
"Netmask for router path selection; each router must be from a distinct IPv4 subnet",
"of the given size.",
"E.g. 16 ensures that all routers are using distinct /16 IP addresses."});
"E.g. 16 ensures that all routers are using IPs from distinct /16 IP ranges."});
#ifdef WITH_GEOIP
conf.defineOption<std::string>(
@ -1306,9 +1318,11 @@ namespace llarp
m_ExcludeCountries.emplace(lowercase_ascii_string(std::move(arg)));
},
Comment{
"exclude a country given its 2 letter country code from being used in path builds",
"e.g. exclude-country=DE",
"can be listed multiple times to exclude multiple countries"});
"Exclude a country given its 2 letter country code from being used in path builds.",
"For example:",
" exclude-country=DE",
"would avoid building paths through routers with IPs in Germany.",
"This option can be specified multiple times to exclude multiple countries"});
#endif
}
@ -1399,6 +1413,7 @@ namespace llarp
params->isRelay = isRelay;
params->defaultDataDir = m_DataDir;
ConfigDefinition conf{isRelay};
addBackwardsCompatibleConfigOptions(conf);
initializeConfig(conf, *params);
for (const auto& item : m_Additional)
@ -1616,11 +1631,11 @@ namespace llarp
initializeConfig(def, *params);
generateCommonConfigComments(def);
// lokid
// oxend
def.addSectionComments(
"lokid",
{
"Settings for communicating with lokid",
"Settings for communicating with oxend",
});
return def.generateINIConfig(true);

@ -441,7 +441,7 @@ namespace llarp
Context::CleanupTX()
{
auto now = Now();
llarp::LogDebug("DHT tick");
llarp::LogTrace("DHT tick");
pendingRouterLookups().Expire(now);
_pendingIntrosetLookups.Expire(now);

@ -160,7 +160,8 @@ namespace llarp
return OwnedBuffer::copy_used(buf);
}
void Message::AddServFail(RR_TTL_t)
void
Message::AddServFail(RR_TTL_t)
{
if (questions.size())
{
@ -386,7 +387,8 @@ namespace llarp
std::copy_n(buf.base, buf.sz, rec.rData.data());
}
void Message::AddNXReply(RR_TTL_t)
void
Message::AddNXReply(RR_TTL_t)
{
if (questions.size())
{

@ -89,7 +89,6 @@ namespace llarp::dns
class Query : public QueryJob_Base
{
std::weak_ptr<Resolver> parent;
std::shared_ptr<PacketSource_Base> src;
SockAddr resolverAddr;
SockAddr askerAddr;
@ -102,11 +101,13 @@ namespace llarp::dns
SockAddr toaddr,
SockAddr fromaddr)
: QueryJob_Base{std::move(query)}
, parent{parent_}
, src{std::move(pktsrc)}
, resolverAddr{std::move(toaddr)}
, askerAddr{std::move(fromaddr)}
, parent{parent_}
{}
std::weak_ptr<Resolver> parent;
int id{};
virtual void
SendReply(llarp::OwnedBuffer replyBuf) const override;
@ -126,6 +127,7 @@ namespace llarp::dns
#endif
std::optional<SockAddr> m_LocalAddr;
std::set<int> m_Pending;
struct ub_result_deleter
{
@ -166,7 +168,9 @@ namespace llarp::dns
hdr.id = query->Underlying().hdr_id;
buf.cur = buf.base;
hdr.Encode(&buf);
// remove pending query
if (auto ptr = query->parent.lock())
ptr->call([id = query->id, ptr]() { ptr->m_Pending.erase(id); });
// send reply
query->SendReply(std::move(pkt));
}
@ -407,6 +411,13 @@ namespace llarp::dns
#endif
if (m_ctx)
{
// cancel pending queries
// make copy as ub_cancel modifies m_Pending
const auto pending = m_Pending;
for (auto id : pending)
::ub_cancel(m_ctx, id);
m_Pending.clear();
::ub_ctx_delete(m_ctx);
m_ctx = nullptr;
}
@ -478,6 +489,12 @@ namespace llarp::dns
return true;
}
}
if (not m_ctx)
{
// we are down
tmp->Cancel();
return true;
}
const auto& q = query.questions[0];
if (auto err = ub_resolve_async(
m_ctx,
@ -486,7 +503,7 @@ namespace llarp::dns
q.qclass,
tmp.get(),
&Resolver::Callback,
nullptr))
&tmp->id))
{
log::warning(
logcat, "failed to send upstream query with libunbound: {}", ub_strerror(err));
@ -494,6 +511,7 @@ namespace llarp::dns
}
else
{
m_Pending.insert(tmp->id);
// Leak the bare pointer we gave to unbound; we'll recapture it in Callback
(void)tmp.release();
}

@ -10,7 +10,7 @@
namespace llarp::dns
{
typedef std::tuple<std::string, uint16_t, uint16_t, uint16_t, std::string> SRVTuple;
using SRVTuple = std::tuple<std::string, uint16_t, uint16_t, uint16_t, std::string>;
struct SRVData
{
@ -38,19 +38,23 @@ namespace llarp::dns
SRVTuple
toTuple() const;
auto
toTupleRef() const
{
return std::tie(service_proto, priority, weight, port, target);
}
/// so we can put SRVData in a std::set
bool
operator<(const SRVData& other) const
{
return service_proto < other.service_proto or priority < other.priority
or weight < other.weight or port < other.port or target < other.target;
return toTupleRef() < other.toTupleRef();
}
bool
operator==(const SRVData& other) const
{
return service_proto == other.service_proto and priority == other.priority
and weight == other.weight and port == other.port and target == other.target;
return toTupleRef() == other.toTupleRef();
}
bool

@ -613,7 +613,8 @@ namespace llarp
});
}
std::optional<EndpointBase::SendStat> ExitEndpoint::GetStatFor(AddressVariant_t) const
std::optional<EndpointBase::SendStat>
ExitEndpoint::GetStatFor(AddressVariant_t) const
{
/// TODO: implement me
return std::nullopt;

@ -101,13 +101,14 @@ namespace llarp::handlers
void
SendPacketToRemote(const llarp_buffer_t&, service::ProtocolType) override{};
huint128_t ObtainIPForAddr(std::variant<service::Address, RouterID>) override
huint128_t
ObtainIPForAddr(std::variant<service::Address, RouterID>) override
{
return {0};
}
std::optional<std::variant<service::Address, RouterID>> ObtainAddrForIP(
huint128_t) const override
std::optional<std::variant<service::Address, RouterID>>
ObtainAddrForIP(huint128_t) const override
{
return std::nullopt;
}

@ -26,7 +26,7 @@ namespace llarp::iwp
, m_Inbound{allowInbound}
{}
const char*
std::string_view
LinkLayer::Name() const
{
return "iwp";

@ -35,7 +35,7 @@ namespace llarp::iwp
std::shared_ptr<ILinkSession>
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) override;
const char*
std::string_view
Name() const override;
uint16_t

@ -53,11 +53,12 @@ namespace llarp
uint16_t m_ResendPriority;
bool
operator<(const OutboundMessage& msg) const
operator<(const OutboundMessage& other) const
{
// yes, the first order is reversed as higher means more important
// second part is for queue order
return msg.m_ResendPriority < m_ResendPriority or m_MsgID < msg.m_MsgID;
int prioA = -m_ResendPriority, prioB = -other.m_ResendPriority;
return std::tie(prioA, m_MsgID) < std::tie(prioB, other.m_MsgID);
}
ILinkSession::Packet_t

@ -924,13 +924,15 @@ namespace llarp
}
}
void Session::HandleCLOS(Packet_t)
void
Session::HandleCLOS(Packet_t)
{
LogInfo("remote closed by ", m_RemoteAddr);
Close();
}
void Session::HandlePING(Packet_t)
void
Session::HandlePING(Packet_t)
{
m_LastRX = m_Parent->Now();
}

@ -249,7 +249,7 @@ namespace llarp
bool
ILinkLayer::PickAddress(const RouterContact& rc, llarp::AddressInfo& picked) const
{
std::string OurDialect = Name();
auto OurDialect = Name();
for (const auto& addr : rc.addrs)
{
if (addr.dialect == OurDialect)

@ -135,7 +135,7 @@ namespace llarp
virtual void
Stop();
virtual const char*
virtual std::string_view
Name() const = 0;
util::StatusObject
@ -179,7 +179,7 @@ namespace llarp
bool
IsCompatable(const llarp::RouterContact& other) const
{
const std::string us = Name();
const auto us = Name();
for (const auto& ai : other.addrs)
if (ai.dialect == us)
return true;
@ -207,7 +207,9 @@ namespace llarp
bool
operator<(const ILinkLayer& other) const
{
return Rank() < other.Rank() || Name() < other.Name() || m_ourAddr < other.m_ourAddr;
auto rankA = Rank(), rankB = other.Rank();
auto nameA = Name(), nameB = other.Name();
return std::tie(rankA, nameA, m_ourAddr) < std::tie(rankB, nameB, other.m_ourAddr);
}
/// called by link session to remove a pending session who is timed out

@ -68,7 +68,8 @@ namespace llarp
/// recv packet on low layer
/// not used by utp
virtual bool Recv_LL(Packet_t)
virtual bool
Recv_LL(Packet_t)
{
return true;
}

@ -23,7 +23,7 @@ namespace llarp
bool
operator<(const AddressInfo& lhs, const AddressInfo& rhs)
{
return lhs.rank < rhs.rank || lhs.ip < rhs.ip || lhs.port < rhs.port;
return std::tie(lhs.rank, lhs.ip, lhs.port) < std::tie(rhs.rank, rhs.ip, rhs.port);
}
std::variant<nuint32_t, nuint128_t>

@ -117,8 +117,8 @@ namespace llarp
bool
operator<(const IPRange& other) const
{
return (this->addr & this->netmask_bits) < (other.addr & other.netmask_bits)
|| this->netmask_bits < other.netmask_bits;
auto maskedA = addr & netmask_bits, maskedB = other.addr & other.netmask_bits;
return std::tie(maskedA, netmask_bits) < std::tie(maskedB, other.netmask_bits);
}
bool

@ -34,62 +34,16 @@
namespace llarp
{
inline bool
operator==(const in_addr& a, const in_addr& b)
inline int
cmp(const in_addr& a, const in_addr& b)
{
return memcmp(&a, &b, sizeof(in_addr)) == 0;
return memcmp(&a, &b, sizeof(in_addr));
}
inline bool
operator==(const in6_addr& a, const in6_addr& b)
inline int
cmp(const in6_addr& a, const in6_addr& b)
{
return memcmp(&a, &b, sizeof(in6_addr)) == 0;
}
inline bool
operator==(const sockaddr_in& a, const sockaddr_in& b)
{
return a.sin_port == b.sin_port and a.sin_addr.s_addr == b.sin_addr.s_addr;
}
inline bool
operator==(const sockaddr_in6& a, const sockaddr_in6& b)
{
return a.sin6_port == b.sin6_port and a.sin6_addr == b.sin6_addr;
}
inline bool
operator==(const sockaddr& a, const sockaddr& b)
{
if (a.sa_family != b.sa_family)
return false;
switch (a.sa_family)
{
case AF_INET:
return reinterpret_cast<const sockaddr_in&>(a) == reinterpret_cast<const sockaddr_in&>(b);
case AF_INET6:
return reinterpret_cast<const sockaddr_in6&>(a) == reinterpret_cast<const sockaddr_in6&>(b);
default:
return false;
}
}
inline bool
operator<(const in_addr& a, const in_addr& b)
{
return memcmp(&a, &b, sizeof(in_addr)) < 0;
}
inline bool
operator<(const in6_addr& a, const in6_addr& b)
{
return memcmp(&a, &b, sizeof(in6_addr)) < 0;
}
inline bool
operator<(const sockaddr_in6& a, const sockaddr_in6& b)
{
return a.sin6_addr < b.sin6_addr or a.sin6_port < b.sin6_port;
return memcmp(&a, &b, sizeof(in6_addr));
}
namespace net
@ -261,3 +215,61 @@ namespace llarp
} // namespace net
} // namespace llarp
inline bool
operator==(const in_addr& a, const in_addr& b)
{
return llarp::cmp(a, b) == 0;
}
inline bool
operator==(const in6_addr& a, const in6_addr& b)
{
return llarp::cmp(a, b) == 0;
}
inline bool
operator==(const sockaddr_in& a, const sockaddr_in& b)
{
return a.sin_port == b.sin_port and a.sin_addr.s_addr == b.sin_addr.s_addr;
}
inline bool
operator==(const sockaddr_in6& a, const sockaddr_in6& b)
{
return a.sin6_port == b.sin6_port and a.sin6_addr == b.sin6_addr;
}
inline bool
operator==(const sockaddr& a, const sockaddr& b)
{
if (a.sa_family != b.sa_family)
return false;
switch (a.sa_family)
{
case AF_INET:
return reinterpret_cast<const sockaddr_in&>(a) == reinterpret_cast<const sockaddr_in&>(b);
case AF_INET6:
return reinterpret_cast<const sockaddr_in6&>(a) == reinterpret_cast<const sockaddr_in6&>(b);
default:
return false;
}
}
inline bool
operator<(const in_addr& a, const in_addr& b)
{
return llarp::cmp(a, b) < 0;
}
inline bool
operator<(const in6_addr& a, const in6_addr& b)
{
return llarp::cmp(a, b) < 0;
}
inline bool
operator<(const sockaddr_in6& a, const sockaddr_in6& b)
{
return std::tie(a.sin6_addr, a.sin6_port) < std::tie(b.sin6_addr, b.sin6_port);
}

@ -93,7 +93,8 @@ namespace llarp::net
return IPRange::FindPrivateRange(currentRanges);
}
std::optional<int> GetInterfaceIndex(ipaddr_t) const override
std::optional<int>
GetInterfaceIndex(ipaddr_t) const override
{
// todo: implement me
return std::nullopt;

@ -206,15 +206,13 @@ namespace llarp
bool
SockAddr::operator<(const SockAddr& other) const
{
return (m_addr.sin6_addr < other.m_addr.sin6_addr)
or (m_addr.sin6_port < other.m_addr.sin6_port);
return m_addr < other.m_addr;
}
bool
SockAddr::operator==(const SockAddr& other) const
{
return m_addr.sin6_addr == other.m_addr.sin6_addr
and m_addr.sin6_port == other.m_addr.sin6_port;
return m_addr == other.m_addr;
}
huint128_t

@ -33,11 +33,7 @@ namespace llarp::net
bool
operator<(const ProtocolInfo& other) const
{
if (port and other.port)
{
return protocol < other.protocol or *port < *other.port;
}
return protocol < other.protocol;
return std::tie(protocol, port) < std::tie(other.protocol, other.port);
}
ProtocolInfo() = default;

@ -141,25 +141,25 @@ namespace llarp
constexpr bool
operator<(const uint128_t& b) const
{
return upper < b.upper || (upper == b.upper && lower < b.lower);
return std::tie(upper, lower) < std::tie(b.upper, b.lower);
}
constexpr bool
operator<=(const uint128_t& b) const
{
return upper < b.upper || (upper == b.upper && lower <= b.lower);
return std::tie(upper, lower) <= std::tie(b.upper, b.lower);
}
constexpr bool
operator>(const uint128_t& b) const
{
return upper > b.upper || (upper == b.upper && lower > b.lower);
return std::tie(upper, lower) > std::tie(b.upper, b.lower);
}
constexpr bool
operator>=(const uint128_t& b) const
{
return upper > b.upper || (upper == b.upper && lower >= b.lower);
return std::tie(upper, lower) >= std::tie(b.upper, b.lower);
}
constexpr uint128_t&

@ -412,7 +412,8 @@ namespace llarp
return nullptr;
}
void PathContext::RemovePathSet(PathSet_ptr)
void
PathContext::RemovePathSet(PathSet_ptr)
{}
} // namespace path
} // namespace llarp

@ -335,7 +335,8 @@ namespace llarp
Build(*maybe, roles);
}
bool Builder::UrgentBuild(llarp_time_t) const
bool
Builder::UrgentBuild(llarp_time_t) const
{
return buildIntervalLimit > MIN_PATH_BUILD_INTERVAL * 4;
}

@ -73,7 +73,8 @@ namespace llarp
}
}
void PathSet::Tick(llarp_time_t)
void
PathSet::Tick(llarp_time_t)
{
std::unordered_set<RouterID> endpoints;
for (auto& item : m_Paths)

@ -210,19 +210,22 @@ namespace llarp
BlacklistSNode(const RouterID) = 0;
/// override me in subtype
virtual bool HandleGotIntroMessage(std::shared_ptr<const dht::GotIntroMessage>)
virtual bool
HandleGotIntroMessage(std::shared_ptr<const dht::GotIntroMessage>)
{
return false;
}
/// override me in subtype
virtual bool HandleGotRouterMessage(std::shared_ptr<const dht::GotRouterMessage>)
virtual bool
HandleGotRouterMessage(std::shared_ptr<const dht::GotRouterMessage>)
{
return false;
}
/// override me in subtype
virtual bool HandleGotNameMessage(std::shared_ptr<const dht::GotNameMessage>)
virtual bool
HandleGotNameMessage(std::shared_ptr<const dht::GotNameMessage>)
{
return false;
}

@ -308,7 +308,8 @@ namespace llarp
throw std::logic_error{"Peer stats backend not enabled!"};
}
void PeerDb::loadDatabase(std::optional<fs::path>)
void
PeerDb::loadDatabase(std::optional<fs::path>)
{}
void
@ -349,7 +350,8 @@ namespace llarp
PeerDb::configure(const RouterConfig&)
{}
bool PeerDb::shouldFlush(llarp_time_t)
bool
PeerDb::shouldFlush(llarp_time_t)
{
return false;
}

@ -199,14 +199,12 @@ namespace llarp
virtual bool
IsServiceNode() const = 0;
virtual bool
IsActiveServiceNode() const = 0;
/// If we are running as a service node and appear active, i.e. registered and not
/// decommissioned, we should *not* ping core if we know of too few peers, to indicate to core
/// we are not in a good state.
virtual bool
ShouldPingOxen() const = 0;
/// Called to determine if we're in a bad state (which gets reported to our oxend) that should
/// prevent uptime proofs from going out to the network (so that the error state gets noticed).
/// Currently this means we require a decent number of peers whenever we are fully staked
/// (active or decommed).
virtual std::optional<std::string>
OxendErrorState() const = 0;
virtual bool
StartRpcServer() = 0;
@ -315,7 +313,9 @@ namespace llarp
/// set router's service node whitelist
virtual void
SetRouterWhitelist(
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist) = 0;
const std::vector<RouterID>& whitelist,
const std::vector<RouterID>& greylist,
const std::vector<RouterID>& unfundedlist) = 0;
virtual std::unordered_set<RouterID>
GetRouterWhitelist() const = 0;

@ -34,7 +34,9 @@ namespace llarp
virtual void
SetRouterWhitelist(
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist) = 0;
const std::vector<RouterID>& whitelist,
const std::vector<RouterID>& greylist,
const std::vector<RouterID>& greenlist) = 0;
virtual void
GetRC(const RouterID& router, RCRequestCallback callback, bool forceLookup = false) = 0;
@ -48,6 +50,12 @@ namespace llarp
virtual bool
IsGreylisted(const RouterID& remote) const = 0;
virtual bool
IsGreenlisted(const RouterID& remote) const = 0;
virtual bool
IsRegistered(const RouterID& remote) const = 0;
virtual bool
CheckRC(const RouterContact& rc) const = 0;

@ -32,26 +32,28 @@ namespace llarp
whitelistRouters.erase(router);
}
static void
loadColourList(std::unordered_set<RouterID>& beigelist, const std::vector<RouterID>& new_beige)
{
beigelist.clear();
beigelist.insert(new_beige.begin(), new_beige.end());
}
void
RCLookupHandler::SetRouterWhitelist(
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist)
const std::vector<RouterID>& whitelist,
const std::vector<RouterID>& greylist,
const std::vector<RouterID>& greenlist)
{
if (whitelist.empty())
return;
util::Lock l(_mutex);
whitelistRouters.clear();
greylistRouters.clear();
for (auto& router : whitelist)
{
whitelistRouters.emplace(router);
}
for (auto& router : greylist)
{
greylistRouters.emplace(router);
}
loadColourList(whitelistRouters, whitelist);
loadColourList(greylistRouters, greylist);
loadColourList(greenlistRouters, greenlist);
LogInfo("lokinet service node list now has ", whitelistRouters.size(), " routers");
LogInfo("lokinet service node list now has ", whitelistRouters.size(), " active routers");
}
bool
@ -140,6 +142,21 @@ namespace llarp
return greylistRouters.count(remote);
}
bool
RCLookupHandler::IsGreenlisted(const RouterID& remote) const
{
util::Lock lock{_mutex};
return greenlistRouters.count(remote);
}
bool
RCLookupHandler::IsRegistered(const RouterID& remote) const
{
util::Lock lock{_mutex};
return whitelistRouters.count(remote) || greylistRouters.count(remote)
|| greenlistRouters.count(remote);
}
bool
RCLookupHandler::PathIsAllowed(const RouterID& remote) const
{

@ -42,8 +42,11 @@ namespace llarp
void
SetRouterWhitelist(
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist) override
EXCLUDES(_mutex);
const std::vector<RouterID>& whitelist,
const std::vector<RouterID>& greylist,
const std::vector<RouterID>& greenlist
) override EXCLUDES(_mutex);
bool
HaveReceivedWhitelist() const override;
@ -61,6 +64,16 @@ namespace llarp
bool
IsGreylisted(const RouterID& remote) const override EXCLUDES(_mutex);
// "greenlist" = new routers (i.e. "green") that aren't fully funded yet
bool
IsGreenlisted(const RouterID& remote) const override EXCLUDES(_mutex);
// registered just means that there is at least an operator stake, but doesn't require the node
// be fully funded, active, or not decommed. (In other words: it is any of the white, grey, or
// green list).
bool
IsRegistered(const RouterID& remote) const override EXCLUDES(_mutex);
bool
CheckRC(const RouterContact& rc) const override;
@ -134,8 +147,12 @@ namespace llarp
bool useWhitelist = false;
bool isServiceNode = false;
// whitelist = active routers
std::unordered_set<RouterID> whitelistRouters GUARDED_BY(_mutex);
// greylist = fully funded, but decommissioned routers
std::unordered_set<RouterID> greylistRouters GUARDED_BY(_mutex);
// greenlist = registered but not fully-staked routers
std::unordered_set<RouterID> greenlistRouters GUARDED_BY(_mutex);
using TimePoint = std::chrono::steady_clock::time_point;
std::unordered_map<RouterID, TimePoint> _routerLookupTimes;

@ -147,13 +147,16 @@ namespace llarp
auto& route = platform->RouteManager();
// find current gateways
// get current gateways, assume sorted by lowest metric first
auto gateways = route.GetGatewaysNotOnInterface(*vpn);
std::optional<net::ipv4addr_t> next_gw;
for (auto& gateway : gateways)
{
if (auto* gw_ptr = std::get_if<net::ipv4addr_t>(&gateway))
{
next_gw = *gw_ptr;
break;
}
}
// update current gateway and apply state changes as needed

@ -395,6 +395,31 @@ namespace llarp
{
m_Config = std::move(c);
auto& conf = *m_Config;
// Do logging config as early as possible to get the configured log level applied
// 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;
if (log::get_level_default() != log::Level::off)
log::reset_level(conf.logging.m_logLevel);
log::clear_sinks();
log::add_sink(log_type, conf.logging.m_logFile);
enableRPCServer = conf.api.m_enableRPCServer;
// re-add rpc log sink if rpc enabled, else free it
if (enableRPCServer and llarp::logRingBuffer)
log::add_sink(llarp::logRingBuffer, llarp::log::DEFAULT_PATTERN_MONO);
else
llarp::logRingBuffer = nullptr;
log::debug(logcat, "Configuring router");
whitelistRouters = conf.lokid.whitelistRouters;
if (whitelistRouters)
{
@ -402,33 +427,39 @@ namespace llarp
m_lokidRpcClient = std::make_shared<rpc::LokidRpcClient>(m_lmq, weak_from_this());
}
enableRPCServer = conf.api.m_enableRPCServer;
if (enableRPCServer)
rpcBindAddr = oxenmq::address(conf.api.m_rpcBindAddr);
log::debug(logcat, "Starting RPC server");
if (not StartRpcServer())
throw std::runtime_error("Failed to start rpc server");
if (conf.router.m_workerThreads > 0)
m_lmq->set_general_threads(conf.router.m_workerThreads);
log::debug(logcat, "Starting OMQ server");
m_lmq->start();
_nodedb = std::move(nodedb);
m_isServiceNode = conf.router.m_isRelay;
log::debug(
logcat, m_isServiceNode ? "Running as a relay (service node)" : "Running as a client");
if (whitelistRouters)
{
m_lokidRpcClient->ConnectAsync(lokidRPCAddr);
}
// fetch keys
log::debug(logcat, "Initializing key manager");
if (not m_keyManager->initialize(conf, true, isSNode))
throw std::runtime_error("KeyManager failed to initialize");
log::debug(logcat, "Initializing from configuration");
if (!FromConfig(conf))
throw std::runtime_error("FromConfig() failed");
log::debug(logcat, "Initializing identity");
if (not EnsureIdentity())
throw std::runtime_error("EnsureIdentity() failed");
return true;
@ -471,16 +502,14 @@ namespace llarp
return nodedb()->NumLoaded() < KnownPeerWarningThreshold;
}
bool
Router::IsActiveServiceNode() const
{
return IsServiceNode() and not(LooksDeregistered() or LooksDecommissioned());
}
bool
Router::ShouldPingOxen() const
std::optional<std::string>
Router::OxendErrorState() const
{
return IsActiveServiceNode() and not TooFewPeers();
// If we're in the white or gray list then we *should* be establishing connections to other
// routers, so if we have almost no peers then something is almost certainly wrong.
if (LooksFunded() and TooFewPeers())
return "too few peer connections; lokinet is not adequately connected to the network";
return std::nullopt;
}
void
@ -508,10 +537,17 @@ namespace llarp
}
bool
Router::LooksDeregistered() const
Router::LooksFunded() const
{
return IsServiceNode() and whitelistRouters and _rcLookupHandler.HaveReceivedWhitelist()
and _rcLookupHandler.SessionIsAllowed(pubkey());
}
bool
Router::LooksRegistered() const
{
return IsServiceNode() and whitelistRouters and _rcLookupHandler.HaveReceivedWhitelist()
and not _rcLookupHandler.SessionIsAllowed(pubkey());
and _rcLookupHandler.IsRegistered(pubkey());
}
bool
@ -596,6 +632,7 @@ namespace llarp
Router::FromConfig(const Config& conf)
{
// Set netid before anything else
log::debug(logcat, "Network ID set to {}", conf.router.m_netId);
if (!conf.router.m_netId.empty() && strcmp(conf.router.m_netId.c_str(), llarp::DEFAULT_NETID))
{
const auto& netid = conf.router.m_netId;
@ -635,28 +672,27 @@ namespace llarp
_ourAddress->setPort(*maybe_port);
else
throw std::runtime_error{"public ip provided without public port"};
log::debug(logcat, "Using {} for our public address", *_ourAddress);
}
else
log::debug(logcat, "No explicit public address given; will auto-detect during link setup");
RouterContact::BlockBogons = conf.router.m_blockBogons;
// Lokid Config
whitelistRouters = conf.lokid.whitelistRouters;
lokidRPCAddr = oxenmq::address(conf.lokid.lokidRPCAddr);
m_isServiceNode = conf.router.m_isRelay;
auto& networkConfig = conf.network;
/// build a set of strictConnectPubkeys (
/// TODO: make this consistent with config -- do we support multiple strict connections
// or not?
std::unordered_set<RouterID> strictConnectPubkeys;
if (not networkConfig.m_strictConnect.empty())
{
const auto& val = networkConfig.m_strictConnect;
if (IsServiceNode())
throw std::runtime_error("cannot use strict-connect option as service node");
if (val.size() < 2)
throw std::runtime_error(
"Must specify more than one strict-connect router if using strict-connect");
strictConnectPubkeys.insert(val.begin(), val.end());
log::debug(logcat, "{} strict-connect routers configured", val.size());
}
std::vector<fs::path> configRouters = conf.connect.routers;
@ -675,58 +711,51 @@ namespace llarp
}
}
BootstrapList b_list;
bootstrapRCList.clear();
for (const auto& router : configRouters)
{
b_list.AddFromFile(router);
log::debug(logcat, "Loading bootstrap router list from {}", defaultBootstrapFile);
bootstrapRCList.AddFromFile(router);
}
for (const auto& rc : conf.bootstrap.routers)
{
b_list.emplace(rc);
bootstrapRCList.emplace(rc);
}
// in case someone has an old bootstrap file and is trying to use a bootstrap
// that no longer exists
for (auto rc_itr = b_list.begin(); rc_itr != b_list.end();)
{
if (rc_itr->IsObsoleteBootstrap())
b_list.erase(rc_itr);
else
rc_itr++;
}
auto verifyRCs = [&]() {
for (auto& rc : b_list)
auto clearBadRCs = [this]() {
for (auto it = bootstrapRCList.begin(); it != bootstrapRCList.end();)
{
if (rc.IsObsoleteBootstrap())
{
log::warning(logcat, "ignoring obsolete boostrap RC: {}", RouterID(rc.pubkey));
continue;
}
if (not rc.Verify(Now()))
if (it->IsObsoleteBootstrap())
log::warning(logcat, "ignoring obsolete boostrap RC: {}", RouterID{it->pubkey});
else if (not it->Verify(Now()))
log::warning(logcat, "ignoring invalid bootstrap RC: {}", RouterID{it->pubkey});
else
{
log::warning(logcat, "ignoring invalid RC: {}", RouterID(rc.pubkey));
++it;
continue;
}
bootstrapRCList.emplace(std::move(rc));
// we are in one of the above error cases that we warned about:
it = bootstrapRCList.erase(it);
}
};
verifyRCs();
clearBadRCs();
if (bootstrapRCList.empty() and not conf.bootstrap.seednode)
{
auto fallbacks = llarp::load_bootstrap_fallbacks();
if (auto itr = fallbacks.find(_rc.netID.ToString()); itr != fallbacks.end())
{
b_list = itr->second;
verifyRCs();
bootstrapRCList = itr->second;
log::debug(logcat, "loaded {} default fallback bootstrap routers", bootstrapRCList.size());
clearBadRCs();
}
if (bootstrapRCList.empty()
and not conf.bootstrap.seednode) // empty after trying fallback, if set
if (bootstrapRCList.empty() and not conf.bootstrap.seednode)
{
// empty after trying fallback, if set
log::error(
logcat,
"No bootstrap routers were loaded. The default bootstrap file {} does not exist, and "
@ -797,26 +826,6 @@ namespace llarp
hiddenServiceContext().AddEndpoint(conf);
}
// Logging config
// 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;
if (log::get_level_default() != log::Level::off)
log::reset_level(conf.logging.m_logLevel);
log::clear_sinks();
log::add_sink(log_type, conf.logging.m_logFile);
// re-add rpc log sink if rpc enabled, else free it
if (enableRPCServer and llarp::logRingBuffer)
log::add_sink(llarp::logRingBuffer, llarp::log::DEFAULT_PATTERN_MONO);
else
llarp::logRingBuffer = nullptr;
return true;
}
@ -973,7 +982,7 @@ namespace llarp
// don't purge bootstrap nodes from nodedb
if (IsBootstrapNode(rc.pubkey))
{
log::debug(logcat, "Not removing {}: is bootstrap node", rc.pubkey);
log::trace(logcat, "Not removing {}: is bootstrap node", rc.pubkey);
return false;
}
// if for some reason we stored an RC that isn't a valid router
@ -1058,18 +1067,22 @@ namespace llarp
connectToNum = strictConnect;
}
if (now >= m_NextDecommissionWarn)
if (isSvcNode and now >= m_NextDecommissionWarn)
{
constexpr auto DecommissionWarnInterval = 5min;
if (auto dereg = LooksDeregistered(); dereg or decom)
if (auto registered = LooksRegistered(), funded = LooksFunded();
not(registered and funded and not decom))
{
// complain about being deregistered
LogError(
"We are running as a service node but we seem to be ",
dereg ? "deregistered" : "decommissioned");
// complain about being deregistered/decommed/unfunded
log::error(
logcat,
"We are running as a service node but we seem to be {}",
not registered ? "deregistered"
: decom ? "decommissioned"
: "not fully staked");
m_NextDecommissionWarn = now + DecommissionWarnInterval;
}
else if (isSvcNode and TooFewPeers())
else if (TooFewPeers())
{
log::error(
logcat,
@ -1079,9 +1092,9 @@ namespace llarp
}
}
// if we need more sessions to routers and we are not a service node kicked from the network
// we shall connect out to others
if (connected < connectToNum and not LooksDeregistered())
// if we need more sessions to routers and we are not a service node kicked from the network or
// we are a client we shall connect out to others
if (connected < connectToNum and (LooksFunded() or not isSvcNode))
{
size_t dlt = connectToNum - connected;
LogDebug("connecting to ", dlt, " random routers to keep alive");
@ -1233,9 +1246,11 @@ namespace llarp
void
Router::SetRouterWhitelist(
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist)
const std::vector<RouterID>& whitelist,
const std::vector<RouterID>& greylist,
const std::vector<RouterID>& unfundedlist)
{
_rcLookupHandler.SetRouterWhitelist(whitelist, greylist);
_rcLookupHandler.SetRouterWhitelist(whitelist, greylist, unfundedlist);
}
bool

@ -143,7 +143,9 @@ namespace llarp
void
SetRouterWhitelist(
const std::vector<RouterID>& whitelist, const std::vector<RouterID>& greylist) override;
const std::vector<RouterID>& whitelist,
const std::vector<RouterID>& greylist,
const std::vector<RouterID>& unfunded) override;
std::unordered_set<RouterID>
GetRouterWhitelist() const override
@ -203,9 +205,16 @@ namespace llarp
bool
LooksDecommissioned() const;
/// return true if we look like we are a deregistered service node
/// return true if we look like we are a registered, fully-staked service node (either active or
/// decommissioned). This condition determines when we are allowed to (and attempt to) connect
/// to other peers when running as a service node.
bool
LooksDeregistered() const;
LooksFunded() const;
/// return true if we a registered service node; not that this only requires a partial stake,
/// and does not imply that this service node is *active* or fully funded.
bool
LooksRegistered() const;
/// return true if we look like we are allowed and able to test other routers
bool
@ -378,12 +387,8 @@ namespace llarp
bool
IsServiceNode() const override;
/// return true if service node *and* not deregistered or decommissioned
bool
IsActiveServiceNode() const override;
bool
ShouldPingOxen() const override;
std::optional<std::string>
OxendErrorState() const override;
void
Close();
@ -556,8 +561,11 @@ namespace llarp
bool m_isServiceNode = false;
// Delay warning about being decommed/dereged until we've had enough time to sync up with oxend
static constexpr auto DECOMM_WARNING_STARTUP_DELAY = 15s;
llarp_time_t m_LastStatsReport = 0s;
llarp_time_t m_NextDecommissionWarn = 0s;
llarp_time_t m_NextDecommissionWarn = time_now_ms() + DECOMM_WARNING_STARTUP_DELAY;
std::shared_ptr<llarp::KeyManager> m_keyManager;
std::shared_ptr<PeerDb> m_peerDb;

@ -41,7 +41,7 @@ namespace llarp
bool
operator<(const RouterVersion& other) const
{
return m_ProtoVersion < other.m_ProtoVersion || m_Version < other.m_Version;
return std::tie(m_ProtoVersion, m_Version) < std::tie(other.m_ProtoVersion, other.m_Version);
}
bool

@ -112,35 +112,57 @@ namespace llarp
void
LokidRpcClient::UpdateServiceNodeList()
{
nlohmann::json request, fields;
fields["pubkey_ed25519"] = true;
fields["service_node_pubkey"] = true;
fields["funded"] = true;
fields["active"] = true;
request["fields"] = fields;
m_UpdatingList = true;
if (m_UpdatingList.exchange(true))
return; // update already in progress
nlohmann::json request{
{"fields",
{
{"pubkey_ed25519", true},
{"service_node_pubkey", true},
{"funded", true},
{"active", true},
{"block_hash", true},
}},
};
if (!m_LastUpdateHash.empty())
request["fields"]["poll_block_hash"] = m_LastUpdateHash;
Request(
"rpc.get_service_nodes",
[self = shared_from_this()](bool success, std::vector<std::string> data) {
self->m_UpdatingList = false;
if (not success)
{
LogWarn("failed to update service node list");
return;
}
if (data.size() < 2)
{
LogWarn("lokid gave empty reply for service node list");
return;
}
try
else if (data.size() < 2)
LogWarn("oxend gave empty reply for service node list");
else
{
self->HandleGotServiceNodeList(std::move(data[1]));
}
catch (std::exception& ex)
{
LogError("failed to process service node list: ", ex.what());
try
{
auto json = nlohmann::json::parse(std::move(data[1]));
if (json.at("status") != "OK")
throw std::runtime_error{"get_service_nodes did not return 'OK' status"};
if (auto it = json.find("unchanged");
it != json.end() and it->is_boolean() and it->get<bool>())
LogDebug("service node list unchanged");
else
{
self->HandleNewServiceNodeList(json.at("service_node_states"));
if (auto it = json.find("block_hash"); it != json.end() and it->is_string())
self->m_LastUpdateHash = it->get<std::string>();
else
self->m_LastUpdateHash.clear();
}
}
catch (const std::exception& ex)
{
LogError("failed to process service node list: ", ex.what());
}
}
// set down here so that the 1) we don't start updating until we're completely finished
// with the previous update; and 2) so that m_UpdatingList also guards m_LastUpdateHash
self->m_UpdatingList = false;
},
request.dump());
}
@ -152,25 +174,27 @@ namespace llarp
auto makePingRequest = [self = shared_from_this()]() {
// send a ping
PubKey pk{};
bool should_ping = false;
if (auto r = self->m_Router.lock())
{
pk = r->pubkey();
should_ping = r->ShouldPingOxen();
}
if (should_ping)
{
nlohmann::json payload = {
{"pubkey_ed25519", oxenc::to_hex(pk.begin(), pk.end())},
{"version", {VERSION[0], VERSION[1], VERSION[2]}}};
self->Request(
"admin.lokinet_ping",
[](bool success, std::vector<std::string> data) {
(void)data;
LogDebug("Received response for ping. Successful: ", success);
},
payload.dump());
}
auto r = self->m_Router.lock();
if (not r)
return; // router has gone away, maybe shutting down?
pk = r->pubkey();
nlohmann::json payload = {
{"pubkey_ed25519", oxenc::to_hex(pk.begin(), pk.end())},
{"version", {VERSION[0], VERSION[1], VERSION[2]}}};
if (auto err = r->OxendErrorState())
payload["error"] = *err;
self->Request(
"admin.lokinet_ping",
[](bool success, std::vector<std::string> data) {
(void)data;
LogDebug("Received response for ping. Successful: ", success);
},
payload.dump());
// subscribe to block updates
self->Request("sub.block", [](bool success, std::vector<std::string> data) {
if (data.empty() or not success)
@ -180,52 +204,53 @@ namespace llarp
}
LogDebug("subscribed to new blocks: ", data[0]);
});
// Trigger an update on a regular timer as well in case we missed a block notify for some
// reason (e.g. oxend restarts and loses the subscription); we poll using the last known
// hash so that the poll is very cheap (basically empty) if the block hasn't advanced.
self->UpdateServiceNodeList();
};
// Fire one ping off right away to get things going.
makePingRequest();
m_lokiMQ->add_timer(makePingRequest, PingInterval);
// initial fetch of service node list
UpdateServiceNodeList();
}
void
LokidRpcClient::HandleGotServiceNodeList(std::string data)
LokidRpcClient::HandleNewServiceNodeList(const nlohmann::json& j)
{
auto j = nlohmann::json::parse(std::move(data));
if (const auto itr = j.find("unchanged"); itr != j.end() and itr->get<bool>())
{
LogDebug("service node list unchanged");
return;
}
std::unordered_map<RouterID, PubKey> keymap;
std::vector<RouterID> activeNodeList, nonActiveNodeList;
if (const auto itr = j.find("service_node_states"); itr != j.end() and itr->is_array())
std::vector<RouterID> activeNodeList, decommNodeList, unfundedNodeList;
if (not j.is_array())
throw std::runtime_error{
"Invalid service node list: expected array of service node states"};
for (auto& snode : j)
{
for (auto& snode : *itr)
{
// Skip unstaked snodes:
if (const auto funded_itr = snode.find("funded"); funded_itr == snode.end()
or not funded_itr->is_boolean() or not funded_itr->get<bool>())
continue;
const auto ed_itr = snode.find("pubkey_ed25519");
if (ed_itr == snode.end() or not ed_itr->is_string())
continue;
const auto svc_itr = snode.find("service_node_pubkey");
if (svc_itr == snode.end() or not svc_itr->is_string())
continue;
const auto active_itr = snode.find("active");
if (active_itr == snode.end() or not active_itr->is_boolean())
continue;
const bool active = active_itr->get<bool>();
RouterID rid;
PubKey pk;
if (not rid.FromHex(ed_itr->get<std::string_view>())
or not pk.FromHex(svc_itr->get<std::string_view>()))
continue;
keymap[rid] = pk;
(active ? activeNodeList : nonActiveNodeList).push_back(std::move(rid));
}
const auto ed_itr = snode.find("pubkey_ed25519");
if (ed_itr == snode.end() or not ed_itr->is_string())
continue;
const auto svc_itr = snode.find("service_node_pubkey");
if (svc_itr == snode.end() or not svc_itr->is_string())
continue;
const auto active_itr = snode.find("active");
if (active_itr == snode.end() or not active_itr->is_boolean())
continue;
const bool active = active_itr->get<bool>();
const auto funded_itr = snode.find("funded");
if (funded_itr == snode.end() or not funded_itr->is_boolean())
continue;
const bool funded = funded_itr->get<bool>();
RouterID rid;
PubKey pk;
if (not rid.FromHex(ed_itr->get<std::string_view>())
or not pk.FromHex(svc_itr->get<std::string_view>()))
continue;
keymap[rid] = pk;
(active ? activeNodeList
: funded ? decommNodeList
: unfundedNodeList)
.push_back(std::move(rid));
}
if (activeNodeList.empty())
@ -233,17 +258,19 @@ namespace llarp
LogWarn("got empty service node list, ignoring.");
return;
}
// inform router about the new list
if (auto router = m_Router.lock())
{
auto& loop = router->loop();
loop->call([this,
active = std::move(activeNodeList),
inactive = std::move(nonActiveNodeList),
decomm = std::move(decommNodeList),
unfunded = std::move(unfundedNodeList),
keymap = std::move(keymap),
router = std::move(router)]() mutable {
m_KeyMap = std::move(keymap);
router->SetRouterWhitelist(active, inactive);
router->SetRouterWhitelist(active, decomm, unfunded);
});
}
else

@ -55,6 +55,8 @@ namespace llarp
void
Command(std::string_view cmd);
/// triggers a service node list refresh from oxend; thread-safe and will do nothing if an
/// update is already in progress.
void
UpdateServiceNodeList();
@ -72,8 +74,10 @@ namespace llarp
m_lokiMQ->request(*m_Connection, std::move(cmd), std::move(func));
}
// Handles a service node list update; takes the "service_node_states" object of an oxend
// "get_service_nodes" rpc request.
void
HandleGotServiceNodeList(std::string json);
HandleNewServiceNodeList(const nlohmann::json& json);
// Handles request from lokid for peer stats on a specific peer
void
@ -88,6 +92,7 @@ namespace llarp
std::weak_ptr<AbstractRouter> m_Router;
std::atomic<bool> m_UpdatingList;
std::string m_LastUpdateHash;
std::unordered_map<RouterID, PubKey> m_KeyMap;

@ -40,6 +40,11 @@
#include <uvw.hpp>
#include <variant>
namespace
{
constexpr size_t MIN_ENDPOINTS_FOR_LNS_LOOKUP = 2;
} // namespace
namespace llarp
{
namespace service
@ -309,6 +314,7 @@ namespace llarp
auto obj = path::Builder::ExtractStatus();
obj["exitMap"] = m_ExitMap.ExtractStatus();
obj["identity"] = m_Identity.pub.Addr().ToString();
obj["networkReady"] = ReadyToDoLookup();
util::StatusObject authCodes;
for (const auto& [service, info] : m_RemoteAuthInfos)
@ -320,7 +326,8 @@ namespace llarp
return m_state->ExtractStatus(obj);
}
void Endpoint::Tick(llarp_time_t)
void
Endpoint::Tick(llarp_time_t)
{
const auto now = llarp::time_now_ms();
path::Builder::Tick(now);
@ -945,6 +952,22 @@ namespace llarp
return not m_ExitMap.Empty();
}
bool
Endpoint::ReadyToDoLookup(std::optional<uint64_t> numPaths) const
{
if (not numPaths)
{
path::Path::UniqueEndpointSet_t paths;
ForEachPath([&paths](auto path) {
if (path and path->IsReady())
paths.insert(path);
});
numPaths = paths.size();
}
return numPaths >= MIN_ENDPOINTS_FOR_LNS_LOOKUP;
}
void
Endpoint::LookupNameAsync(
std::string name,
@ -964,23 +987,20 @@ namespace llarp
}
LogInfo(Name(), " looking up LNS name: ", name);
path::Path::UniqueEndpointSet_t paths;
ForEachPath([&](auto path) {
ForEachPath([&paths](auto path) {
if (path and path->IsReady())
paths.insert(path);
});
constexpr size_t min_unique_lns_endpoints = 2;
constexpr size_t max_unique_lns_endpoints = 7;
// not enough paths
if (paths.size() < min_unique_lns_endpoints)
if (not ReadyToDoLookup(paths.size()))
{
LogWarn(
Name(),
" not enough paths for lns lookup, have ",
paths.size(),
" need ",
min_unique_lns_endpoints);
MIN_ENDPOINTS_FOR_LNS_LOOKUP);
handler(std::nullopt);
return;
}
@ -1005,11 +1025,12 @@ namespace llarp
handler(result);
};
constexpr size_t max_lns_lookup_endpoints = 7;
// pick up to max_unique_lns_endpoints random paths to do lookups from
std::vector<path::Path_ptr> chosenpaths;
chosenpaths.insert(chosenpaths.begin(), paths.begin(), paths.end());
std::shuffle(chosenpaths.begin(), chosenpaths.end(), CSRNG{});
chosenpaths.resize(std::min(paths.size(), max_unique_lns_endpoints));
chosenpaths.resize(std::min(paths.size(), max_lns_lookup_endpoints));
auto resultHandler =
m_state->lnsTracker.MakeResultHandler(name, chosenpaths.size(), maybeInvalidateCache);
@ -1165,7 +1186,8 @@ namespace llarp
return m_Identity.pub.Addr();
}
std::optional<EndpointBase::SendStat> Endpoint::GetStatFor(AddressVariant_t) const
std::optional<EndpointBase::SendStat>
Endpoint::GetStatFor(AddressVariant_t) const
{
// TODO: implement me
return std::nullopt;

@ -521,6 +521,9 @@ namespace llarp
return false;
}
bool
ReadyToDoLookup(std::optional<uint64_t> numPaths = std::nullopt) const;
protected:
IDataHandler* m_DataHandler = nullptr;
Identity m_Identity;

@ -80,7 +80,6 @@ namespace llarp
Clear();
std::array<byte_t, 4096> tmp;
llarp_buffer_t buf(tmp);
// this can throw
bool exists = fs::exists(fname);
@ -94,6 +93,7 @@ namespace llarp
// check for file
if (!exists)
{
llarp_buffer_t buf{tmp};
// regen and encode
RegenerateKeys();
if (!BEncode(&buf))
@ -108,6 +108,7 @@ namespace llarp
{
throw std::runtime_error{fmt::format("failed to write {}: {}", fname, e.what())};
}
return;
}
if (not fs::is_regular_file(fname))
@ -125,10 +126,11 @@ namespace llarp
throw std::length_error{"service identity too big"};
}
// (don't catch io error exceptions)
if (!bencode_decode_dict(*this, &buf))
throw std::length_error{"could not decode service identity"};
{
llarp_buffer_t buf{tmp};
if (!bencode_decode_dict(*this, &buf))
throw std::length_error{"could not decode service identity"};
}
auto crypto = CryptoManager::instance();
// ensure that the encryption key is set

@ -55,8 +55,8 @@ namespace llarp
bool
operator<(const Introduction& other) const
{
return expiresAt < other.expiresAt || pathID < other.pathID || router < other.router
|| version < other.version || latency < other.latency;
return std::tie(expiresAt, pathID, router, version, latency)
< std::tie(other.expiresAt, other.pathID, other.router, other.version, other.latency);
}
bool

@ -35,7 +35,8 @@ namespace llarp
}
/// handle lookup result for introsets
virtual bool HandleNameResponse(std::optional<Address>)
virtual bool
HandleNameResponse(std::optional<Address>)
{
return false;
}
@ -76,7 +77,8 @@ namespace llarp
RouterID endpoint;
/// return true if this lookup is for a remote address
virtual bool IsFor(EndpointBase::AddressVariant_t) const
virtual bool
IsFor(EndpointBase::AddressVariant_t) const
{
return false;
}

@ -25,7 +25,7 @@ namespace llarp::vpn
bool
operator<(const InterfaceAddress& other) const
{
return range < other.range or fam < other.fam;
return std::tie(range, fam) < std::tie(other.range, other.fam);
}
};

@ -125,7 +125,8 @@ namespace llarp::win32
return -1;
}
virtual bool WritePacket(net::IPPacket) override
virtual bool
WritePacket(net::IPPacket) override
{
return false;
}

@ -66,13 +66,14 @@ namespace llarp
return false;
}
llarp::huint128_t ObtainIPForAddr(std::variant<service::Address, RouterID>) override
llarp::huint128_t
ObtainIPForAddr(std::variant<service::Address, RouterID>) override
{
return {0};
}
std::optional<std::variant<service::Address, RouterID>> ObtainAddrForIP(
huint128_t) const override
std::optional<std::variant<service::Address, RouterID>>
ObtainAddrForIP(huint128_t) const override
{
return std::nullopt;
}

Loading…
Cancel
Save