From 472b28690c5bc7008bb610217d043c70cb3459b1 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 10 Mar 2019 11:52:07 -0400 Subject: [PATCH 1/4] typo fix --- docs/high-level.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/high-level.txt b/docs/high-level.txt index 667a2d0e1..5fa07a097 100644 --- a/docs/high-level.txt +++ b/docs/high-level.txt @@ -27,7 +27,7 @@ LLARP - Low Latency Anon Routing Protocol state sponsored network attacks. The former is an inherit property of low latency computer networks that I personally do not think is possible to properly fully "solve". The latter is a threat that lies outside the scope of what the current - toolset that is available to me at the moment. + toolset that is available to me at the moment provides. This project does not attempt to be a magical application level cure-all for From 734a5b5faeae7a4d067c990ce2f717704189ac16 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 11 Mar 2019 09:01:43 -0400 Subject: [PATCH 2/4] more --- .gitignore | 5 ++++ CMakeLists.txt | 34 ++++++++++++------------ Makefile | 19 +++++++------ llarp/ev/ev_win32.cpp | 60 ++++++++++++++++++++++++++++++++++++------ llarp/ev/ev_win32.hpp | 11 ++++---- llarp/handlers/tun.hpp | 1 - llarp/link/server.cpp | 11 +++----- llarp/link/server.hpp | 4 +-- llarp/link/utp.cpp | 1 - 9 files changed, 95 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index 37c91958a..2a12295e3 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,8 @@ build2/ /contrib/lokinet-bootstrap-winnt/data.enc /contrib/lokinet-bootstrap-winnt/out.bine default.profraw + +# ctags shit +GTAGS +GRTAGS +GPATH \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 165e43a4e..249042e41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,11 +59,10 @@ add_subdirectory(vendor/nlohmann) # still need the headers unconditionally set(ABSEIL_DIR vendor/abseil-cpp) include_directories(${ABSEIL_DIR}) - if (NOT WIN32) add_compile_options(-fPIC) - add_subdirectory(${ABSEIL_DIR}) endif(NOT WIN32) +add_subdirectory(${ABSEIL_DIR}) # turns off those annoying warnings for # target-specific crypto code paths not @@ -168,7 +167,7 @@ if(ASAN) endif(ASAN) if(SHADOW) - set(WITH_STATIC OFF) + set(WITH_SHARED ON) add_compile_options(-fPIC) if("${SHADOW_ROOT}" STREQUAL "") set(SHADOW_ROOT "$ENV{HOME}/.shadow") @@ -182,12 +181,10 @@ if(SHADOW) set(CMAKE_MODULE_PATH "${SHADOW_ROOT}/share/cmake/Modules") include_directories(${CMAKE_MODULE_PATH}) include(ShadowTools) - add_compile_options( -fno-inline -fno-strict-aliasing ) - add_definitions(-DTESTNET=true) + add_compile_options(-fno-inline -fno-strict-aliasing ) + add_definitions(-DTESTNET=1) add_definitions(-DSHADOW_TESTNET) include_directories(${SHADOW_ROOT}/include) -else() - set(WITH_STATIC ON) endif(SHADOW) if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]") @@ -346,11 +343,19 @@ endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") add_log_tag(${ABYSS_EXE}) add_log_tag(${ABYSS_LIB}) +if (WIN32) + set(EXE_LIBS ${STATIC_LIB} ws2_32 iphlpapi) +else() + set(EXE_LIBS ${STATIC_LIB} cppbackport libutp) +endif(WIN32) + + if(SHADOW) - add_shadow_plugin(shadow-plugin-${SHARED_LIB} ${EXE_SRC}) - target_include_directories(shadow-plugin-${SHARED_LIB} PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/llarp ${PROJECT_SOURCE_DIR}/crypto/include ${PROJECT_SOURCE_DIR}/vendor/cppbackport-master/lib) - target_link_libraries(shadow-plugin-${SHARED_LIB} ${STATIC_LIB} ${LIBS}) - install(TARGETS shadow-plugin-${SHARED_LIB} DESTINATION plugins) + set(LOKINET_SHADOW shadow-plugin-${SHARED_LIB}) + set(LOKINET_SHADOW_LIBS ${SHARED_LIB}) + add_shadow_plugin(${LOKINET_SHADOW} ${EXE_SRC}) + target_link_libraries(${LOKINET_SHADOW} ${LOKINET_SHADOW_LIBS}) + target_include_directories(${LOKINET_SHADOW} PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/llarp ${PROJECT_SOURCE_DIR}/crypto/include ${PROJECT_SOURCE_DIR}/vendor/cppbackport-master/lib) else() if(NOT WIN32) add_executable(${EXE} ${EXE_SRC}) @@ -371,12 +376,7 @@ else() install(CODE "execute_process(COMMAND setcap cap_net_admin,cap_net_bind_service=+eip ${CMAKE_INSTALL_PREFIX}/bin/lokinet)") endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - if (WIN32) - target_link_libraries(${EXE} PUBLIC ${STATIC_LIB} ws2_32 iphlpapi) - else() - target_link_libraries(${EXE} PUBLIC ${STATIC_LIB} cppbackport libutp) - endif(WIN32) - + target_link_libraries(${EXE} PUBLIC ${EXE_LIBS}) if(ANDROID) add_library(${ANDROID_LIB} SHARED jni/lokinet_android.cpp) diff --git a/Makefile b/Makefile index 2d752643f..a4f80574c 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ SHADOW_LOG=$(REPO)/shadow.log.txt SHADOW_SRC ?= $(HOME)/local/shadow SHADOW_PARSE ?= $(PYTHON) $(SHADOW_SRC)/src/tools/parse-shadow.py - -m 0 --packet-data SHADOW_PLOT ?= $(PYTHON) $(SHADOW_SRC)/src/tools/plot-shadow.py -d $(REPO) LokiNET -c $(SHADOW_CONFIG) -r 10000 -e '.*' +SHADOW_OPTS ?= TESTNET_ROOT=/tmp/lokinet_testnet_tmp TESTNET_CONF=$(TESTNET_ROOT)/supervisor.conf @@ -82,11 +83,11 @@ BUILD_ROOT = $(REPO)/build SCAN_BUILD ?= scan-build -CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) '$(REPO)'") +CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON '$(REPO)'") -ANALYZE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "$(SCAN_BUILD) cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) '$(REPO)'") +ANALYZE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "$(SCAN_BUILD) cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON '$(REPO)'") -COVERAGE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) -DWITH_COVERAGE=yes '$(REPO)'") +COVERAGE_CONFIG_CMD = $(shell /bin/echo -n "cd '$(BUILD_ROOT)' && " ; /bin/echo -n "cmake -G'$(CMAKE_GEN)' -DCMAKE_CROSSCOMPILING=$(CROSS) -DSTATIC_LINK_RUNTIME=$(STATIC_LINK) -DUSE_NETNS=$(NETNS) -DUSE_AVX2=$(AVX2) -DUSE_LIBABYSS=$(JSONRPC) -DNON_PC_TARGET=$(NON_PC_TARGET) -DWITH_SHARED=$(SHARED_LIB) -DWITH_COVERAGE=yes -DCMAKE_EXPORT_COMPILE_COMMANDS=ON '$(REPO)'") TARGETS = $(REPO)/lokinet SIGS = $(TARGETS:=.sig) @@ -139,8 +140,8 @@ shadow-build: shadow-configure shadow-run: shadow-build $(PYTHON) $(REPO)/contrib/shadow/genconf.py $(SHADOW_CONFIG) - cp $(SHADOW_PLUGIN) $(REPO) - bash -c "$(SHADOW_BIN) -w $$(cat /proc/cpuinfo | grep processor | wc -l) $(SHADOW_CONFIG) | $(SHADOW_PARSE)" + cp $(SHADOW_PLUGIN) $(REPO)/libshadow-plugin-lokinet.so + $(SHADOW_BIN) $(SHADOW_OPTS) $(SHADOW_CONFIG) | $(SHADOW_PARSE) shadow-plot: shadow-run $(SHADOW_PLOT) @@ -184,14 +185,16 @@ android-gradle: android-gradle-prepare android: android-gradle cp -f $(ANDROID_DIR)/build/outputs/apk/*.apk $(REPO) -windows-configure: clean +windows-release-configure: clean mkdir -p '$(BUILD_ROOT)' - $(CONFIG_CMD) -DCMAKE_CROSSCOMPILING=ON -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/mingw.cmake' -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc-win32 -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++-win32 -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' + $(CONFIG_CMD) -DCMAKE_TOOLCHAIN_FILE='$(REPO)/contrib/cross/mingw.cmake' -DCMAKE_BUILD_TYPE=Release -DCMAKE_ASM_FLAGS='$(ASFLAGS)' -DCMAKE_C_FLAGS='$(CFLAGS)' -DCMAKE_CXX_FLAGS='$(CXXFLAGS)' -windows: windows-configure +windows-release: windows-release-configure $(MAKE) -C '$(BUILD_ROOT)' cp '$(BUILD_ROOT)/lokinet.exe' '$(REPO)/lokinet.exe' +windows: windows-release + abyss: debug $(ABYSS_EXE) diff --git a/llarp/ev/ev_win32.cpp b/llarp/ev/ev_win32.cpp index 34e85bd07..402fc3d74 100644 --- a/llarp/ev/ev_win32.cpp +++ b/llarp/ev/ev_win32.cpp @@ -12,13 +12,12 @@ static CRITICAL_SECTION HandlerMtx; std::list< win32_tun_io* > tun_listeners; void -begin_tun_loop(int nThreads) +win32_tun_io::begin_tun_loop(int nThreads) { kThreadPool = new HANDLE[nThreads]; for(int i = 0; i < nThreads; ++i) { - kThreadPool[i] = - CreateThread(nullptr, 0, &tun_ev_loop, nullptr, 0, nullptr); + kThreadPool[i] = CreateThread(nullptr, 0, &tun_ev_loop, this, 0, nullptr); } llarp::LogInfo("created ", nThreads, " threads for TUN event queue"); poolSize = nThreads; @@ -124,11 +123,48 @@ win32_tun_io::read(byte_t* buf, size_t sz) ReadFile(tunif->tun_fd, buf, sz, nullptr, &pkt->pkt); } +static void +tun_ev_tick_and_flush(void* user) +{ + llarp_tun_io* tun = static_cast< llarp_tun_io* >(user); + if(tun->tick) + tun->tick(tun); + tun->flush(tun); +} + +struct tun_pkt_t +{ + std::vector< byte_t > pkt; + llarp_tun_io* tun; + + tun_pkt_t(llarp_tun_io* t, const byte_t* buf, size_t sz) : tun(t), pkt(sz) + { + std::copy_n(buf, sz, pkt.begin()); + } + + static void + recv_pkt(void* user) + { + tun_pkt_t* pkt = static_cast< tun_pkt_t* >(user); + pkt->Recv(); + delete pkt; + } + + private: + void + Recv() + { + llarp_buffer_t buf(pkt); + if(tun->recvpkt) + tun->recvpkt(tun, buf); + } +} + // and now the event loop itself extern "C" DWORD FAR PASCAL -tun_ev_loop(void* unused) +tun_ev_loop(void* user) { - UNREFERENCED_PARAMETER(unused); + win32_tun_io* tun_io = static_cast< win32_tun_io* >(user); DWORD size = 0; OVERLAPPED* ovl = nullptr; @@ -148,11 +184,14 @@ tun_ev_loop(void* unused) // of the tun logic for(const auto& tun : tun_listeners) { + /* EnterCriticalSection(&HandlerMtx); if(tun->t->tick) tun->t->tick(tun->t); tun->flush_write(); LeaveCriticalSection(&HandlerMtx); + */ + tun_io->logic->queue_job({tun->t, &tun_ev_tick_and_flush}); } continue; // let's go at it once more } @@ -173,8 +212,10 @@ tun_ev_loop(void* unused) continue; } // EnterCriticalSection(&HandlerMtx); - if(ev->t->recvpkt) - ev->t->recvpkt(ev->t, llarp_buffer_t(pkt->buf, size)); + tun_pkt_t* recv_pkt = new tun_pkt_t(ev->t, pkt->buf, size); + tun_io->logic->queue_job({recv_pkt, &tun_pkt_t::recv_pkt}); + // if(ev->t->recvpkt) + // ev->t->recvpkt(ev->t, llarp_buffer_t(pkt->buf, size)); ev->read(ev->readbuf, sizeof(ev->readbuf)); // LeaveCriticalSection(&HandlerMtx); } @@ -185,11 +226,14 @@ tun_ev_loop(void* unused) ev->read(ev->readbuf, sizeof(ev->readbuf)); // LeaveCriticalSection(&HandlerMtx); } + /* EnterCriticalSection(&HandlerMtx); if(ev->t->tick) ev->t->tick(ev->t); ev->flush_write(); LeaveCriticalSection(&HandlerMtx); + */ + tun_io->logic->queue_job({ev->t, &tun_ev_tick_and_flush}); delete pkt; // don't leak } llarp::LogDebug("exit TUN event loop thread from system managed thread pool"); @@ -657,4 +701,4 @@ llarp_win32_loop::stop() upoll_destroy(upollfd); upollfd = nullptr; llarp::LogDebug("destroy upoll"); -} \ No newline at end of file +} diff --git a/llarp/ev/ev_win32.hpp b/llarp/ev/ev_win32.hpp index 0d9c31fd8..d3ac84c34 100644 --- a/llarp/ev/ev_win32.hpp +++ b/llarp/ev/ev_win32.hpp @@ -23,14 +23,11 @@ struct asio_evt_pkt }; extern "C" DWORD FAR PASCAL -tun_ev_loop(void* unused); +tun_ev_loop(void* ev); void exit_tun_loop(); -void -begin_tun_loop(int nThreads); - namespace llarp { struct udp_listener : public ev_io @@ -60,10 +57,12 @@ namespace llarp struct win32_tun_io { llarp_tun_io* t; + llarp::Logic* logic; device* tunif; byte_t readbuf[EV_READ_BUF_SZ] = {0}; - win32_tun_io(llarp_tun_io* tio) : t(tio), tunif(tuntap_init()){}; + win32_tun_io(llarp_tun_io* tio, llarp::Logic* l) + : t(tio), logic(l), tunif(tuntap_init()){}; bool queue_write(const byte_t* buf, size_t sz); @@ -152,4 +151,4 @@ struct llarp_win32_loop : public llarp_ev_loop stop(); }; -#endif \ No newline at end of file +#endif diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index c66e8a099..b83d11d93 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -184,7 +184,6 @@ namespace llarp QueueInboundPacketForExit(const llarp_buffer_t& buf) { ManagedBuffer copy{buf}; - return m_NetworkToUserPktQueue.EmplaceIf( [&](llarp::net::IPv4Packet& pkt) -> bool { if(!pkt.Load(copy.underlying)) diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index e594314a7..8cd6fac76 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -123,7 +123,10 @@ namespace llarp ++itr; } else + { + LogInfo("pending session at ", itr->first, " timed out"); itr = m_Pending.erase(itr); + } } } } @@ -166,14 +169,6 @@ namespace llarp return false; } - void - ILinkLayer::RemovePending(ILinkSession* s) - { - Lock l(&m_PendingMutex); - llarp::Addr remote = s->GetRemoteEndpoint(); - m_Pending.erase(remote); - } - util::StatusObject ILinkLayer::ExtractStatus() const { diff --git a/llarp/link/server.hpp b/llarp/link/server.hpp index ef5cc0f2e..dc2ba4dc2 100644 --- a/llarp/link/server.hpp +++ b/llarp/link/server.hpp @@ -197,8 +197,8 @@ namespace llarp SessionRenegotiateHandler SessionRenegotiate; /// called by link session to remove a pending session who is timed out - void - RemovePending(ILinkSession* s) LOCKS_EXCLUDED(m_PendingMutex); + // void + // RemovePending(ILinkSession* s) LOCKS_EXCLUDED(m_PendingMutex); private: static void diff --git a/llarp/link/utp.cpp b/llarp/link/utp.cpp index 4b8c81b9b..ac5ee31cc 100644 --- a/llarp/link/utp.cpp +++ b/llarp/link/utp.cpp @@ -358,7 +358,6 @@ namespace llarp utp_close(arg->socket); else session->Close(); - link->RemovePending(session); } return 0; } From 232a7ff0108b52ac7674522c55bf9b0cd0035c39 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 11 Mar 2019 09:01:53 -0400 Subject: [PATCH 3/4] more --- llarp/CMakeLists.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 5ca41df34..a7b1685e7 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -203,17 +203,18 @@ set(LIB_SRC service/types.cpp service/vanity.cpp ) +if(TESTNET) + set(LIB_SRC ${LIB_SRC} testnet.c) +endif() add_library(${STATIC_LIB} STATIC ${LIB_SRC}) -target_link_libraries(${STATIC_LIB} PUBLIC ${ABYSS_LIB} ${PLATFORM_LIB} ${UTIL_LIB} ${CRYPTOGRAPHY_LIB} libutp ${LIBS}) - -if(TESTNET) - target_sources(${STATIC_LIB} PUBLIC testnet.c) -endif() +set(LIBS ${LIBS} libutp) +target_link_libraries(${STATIC_LIB} PUBLIC ${ABYSS_LIB} ${PLATFORM_LIB} ${UTIL_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS}) if(WITH_SHARED) add_library(${SHARED_LIB} SHARED ${LIB_SRC}) - target_link_libraries(${SHARED_LIB} PUBLIC ${ABYSS_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS} ${UTIL_LIB} ${PLATFORM_LIB} Threads::Threads) + set(LIBS ${LIBS} Threads::Threads) + target_link_libraries(${SHARED_LIB} PUBLIC ${ABYSS_LIB} ${CRYPTOGRAPHY_LIB} ${UTIL_LIB} ${PLATFORM_LIB} ${LIBS}) if (WIN32) target_link_libraries(${SHARED_LIB} PUBLIC ws2_32 iphlpapi) else() From 5d3833ef1aad5baf487488208dff45d00a0bfd53 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 11 Mar 2019 09:58:31 -0400 Subject: [PATCH 4/4] fix dumb as shit path building that causes premature termiantion because of duplicate hops --- llarp/exit/session.cpp | 5 +++++ llarp/link/utp.cpp | 2 ++ llarp/nodedb.cpp | 44 ++++++++++++++++++++++++++++++++++++++ llarp/nodedb.hpp | 7 ++++++ llarp/path/path.cpp | 9 ++++++++ llarp/path/path.hpp | 3 +++ llarp/path/pathbuilder.cpp | 10 ++++++--- llarp/path/pathset.cpp | 2 +- llarp/profiling.cpp | 2 +- llarp/router_contact.hpp | 6 ++++++ llarp/service/endpoint.cpp | 5 +++++ 11 files changed, 90 insertions(+), 5 deletions(-) diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 100e8a1e7..f4a5f2603 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -67,6 +67,11 @@ namespace llarp { return db->Get(m_ExitRouter, cur); } + else if(hop == numHops - 2) + { + return db->select_random_hop_excluding(cur, + {prev.pubkey, m_ExitRouter}); + } else return path::Builder::SelectHop(db, prev, cur, hop, roles); } diff --git a/llarp/link/utp.cpp b/llarp/link/utp.cpp index ac5ee31cc..ae030b35b 100644 --- a/llarp/link/utp.cpp +++ b/llarp/link/utp.cpp @@ -228,6 +228,8 @@ namespace llarp bool Session::IsTimedOut(llarp_time_t now) const { + if(state == eConnecting) + return false; if(state == eClose) return true; if(now <= lastActive) diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index bcef02c6c..897886f90 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -468,3 +468,47 @@ llarp_nodedb::select_random_hop(const llarp::RouterContact &prev, } return false; } + +bool +llarp_nodedb::select_random_hop_excluding( + llarp::RouterContact &result, const std::set< llarp::RouterID > &exclude) +{ + llarp::util::Lock lock(&access); + /// checking for "guard" status for N = 0 is done by caller inside of + /// pathbuilder's scope + size_t sz = entries.size(); + if(sz < 3) + return false; + llarp_time_t now = llarp::time_now_ms(); + + auto itr = entries.begin(); + size_t pos = llarp::randint() % sz; + std::advance(itr, pos); + auto start = itr; + while(itr == entries.end()) + { + if(exclude.count(itr->first) == 0) + { + if(itr->second.addrs.size() && !itr->second.IsExpired(now)) + { + result = itr->second; + return true; + } + } + itr++; + } + itr = entries.begin(); + while(itr != start) + { + if(exclude.count(itr->first) == 0) + { + if(itr->second.addrs.size() && !itr->second.IsExpired(now)) + { + result = itr->second; + return true; + } + } + ++itr; + } + return false; +} diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 61109797e..b3c4a94fe 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -9,6 +9,8 @@ #include +#include + /** * nodedb.hpp * @@ -113,6 +115,11 @@ struct llarp_nodedb llarp::RouterContact &result, size_t N) LOCKS_EXCLUDED(access); + bool + select_random_hop_excluding(llarp::RouterContact &result, + const std::set< llarp::RouterID > &exclude) + LOCKS_EXCLUDED(access); + static bool ensure_dir(const char *dir); }; diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index f3d7931a5..dcd546cc9 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -450,6 +450,15 @@ namespace llarp return hops[0].rc.pubkey; } + std::string + Path::HopsString() const + { + std::stringstream ss; + for(const auto& hop : hops) + ss << RouterID(hop.rc.pubkey) << " -> "; + return ss.str(); + } + void Path::EnterState(PathStatus st, llarp_time_t now) { diff --git a/llarp/path/path.hpp b/llarp/path/path.hpp index 12fcaa510..ab1ee722b 100644 --- a/llarp/path/path.hpp +++ b/llarp/path/path.hpp @@ -362,6 +362,9 @@ namespace llarp return _status; } + std::string + HopsString() const; + llarp_time_t LastRemoteActivityAt() const override { diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 5b2289f79..53433b005 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -213,11 +213,15 @@ namespace llarp size_t tries = 10; do { + cur.Clear(); --tries; if(db->select_random_hop(prev, cur, hop)) - return true; - } while(router->routerProfiling().IsBad(cur.pubkey) && tries > 0); - return false; + { + if(!router->routerProfiling().IsBad(cur.pubkey)) + return true; + } + } while(tries > 0); + return tries > 0; } bool diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index 469899eb1..54efeffd1 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -292,7 +292,7 @@ namespace llarp void PathSet::HandlePathBuildTimeout(Path* p) { - LogInfo("path build for ", p->Name(), " has timed out"); + LogInfo("path build ", p->HopsString(), " timed out"); } bool diff --git a/llarp/profiling.cpp b/llarp/profiling.cpp index 4bb7146a1..da2a1164d 100644 --- a/llarp/profiling.cpp +++ b/llarp/profiling.cpp @@ -70,7 +70,7 @@ namespace llarp bool RouterProfile::IsGood(uint64_t chances) const { - if(connectTimeoutCount > 3) + if(connectTimeoutCount > chances) return connectTimeoutCount <= connectGoodCount && (pathSuccessCount * chances) >= pathFailCount; else diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 4ee9278e4..db7a0e9a3 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -131,6 +131,12 @@ namespace llarp && netID == other.netID; } + bool + operator<(const RouterContact &other) const + { + return pubkey < other.pubkey; + } + bool operator!=(const RouterContact &other) const { diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index d89520e78..d589c71ec 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1854,6 +1854,11 @@ namespace llarp return false; } } + else if(hop == numHops - 2) + { + return db->select_random_hop_excluding( + cur, {prev.pubkey, m_NextIntro.router}); + } (void)roles; return path::Builder::SelectHop(db, prev, cur, hop, roles); }