From 86dcdde8d3f0323b80a5bec26da0cf25d960b8c1 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Thu, 22 Apr 2021 16:55:37 -0300 Subject: [PATCH 01/52] Add missing header Reported by TechnicalTumbleweed as needed to fix a build. --- llarp/router/route_poker.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llarp/router/route_poker.hpp b/llarp/router/route_poker.hpp index 979d59d65..3ea8c694a 100644 --- a/llarp/router/route_poker.hpp +++ b/llarp/router/route_poker.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace llarp From 6d12a7a712cfafb93a58107e6ce612d1a21d6408 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Apr 2021 06:08:02 -0400 Subject: [PATCH 02/52] fixes for android jni --- llarp/ev/ev_libuv.cpp | 4 +++- llarp/net/route.cpp | 4 +++- llarp/router/route_poker.cpp | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 13e63c180..a1d7b330b 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -368,7 +368,9 @@ namespace llarp::uv bool Loop::inEventLoop() const { - return m_EventLoopThreadID and *m_EventLoopThreadID == std::this_thread::get_id(); + if (m_EventLoopThreadID) + return *m_EventLoopThreadID == std::this_thread::get_id(); + return true; } } // namespace llarp::uv diff --git a/llarp/net/route.cpp b/llarp/net/route.cpp index 840f15dda..051d86fae 100644 --- a/llarp/net/route.cpp +++ b/llarp/net/route.cpp @@ -498,6 +498,8 @@ namespace llarp::net { std::vector gateways; #ifdef __linux__ +#ifdef ANDROID +#else std::ifstream inf("/proc/net/route"); for (std::string line; std::getline(inf, line);) { @@ -513,7 +515,7 @@ namespace llarp::net } } } - +#endif return gateways; #elif _WIN32 ForEachWIN32Interface([&](auto w32interface) { diff --git a/llarp/router/route_poker.cpp b/llarp/router/route_poker.cpp index 6ad13d147..02db6bbd8 100644 --- a/llarp/router/route_poker.cpp +++ b/llarp/router/route_poker.cpp @@ -119,7 +119,9 @@ namespace llarp const auto maybe = GetDefaultGateway(); if (not maybe.has_value()) { +#ifndef ANDROID LogError("Network is down"); +#endif // mark network lost m_HasNetwork = false; return; From 3e7137ad96f9382738a47c33977fa831b403c0c1 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Apr 2021 06:19:46 -0400 Subject: [PATCH 03/52] fix regression: llarp::Context::CallSafe was not deferring call on startup --- llarp/context.cpp | 2 +- llarp/ev/ev_libuv.cpp | 1 + test/regress/2020-06-08-key-backup-bug.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/llarp/context.cpp b/llarp/context.cpp index c62d5893d..9bf260ce7 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -27,7 +27,7 @@ namespace llarp { if (!loop) return false; - loop->call(std::move(f)); + loop->call_soon(std::move(f)); return true; } diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index a1d7b330b..9832082d8 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -370,6 +370,7 @@ namespace llarp::uv { if (m_EventLoopThreadID) return *m_EventLoopThreadID == std::this_thread::get_id(); + // assume we are in it because we haven't started up yet return true; } diff --git a/test/regress/2020-06-08-key-backup-bug.cpp b/test/regress/2020-06-08-key-backup-bug.cpp index 0de1fc85b..e4ebfaa97 100644 --- a/test/regress/2020-06-08-key-backup-bug.cpp +++ b/test/regress/2020-06-08-key-backup-bug.cpp @@ -6,7 +6,7 @@ llarp::RuntimeOptions opts = {false, false, false}; -/// make a llarp_main* with 1 endpoint that specifies a keyfile +/// make a context with 1 endpoint that specifies a keyfile static std::shared_ptr make_context(std::optional keyfile) { From d750f683285d28ba8a074dbcecc09461fc12ff99 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Apr 2021 10:40:10 -0400 Subject: [PATCH 04/52] prepare for ipv6 on android * remove 21/8 from ipv4 bogon ranges as it is being sold by DoD * start adding ipv6 bogon ranges --- .../network/loki/lokinet/LokinetDaemon.java | 30 ++++----- llarp/net/net.cpp | 65 ++++++++++++------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/android/src/network/loki/lokinet/LokinetDaemon.java b/android/src/network/loki/lokinet/LokinetDaemon.java index ed808d7a5..072d21ab4 100644 --- a/android/src/network/loki/lokinet/LokinetDaemon.java +++ b/android/src/network/loki/lokinet/LokinetDaemon.java @@ -114,11 +114,17 @@ public class LokinetDaemon extends VpnService builder.setMtu(1500); String[] parts = ourRange.split("/"); - String ourIP = parts[0]; + String ourIPv4 = parts[0]; int ourMask = Integer.parseInt(parts[1]); - builder.addAddress(ourIP, ourMask); + // set ip4 + builder.addAddress(ourIPv4, ourMask); builder.addRoute("0.0.0.0", 0); + // set ip6 + // TODO: convert ipv4 to fd00::/8 range for ipv6 + // builder.addAddress(ourIPv6, ourMask + 96); + // builder.addRoute("::", 0); + builder.addDnsServer(upstreamDNS); builder.setSession("Lokinet"); builder.setConfigureIntent(null); @@ -134,24 +140,10 @@ public class LokinetDaemon extends VpnService InjectVPNFD(); - if (!Configure(config)) - { - //TODO: close vpn FD if this fails, either on native side, or here if possible - Log.e(LOG_TAG, "failed to configure daemon"); - return START_NOT_STICKY; - } - - m_UDPSocket = GetUDPSocket(); - - if (m_UDPSocket <= 0) - { - Log.e(LOG_TAG, "failed to get proper UDP handle from daemon, aborting."); - return START_NOT_STICKY; - } - - protect(m_UDPSocket); - new Thread(() -> { + Configure(config); + m_UDPSocket = GetUDPSocket(); + protect(m_UDPSocket); Mainloop(); }).start(); diff --git a/llarp/net/net.cpp b/llarp/net/net.cpp index 48c886fef..05479d8dd 100644 --- a/llarp/net/net.cpp +++ b/llarp/net/net.cpp @@ -600,6 +600,40 @@ namespace llarp return false; } +#if !defined(TESTNET) + static constexpr std::array bogonRanges_v6 = { + // zero + IPRange{huint128_t{0}, netmask_ipv6_bits(128)}, + // loopback + IPRange{huint128_t{1}, netmask_ipv6_bits(128)}, + // yggdrasil + IPRange{huint128_t{uint128_t{0x0200'0000'0000'0000UL, 0UL}}, netmask_ipv6_bits(7)}, + // multicast + IPRange{huint128_t{uint128_t{0xff00'0000'0000'0000UL, 0UL}}, netmask_ipv6_bits(8)}, + // local + IPRange{huint128_t{uint128_t{0xfc00'0000'0000'0000UL, 0UL}}, netmask_ipv6_bits(8)}, + // local + IPRange{huint128_t{uint128_t{0xf800'0000'0000'0000UL, 0UL}}, netmask_ipv6_bits(8)}}; + + static constexpr std::array bogonRanges_v4 = { + IPRange::FromIPv4(0, 0, 0, 0, 8), + IPRange::FromIPv4(10, 0, 0, 0, 8), + IPRange::FromIPv4(100, 64, 0, 0, 10), + IPRange::FromIPv4(127, 0, 0, 0, 8), + IPRange::FromIPv4(169, 254, 0, 0, 16), + IPRange::FromIPv4(172, 16, 0, 0, 12), + IPRange::FromIPv4(192, 0, 0, 0, 24), + IPRange::FromIPv4(192, 0, 2, 0, 24), + IPRange::FromIPv4(192, 88, 99, 0, 24), + IPRange::FromIPv4(192, 168, 0, 0, 16), + IPRange::FromIPv4(198, 18, 0, 0, 15), + IPRange::FromIPv4(198, 51, 100, 0, 24), + IPRange::FromIPv4(203, 0, 113, 0, 24), + IPRange::FromIPv4(224, 0, 0, 0, 4), + IPRange::FromIPv4(240, 0, 0, 0, 4)}; + +#endif + bool IsBogon(const in6_addr& addr) { @@ -607,11 +641,14 @@ namespace llarp (void)addr; return false; #else - if (!ipv6_is_mapped_ipv4(addr)) + if (not ipv6_is_mapped_ipv4(addr)) { - static in6_addr zero = {}; - if (addr == zero) - return true; + const auto ip = net::In6ToHUInt(addr); + for (const auto& range : bogonRanges_v6) + { + if (range.Contains(ip)) + return true; + } return false; } return IsIPv4Bogon( @@ -636,28 +673,10 @@ namespace llarp } #if !defined(TESTNET) - static constexpr std::array bogonRanges = { - IPRange::FromIPv4(0, 0, 0, 0, 8), - IPRange::FromIPv4(10, 0, 0, 0, 8), - IPRange::FromIPv4(21, 0, 0, 0, 8), - IPRange::FromIPv4(100, 64, 0, 0, 10), - IPRange::FromIPv4(127, 0, 0, 0, 8), - IPRange::FromIPv4(169, 254, 0, 0, 16), - IPRange::FromIPv4(172, 16, 0, 0, 12), - IPRange::FromIPv4(192, 0, 0, 0, 24), - IPRange::FromIPv4(192, 0, 2, 0, 24), - IPRange::FromIPv4(192, 88, 99, 0, 24), - IPRange::FromIPv4(192, 168, 0, 0, 16), - IPRange::FromIPv4(198, 18, 0, 0, 15), - IPRange::FromIPv4(198, 51, 100, 0, 24), - IPRange::FromIPv4(203, 0, 113, 0, 24), - IPRange::FromIPv4(224, 0, 0, 0, 4), - IPRange::FromIPv4(240, 0, 0, 0, 4)}; - bool IsIPv4Bogon(const huint32_t& addr) { - for (const auto& bogon : bogonRanges) + for (const auto& bogon : bogonRanges_v4) { if (bogon.Contains(addr)) { From 8f588c9638f5c86f6eb1f61a6821b2e2ddad55e0 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Apr 2021 10:42:19 -0400 Subject: [PATCH 05/52] remove test case --- test/net/test_llarp_net.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/net/test_llarp_net.cpp b/test/net/test_llarp_net.cpp index aea061bd4..4e5b92902 100644 --- a/test/net/test_llarp_net.cpp +++ b/test/net/test_llarp_net.cpp @@ -80,11 +80,6 @@ TEST_CASE("Bogon") REQUIRE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(192, 168, 1, 111))); } - SECTION("Bogon_DoD_8") - { - REQUIRE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(21, 3, 37, 70))); - } - SECTION("Bogon_127_8") { REQUIRE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(127, 0, 0, 1))); From 8a74b55af35c18f81f5f33b7a3527a4868ebf38c Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 26 Apr 2021 06:41:23 -0400 Subject: [PATCH 06/52] limit calls to service node list updates for when we are synching the chain we dont spam with list updates --- llarp/rpc/lokid_rpc_client.cpp | 7 ++++++- llarp/rpc/lokid_rpc_client.hpp | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/llarp/rpc/lokid_rpc_client.cpp b/llarp/rpc/lokid_rpc_client.cpp index 691115f81..6051ce9bc 100644 --- a/llarp/rpc/lokid_rpc_client.cpp +++ b/llarp/rpc/lokid_rpc_client.cpp @@ -45,6 +45,7 @@ namespace llarp auto lokidCategory = m_lokiMQ->add_category("lokid", oxenmq::Access{oxenmq::AuthLevel::none}); lokidCategory.add_request_command( "get_peer_stats", [this](oxenmq::Message& m) { HandleGetPeerStats(m); }); + m_UpdatingList = false; } void @@ -83,7 +84,9 @@ namespace llarp return; // bail } LogDebug("new block at hieght ", msg.data[0]); - UpdateServiceNodeList(std::string{msg.data[1]}); + // don't upadate on block notification if an update is pending + if (not m_UpdatingList) + UpdateServiceNodeList(std::string{msg.data[1]}); } void @@ -95,9 +98,11 @@ namespace llarp request["active_only"] = true; if (not topblock.empty()) request["poll_block_hash"] = topblock; + m_UpdatingList = true; Request( "rpc.get_service_nodes", [self = shared_from_this()](bool success, std::vector data) { + self->m_UpdatingList = false; if (not success) { LogWarn("failed to update service node list"); diff --git a/llarp/rpc/lokid_rpc_client.hpp b/llarp/rpc/lokid_rpc_client.hpp index 08c84e9f1..2c4df49ab 100644 --- a/llarp/rpc/lokid_rpc_client.hpp +++ b/llarp/rpc/lokid_rpc_client.hpp @@ -76,6 +76,7 @@ namespace llarp LMQ_ptr m_lokiMQ; AbstractRouter* const m_Router; + std::atomic m_UpdatingList; }; } // namespace rpc From 4b4d261c0243ddfe0385012d8c30f020afee2358 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Tue, 27 Apr 2021 17:34:17 -0300 Subject: [PATCH 07/52] Limit builds to 6 jobs (4 for arm) The CI runners don't use fixed CPU cores anymore, so that they can better allocate jobs across idle cores, but this means ninja's default is running an insane number of parallel compilations that likely just makes things slower. Add 6-job limiting to match the core limits that used to be in place. --- .drone.jsonnet | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/.drone.jsonnet b/.drone.jsonnet index 93a8b82e1..54951b7b6 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -21,6 +21,7 @@ local debian_pipeline(name, image, werror=true, cmake_extra='', extra_cmds=[], + jobs=6, loki_repo=false, allow_fail=false) = { kind: 'pipeline', @@ -55,7 +56,7 @@ local debian_pipeline(name, image, (if werror then '-DWARNINGS_AS_ERRORS=ON ' else '') + '-DWITH_LTO=' + (if lto then 'ON ' else 'OFF ') + cmake_extra, - 'ninja -v', + 'ninja -j' + jobs + ' -v', '../contrib/ci/drone-gdb.sh ./test/testAll --use-colour yes', ] + extra_cmds, } @@ -93,6 +94,7 @@ local windows_cross_pipeline(name, image, cmake_extra='', toolchain='32', extra_cmds=[], + jobs=6, allow_fail=false) = { kind: 'pipeline', type: 'docker', @@ -121,7 +123,7 @@ local windows_cross_pipeline(name, image, (if lto then '' else '-DWITH_LTO=OFF ') + "-DBUILD_STATIC_DEPS=ON -DDOWNLOAD_SODIUM=ON -DBUILD_PACKAGE=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DNATIVE_BUILD=OFF -DSTATIC_LINK=ON" + cmake_extra, - 'ninja -v package', + 'ninja -j' + jobs + ' -v package', ] + extra_cmds, } ], @@ -178,7 +180,13 @@ local deb_builder(image, distro, distro_branch, arch='amd64', loki_repo=true) = // Macos build -local mac_builder(name, build_type='Release', werror=true, cmake_extra='', extra_cmds=[], allow_fail=false) = { +local mac_builder(name, + build_type='Release', + werror=true, + cmake_extra='', + extra_cmds=[], + jobs=6, + allow_fail=false) = { kind: 'pipeline', type: 'exec', name: name, @@ -198,7 +206,7 @@ local mac_builder(name, build_type='Release', werror=true, cmake_extra='', extra 'cd build', 'cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-fcolor-diagnostics -DCMAKE_BUILD_TYPE='+build_type+' ' + (if werror then '-DWARNINGS_AS_ERRORS=ON ' else '') + cmake_extra, - 'ninja -v', + 'ninja -j' + jobs + ' -v', './test/testAll --use-colour yes', ] + extra_cmds, } @@ -233,8 +241,8 @@ local mac_builder(name, build_type='Release', werror=true, cmake_extra='', extra cmake_extra='-DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8', loki_repo=true), // ARM builds (ARM64 and armhf) - debian_pipeline("Debian sid (ARM64)", "debian:sid", arch="arm64"), - debian_pipeline("Debian buster (armhf)", "arm32v7/debian:buster", arch="arm64", cmake_extra='-DDOWNLOAD_SODIUM=ON'), + debian_pipeline("Debian sid (ARM64)", "debian:sid", arch="arm64", jobs=4), + debian_pipeline("Debian buster (armhf)", "arm32v7/debian:buster", arch="arm64", cmake_extra='-DDOWNLOAD_SODIUM=ON', jobs=4), // Static armhf build (gets uploaded) debian_pipeline("Static (buster armhf)", "arm32v7/debian:buster", arch="arm64", deps='g++ python3-dev automake libtool', cmake_extra='-DBUILD_STATIC_DEPS=ON -DBUILD_SHARED_LIBS=OFF -DSTATIC_LINK=ON ' + @@ -243,7 +251,8 @@ local mac_builder(name, build_type='Release', werror=true, cmake_extra='', extra extra_cmds=[ '../contrib/ci/drone-check-static-libs.sh', 'UPLOAD_OS=linux-armhf ../contrib/ci/drone-static-upload.sh' - ]), + ], + jobs=4), // android apk builder apk_builder("android apk", "registry.oxen.rocks/lokinet-ci-android", extra_cmds=['UPLOAD_OS=anrdoid ../contrib/ci/drone-static-upload.sh']), From 35e4e8817bb0fd6d91cacc57830e0c4c0a50e3fb Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 28 Apr 2021 15:41:14 -0300 Subject: [PATCH 08/52] Add missing getIPv6 implementation --- llarp/net/sock_addr.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/llarp/net/sock_addr.cpp b/llarp/net/sock_addr.cpp index 3324493b3..85098d2ea 100644 --- a/llarp/net/sock_addr.cpp +++ b/llarp/net/sock_addr.cpp @@ -342,6 +342,17 @@ namespace llarp return {m_addr4.sin_addr.s_addr}; } + nuint128_t + SockAddr::getIPv6() const + { + nuint128_t a; + // Explicit cast to void* here to avoid non-trivial type copying warnings (technically this + // isn't trivial because of the zeroing default constructor, but it's trivial enough that this + // copy is safe). + std::memcpy(static_cast(&a), &m_addr.sin6_addr, 16); + return a; + } + void SockAddr::setIPv4(nuint32_t ip) { From 4ef25ef679785fc5c34303b25d5594360699a67c Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 28 Apr 2021 16:48:10 -0300 Subject: [PATCH 09/52] Add systemd-resolved dynamic DNS updating Wires up systemd support to configure DNS on startup and when enabling/disabling exit mode. On startup (and when turning off an exit) we tell systemd-resolved to direct .loki and .snode lookups to lokinet (leaving other DNS traffic alone). On exit enabling, we reconfigure it to resolve "." (i.e. the root DNS domain) so that all lookups come into it. --- contrib/systemd-resolved/README.md | 18 +++- contrib/systemd-resolved/lokinet.conf | 3 - contrib/systemd-resolved/lokinet.pkla | 4 + contrib/systemd-resolved/lokinet.rules | 9 ++ llarp/CMakeLists.txt | 1 + llarp/handlers/tun.cpp | 5 + llarp/router/route_poker.cpp | 11 +++ llarp/router/route_poker.hpp | 1 + llarp/router/systemd_resolved.cpp | 129 +++++++++++++++++++++++++ llarp/router/systemd_resolved.hpp | 18 ++++ 10 files changed, 194 insertions(+), 5 deletions(-) delete mode 100644 contrib/systemd-resolved/lokinet.conf create mode 100644 contrib/systemd-resolved/lokinet.pkla create mode 100644 contrib/systemd-resolved/lokinet.rules create mode 100644 llarp/router/systemd_resolved.cpp create mode 100644 llarp/router/systemd_resolved.hpp diff --git a/contrib/systemd-resolved/README.md b/contrib/systemd-resolved/README.md index e54f02f18..5cd18d98e 100644 --- a/contrib/systemd-resolved/README.md +++ b/contrib/systemd-resolved/README.md @@ -1,6 +1,20 @@ -To be put at `/usr/lib/systemd/resolved.conf.d/lokinet.conf` for distro use and `/etc/systemd/resolved.conf.d/lokinet.conf` for local admin use. +Lokinet now talks to systemd directly via sdbus to set up DNS, but in order for this to work the +user running lokinet (assumed `_lokinet` in these example files) needs permission to set dns servers +and domains. -To make use of it: +To set up the permissions: + +- If lokinet is running as some user other than `_lokinet` the change the `_lokinet` username inside + `lokinet.rules` and `lokinet.pkla`. + +- If on a Debian or Debian-derived distribution (such as Ubuntu) using polkit 105, + copy `lokinet.pkla` to `/var/lib/polkit-1/localauthority/10-vendor.d/lokinet.pkla` (for a distro + install) or `/etc/polkit-1/localauthority.conf.d/` (for a local install). + +- Copy `lokinet.rules` to `/usr/share/polkit-1/rules.d/` (distro install) or `/etc/polkit-1/rules.d` + (local install). + +Make use of it by switching to systemd-resolved: ``` sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf sudo systemctl enable --now systemd-resolved diff --git a/contrib/systemd-resolved/lokinet.conf b/contrib/systemd-resolved/lokinet.conf deleted file mode 100644 index 007db4fec..000000000 --- a/contrib/systemd-resolved/lokinet.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Resolve] -DNS=127.3.2.1 -Domains=~loki ~snode diff --git a/contrib/systemd-resolved/lokinet.pkla b/contrib/systemd-resolved/lokinet.pkla new file mode 100644 index 000000000..ec7ad7098 --- /dev/null +++ b/contrib/systemd-resolved/lokinet.pkla @@ -0,0 +1,4 @@ +[Allow lokinet to set DNS settings] +Identity=unix-user:_lokinet +Action=org.freedesktop.resolve1.set-dns-servers;org.freedesktop.resolve1.set-domains +ResultAny=yes diff --git a/contrib/systemd-resolved/lokinet.rules b/contrib/systemd-resolved/lokinet.rules new file mode 100644 index 000000000..60bbfb3e3 --- /dev/null +++ b/contrib/systemd-resolved/lokinet.rules @@ -0,0 +1,9 @@ +/* Allow lokinet to set DNS settings */ +polkit.addRule(function(action, subject) { + if ((action.id == "org.freedesktop.resolve1.set-dns-servers" || + action.id == "org.freedesktop.resolve1.set-domains") && + subject.user == "_lokinet") { + return polkit.Result.YES; + } +}); + diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 279b621a4..7314971f3 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -186,6 +186,7 @@ add_library(liblokinet router/rc_gossiper.cpp router/router.cpp router/route_poker.cpp + router/systemd_resolved.cpp routing/dht_message.cpp routing/message_parser.cpp routing/path_confirm_message.cpp diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index ba7a1ac7f..441bf0843 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -784,6 +785,10 @@ namespace llarp Router()->loop()->add_ticker([this] { Flush(); }); + // Attempt to register DNS on the interface + systemd_resolved_set_dns(m_IfName, m_LocalResolverAddr.createSockAddr(), + false /* just .loki/.snode DNS initially */); + if (m_OnUp) { m_OnUp->NotifyAsync(NotifyParams()); diff --git a/llarp/router/route_poker.cpp b/llarp/router/route_poker.cpp index 6ad13d147..251216344 100644 --- a/llarp/router/route_poker.cpp +++ b/llarp/router/route_poker.cpp @@ -1,5 +1,6 @@ #include "route_poker.hpp" #include "abstractrouter.hpp" +#include "net/sock_addr.hpp" #include #include #include @@ -157,6 +158,11 @@ namespace llarp Update(); m_Enabling = false; m_Enabled = true; + + systemd_resolved_set_dns( + m_Router->hiddenServiceContext().GetDefault()->GetIfName(), + m_Router->GetConfig()->dns.m_bind.createSockAddr(), + true /* route all DNS */); } void @@ -167,6 +173,11 @@ namespace llarp DisableAllRoutes(); m_Enabled = false; + + systemd_resolved_set_dns( + m_Router->hiddenServiceContext().GetDefault()->GetIfName(), + m_Router->GetConfig()->dns.m_bind.createSockAddr(), + false /* route DNS only for .loki/.snode */); } void diff --git a/llarp/router/route_poker.hpp b/llarp/router/route_poker.hpp index 3ea8c694a..f494fada8 100644 --- a/llarp/router/route_poker.hpp +++ b/llarp/router/route_poker.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "systemd_resolved.hpp" namespace llarp { diff --git a/llarp/router/systemd_resolved.cpp b/llarp/router/systemd_resolved.cpp new file mode 100644 index 000000000..295ca9c17 --- /dev/null +++ b/llarp/router/systemd_resolved.cpp @@ -0,0 +1,129 @@ +#include "systemd_resolved.hpp" +#include + +#include + +extern "C" { +#include +#include +} + +using namespace std::literals; + +namespace llarp { + +#ifndef WITH_SYSTEMD + + bool systemd_resolved_set_dns(std::string, llarp::SockAddr, bool) { + LogDebug("lokinet is not build with systemd support, cannot set systemd resolved DNS"); + return false; + } + +#else + + namespace { + template + void resolved_call(sd_bus* bus, const char* method, const char* arg_format, T... args) { + sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *msg = nullptr; + int r = sd_bus_call_method(bus, + "org.freedesktop.resolve1", + "/org/freedesktop/resolve1", + "org.freedesktop.resolve1.Manager", + method, + &error, + &msg, + arg_format, + args...); + + if (r < 0) + throw std::runtime_error{"sdbus resolved "s + method + " failed: " + strerror(-r)}; + + sd_bus_message_unref(msg); + sd_bus_error_free(&error); + } + + struct sd_bus_deleter { void operator()(sd_bus* ptr) const { sd_bus_unref(ptr); } }; + } + + bool systemd_resolved_set_dns(std::string ifname, llarp::SockAddr dns, bool global) { + unsigned int if_ndx = if_nametoindex(ifname.c_str()); + if (if_ndx == 0) { + LogWarn("No such interface '", ifname, "'"); + return false; + } + + // Connect to the system bus + sd_bus *bus = nullptr; + int r = sd_bus_open_system(&bus); + if (r < 0) { + LogWarn("Failed to connect to system bus to set DNS: ", strerror(-r)); + return false; + } + std::unique_ptr bus_ptr{bus}; + + try { + // This passing address by bytes and using two separate calls for ipv4/ipv6 is gross, but the + // alternative is to build up a bunch of crap with va_args, which is slightly more gross. + if (dns.isIPv6()) { + auto ipv6 = dns.getIPv6(); + static_assert(sizeof(ipv6) == 16); + auto* a = reinterpret_cast(&ipv6); + resolved_call(bus, "SetLinkDNSEx", "ia(iayqs)", + (int32_t) if_ndx, + (int) 1, // number of "iayqs"s we are passing + (int32_t) AF_INET6, // network address type + (int) 16, // network addr byte size + a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], // yuck + (uint16_t) dns.getPort(), + nullptr // dns server name (for TLS SNI which we don't care about) + ); + } + else + { + auto ipv4 = dns.getIPv4(); + static_assert(sizeof(ipv4) == 4); + auto* a = reinterpret_cast(&ipv4); + resolved_call(bus, "SetLinkDNSEx", "ia(iayqs)", + (int32_t) if_ndx, + (int) 1, // number of "iayqs"s we are passing + (int32_t) AF_INET, // network address type + (int) 4, // network addr byte size + a[0], a[1], a[2], a[3], // yuck + (uint16_t) dns.getPort(), + nullptr // dns server name (for TLS SNI which we don't care about) + ); + } + + if (global) + // Setting "." as a routing domain gives this DNS server higher priority in resolution + // compared to dns servers that are set without a domain (e.g. the default for a + // DHCP-configured DNS server) + resolved_call(bus, "SetLinkDomains", "ia(sb)", + (int32_t) if_ndx, + (int) 1, // array size + "." // global DNS root + ); + else + // Only resolve .loki and .snode through lokinet (so you keep using your local DNS server for + // everything else, which is nicer than forcing everything though lokinet's upstream DNS). + resolved_call(bus, "SetLinkDomains", "ia(sb)", + (int32_t) if_ndx, + (int) 2, // array size + "loki", // domain + (int) 1, // routing domain = true + "snode", // domain + (int) 1 // routing domain = true + ); + + return true; + + } catch (const std::exception& e) { + LogWarn("Failed to set DNS via systemd-resolved: ", e.what()); + } + return false; + } + +#endif // WITH_SYSTEMD + +} // namespace llarp diff --git a/llarp/router/systemd_resolved.hpp b/llarp/router/systemd_resolved.hpp new file mode 100644 index 000000000..c07cc6f89 --- /dev/null +++ b/llarp/router/systemd_resolved.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +namespace llarp +{ + /// Attempts to set lokinet as the DNS server for systemd-resolved. Returns true if successful, + /// false if unsupported or fails. (When compiled without systemd support this always returns + /// false without doing anything). + /// + /// \param if_name -- the interface name to which we add the DNS servers, e.g. lokitun0. + /// Typically tun_endpoint.GetIfName(). + /// \param dns -- the listening address of the lokinet DNS server + /// \param global -- whether to set up lokinet for all DNS queries (true) or just .loki & .snode + /// addresses (false). + bool systemd_resolved_set_dns(std::string if_name, llarp::SockAddr dns, bool global); +} From b9363c8d218ad7e02eff3efe0116461cfacd268d Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 28 Apr 2021 16:56:49 -0300 Subject: [PATCH 10/52] Put systemd ifdef around the headers, too --- llarp/router/systemd_resolved.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/llarp/router/systemd_resolved.cpp b/llarp/router/systemd_resolved.cpp index 295ca9c17..c5e4556d4 100644 --- a/llarp/router/systemd_resolved.cpp +++ b/llarp/router/systemd_resolved.cpp @@ -1,4 +1,16 @@ #include "systemd_resolved.hpp" + +#ifndef WITH_SYSTEMD + +namespace llarp { + bool systemd_resolved_set_dns(std::string, llarp::SockAddr, bool) { + LogDebug("lokinet is not build with systemd support, cannot set systemd resolved DNS"); + return false; + } +} + +#else + #include #include @@ -12,15 +24,6 @@ using namespace std::literals; namespace llarp { -#ifndef WITH_SYSTEMD - - bool systemd_resolved_set_dns(std::string, llarp::SockAddr, bool) { - LogDebug("lokinet is not build with systemd support, cannot set systemd resolved DNS"); - return false; - } - -#else - namespace { template void resolved_call(sd_bus* bus, const char* method, const char* arg_format, T... args) { From 1d48cd6d35696839a4ac2706651ae355ca8fd8f6 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 28 Apr 2021 17:07:44 -0300 Subject: [PATCH 11/52] format --- llarp/handlers/tun.cpp | 6 +- llarp/router/systemd_resolved.cpp | 142 +++++++++++++++++++----------- llarp/router/systemd_resolved.hpp | 5 +- 3 files changed, 98 insertions(+), 55 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 441bf0843..f58e6c5b8 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -786,8 +786,10 @@ namespace llarp Router()->loop()->add_ticker([this] { Flush(); }); // Attempt to register DNS on the interface - systemd_resolved_set_dns(m_IfName, m_LocalResolverAddr.createSockAddr(), - false /* just .loki/.snode DNS initially */); + systemd_resolved_set_dns( + m_IfName, + m_LocalResolverAddr.createSockAddr(), + false /* just .loki/.snode DNS initially */); if (m_OnUp) { diff --git a/llarp/router/systemd_resolved.cpp b/llarp/router/systemd_resolved.cpp index c5e4556d4..90a3b3f2a 100644 --- a/llarp/router/systemd_resolved.cpp +++ b/llarp/router/systemd_resolved.cpp @@ -2,8 +2,11 @@ #ifndef WITH_SYSTEMD -namespace llarp { - bool systemd_resolved_set_dns(std::string, llarp::SockAddr, bool) { +namespace llarp +{ + bool + systemd_resolved_set_dns(std::string, llarp::SockAddr, bool) + { LogDebug("lokinet is not build with systemd support, cannot set systemd resolved DNS"); return false; } @@ -15,21 +18,26 @@ namespace llarp { #include -extern "C" { +extern "C" +{ #include #include } using namespace std::literals; -namespace llarp { - - namespace { +namespace llarp +{ + namespace + { template - void resolved_call(sd_bus* bus, const char* method, const char* arg_format, T... args) { + void + resolved_call(sd_bus* bus, const char* method, const char* arg_format, T... args) + { sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus_message *msg = nullptr; - int r = sd_bus_call_method(bus, + sd_bus_message* msg = nullptr; + int r = sd_bus_call_method( + bus, "org.freedesktop.resolve1", "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", @@ -46,40 +54,59 @@ namespace llarp { sd_bus_error_free(&error); } - struct sd_bus_deleter { void operator()(sd_bus* ptr) const { sd_bus_unref(ptr); } }; - } + struct sd_bus_deleter + { + void + operator()(sd_bus* ptr) const + { + sd_bus_unref(ptr); + } + }; + } // namespace - bool systemd_resolved_set_dns(std::string ifname, llarp::SockAddr dns, bool global) { + bool + systemd_resolved_set_dns(std::string ifname, llarp::SockAddr dns, bool global) + { unsigned int if_ndx = if_nametoindex(ifname.c_str()); - if (if_ndx == 0) { + if (if_ndx == 0) + { LogWarn("No such interface '", ifname, "'"); return false; } // Connect to the system bus - sd_bus *bus = nullptr; + sd_bus* bus = nullptr; int r = sd_bus_open_system(&bus); - if (r < 0) { + if (r < 0) + { LogWarn("Failed to connect to system bus to set DNS: ", strerror(-r)); return false; } std::unique_ptr bus_ptr{bus}; - try { + try + { // This passing address by bytes and using two separate calls for ipv4/ipv6 is gross, but the // alternative is to build up a bunch of crap with va_args, which is slightly more gross. - if (dns.isIPv6()) { + if (dns.isIPv6()) + { auto ipv6 = dns.getIPv6(); static_assert(sizeof(ipv6) == 16); auto* a = reinterpret_cast(&ipv6); - resolved_call(bus, "SetLinkDNSEx", "ia(iayqs)", - (int32_t) if_ndx, - (int) 1, // number of "iayqs"s we are passing - (int32_t) AF_INET6, // network address type - (int) 16, // network addr byte size - a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], // yuck - (uint16_t) dns.getPort(), - nullptr // dns server name (for TLS SNI which we don't care about) + resolved_call( + bus, + "SetLinkDNSEx", + "ia(iayqs)", + (int32_t)if_ndx, + (int)1, // number of "iayqs"s we are passing + (int32_t)AF_INET6, // network address type + (int)16, // network addr byte size + // clang-format off + a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], + a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], // yuck + // clang-format on + (uint16_t)dns.getPort(), + nullptr // dns server name (for TLS SNI which we don't care about) ); } else @@ -87,14 +114,19 @@ namespace llarp { auto ipv4 = dns.getIPv4(); static_assert(sizeof(ipv4) == 4); auto* a = reinterpret_cast(&ipv4); - resolved_call(bus, "SetLinkDNSEx", "ia(iayqs)", - (int32_t) if_ndx, - (int) 1, // number of "iayqs"s we are passing - (int32_t) AF_INET, // network address type - (int) 4, // network addr byte size + resolved_call( + bus, + "SetLinkDNSEx", + "ia(iayqs)", + (int32_t)if_ndx, + (int)1, // number of "iayqs"s we are passing + (int32_t)AF_INET, // network address type + (int)4, // network addr byte size + // clang-format off a[0], a[1], a[2], a[3], // yuck - (uint16_t) dns.getPort(), - nullptr // dns server name (for TLS SNI which we don't care about) + // clang-format on + (uint16_t)dns.getPort(), + nullptr // dns server name (for TLS SNI which we don't care about) ); } @@ -102,31 +134,39 @@ namespace llarp { // Setting "." as a routing domain gives this DNS server higher priority in resolution // compared to dns servers that are set without a domain (e.g. the default for a // DHCP-configured DNS server) - resolved_call(bus, "SetLinkDomains", "ia(sb)", - (int32_t) if_ndx, - (int) 1, // array size - "." // global DNS root - ); + resolved_call( + bus, + "SetLinkDomains", + "ia(sb)", + (int32_t)if_ndx, + (int)1, // array size + "." // global DNS root + ); else - // Only resolve .loki and .snode through lokinet (so you keep using your local DNS server for - // everything else, which is nicer than forcing everything though lokinet's upstream DNS). - resolved_call(bus, "SetLinkDomains", "ia(sb)", - (int32_t) if_ndx, - (int) 2, // array size - "loki", // domain - (int) 1, // routing domain = true - "snode", // domain - (int) 1 // routing domain = true - ); + // Only resolve .loki and .snode through lokinet (so you keep using your local DNS server + // for everything else, which is nicer than forcing everything though lokinet's upstream + // DNS). + resolved_call( + bus, + "SetLinkDomains", + "ia(sb)", + (int32_t)if_ndx, + (int)2, // array size + "loki", // domain + (int)1, // routing domain = true + "snode", // domain + (int)1 // routing domain = true + ); return true; - - } catch (const std::exception& e) { + } + catch (const std::exception& e) + { LogWarn("Failed to set DNS via systemd-resolved: ", e.what()); } return false; } -#endif // WITH_SYSTEMD +#endif // WITH_SYSTEMD -} // namespace llarp +} // namespace llarp diff --git a/llarp/router/systemd_resolved.hpp b/llarp/router/systemd_resolved.hpp index c07cc6f89..8fc8c20af 100644 --- a/llarp/router/systemd_resolved.hpp +++ b/llarp/router/systemd_resolved.hpp @@ -14,5 +14,6 @@ namespace llarp /// \param dns -- the listening address of the lokinet DNS server /// \param global -- whether to set up lokinet for all DNS queries (true) or just .loki & .snode /// addresses (false). - bool systemd_resolved_set_dns(std::string if_name, llarp::SockAddr dns, bool global); -} + bool + systemd_resolved_set_dns(std::string if_name, llarp::SockAddr dns, bool global); +} // namespace llarp From 7963cd01815047aa8e2d90b35924cbb06563a7fd Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 28 Apr 2021 17:11:36 -0300 Subject: [PATCH 12/52] Fix headers & grammar for non-systemd --- llarp/router/systemd_resolved.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/llarp/router/systemd_resolved.cpp b/llarp/router/systemd_resolved.cpp index 90a3b3f2a..d0ee535c2 100644 --- a/llarp/router/systemd_resolved.cpp +++ b/llarp/router/systemd_resolved.cpp @@ -1,4 +1,5 @@ #include "systemd_resolved.hpp" +#include #ifndef WITH_SYSTEMD @@ -7,15 +8,13 @@ namespace llarp bool systemd_resolved_set_dns(std::string, llarp::SockAddr, bool) { - LogDebug("lokinet is not build with systemd support, cannot set systemd resolved DNS"); + LogDebug("lokinet is not built with systemd support, cannot set systemd resolved DNS"); return false; } -} +} // namespace llarp #else -#include - #include extern "C" @@ -167,6 +166,6 @@ namespace llarp return false; } -#endif // WITH_SYSTEMD - } // namespace llarp + +#endif // WITH_SYSTEMD From cecbddc912f9520be6216a16693d464c10af1e7e Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Thu, 29 Apr 2021 18:54:43 -0400 Subject: [PATCH 13/52] Fixes subtle memory leak, adds comments Fixes a subtle memory leak that was a result of outbound messages which were in the shared queue (not yet sorted into a per-path queue) when a path was removed, resulting in a ghost path queue (and thus round-robin order entry as well). Adds much needed documentation to the outbound message handler class. --- llarp/path/path_context.cpp | 2 +- llarp/path/pathset.cpp | 4 +- llarp/router/i_outbound_message_handler.hpp | 2 +- llarp/router/outbound_message_handler.cpp | 95 ++++++++++++--------- llarp/router/outbound_message_handler.hpp | 85 ++++++++++++++++-- 5 files changed, 137 insertions(+), 51 deletions(-) diff --git a/llarp/path/path_context.cpp b/llarp/path/path_context.cpp index accecefdd..fe737396e 100644 --- a/llarp/path/path_context.cpp +++ b/llarp/path/path_context.cpp @@ -302,7 +302,7 @@ namespace llarp { if (itr->second->Expired(now)) { - m_Router->outboundMessageHandler().QueueRemoveEmptyPath(itr->first); + m_Router->outboundMessageHandler().RemovePath(itr->first); itr = map.erase(itr); } else diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index 55c0b8b73..ae080bca7 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -85,9 +85,9 @@ namespace llarp if (itr->second->Expired(now)) { PathID_t txid = itr->second->TXID(); - router->outboundMessageHandler().QueueRemoveEmptyPath(std::move(txid)); + router->outboundMessageHandler().RemovePath(std::move(txid)); PathID_t rxid = itr->second->RXID(); - router->outboundMessageHandler().QueueRemoveEmptyPath(std::move(rxid)); + router->outboundMessageHandler().RemovePath(std::move(rxid)); itr = m_Paths.erase(itr); } else diff --git a/llarp/router/i_outbound_message_handler.hpp b/llarp/router/i_outbound_message_handler.hpp index 83f02d25c..0ab96c434 100644 --- a/llarp/router/i_outbound_message_handler.hpp +++ b/llarp/router/i_outbound_message_handler.hpp @@ -38,7 +38,7 @@ namespace llarp Tick() = 0; virtual void - QueueRemoveEmptyPath(const PathID_t& pathid) = 0; + RemovePath(const PathID_t& pathid) = 0; virtual util::StatusObject ExtractStatus() const = 0; diff --git a/llarp/router/outbound_message_handler.cpp b/llarp/router/outbound_message_handler.cpp index 1e3180723..b676383dd 100644 --- a/llarp/router/outbound_message_handler.cpp +++ b/llarp/router/outbound_message_handler.cpp @@ -15,14 +15,17 @@ namespace llarp { const PathID_t OutboundMessageHandler::zeroID; + using namespace std::chrono_literals; + OutboundMessageHandler::OutboundMessageHandler(size_t maxQueueSize) - : outboundQueue(maxQueueSize), removedPaths(20), removedSomePaths(false) + : outboundQueue(maxQueueSize), recentlyRemovedPaths(5s), removedSomePaths(false) {} bool OutboundMessageHandler::QueueMessage( const RouterID& remote, const ILinkMessage& msg, SendStatusHandler callback) { + // if the destination is invalid, callback with failure and return if (not _linkManager->SessionIsClient(remote) and not _lookupHandler->RemoteIsAllowed(remote)) { DoCallback(callback, SendStatus::InvalidRouter); @@ -44,26 +47,31 @@ namespace llarp std::copy_n(buf.base, buf.sz, message.first.data()); + // if we have a session to the destination, queue the message and return if (_linkManager->HasSessionTo(remote)) { QueueOutboundMessage(remote, std::move(message), msg.pathid, priority); return true; } + // if we don't have a session to the destination, queue the message onto + // a special pending session queue for that destination, and then create + // that pending session if there is not already a session establish attempt + // in progress. bool shouldCreateSession = false; { util::Lock l(_mutex); // create queue for if it doesn't exist, and get iterator - auto itr_pair = pendingSessionMessageQueues.emplace(remote, MessageQueue()); + auto [queue_itr, is_new] = pendingSessionMessageQueues.emplace(remote, MessageQueue()); MessageQueueEntry entry; entry.priority = priority; entry.message = message; entry.router = remote; - itr_pair.first->second.push(std::move(entry)); + queue_itr->second.push(std::move(entry)); - shouldCreateSession = itr_pair.second; + shouldCreateSession = is_new; } if (shouldCreateSession) @@ -77,26 +85,33 @@ namespace llarp void OutboundMessageHandler::Tick() { - m_Killer.TryAccess([self = this]() { - self->ProcessOutboundQueue(); - self->RemoveEmptyPathQueues(); - self->SendRoundRobin(); + m_Killer.TryAccess([this]() { + recentlyRemovedPaths.Decay(); + ProcessOutboundQueue(); + SendRoundRobin(); }); } void - OutboundMessageHandler::QueueRemoveEmptyPath(const PathID_t& pathid) + OutboundMessageHandler::RemovePath(const PathID_t& pathid) { - m_Killer.TryAccess([self = this, pathid]() { - if (self->removedPaths.full()) + m_Killer.TryAccess([this, pathid]() { + /* add the path id to a list of recently removed paths to act as a filter + * for messages that are queued but haven't been sorted into path queues yet. + * + * otherwise these messages would re-create the path queue we just removed, and + * those path queues would be leaked / never removed. + */ + recentlyRemovedPaths.Insert(pathid); + auto itr = outboundMessageQueues.find(pathid); + if (itr != outboundMessageQueues.end()) { - self->RemoveEmptyPathQueues(); + outboundMessageQueues.erase(itr); } - self->removedPaths.pushBack(pathid); + removedSomePaths = true; }); } - // TODO: this util::StatusObject OutboundMessageHandler::ExtractStatus() const { @@ -241,6 +256,8 @@ namespace llarp { MessageQueueEntry entry; entry.message = std::move(msg); + + // copy callback in case we need to call it, so we can std::move(entry) auto callback_copy = entry.message.second; entry.router = remote; entry.pathid = pathid; @@ -266,17 +283,23 @@ namespace llarp { while (not outboundQueue.empty()) { - // TODO: can we add util::thread::Queue::front() for move semantics here? MessageQueueEntry entry = outboundQueue.popFront(); - auto itr_pair = outboundMessageQueues.emplace(entry.pathid, MessageQueue()); + // messages may still be queued for processing when a pathid is removed, + // so check here if the pathid was recently removed. + if (recentlyRemovedPaths.Contains(entry.pathid)) + { + return; + } + + auto [queue_itr, is_new] = outboundMessageQueues.emplace(entry.pathid, MessageQueue()); - if (itr_pair.second && !entry.pathid.IsZero()) + if (is_new && !entry.pathid.IsZero()) { roundRobinOrder.push(entry.pathid); } - MessageQueue& path_queue = itr_pair.first->second; + MessageQueue& path_queue = queue_itr->second; if (path_queue.size() < MAX_PATH_QUEUE_SIZE || entry.pathid.IsZero()) { @@ -290,41 +313,25 @@ namespace llarp } } - void - OutboundMessageHandler::RemoveEmptyPathQueues() - { - removedSomePaths = false; - if (removedPaths.empty()) - return; - - while (not removedPaths.empty()) - { - auto itr = outboundMessageQueues.find(removedPaths.popFront()); - if (itr != outboundMessageQueues.end()) - { - outboundMessageQueues.erase(itr); - } - } - removedSomePaths = true; - } - void OutboundMessageHandler::SendRoundRobin() { m_queueStats.numTicks++; - // send non-routing messages first priority - auto& non_routing_mq = outboundMessageQueues[zeroID]; - while (not non_routing_mq.empty()) + // send routing messages first priority + auto& routing_mq = outboundMessageQueues[zeroID]; + while (not routing_mq.empty()) { - const MessageQueueEntry& entry = non_routing_mq.top(); + const MessageQueueEntry& entry = routing_mq.top(); Send(entry.router, entry.message); - non_routing_mq.pop(); + routing_mq.pop(); } size_t empty_count = 0; size_t num_queues = roundRobinOrder.size(); + // if any paths have been removed since last tick, remove any stale + // entries from the round-robin ordering if (removedSomePaths) { for (size_t i = 0; i < num_queues; i++) @@ -338,6 +345,7 @@ namespace llarp } } } + removedSomePaths = false; num_queues = roundRobinOrder.size(); size_t sent_count = 0; @@ -346,7 +354,10 @@ namespace llarp return; } - while (sent_count < MAX_OUTBOUND_MESSAGES_PER_TICK) // TODO: better stop condition + // send messages for each pathid in roundRobinOrder, stopping when + // either every path's queue is empty or a set maximum amount of + // messages have been sent. + while (sent_count < MAX_OUTBOUND_MESSAGES_PER_TICK) { PathID_t pathid = std::move(roundRobinOrder.front()); roundRobinOrder.pop(); diff --git a/llarp/router/outbound_message_handler.hpp b/llarp/router/outbound_message_handler.hpp index a3cfa4bad..51beac9cc 100644 --- a/llarp/router/outbound_message_handler.hpp +++ b/llarp/router/outbound_message_handler.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -27,15 +28,45 @@ namespace llarp OutboundMessageHandler(size_t maxQueueSize = MAX_OUTBOUND_QUEUE_SIZE); + /* Called to queue a message to be sent to a router. + * + * If there is no session with the destination router, the message is added to a + * pending session queue for that router. If there is no pending session to that + * router, one is created. + * + * If there is a session to the destination router, the message is placed on the shared + * outbound message queue to be processed on Tick(). + * + * When this class' Tick() is called, that queue is emptied and the messages there + * are placed in their paths' respective individual queues. + * + * Returns false if encoding the message into a buffer fails, true otherwise. + * A return value of true merely means we successfully processed the queue request, + * so for example an invalid destination still yields a true return. + */ bool QueueMessage(const RouterID& remote, const ILinkMessage& msg, SendStatusHandler callback) override EXCLUDES(_mutex); + /* Called once per event loop tick. + * + * Processes messages on the shared message queue into their paths' respective + * individual queues. + * + * Removes the individual queues for paths which have died / expired, as informed by + * QueueRemoveEmptyPath. + * + * Sends all routing messages that have been queued, indicated by pathid 0 when queued. + * Sends messages from path queues until all are empty or a set cap has been reached. + */ void Tick() override; + /* Called from outside this class to inform it that a path has died / expired + * and its queue should be discarded. + */ void - QueueRemoveEmptyPath(const PathID_t& pathid) override; + RemovePath(const PathID_t& pathid) override; util::StatusObject ExtractStatus() const override; @@ -46,6 +77,9 @@ namespace llarp private: using Message = std::pair, SendStatusHandler>; + /* A message that has been queued for sending, but not yet + * processed into an individual path's message queue. + */ struct MessageQueueEntry { uint16_t priority; @@ -73,6 +107,14 @@ namespace llarp using MessageQueue = std::priority_queue; + /* If a session is not yet created with the destination router for a message, + * a special queue is created for that router and an attempt is made to + * establish a session. When this establish attempt concludes, either + * the messages are then sent to that router immediately, on success, or + * the messages are dropped and their send status callbacks are invoked with + * the appropriate send status. + */ + void OnSessionEstablished(const RouterID& router); @@ -91,6 +133,7 @@ namespace llarp void OnSessionResult(const RouterID& router, const SessionResult result); + /* queues a message's send result callback onto the event loop */ void DoCallback(SendStatusHandler callback, SendStatus status); @@ -100,30 +143,62 @@ namespace llarp bool EncodeBuffer(const ILinkMessage& msg, llarp_buffer_t& buf); + /* sends the message along to the link layer, and hopefully out to the network + * + * returns the result of the call to LinkManager::SendTo() + */ bool Send(const RouterID& remote, const Message& msg); + /* Sends the message along to the link layer if we have a session to the remote + * + * returns the result of the Send() call, or false if no session. + */ bool SendIfSession(const RouterID& remote, const Message& msg); + /* queues a message to the shared outbound message queue. + * + * If the queue is full, the message is dropped and the message's status + * callback is invoked with a congestion status. + * + * When this class' Tick() is called, that queue is emptied and the messages there + * are placed in their paths' respective individual queues. + */ bool QueueOutboundMessage( const RouterID& remote, Message&& msg, const PathID_t& pathid, uint16_t priority = 0); + /* Processes messages on the shared message queue into their paths' respective + * individual queues. + */ void ProcessOutboundQueue(); - void - RemoveEmptyPathQueues(); - + /* + * Sends all routing messages that have been queued, indicated by pathid 0 when queued. + * + * Sends messages from path queues until all are empty or a set cap has been reached. + * This will send one message from each queue in a round-robin fashion such that they + * all have roughly equal access to bandwidth. A notion of priority may be introduced + * at a later time, but for now only routing messages get priority. + */ void SendRoundRobin(); + /* Invoked when an outbound session establish attempt has concluded. + * + * If the outbound session was successfully created, sends any messages queued + * for that destination along to it. + * + * If the session was unsuccessful, invokes the send status callbacks of those + * queued messages and drops them. + */ void FinalizeSessionRequest(const RouterID& router, SendStatus status) EXCLUDES(_mutex); llarp::thread::Queue outboundQueue; - llarp::thread::Queue removedPaths; + llarp::util::DecayingHashSet recentlyRemovedPaths; bool removedSomePaths; mutable util::Mutex _mutex; // protects pendingSessionMessageQueues From 6b115913bcc99469732abd240c2fb7c4207ea041 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 08:44:37 -0400 Subject: [PATCH 14/52] lokinetmon updates * add country flags to lokinetmon * expose hop ip addresses via rpc introspection for geoip in lokinetmon --- contrib/py/admin/lokinetmon | 48 +++++++++++++++++++++++++++++++------ llarp/path/path.cpp | 2 ++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/contrib/py/admin/lokinetmon b/contrib/py/admin/lokinetmon index 82e497000..8b3618dd7 100755 --- a/contrib/py/admin/lokinetmon +++ b/contrib/py/admin/lokinetmon @@ -7,6 +7,32 @@ import time import zmq +geo = None + +try: + import GeoIP + geo = GeoIP.open("/usr/share/GeoIP/GeoIP.dat", GeoIP.GEOIP_STANDARD) +except Exception as ex: + print('no geoip: {}'.format(ex)) + time.sleep(1) + + +def ip_to_flag(ip): + """ + convert an ip to a flag emoji + """ + # bail if no geoip available + if not geo: + return '' + # trim off excess ipv6 jizz + ip = ip.replace("::ffff:", "") + # get the country code + cc = geo.country_code_by_addr(ip) + # Unicode flag sequences are just country codes transposed into the REGIONAL + # INDICATOR SYMBOL LETTER A ... Z range (U+1F1E6 ... U+1F1FF): + flag = ''.join(chr(0x1f1e6 + ord(i) - ord('A')) for i in cc) + return '({}) {}'.format(cc, flag) + class Monitor: @@ -26,7 +52,7 @@ class Monitor: self._rpc_socket.connect(url) self._speed_samples = [(0,0,0,0)] * self._sample_size self._run = True - + def rpc(self, method): self._rpc_socket.send_multipart([method.encode(), b'lokinetmon'+method.encode()]) if not self._rpc_socket.poll(timeout=50): @@ -34,10 +60,10 @@ class Monitor: reply = self._rpc_socket.recv_multipart() if len(reply) >= 3 and reply[0:2] == [b'REPLY', b'lokinetmon'+method.encode()]: return reply[2].decode() - + def _close(self): self._rpc_socket.close(linger=0) - self._run = False + self._run = False curses.endwin() def update_data(self): @@ -62,7 +88,11 @@ class Monitor: y_pos += 1 self.win.addstr("me -> ") for hop in path["hops"]: - self.win.addstr(" {} ->".format(hop["router"][:4])) + hopstr = hop['router'][:4] + if 'ip' in hop: + hopstr += ' {}'.format(ip_to_flag(hop['ip'])) + self.win.addstr(" {} ->".format(hopstr)) + self.win.addstr(" [{} ms latency]".format(path["intro"]["latency"])) self.win.addstr(" [{} until expire]".format(self.time_to(path["expiresAt"]))) if path["expiresSoon"]: @@ -174,7 +204,7 @@ class Monitor: barstr = "#" * (samp - badsamp) pad = " " * (maxsamp - samp) return pad, barstr, '#' * badsamp - + def display_speedgraph(self, y_pos, maxsz=40): """ display global speed graph """ txmax, rxmax = 1024, 1024 @@ -260,9 +290,13 @@ class Monitor: self.win.move(y_pos, 1) self.txrate += sess["txRateCurrent"] self.rxrate += sess["rxRateCurrent"] + addr = sess['remoteAddr'] + if geo: + ip = addr.split(':')[0] + addr += '\t{}'.format(ip_to_flag(ip)) self.win.addstr( "{}\t[{}\ttx]\t[{}\trx]".format( - sess["remoteAddr"], self.speed_of(sess["txRateCurrent"]), self.speed_of(sess["rxRateCurrent"]) + addr, self.speed_of(sess["txRateCurrent"]), self.speed_of(sess["rxRateCurrent"]) ) ) if (sess['txMsgQueueSize'] or 0) > 1: @@ -333,7 +367,7 @@ class Monitor: self.version = json.loads(self.rpc("llarp.version"))['result']['version'] except: self.version = None - + while self._run: if self.update_data(): self.win.box() diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 79ee51c68..c870cfa20 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -303,7 +303,9 @@ namespace llarp util::StatusObject PathHopConfig::ExtractStatus() const { + const auto ip = net::In6ToHUInt(rc.addrs[0].ip); util::StatusObject obj{ + {"ip", ip.ToString()}, {"lifetime", to_json(lifetime)}, {"router", rc.pubkey.ToHex()}, {"txid", txID.ToHex()}, From b31a484bc99843cc2e4281df0a3860eb8ecccc01 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 08:52:41 -0400 Subject: [PATCH 15/52] fix up outbound session * prevent introset lookup spam * change return values to void becuase bool doesn't mean fucking shit at all --- llarp/service/outbound_context.cpp | 51 +++++++++--------------------- llarp/service/outbound_context.hpp | 5 +-- llarp/service/sendcontext.hpp | 2 +- 3 files changed, 19 insertions(+), 39 deletions(-) diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index b35be22bf..5b5c9e476 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -45,20 +45,18 @@ namespace llarp if (dst == remoteIntro.pathID && remoteIntro.router == p->Endpoint()) { LogWarn(Name(), " message ", seq, " dropped by endpoint ", p->Endpoint(), " via ", dst); - if (MarkCurrentIntroBad(Now())) - { - SwapIntros(); - } - UpdateIntroSet(); + MarkCurrentIntroBad(Now()); } return true; } + constexpr auto OutboundContextNumPaths = 2; + OutboundContext::OutboundContext(const IntroSet& introset, Endpoint* parent) - : path::Builder(parent->Router(), 4, parent->numHops) - , SendContext(introset.addressKeys, {}, this, parent) - , location(introset.addressKeys.Addr().ToKey()) - , currentIntroSet(introset) + : path::Builder{parent->Router(), OutboundContextNumPaths, parent->numHops} + , SendContext{introset.addressKeys, {}, this, parent} + , location{introset.addressKeys.Addr().ToKey()} + , currentIntroSet{introset} { updatingIntroSet = false; @@ -243,8 +241,12 @@ namespace llarp void OutboundContext::UpdateIntroSet() { - if (updatingIntroSet || markedBad) + constexpr auto IntrosetUpdateInterval = 10s; + const auto now = Now(); + if (updatingIntroSet or markedBad or now < m_LastIntrosetUpdateAt + IntrosetUpdateInterval) return; + LogInfo(Name(), " updating introset"); + m_LastIntrosetUpdateAt = now; const auto addr = currentIntroSet.addressKeys.Addr(); // we want to use the parent endpoint's paths because outbound context // does not implement path::PathSet::HandleGotIntroMessage @@ -410,40 +412,17 @@ namespace llarp return t >= now + path::default_lifetime / 4; } - bool + void OutboundContext::MarkCurrentIntroBad(llarp_time_t now) { - return MarkIntroBad(remoteIntro, now); + MarkIntroBad(remoteIntro, now); } - bool + void OutboundContext::MarkIntroBad(const Introduction& intro, llarp_time_t now) { // insert bad intro m_BadIntros[intro] = now; - // try shifting intro without rebuild - if (ShiftIntroduction(false)) - { - // we shifted - // check if we have a path to the next intro router - if (GetNewestPathByRouter(m_NextIntro.router)) - return true; - // we don't have a path build one if we aren't building too fast - if (!BuildCooldownHit(now)) - BuildOneAlignedTo(m_NextIntro.router); - return true; - } - - // we didn't shift check if we should update introset - if (now - lastShift >= MIN_SHIFT_INTERVAL || currentIntroSet.HasExpiredIntros(now) - || currentIntroSet.IsExpired(now)) - { - // update introset - LogInfo(Name(), " updating introset"); - UpdateIntroSet(); - return true; - } - return false; } bool diff --git a/llarp/service/outbound_context.hpp b/llarp/service/outbound_context.hpp index cf374b60c..011aa74b8 100644 --- a/llarp/service/outbound_context.hpp +++ b/llarp/service/outbound_context.hpp @@ -60,10 +60,10 @@ namespace llarp ShiftIntroRouter(const RouterID remote); /// mark the current remote intro as bad - bool + void MarkCurrentIntroBad(llarp_time_t now) override; - bool + void MarkIntroBad(const Introduction& marked, llarp_time_t now); /// return true if we are ready to send @@ -153,6 +153,7 @@ namespace llarp bool m_GotInboundTraffic = false; bool sentIntro = false; std::function m_ReadyHook; + llarp_time_t m_LastIntrosetUpdateAt = 0s; }; } // namespace service diff --git a/llarp/service/sendcontext.hpp b/llarp/service/sendcontext.hpp index c946efd86..517bea988 100644 --- a/llarp/service/sendcontext.hpp +++ b/llarp/service/sendcontext.hpp @@ -65,7 +65,7 @@ namespace llarp virtual void UpdateIntroSet() = 0; - virtual bool + virtual void MarkCurrentIntroBad(llarp_time_t now) = 0; void From f69ccb73a898e75e50fe82e7121fdd7761c93b93 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 08:54:46 -0400 Subject: [PATCH 16/52] limit path reanimation * wait for a limited time for dead paths to reanimate and then remove them after that forever --- llarp/path/path.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index c870cfa20..1cbd056e5 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -499,6 +499,9 @@ namespace llarp } } + /// how long we wait for a path to become active again after it times out + constexpr auto PathReanimationTimeout = 45s; + bool Path::Expired(llarp_time_t now) const { @@ -506,7 +509,11 @@ namespace llarp return true; if (_status == ePathBuilding) return false; - if (_status == ePathEstablished || _status == ePathTimeout) + if (_status == ePathTimeout) + { + return now >= m_LastRecvMessage + PathReanimationTimeout; + } + if (_status == ePathEstablished) { return now >= ExpireTime(); } From c6320724d369902a54746140e9a3053873a25404 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 08:55:54 -0400 Subject: [PATCH 17/52] parameterize traffic alignement timeout in dns lookups --- llarp/handlers/tun.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index f58e6c5b8..cc7dd67e5 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -259,27 +259,29 @@ namespace llarp return service::Address{itr->second.as_array()}; } + constexpr auto TrafficAlignmentTimeout = 10s; + bool TunEndpoint::HandleHookedDNSMessage(dns::Message msg, std::function reply) { - auto ReplyToSNodeDNSWhenReady = [self = this, reply = reply]( - RouterID snode, auto msg, bool isV6) -> bool { - return self->EnsurePathToSNode( + auto ReplyToSNodeDNSWhenReady = [this, reply](RouterID snode, auto msg, bool isV6) -> bool { + return EnsurePathToSNode( snode, - [=](const RouterID&, exit::BaseSession_ptr s, [[maybe_unused]] service::ConvoTag tag) { - self->SendDNSReply(snode, s, msg, reply, isV6); + [this, snode, msg, reply, isV6]( + const RouterID&, exit::BaseSession_ptr s, [[maybe_unused]] service::ConvoTag tag) { + SendDNSReply(snode, s, msg, reply, isV6); }); }; - auto ReplyToLokiDNSWhenReady = [self = this, reply = reply]( + auto ReplyToLokiDNSWhenReady = [this, reply]( service::Address addr, auto msg, bool isV6) -> bool { using service::Address; using service::OutboundContext; - return self->EnsurePathToService( + return EnsurePathToService( addr, - [=](const Address&, OutboundContext* ctx) { - self->SendDNSReply(addr, ctx, msg, reply, isV6); + [this, addr, msg, reply, isV6](const Address&, OutboundContext* ctx) { + SendDNSReply(addr, ctx, msg, reply, isV6); }, - 2s); + TrafficAlignmentTimeout); }; auto ReplyToDNSWhenReady = [ReplyToLokiDNSWhenReady, ReplyToSNodeDNSWhenReady]( @@ -296,14 +298,13 @@ namespace llarp } }; - auto ReplyToLokiSRVWhenReady = [self = this, reply = reply]( - service::Address addr, auto msg) -> bool { + auto ReplyToLokiSRVWhenReady = [this, reply](service::Address addr, auto msg) -> bool { using service::Address; using service::OutboundContext; - return self->EnsurePathToService( + return EnsurePathToService( addr, - [=](const Address&, OutboundContext* ctx) { + [msg, addr, reply](const Address&, OutboundContext* ctx) { if (ctx == nullptr) return; @@ -311,7 +312,7 @@ namespace llarp msg->AddSRVReply(introset.GetMatchingSRVRecords(addr.subdomain)); reply(*msg); }, - 2s); + TrafficAlignmentTimeout); }; if (msg.answers.size() > 0) @@ -923,7 +924,7 @@ namespace llarp } self->SendToOrQueue(addr, pkt.ConstBuffer(), service::ProtocolType::Exit); }, - 1s); + TrafficAlignmentTimeout); return; } bool rewriteAddrs = true; From e0185bab0995524b1f93738b8e5c0a5a9b2f85cc Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 08:56:18 -0400 Subject: [PATCH 18/52] don't rehash decaying hashsets that is no bueno and probably leaks like the pipes in tom's apartment --- llarp/util/decaying_hashset.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llarp/util/decaying_hashset.hpp b/llarp/util/decaying_hashset.hpp index 8d5d0a5b1..e9561f4f5 100644 --- a/llarp/util/decaying_hashset.hpp +++ b/llarp/util/decaying_hashset.hpp @@ -45,7 +45,6 @@ namespace llarp if (now == 0s) now = llarp::time_now_ms(); EraseIf([&](const auto& item) { return (m_CacheInterval + item.second) <= now; }); - m_Values.rehash(0); } Time_t From f2e8b5547d731e2dd6275745ac4f2a0df6729b88 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 08:58:50 -0400 Subject: [PATCH 19/52] compat for lokinet 0.8.x * don't send messages back that aren't expected --- llarp/service/endpoint.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 32e9bfd76..1b2107918 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1164,6 +1164,9 @@ namespace llarp Endpoint::SendAuthResult( path::Path_ptr path, PathID_t replyPath, ConvoTag tag, AuthResult result) { + // not applicable because we are not an exit or don't have an endpoint auth policy + if ((not m_state->m_ExitEnabled) or m_AuthPolicy == nullptr) + return; ProtocolFrame f; f.R = AuthResultCodeAsInt(result.code); f.T = tag; From f9fe6f7e3b412f232b93bba391a2fda68ae3e3c2 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 08:59:56 -0400 Subject: [PATCH 20/52] consmetic fixes * print names in lookup jobs instead of yyyyyy * update syntax in construction of objects --- llarp/service/endpoint.cpp | 38 ++++++++----------- llarp/service/endpoint.hpp | 3 ++ .../service/hidden_service_address_lookup.cpp | 7 +++- .../service/hidden_service_address_lookup.hpp | 1 + llarp/service/outbound_context.cpp | 1 + 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 1b2107918..4fe7c9c1d 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -46,11 +46,12 @@ namespace llarp namespace service { Endpoint::Endpoint(AbstractRouter* r, Context* parent) - : path::Builder(r, 3, path::default_len) - , context(parent) - , m_InboundTrafficQueue(512) - , m_SendQueue(512) - , m_RecvQueue(512) + : path::Builder{r, 3, path::default_len} + , context{parent} + , m_InboundTrafficQueue{512} + , m_SendQueue{512} + , m_RecvQueue{512} + , m_IntrosetLookupFilter{5s} { m_state = std::make_unique(); m_state->m_Router = r; @@ -283,7 +284,8 @@ namespace llarp { RegenAndPublishIntroSet(); } - + // decay introset lookup filter + m_IntrosetLookupFilter.Decay(now); // expire name cache m_state->nameCache.Decay(now); // expire snode sessions @@ -955,7 +957,7 @@ namespace llarp for (const auto& path : paths) { LogInfo(Name(), " lookup ", name, " from ", path->Endpoint()); - auto job = new LookupNameJob(this, GenTXID(), name, resultHandler); + auto job = new LookupNameJob{this, GenTXID(), name, resultHandler}; job->SendRequestViaPath(path, m_router); } } @@ -1003,7 +1005,7 @@ namespace llarp msg.S = path->NextSeqNo(); if (path && path->SendRoutingMessage(msg, Router())) { - RouterLookupJob job(this, handler); + RouterLookupJob job{this, handler}; assert(msg.M.size() == 1); auto dhtMsg = dynamic_cast(msg.M[0].get()); @@ -1011,7 +1013,7 @@ namespace llarp m_router->NotifyRouterEvent(m_router->pubkey(), *dhtMsg); - routers.emplace(router, RouterLookupJob(this, handler)); + routers.emplace(router, std::move(job)); return true; } } @@ -1266,6 +1268,7 @@ namespace llarp void Endpoint::HandlePathDied(path::Path_ptr p) { + m_router->routerProfiling().MarkPathTimeout(p.get()); ManualRebuild(1); RegenAndPublishIntroSet(); path::Builder::HandlePathDied(p); @@ -1349,13 +1352,8 @@ namespace llarp // add response hook to list for address. m_state->m_PendingServiceLookups.emplace(remote, hook); - auto& lookupTimes = m_state->m_LastServiceLookupTimes; - const auto now = Now(); - - // if most recent lookup was within last INTROSET_LOOKUP_RETRY_COOLDOWN - // just add callback to the list and return - if (lookupTimes.find(remote) != lookupTimes.end() - && now < (lookupTimes[remote] + INTROSET_LOOKUP_RETRY_COOLDOWN)) + /// check replay filter + if (not m_IntrosetLookupFilter.Insert(remote)) return true; const auto paths = GetManyPathsWithUniqueEndpoints(this, NumParallelLookups); @@ -1379,6 +1377,7 @@ namespace llarp }, location, PubKey{remote.as_array()}, + path->Endpoint(), order, GenTXID(), timeout); @@ -1394,12 +1393,7 @@ namespace llarp order++; if (job->SendRequestViaPath(path, Router())) { - if (not hookAdded) - { - // if any of the lookups is successful, set last lookup time - lookupTimes[remote] = now; - hookAdded = true; - } + hookAdded = true; } else LogError(Name(), " send via path failed for lookup"); diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 6f17bec07..372447a21 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -525,6 +525,9 @@ namespace llarp ConvoMap& Sessions(); // clang-format on thread::Queue m_RecvQueue; + + /// for rate limiting introset lookups + util::DecayingHashSet
m_IntrosetLookupFilter; }; using Endpoint_ptr = std::shared_ptr; diff --git a/llarp/service/hidden_service_address_lookup.cpp b/llarp/service/hidden_service_address_lookup.cpp index 2983bc1de..d1a294797 100644 --- a/llarp/service/hidden_service_address_lookup.cpp +++ b/llarp/service/hidden_service_address_lookup.cpp @@ -13,6 +13,7 @@ namespace llarp HandlerFunc h, const dht::Key_t& l, const PubKey& k, + const RouterID& ep, uint64_t order, uint64_t tx, llarp_time_t timeout) @@ -21,13 +22,15 @@ namespace llarp , relayOrder(order) , location(l) , handle(std::move(h)) - {} + { + endpoint = ep; + } bool HiddenServiceAddressLookup::HandleIntrosetResponse(const std::set& results) { std::optional found; - const Address remote(rootkey); + const Address remote{rootkey}; if (results.size() > 0) { EncryptedIntroSet selected; diff --git a/llarp/service/hidden_service_address_lookup.hpp b/llarp/service/hidden_service_address_lookup.hpp index 5512c5657..fcc331f6d 100644 --- a/llarp/service/hidden_service_address_lookup.hpp +++ b/llarp/service/hidden_service_address_lookup.hpp @@ -23,6 +23,7 @@ namespace llarp HandlerFunc h, const dht::Key_t& location, const PubKey& rootkey, + const RouterID& routerAsked, uint64_t relayOrder, uint64_t tx, llarp_time_t timeout); diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 5b5c9e476..94b1748e2 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -259,6 +259,7 @@ namespace llarp util::memFn(&OutboundContext::OnIntroSetUpdate, shared_from_this()), location, PubKey{addr.as_array()}, + path->Endpoint(), relayOrder, m_Endpoint->GenTXID(), 5s); From 94f24b2fdec2b1816b62970332b2fbf48658b969 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 10:16:57 -0400 Subject: [PATCH 21/52] win32 installer * make tuntap driver its own install component so that we can optionally not install it --- cmake/win32_installer_deps.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/win32_installer_deps.cmake b/cmake/win32_installer_deps.cmake index 72945fbcf..bc40a6043 100644 --- a/cmake/win32_installer_deps.cmake +++ b/cmake/win32_installer_deps.cmake @@ -25,14 +25,14 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_BINARY_DIR}/lokinet-g WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) install(DIRECTORY ${CMAKE_BINARY_DIR}/gui DESTINATION share COMPONENT gui) -install(PROGRAMS ${TUNTAP_EXE} DESTINATION bin) +install(PROGRAMS ${TUNTAP_EXE} DESTINATION bin COMPONENT tuntap) install(FILES ${BOOTSTRAP_FILE} DESTINATION share) set(CPACK_PACKAGE_INSTALL_DIRECTORY "Lokinet") set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/win32-setup/lokinet.ico") set(CPACK_NSIS_DEFINES "RequestExecutionLevel admin") set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) -set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '$INSTDIR\\\\bin\\\\tuntap-install.exe /S'\\nExecWait '$INSTDIR\\\\bin\\\\lokinet.exe --install'\\nExecWait 'sc failure lokinet reset= 60 actions= restart/1000'\\nExecWait '$INSTDIR\\\\bin\\\\lokinet.exe -g C:\\\\ProgramData\\\\lokinet\\\\lokinet.ini'\\nCopyFiles '$INSTDIR\\\\share\\\\bootstrap.signed' C:\\\\ProgramData\\\\lokinet\\\\bootstrap.signed\\nExecWait '$INSTDIR\\\\bin\\\\lokinet-bootstrap.exe'") +set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ifFileExists $INSTDIR\\\\bin\\\\tuntap-install.exe 0 +2\\nExecWait '$INSTDIR\\\\bin\\\\tuntap-install.exe /S'\\nExecWait '$INSTDIR\\\\bin\\\\lokinet.exe --install'\\nExecWait 'sc failure lokinet reset= 60 actions= restart/1000'\\nExecWait '$INSTDIR\\\\bin\\\\lokinet.exe -g C:\\\\ProgramData\\\\lokinet\\\\lokinet.ini'\\nCopyFiles '$INSTDIR\\\\share\\\\bootstrap.signed' C:\\\\ProgramData\\\\lokinet\\\\bootstrap.signed\\nExecWait '$INSTDIR\\\\bin\\\\lokinet-bootstrap.exe'") set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "ExecWait 'net stop lokinet'\\nExecWait 'taskkill /f /t /im lokinet-gui.exe'\\nExecWait '$INSTDIR\\\\bin\\\\lokinet.exe --remove'\\nRMDir /r /REBOOTOK C:\\\\ProgramData\\\\lokinet") set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Lokinet.lnk' '$INSTDIR\\\\share\\\\gui\\\\lokinet-gui.exe'" From 54f9e1b44e79f3b0d7555eaf58f1a05d9ad86c1f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 16:25:32 -0400 Subject: [PATCH 22/52] make path alignment timeout configuable adds [network] section parameter called path-alignment-timeout that allows configring the timeout for optional name lookup + introset lookup + aligned path build, used by tun endpoint dns, provided as milliseconds. --- llarp/config/config.cpp | 15 +++++++++++++++ llarp/config/config.hpp | 2 ++ llarp/handlers/tun.cpp | 22 +++++++++++++++------- llarp/handlers/tun.hpp | 2 ++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index e6deec451..6ce3971a3 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -659,6 +659,21 @@ namespace llarp m_SRVRecords.push_back(std::move(newSRV)); }); + conf.defineOption( + "network", + "path-alignment-timeout", + ClientOnly, + Comment{ + "time in milliseconds how long to wait for a path to align to pivot routers", + "if not provided a sensible default will be used", + }, + [this](int val) { + if (val <= 200) + throw std::invalid_argument{ + "invalid path alignment timeout: " + std::to_string(val) + " <= 200"}; + m_PathAlignmentTimeout = std::chrono::milliseconds{val}; + }); + // Deprecated options: conf.defineOption("network", "enabled", Deprecated); } diff --git a/llarp/config/config.hpp b/llarp/config/config.hpp index 399fac8a2..7fb212df4 100644 --- a/llarp/config/config.hpp +++ b/llarp/config/config.hpp @@ -125,6 +125,8 @@ namespace llarp std::set m_OwnedRanges; std::optional m_TrafficPolicy; + std::optional m_PathAlignmentTimeout; + // TODO: // on-up // on-down diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index cc7dd67e5..172479ddd 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -131,6 +131,8 @@ namespace llarp m_Resolver->Restart(); } + constexpr auto DefaultAlignmentTimeout = 10s; + bool TunEndpoint::Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) { @@ -167,6 +169,13 @@ namespace llarp m_BaseV6Address = conf.m_baseV6Address; + if (conf.m_PathAlignmentTimeout) + { + m_PathAlignmentTimeout = *conf.m_PathAlignmentTimeout; + } + else + m_PathAlignmentTimeout = DefaultAlignmentTimeout; + for (const auto& item : conf.m_mapAddrs) { if (not MapAddress(item.second, item.first, false)) @@ -259,8 +268,6 @@ namespace llarp return service::Address{itr->second.as_array()}; } - constexpr auto TrafficAlignmentTimeout = 10s; - bool TunEndpoint::HandleHookedDNSMessage(dns::Message msg, std::function reply) { @@ -272,7 +279,7 @@ namespace llarp SendDNSReply(snode, s, msg, reply, isV6); }); }; - auto ReplyToLokiDNSWhenReady = [this, reply]( + auto ReplyToLokiDNSWhenReady = [this, reply, timeout = m_PathAlignmentTimeout]( service::Address addr, auto msg, bool isV6) -> bool { using service::Address; using service::OutboundContext; @@ -281,7 +288,7 @@ namespace llarp [this, addr, msg, reply, isV6](const Address&, OutboundContext* ctx) { SendDNSReply(addr, ctx, msg, reply, isV6); }, - TrafficAlignmentTimeout); + timeout); }; auto ReplyToDNSWhenReady = [ReplyToLokiDNSWhenReady, ReplyToSNodeDNSWhenReady]( @@ -298,7 +305,8 @@ namespace llarp } }; - auto ReplyToLokiSRVWhenReady = [this, reply](service::Address addr, auto msg) -> bool { + auto ReplyToLokiSRVWhenReady = [this, reply, timeout = m_PathAlignmentTimeout]( + service::Address addr, auto msg) -> bool { using service::Address; using service::OutboundContext; @@ -312,7 +320,7 @@ namespace llarp msg->AddSRVReply(introset.GetMatchingSRVRecords(addr.subdomain)); reply(*msg); }, - TrafficAlignmentTimeout); + timeout); }; if (msg.answers.size() > 0) @@ -924,7 +932,7 @@ namespace llarp } self->SendToOrQueue(addr, pkt.ConstBuffer(), service::ProtocolType::Exit); }, - TrafficAlignmentTimeout); + m_PathAlignmentTimeout); return; } bool rewriteAddrs = true; diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 77054fb6f..f1626d468 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -267,6 +267,8 @@ namespace llarp std::optional m_TrafficPolicy; /// ranges we advetise as reachable std::set m_OwnedRanges; + /// how long to wait for path alignment + llarp_time_t m_PathAlignmentTimeout; }; } // namespace handlers From 2968caf7af9402491a0e1fbd0c2ab394cdb00cc8 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 16:45:04 -0400 Subject: [PATCH 23/52] make default log level warn fixes #1593 --- llarp/config/config.cpp | 2 +- llarp/util/logging/logger.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index e6deec451..5699eff66 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -989,7 +989,7 @@ namespace llarp constexpr Default DefaultLogType{"file"}; constexpr Default DefaultLogFile{""}; - constexpr Default DefaultLogLevel{"info"}; + constexpr Default DefaultLogLevel{"warn"}; conf.defineOption( "logging", diff --git a/llarp/util/logging/logger.hpp b/llarp/util/logging/logger.hpp index 99c18b424..599242147 100644 --- a/llarp/util/logging/logger.hpp +++ b/llarp/util/logging/logger.hpp @@ -24,7 +24,7 @@ namespace llarp LogContext(); LogLevel curLevel = eLogInfo; LogLevel startupLevel = eLogInfo; - LogLevel runtimeLevel = eLogInfo; + LogLevel runtimeLevel = eLogWarn; ILogStream_ptr logStream; std::string nodeName = "lokinet"; From ed707eecf9f2633c3dd593cf40233f7373fd23fa Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 1 May 2021 17:22:57 -0400 Subject: [PATCH 24/52] change granularity to seconds --- llarp/config/config.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index 6ce3971a3..d8b284dbf 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -664,14 +664,14 @@ namespace llarp "path-alignment-timeout", ClientOnly, Comment{ - "time in milliseconds how long to wait for a path to align to pivot routers", + "time in seconds how long to wait for a path to align to pivot routers", "if not provided a sensible default will be used", }, [this](int val) { - if (val <= 200) + if (val <= 0) throw std::invalid_argument{ - "invalid path alignment timeout: " + std::to_string(val) + " <= 200"}; - m_PathAlignmentTimeout = std::chrono::milliseconds{val}; + "invalid path alignment timeout: " + std::to_string(val) + " <= 0"}; + m_PathAlignmentTimeout = std::chrono::seconds{val}; }); // Deprecated options: From 397d8b01fca2a9da23135703a5a7c472609d82f5 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 2 May 2021 17:52:29 -0400 Subject: [PATCH 25/52] try fixing std::shared_ptr leak with paths --- llarp/path/pathbuilder.cpp | 54 ++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 3fdb4d9ba..f833dd9f3 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -96,7 +96,10 @@ namespace llarp { // farthest hop // TODO: encrypt junk frames because our public keys are not eligator - loop->call([self = shared_from_this()] { self->result(self); }); + loop->call([self = shared_from_this()] { + self->result(self); + self->result = nullptr; + }); } else { @@ -125,36 +128,31 @@ namespace llarp static void PathBuilderKeysGenerated(std::shared_ptr ctx) { - if (!ctx->pathset->IsStopped()) - { - ctx->router->NotifyRouterEvent(ctx->router->pubkey(), ctx->path); + if (ctx->pathset->IsStopped()) + return; - const RouterID remote = ctx->path->Upstream(); - auto sentHandler = [ctx](auto status) { - if (status == SendStatus::Success) - { - ctx->router->pathContext().AddOwnPath(ctx->pathset, ctx->path); - ctx->pathset->PathBuildStarted(std::move(ctx->path)); - } - else - { - LogError(ctx->pathset->Name(), " failed to send LRCM to ", ctx->path->Upstream()); - ctx->path->EnterState(path::ePathFailed, ctx->router->Now()); - } - ctx->path = nullptr; - ctx->pathset = nullptr; - }; - if (ctx->router->SendToOrQueue(remote, ctx->LRCM, sentHandler)) - { - // persist session with router until this path is done - if (ctx->path) - ctx->router->PersistSessionUntil(remote, ctx->path->ExpireTime()); - } - else + ctx->router->NotifyRouterEvent(ctx->router->pubkey(), ctx->path); + + ctx->router->pathContext().AddOwnPath(ctx->pathset, ctx->path); + ctx->pathset->PathBuildStarted(ctx->path); + + const RouterID remote = ctx->path->Upstream(); + auto sentHandler = [router = ctx->router, path = ctx->path](auto status) { + if (status != SendStatus::Success) { - LogError(ctx->pathset->Name(), " failed to queue LRCM to ", remote); - sentHandler(SendStatus::NoLink); + path->EnterState(path::ePathFailed, router->Now()); } + }; + if (ctx->router->SendToOrQueue(remote, ctx->LRCM, sentHandler)) + { + // persist session with router until this path is done + if (ctx->path) + ctx->router->PersistSessionUntil(remote, ctx->path->ExpireTime()); + } + else + { + LogError(ctx->pathset->Name(), " failed to queue LRCM to ", remote); + sentHandler(SendStatus::NoLink); } } From d563e3b340c9d2f61ad4ddd55b37f461f6c39063 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 09:22:06 -0400 Subject: [PATCH 26/52] if a path's latency is zero dont use it because it's not actually a zero latency path it's probably about to be failed or timed out increase default path alignment timeout --- llarp/handlers/tun.cpp | 2 +- llarp/path/pathset.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 172479ddd..fc521d94b 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -131,7 +131,7 @@ namespace llarp m_Resolver->Restart(); } - constexpr auto DefaultAlignmentTimeout = 10s; + constexpr auto DefaultAlignmentTimeout = 15s; bool TunEndpoint::Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index ae080bca7..f5f788551 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -156,7 +156,8 @@ namespace llarp { if (chosen == nullptr) chosen = itr->second; - else if (chosen->intro.latency > itr->second->intro.latency) + else if ( + chosen->intro.latency != 0s and chosen->intro.latency > itr->second->intro.latency) chosen = itr->second; } } @@ -429,7 +430,7 @@ namespace llarp llarp_time_t minLatency = 30s; for (const auto& path : established) { - if (path->intro.latency < minLatency) + if (path->intro.latency < minLatency and path->intro.latency != 0s) { minLatency = path->intro.latency; chosen = path; From 83e70d95e0ea7c40ad8d82219bb4c3cd6b5ddd39 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 10:31:35 -0400 Subject: [PATCH 27/52] dont invalidate cache on lns timeout, only on explicit negative --- llarp/service/endpoint.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 4fe7c9c1d..a0995ba26 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -932,9 +932,10 @@ namespace llarp if (result) { var::visit( - [&](auto&& value) { + [&result, &cache, name](auto&& value) { if (value.IsZero()) { + cache.Remove(name); result = std::nullopt; } }, @@ -944,10 +945,6 @@ namespace llarp { cache.Put(name, *result); } - else - { - cache.Remove(name); - } handler(result); }; From 0005bee1961f1ba5377564c981db8cb4fd662b89 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 11:09:45 -0400 Subject: [PATCH 28/52] allow more than one outbound context per endpoint for fallback in case one outbound context takes a shit --- llarp/service/endpoint.cpp | 4 +++- llarp/service/endpoint.hpp | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index a0995ba26..9a9e08bb0 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -749,6 +749,8 @@ namespace llarp path::Builder::PathBuildStarted(path); } + constexpr auto MaxOutboundContextPerRemote = 4; + void Endpoint::PutNewOutboundContext(const service::IntroSet& introset, llarp_time_t left) { @@ -757,7 +759,7 @@ namespace llarp auto& remoteSessions = m_state->m_RemoteSessions; auto& serviceLookups = m_state->m_PendingServiceLookups; - if (remoteSessions.count(addr) >= MAX_OUTBOUND_CONTEXT_COUNT) + if (remoteSessions.count(addr) >= MaxOutboundContextPerRemote) { auto itr = remoteSessions.find(addr); diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 372447a21..5062ad3a2 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -61,8 +61,6 @@ namespace llarp public IDataHandler, public EndpointBase { - static const size_t MAX_OUTBOUND_CONTEXT_COUNT = 1; - Endpoint(AbstractRouter* r, Context* parent); ~Endpoint() override; From f108af3d8b4c066264f944f5211068bb88488dd8 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 11:35:40 -0400 Subject: [PATCH 29/52] only use alive paths for lookups only track usage from sessions and don't care about intro timeouts --- llarp/service/endpoint_util.hpp | 2 +- llarp/service/session.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llarp/service/endpoint_util.hpp b/llarp/service/endpoint_util.hpp index 7f01a65a6..2aa66bfd4 100644 --- a/llarp/service/endpoint_util.hpp +++ b/llarp/service/endpoint_util.hpp @@ -50,7 +50,7 @@ namespace llarp { --tries; const auto path = ep->PickRandomEstablishedPath(); - if (path) + if (path and path->IsReady()) paths.emplace(path); } while (tries > 0 and paths.size() < N); return paths; diff --git a/llarp/service/session.cpp b/llarp/service/session.cpp index bf710dcdd..0a410b641 100644 --- a/llarp/service/session.cpp +++ b/llarp/service/session.cpp @@ -27,7 +27,7 @@ namespace llarp const auto lastUsed = std::max(lastSend, lastRecv); if (lastUsed == 0s) return intro.IsExpired(now); - return now > lastUsed && (now - lastUsed > lifetime || intro.IsExpired(now)); + return now > lastUsed && now - lastUsed > lifetime; } void From 0826a557d68d3cd6e027a0b70dd4cb011af92f75 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 15:14:16 -0400 Subject: [PATCH 30/52] use correct intro --- llarp/service/endpoint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 9a9e08bb0..e7f461847 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1604,7 +1604,7 @@ namespace llarp } if (session.inbound) { - auto path = GetPathByRouter(session.intro.router); + auto path = GetPathByRouter(session.replyIntro.router); if (path) { const auto rttEstimate = (session.replyIntro.latency + path->intro.latency) * 2; From f955bec5da338d281a17ae17dd42f93f00ec0d7a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 15:16:23 -0400 Subject: [PATCH 31/52] re-add parans --- llarp/service/session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/service/session.cpp b/llarp/service/session.cpp index 0a410b641..6238a2166 100644 --- a/llarp/service/session.cpp +++ b/llarp/service/session.cpp @@ -27,7 +27,7 @@ namespace llarp const auto lastUsed = std::max(lastSend, lastRecv); if (lastUsed == 0s) return intro.IsExpired(now); - return now > lastUsed && now - lastUsed > lifetime; + return now >= lastUsed && (now - lastUsed > lifetime); } void From 554a44c8bf30adf83714d09d20d2e051cb2400d6 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 16:53:00 -0400 Subject: [PATCH 32/52] report block height reported by oxend in systemd status --- llarp/router/router.cpp | 3 ++- llarp/rpc/lokid_rpc_client.cpp | 12 +++++++++++- llarp/rpc/lokid_rpc_client.hpp | 9 +++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 58a823a8b..07ec37734 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -735,7 +735,8 @@ namespace llarp { ss << " snode | known/svc/clients: " << nodedb()->NumLoaded() << "/" << NumberOfConnectedRouters() << "/" << NumberOfConnectedClients() << " | " - << pathContext().CurrentTransitPaths() << " active paths"; + << pathContext().CurrentTransitPaths() << " active paths | " + << "block " << m_lokidRpcClient->BlockHeight(); } else { diff --git a/llarp/rpc/lokid_rpc_client.cpp b/llarp/rpc/lokid_rpc_client.cpp index 6051ce9bc..5ee2676da 100644 --- a/llarp/rpc/lokid_rpc_client.cpp +++ b/llarp/rpc/lokid_rpc_client.cpp @@ -83,7 +83,17 @@ namespace llarp " parts instead of 2 parts so we will not update the list of service nodes"); return; // bail } - LogDebug("new block at hieght ", msg.data[0]); + try + { + m_BlockHeight = std::stoll(std::string{msg.data[0]}); + } + catch (std::exception& ex) + { + LogError("bad block hieght: ", ex.what()); + return; // bail + } + + LogDebug("new block at hieght ", m_BlockHeight); // don't upadate on block notification if an update is pending if (not m_UpdatingList) UpdateServiceNodeList(std::string{msg.data[1]}); diff --git a/llarp/rpc/lokid_rpc_client.hpp b/llarp/rpc/lokid_rpc_client.hpp index 2c4df49ab..b05755dd7 100644 --- a/llarp/rpc/lokid_rpc_client.hpp +++ b/llarp/rpc/lokid_rpc_client.hpp @@ -30,6 +30,13 @@ namespace llarp SecretKey ObtainIdentityKey(); + /// get what the current block height is according to oxend + uint64_t + BlockHeight() const + { + return m_BlockHeight; + } + void LookupLNSNameHash( dht::Key_t namehash, @@ -77,6 +84,8 @@ namespace llarp AbstractRouter* const m_Router; std::atomic m_UpdatingList; + + uint64_t m_BlockHeight; }; } // namespace rpc From 099276c4e730a15196409d3e4b158aa7591e131c Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 16:53:00 -0400 Subject: [PATCH 33/52] report block height reported by oxend in systemd status --- llarp/router/router.cpp | 3 ++- llarp/rpc/lokid_rpc_client.cpp | 12 +++++++++++- llarp/rpc/lokid_rpc_client.hpp | 9 +++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 58a823a8b..07ec37734 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -735,7 +735,8 @@ namespace llarp { ss << " snode | known/svc/clients: " << nodedb()->NumLoaded() << "/" << NumberOfConnectedRouters() << "/" << NumberOfConnectedClients() << " | " - << pathContext().CurrentTransitPaths() << " active paths"; + << pathContext().CurrentTransitPaths() << " active paths | " + << "block " << m_lokidRpcClient->BlockHeight(); } else { diff --git a/llarp/rpc/lokid_rpc_client.cpp b/llarp/rpc/lokid_rpc_client.cpp index 6051ce9bc..5ee2676da 100644 --- a/llarp/rpc/lokid_rpc_client.cpp +++ b/llarp/rpc/lokid_rpc_client.cpp @@ -83,7 +83,17 @@ namespace llarp " parts instead of 2 parts so we will not update the list of service nodes"); return; // bail } - LogDebug("new block at hieght ", msg.data[0]); + try + { + m_BlockHeight = std::stoll(std::string{msg.data[0]}); + } + catch (std::exception& ex) + { + LogError("bad block hieght: ", ex.what()); + return; // bail + } + + LogDebug("new block at hieght ", m_BlockHeight); // don't upadate on block notification if an update is pending if (not m_UpdatingList) UpdateServiceNodeList(std::string{msg.data[1]}); diff --git a/llarp/rpc/lokid_rpc_client.hpp b/llarp/rpc/lokid_rpc_client.hpp index 2c4df49ab..b05755dd7 100644 --- a/llarp/rpc/lokid_rpc_client.hpp +++ b/llarp/rpc/lokid_rpc_client.hpp @@ -30,6 +30,13 @@ namespace llarp SecretKey ObtainIdentityKey(); + /// get what the current block height is according to oxend + uint64_t + BlockHeight() const + { + return m_BlockHeight; + } + void LookupLNSNameHash( dht::Key_t namehash, @@ -77,6 +84,8 @@ namespace llarp AbstractRouter* const m_Router; std::atomic m_UpdatingList; + + uint64_t m_BlockHeight; }; } // namespace rpc From e916c9610c3823875670ec1dfc7679ea7161f7b7 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 3 May 2021 19:42:13 -0400 Subject: [PATCH 34/52] format --- llarp/service/endpoint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index e7f461847..dbc67362d 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -934,7 +934,7 @@ namespace llarp if (result) { var::visit( - [&result, &cache, name](auto&& value) { + [&result, &cache, name](auto&& value) { if (value.IsZero()) { cache.Remove(name); From 955071ba5cd1ce3dd8e85d83d79e97ea967d310e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 4 May 2021 17:01:29 -0400 Subject: [PATCH 35/52] make profiling far stricter for path builds --- llarp/profiling.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/llarp/profiling.hpp b/llarp/profiling.hpp index 1af23e82f..03372d3fb 100644 --- a/llarp/profiling.hpp +++ b/llarp/profiling.hpp @@ -50,17 +50,20 @@ namespace llarp { Profiling(); + inline static const int profiling_chances = 4; + /// generic variant bool - IsBad(const RouterID& r, uint64_t chances = 8) EXCLUDES(m_ProfilesMutex); + IsBad(const RouterID& r, uint64_t chances = profiling_chances) EXCLUDES(m_ProfilesMutex); /// check if this router should have paths built over it bool - IsBadForPath(const RouterID& r, uint64_t chances = 8) EXCLUDES(m_ProfilesMutex); + IsBadForPath(const RouterID& r, uint64_t chances = profiling_chances) EXCLUDES(m_ProfilesMutex); /// check if this router should be connected directly to bool - IsBadForConnect(const RouterID& r, uint64_t chances = 8) EXCLUDES(m_ProfilesMutex); + IsBadForConnect(const RouterID& r, uint64_t chances = profiling_chances) + EXCLUDES(m_ProfilesMutex); void MarkConnectTimeout(const RouterID& r) EXCLUDES(m_ProfilesMutex); From ec62228149d84151717e0e24dab68f482cdcf640 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 5 May 2021 08:21:39 -0400 Subject: [PATCH 36/52] limit path builds across all builders --- llarp/path/pathbuilder.cpp | 33 ++++++++++++++++++++++----------- llarp/path/pathbuilder.hpp | 22 +++++++++++++++++++++- llarp/router/abstractrouter.hpp | 3 +++ llarp/router/router.cpp | 2 ++ llarp/router/router.hpp | 8 ++++++++ 5 files changed, 56 insertions(+), 12 deletions(-) diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 3fdb4d9ba..f7a52b20e 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -160,12 +160,26 @@ namespace llarp namespace path { + bool + BuildLimiter::Attempt(const RouterID& router) + { + return m_EdgeLimiter.Insert(router); + } + + void + BuildLimiter::Decay(llarp_time_t now) + { + m_EdgeLimiter.Decay(now); + } + + bool + BuildLimiter::Limited(const RouterID& router) const + { + return m_EdgeLimiter.Contains(router); + } + Builder::Builder(AbstractRouter* p_router, size_t pathNum, size_t hops) - : path::PathSet{pathNum} - , m_EdgeLimiter{MIN_PATH_BUILD_INTERVAL} - , _run{true} - , m_router{p_router} - , numHops{hops} + : path::PathSet{pathNum}, _run{true}, m_router{p_router}, numHops{hops} { CryptoManager::instance()->encryption_keygen(enckey); } @@ -180,7 +194,6 @@ namespace llarp void Builder::Tick(llarp_time_t) { const auto now = llarp::time_now_ms(); - m_EdgeLimiter.Decay(now); ExpirePaths(now, m_router); if (ShouldBuildMore(now)) BuildOne(); @@ -226,7 +239,7 @@ namespace llarp if (exclude.count(rc.pubkey)) return; - if (m_EdgeLimiter.Contains(rc.pubkey)) + if (BuildCooldownHit(rc.pubkey)) return; found = rc; @@ -277,7 +290,7 @@ namespace llarp bool Builder::BuildCooldownHit(RouterID edge) const { - return m_EdgeLimiter.Contains(edge); + return m_router->pathBuildLimiter().Limited(edge); } bool @@ -399,7 +412,7 @@ namespace llarp return; lastBuild = Now(); const RouterID edge{hops[0].pubkey}; - if (not m_EdgeLimiter.Insert(edge)) + if (not m_router->pathBuildLimiter().Attempt(edge)) { LogWarn(Name(), " building too fast to edge router ", edge); return; @@ -437,8 +450,6 @@ namespace llarp { PathSet::HandlePathBuildFailedAt(p, edge); DoPathBuildBackoff(); - /// add it to the edge limter even if it's not an edge for simplicity - m_EdgeLimiter.Insert(edge); } void diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index fa1c1d367..48e72ae77 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -15,11 +15,31 @@ namespace llarp static constexpr auto MIN_PATH_BUILD_INTERVAL = 500ms; static constexpr auto PATH_BUILD_RATE = 100ms; + /// limiter for path builds + /// prevents overload and such + class BuildLimiter + { + util::DecayingHashSet m_EdgeLimiter; + + public: + /// attempt a build + /// return true if we are allowed to continue + bool + Attempt(const RouterID& router); + + /// decay limit entries + void + Decay(llarp_time_t now); + + /// return true if this router is currently limited + bool + Limited(const RouterID& router) const; + }; + struct Builder : public PathSet { private: llarp_time_t m_LastWarn = 0s; - util::DecayingHashSet m_EdgeLimiter; protected: /// flag for PathSet::Stop() diff --git a/llarp/router/abstractrouter.hpp b/llarp/router/abstractrouter.hpp index dff705206..2f114a280 100644 --- a/llarp/router/abstractrouter.hpp +++ b/llarp/router/abstractrouter.hpp @@ -292,6 +292,9 @@ namespace llarp virtual bool ConnectionToRouterAllowed(const RouterID& router) const = 0; + virtual path::BuildLimiter& + pathBuildLimiter() = 0; + /// return true if we have at least 1 session to this router in either /// direction virtual bool diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 07ec37734..1f4151321 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -753,6 +753,8 @@ namespace llarp } #endif + m_PathBuildLimiter.Decay(now); + routerProfiling().Tick(); if (ShouldReportStats(now)) diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index b0dd03575..697eb401d 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -74,6 +74,14 @@ namespace llarp LMQ_ptr m_lmq; + path::BuildLimiter m_PathBuildLimiter; + + path::BuildLimiter& + pathBuildLimiter() override + { + return m_PathBuildLimiter; + } + const LMQ_ptr& lmq() const override { From b1afe0f596e27d1eed382f44922c9c0e29cf57ee Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 5 May 2021 18:24:15 -0400 Subject: [PATCH 37/52] always do path tests this reverts some stupid bullshit that broke 0.9.0 --- llarp/path/path.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 1cbd056e5..fcc27347b 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -412,9 +412,6 @@ namespace llarp auto dlt = now - m_LastLatencyTestTime; if (dlt > path::latency_interval && m_LastLatencyTestID == 0) { - // bail doing test if we are active - if (now - m_LastRecvMessage < path::latency_interval) - return; routing::PathLatencyMessage latency; latency.T = randint(); m_LastLatencyTestID = latency.T; From a644b93d114c3def4d6c3014b2a6f36f73a8ac6a Mon Sep 17 00:00:00 2001 From: David Arnold Date: Thu, 6 May 2021 10:33:47 +1000 Subject: [PATCH 38/52] Tyops Originally [#10](https://github.com/majestrate/llarp/pull/10) --- docs/proto_v0.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/proto_v0.txt b/docs/proto_v0.txt index b949de74e..6a3bb0ecf 100644 --- a/docs/proto_v0.txt +++ b/docs/proto_v0.txt @@ -24,11 +24,11 @@ BE(x) is bittorrent encode x BD(x) is bittorrent decode x { a: b, y: z } is a dictionary with two keys a and y - who's values are b and z respectively + whose values are b and z respectively [ a, b, c ... ] is a list containing a b c and more items in that order -"" is a bytestring who's contents and length is described by the +"" is a bytestring whose contents and length is described by the quoted value "" * N is a bytestring containing the concatenated N times. @@ -354,8 +354,8 @@ hop length. link relay commit record (LRCR) record requesting relaying messages for 600 seconds to router -on network who's i is equal to RC.k and decrypt data any messages using -PKE(n, rc.p, c) as symettric key for encryption and decryption. +on network whose i is equal to RC.k and decrypt data any messages using +PKE(n, rc.p, c) as symmetric key for encryption and decryption. if l is provided and is less than 600 and greater than 10 then that lifespan is used (in seconds) instead of 600 seconds. @@ -845,8 +845,8 @@ X is parsed as a list of IP packet buffers. for each ip packet the source addresss is extracted and sent on the appropriate network interface. -When we recieve an ip packet from the internet to an exit address, we put it -into a TITM, and send it downstream the corrisponding path in an LRDM. +When we receive an ip packet from the internet to an exit address, we put it +into a TITM, and send it downstream the corresponding path in an LRDM. update exit path message (UXPM) From d3d929efa7e7a091ed3c1905fed1d4a8730d7f99 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 5 May 2021 08:32:07 -0400 Subject: [PATCH 39/52] fixups in service endpoint * increase publish introset timeout so that it does not time out on the network * remove pedantic log warn * make sure the path we are using for replying on inbound sessions is alive * include convotag in log message so we know wtf is going on * appease tom's autism, improve log message text --- llarp/service/endpoint.cpp | 19 +++++++++++-------- llarp/service/outbound_context.cpp | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index dbc67362d..2c6a93e49 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -622,8 +622,12 @@ namespace llarp Endpoint* m_Endpoint; uint64_t m_relayOrder; PublishIntroSetJob( - Endpoint* parent, uint64_t id, EncryptedIntroSet introset, uint64_t relayOrder) - : IServiceLookup(parent, id, "PublishIntroSet") + Endpoint* parent, + uint64_t id, + EncryptedIntroSet introset, + uint64_t relayOrder, + llarp_time_t timeout) + : IServiceLookup(parent, id, "PublishIntroSet", timeout) , m_IntroSet(std::move(introset)) , m_Endpoint(parent) , m_relayOrder(relayOrder) @@ -665,6 +669,8 @@ namespace llarp } } + constexpr auto PublishIntrosetTimeout = 20s; + bool Endpoint::PublishIntroSetVia( const EncryptedIntroSet& introset, @@ -672,7 +678,8 @@ namespace llarp path::Path_ptr path, uint64_t relayOrder) { - auto job = new PublishIntroSetJob(this, GenTXID(), introset, relayOrder); + auto job = + new PublishIntroSetJob(this, GenTXID(), introset, relayOrder, PublishIntrosetTimeout); if (job->SendRequestViaPath(path, r)) { m_state->m_LastPublishAttempt = Now(); @@ -1605,7 +1612,7 @@ namespace llarp if (session.inbound) { auto path = GetPathByRouter(session.replyIntro.router); - if (path) + if (path and path->IsReady()) { const auto rttEstimate = (session.replyIntro.latency + path->intro.latency) * 2; if (rttEstimate < rtt) @@ -1614,10 +1621,6 @@ namespace llarp rtt = rttEstimate; } } - else - { - LogWarn("no path for inbound session T=", tag); - } } else { diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 94b1748e2..3c1a59c48 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -567,7 +567,7 @@ namespace llarp // verify source if (!frame.Verify(si)) { - LogWarn("signature failed"); + LogWarn("signature verification failed, T=", frame.T); return false; } // remove convotag it doesn't exist From 6bb31468d771518dd40ab620485d7d2b73b12353 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 5 May 2021 08:57:39 -0400 Subject: [PATCH 40/52] don't send nx if we have an address already mapped --- llarp/handlers/tun.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index f1626d468..298946d77 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -222,7 +222,7 @@ namespace llarp std::function reply, bool sendIPv6) { - if (ctx) + if (ctx or HasAddress(addr)) { huint128_t ip = ObtainIPForAddr(addr); query->answers.clear(); From 3c22e01d7cfd28746ddf7840faad041e8231f40b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 9 May 2021 08:00:31 -0400 Subject: [PATCH 41/52] in the event that a session is removed and then gets more traffic we would re-add the session with everything blank if there was more traffic in the same tick. this remedies this behavior by only increment usage timestamps on sessions if they exist. --- llarp/service/endpoint.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 2c6a93e49..b2a277641 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -520,13 +520,15 @@ namespace llarp void Endpoint::ConvoTagTX(const ConvoTag& tag) { - Sessions()[tag].TX(); + if (Sessions().count(tag)) + Sessions()[tag].TX(); } void Endpoint::ConvoTagRX(const ConvoTag& tag) { - Sessions()[tag].RX(); + if (Sessions().count(tag)) + Sessions()[tag].RX(); } bool From 38cc130dc3a69851892a9001517ed3b264bd7346 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 10 May 2021 09:01:46 -0400 Subject: [PATCH 42/52] shift off bad intros when we get a discard message, this happens if the other side's intro expires or the pivot restarts for whatever reason. --- llarp/service/outbound_context.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index 3c1a59c48..15b16fdbe 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -46,6 +46,7 @@ namespace llarp { LogWarn(Name(), " message ", seq, " dropped by endpoint ", p->Endpoint(), " via ", dst); MarkCurrentIntroBad(Now()); + ShiftIntroduction(false); } return true; } From c834414b47e0c5ccc14181b1ff0ebb3478aaf65b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 8 May 2021 07:16:21 -0400 Subject: [PATCH 43/52] when we have to reestablish an outbound session use a much much higher timeout for restablishment so it doesn't time out and get into a state that's totally screwed. add virtual function service::Endpont::DefaultPathAlignmentTimeout() to get the timeout for path alignment and use it for resetablishing outbound sessions --- llarp/handlers/tun.hpp | 6 ++++++ llarp/service/endpoint.cpp | 2 +- llarp/service/endpoint.hpp | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 298946d77..d92853a80 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -135,6 +135,12 @@ namespace llarp return m_OwnedRanges; } + llarp_time_t + DefaultPathAlignmentTimeout() const override + { + return m_PathAlignmentTimeout; + } + /// ip packet against any exit policies we have /// returns false if this traffic is disallowed by any of those policies /// returns true otherwise diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index b2a277641..6ff50f51d 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1850,7 +1850,7 @@ namespace llarp } self->m_state->m_PendingTraffic.erase(addr); }, - 1500ms); + DefaultPathAlignmentTimeout()); return true; } LogDebug("SendOrQueue failed: no inbound/outbound sessions"); diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 5062ad3a2..831d63814 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -306,6 +306,12 @@ namespace llarp bool ShouldBuildMore(llarp_time_t now) const override; + virtual llarp_time_t + DefaultPathAlignmentTimeout() const + { + return 10s; + } + bool EnsurePathTo( std::variant addr, From c5350ab2c4b3a0a9672cf0828ca09a2a02f066d2 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 11 May 2021 05:12:02 -0400 Subject: [PATCH 44/52] DefaultPathAlignmentTimeout -> PathAlignmentTimeout --- llarp/handlers/tun.cpp | 10 ++++------ llarp/handlers/tun.hpp | 2 +- llarp/service/endpoint.cpp | 2 +- llarp/service/endpoint.hpp | 5 +++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index fc521d94b..0504f74d2 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -131,8 +131,6 @@ namespace llarp m_Resolver->Restart(); } - constexpr auto DefaultAlignmentTimeout = 15s; - bool TunEndpoint::Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) { @@ -174,7 +172,7 @@ namespace llarp m_PathAlignmentTimeout = *conf.m_PathAlignmentTimeout; } else - m_PathAlignmentTimeout = DefaultAlignmentTimeout; + m_PathAlignmentTimeout = service::Endpoint::PathAlignmentTimeout(); for (const auto& item : conf.m_mapAddrs) { @@ -279,7 +277,7 @@ namespace llarp SendDNSReply(snode, s, msg, reply, isV6); }); }; - auto ReplyToLokiDNSWhenReady = [this, reply, timeout = m_PathAlignmentTimeout]( + auto ReplyToLokiDNSWhenReady = [this, reply, timeout = PathAlignmentTimeout()]( service::Address addr, auto msg, bool isV6) -> bool { using service::Address; using service::OutboundContext; @@ -305,7 +303,7 @@ namespace llarp } }; - auto ReplyToLokiSRVWhenReady = [this, reply, timeout = m_PathAlignmentTimeout]( + auto ReplyToLokiSRVWhenReady = [this, reply, timeout = PathAlignmentTimeout()]( service::Address addr, auto msg) -> bool { using service::Address; using service::OutboundContext; @@ -932,7 +930,7 @@ namespace llarp } self->SendToOrQueue(addr, pkt.ConstBuffer(), service::ProtocolType::Exit); }, - m_PathAlignmentTimeout); + PathAlignmentTimeout()); return; } bool rewriteAddrs = true; diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index d92853a80..685898e17 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -136,7 +136,7 @@ namespace llarp } llarp_time_t - DefaultPathAlignmentTimeout() const override + PathAlignmentTimeout() const override { return m_PathAlignmentTimeout; } diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 6ff50f51d..29b24262c 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1850,7 +1850,7 @@ namespace llarp } self->m_state->m_PendingTraffic.erase(addr); }, - DefaultPathAlignmentTimeout()); + PathAlignmentTimeout()); return true; } LogDebug("SendOrQueue failed: no inbound/outbound sessions"); diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 831d63814..9de2e05a8 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -307,9 +307,10 @@ namespace llarp ShouldBuildMore(llarp_time_t now) const override; virtual llarp_time_t - DefaultPathAlignmentTimeout() const + PathAlignmentTimeout() const { - return 10s; + constexpr auto DefaultPathAlignmentTimeout = 30s; + return DefaultPathAlignmentTimeout; } bool From 51b7566a46b50224bbd9c1535981981b2f697a0d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Tue, 11 May 2021 09:10:16 -0400 Subject: [PATCH 45/52] if we look deregistered we will now: * not gossip our rc * not explore the network to prevent outbound session attempts * not establish sessions to other service nodes * close all open sessions we have to tell clients we don't want them * catch exceptions flushing peerdb in disk thread * don't connect out to non allowed routers * simplify logic in RCLookupHandler::RemoteIsAllowed() * add HaveReceivedWhitelist to I_RCLookupHandler base type * add LooksDeregistered to Router type that tells us if we think we are deregistered * don't allow building paths over us if we are deregistered --- llarp/router/i_rc_lookup_handler.hpp | 3 ++ llarp/router/outbound_session_maker.cpp | 2 +- llarp/router/rc_lookup_handler.cpp | 12 +++---- llarp/router/rc_lookup_handler.hpp | 2 +- llarp/router/router.cpp | 42 ++++++++++++++++++++++--- llarp/router/router.hpp | 4 +++ 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/llarp/router/i_rc_lookup_handler.hpp b/llarp/router/i_rc_lookup_handler.hpp index 42ad1f0ef..7883dd3b4 100644 --- a/llarp/router/i_rc_lookup_handler.hpp +++ b/llarp/router/i_rc_lookup_handler.hpp @@ -58,6 +58,9 @@ namespace llarp virtual size_t NumberOfStrictConnectRouters() const = 0; + + virtual bool + HaveReceivedWhitelist() const = 0; }; } // namespace llarp diff --git a/llarp/router/outbound_session_maker.cpp b/llarp/router/outbound_session_maker.cpp index c980ed592..8846a38ec 100644 --- a/llarp/router/outbound_session_maker.cpp +++ b/llarp/router/outbound_session_maker.cpp @@ -232,7 +232,7 @@ namespace llarp bool OutboundSessionMaker::ShouldConnectTo(const RouterID& router) const { - if (router == us) + if (router == us or not _rcLookup->RemoteIsAllowed(router)) return false; size_t numPending = 0; { diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index 12b8b1beb..76ae45053 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -49,7 +49,7 @@ namespace llarp } bool - RCLookupHandler::HaveReceivedWhitelist() + RCLookupHandler::HaveReceivedWhitelist() const { util::Lock l(_mutex); return not whitelistRouters.empty(); @@ -127,14 +127,12 @@ namespace llarp return false; } - util::Lock l(_mutex); + if (not useWhitelist) + return true; - if (useWhitelist && whitelistRouters.find(remote) == whitelistRouters.end()) - { - return false; - } + util::Lock lock{_mutex}; - return true; + return whitelistRouters.count(remote); } bool diff --git a/llarp/router/rc_lookup_handler.hpp b/llarp/router/rc_lookup_handler.hpp index a3b88e924..cc0bed223 100644 --- a/llarp/router/rc_lookup_handler.hpp +++ b/llarp/router/rc_lookup_handler.hpp @@ -44,7 +44,7 @@ namespace llarp SetRouterWhitelist(const std::vector& routers) override EXCLUDES(_mutex); bool - HaveReceivedWhitelist(); + HaveReceivedWhitelist() const override; void GetRC(const RouterID& router, RCRequestCallback callback, bool forceLookup = false) override diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 1f4151321..bff2aa155 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -374,9 +374,21 @@ namespace llarp return inbound_routing_msg_parser.ParseMessageBuffer(buf, h, rxid, this); } + bool + Router::LooksDeregistered() const + { + return IsServiceNode() and whitelistRouters and _rcLookupHandler.HaveReceivedWhitelist() + and not _rcLookupHandler.RemoteIsAllowed(pubkey()); + } + bool Router::ConnectionToRouterAllowed(const RouterID& router) const { + if (LooksDeregistered()) + { + // we are deregistered don't allow any connections outbound at all + return false; + } return _rcLookupHandler.RemoteIsAllowed(router); } @@ -766,7 +778,9 @@ namespace llarp _rcLookupHandler.PeriodicUpdate(now); + const bool gotWhitelist = _rcLookupHandler.HaveReceivedWhitelist(); const bool isSvcNode = IsServiceNode(); + const bool looksDeregistered = LooksDeregistered(); if (_rc.ExpiresSoon(now, std::chrono::milliseconds(randint() % 10000)) || (now - _rc.last_updated) > rcRegenInterval) @@ -775,11 +789,10 @@ namespace llarp if (!UpdateOurRC(false)) LogError("Failed to update our RC"); } - else + else if (not looksDeregistered) { GossipRCIfNeeded(_rc); } - const bool gotWhitelist = _rcLookupHandler.HaveReceivedWhitelist(); // remove RCs for nodes that are no longer allowed by network policy nodedb()->RemoveIf([&](const RouterContact& rc) -> bool { // don't purge bootstrap nodes from nodedb @@ -847,7 +860,7 @@ namespace llarp const int interval = isSvcNode ? 5 : 2; const auto timepoint_now = Clock_t::now(); - if (timepoint_now >= m_NextExploreAt) + if (timepoint_now >= m_NextExploreAt and not looksDeregistered) { _rcLookupHandler.ExploreNetwork(); m_NextExploreAt = timepoint_now + std::chrono::seconds(interval); @@ -859,7 +872,17 @@ namespace llarp connectToNum = strictConnect; } - if (connected < connectToNum) + if (looksDeregistered) + { + // kill all sessions that are open because we think we are deregistered + _linkManager.ForEachPeer([](auto* peer) { + if (peer) + peer->Close(); + }); + // complain about being deregistered + LogError("We are running as a service node but we seem to be decommissioned"); + } + else if (connected < connectToNum) { size_t dlt = connectToNum - connected; LogDebug("connecting to ", dlt, " random routers to keep alive"); @@ -886,7 +909,16 @@ namespace llarp if (m_peerDb->shouldFlush(now)) { LogDebug("Queing database flush..."); - QueueDiskIO([this]() { m_peerDb->flushDatabase(); }); + QueueDiskIO([this]() { + try + { + m_peerDb->flushDatabase(); + } + catch (std::exception& ex) + { + LogError("Could not flush peer stats database: ", ex.what()); + } + }); } } diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 697eb401d..188f2c0ee 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -181,6 +181,10 @@ namespace llarp void QueueDiskIO(std::function func) override; + /// return true if we look like we are a deregistered service node + bool + LooksDeregistered() const; + std::optional _ourAddress; EventLoop_ptr _loop; From 52b9dbd793b57f4523f5904f3a7c6b6a9f52e6a1 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 12 May 2021 11:32:54 -0400 Subject: [PATCH 46/52] version bump for 0.9.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 07b580d08..df20b1ace 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ if(CCACHE_PROGRAM) endif() project(lokinet - VERSION 0.9.0 + VERSION 0.9.1 DESCRIPTION "lokinet - IP packet onion router" LANGUAGES C CXX) From 3c2334112c6d0994ab3d982c0cf07983672d0fcb Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 12 May 2021 12:48:24 -0400 Subject: [PATCH 47/52] when we stop a path builder we want to expire all of their paths so they go away --- llarp/path/pathbuilder.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 87074fd4d..e035bbd5e 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -264,6 +264,14 @@ namespace llarp Builder::Stop() { _run = false; + // tell all our paths that they have expired + const auto now = Now(); + for (auto& item : m_Paths) + { + item.second->EnterState(ePathExpired, now); + } + // remove expired paths + ExpirePaths(now, m_router); return true; } From 2458b5fd719d3b2e931e0ca63370ce243fec66ee Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 13 May 2021 06:09:52 -0400 Subject: [PATCH 48/52] rpc server fixups for win32: * RoutePoker::Enable calls RoutePoker::Up so remove additional call to RoutePoker::Up * allow specifying null exit via rpc --- llarp/rpc/rpc_server.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llarp/rpc/rpc_server.cpp b/llarp/rpc/rpc_server.cpp index 9cc244fb2..7e7ed9eba 100644 --- a/llarp/rpc/rpc_server.cpp +++ b/llarp/rpc/rpc_server.cpp @@ -402,7 +402,7 @@ namespace llarp::rpc { service::Address addr; const auto exit_str = exit_itr->get(); - if (service::NameIsValid(exit_str)) + if (service::NameIsValid(exit_str) or exit_str == "null") { lnsExit = exit_str; } @@ -472,7 +472,6 @@ namespace llarp::rpc } auto onGoodResult = [r, reply](std::string reason) { r->routePoker().Enable(); - r->routePoker().Up(); reply(CreateJSONResponse(reason)); }; if (not shouldSendAuth) From 8c0f448e12b06f5a8e56ca83e40c6e614f106ce9 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 13 May 2021 06:30:40 -0400 Subject: [PATCH 49/52] add liblokinet option to nsis cpack installer --- cmake/win32_installer_deps.cmake | 6 +++++- contrib/windows.sh | 1 + llarp/CMakeLists.txt | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/win32_installer_deps.cmake b/cmake/win32_installer_deps.cmake index bc40a6043..07d0ed39f 100644 --- a/cmake/win32_installer_deps.cmake +++ b/cmake/win32_installer_deps.cmake @@ -26,7 +26,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_BINARY_DIR}/lokinet-g install(DIRECTORY ${CMAKE_BINARY_DIR}/gui DESTINATION share COMPONENT gui) install(PROGRAMS ${TUNTAP_EXE} DESTINATION bin COMPONENT tuntap) -install(FILES ${BOOTSTRAP_FILE} DESTINATION share) +install(FILES ${BOOTSTRAP_FILE} DESTINATION share COMPONENT lokinet) set(CPACK_PACKAGE_INSTALL_DIRECTORY "Lokinet") set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/win32-setup/lokinet.ico") @@ -40,3 +40,7 @@ set(CPACK_NSIS_CREATE_ICONS_EXTRA set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\Lokinet.lnk'" ) + +get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) +list(REMOVE_ITEM CPACK_COMPONENTS_ALL "Unspecified") +list(APPEND CPACK_COMPONENTS_ALL liblokinet) diff --git a/contrib/windows.sh b/contrib/windows.sh index e89a67618..99c814590 100755 --- a/contrib/windows.sh +++ b/contrib/windows.sh @@ -12,6 +12,7 @@ cmake \ -DBUILD_PACKAGE=ON \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_TESTING=OFF \ + -DBUILD_LIBLOKINET=ON \ -DWITH_TESTS=OFF \ -DNATIVE_BUILD=OFF \ -DSTATIC_LINK=ON \ diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 7314971f3..d3be575d6 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -249,7 +249,7 @@ if(BUILD_LIBLOKINET) include(GNUInstallDirs) add_library(lokinet-shared SHARED lokinet_shared.cpp) target_link_libraries(lokinet-shared PUBLIC liblokinet) - install(TARGETS lokinet-shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(TARGETS lokinet-shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT liblokinet) if(WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX_CXX "") target_link_libraries(lokinet-shared PUBLIC ws2_32 iphlpapi -fstack-protector) From 209bcc39dd6502d031458aa161be10c987ecf4bd Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 13 May 2021 06:40:17 -0400 Subject: [PATCH 50/52] make liblokinet target work on nsis cpack --- llarp/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index d3be575d6..bc6423f85 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -249,12 +249,16 @@ if(BUILD_LIBLOKINET) include(GNUInstallDirs) add_library(lokinet-shared SHARED lokinet_shared.cpp) target_link_libraries(lokinet-shared PUBLIC liblokinet) - install(TARGETS lokinet-shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT liblokinet) if(WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX_CXX "") - target_link_libraries(lokinet-shared PUBLIC ws2_32 iphlpapi -fstack-protector) endif() set_target_properties(lokinet-shared PROPERTIES OUTPUT_NAME lokinet) + if(WIN32) + target_link_libraries(lokinet-shared PUBLIC ws2_32 iphlpapi -fstack-protector) + install(TARGETS lokinet-shared DESTINATION bin COMPONENT liblokinet) + else() + install(TARGETS lokinet-shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT liblokinet) + endif() add_log_tag(lokinet-shared) endif() From 499bb38e6f1ca94f66d4c86bce73664f9e391e44 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 13 May 2021 07:30:53 -0400 Subject: [PATCH 51/52] fix route poking via rpc: * immediately poke routes when we are told to use an exit so that packets get pushed which makes an exit path happen * fix up cmake oddity in nsis section --- cmake/win32_installer_deps.cmake | 1 - llarp/router/abstractrouter.hpp | 7 +++++ llarp/router/router.hpp | 2 +- llarp/rpc/rpc_server.cpp | 49 +++++++++++++++++++++----------- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/cmake/win32_installer_deps.cmake b/cmake/win32_installer_deps.cmake index 07d0ed39f..ab59ef540 100644 --- a/cmake/win32_installer_deps.cmake +++ b/cmake/win32_installer_deps.cmake @@ -43,4 +43,3 @@ set(CPACK_NSIS_DELETE_ICONS_EXTRA get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) list(REMOVE_ITEM CPACK_COMPONENTS_ALL "Unspecified") -list(APPEND CPACK_COMPONENTS_ALL liblokinet) diff --git a/llarp/router/abstractrouter.hpp b/llarp/router/abstractrouter.hpp index 2f114a280..9e9043b87 100644 --- a/llarp/router/abstractrouter.hpp +++ b/llarp/router/abstractrouter.hpp @@ -292,6 +292,13 @@ namespace llarp virtual bool ConnectionToRouterAllowed(const RouterID& router) const = 0; + /// return true if we have an exit as a client + virtual bool + HasClientExit() const + { + return false; + }; + virtual path::BuildLimiter& pathBuildLimiter() = 0; diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 188f2c0ee..b1277ed69 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -402,7 +402,7 @@ namespace llarp /// return true if we are a client with an exit configured bool - HasClientExit() const; + HasClientExit() const override; const byte_t* pubkey() const override diff --git a/llarp/rpc/rpc_server.cpp b/llarp/rpc/rpc_server.cpp index 7e7ed9eba..ef5977dbc 100644 --- a/llarp/rpc/rpc_server.cpp +++ b/llarp/rpc/rpc_server.cpp @@ -456,38 +456,54 @@ namespace llarp::rpc { auto mapExit = [=](service::Address addr) mutable { ep->MapExitRange(range, addr); + r->routePoker().Enable(); + r->routePoker().Up(); bool shouldSendAuth = false; if (token.has_value()) { shouldSendAuth = true; ep->SetAuthInfoForEndpoint(*exit, service::AuthInfo{*token}); } + auto onGoodResult = [r, reply](std::string reason) { + if (r->HasClientExit()) + reply(CreateJSONResponse(reason)); + else + reply(CreateJSONError("we dont have an exit?")); + }; + auto onBadResult = [r, reply, ep, range](std::string reason) { + r->routePoker().Down(); + ep->UnmapExitRange(range); + reply(CreateJSONError(reason)); + }; + if (addr.IsZero()) + { + onGoodResult("added null exit"); + return; + } ep->EnsurePathToService( addr, - [reply, r, shouldSendAuth](auto, service::OutboundContext* ctx) { + [onBadResult, onGoodResult, shouldSendAuth, addrStr = addr.ToString()]( + auto, service::OutboundContext* ctx) { if (ctx == nullptr) { - reply(CreateJSONError("could not find exit")); + onBadResult("could not find exit"); return; } - auto onGoodResult = [r, reply](std::string reason) { - r->routePoker().Enable(); - reply(CreateJSONResponse(reason)); - }; if (not shouldSendAuth) { - onGoodResult("OK"); + onGoodResult("OK: connected to " + addrStr); return; } - ctx->AsyncSendAuth([onGoodResult, reply](service::AuthResult result) { - // TODO: refactor this code. We are 5 lambdas deep here! - if (result.code != service::AuthResultCode::eAuthAccepted) - { - reply(CreateJSONError(result.reason)); - return; - } - onGoodResult(result.reason); - }); + ctx->AsyncSendAuth( + [onGoodResult, onBadResult](service::AuthResult result) { + // TODO: refactor this code. We are 5 lambdas deep here! + if (result.code != service::AuthResultCode::eAuthAccepted) + { + onBadResult(result.reason); + return; + } + onGoodResult(result.reason); + }); }, 5s); }; @@ -520,7 +536,6 @@ namespace llarp::rpc else { reply(CreateJSONError("lns name resolved to a snode")); - return; } }); } From 5fb457e18ad2d7b7a2b38ec3b4ea391fa23b6c1c Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 14 May 2021 15:15:00 -0400 Subject: [PATCH 52/52] update release motto --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df20b1ace..f400e0339 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ project(lokinet DESCRIPTION "lokinet - IP packet onion router" LANGUAGES C CXX) -set(RELEASE_MOTTO "Proof of soon" CACHE STRING "Release motto") +set(RELEASE_MOTTO "A Series of Tubes" CACHE STRING "Release motto") add_definitions(-DLLARP_VERSION_MAJOR=${lokinet_VERSION_MAJOR}) add_definitions(-DLLARP_VERSION_MINOR=${lokinet_VERSION_MINOR})