diff --git a/.gitignore b/.gitignore index afba6f033..b688b6ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ *.a *.o -*.plist *.so build/ diff --git a/CMakeLists.txt b/CMakeLists.txt index dac39e848..cec1825bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,9 +13,8 @@ if(CCACHE_PROGRAM) endforeach() endif() -set(PROJECT_NAME lokinet) -project(${PROJECT_NAME} - VERSION 0.8.1 +project(lokinet + VERSION 0.8.2 DESCRIPTION "lokinet - IP packet onion router" LANGUAGES C CXX) @@ -150,7 +149,7 @@ endif() option(FORCE_LOKIMQ_SUBMODULE "force using lokimq submodule" OFF) if(NOT FORCE_LOKIMQ_SUBMODULE) - pkg_check_modules(LOKIMQ liblokimq>=1.2) + pkg_check_modules(LOKIMQ liblokimq>=1.2.2) endif() if(LOKIMQ_FOUND) add_library(lokimq INTERFACE) diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake index c7f3ff197..e90859f93 100644 --- a/cmake/StaticBuild.cmake +++ b/cmake/StaticBuild.cmake @@ -19,10 +19,10 @@ set(EXPAT_SOURCE expat-${EXPAT_VERSION}.tar.xz) set(EXPAT_HASH SHA512=e082874efcc4b00709e2c0192c88fb15dfc4f33fc3a2b09e619b010ea93baaf7e7572683f738463db0ce2350cab3de48a0c38af6b74d1c4f5a9e311f499edab0 CACHE STRING "expat source hash") -set(UNBOUND_VERSION 1.11.0 CACHE STRING "unbound version") +set(UNBOUND_VERSION 1.12.0 CACHE STRING "unbound version") set(UNBOUND_MIRROR ${LOCAL_MIRROR} https://nlnetlabs.nl/downloads/unbound CACHE STRING "unbound download mirror(s)") set(UNBOUND_SOURCE unbound-${UNBOUND_VERSION}.tar.gz) -set(UNBOUND_HASH SHA256=9f2f0798f76eb8f30feaeda7e442ceed479bc54db0e3ac19c052d68685e51ef7 +set(UNBOUND_HASH SHA256=5b9253a97812f24419bf2e6b3ad28c69287261cf8c8fa79e3e9f6d3bf7ef5835 CACHE STRING "unbound source hash") set(SQLITE3_VERSION 3330000 CACHE STRING "sqlite3 version") @@ -232,6 +232,7 @@ add_static_target(expat expat_external libexpat.a) build_external(unbound DEPENDS openssl_external expat_external + PATCH_COMMAND patch -p1 -i ${PROJECT_SOURCE_DIR}/contrib/patches/unbound-no-apple-dontfrag.patch CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-libunbound-only --with-pic --$,enable,disable>-flto --with-ssl=${DEPS_DESTDIR} @@ -257,7 +258,7 @@ add_static_target(sqlite3 sqlite3_external libsqlite3.a) if(ZMQ_VERSION VERSION_LESS 4.3.4 AND CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw) set(zmq_patch - PATCH_COMMAND patch -p1 -i ${PROJECT_SOURCE_DIR}/contrib/cross/patches/libzmq-mingw-closesocket.patch) + PATCH_COMMAND patch -p1 -i ${PROJECT_SOURCE_DIR}/contrib/patches/libzmq-mingw-closesocket.patch) endif() build_external(zmq diff --git a/cmake/macos_installer_deps.cmake b/cmake/macos_installer_deps.cmake index 217433d5d..322cb213c 100644 --- a/cmake/macos_installer_deps.cmake +++ b/cmake/macos_installer_deps.cmake @@ -20,23 +20,45 @@ set(MACOS_NOTARIZE_ASC "" include(ExternalProject) +message(STATUS "Building UninstallLokinet.app") + +ExternalProject_Add(lokinet-uninstaller + SOURCE_DIR ${CMAKE_SOURCE_DIR}/contrib/macos/uninstaller + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR} -DMACOS_SIGN=${MACOS_SIGN_APP} + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} +) + message(STATUS "Building LokinetGUI.app from ${LOKINET_GUI_REPO} @ ${LOKINET_GUI_CHECKOUT}") +if(NOT BUILD_STATIC_DEPS) + message(FATAL_ERROR "Building an installer on macos requires -DBUILD_STATIC_DEPS=ON") +endif() + + + ExternalProject_Add(lokinet-gui + DEPENDS lokimq::lokimq GIT_REPOSITORY "${LOKINET_GUI_REPO}" GIT_TAG "${LOKINET_GUI_CHECKOUT}" CMAKE_ARGS -DMACOS_APP=ON -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR} -DMACOS_SIGN=${MACOS_SIGN_APP} - -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DBUILD_STATIC_DEPS=ON -DBUILD_SHARED_LIBS=OFF - ) - - + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DBUILD_SHARED_LIBS=OFF + "-DLOKIMQ_LIBRARIES=$$$$$" + "-DLOKIMQ_INCLUDE_DIRS=$" + ) install(PROGRAMS ${CMAKE_SOURCE_DIR}/contrib/macos/lokinet_uninstall.sh DESTINATION "bin/" COMPONENT lokinet) install(DIRECTORY ${PROJECT_BINARY_DIR}/LokinetGUI.app - DESTINATION "../../Applications" + DESTINATION "../../Applications/Lokinet" + USE_SOURCE_PERMISSIONS + COMPONENT gui + PATTERN "*" + ) + +install(DIRECTORY ${PROJECT_BINARY_DIR}/UninstallLokinet.app + DESTINATION "../../Applications/Lokinet" USE_SOURCE_PERMISSIONS COMPONENT gui PATTERN "*" @@ -44,9 +66,10 @@ install(DIRECTORY ${PROJECT_BINARY_DIR}/LokinetGUI.app # copy files that will be later moved by the postinstall script to proper locations install(FILES ${CMAKE_SOURCE_DIR}/contrib/macos/lokinet_macos_daemon_script.sh - ${CMAKE_SOURCE_DIR}/contrib/macos/network.loki.lokinet.daemon.plist - DESTINATION "extra/" - COMPONENT lokinet) + ${CMAKE_SOURCE_DIR}/contrib/macos/network.loki.lokinet.daemon.plist + ${CMAKE_SOURCE_DIR}/contrib/macos/lokinet-newsyslog.conf + DESTINATION "extra/" + COMPONENT lokinet) set(CPACK_COMPONENTS_ALL lokinet gui) @@ -58,6 +81,7 @@ set(CPACK_COMPONENT_GUI_DESCRIPTION "Small GUI which provides stats and limited set(CPACK_GENERATOR "productbuild") set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/lokinet") +set(CPACK_PREINSTALL_LOKINET_SCRIPT ${CMAKE_SOURCE_DIR}/contrib/macos/preinstall) set(CPACK_POSTFLIGHT_LOKINET_SCRIPT ${CMAKE_SOURCE_DIR}/contrib/macos/postinstall) set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt") diff --git a/cmake/win32_installer_deps.cmake b/cmake/win32_installer_deps.cmake index 03cfd6d7e..1ca1fe72a 100644 --- a/cmake/win32_installer_deps.cmake +++ b/cmake/win32_installer_deps.cmake @@ -1,5 +1,5 @@ -set(GUI_ZIP_URL "https://builds.lokinet.dev/loki-project/loki-network-control-panel/master/lokinet-gui-windows-32bit-20201106T142720Z-b92e5fd10.zip") -set(GUI_ZIP_HASH SHA256=52868f7bf6d1f4fc7ca587cc79449fefd8000a485bb7917acbc29fdefdd55839) +set(GUI_ZIP_URL "https://builds.lokinet.dev/loki-project/loki-network-control-panel/master/lokinet-gui-windows-32bit-v0.3.4.zip") +set(GUI_ZIP_HASH SHA256=a91467dc37e9f55eea81141253099579ca68749b0ca89637db619d8ab466ccfa) set(TUNTAP_URL "https://build.openvpn.net/downloads/releases/latest/tap-windows-latest-stable.exe") set(TUNTAP_EXE "${CMAKE_BINARY_DIR}/tuntap-install.exe") set(BOOTSTRAP_URL "https://seed.lokinet.org/lokinet.signed") @@ -29,7 +29,7 @@ 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_EXTRA_INSTALL_COMMANDS "ExecWait '$INSTDIR\\\\bin\\\\tuntap-install.exe /S'\\nExecWait '$INSTDIR\\\\bin\\\\lokinet.exe --install'\\nExecWait '$INSTDIR\\\\bin\\\\lokinet.exe -g C:\\\\ProgramData\\\\lokinet\\\\lokinet.ini'\\nCopyFiles '$INSTDIR\\\\share\\\\bootstrap.signed' C:\\\\ProgramData\\\\lokinet\\\\bootstrap.signed") -set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "ExecWait '$INSTDIR\\\\bin\\\\lokinet.exe --remove'\\nRMDir /r /REBOOTOK C:\\\\ProgramData\\\\lokinet") +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'" ) diff --git a/contrib/macos/lokinet-newsyslog.conf b/contrib/macos/lokinet-newsyslog.conf new file mode 100644 index 000000000..69c30ffd3 --- /dev/null +++ b/contrib/macos/lokinet-newsyslog.conf @@ -0,0 +1 @@ +/var/log/lokinet.log 644 5 5M $D0 J \ No newline at end of file diff --git a/contrib/macos/lokinet_uninstall.sh b/contrib/macos/lokinet_uninstall.sh index 68029fa20..63885b972 100755 --- a/contrib/macos/lokinet_uninstall.sh +++ b/contrib/macos/lokinet_uninstall.sh @@ -1,14 +1,53 @@ #!/bin/sh +set -x +test `whoami` == root || exit 1 -touch /var/lib/lokinet/suspend-launchd-service # Prevent restarting on exit +# this is for dns tomfoolery +scutil_query() +{ + key=$1 + + scutil< StandardOutPath - /var/lib/lokinet/stdout - - StandardErrorPath - /var/lib/lokinet/stderr - + /var/log/lokinet.log diff --git a/contrib/macos/postinstall b/contrib/macos/postinstall index 6e8f1638a..ac2674f7f 100644 --- a/contrib/macos/postinstall +++ b/contrib/macos/postinstall @@ -18,6 +18,10 @@ mv /opt/lokinet/extra/network.loki.lokinet.daemon.plist /Library/LaunchDaemons/ chown $CHOWN /Library/LaunchDaemons/network.loki.lokinet.daemon.plist chmod 640 /Library/LaunchDaemons/network.loki.lokinet.daemon.plist +mv /opt/lokinet/extra/lokinet-newsyslog.conf /etc/newsyslog.d/lokinet.conf +chown $CHOWN /etc/newsyslog.d/lokinet.conf +chmod 640 /etc/newsyslog.d/lokinet.conf + # clean up by removing 'extra/' (so long as it's empty) rmdir /opt/lokinet/extra/ diff --git a/contrib/macos/preinstall b/contrib/macos/preinstall new file mode 100644 index 000000000..27006b982 --- /dev/null +++ b/contrib/macos/preinstall @@ -0,0 +1,46 @@ +#!/bin/sh + + +# this is for dns tomfoolery +scutil_query() +{ + key=$1 + + scutil< + + + + + image/svg+xml + + lokinet icon + + + + + + + lokinet icon + + + + + + + + + + + diff --git a/contrib/macos/uninstaller/main.cpp b/contrib/macos/uninstaller/main.cpp new file mode 100644 index 000000000..a58b116c8 --- /dev/null +++ b/contrib/macos/uninstaller/main.cpp @@ -0,0 +1,45 @@ + +#include +#include +#include +#include + +int uninstall(); + +int main(int argc, char * argv[]) +{ + QApplication app{argc, argv}; + if(QMessageBox::question(nullptr, "Lokinet Uninstaller", "Do You want to uninstall Lokinet?", + QMessageBox::Yes|QMessageBox::No) + == QMessageBox::Yes) + { + QMessageBox msgBox; + const auto retcode = uninstall(); + if(retcode == 0) + { + msgBox.setText("Lokinet has been successfully uninstalled, you may now remove the uninstaller if you wish."); + } + else + { + msgBox.setText("Failed to uninstall lokinet"); + } + msgBox.exec(); + } + return 0; +} + +int uninstall() +{ + AuthorizationRef authorizationRef; + OSStatus status; + + status = AuthorizationCreate(nullptr, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef); + if(status != 0) + return status; + char* tool = "/bin/sh"; + char* args[] = {"/opt/lokinet/bin/lokinet_uninstall.sh", nullptr}; + FILE* pipe = stdout; + + return AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe); +} + diff --git a/contrib/macos/uninstaller/mk-icns.sh b/contrib/macos/uninstaller/mk-icns.sh new file mode 100755 index 000000000..8ba62be49 --- /dev/null +++ b/contrib/macos/uninstaller/mk-icns.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Invoked from cmake as mk-icns.sh /path/to/icon.svg /path/to/output.icns +svg="$1" +out="$2" +outdir="${out/%.icns/.iconset}" + +set -e + +mkdir -p "${outdir}" +for size in 16 32 64 128 256 512 1024; do + convert -background none -resize "${size}x${size}" "$svg" -strip "png32:${outdir}/icon_${size}x${size}.png" +done +mv "${outdir}/icon_1024x1024.png" "${outdir}/icon_512x512@2x.png" +for size in 16 32 128 256; do + double=$((size * 2)) + cp "${outdir}/icon_${double}x${double}.png" "${outdir}/icon_${size}x${size}@2x.png" +done + +iconutil -c icns "${outdir}" diff --git a/contrib/cross/patches/libzmq-mingw-closesocket.patch b/contrib/patches/libzmq-mingw-closesocket.patch similarity index 100% rename from contrib/cross/patches/libzmq-mingw-closesocket.patch rename to contrib/patches/libzmq-mingw-closesocket.patch diff --git a/contrib/patches/unbound-no-apple-dontfrag.patch b/contrib/patches/unbound-no-apple-dontfrag.patch new file mode 100644 index 000000000..e6dfa6710 --- /dev/null +++ b/contrib/patches/unbound-no-apple-dontfrag.patch @@ -0,0 +1,11 @@ +--- a/services/listen_dnsport.c 2020-11-16 20:07:44.494582149 -0400 ++++ b/services/listen_dnsport.c 2020-11-16 20:07:31.074585943 -0400 +@@ -533,7 +533,7 @@ + return -1; + } + } +-# elif defined(IP_DONTFRAG) ++# elif defined(IP_DONTFRAG) && !defined(__APPLE__) + int off = 0; + if (setsockopt(s, IPPROTO_IP, IP_DONTFRAG, + &off, (socklen_t)sizeof(off)) < 0) { diff --git a/contrib/windows.sh b/contrib/windows.sh new file mode 100755 index 000000000..5215e4420 --- /dev/null +++ b/contrib/windows.sh @@ -0,0 +1,5 @@ +#!/bin/bash +mkdir -p build-windows +cd build-windows +cmake -G Ninja -DCMAKE_CROSSCOMPILE=ON -DCMAKE_EXE_LINKER_FLAGS=-fstack-protector -DLIBUV_ROOT=$PWD/../external/libuv -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always -DCMAKE_TOOLCHAIN_FILE=../contrib/cross/mingw64.cmake -DBUILD_STATIC_DEPS=ON -DBUILD_PACKAGE=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DWITH_TESTS=OFF -DNATIVE_BUILD=OFF -DSTATIC_LINK=ON -DWITH_SYSTEMD=OFF -DFORCE_LOKIMQ_SUBMODULE=ON -DSUBMODULE_CHECK=OFF -DWITH_LTO=OFF .. +ninja package diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 0500aa9ed..bbadc09f0 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -59,7 +59,7 @@ enable_lto(lokinet-cryptography) add_log_tag(lokinet-cryptography) if(BUILD_SHARED_LIBS) - install(TARGETS lokinet-cryptography LIBRARY DESTINATION lib) + install(TARGETS lokinet-cryptography LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() if (WARNINGS_AS_ERRORS) diff --git a/daemon/lokinet-vpn.cpp b/daemon/lokinet-vpn.cpp index 51ac591bc..5e43f6722 100644 --- a/daemon/lokinet-vpn.cpp +++ b/daemon/lokinet-vpn.cpp @@ -59,6 +59,7 @@ main(int argc, char* argv[]) opts.add_options() ("v,verbose", "Verbose", cxxopts::value()) ("h,help", "help", cxxopts::value()) + ("kill", "kill the daemon", cxxopts::value()) ("up", "put vpn up", cxxopts::value()) ("down", "put vpn down", cxxopts::value()) ("exit", "specify exit node address", cxxopts::value()) @@ -77,6 +78,7 @@ main(int argc, char* argv[]) bool goUp = false; bool goDown = false; bool printStatus = false; + bool killDaemon = false; try { const auto result = opts.parse(argc, argv); @@ -102,6 +104,7 @@ main(int argc, char* argv[]) goUp = result.count("up") > 0; goDown = result.count("down") > 0; printStatus = result.count("status") > 0; + killDaemon = result.count("kill") > 0; if (result.count("endpoint") > 0) { @@ -127,7 +130,7 @@ main(int argc, char* argv[]) std::cout << ex.what() << std::endl; return 1; } - if ((not goUp) and (not goDown) and (not printStatus)) + if ((not goUp) and (not goDown) and (not printStatus) and (not killDaemon)) { std::cout << opts.help() << std::endl; return 1; @@ -161,6 +164,17 @@ main(int argc, char* argv[]) return 1; } + if (killDaemon) + { + const auto maybe = LMQ_Request(lmq, connID, "llarp.halt"); + if (not maybe.has_value()) + { + std::cout << "call to llarp.admin.die failed" << std::endl; + return 1; + } + return 0; + } + if (printStatus) { const auto maybe_status = LMQ_Request(lmq, connID, "llarp.status"); diff --git a/external/loki-mq b/external/loki-mq index ea484729c..e7487fd0c 160000 --- a/external/loki-mq +++ b/external/loki-mq @@ -1 +1 @@ -Subproject commit ea484729c7bb7b430259a422df373e86bdd95b55 +Subproject commit e7487fd0c8ee843b3a3df16563ee42dad2fde050 diff --git a/llarp/config/key_manager.cpp b/llarp/config/key_manager.cpp index 952559372..7827e3916 100644 --- a/llarp/config/key_manager.cpp +++ b/llarp/config/key_manager.cpp @@ -175,32 +175,21 @@ namespace llarp bool KeyManager::loadOrCreateKey( - const fs::path& filepath, - llarp::SecretKey& key, - std::function keygen) + fs::path path, llarp::SecretKey& key, std::function keygen) { - fs::path path(filepath); - std::error_code ec; - if (!fs::exists(path, ec)) + if (not fs::exists(path)) { - if (ec) - { - LogError("Error checking key", filepath, ec.message()); - return false; - } - - LogInfo("Generating new key", filepath); + LogInfo("Generating new key", path); keygen(key); - if (!key.SaveToFile(filepath)) + if (!key.SaveToFile(path)) { LogError("Failed to save new key"); return false; } } - - LogDebug("Loading key from file ", filepath); - return key.LoadFromFile(filepath); + LogDebug("Loading key from file ", path); + return key.LoadFromFile(path); } } // namespace llarp diff --git a/llarp/config/key_manager.hpp b/llarp/config/key_manager.hpp index ca089b1e9..a967ffba3 100644 --- a/llarp/config/key_manager.hpp +++ b/llarp/config/key_manager.hpp @@ -82,7 +82,7 @@ namespace llarp /// @param keygen is a function that will generate the key if needed static bool loadOrCreateKey( - const fs::path& filepath, + fs::path filepath, llarp::SecretKey& key, std::function keygen); }; diff --git a/llarp/net/route.cpp b/llarp/net/route.cpp index cb681ad38..ba7b301b1 100644 --- a/llarp/net/route.cpp +++ b/llarp/net/route.cpp @@ -82,6 +82,14 @@ namespace llarp::net #ifdef __linux__ #ifndef ANDROID + + enum class GatewayMode + { + eFirstHop, + eLowerDefault, + eUpperDefault + }; + struct NLSocket { NLSocket() : fd(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) @@ -139,7 +147,14 @@ namespace llarp::net } int - do_route(int sock, int cmd, int flags, _inet_addr* dst, _inet_addr* gw, int def_gw, int if_idx) + do_route( + int sock, + int cmd, + int flags, + const _inet_addr* dst, + const _inet_addr* gw, + GatewayMode mode, + int if_idx) { struct { @@ -187,27 +202,27 @@ namespace llarp::net if (gw->bitlen != 0) { rtattr_add(&nl_request.n, sizeof(nl_request), RTA_GATEWAY, &gw->data, gw->bitlen / 8); - nl_request.r.rtm_scope = 0; - nl_request.r.rtm_family = gw->family; } - - /* Don't set destination and interface in case of default gateways */ - if (!def_gw) + nl_request.r.rtm_scope = 0; + nl_request.r.rtm_family = gw->family; + if (mode == GatewayMode::eFirstHop) { - /* Set destination network */ rtattr_add( &nl_request.n, sizeof(nl_request), /*RTA_NEWDST*/ RTA_DST, &dst->data, dst->bitlen / 8); - /* Set interface */ rtattr_add(&nl_request.n, sizeof(nl_request), RTA_OIF, &if_idx, sizeof(int)); } - + if (mode == GatewayMode::eUpperDefault) + { + rtattr_add( + &nl_request.n, sizeof(nl_request), /*RTA_NEWDST*/ RTA_DST, &dst->data, sizeof(uint32_t)); + } /* Send message to the netlink */ return send(sock, &nl_request, sizeof(nl_request), 0); } int - read_addr(const char* addr, _inet_addr* res) + read_addr(const char* addr, _inet_addr* res, int bitlen = 32) { if (strchr(addr, ':')) { @@ -217,7 +232,7 @@ namespace llarp::net else { res->family = AF_INET; - res->bitlen = 32; + res->bitlen = bitlen; } return inet_pton(res->family, addr, res->data); } @@ -295,7 +310,6 @@ namespace llarp::net #ifdef __linux__ #ifndef ANDROID NLSocket sock; - int default_gw = 0; int if_idx = 0; _inet_addr to_addr{}; _inet_addr gw_addr{}; @@ -303,7 +317,7 @@ namespace llarp::net int nl_flags = NLM_F_CREATE | NLM_F_EXCL; read_addr(gateway.c_str(), &gw_addr); read_addr(ip.c_str(), &to_addr); - do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, default_gw, if_idx); + do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eFirstHop, if_idx); #endif #else std::stringstream ss; @@ -325,7 +339,6 @@ namespace llarp::net #ifdef __linux__ #ifndef ANDROID NLSocket sock; - int default_gw = 0; int if_idx = 0; _inet_addr to_addr{}; _inet_addr gw_addr{}; @@ -333,7 +346,7 @@ namespace llarp::net int nl_flags = 0; read_addr(gateway.c_str(), &gw_addr); read_addr(ip.c_str(), &to_addr); - do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, default_gw, if_idx); + do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eFirstHop, if_idx); #endif #else std::stringstream ss; @@ -355,20 +368,23 @@ namespace llarp::net #ifdef __linux__ #ifndef ANDROID NLSocket sock; - int default_gw = 1; int if_idx = if_nametoindex(ifname.c_str()); _inet_addr to_addr{}; _inet_addr gw_addr{}; - const auto maybe = GetIFAddr(ifname); if (not maybe.has_value()) throw std::runtime_error("we dont have our own net interface?"); int nl_cmd = RTM_NEWROUTE; int nl_flags = NLM_F_CREATE | NLM_F_EXCL; read_addr(maybe->toHost().c_str(), &gw_addr); - do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, default_gw, if_idx); + read_addr("0.0.0.0", &to_addr, 1); + do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eLowerDefault, if_idx); + read_addr("128.0.0.0", &to_addr, 1); + do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eUpperDefault, if_idx); #endif #elif _WIN32 + // poke hole for loopback bacause god is dead on windows + Execute(RouteCommand() + " ADD 127.0.0.0 MASK 255.0.0.0 0.0.0.0"); ifname.back()++; Execute(RouteCommand() + " ADD 0.0.0.0 MASK 128.0.0.0 " + ifname); Execute(RouteCommand() + " ADD 128.0.0.0 MASK 128.0.0.0 " + ifname); @@ -387,7 +403,6 @@ namespace llarp::net #ifdef __linux__ #ifndef ANDROID NLSocket sock; - int default_gw = 1; int if_idx = if_nametoindex(ifname.c_str()); _inet_addr to_addr{}; _inet_addr gw_addr{}; @@ -398,12 +413,16 @@ namespace llarp::net int nl_cmd = RTM_DELROUTE; int nl_flags = 0; read_addr(maybe->toHost().c_str(), &gw_addr); - do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, default_gw, if_idx); + read_addr("0.0.0.0", &to_addr, 1); + do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eLowerDefault, if_idx); + read_addr("128.0.0.0", &to_addr, 1); + do_route(sock.fd, nl_cmd, nl_flags, &to_addr, &gw_addr, GatewayMode::eUpperDefault, if_idx); #endif #elif _WIN32 ifname.back()++; Execute(RouteCommand() + " DELETE 0.0.0.0 MASK 128.0.0.0 " + ifname); Execute(RouteCommand() + " DELETE 128.0.0.0 MASK 128.0.0.0 " + ifname); + Execute(RouteCommand() + " DELETE 127.0.0.0 MASK 255.0.0.0 0.0.0.0"); #elif __APPLE__ Execute("/sbin/route -n delete -cloning -net 0.0.0.0 -netmask 128.0.0.0 -interface " + ifname); Execute( diff --git a/llarp/rpc/rpc_server.cpp b/llarp/rpc/rpc_server.cpp index 1dd861cc3..a0d138f54 100644 --- a/llarp/rpc/rpc_server.cpp +++ b/llarp/rpc/rpc_server.cpp @@ -93,8 +93,8 @@ namespace llarp::rpc msg.send_reply(CreateJSONError("router is not running")); return; } - m_Router->Stop(); msg.send_reply(CreateJSONResponse("OK")); + m_Router->Stop(); }) .add_request_command( "version",