mirror of https://github.com/oxen-io/lokinet
Merge branch 'master' of https://github.com/majestrate/llarp + gcc 7.2 fixes
This commit is contained in:
commit
16c56ff04b
123
CMakeLists.txt
123
CMakeLists.txt
|
@ -13,27 +13,37 @@ endmacro(add_cxxflags)
|
|||
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
|
||||
if (WIN32 AND NOT MINGW)
|
||||
CHECK_CXX_COMPILER_FLAG("/std:c++17" COMPILER_SUPPORTS_CXX17)
|
||||
else()
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17)
|
||||
if(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
||||
endif()
|
||||
|
||||
option(HAVE_CXX17_FILESYSTEM "Enable if your C++ compiler and runtime library implements std::[experimental::]filesystem" OFF)
|
||||
|
||||
if(COMPILER_SUPPORTS_CXX11 AND NOT HAVE_CXX17_FILESYSTEM)
|
||||
add_cxxflags("-std=c++11")
|
||||
elseif(COMPILER_SUPPORTS_CXX17)
|
||||
elseif(COMPILER_SUPPORTS_CXX17 AND HAVE_CXX17_FILESYSTEM)
|
||||
if (WIN32 AND NOT MINGW)
|
||||
add_cxxflags("/std:c++17")
|
||||
else()
|
||||
add_cxxflags("-std=c++17")
|
||||
endif()
|
||||
add_definitions(-DUSE_CXX17_FILESYSTEM)
|
||||
else()
|
||||
message(ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 or C++17 support. Please use a different C++ compiler.")
|
||||
endif()
|
||||
|
||||
# attempting to fix linux gcc 7.2 which COMPILER_SUPPORTS_CXX17 but doesn't have filesystem.h
|
||||
include(CheckIncludeFileCXX)
|
||||
CHECK_INCLUDE_FILE_CXX(filesystem.h HAVE_STD_FS)
|
||||
|
||||
if(ANDROID)
|
||||
set(THREAD_LIB "-pthread")
|
||||
# finally removed pthread dependency for MSC++
|
||||
elseif(WIN32 AND NOT MINGW)
|
||||
set(THREAD_LIB)
|
||||
else()
|
||||
set(THREAD_LIB pthread)
|
||||
endif()
|
||||
|
||||
if(STATIC_LINK)
|
||||
set(STATIC_LINK_LIBS c)
|
||||
add_cflags("-static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
|
||||
add_cxxflags("-static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
|
||||
endif()
|
||||
|
@ -44,11 +54,18 @@ else()
|
|||
set(WITH_STATIC ON)
|
||||
endif()
|
||||
|
||||
if (UNIX OR MINGW OR APPLE)
|
||||
add_cflags("-Wall")
|
||||
add_cxxflags("-Wall")
|
||||
endif()
|
||||
|
||||
set(DEBUG_FLAGS "-g")
|
||||
if (WIN32 AND NOT MINGW)
|
||||
set(OPTIMIZE_FLAGS "-Od")
|
||||
set(DEBUG_FLAGS "-ZI")
|
||||
else()
|
||||
set(OPTIMIZE_FLAGS "-O0")
|
||||
set(DEBUG_FLAGS "-g")
|
||||
endif()
|
||||
|
||||
if(ASAN)
|
||||
set(DEBUG_FLAGS "${DEBUG_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||
|
@ -69,14 +86,18 @@ if(SHADOW)
|
|||
include(ShadowTools)
|
||||
add_cxxflags("-fno-inline -fno-strict-aliasing")
|
||||
add_cflags("-fno-inline -fno-strict-aliasing")
|
||||
|
||||
add_definitions(-DTESTNET=true)
|
||||
add_definitions(-DSHADOW_TESTNET)
|
||||
include_directories(${SHADOW_ROOT}/include)
|
||||
endif()
|
||||
|
||||
if (WIN32 AND NOT MINGW)
|
||||
add_cflags("-wd4996 -wd4244 -MP ${OPTIMIZE_FLAGS}")
|
||||
add_cxxflags("-wd4996 -wd4244 -MP ${OPTIMIZE_FLAGS}")
|
||||
else()
|
||||
add_cflags("-Wall -Wno-deprecated-declarations ${OPTIMIZE_FLAGS}")
|
||||
add_cxxflags("-Wall -Wno-deprecated-declarations ${OPTIMIZE_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
|
||||
add_cflags("${DEBUG_FLAGS}")
|
||||
|
@ -116,37 +137,50 @@ endif()
|
|||
|
||||
set(LIBS ${SODIUM_LIB} ${THREAD_LIB})
|
||||
|
||||
set(LIB llarp)
|
||||
set(LIB lokinet)
|
||||
set(SHARED_LIB ${LIB})
|
||||
set(STATIC_LIB ${LIB}-static)
|
||||
|
||||
set(TT_ROOT vendor/libtuntap-master)
|
||||
|
||||
add_definitions(-D${CMAKE_SYSTEM_NAME})
|
||||
|
||||
if (UNIX)
|
||||
add_definitions(-DUNIX)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-linux.c)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-linux.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-openbsd.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-netbsd.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "DragonFly")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-freebsd.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-unix-darwin.c ${TT_ROOT}/tuntap-unix-bsd.c)
|
||||
else()
|
||||
message(FATAL_ERROR "Your operating system is not supported yet")
|
||||
endif()
|
||||
elseif(WIN32 OR MINGW)
|
||||
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
else()
|
||||
message(FATAL_ERROR "What operating system _are_ you building on/for?")
|
||||
endif(UNIX)
|
||||
|
||||
if(TUNTAP)
|
||||
set(LIBTUNTAP_SRC
|
||||
${TT_ROOT}/tuntap.c
|
||||
${TT_ROOT}/tuntap_log.c
|
||||
if (UNIX)
|
||||
${TT_ROOT}/tuntap-unix.c
|
||||
endif()
|
||||
${LIBTUNTAP_IMPL})
|
||||
else()
|
||||
set(LIBTUNTAP_SRC "")
|
||||
|
@ -198,6 +232,11 @@ set(LIB_PLATFORM_SRC
|
|||
llarp/threadpool.cpp
|
||||
# for android shim
|
||||
${ANDROID_PLATFORM_SRC}
|
||||
# win32 inline procs
|
||||
llarp/win32_inet.c
|
||||
llarp/win32_intrnl.c
|
||||
contrib/msc/getopt.c
|
||||
contrib/msc/getopt1.c
|
||||
)
|
||||
|
||||
|
||||
|
@ -303,12 +342,16 @@ set(STATIC_LIB ${LIB}-static)
|
|||
|
||||
# TODO: exclude this from includes and expose stuff properly for rcutil
|
||||
include_directories(llarp)
|
||||
|
||||
include_directories(include)
|
||||
include_directories(vendor/cppbackport-master/lib)
|
||||
#include_directories(/usr/local/include)
|
||||
include_directories(${sodium_INCLUDE_DIR})
|
||||
|
||||
if (WIN32 AND NOT MINGW)
|
||||
include_directories(contrib/msc/include)
|
||||
link_directories(contrib/msc/lib)
|
||||
endif()
|
||||
|
||||
if(SHADOW)
|
||||
add_shadow_plugin(shadow-plugin-${SHARED_LIB} ${EXE_SRC} ${LIB_SRC})
|
||||
target_link_libraries(shadow-plugin-${SHARED_LIB} ${LIBS})
|
||||
|
@ -319,6 +362,8 @@ else()
|
|||
add_executable(${CLIENT_EXE} ${CLIENT_SRC})
|
||||
add_executable(dns ${DNS_SRC})
|
||||
|
||||
|
||||
|
||||
if(WITH_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(${GTEST_DIR})
|
||||
|
@ -330,62 +375,66 @@ else()
|
|||
|
||||
if(WITH_STATIC)
|
||||
add_library(${STATIC_LIB} STATIC ${LIB_SRC})
|
||||
if(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
if(NOT HAVE_CXX17_FILESYSTEM)
|
||||
add_library(backport-static STATIC ${CPP_BACKPORT_SRC})
|
||||
endif(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
endif(NOT HAVE_CXX17_FILESYSTEM)
|
||||
add_library(llarpplatform-static STATIC ${LIB_PLATFORM_SRC})
|
||||
target_link_libraries(llarpplatform-static ${THREAD_LIB})
|
||||
if(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
if(NOT HAVE_CXX17_FILESYSTEM)
|
||||
target_link_libraries(${STATIC_LIB} ${LIBS} backport-static llarpplatform-static)
|
||||
else()
|
||||
target_link_libraries(${STATIC_LIB} ${LIBS} llarpplatform-static)
|
||||
endif(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
endif(NOT HAVE_CXX17_FILESYSTEM)
|
||||
if(NOT WITH_SHARED)
|
||||
if(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
if(NOT HAVE_CXX17_FILESYSTEM)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static)
|
||||
if (MINGW)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 stdc++fs)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 stdc++fs)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 stdc++fs)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 stdc++fs iphlpapi)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 stdc++fs iphlpapi)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 stdc++fs iphlpapi)
|
||||
elseif(WIN32)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 iphlpapi)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 iphlpapi)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} backport-static llarpplatform-static ws2_32 iphlpapi)
|
||||
endif(MINGW)
|
||||
else()
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static)
|
||||
if (MINGW)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 stdc++fs)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 stdc++fs)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 stdc++fs)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 stdc++fs iphlpapi)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 stdc++fs iphlpapi)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 stdc++fs iphlpapi)
|
||||
elseif(WIN32)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32)
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 iphlpapi)
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 iphlpapi)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB} llarpplatform-static ws2_32 iphlpapi)
|
||||
endif(MINGW)
|
||||
endif(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
endif(NOT HAVE_CXX17_FILESYSTEM)
|
||||
if (MINGW)
|
||||
target_link_libraries(dns ${STATIC_LIB} llarpplatform-static ${THREAD_LIB} ws2_32 stdc++fs)
|
||||
target_link_libraries(dns ${STATIC_LIB} llarpplatform-static ${THREAD_LIB} ws2_32 stdc++fs iphlpapi)
|
||||
elseif(WIN32)
|
||||
target_link_libraries(dns ${STATIC_LIB} llarpplatform-static ${THREAD_LIB} ws2_32)
|
||||
target_link_libraries(dns ${STATIC_LIB} llarpplatform-static ${THREAD_LIB} ws2_32 iphlpapi)
|
||||
endif(MINGW)
|
||||
target_link_libraries(dns ${STATIC_LIB} llarpplatform-static ${THREAD_LIB})
|
||||
endif(NOT WITH_SHARED)
|
||||
endif(WITH_STATIC)
|
||||
if(ANDROID)
|
||||
add_library(lokinetandroid SHARED jni/lokinet_android.cpp)
|
||||
target_link_libraries(lokinetandroid ${STATIC_LIB} ${LIBS} log)
|
||||
endif()
|
||||
|
||||
if(WITH_SHARED)
|
||||
if(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
if(HAVE_CXX17_FILESYSTEM)
|
||||
set(LIB_SRC ${LIB_SRC} ${CPP_BACKPORT_SRC})
|
||||
endif(COMPILER_SUPPORTS_CXX11 AND NOT COMPILER_SUPPORTS_CXX17 OR ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD" OR NOT HAVE_STD_FS)
|
||||
endif(HAVE_CXX17_FILESYSTEM)
|
||||
add_library(${SHARED_LIB} SHARED ${LIB_SRC} ${LIB_PLATFORM_SRC})
|
||||
if (MINGW)
|
||||
set(${LIBS} ${LIBS} ws2_32 stdc++fs)
|
||||
set(${LIBS} ${LIBS} ws2_32 stdc++fs iphlpapi)
|
||||
elseif(WIN32)
|
||||
set(${LIBS} ${LIBS} ws2_32)
|
||||
set(${LIBS} ${LIBS} ws2_32 iphlpapi)
|
||||
endif(MINGW)
|
||||
target_link_libraries(${SHARED_LIB} ${LIBS} ${THREAD_LIB})
|
||||
target_link_libraries(${EXE} ${SHARED_LIB})
|
||||
|
|
8
Makefile
8
Makefile
|
@ -34,9 +34,10 @@ TESTNET_DEBUG ?= 0
|
|||
clean:
|
||||
rm -f build.ninja rules.ninja cmake_install.cmake CMakeCache.txt
|
||||
rm -rf CMakeFiles
|
||||
rm -f $(TARGETS) llarpd
|
||||
rm -f $(TARGETS) llarpd llarpc dns rcutil testAll
|
||||
rm -f $(SHADOW_PLUGIN) $(SHADOW_CONFIG)
|
||||
rm -f *.sig
|
||||
rm -f *.a *.so
|
||||
|
||||
debug-configure:
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DWITH_TESTS=ON -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX)
|
||||
|
@ -77,7 +78,10 @@ shadow-plot: shadow-run
|
|||
|
||||
shadow: shadow-plot
|
||||
|
||||
testnet-configure: clean
|
||||
testnet-clean: clean
|
||||
rm -rf $(TESTNET_ROOT)
|
||||
|
||||
testnet-configure: testnet-clean
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX)
|
||||
|
||||
testnet-build: testnet-configure
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,190 @@
|
|||
#ifdef _MSC_VER
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Not ELIDE_CODE. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
#endif /* _MSC_VER */
|
|
@ -0,0 +1,157 @@
|
|||
#ifdef _MSC_VER
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
|
||||
#ifndef __need_getopt
|
||||
# define _GETOPT_H 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
#ifndef __need_getopt
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
# if defined __STDC__ && __STDC__
|
||||
const char *name;
|
||||
# else
|
||||
char *name;
|
||||
# endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
# define no_argument 0
|
||||
# define required_argument 1
|
||||
# define optional_argument 2
|
||||
#endif /* need getopt */
|
||||
|
||||
|
||||
/* Get definitions and prototypes for functions to process the
|
||||
arguments in ARGV (ARGC of them, minus the program name) for
|
||||
options given in OPTS.
|
||||
|
||||
Return the option character from OPTS just read. Return -1 when
|
||||
there are no more options. For unrecognized options, or options
|
||||
missing arguments, `optopt' is set to the option letter, and '?' is
|
||||
returned.
|
||||
|
||||
The OPTS string is a list of characters which are recognized option
|
||||
letters, optionally followed by colons, specifying that that letter
|
||||
takes an argument, to be placed in `optarg'.
|
||||
|
||||
If a letter in OPTS is followed by two colons, its argument is
|
||||
optional. This behavior is specific to the GNU `getopt'.
|
||||
|
||||
The argument `--' causes premature termination of argument
|
||||
scanning, explicitly telling `getopt' that there are no more
|
||||
options.
|
||||
|
||||
If OPTS begins with `--', then non-option arguments are treated as
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`getopt'. */
|
||||
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
|
||||
|
||||
# ifndef __need_getopt
|
||||
extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
extern int getopt_long_only (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind,
|
||||
int __long_only);
|
||||
# endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure we later can get all the definitions and declarations. */
|
||||
#undef __need_getopt
|
||||
|
||||
#endif /* getopt.h */
|
||||
#endif /* _MSC_VER */
|
|
@ -37,7 +37,8 @@ def main():
|
|||
config = CP()
|
||||
config['router'] = {
|
||||
'net-threads': '1',
|
||||
'worker-threads': '4'
|
||||
'worker-threads': '4',
|
||||
'nickname': svcNodeName(nodeid)
|
||||
}
|
||||
config['bind'] = {
|
||||
args.ifname: str(args.baseport + nodeid)
|
||||
|
@ -64,7 +65,8 @@ def main():
|
|||
|
||||
config['router'] = {
|
||||
'net-threads': '1',
|
||||
'worker-threads': '2'
|
||||
'worker-threads': '2',
|
||||
'nickname': clientNodeName(nodeid)
|
||||
}
|
||||
config['netdb'] = {
|
||||
'dir': 'netdb'
|
||||
|
@ -90,28 +92,31 @@ def main():
|
|||
f.write('''[test-service]
|
||||
tag=test
|
||||
prefetch-tag=test
|
||||
prefetch-tag=nonexist
|
||||
''')
|
||||
|
||||
with open(args.out, 'w') as f:
|
||||
f.write('''[program:svc-node]
|
||||
directory = {}
|
||||
command = {}
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/fd/1
|
||||
#stdout_logfile=/dev/fd/1
|
||||
stdout_logfile={}/svc-node-%(process_num)03d-log.txt
|
||||
stdout_logfile_maxbytes=0
|
||||
process_name = svc-node-%(process_num)03d
|
||||
numprocs = {}
|
||||
'''.format(os.path.join(args.dir, 'svc-node-%(process_num)03d'), args.bin, args.svc))
|
||||
'''.format(os.path.join(args.dir, 'svc-node-%(process_num)03d'), args.bin, args.dir, args.svc))
|
||||
f.write('''[program:client-node]
|
||||
directory = {}
|
||||
command = {}
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/fd/1
|
||||
#stdout_logfile=/dev/fd/1
|
||||
stdout_logfile={}/client-node-%(process_num)03d-log.txt
|
||||
stdout_logfile_maxbytes=0
|
||||
process_name = client-node-%(process_num)03d
|
||||
numprocs = {}
|
||||
'''.format(os.path.join(args.dir, 'client-node-%(process_num)03d'), args.bin, args.clients))
|
||||
'''.format(os.path.join(args.dir, 'client-node-%(process_num)03d'),args.bin, args.dir, args.clients))
|
||||
f.write('[supervisord]\ndirectory=.\n')
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h> /* fprintf, printf */
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <llarp.h>
|
||||
#include <llarp/logic.h>
|
||||
|
@ -12,6 +14,17 @@
|
|||
|
||||
#include <thread> // for multithreaded version
|
||||
#include <vector>
|
||||
#include <algorithm> // for std::generate_n
|
||||
|
||||
// keep this once jeff reenables concurrency
|
||||
#ifdef _MSC_VER
|
||||
extern "C" void
|
||||
SetThreadName(DWORD dwThreadID, LPCSTR szThreadName);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define uint UINT
|
||||
#endif
|
||||
|
||||
#if(__FreeBSD__) || (__OpenBSD__) || (__NetBSD__)
|
||||
#include <pthread_np.h>
|
||||
|
@ -34,11 +47,11 @@ std::string const default_chars =
|
|||
|
||||
std::string random_string(size_t len = 15, std::string const &allowed_chars = default_chars) {
|
||||
std::mt19937_64 gen { std::random_device()() };
|
||||
|
||||
|
||||
std::uniform_int_distribution<size_t> dist { 0, allowed_chars.length()-1 };
|
||||
|
||||
|
||||
std::string ret;
|
||||
|
||||
|
||||
std::generate_n(std::back_inserter(ret), len, [&] { return allowed_chars[dist(gen)]; });
|
||||
return ret;
|
||||
}
|
||||
|
@ -46,14 +59,14 @@ std::string random_string(size_t len = 15, std::string const &allowed_chars = de
|
|||
/*
|
||||
/// check_online_request hook definition
|
||||
typedef void (*check_query_request_hook_func)(struct check_query_request *);
|
||||
|
||||
|
||||
struct check_query_request
|
||||
{
|
||||
bool done;
|
||||
///hook
|
||||
check_query_request_hook_func hook;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
llarp_dnsd_checkQuery_resolved(struct check_query_request *request)
|
||||
{
|
||||
|
@ -160,7 +173,7 @@ main(int argc, char *argv[])
|
|||
iter.visit = &dns_iter_config;
|
||||
llarp_config_iter(config_reader, &iter);
|
||||
llarp::LogInfo("config [", conffname, "] loaded");
|
||||
|
||||
|
||||
const uint16_t server_port = 1053;
|
||||
|
||||
// llarp::SetLogLevel(llarp::eLogDebug);
|
||||
|
@ -171,7 +184,7 @@ main(int argc, char *argv[])
|
|||
llarp_ev_loop *netloop = nullptr;
|
||||
llarp_threadpool *worker = nullptr;
|
||||
llarp_logic *logic = nullptr;
|
||||
|
||||
|
||||
llarp_ev_loop_alloc(&netloop); // set up netio worker
|
||||
worker = llarp_init_same_process_threadpool();
|
||||
logic = llarp_init_single_process_logic(worker); // set up logic worker
|
||||
|
@ -192,6 +205,7 @@ main(int argc, char *argv[])
|
|||
llarp::LogInfo("singlethread start");
|
||||
llarp_ev_loop_run_single_process(netloop, worker, logic);
|
||||
llarp::LogInfo("singlethread end");
|
||||
|
||||
llarp_ev_loop_free(&netloop);
|
||||
}
|
||||
else
|
||||
|
@ -201,7 +215,7 @@ main(int argc, char *argv[])
|
|||
llarp_logic *logic = nullptr;
|
||||
worker = llarp_init_same_process_threadpool();
|
||||
logic = llarp_init_single_process_logic(worker); // set up logic worker
|
||||
|
||||
|
||||
// configure main netloop
|
||||
struct dnsd_context dnsd;
|
||||
if(!llarp_dnsd_init(&dnsd, nullptr, logic, "*", server_port,
|
||||
|
@ -214,7 +228,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
// Configure intercept
|
||||
dnsd.intercept = &hookChecker;
|
||||
|
||||
|
||||
struct sockaddr_in m_address;
|
||||
int m_sockfd;
|
||||
|
||||
|
@ -239,7 +253,11 @@ main(int argc, char *argv[])
|
|||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100 * 1000; // 1 sec
|
||||
#ifndef _WIN32
|
||||
if(setsockopt(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
|
||||
#else
|
||||
if(setsockopt(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)) < 0)
|
||||
#endif
|
||||
{
|
||||
perror("Error");
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
#include <signal.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define wmin(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define MIN wmin
|
||||
#endif
|
||||
|
||||
struct llarp_main *ctx = 0;
|
||||
|
||||
void
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <getopt.h>
|
||||
#include <llarp.h>
|
||||
#include <signal.h>
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/time.h>
|
||||
|
||||
|
@ -278,14 +278,18 @@ main(int argc, char *argv[])
|
|||
// "encryption.key")
|
||||
fs::path encryption_keyfile = "encryption.key";
|
||||
llarp::SecretKey encryption;
|
||||
llarp_findOrCreateEncryption(&crypt, encryption_keyfile.c_str(),
|
||||
|
||||
llarp_findOrCreateEncryption(&crypt, encryption_keyfile.string().c_str(),
|
||||
&encryption);
|
||||
|
||||
llarp_rc_set_pubenckey(&tmp, llarp::seckey_topublic(encryption));
|
||||
|
||||
// get identity public sig key
|
||||
fs::path ident_keyfile = "identity.key";
|
||||
byte_t identity[SECKEYSIZE];
|
||||
llarp_findOrCreateIdentity(&crypt, ident_keyfile.c_str(), identity);
|
||||
llarp_findOrCreateIdentity(&crypt, ident_keyfile.string().c_str(),
|
||||
identity);
|
||||
|
||||
llarp_rc_set_pubsigkey(&tmp, llarp::seckey_topublic(identity));
|
||||
|
||||
// this causes a segfault
|
||||
|
@ -293,7 +297,8 @@ main(int argc, char *argv[])
|
|||
// set filename
|
||||
fs::path our_rc_file = rcfname;
|
||||
// write file
|
||||
llarp_rc_write(&tmp, our_rc_file.c_str());
|
||||
llarp_rc_write(&tmp, our_rc_file.string().c_str());
|
||||
|
||||
// release memory for tmp lists
|
||||
llarp_rc_free(&tmp);
|
||||
}
|
||||
|
@ -311,7 +316,8 @@ main(int argc, char *argv[])
|
|||
llarp_crypto_libsodium_init(&crypt);
|
||||
fs::path ident_keyfile = "identity.key";
|
||||
byte_t identity[SECKEYSIZE];
|
||||
llarp_findOrCreateIdentity(&crypt, ident_keyfile.c_str(), identity);
|
||||
llarp_findOrCreateIdentity(&crypt, ident_keyfile.string().c_str(),
|
||||
identity);
|
||||
// get identity public key
|
||||
uint8_t *pubkey = llarp::seckey_topublic(identity);
|
||||
llarp_rc_set_pubsigkey(&rc, pubkey);
|
||||
|
@ -320,7 +326,7 @@ main(int argc, char *argv[])
|
|||
// set filename
|
||||
fs::path our_rc_file_out = "update_debug.rc";
|
||||
// write file
|
||||
llarp_rc_write(&tmp, our_rc_file_out.c_str());
|
||||
llarp_rc_write(&tmp, our_rc_file_out.string().c_str());
|
||||
}
|
||||
if(listMode)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
## Building on Linux
|
||||
|
||||
# or your OS or distro's package manager
|
||||
$ sudo apt install build-essential libtool autoconf cmake git
|
||||
$ git clone --recursive https://github.com/loki-project/lokinet-builder
|
||||
$ cd lokinet-builder
|
||||
$ make
|
||||
|
||||
## Building on Windows (mingw-w64 native, or wow64/linux/unix cross-compiler)
|
||||
|
||||
#i686 or x86_64
|
||||
#if cross-compiling from anywhere other than wow64, export CC and CXX to
|
||||
#$ARCH-w64-mingw32-g[cc++] respectively
|
||||
$ pacman -Sy base-devel mingw-w64-$ARCH-toolchain git libtool autoconf cmake
|
||||
$ git clone --recursive https://github.com/loki-project/lokinet-builder
|
||||
$ cd lokinet-builder
|
||||
$ make ensure sodium
|
||||
$ cd build
|
||||
$ cmake ../deps/llarp -DSODIUM_LIBRARIES=./prefix/lib/libsodium.a -DSODIUM_INCLUDE_DIR=./prefix/include -G "Unix Makefiles" -DHAVE_CXX17_FILESYSTEM=ON
|
||||
$ make
|
||||
$ cp llarpd ../lokinet.exe
|
||||
|
||||
## Building on Windows using Microsoft C/C++ (Visual Studio 2017)
|
||||
|
||||
* clone https://github.com/loki-project/lokinet-builder from git-bash or whatever git browser you use
|
||||
* open `%CLONE_PATH%/lokinet-builder/deps/sodium/builds/msvc/vs2017/libsodium.sln` and build one of the targets
|
||||
* create a `build` folder in `%CLONE_PATH%/lokinet-builder`
|
||||
* run cmake-gui from `%CLONE_PATH%/lokinet-builder/deps/llarp` as the source directory
|
||||
* define `SODIUM_LIB` to `%CLONE_PATH%/lokinet-builder/deps/sodium/bin/win32/%CONFIG%/%TOOLSET%/%TARGET%/libsodium.lib`
|
||||
* define `SODIUM_INCLUDE_DIR` to `%CLONE_PATH%/lokinet-builder/deps/sodium/src/libsodium/include`
|
||||
* define `HAVE_CXX17_FILESYSTEM` to `TRUE`
|
||||
* select `Visual Studio 2017 15 %ARCH%` as the generator
|
||||
* enter a custom toolset if desired (usually `v141_xp`)
|
||||
* generate the developer studio project files and open in the IDE
|
||||
* select a configuration
|
||||
* press F7 to build everything
|
||||
|
||||
## Running
|
||||
|
||||
$ ./lokinet
|
||||
|
||||
or press `Debug`/`Local Windows Debugger` in the visual studio standard toolbar
|
||||
|
||||
### Development
|
||||
|
||||
Please note development builds are likely to be unstable.
|
||||
|
||||
##### Build requirements:
|
||||
|
||||
* CMake
|
||||
* ninja (for unit testing with Google Tests)
|
||||
* libsodium >= 1.0.14 (included here)
|
||||
* c++ 11 capable C++ compiler
|
||||
* if you have C++17 `<filesystem>` or `<experimental/filesystem>` declared and defined in your platform's C++ toolchain, re-run CMake (in `lokinet-builder/build`) with `-DHAVE_CXX17_FILESYSTEM=ON`.
|
||||
* since each platform seems to have its own idea of where `std::[experimental::]filesystem` is defined, you will need to manually specify its library in `LDFLAGS` or `CMAKE_x_LINKER_FLAGS` as well.
|
||||
|
||||
##### Windows:
|
||||
|
||||
* Mingw-w64 is recommended for 32 or 64-bit builds.
|
||||
* It *is* possible to compile with Microsoft C++ (v19 or later from VS2015+).
|
||||
* `cpp17::filesystem` in `vendor/cppbackport-master` is not available for Windows.
|
||||
|
||||
#### Boxed warning
|
||||
<div style="border:5px solid #f00;padding:5px">
|
||||
<p>Inbound sessions are unsupported on Windows Server systems.</p>
|
||||
<p><strong><em>Ignore this warning at your own peril.</em></strong></p>
|
||||
</div>
|
||||
|
||||
##### Building a debug build:
|
||||
|
||||
#in lokinet-builder/
|
||||
$ cd build
|
||||
$ make
|
|
@ -121,6 +121,7 @@ router's full identity
|
|||
{
|
||||
a: [ one, or, many, AI, here ... ],
|
||||
k: "<32 bytes public long term identity signing key>",
|
||||
n: "<optional max 32 bytes router nickname>",
|
||||
p: "<32 bytes public path encryption key>",
|
||||
u: last_updated_seconds_since_epoch_uint64,
|
||||
v: 0,
|
||||
|
|
Binary file not shown.
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <llarp.h>
|
||||
#include <iostream>
|
||||
#include <llarp/threading.hpp>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
|
|
|
@ -87,4 +87,20 @@ llarp_buffer_read_until(llarp_buffer_t *buff, char delim, byte_t *result,
|
|||
bool
|
||||
llarp_buffer_eq(llarp_buffer_t buff, const char *data);
|
||||
|
||||
/// put big endian unsigned 16 bit integer
|
||||
bool
|
||||
llarp_buffer_put_uint16(llarp_buffer_t *buf, uint16_t i);
|
||||
|
||||
/// put big endian unsigned 32 bit integer
|
||||
bool
|
||||
llarp_buffer_put_uint32(llarp_buffer_t *buf, uint32_t i);
|
||||
|
||||
/// read big endian unsigned 16 bit integer
|
||||
bool
|
||||
llarp_buffer_read_uint16(llarp_buffer_t *buf, uint16_t *i);
|
||||
|
||||
/// read big endian unsigned 32 bit integer
|
||||
bool
|
||||
llarp_buffer_read_uint32(llarp_buffer_t *buf, uint32_t *i);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#ifndef LLARP_CODEL_QUEUE_HPP
|
||||
#define LLARP_CODEL_QUEUE_HPP
|
||||
#ifdef _MSC_VER
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <llarp/time.h>
|
||||
#include <llarp/logger.hpp>
|
||||
#include <llarp/threading.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <llarp/dht/key.hpp>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -17,6 +18,22 @@ namespace llarp
|
|||
|
||||
Bucket(const Key_t& us) : nodes(XorMetric(us)){};
|
||||
|
||||
bool
|
||||
GetRandomNodeExcluding(Key_t& result,
|
||||
const std::set< Key_t >& exclude) const
|
||||
{
|
||||
std::vector< Key_t > candidates;
|
||||
for(const auto& item : nodes)
|
||||
{
|
||||
if(exclude.find(item.first) == exclude.end())
|
||||
candidates.push_back(item.first);
|
||||
}
|
||||
if(candidates.size() == 0)
|
||||
return false;
|
||||
result = candidates[llarp_randint() % candidates.size()];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FindClosest(const Key_t& target, Key_t& result) const
|
||||
{
|
||||
|
|
|
@ -48,7 +48,8 @@ namespace llarp
|
|||
void
|
||||
LookupTag(const service::Tag& tag, const Key_t& whoasked,
|
||||
uint64_t whoaskedTX, const Key_t& askpeer,
|
||||
bool iterative = false);
|
||||
const std::set< service::IntroSet >& include = {},
|
||||
uint64_t R = 0);
|
||||
|
||||
void
|
||||
LookupRouterViaJob(llarp_router_lookup_job* job);
|
||||
|
@ -57,6 +58,15 @@ namespace llarp
|
|||
LookupTagForPath(const service::Tag& tag, uint64_t txid,
|
||||
const llarp::PathID_t& path, const Key_t& askpeer);
|
||||
|
||||
void
|
||||
LookupIntroSetForPath(const service::Address& addr, uint64_t txid,
|
||||
const llarp::PathID_t& path, const Key_t& askpeer);
|
||||
|
||||
void
|
||||
LookupIntroSetRelayed(const Key_t& requester, uint64_t txid,
|
||||
const service::Address& addr, bool recursive,
|
||||
std::vector< IMessage* >& reply);
|
||||
|
||||
std::set< service::IntroSet >
|
||||
FindRandomIntroSetsWithTag(const service::Tag& tag, size_t max = 2);
|
||||
|
||||
|
@ -72,7 +82,7 @@ namespace llarp
|
|||
void
|
||||
PropagateIntroSetTo(const Key_t& from, uint64_t fromTX,
|
||||
const service::IntroSet& introset, const Key_t& peer,
|
||||
uint64_t S);
|
||||
uint64_t S, const std::set< Key_t >& exclude);
|
||||
|
||||
void
|
||||
Init(const Key_t& us, llarp_router* router);
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
#include <llarp/ev.h> // for sockaadr
|
||||
#include <sys/types.h> // for uint & ssize_t
|
||||
|
||||
/* non-cygnus does not have this type */
|
||||
#ifdef _WIN32
|
||||
#define uint UINT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -6,15 +6,12 @@
|
|||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/endian.h>
|
||||
#elif defined(__linux__) || defined(__FreeBSD_kernel__) \
|
||||
|| defined(__OpenBSD__) || defined(__GLIBC__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__GLIBC__)
|
||||
#include <endian.h>
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
|
||||
#include <libkern/OSByteOrder.h>
|
||||
|
||||
#define htobe16(x) OSSwapHostToBigInt16(x)
|
||||
#define htole16(x) OSSwapHostToLittleInt16(x)
|
||||
#define be16toh(x) OSSwapBigToHostInt16(x)
|
||||
|
@ -29,7 +26,26 @@
|
|||
#define htole64(x) OSSwapHostToLittleInt64(x)
|
||||
#define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||
#elif defined(_WIN32)
|
||||
#include <winsock2.h>
|
||||
#define htobe16(x) htons(x)
|
||||
#define htole16(x) (x)
|
||||
#define be16toh(x) ntohs(x)
|
||||
#define le16toh(x) (x)
|
||||
|
||||
#define htobe32(x) htonl(x)
|
||||
#define htole32(x) (x)
|
||||
#define be32toh(x) ntohl(x)
|
||||
#define le32toh(x) (x)
|
||||
|
||||
#define htobe64(x) \
|
||||
(((uint64_t)htonl(((uint32_t)(((uint64_t)(x)) >> 32)))) \
|
||||
| (((uint64_t)htonl(((uint32_t)(x)))) << 32))
|
||||
#define htole64(x) (x)
|
||||
#define be64toh(x) \
|
||||
(((uint64_t)ntohl(((uint32_t)(((uint64_t)(x)) >> 32)))) \
|
||||
| (((uint64_t)ntohl(((uint32_t)(x)))) << 32))
|
||||
#define le64toh(x) (x)
|
||||
#else
|
||||
#define NEEDS_LOCAL_ENDIAN
|
||||
#include <cstdint>
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#ifndef LLARP_EV_H
|
||||
#define LLARP_EV_H
|
||||
#if defined(__MINGW32__)
|
||||
#if defined(__MINGW32__) || defined(_WIN32)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#ifndef ssize_t
|
||||
#define ssize_t long
|
||||
#endif
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -12,10 +16,10 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* ev.h
|
||||
*
|
||||
* event handler (cross platform high performance event system for IO)
|
||||
*/
|
||||
* ev.h
|
||||
*
|
||||
* event handler (cross platform high performance event system for IO)
|
||||
*/
|
||||
|
||||
// forward declare
|
||||
struct llarp_threadpool;
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
#ifndef LLARP_LOGGER_H
|
||||
#define LLARP_LOGGER_H
|
||||
|
||||
enum LogLevel
|
||||
extern "C"
|
||||
{
|
||||
eLogDebug,
|
||||
eLogInfo,
|
||||
eLogWarn,
|
||||
eLogError
|
||||
};
|
||||
enum LogLevel
|
||||
{
|
||||
eLogDebug,
|
||||
eLogInfo,
|
||||
eLogWarn,
|
||||
eLogError
|
||||
};
|
||||
|
||||
void
|
||||
cSetLogLevel(enum LogLevel lvl);
|
||||
void
|
||||
cSetLogLevel(enum LogLevel lvl);
|
||||
|
||||
void
|
||||
cSetLogNodeName(const char* name);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#ifndef LLARP_LOGGER_HPP
|
||||
#define LLARP_LOGGER_HPP
|
||||
|
||||
#include <llarp/time.h>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
|
@ -8,6 +7,13 @@
|
|||
#include <llarp/threading.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#ifdef _WIN32
|
||||
#define VC_EXTRALEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -22,13 +28,23 @@ namespace llarp
|
|||
|
||||
struct Logger
|
||||
{
|
||||
std::string nodeName;
|
||||
LogLevel minlevel = eLogInfo;
|
||||
std::ostream& out;
|
||||
std::mutex access;
|
||||
Logger() : Logger(std::cout)
|
||||
Logger() : Logger(std::cout, "unnamed")
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD mode_flags;
|
||||
HANDLE fd1 = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
GetConsoleMode(fd1, &mode_flags);
|
||||
// since release SDKs don't have ANSI escape support yet
|
||||
mode_flags |= 0x0004;
|
||||
SetConsoleMode(fd1, mode_flags);
|
||||
#endif
|
||||
}
|
||||
Logger(std::ostream& o) : out(o)
|
||||
|
||||
Logger(std::ostream& o, const std::string& name) : nodeName(name), out(o)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -57,12 +73,29 @@ namespace llarp
|
|||
/** internal */
|
||||
template < typename... TArgs >
|
||||
void
|
||||
_Log(LogLevel lvl, const char* fname, TArgs&&... args) noexcept
|
||||
_Log(LogLevel lvl, const char* fname, int lineno, TArgs&&... args) noexcept
|
||||
{
|
||||
if(_glog.minlevel > lvl)
|
||||
return;
|
||||
|
||||
std::stringstream ss;
|
||||
#ifdef ANDROID
|
||||
switch(lvl)
|
||||
{
|
||||
case eLogDebug:
|
||||
ss << "[DBG] ";
|
||||
break;
|
||||
case eLogInfo:
|
||||
ss << "[NFO] ";
|
||||
break;
|
||||
case eLogWarn:
|
||||
ss << "[WRN] ";
|
||||
break;
|
||||
case eLogError:
|
||||
ss << "[ERR] ";
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch(lvl)
|
||||
{
|
||||
case eLogDebug:
|
||||
|
@ -82,34 +115,45 @@ namespace llarp
|
|||
ss << "[ERR] ";
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
std::string tag = fname;
|
||||
ss << llarp_time_now_ms() << " " << tag;
|
||||
ss << _glog.nodeName << " " << llarp_time_now_ms() << " " << tag << ":"
|
||||
<< lineno;
|
||||
ss << "\t";
|
||||
LogAppend(ss, std::forward< TArgs >(args)...);
|
||||
#ifndef ANDROID
|
||||
ss << (char)27 << "[0;0m";
|
||||
#else
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(_glog.access);
|
||||
_glog.out << ss.str() << std::endl;
|
||||
#ifdef SHADOW_TESTNET
|
||||
__android_log_write(ANDROID_LOG_INFO, "LOKINET", ss.str().c_str());
|
||||
_glog.out << "\n" << std::flush;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
|
||||
|
||||
#define LogDebug(x, ...) \
|
||||
_Log(llarp::eLogDebug, LOG_TAG, __LINE__, x, ##__VA_ARGS__)
|
||||
#define LogInfo(x, ...) \
|
||||
_Log(llarp::eLogInfo, LOG_TAG, __LINE__, x, ##__VA_ARGS__)
|
||||
#define LogWarn(x, ...) \
|
||||
_Log(llarp::eLogWarn, LOG_TAG, __LINE__, x, ##__VA_ARGS__)
|
||||
#define LogError(x, ...) \
|
||||
_Log(llarp::eLogError, LOG_TAG, __LINE__, x, ##__VA_ARGS__)
|
||||
#define LogDebugTag(tag, x, ...) \
|
||||
_Log(llarp::eLogDebug, tag, __LINE__, x, ##__VA_ARGS__)
|
||||
#define LogInfoTag(tag, x, ...) \
|
||||
_Log(llarp::eLogInfo, tag, __LINE__, x, ##__VA_ARGS__)
|
||||
#define LogWarnTag(tag, x, ...) \
|
||||
_Log(llarp::eLogWarn, tag, __LINE__, x, ##__VA_ARGS__)
|
||||
#define LogErrorTag(tag, x, ...) \
|
||||
_Log(llarp::eLogError, tag, __LINE__, x, ##__VA_ARGS__)
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG "default"
|
||||
#endif
|
||||
|
||||
#define LogDebug(x, ...) _Log(llarp::eLogDebug, LOG_TAG, x, ##__VA_ARGS__)
|
||||
#define LogInfo(x, ...) _Log(llarp::eLogInfo, LOG_TAG, x, ##__VA_ARGS__)
|
||||
#define LogWarn(x, ...) _Log(llarp::eLogWarn, LOG_TAG, x, ##__VA_ARGS__)
|
||||
#define LogError(x, ...) _Log(llarp::eLogError, LOG_TAG, x, ##__VA_ARGS__)
|
||||
|
||||
#define LogDebugTag(tag, x, ...) _Log(llarp::eLogDebug, tag, x, ##__VA_ARGS__)
|
||||
#define LogInfoTag(tag, x, ...) _Log(llarp::eLogInfo, tag, x, ##__VA_ARGS__)
|
||||
#define LogWarnTag(tag, x, ...) _Log(llarp::eLogWarn, tag, x, ##__VA_ARGS__)
|
||||
#define LogErrorTag(tag, x, ...) _Log(llarp::eLogError, tag, x, ##__VA_ARGS__)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,27 @@
|
|||
#ifndef LLARP_NET_H
|
||||
#define LLARP_NET_H
|
||||
#if defined(__MINGW32__)
|
||||
#if defined(_WIN32) || defined(__MINGW32__)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
// because this shit is not defined for Windows NT reeeee
|
||||
#ifndef _MSC_VER
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
const char*
|
||||
inet_ntop(int af, const void* src, char* dst, size_t size);
|
||||
int
|
||||
inet_pton(int af, const char* src, void* dst);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef ssize_t
|
||||
#define ssize_t long
|
||||
#endif
|
||||
typedef unsigned short in_port_t;
|
||||
typedef unsigned int in_addr_t;
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
|
|
@ -121,7 +121,11 @@ namespace llarp
|
|||
sz = sizeof(sockaddr_in);
|
||||
ptr = a.addr4();
|
||||
}
|
||||
#ifndef _MSC_VER
|
||||
if(inet_ntop(a.af(), ptr, tmp, sz))
|
||||
#else
|
||||
if(inet_ntop(a.af(), (void*)ptr, tmp, sz))
|
||||
#endif
|
||||
{
|
||||
out << tmp;
|
||||
if(a.af() == AF_INET6)
|
||||
|
@ -236,7 +240,7 @@ namespace llarp
|
|||
{
|
||||
if(a.af() == AF_INET)
|
||||
{
|
||||
return a.port() + a.addr4()->s_addr;
|
||||
return a.port() ^ a.addr4()->s_addr;
|
||||
}
|
||||
uint8_t empty[16] = {0};
|
||||
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
|
||||
|
|
|
@ -163,6 +163,14 @@ namespace llarp
|
|||
HandlePathLatencyMessage(const llarp::routing::PathLatencyMessage* msg,
|
||||
llarp_router* r);
|
||||
|
||||
bool
|
||||
HandleHiddenServiceFrame(const llarp::service::ProtocolFrame* frame)
|
||||
{
|
||||
/// TODO: implement me
|
||||
llarp::LogWarn("Got hidden service data on transit hop");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg);
|
||||
|
||||
|
@ -207,6 +215,9 @@ namespace llarp
|
|||
{
|
||||
typedef std::function< void(Path*) > BuildResultHookFunc;
|
||||
typedef std::vector< PathHopConfig > HopList;
|
||||
typedef std::function< bool(const service::ProtocolFrame*) >
|
||||
DataHandlerFunc;
|
||||
|
||||
HopList hops;
|
||||
|
||||
llarp::service::Introduction intro;
|
||||
|
@ -219,6 +230,12 @@ namespace llarp
|
|||
void
|
||||
SetBuildResultHook(BuildResultHookFunc func);
|
||||
|
||||
void
|
||||
SetDataHandler(DataHandlerFunc func)
|
||||
{
|
||||
m_DataHandler = func;
|
||||
}
|
||||
|
||||
bool
|
||||
Expired(llarp_time_t now) const;
|
||||
|
||||
|
@ -240,6 +257,9 @@ namespace llarp
|
|||
HandlePathTransferMessage(const llarp::routing::PathTransferMessage* msg,
|
||||
llarp_router* r);
|
||||
|
||||
bool
|
||||
HandleHiddenServiceFrame(const llarp::service::ProtocolFrame* frame);
|
||||
|
||||
bool
|
||||
HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg);
|
||||
|
||||
|
@ -279,6 +299,7 @@ namespace llarp
|
|||
|
||||
private:
|
||||
BuildResultHookFunc m_BuiltHook;
|
||||
DataHandlerFunc m_DataHandler;
|
||||
llarp_time_t m_LastLatencyTestTime = 0;
|
||||
uint64_t m_LastLatencyTestID = 0;
|
||||
};
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#define LLARP_PATHBUILDER_HPP_
|
||||
#include <llarp/pathbuilder.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/path.hpp>
|
||||
#include <llarp/pathset.hpp>
|
||||
|
||||
struct llarp_pathbuilder_context : public llarp::path::PathSet
|
||||
{
|
||||
struct llarp_router* router;
|
||||
struct llarp_dht_context* dht;
|
||||
llarp::SecretKey enckey;
|
||||
size_t numHops;
|
||||
/// construct
|
||||
llarp_pathbuilder_context(llarp_router* p_router,
|
||||
|
@ -21,6 +23,9 @@ struct llarp_pathbuilder_context : public llarp::path::PathSet
|
|||
|
||||
void
|
||||
BuildOne();
|
||||
|
||||
virtual byte_t*
|
||||
GetTunnelEncryptionSecretKey();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,14 +44,14 @@ namespace llarp
|
|||
void
|
||||
RemovePath(Path* path);
|
||||
|
||||
void
|
||||
virtual void
|
||||
HandlePathBuilt(Path* path);
|
||||
|
||||
void
|
||||
AddPath(Path* path);
|
||||
|
||||
Path*
|
||||
GetByUpstream(const RouterID& remote, const PathID_t& rxid);
|
||||
GetByUpstream(const RouterID& remote, const PathID_t& rxid) const;
|
||||
|
||||
void
|
||||
ExpirePaths(llarp_time_t now);
|
||||
|
@ -79,10 +79,13 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PickRandomEstablishedPath();
|
||||
GetEstablishedPathClosestTo(const RouterID& router) const;
|
||||
|
||||
Path*
|
||||
GetPathByRouter(const RouterID& router);
|
||||
PickRandomEstablishedPath() const;
|
||||
|
||||
Path*
|
||||
GetPathByRouter(const RouterID& router) const;
|
||||
|
||||
bool
|
||||
GetCurrentIntroductions(
|
||||
|
|
|
@ -4,11 +4,16 @@
|
|||
#include <llarp/crypto.h>
|
||||
#include <llarp/exit_info.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
// forward declare
|
||||
struct llarp_alloc;
|
||||
struct llarp_rc;
|
||||
|
||||
#define MAX_RC_SIZE (1024)
|
||||
#define NICKLEN (32)
|
||||
|
||||
bool
|
||||
llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buf);
|
||||
|
@ -24,6 +29,9 @@ struct llarp_rc
|
|||
byte_t pubkey[PUBKEYSIZE];
|
||||
struct llarp_xi_list *exits;
|
||||
byte_t signature[SIGSIZE];
|
||||
/// node nickname, yw kee
|
||||
byte_t nickname[NICKLEN];
|
||||
|
||||
uint64_t last_updated;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -38,6 +46,14 @@ struct llarp_rc
|
|||
{
|
||||
return llarp_rc_bdecode(this, buf);
|
||||
}
|
||||
|
||||
std::string
|
||||
Nick() const
|
||||
{
|
||||
const char *nick = (const char *)nickname;
|
||||
return std::string(nick, strnlen(nick, sizeof(nickname)));
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -60,6 +76,9 @@ void
|
|||
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
|
||||
struct llarp_ai_list *addr);
|
||||
|
||||
bool
|
||||
llarp_rc_set_nickname(struct llarp_rc *rc, const char *name);
|
||||
|
||||
void
|
||||
llarp_rc_set_pubenckey(struct llarp_rc *rc, const uint8_t *pubenckey);
|
||||
|
||||
|
|
|
@ -21,10 +21,7 @@ namespace llarp
|
|||
llarp_router *r) = 0;
|
||||
|
||||
virtual bool
|
||||
HandleHiddenServiceFrame(const service::ProtocolFrame *msg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
HandleHiddenServiceFrame(const service::ProtocolFrame *msg) = 0;
|
||||
|
||||
virtual bool
|
||||
HandlePathConfirmMessage(const PathConfirmMessage *msg,
|
||||
|
|
|
@ -13,6 +13,9 @@ namespace llarp
|
|||
std::string
|
||||
ToString() const;
|
||||
|
||||
bool
|
||||
FromString(const std::string& str);
|
||||
|
||||
Address() : llarp::AlignedBuffer< 32 >()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace llarp
|
|||
{
|
||||
namespace service
|
||||
{
|
||||
struct Endpoint : public llarp_pathbuilder_context
|
||||
struct Endpoint : public llarp_pathbuilder_context, public ILookupHolder
|
||||
{
|
||||
/// minimum interval for publishing introsets
|
||||
static const llarp_time_t INTROSET_PUBLISH_INTERVAL =
|
||||
|
@ -74,6 +74,12 @@ namespace llarp
|
|||
return &m_Identity;
|
||||
}
|
||||
|
||||
void
|
||||
PutLookup(IServiceLookup* lookup, uint64_t txid);
|
||||
|
||||
void
|
||||
HandlePathBuilt(path::Path* path);
|
||||
|
||||
/// context needed to initiate an outbound hidden service session
|
||||
struct OutboundContext : public llarp_pathbuilder_context
|
||||
{
|
||||
|
@ -102,12 +108,24 @@ namespace llarp
|
|||
void
|
||||
UpdateIntroSet();
|
||||
|
||||
void
|
||||
HandlePathBuilt(path::Path* path);
|
||||
|
||||
bool
|
||||
SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur, size_t hop);
|
||||
|
||||
bool
|
||||
HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg);
|
||||
|
||||
bool
|
||||
HandleHiddenServiceFrame(const ProtocolFrame* frame);
|
||||
|
||||
void
|
||||
PutLookup(IServiceLookup* lookup, uint64_t txid);
|
||||
|
||||
std::string
|
||||
Name() const;
|
||||
|
||||
private:
|
||||
void
|
||||
AsyncEncrypt(llarp_buffer_t payload);
|
||||
|
@ -122,6 +140,7 @@ namespace llarp
|
|||
uint64_t sequenceNo = 0;
|
||||
llarp::SharedSecret sharedKey;
|
||||
Endpoint* m_Parent;
|
||||
uint64_t m_UpdateIntrosetTX = 0;
|
||||
};
|
||||
|
||||
// passed a sendto context when we have a path established otherwise
|
||||
|
@ -176,6 +195,8 @@ namespace llarp
|
|||
service::IntroSet m_IntroSet;
|
||||
/// pending remote service lookups by id
|
||||
std::unordered_map< uint64_t, service::IServiceLookup* > m_PendingLookups;
|
||||
/// prefetch remote address list
|
||||
std::set< Address > m_PrefetchAddrs;
|
||||
/// hidden service tag
|
||||
Tag m_Tag;
|
||||
/// prefetch descriptors for these hidden service tags
|
||||
|
@ -185,13 +206,12 @@ namespace llarp
|
|||
{
|
||||
const static llarp_time_t TTL = 10000;
|
||||
llarp_time_t lastRequest = 0;
|
||||
llarp_time_t lastModified;
|
||||
uint64_t pendingTX = 0;
|
||||
llarp_time_t lastModified = 0;
|
||||
std::set< IntroSet > result;
|
||||
Tag tag;
|
||||
|
||||
CachedTagResult(const Tag& t, llarp_time_t now)
|
||||
: lastModified(now), tag(t)
|
||||
CachedTagResult(Endpoint* p, const Tag& t, uint64_t tx)
|
||||
: IServiceLookup(p, tx), tag(t)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -205,7 +225,7 @@ namespace llarp
|
|||
{
|
||||
if(now <= lastRequest)
|
||||
return false;
|
||||
return (now - lastRequest) > TTL && pendingTX == 0;
|
||||
return (now - lastRequest) > TTL;
|
||||
}
|
||||
|
||||
llarp::routing::IMessage*
|
||||
|
|
|
@ -16,11 +16,11 @@ namespace llarp
|
|||
|
||||
namespace service
|
||||
{
|
||||
struct ILookupHolder;
|
||||
|
||||
struct IServiceLookup
|
||||
{
|
||||
IServiceLookup() : m_created(llarp_time_now_ms())
|
||||
{
|
||||
}
|
||||
IServiceLookup(ILookupHolder* parent, uint64_t tx);
|
||||
|
||||
virtual ~IServiceLookup(){};
|
||||
|
||||
|
@ -45,10 +45,19 @@ namespace llarp
|
|||
bool
|
||||
SendRequestViaPath(llarp::path::Path* p, llarp_router* r);
|
||||
|
||||
private:
|
||||
ILookupHolder* parent;
|
||||
uint64_t txid;
|
||||
|
||||
protected:
|
||||
llarp_time_t m_created;
|
||||
};
|
||||
|
||||
struct ILookupHolder
|
||||
{
|
||||
virtual void
|
||||
PutLookup(IServiceLookup* l, uint64_t txid) = 0;
|
||||
};
|
||||
|
||||
} // namespace service
|
||||
} // namespace llarp
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ namespace llarp
|
|||
struct ProtocolFrame : public llarp::routing::IMessage
|
||||
{
|
||||
llarp::Encrypted D;
|
||||
uint64_t S = 0;
|
||||
llarp::PubKey H;
|
||||
llarp::KeyExchangeNonce N;
|
||||
llarp::Signature Z;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef LLARP_THREADING_HPP
|
||||
#define LLARP_THREADING_HPP
|
||||
#include <mutex>
|
||||
#if defined(__MINGW32__)
|
||||
#if defined(__MINGW32__) && !defined(_GLIBCXX_HAS_GTHREADS)
|
||||
#include <llarp/win32/threads/mingw.condition_variable.h>
|
||||
#include <llarp/win32/threads/mingw.mutex.h>
|
||||
#include <llarp/win32/threads/mingw.thread.h>
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
|
||||
//#include <string.h>
|
||||
#include <jni.h>
|
||||
#include <llarp.h>
|
||||
#include <signal.h>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
struct AndroidMain
|
||||
{
|
||||
llarp_main* m_impl = nullptr;
|
||||
std::thread* m_thread = nullptr;
|
||||
|
||||
bool
|
||||
Start(const char* conf)
|
||||
{
|
||||
if(m_impl || m_thread)
|
||||
return true;
|
||||
if(!llarp_ensure_config(conf))
|
||||
return false;
|
||||
m_impl = llarp_main_init(conf, true);
|
||||
if(m_impl == nullptr)
|
||||
return false;
|
||||
m_thread = new std::thread(std::bind(&AndroidMain::Run, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Running() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Run()
|
||||
{
|
||||
printf("running\n");
|
||||
llarp_main_run(m_impl);
|
||||
}
|
||||
|
||||
void
|
||||
Stop()
|
||||
{
|
||||
llarp_main_signal(m_impl, SIGINT);
|
||||
m_thread->join();
|
||||
delete m_thread;
|
||||
m_thread = nullptr;
|
||||
llarp_main_free(m_impl);
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
typedef std::unique_ptr< AndroidMain > Ptr;
|
||||
};
|
||||
|
||||
static AndroidMain::Ptr daemon(new AndroidMain());
|
||||
|
||||
extern "C"
|
||||
{
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_network_loki_lokinet_Lokinet_1JNI_getABICompiledWith(JNIEnv* env, jclass)
|
||||
{
|
||||
// TODO: fixme
|
||||
return env->NewStringUTF("android");
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_network_loki_lokinet_Lokinet_1JNI_startLokinet(JNIEnv* env, jclass jcl,
|
||||
jstring configfile)
|
||||
{
|
||||
if(daemon->Running())
|
||||
return env->NewStringUTF("already running");
|
||||
std::string conf;
|
||||
{
|
||||
const char* nativeString = env->GetStringUTFChars(configfile, JNI_FALSE);
|
||||
conf += std::string(nativeString);
|
||||
env->ReleaseStringUTFChars(configfile, nativeString);
|
||||
}
|
||||
if(daemon->Start(conf.c_str()))
|
||||
return env->NewStringUTF("ok");
|
||||
else
|
||||
return env->NewStringUTF("failed to start");
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet(JNIEnv* env, jclass)
|
||||
{
|
||||
if(daemon->Running())
|
||||
{
|
||||
daemon->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged(JNIEnv*, jclass,
|
||||
jboolean)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class network_loki_lokinet_Lokinet_JNI */
|
||||
|
||||
#ifndef _Included_network_loki_lokinet_Lokinet_JNI
|
||||
#define _Included_network_loki_lokinet_Lokinet_JNI
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: network_loki_lokinet_Lokinet_JNI
|
||||
* Method: getABICompiledWith
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_network_loki_lokinet_Lokinet_1JNI_getABICompiledWith
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: network_loki_lokinet_Lokinet_JNI
|
||||
* Method: startLokinet
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_network_loki_lokinet_Lokinet_1JNI_startLokinet
|
||||
(JNIEnv *, jclass, jstring);
|
||||
|
||||
/*
|
||||
* Class: network_loki_lokinet_Lokinet_JNI
|
||||
* Method: stopLokinet
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: network_loki_lokinet_Lokinet_JNI
|
||||
* Method: onNetworkStateChanged
|
||||
* Signature: (Z)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged
|
||||
(JNIEnv *, jclass, jboolean);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -1,5 +1,7 @@
|
|||
#include "address_info.hpp"
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/mem.h>
|
||||
#include <llarp/string.h>
|
||||
|
@ -120,8 +122,12 @@ llarp_ai_list_iter_bencode(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
|
|||
bool
|
||||
llarp_ai_bdecode(struct llarp_ai *ai, llarp_buffer_t *buff)
|
||||
{
|
||||
#ifndef _MSC_VER
|
||||
struct dict_reader reader = {
|
||||
.buffer = nullptr, .user = ai, .on_key = &llarp_ai_decode_key};
|
||||
#else
|
||||
struct dict_reader reader = { nullptr, ai, &llarp_ai_decode_key };
|
||||
#endif
|
||||
return bencode_read_dict(buff, &reader);
|
||||
}
|
||||
|
||||
|
@ -174,8 +180,13 @@ llarp_ai_list_bencode(struct llarp_ai_list *l, llarp_buffer_t *buff)
|
|||
{
|
||||
if(!bencode_start_list(buff))
|
||||
return false;
|
||||
#ifndef _MSC_VER
|
||||
struct llarp_ai_list_iter ai_itr = {
|
||||
.user = buff, .list = nullptr, .visit = &llarp_ai_list_iter_bencode};
|
||||
#else
|
||||
struct llarp_ai_list_iter ai_itr = {buff, nullptr,
|
||||
&llarp_ai_list_iter_bencode};
|
||||
#endif
|
||||
llarp_ai_list_iterate(l, &ai_itr);
|
||||
return bencode_end(buff);
|
||||
}
|
||||
|
@ -255,7 +266,12 @@ llarp_ai_list_index(struct llarp_ai_list *l, ssize_t idx, struct llarp_ai *dst)
|
|||
bool
|
||||
llarp_ai_list_bdecode(struct llarp_ai_list *l, llarp_buffer_t *buff)
|
||||
{
|
||||
#ifndef _MSC_VER
|
||||
struct list_reader r = {
|
||||
.buffer = nullptr, .user = l, .on_item = &llarp_ai_list_bdecode_item};
|
||||
#else
|
||||
struct list_reader r = {
|
||||
nullptr, l, &llarp_ai_list_bdecode_item};
|
||||
#endif
|
||||
return bencode_read_list(buff, &r);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#include <llarp/buffer.h>
|
||||
#include <llarp/endian.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef ssize_t
|
||||
#define ssize_t long
|
||||
#endif
|
||||
size_t
|
||||
llarp_buffer_size_left(llarp_buffer_t buff)
|
||||
{
|
||||
|
@ -76,3 +80,42 @@ llarp_buffer_eq(llarp_buffer_t buf, const char* str)
|
|||
}
|
||||
return *str == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_buffer_put_uint16(llarp_buffer_t* buf, uint16_t i)
|
||||
{
|
||||
if(llarp_buffer_size_left(*buf) < sizeof(uint16_t))
|
||||
return false;
|
||||
htobe16buf(buf->cur, i);
|
||||
buf->cur += sizeof(uint16_t);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_buffer_put_uint32(llarp_buffer_t* buf, uint32_t i)
|
||||
{
|
||||
if(llarp_buffer_size_left(*buf) < sizeof(uint32_t))
|
||||
return false;
|
||||
htobe32buf(buf->cur, i);
|
||||
buf->cur += sizeof(uint32_t);
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
llarp_buffer_read_uint16(llarp_buffer_t* buf, uint16_t* i)
|
||||
{
|
||||
if(llarp_buffer_size_left(*buf) < sizeof(uint16_t))
|
||||
return false;
|
||||
*i = bufbe16toh(buf->cur);
|
||||
buf->cur += sizeof(uint16_t);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_buffer_put_uint32(llarp_buffer_t* buf, uint32_t* i)
|
||||
{
|
||||
if(llarp_buffer_size_left(*buf) < sizeof(uint32_t))
|
||||
return false;
|
||||
*i = bufbe32toh(buf->cur);
|
||||
buf->cur += sizeof(uint32_t);
|
||||
return true;
|
||||
}
|
|
@ -2,7 +2,9 @@
|
|||
#include <llarp.h>
|
||||
#include <llarp/logger.h>
|
||||
#include <signal.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <sys/param.h> // for MIN
|
||||
#endif
|
||||
#include <llarp.hpp>
|
||||
#include "logger.hpp"
|
||||
#include "math.h"
|
||||
|
@ -12,6 +14,16 @@
|
|||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
// keep this once jeff reenables concurrency
|
||||
#ifdef _MSC_VER
|
||||
extern "C" void
|
||||
SetThreadName(DWORD dwThreadID, LPCSTR szThreadName);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define wmin(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define MIN wmin
|
||||
#endif
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -188,6 +200,7 @@ namespace llarp
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
llarp::LogInfo("running mainloop");
|
||||
return llarp_ev_loop_run(mainloop, logic);
|
||||
}
|
||||
|
@ -202,11 +215,14 @@ namespace llarp
|
|||
llarp::LogInfo("SIGINT");
|
||||
SigINT();
|
||||
}
|
||||
// TODO(despair): implement hot-reloading config on NT
|
||||
#ifndef _WIN32
|
||||
if(sig == SIGHUP)
|
||||
{
|
||||
llarp::LogInfo("SIGHUP");
|
||||
ReloadConfig();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -289,194 +305,194 @@ extern "C"
|
|||
struct llarp_main *
|
||||
llarp_main_init(const char *fname, bool multiProcess)
|
||||
{
|
||||
if(!fname)
|
||||
fname = "daemon.ini";
|
||||
char *var = getenv("LLARP_DEBUG");
|
||||
if(var && *var == '1')
|
||||
{
|
||||
cSetLogLevel(eLogDebug);
|
||||
}
|
||||
llarp_main *m = new llarp_main;
|
||||
m->ctx.reset(new llarp::Context());
|
||||
m->ctx->singleThreaded = !multiProcess;
|
||||
if(!m->ctx->LoadConfig(fname))
|
||||
{
|
||||
m->ctx->Close();
|
||||
delete m;
|
||||
return nullptr;
|
||||
}
|
||||
return m;
|
||||
if(!fname)
|
||||
fname = "daemon.ini";
|
||||
char *var = getenv("LLARP_DEBUG");
|
||||
if(var && *var == '1')
|
||||
{
|
||||
cSetLogLevel(eLogDebug);
|
||||
}
|
||||
llarp_main *m = new llarp_main;
|
||||
m->ctx.reset(new llarp::Context());
|
||||
m->ctx->singleThreaded = !multiProcess;
|
||||
if(!m->ctx->LoadConfig(fname))
|
||||
{
|
||||
m->ctx->Close();
|
||||
delete m;
|
||||
return nullptr;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_main_signal(struct llarp_main *ptr, int sig)
|
||||
{
|
||||
ptr->ctx->HandleSignal(sig);
|
||||
ptr->ctx->HandleSignal(sig);
|
||||
}
|
||||
|
||||
int
|
||||
llarp_main_setup(struct llarp_main *ptr)
|
||||
{
|
||||
return ptr->ctx->Setup();
|
||||
return ptr->ctx->Setup();
|
||||
}
|
||||
|
||||
int
|
||||
llarp_main_run(struct llarp_main *ptr)
|
||||
{
|
||||
return ptr->ctx->Run();
|
||||
return ptr->ctx->Run();
|
||||
}
|
||||
|
||||
void
|
||||
llarp_main_abort(struct llarp_main *ptr)
|
||||
{
|
||||
llarp_logic_stop_timer(ptr->ctx->router->logic);
|
||||
llarp_logic_stop_timer(ptr->ctx->router->logic);
|
||||
}
|
||||
|
||||
int
|
||||
llarp_main_loadDatabase(struct llarp_main *ptr)
|
||||
{
|
||||
return ptr->ctx->LoadDatabase();
|
||||
return ptr->ctx->LoadDatabase();
|
||||
}
|
||||
|
||||
int
|
||||
llarp_main_iterateDatabase(struct llarp_main *ptr, struct llarp_nodedb_iter i)
|
||||
{
|
||||
return ptr->ctx->IterateDatabase(i);
|
||||
return ptr->ctx->IterateDatabase(i);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_main_putDatabase(struct llarp_main *ptr, struct llarp_rc *rc)
|
||||
{
|
||||
return ptr->ctx->PutDatabase(rc);
|
||||
return ptr->ctx->PutDatabase(rc);
|
||||
}
|
||||
|
||||
struct llarp_rc *
|
||||
llarp_main_getDatabase(struct llarp_main *ptr, byte_t *pk)
|
||||
{
|
||||
return ptr->ctx->GetDatabase(pk);
|
||||
return ptr->ctx->GetDatabase(pk);
|
||||
}
|
||||
|
||||
struct llarp_rc *
|
||||
llarp_main_getLocalRC(struct llarp_main *ptr)
|
||||
{
|
||||
//
|
||||
/*
|
||||
llarp_config_iterator iter;
|
||||
iter.user = this;
|
||||
iter.visit = &iter_config;
|
||||
llarp_config_iter(ctx->config, &iter);
|
||||
*/
|
||||
llarp_rc *rc = new llarp_rc;
|
||||
llarp_rc_new(rc);
|
||||
llarp::LogInfo("Loading ", ptr->ctx->conatctFile);
|
||||
if(llarp_rc_read(ptr->ctx->conatctFile, rc))
|
||||
return rc;
|
||||
else
|
||||
return nullptr;
|
||||
//
|
||||
/*
|
||||
llarp_config_iterator iter;
|
||||
iter.user = this;
|
||||
iter.visit = &iter_config;
|
||||
llarp_config_iter(ctx->config, &iter);
|
||||
*/
|
||||
llarp_rc *rc = new llarp_rc;
|
||||
llarp_rc_new(rc);
|
||||
llarp::LogInfo("Loading ", ptr->ctx->conatctFile);
|
||||
if(llarp_rc_read(ptr->ctx->conatctFile, rc))
|
||||
return rc;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_main_checkOnline(void *u, uint64_t orig, uint64_t left)
|
||||
{
|
||||
// llarp::LogInfo("checkOnline - check ", left);
|
||||
if(left)
|
||||
return;
|
||||
struct check_online_request *request =
|
||||
static_cast< struct check_online_request * >(u);
|
||||
// llarp::LogDebug("checkOnline - running");
|
||||
// llarp::LogInfo("checkOnline - DHT nodes ",
|
||||
// request->ptr->ctx->router->dht->impl.nodes->nodes.size());
|
||||
request->online = false;
|
||||
request->nodes = request->ptr->ctx->router->dht->impl.nodes->nodes.size();
|
||||
if(request->ptr->ctx->router->dht->impl.nodes->nodes.size())
|
||||
{
|
||||
// llarp::LogInfo("checkOnline - Going to say we're online");
|
||||
request->online = true;
|
||||
}
|
||||
request->hook(request);
|
||||
// reschedue our self
|
||||
llarp_main_queryDHT(request);
|
||||
// llarp::LogInfo("checkOnline - check ", left);
|
||||
if(left)
|
||||
return;
|
||||
struct check_online_request *request =
|
||||
static_cast< struct check_online_request * >(u);
|
||||
// llarp::LogDebug("checkOnline - running");
|
||||
// llarp::LogInfo("checkOnline - DHT nodes ",
|
||||
// request->ptr->ctx->router->dht->impl.nodes->nodes.size());
|
||||
request->online = false;
|
||||
request->nodes = request->ptr->ctx->router->dht->impl.nodes->nodes.size();
|
||||
if(request->ptr->ctx->router->dht->impl.nodes->nodes.size())
|
||||
{
|
||||
// llarp::LogInfo("checkOnline - Going to say we're online");
|
||||
request->online = true;
|
||||
}
|
||||
request->hook(request);
|
||||
// reschedue our self
|
||||
llarp_main_queryDHT(request);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_main_queryDHT_online(struct check_online_request *request)
|
||||
{
|
||||
// Info("llarp_main_queryDHT_online: ", request->online ? "online" :
|
||||
// "offline");
|
||||
if(request->online && !request->first)
|
||||
{
|
||||
request->first = true;
|
||||
llarp::LogInfo("llarp_main_queryDHT_online - We're online");
|
||||
llarp::LogInfo("llarp_main_queryDHT_online - Querying DHT");
|
||||
llarp_dht_lookup_router(request->ptr->ctx->router->dht, request->job);
|
||||
}
|
||||
// Info("llarp_main_queryDHT_online: ", request->online ? "online" :
|
||||
// "offline");
|
||||
if(request->online && !request->first)
|
||||
{
|
||||
request->first = true;
|
||||
llarp::LogInfo("llarp_main_queryDHT_online - We're online");
|
||||
llarp::LogInfo("llarp_main_queryDHT_online - Querying DHT");
|
||||
llarp_dht_lookup_router(request->ptr->ctx->router->dht, request->job);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_main_queryDHT(struct check_online_request *request)
|
||||
{
|
||||
// llarp::LogInfo("llarp_main_queryDHT - setting up timer");
|
||||
request->hook = &llarp_main_queryDHT_online;
|
||||
llarp_logic_call_later(request->ptr->ctx->router->logic,
|
||||
{1000, request, &llarp_main_checkOnline});
|
||||
// llarp_dht_lookup_router(ptr->ctx->router->dht, job);
|
||||
// llarp::LogInfo("llarp_main_queryDHT - setting up timer");
|
||||
request->hook = &llarp_main_queryDHT_online;
|
||||
llarp_logic_call_later(request->ptr->ctx->router->logic,
|
||||
{1000, request, &llarp_main_checkOnline});
|
||||
// llarp_dht_lookup_router(ptr->ctx->router->dht, job);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_main_free(struct llarp_main *ptr)
|
||||
{
|
||||
delete ptr;
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
const char *
|
||||
handleBaseCmdLineArgs(int argc, char *argv[])
|
||||
{
|
||||
const char *conffname = "daemon.ini";
|
||||
int c;
|
||||
while(1)
|
||||
const char *conffname = "daemon.ini";
|
||||
int c;
|
||||
while(1)
|
||||
{
|
||||
static struct option long_options[] = {
|
||||
{"config", required_argument, 0, 'c'},
|
||||
{"logLevel", required_argument, 0, 'o'},
|
||||
{0, 0, 0, 0}};
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "c:o:", long_options, &option_index);
|
||||
if(c == -1)
|
||||
break;
|
||||
switch(c)
|
||||
{
|
||||
static struct option long_options[] = {
|
||||
{"config", required_argument, 0, 'c'},
|
||||
{"logLevel", required_argument, 0, 'o'},
|
||||
{0, 0, 0, 0}};
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "c:o:", long_options, &option_index);
|
||||
if(c == -1)
|
||||
case 0:
|
||||
break;
|
||||
switch(c)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 'c':
|
||||
conffname = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
case 'c':
|
||||
conffname = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
if(strncmp(optarg, "debug", MIN(strlen(optarg), (unsigned long)5))
|
||||
== 0)
|
||||
{
|
||||
cSetLogLevel(eLogDebug);
|
||||
}
|
||||
else if(strncmp(optarg, "info", MIN(strlen(optarg), (unsigned long)4))
|
||||
== 0)
|
||||
{
|
||||
cSetLogLevel(eLogInfo);
|
||||
}
|
||||
else if(strncmp(optarg, "warn", MIN(strlen(optarg), (unsigned long)4))
|
||||
== 0)
|
||||
{
|
||||
cSetLogLevel(eLogWarn);
|
||||
}
|
||||
{
|
||||
cSetLogLevel(eLogDebug);
|
||||
}
|
||||
else if(strncmp(optarg, "info", MIN(strlen(optarg), (unsigned long)4))
|
||||
== 0)
|
||||
{
|
||||
cSetLogLevel(eLogInfo);
|
||||
}
|
||||
else if(strncmp(optarg, "warn", MIN(strlen(optarg), (unsigned long)4))
|
||||
== 0)
|
||||
{
|
||||
cSetLogLevel(eLogWarn);
|
||||
}
|
||||
else if(strncmp(optarg, "error",
|
||||
MIN(strlen(optarg), (unsigned long)5))
|
||||
== 0)
|
||||
{
|
||||
cSetLogLevel(eLogError);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
== 0)
|
||||
{
|
||||
cSetLogLevel(eLogError);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return conffname;
|
||||
}
|
||||
return conffname;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,6 +256,10 @@ namespace iwp
|
|||
{
|
||||
iwp_async_session_start *session =
|
||||
static_cast< iwp_async_session_start * >(user);
|
||||
// possible repeat job
|
||||
if(session->buf == nullptr)
|
||||
return;
|
||||
|
||||
auto crypto = session->iwp->crypto;
|
||||
auto logic = session->iwp->logic;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace llarp
|
|||
|
||||
if(crypto_scalarmult_curve25519(shared, usSec, themPub))
|
||||
return false;
|
||||
crypto_generichash_init(&h, NULL, 0U, outsz);
|
||||
crypto_generichash_init(&h, nullptr, 0U, outsz);
|
||||
crypto_generichash_update(&h, client_pk, 32);
|
||||
crypto_generichash_update(&h, server_pk, 32);
|
||||
crypto_generichash_update(&h, shared, 32);
|
||||
|
|
|
@ -38,7 +38,10 @@ namespace llarp
|
|||
while(itr != nodes.end())
|
||||
{
|
||||
if(itr->second.introset.IsExpired(now))
|
||||
{
|
||||
llarp::LogInfo("introset expired ", itr->second.introset.A.Addr());
|
||||
itr = nodes.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
|
@ -46,13 +49,15 @@ namespace llarp
|
|||
ctx->ScheduleCleanupTimer();
|
||||
}
|
||||
|
||||
struct PathTagLookupJob
|
||||
struct PathLookupJob
|
||||
{
|
||||
uint64_t txid;
|
||||
PathID_t pathID;
|
||||
llarp_router *m_router;
|
||||
std::set< service::IntroSet > localtags;
|
||||
PathTagLookupJob(llarp_router *r, const PathID_t &localpath, uint64_t tx)
|
||||
std::set< service::IntroSet > localIntroSets;
|
||||
std::set< Key_t > asked;
|
||||
|
||||
PathLookupJob(llarp_router *r, const PathID_t &localpath, uint64_t tx)
|
||||
: txid(tx), pathID(localpath), m_router(r)
|
||||
{
|
||||
}
|
||||
|
@ -66,15 +71,16 @@ namespace llarp
|
|||
{
|
||||
for(const auto &introset : results)
|
||||
{
|
||||
localtags.insert(introset);
|
||||
localIntroSets.insert(introset);
|
||||
}
|
||||
llarp::routing::DHTMessage msg;
|
||||
auto sz = localtags.size();
|
||||
auto sz = localIntroSets.size();
|
||||
std::vector< service::IntroSet > intros(sz);
|
||||
for(const auto &i : localtags)
|
||||
for(const auto &i : localIntroSets)
|
||||
{
|
||||
intros[--sz] = i;
|
||||
}
|
||||
llarp::LogInfo("found ", sz, " introsets for txid=", txid);
|
||||
msg.M.push_back(new llarp::dht::GotIntroMessage(intros, txid));
|
||||
path->SendRoutingMessage(&msg, m_router);
|
||||
}
|
||||
|
@ -90,12 +96,17 @@ namespace llarp
|
|||
void
|
||||
Context::PropagateIntroSetTo(const Key_t &from, uint64_t txid,
|
||||
const service::IntroSet &introset,
|
||||
const Key_t &peer, uint64_t S)
|
||||
const Key_t &peer, uint64_t S,
|
||||
const std::set< Key_t > &exclude)
|
||||
{
|
||||
llarp::LogInfo("Propagate Introset for ", introset.A.Name(), " to ",
|
||||
peer);
|
||||
auto id = ++ids;
|
||||
|
||||
std::vector< Key_t > E;
|
||||
for(const auto &ex : exclude)
|
||||
E.push_back(ex);
|
||||
|
||||
TXOwner ownerKey;
|
||||
ownerKey.node = peer;
|
||||
ownerKey.txid = id;
|
||||
|
@ -103,7 +114,7 @@ namespace llarp
|
|||
[](const std::vector< service::IntroSet > &) {});
|
||||
pendingTX[ownerKey] = job;
|
||||
auto msg = new llarp::DHTImmeidateMessage(peer);
|
||||
msg->msgs.push_back(new PublishIntroMessage(introset, id, S));
|
||||
msg->msgs.push_back(new PublishIntroMessage(introset, id, S, E));
|
||||
router->SendToOrQueue(peer, msg);
|
||||
}
|
||||
|
||||
|
@ -113,17 +124,41 @@ namespace llarp
|
|||
{
|
||||
auto id = ++ids;
|
||||
TXOwner ownerKey;
|
||||
ownerKey.node = askpeer;
|
||||
ownerKey.txid = id;
|
||||
PathTagLookupJob *j = new PathTagLookupJob(router, path, txid);
|
||||
j->localtags = FindRandomIntroSetsWithTag(tag);
|
||||
ownerKey.node = askpeer;
|
||||
ownerKey.txid = id;
|
||||
PathLookupJob *j = new PathLookupJob(router, path, txid);
|
||||
j->localIntroSets = FindRandomIntroSetsWithTag(tag);
|
||||
SearchJob job(
|
||||
OurKey(), txid,
|
||||
std::bind(&PathTagLookupJob::OnResult, j, std::placeholders::_1));
|
||||
std::bind(&PathLookupJob::OnResult, j, std::placeholders::_1));
|
||||
pendingTX[ownerKey] = job;
|
||||
|
||||
auto msg = new llarp::DHTImmeidateMessage(askpeer);
|
||||
auto dhtmsg = new FindIntroMessage(tag, id);
|
||||
dhtmsg->R = 5;
|
||||
msg->msgs.push_back(dhtmsg);
|
||||
llarp::LogInfo("asking ", askpeer, " for tag ", tag.ToString(), " with ",
|
||||
j->localIntroSets.size(), " local tags txid=", txid);
|
||||
router->SendToOrQueue(askpeer, msg);
|
||||
}
|
||||
|
||||
void
|
||||
Context::LookupIntroSetForPath(const service::Address &addr, uint64_t txid,
|
||||
const llarp::PathID_t &path,
|
||||
const Key_t &askpeer)
|
||||
{
|
||||
auto id = ++ids;
|
||||
TXOwner ownerKey;
|
||||
ownerKey.node = askpeer;
|
||||
ownerKey.txid = id;
|
||||
PathLookupJob *j = new PathLookupJob(router, path, txid);
|
||||
SearchJob job(
|
||||
OurKey(), txid,
|
||||
std::bind(&PathLookupJob::OnResult, j, std::placeholders::_1));
|
||||
pendingTX[ownerKey] = job;
|
||||
|
||||
auto msg = new llarp::DHTImmeidateMessage(askpeer);
|
||||
auto dhtmsg = new FindIntroMessage(addr, id);
|
||||
msg->msgs.push_back(dhtmsg);
|
||||
router->SendToOrQueue(askpeer, msg);
|
||||
}
|
||||
|
@ -140,10 +175,11 @@ namespace llarp
|
|||
// start at random middle point
|
||||
auto start = llarp_randint() % nodes.size();
|
||||
std::advance(itr, start);
|
||||
auto end = itr;
|
||||
auto end = itr;
|
||||
std::string tagname = tag.ToString();
|
||||
while(itr != nodes.end())
|
||||
{
|
||||
if(itr->second.introset.topic == tag)
|
||||
if(itr->second.introset.topic.ToString() == tagname)
|
||||
{
|
||||
found.insert(itr->second.introset);
|
||||
if(found.size() == max)
|
||||
|
@ -154,7 +190,7 @@ namespace llarp
|
|||
itr = nodes.begin();
|
||||
while(itr != end)
|
||||
{
|
||||
if(itr->second.introset.topic == tag)
|
||||
if(itr->second.introset.topic.ToString() == tagname)
|
||||
{
|
||||
found.insert(itr->second.introset);
|
||||
if(found.size() == max)
|
||||
|
@ -307,6 +343,7 @@ namespace llarp
|
|||
/// handles replying with a GIM for a lookup
|
||||
struct IntroSetInformJob
|
||||
{
|
||||
std::set< service::IntroSet > localIntroSets;
|
||||
Key_t replyNode;
|
||||
uint64_t txid;
|
||||
llarp_router *m_Router;
|
||||
|
@ -318,10 +355,19 @@ namespace llarp
|
|||
void
|
||||
OnResult(const std::vector< llarp::service::IntroSet > &results)
|
||||
{
|
||||
for(const auto &introset : results)
|
||||
{
|
||||
localIntroSets.insert(introset);
|
||||
}
|
||||
if(replyNode != m_Router->dht->impl.OurKey())
|
||||
{
|
||||
std::vector< service::IntroSet > reply;
|
||||
for(const auto &introset : localIntroSets)
|
||||
{
|
||||
reply.push_back(introset);
|
||||
}
|
||||
auto msg = new llarp::DHTImmeidateMessage(replyNode);
|
||||
msg->msgs.push_back(new GotIntroMessage(results, txid));
|
||||
msg->msgs.push_back(new GotIntroMessage(reply, txid));
|
||||
m_Router->SendToOrQueue(replyNode, msg);
|
||||
}
|
||||
delete this;
|
||||
|
@ -330,7 +376,8 @@ namespace llarp
|
|||
|
||||
void
|
||||
Context::LookupTag(const llarp::service::Tag &tag, const Key_t &whoasked,
|
||||
uint64_t txid, const Key_t &askpeer, bool iterative)
|
||||
uint64_t txid, const Key_t &askpeer,
|
||||
const std::set< service::IntroSet > &include, uint64_t R)
|
||||
{
|
||||
auto id = ++ids;
|
||||
if(txid == 0)
|
||||
|
@ -339,14 +386,15 @@ namespace llarp
|
|||
ownerKey.node = askpeer;
|
||||
ownerKey.txid = id;
|
||||
IntroSetInformJob *j = new IntroSetInformJob(router, whoasked, txid);
|
||||
j->localIntroSets = include;
|
||||
SearchJob job(
|
||||
whoasked, txid,
|
||||
std::bind(&IntroSetInformJob::OnResult, j, std::placeholders::_1));
|
||||
pendingTX[ownerKey] = job;
|
||||
|
||||
auto msg = new llarp::DHTImmeidateMessage(askpeer);
|
||||
auto dhtmsg = new FindIntroMessage(tag, id);
|
||||
dhtmsg->iterative = iterative;
|
||||
auto msg = new llarp::DHTImmeidateMessage(askpeer);
|
||||
auto dhtmsg = new FindIntroMessage(tag, id);
|
||||
dhtmsg->R = R;
|
||||
msg->msgs.push_back(dhtmsg);
|
||||
router->SendToOrQueue(askpeer, msg);
|
||||
}
|
||||
|
@ -363,7 +411,7 @@ namespace llarp
|
|||
TXOwner ownerKey;
|
||||
ownerKey.node = askpeer;
|
||||
ownerKey.txid = id;
|
||||
IntroSetInformJob *j = new IntroSetInformJob(router, askpeer, txid);
|
||||
IntroSetInformJob *j = new IntroSetInformJob(router, whoasked, txid);
|
||||
SearchJob job(
|
||||
whoasked, txid, addr, excludes,
|
||||
std::bind(&IntroSetInformJob::OnResult, j, std::placeholders::_1));
|
||||
|
|
|
@ -101,6 +101,11 @@ namespace llarp
|
|||
llarp_dht_context* ctx,
|
||||
std::vector< llarp::dht::IMessage* >& replies) const
|
||||
{
|
||||
if(R > 5)
|
||||
{
|
||||
llarp::LogError("R value too big, ", R, "> 5");
|
||||
return false;
|
||||
}
|
||||
auto& dht = ctx->impl;
|
||||
Key_t peer;
|
||||
std::set< Key_t > exclude = {dht.OurKey(), From};
|
||||
|
@ -109,24 +114,35 @@ namespace llarp
|
|||
const auto introset = dht.GetIntroSetByServiceAddress(S);
|
||||
if(introset)
|
||||
{
|
||||
replies.push_back(new GotIntroMessage({*introset}, T));
|
||||
}
|
||||
else if(iterative)
|
||||
{
|
||||
// we are iterative and don't have it, reply with a direct reply
|
||||
replies.push_back(new GotIntroMessage({}, T));
|
||||
service::IntroSet i = *introset;
|
||||
replies.push_back(new GotIntroMessage({i}, T));
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are recursive
|
||||
if(dht.nodes->FindCloseExcluding(S, peer, exclude))
|
||||
if(iterative)
|
||||
{
|
||||
dht.LookupIntroSet(S, From, T, peer);
|
||||
// we are iterative and don't have it, reply with a direct reply
|
||||
replies.push_back(new GotIntroMessage({}, T));
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogError("cannot find closer peers for introset lookup for ",
|
||||
S);
|
||||
// we are recursive
|
||||
if(dht.nodes->FindCloseExcluding(S, peer, exclude))
|
||||
{
|
||||
if(relayed)
|
||||
dht.LookupIntroSetForPath(S, T, pathID, peer);
|
||||
else if((peer ^ dht.OurKey())
|
||||
> (peer
|
||||
^ From)) // peer is closer than us, recursive search
|
||||
dht.LookupIntroSet(S, From, T, peer);
|
||||
else // we are closer than peer so do iterative search
|
||||
dht.LookupIntroSet(S, From, T, peer, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogError(
|
||||
"cannot find closer peers for introset lookup for ", S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +151,7 @@ namespace llarp
|
|||
if(relayed)
|
||||
{
|
||||
// tag lookup
|
||||
if(dht.nodes->FindCloseExcluding(N.Key(), peer, exclude))
|
||||
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
|
||||
{
|
||||
dht.LookupTagForPath(N, T, pathID, peer);
|
||||
}
|
||||
|
@ -146,20 +162,23 @@ namespace llarp
|
|||
}
|
||||
else
|
||||
{
|
||||
if(iterative)
|
||||
auto introsets = dht.FindRandomIntroSetsWithTag(N);
|
||||
if(iterative || R == 0)
|
||||
{
|
||||
std::vector< service::IntroSet > introsets;
|
||||
for(const auto& introset : dht.FindRandomIntroSetsWithTag(N, 8))
|
||||
introsets.push_back(introset);
|
||||
std::vector< service::IntroSet > reply;
|
||||
for(const auto& introset : introsets)
|
||||
{
|
||||
reply.push_back(introset);
|
||||
}
|
||||
// we are iterative and don't have it, reply with a direct reply
|
||||
replies.push_back(new GotIntroMessage(introsets, T));
|
||||
replies.push_back(new GotIntroMessage(reply, T));
|
||||
}
|
||||
else
|
||||
{
|
||||
// tag lookup
|
||||
if(dht.nodes->FindCloseExcluding(N.Key(), peer, exclude))
|
||||
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
|
||||
{
|
||||
dht.LookupTag(N, From, T, peer, true);
|
||||
dht.LookupTag(N, From, T, peer, introsets, R - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
dht.services->PutNode(I);
|
||||
llarp::LogInfo("Put Introset for ", I.A.Addr().ToString());
|
||||
replies.push_back(new GotIntroMessage({I}, txID));
|
||||
Key_t peer;
|
||||
std::set< Key_t > exclude;
|
||||
|
@ -76,7 +77,7 @@ namespace llarp
|
|||
exclude.insert(dht.OurKey());
|
||||
if(S && dht.nodes->FindCloseExcluding(addr, peer, exclude))
|
||||
{
|
||||
dht.PropagateIntroSetTo(From, txID, I, peer, S - 1);
|
||||
dht.PropagateIntroSetTo(From, txID, I, peer, S - 1, exclude);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@ std::string getDNSstring(const char *buffer)
|
|||
return str;
|
||||
}
|
||||
|
||||
// lets just remove uint
|
||||
#ifdef _WIN32
|
||||
#define uint UINT
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
uint16_t
|
||||
|
@ -57,7 +62,7 @@ extern "C"
|
|||
{
|
||||
dns_msg_header *hdr = new dns_msg_header;
|
||||
hdr->id = get16bits(buffer);
|
||||
uint fields = get16bits(buffer);
|
||||
uint16_t fields = get16bits(buffer);
|
||||
uint8_t lFields = (fields & 0x00FF) >> 0;
|
||||
uint8_t hFields = (fields & 0xFF00) >> 8;
|
||||
// hdr->qr = fields & 0x8000;
|
||||
|
@ -79,7 +84,7 @@ extern "C"
|
|||
hdr->arCount = get16bits(buffer);
|
||||
return hdr;
|
||||
}
|
||||
|
||||
|
||||
dns_msg_question *
|
||||
decode_question(const char *buffer)
|
||||
{
|
||||
|
@ -208,7 +213,7 @@ extern "C"
|
|||
// llarp::LogInfo("start ", start, " domain size ", domain.size());
|
||||
|
||||
*buffer++ = domain.size() - start; // last label length octet
|
||||
for(uint i = start; i < domain.size(); i++)
|
||||
for(size_t i = start; i < domain.size(); i++)
|
||||
{
|
||||
*buffer++ = domain[i]; // last label octets
|
||||
// llarp::LogInfo("Writing ", domain[i], " at ", i);
|
||||
|
@ -242,14 +247,14 @@ extern "C"
|
|||
llarp::LogInfo("msg op ", hdr->opcode);
|
||||
llarp::LogInfo("msg rc ", hdr->rcode);
|
||||
|
||||
for(uint i = 0; i < hdr->qdCount; i++)
|
||||
for(uint8_t i = 0; i < hdr->qdCount; i++)
|
||||
{
|
||||
dns_msg_question *question = decode_question((const char*)castBuf);
|
||||
llarp::LogInfo("Read a question");
|
||||
castBuf += question->name.length() + 8;
|
||||
}
|
||||
|
||||
for(uint i = 0; i < hdr->anCount; i++)
|
||||
for(uint8_t i = 0; i < hdr->anCount; i++)
|
||||
{
|
||||
dns_msg_answer *answer = decode_answer((const char*)castBuf);
|
||||
llarp::LogInfo("Read an answer");
|
||||
|
|
106
llarp/dnsc.cpp
106
llarp/dnsc.cpp
|
@ -2,21 +2,26 @@
|
|||
#include <llarp/dns.h>
|
||||
#include "buffer.hpp"
|
||||
|
||||
#include <netdb.h> /* getaddrinfo, getnameinfo */
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h> /* getaddrinfo, getnameinfo */
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* exit */
|
||||
#include <string.h> /* memset */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h> /* close */
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <llarp/dns.h>
|
||||
#include "llarp/net.hpp" // for llarp::Addr
|
||||
#include "logger.hpp"
|
||||
#include <algorithm> // for std::find_if
|
||||
|
||||
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
|
||||
|
||||
|
@ -76,7 +81,7 @@ build_dns_packet(char *url, uint16_t id, uint16_t reqType)
|
|||
{
|
||||
dnsQuery->request[dnsQuery->length++] = word[i];
|
||||
}
|
||||
word = strtok(NULL, ".");
|
||||
word = strtok(nullptr, ".");
|
||||
}
|
||||
|
||||
dnsQuery->request[dnsQuery->length++] = 0x00; // End of the host name
|
||||
|
@ -104,11 +109,11 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
|
|||
request->resolved = resolved;
|
||||
request->found = false;
|
||||
request->context = dnsc;
|
||||
|
||||
|
||||
|
||||
|
||||
char *sUrl = strdup(url);
|
||||
request->question.name = (char *)sUrl;
|
||||
|
||||
|
||||
// leave 256 bytes available
|
||||
if (request->question.name.size() > 255)
|
||||
{
|
||||
|
@ -119,15 +124,15 @@ answer_request_alloc(struct dnsc_context *dnsc, void *sock, const char *url,
|
|||
}
|
||||
request->question.type = 1;
|
||||
request->question.qClass = 1;
|
||||
|
||||
|
||||
// register our self with the tracker
|
||||
dns_tracker *tracker = request->context->tracker;
|
||||
uint16_t id = ++tracker->c_requests;
|
||||
if (id == 65535) id = 0;
|
||||
tracker->client_request[id] = request;
|
||||
|
||||
|
||||
dns_query *dns_packet = build_dns_packet((char *)request->question.name.c_str(), id, 1);
|
||||
|
||||
|
||||
return dns_packet;
|
||||
}
|
||||
|
||||
|
@ -138,11 +143,11 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
ssize_t sz)
|
||||
{
|
||||
// llarp::LogInfo("got a response, udp user is ", udp->user);
|
||||
|
||||
|
||||
unsigned char *castBuf = (unsigned char *)buf;
|
||||
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
|
||||
dns_msg_header *hdr = decode_hdr((const char *)castBuf);
|
||||
|
||||
|
||||
llarp::LogDebug("Header got client responses for id: ", hdr->id);
|
||||
if(!request)
|
||||
{
|
||||
|
@ -152,17 +157,17 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
return;
|
||||
}
|
||||
// llarp_dnsc_unbind(request);
|
||||
|
||||
|
||||
if(sz < 0)
|
||||
{
|
||||
llarp::LogWarn("Error Receiving DNS Client Response");
|
||||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// unsigned char *castBuf = (unsigned char *)buf;
|
||||
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
|
||||
|
||||
|
||||
// hexdump("received packet", &buffer, ret);
|
||||
/*
|
||||
uint16_t QDCOUNT; // No. of items in Question Section
|
||||
|
@ -178,12 +183,12 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
*/
|
||||
uint8_t rcode;
|
||||
// int length;
|
||||
|
||||
|
||||
// struct dns_query *dnsQuery = &request->query;
|
||||
|
||||
|
||||
// rcode = (buffer[3] & 0x0F);
|
||||
// llarp::LogInfo("dnsc rcode ", rcode);
|
||||
|
||||
|
||||
dns_msg_header *msg = decode_hdr((const char *)castBuf);
|
||||
castBuf += 12;
|
||||
llarp::LogDebug("msg id ", msg->id);
|
||||
|
@ -193,23 +198,23 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
llarp::LogDebug("msg op ", opcode);
|
||||
rcode = msg->rcode;
|
||||
llarp::LogDebug("msg rc ", rcode);
|
||||
|
||||
|
||||
llarp::LogDebug("msg qdc ", msg->qdCount);
|
||||
llarp::LogDebug("msg anc ", msg->anCount);
|
||||
llarp::LogDebug("msg nsc ", msg->nsCount);
|
||||
llarp::LogDebug("msg arc ", msg->arCount);
|
||||
|
||||
|
||||
// we may need to parse question first
|
||||
|
||||
|
||||
/*
|
||||
dns_msg_question *question = decode_question((const char *)castBuf);
|
||||
llarp::LogInfo("que name ", question->name);
|
||||
castBuf += question->name.length() + 8;
|
||||
|
||||
|
||||
dns_msg_answer *answer = decode_answer((const char *)castBuf);
|
||||
castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
|
||||
*/
|
||||
|
||||
|
||||
// FIXME: only handling one atm
|
||||
dns_msg_question *question = nullptr;
|
||||
for(uint i = 0; i < hdr->qdCount; i++)
|
||||
|
@ -221,7 +226,7 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
castBuf += question->name.length() + 1 + 4;
|
||||
castBuf += 2; // skip answer label
|
||||
}
|
||||
|
||||
|
||||
// FIXME: only handling one atm
|
||||
dns_msg_answer *answer = nullptr;
|
||||
for(uint i = 0; i < hdr->anCount; i++)
|
||||
|
@ -243,16 +248,16 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
llarp::LogDebug("Read an authority");
|
||||
castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
|
||||
}
|
||||
|
||||
|
||||
// dns_msg_answer *answer2 = decode_answer((const char*)castBuf);
|
||||
// castBuf += answer->name.length() + 4 + 4 + 4 + answer->rdLen;
|
||||
|
||||
|
||||
// llarp::LogDebug("query type: %u\n", dnsQuery->reqType);
|
||||
/*
|
||||
QCLASS = (uint16_t)dnsQuery->request[dnsQuery->length - 2] * 0x100
|
||||
+ dnsQuery->request[dnsQuery->length - 1];
|
||||
llarp::LogInfo("query class: ", QCLASS);
|
||||
|
||||
|
||||
length = dnsQuery->length + 1; // to skip 0xc00c
|
||||
// printf("length [%d] from [%d]\n", length, buffer.base);
|
||||
ATYPE = (uint16_t)buffer[length + 1] * 0x100 + buffer[length + 2];
|
||||
|
@ -264,31 +269,31 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
llarp::LogInfo("seconds to cache: ", TTL);
|
||||
RDLENGTH = (uint16_t)buffer[length + 9] * 0x100 + buffer[length + 10];
|
||||
llarp::LogInfo("bytes in answer: ", RDLENGTH);
|
||||
|
||||
|
||||
MSGID = (uint16_t)buffer[0] * 0x100 + buffer[1];
|
||||
// llarp::LogDebug("answer msg id: %u\n", MSGID);
|
||||
*/
|
||||
llarp::Addr upstreamAddr(*request->context->server);
|
||||
|
||||
|
||||
if(answer == nullptr)
|
||||
{
|
||||
llarp::LogWarn("nameserver ", upstreamAddr, " didnt return any answers:");
|
||||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
llarp::LogDebug("ans class ", answer->aClass);
|
||||
llarp::LogDebug("ans type ", answer->type);
|
||||
llarp::LogDebug("ans ttl ", answer->ttl);
|
||||
llarp::LogDebug("ans rdlen ", answer->rdLen);
|
||||
|
||||
|
||||
/*
|
||||
llarp::LogInfo("ans2 class ", answer2->aClass);
|
||||
llarp::LogInfo("ans2 type ", answer2->type);
|
||||
llarp::LogInfo("ans2 ttl ", answer2->ttl);
|
||||
llarp::LogInfo("ans2 rdlen ", answer2->rdLen);
|
||||
*/
|
||||
|
||||
|
||||
if(rcode == 2)
|
||||
{
|
||||
llarp::LogWarn("nameserver ", upstreamAddr, " returned SERVFAIL:");
|
||||
|
@ -306,16 +311,16 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int ip = 0;
|
||||
|
||||
|
||||
/* search for and print IPv4 addresses */
|
||||
// if(dnsQuery->reqType == 0x01)
|
||||
if(request->question.type == 1)
|
||||
{
|
||||
// llarp::LogInfo("DNS server's answer is: (type#=", ATYPE, "):");
|
||||
llarp::LogDebug("IPv4 address(es) for ", request->question.name, ":");
|
||||
|
||||
|
||||
if(answer->rdLen == 4)
|
||||
{
|
||||
request->result.sa_family = AF_INET;
|
||||
|
@ -324,20 +329,20 @@ generic_handle_dnsc_recvfrom(dnsc_answer_request *request,
|
|||
#endif
|
||||
struct in_addr *addr =
|
||||
&((struct sockaddr_in *)&request->result)->sin_addr;
|
||||
|
||||
|
||||
unsigned char *ip = (unsigned char *)&(addr->s_addr);
|
||||
ip[0] = answer->rData[0];
|
||||
ip[1] = answer->rData[1];
|
||||
ip[2] = answer->rData[2];
|
||||
ip[3] = answer->rData[3];
|
||||
|
||||
|
||||
llarp::Addr test(request->result);
|
||||
llarp::LogDebug(test);
|
||||
request->found = true;
|
||||
request->resolved(request);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(!ip)
|
||||
{
|
||||
llarp::LogWarn(" No IPv4 address found in the DNS answer!");
|
||||
|
@ -351,14 +356,14 @@ void
|
|||
raw_resolve_host(struct dnsc_context *dnsc, const char *url,
|
||||
dnsc_answer_hook_func resolved, void *user)
|
||||
{
|
||||
|
||||
|
||||
dns_query *dns_packet = answer_request_alloc(dnsc, nullptr, url, resolved, user);
|
||||
if (!dns_packet)
|
||||
{
|
||||
llarp::LogError("Couldn't make dnsc packet");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// char *word;
|
||||
llarp::Addr upstreamAddr(*dnsc->server);
|
||||
llarp::LogDebug("Asking DNS server ", upstreamAddr, " about ", url);
|
||||
|
@ -368,7 +373,11 @@ raw_resolve_host(struct dnsc_context *dnsc, const char *url,
|
|||
socklen_t size;
|
||||
// int length;
|
||||
unsigned char buffer[DNC_BUF_SIZE];
|
||||
#ifndef _WIN32
|
||||
int sockfd;
|
||||
#else
|
||||
SOCKET sockfd;
|
||||
#endif
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(sockfd < 0)
|
||||
|
@ -386,8 +395,15 @@ raw_resolve_host(struct dnsc_context *dnsc, const char *url,
|
|||
size = sizeof(addr);
|
||||
|
||||
//hexdump("sending packet", &dnsQuery.request, dnsQuery.length);
|
||||
ret = sendto(sockfd, dns_packet->request, dns_packet->length, 0,
|
||||
|
||||
#ifdef _WIN32
|
||||
ret = sendto(sockfd, (const char *)dns_packet->request, dns_packet->length, 0,
|
||||
(struct sockaddr *)&addr, size);
|
||||
#else
|
||||
ret = sendto(sockfd, (const char *)dns_packet->request, dns_packet->length, 0,
|
||||
(struct sockaddr *)&addr, size);
|
||||
#endif
|
||||
|
||||
delete dns_packet;
|
||||
if(ret < 0)
|
||||
{
|
||||
|
@ -410,7 +426,11 @@ raw_resolve_host(struct dnsc_context *dnsc, const char *url,
|
|||
|
||||
// hexdump("received packet", &buffer, ret);
|
||||
|
||||
#ifndef _WIN32
|
||||
close(sockfd);
|
||||
#else
|
||||
closesocket(sockfd);
|
||||
#endif
|
||||
|
||||
unsigned char *castBuf = (unsigned char *)buffer;
|
||||
// auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
|
||||
|
|
|
@ -9,6 +9,11 @@
|
|||
|
||||
extern dns_tracker dns_udp_tracker;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define wmin(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define MIN wmin
|
||||
#endif
|
||||
|
||||
ssize_t
|
||||
raw_sendto_dns_hook_func(void *sock, const struct sockaddr *from,
|
||||
const void *buffer, size_t length)
|
||||
|
@ -16,7 +21,11 @@ raw_sendto_dns_hook_func(void *sock, const struct sockaddr *from,
|
|||
int *fd = (int *)sock;
|
||||
// how do we get to these??
|
||||
socklen_t addrLen = sizeof(struct sockaddr_in);
|
||||
return sendto(*fd, buffer, length, 0, from, addrLen);
|
||||
#ifdef _WIN32
|
||||
return sendto(*fd, (const char *)buffer, length, 0, from, addrLen);
|
||||
#else
|
||||
return sendto(*fd, (const char *)buffer, length, 0, from, addrLen);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t
|
||||
|
@ -40,7 +49,7 @@ llarp_sendto_dns_hook_func(void *sock, const struct sockaddr *from,
|
|||
void
|
||||
write404_dnss_response(const struct sockaddr *from, dnsd_question_request *request)
|
||||
{
|
||||
|
||||
|
||||
const size_t BUFFER_SIZE = 1024 + (request->question.name.size() * 2);
|
||||
char buf[BUFFER_SIZE];
|
||||
memset(buf, 0, BUFFER_SIZE);
|
||||
|
@ -52,26 +61,26 @@ write404_dnss_response(const struct sockaddr *from, dnsd_question_request *reque
|
|||
fields += (0 << 14); // I think opcode is always 0
|
||||
fields += 3; // response code (3 => not found, 0 = Ok)
|
||||
put16bits(write_buffer, fields);
|
||||
|
||||
|
||||
put16bits(write_buffer, 1); // QD (number of questions)
|
||||
put16bits(write_buffer, 1); // AN (number of answers)
|
||||
put16bits(write_buffer, 0); // NS (number of auth RRs)
|
||||
put16bits(write_buffer, 0); // AR (number of Additional RRs)
|
||||
|
||||
|
||||
// code question
|
||||
code_domain(write_buffer, request->question.name);
|
||||
put16bits(write_buffer, request->question.type);
|
||||
put16bits(write_buffer, request->question.qClass);
|
||||
|
||||
|
||||
// code answer
|
||||
code_domain(write_buffer, ""); // com, type=6, ttl=0
|
||||
put16bits(write_buffer, request->question.type);
|
||||
put16bits(write_buffer, request->question.qClass);
|
||||
put32bits(write_buffer, 1); // ttl
|
||||
|
||||
|
||||
put16bits(write_buffer, 1); // rdLength
|
||||
*write_buffer++ = 0; // write a null byte
|
||||
|
||||
|
||||
uint out_bytes = write_buffer - bufferBegin;
|
||||
llarp::LogDebug("Sending 404, ", out_bytes, " bytes");
|
||||
// struct llarp_udp_io *udp = (struct llarp_udp_io *)request->user;
|
||||
|
@ -83,7 +92,7 @@ void
|
|||
writecname_dnss_response(std::string cname, const struct sockaddr *from,
|
||||
dnsd_question_request *request)
|
||||
{
|
||||
|
||||
|
||||
const size_t BUFFER_SIZE = 1024 + (request->question.name.size() * 2);
|
||||
char buf[BUFFER_SIZE];
|
||||
memset(buf, 0, BUFFER_SIZE);
|
||||
|
@ -98,39 +107,39 @@ writecname_dnss_response(std::string cname, const struct sockaddr *from,
|
|||
//fields |= 1UL << 8; // RD recursion desired
|
||||
//fields |= 1UL << 9; // 9 is truncate, forces TCP
|
||||
put16bits(write_buffer, fields);
|
||||
|
||||
|
||||
put16bits(write_buffer, 1); // QD (number of questions)
|
||||
put16bits(write_buffer, 1); // AN (number of answers)
|
||||
put16bits(write_buffer, 1); // NS (number of auth RRs)
|
||||
put16bits(write_buffer, 1); // AR (number of Additional RRs)
|
||||
|
||||
|
||||
// code question
|
||||
code_domain(write_buffer, request->question.name);
|
||||
put16bits(write_buffer, request->question.type);
|
||||
put16bits(write_buffer, request->question.qClass);
|
||||
|
||||
|
||||
// code answer
|
||||
code_domain(write_buffer, request->question.name); // com, type=6, ttl=0
|
||||
put16bits(write_buffer, 5); // cname
|
||||
put16bits(write_buffer, request->question.qClass);
|
||||
put32bits(write_buffer, 1); // ttl
|
||||
|
||||
|
||||
put16bits(write_buffer, cname.length() + 2); // rdLength
|
||||
code_domain(write_buffer, cname); // com, type=6, ttl=0
|
||||
// location of cname
|
||||
//*write_buffer++ = ip[0];
|
||||
//*write_buffer++ = ip[1];
|
||||
|
||||
|
||||
// write auth RR
|
||||
code_domain(write_buffer, cname); // com, type=6, ttl=0
|
||||
put16bits(write_buffer, 2); // NS
|
||||
put16bits(write_buffer, request->question.qClass);
|
||||
put32bits(write_buffer, 1); // ttl
|
||||
|
||||
|
||||
std::string local("ns1.loki");
|
||||
put16bits(write_buffer, local.length() + 2); // rdLength
|
||||
code_domain(write_buffer, local); // com, type=6, ttl=0
|
||||
|
||||
|
||||
// write addl RR
|
||||
code_domain(write_buffer, local); // com, type=6, ttl=0
|
||||
put16bits(write_buffer, 1); // A
|
||||
|
@ -142,7 +151,7 @@ writecname_dnss_response(std::string cname, const struct sockaddr *from,
|
|||
*write_buffer++ = 0;
|
||||
*write_buffer++ = 0;
|
||||
*write_buffer++ = 1;
|
||||
|
||||
|
||||
uint out_bytes = write_buffer - bufferBegin;
|
||||
llarp::LogDebug("Sending cname, ", out_bytes, " bytes");
|
||||
// struct llarp_udp_io *udp = (struct llarp_udp_io *)request->user;
|
||||
|
@ -315,7 +324,7 @@ handle_recvfrom(const char *buffer, ssize_t nbytes, const struct sockaddr *from,
|
|||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if(request->llarp)
|
||||
{
|
||||
// make async request
|
||||
|
@ -386,7 +395,7 @@ llarp_dnsd_init(struct dnsd_context *dnsd, struct llarp_ev_loop *netloop,
|
|||
dnsd->udp.tick = nullptr;
|
||||
|
||||
dns_udp_tracker.dnsd = dnsd;
|
||||
|
||||
|
||||
dnsd->tracker = &dns_udp_tracker; // register global tracker with context
|
||||
dnsd->logic = logic; // set logic worker for timers
|
||||
dnsd->intercept = nullptr; // set default intercepter
|
||||
|
@ -397,7 +406,7 @@ llarp_dnsd_init(struct dnsd_context *dnsd, struct llarp_ev_loop *netloop,
|
|||
llarp::LogError("Couldnt init dns client");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (netloop)
|
||||
{
|
||||
return llarp_ev_add_udp(netloop, &dnsd->udp, (const sockaddr *)&bindaddr)
|
||||
|
|
26
llarp/ev.cpp
26
llarp/ev.cpp
|
@ -5,11 +5,11 @@
|
|||
#ifdef __linux__
|
||||
#include "ev_epoll.hpp"
|
||||
#endif
|
||||
#if(__APPLE__ && __MACH__)
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || (__APPLE__ && __MACH__)
|
||||
#include "ev_kqueue.hpp"
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#include "ev_kqueue.hpp"
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__NT__)
|
||||
#include "ev_win32.hpp"
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -18,11 +18,17 @@ llarp_ev_loop_alloc(struct llarp_ev_loop **ev)
|
|||
#ifdef __linux__
|
||||
*ev = new llarp_epoll_loop;
|
||||
#endif
|
||||
#if(__APPLE__ && __MACH__)
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || (__APPLE__ && __MACH__)
|
||||
*ev = new llarp_kqueue_loop;
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
*ev = new llarp_kqueue_loop;
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__NT__)
|
||||
*ev = new llarp_win32_loop;
|
||||
#endif
|
||||
// a) I assume that the libre fork of Solaris is still
|
||||
// 5.10, and b) the current commercial version is 5.11, naturally.
|
||||
// -despair86
|
||||
#if defined(__SunOS_5_10) || defined(__SunOS_5_11)
|
||||
*ev = new llarp_sun_iocp_loop;
|
||||
#endif
|
||||
(*ev)->init();
|
||||
}
|
||||
|
@ -88,5 +94,11 @@ int
|
|||
llarp_ev_udp_sendto(struct llarp_udp_io *udp, const sockaddr *to,
|
||||
const void *buf, size_t sz)
|
||||
{
|
||||
return static_cast< llarp::ev_io * >(udp->impl)->sendto(to, buf, sz);
|
||||
auto ret = static_cast< llarp::ev_io * >(udp->impl)->sendto(to, buf, sz);
|
||||
if(ret == -1)
|
||||
{
|
||||
llarp::LogWarn("sendto failed ", strerror(errno));
|
||||
errno = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
12
llarp/ev.hpp
12
llarp/ev.hpp
|
@ -2,23 +2,35 @@
|
|||
#define LLARP_EV_HPP
|
||||
#include <llarp/ev.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <list>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct ev_io
|
||||
{
|
||||
#ifndef _WIN32
|
||||
int fd;
|
||||
ev_io(int f) : fd(f){};
|
||||
#else
|
||||
SOCKET fd;
|
||||
ev_io(SOCKET f) : fd(f){};
|
||||
#endif
|
||||
virtual int
|
||||
read(void* buf, size_t sz) = 0;
|
||||
|
||||
virtual int
|
||||
sendto(const sockaddr* dst, const void* data, size_t sz) = 0;
|
||||
|
||||
virtual ~ev_io()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
::close(fd);
|
||||
#else
|
||||
closesocket(fd);
|
||||
#endif
|
||||
};
|
||||
};
|
||||
}; // namespace llarp
|
||||
|
|
|
@ -145,7 +145,7 @@ struct llarp_epoll_loop : public llarp_ev_loop
|
|||
byte_t readbuf[2048];
|
||||
do
|
||||
{
|
||||
result = epoll_wait(epollfd, events, 1024, 100);
|
||||
result = epoll_wait(epollfd, events, 1024, 10);
|
||||
if(result > 0)
|
||||
{
|
||||
int idx = 0;
|
||||
|
|
|
@ -3,13 +3,7 @@
|
|||
#include <llarp/buffer.h>
|
||||
#include <llarp/net.h>
|
||||
|
||||
#if __FreeBSD__ || __OpenBSD__ || __NetBSD__
|
||||
// kqueue / kevent
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if(__APPLE__ && __MACH__)
|
||||
#if __FreeBSD__ || __OpenBSD__ || __NetBSD__ || (__APPLE__ && __MACH__)
|
||||
// kqueue / kevent
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -107,11 +101,13 @@ struct llarp_kqueue_loop : public llarp_ev_loop
|
|||
int
|
||||
tick(int ms)
|
||||
{
|
||||
(void)ms;
|
||||
struct kevent events[1024];
|
||||
int result;
|
||||
byte_t readbuf[2048];
|
||||
result = kevent(kqueuefd, NULL, 0, events, 1024, NULL);
|
||||
timespec t;
|
||||
t.tv_sec = 0;
|
||||
t.tv_nsec = ms * 1000UL;
|
||||
result = kevent(kqueuefd, nullptr, 0, events, 1024, &t);
|
||||
// result: 0 is a timeout
|
||||
if(result > 0)
|
||||
{
|
||||
|
@ -129,23 +125,25 @@ struct llarp_kqueue_loop : public llarp_ev_loop
|
|||
}
|
||||
++idx;
|
||||
}
|
||||
|
||||
for(auto& l : udp_listeners)
|
||||
if(l->tick)
|
||||
l->tick(l);
|
||||
}
|
||||
for(auto& l : udp_listeners)
|
||||
if(l->tick)
|
||||
l->tick(l);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
run()
|
||||
{
|
||||
timespec t;
|
||||
t.tv_sec = 0;
|
||||
t.tv_nsec = 10000UL;
|
||||
struct kevent events[1024];
|
||||
int result;
|
||||
byte_t readbuf[2048];
|
||||
do
|
||||
{
|
||||
result = kevent(kqueuefd, NULL, 0, events, 1024, NULL);
|
||||
result = kevent(kqueuefd, nullptr, 0, events, 1024, &t);
|
||||
// result: 0 is a timeout
|
||||
if(result > 0)
|
||||
{
|
||||
|
@ -161,7 +159,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop
|
|||
llarp::LogInfo("run error reading, should close ev");
|
||||
close_ev(ev);
|
||||
// ev->fd = 0;
|
||||
//delete ev;
|
||||
// delete ev;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
@ -241,9 +239,8 @@ struct llarp_kqueue_loop : public llarp_ev_loop
|
|||
bool
|
||||
close_ev(llarp::ev_io* ev)
|
||||
{
|
||||
// printf("closing_ev [%x] fd[%d]\n", ev, ev->fd);
|
||||
EV_SET(&change, ev->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
|
||||
return kevent(kqueuefd, &change, 1, NULL, 0, NULL) == -1;
|
||||
EV_SET(&change, ev->fd, EVFILT_READ, EV_DELETE, 0, 0, nullptr);
|
||||
return kevent(kqueuefd, &change, 1, nullptr, 0, nullptr) == -1;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -255,7 +252,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop
|
|||
llarp::udp_listener* listener = new llarp::udp_listener(fd, l);
|
||||
|
||||
EV_SET(&change, fd, EVFILT_READ, EV_ADD, 0, 0, listener);
|
||||
if(kevent(kqueuefd, &change, 1, NULL, 0, NULL) == -1)
|
||||
if(kevent(kqueuefd, &change, 1, nullptr, 0, nullptr) == -1)
|
||||
{
|
||||
l->impl = nullptr;
|
||||
delete listener;
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
#ifndef EV_WIN32_HPP
|
||||
#define EV_WIN32_HPP
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/net.h>
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
#include <llarp/net.hpp>
|
||||
#include "ev.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct udp_listener : public ev_io
|
||||
{
|
||||
llarp_udp_io* udp;
|
||||
|
||||
// we receive queued data in the OVERLAPPED data field,
|
||||
// much like the pipefds in the UNIX kqueue and loonix
|
||||
// epoll handles
|
||||
// 0 is the read port, 1 is the write port
|
||||
WSAOVERLAPPED portfds[2] = {0};
|
||||
size_t iosz;
|
||||
|
||||
// the unique completion key that helps us to
|
||||
// identify the object instance for which we receive data
|
||||
// Here, we'll use the address of the udp_listener instance, converted to
|
||||
// its literal int/int64 representation.
|
||||
ULONG_PTR listener_id = 0;
|
||||
|
||||
udp_listener(SOCKET fd, llarp_udp_io* u) : ev_io(fd), udp(u){};
|
||||
|
||||
~udp_listener()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
getData(void* buf, size_t sz, size_t ret)
|
||||
{
|
||||
iosz = ret;
|
||||
return read(buf, sz);
|
||||
}
|
||||
|
||||
virtual int
|
||||
read(void* buf, size_t sz)
|
||||
{
|
||||
sockaddr_in6 src;
|
||||
socklen_t slen = sizeof(src);
|
||||
sockaddr* addr = (sockaddr*)&src;
|
||||
unsigned long flags = 0;
|
||||
WSABUF wbuf = {sz, static_cast< char* >(buf)};
|
||||
// WSARecvFrom
|
||||
int ret = ::WSARecvFrom(fd, &wbuf, 1, nullptr, &flags, addr, &slen,
|
||||
&portfds[0], nullptr);
|
||||
// 997 is the error code for queued ops
|
||||
int s_errno = ::WSAGetLastError();
|
||||
if(ret && s_errno != 997)
|
||||
{
|
||||
llarp::LogWarn("recv socket error ", s_errno);
|
||||
return -1;
|
||||
}
|
||||
// get the _real_ payload size from tick()
|
||||
udp->recvfrom(udp, addr, buf, iosz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int
|
||||
sendto(const sockaddr* to, const void* data, size_t sz)
|
||||
{
|
||||
socklen_t slen;
|
||||
WSABUF wbuf = {sz, (char*)data};
|
||||
switch(to->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
slen = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
slen = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
// WSASendTo
|
||||
ssize_t sent =
|
||||
::WSASendTo(fd, &wbuf, 1, nullptr, 0, to, slen, &portfds[1], nullptr);
|
||||
int s_errno = ::WSAGetLastError();
|
||||
if(sent && s_errno != 997)
|
||||
{
|
||||
llarp::LogWarn("send socket error ", s_errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}; // namespace llarp
|
||||
|
||||
struct llarp_win32_loop : public llarp_ev_loop
|
||||
{
|
||||
HANDLE iocpfd;
|
||||
|
||||
llarp_win32_loop() : iocpfd(INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WSADATA wsockd;
|
||||
int err;
|
||||
// So, what I was told last time was that we can defer
|
||||
// loading winsock2 up to this point, as we reach this ctor
|
||||
// early on during daemon startup.
|
||||
err = ::WSAStartup(MAKEWORD(2, 2), &wsockd);
|
||||
if(err)
|
||||
perror("Failed to start Windows Sockets");
|
||||
}
|
||||
|
||||
~llarp_win32_loop()
|
||||
{
|
||||
if(iocpfd != INVALID_HANDLE_VALUE)
|
||||
::CloseHandle(iocpfd);
|
||||
|
||||
::WSACleanup();
|
||||
}
|
||||
|
||||
bool
|
||||
init()
|
||||
{
|
||||
if(iocpfd == INVALID_HANDLE_VALUE)
|
||||
iocpfd = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
|
||||
|
||||
if(iocpfd != INVALID_HANDLE_VALUE)
|
||||
return true; // we don't have a socket to attach to this IOCP yet
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// it works! -despair86, 3-Aug-18 @0420
|
||||
int
|
||||
tick(int ms)
|
||||
{
|
||||
// The only field we really care about is
|
||||
// the listener_id, as it contains the address
|
||||
// of the udp_listener instance.
|
||||
DWORD iolen = 0;
|
||||
// ULONG_PTR is guaranteed to be the same size
|
||||
// as an arch-specific pointer value
|
||||
ULONG_PTR ev_id = 0;
|
||||
WSAOVERLAPPED* qdata = nullptr;
|
||||
int result = 0;
|
||||
int idx = 0;
|
||||
byte_t readbuf[2048];
|
||||
|
||||
do
|
||||
{
|
||||
if(ev_id && qdata && iolen)
|
||||
{
|
||||
llarp::udp_listener* ev =
|
||||
reinterpret_cast< llarp::udp_listener* >(ev_id);
|
||||
if(ev && ev->fd)
|
||||
{
|
||||
if(ev->getData(readbuf, sizeof(readbuf), iolen) == -1)
|
||||
{
|
||||
llarp::LogInfo("tick close ev");
|
||||
close_ev(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
++idx;
|
||||
} while(::GetQueuedCompletionStatus(iocpfd, &iolen, &ev_id, &qdata, ms));
|
||||
|
||||
for(auto& l : udp_listeners)
|
||||
{
|
||||
if(l->tick)
|
||||
l->tick(l);
|
||||
}
|
||||
|
||||
if(!idx)
|
||||
return -1;
|
||||
else
|
||||
result = idx;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ok apparently this isn't being used yet...
|
||||
int
|
||||
run()
|
||||
{
|
||||
// The only field we really care about is
|
||||
// the listener_id, as it contains the address
|
||||
// of the udp_listener instance.
|
||||
DWORD iolen = 0;
|
||||
// ULONG_PTR is guaranteed to be the same size
|
||||
// as an arch-specific pointer value
|
||||
ULONG_PTR ev_id = 0;
|
||||
WSAOVERLAPPED* qdata = nullptr;
|
||||
int result = 0;
|
||||
int idx = 0;
|
||||
byte_t readbuf[2048];
|
||||
|
||||
// unlike epoll and kqueue, we only need to run so long as the
|
||||
// system call returns TRUE
|
||||
do
|
||||
{
|
||||
if(ev_id && qdata && iolen)
|
||||
{
|
||||
llarp::udp_listener* ev = reinterpret_cast< llarp::udp_listener* >(ev_id);
|
||||
if(ev && ev->fd)
|
||||
{
|
||||
if(ev->getData(readbuf, sizeof(readbuf), iolen) == -1)
|
||||
{
|
||||
llarp::LogInfo("close ev");
|
||||
close_ev(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
++idx;
|
||||
} while(::GetQueuedCompletionStatus(iocpfd, &iolen, &ev_id, &qdata, 10));
|
||||
|
||||
for(auto& l : udp_listeners)
|
||||
{
|
||||
if(l->tick)
|
||||
l->tick(l);
|
||||
}
|
||||
|
||||
if(!idx)
|
||||
return -1;
|
||||
else
|
||||
result = idx;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SOCKET
|
||||
udp_bind(const sockaddr* addr)
|
||||
{
|
||||
socklen_t slen;
|
||||
switch(addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
slen = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
slen = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
SOCKET fd = ::WSASocket(addr->sa_family, SOCK_DGRAM, 0, nullptr, 0,
|
||||
WSA_FLAG_OVERLAPPED);
|
||||
if(fd == INVALID_SOCKET)
|
||||
{
|
||||
perror("WSASocket()");
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if(addr->sa_family == AF_INET6)
|
||||
{
|
||||
// enable dual stack explicitly
|
||||
int dual = 1;
|
||||
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&dual,
|
||||
sizeof(dual))
|
||||
== -1)
|
||||
{
|
||||
// failed
|
||||
perror("setsockopt()");
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
llarp::Addr a(*addr);
|
||||
llarp::LogDebug("bind to ", a);
|
||||
if(bind(fd, addr, slen) == -1)
|
||||
{
|
||||
perror("bind()");
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
llarp::LogInfo("socket fd is ", fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
bool
|
||||
close_ev(llarp::ev_io* ev)
|
||||
{
|
||||
// On Windows, just close the socket to decrease the iocp refcount
|
||||
// and stop any pending I/O
|
||||
BOOL stopped = ::CancelIo(reinterpret_cast< HANDLE >(ev->fd));
|
||||
return closesocket(ev->fd) == 0 && stopped == TRUE;
|
||||
}
|
||||
|
||||
bool
|
||||
udp_listen(llarp_udp_io* l, const sockaddr* src)
|
||||
{
|
||||
SOCKET fd = udp_bind(src);
|
||||
llarp::LogDebug("new socket fd is ", fd);
|
||||
if(fd == INVALID_SOCKET)
|
||||
return false;
|
||||
llarp::udp_listener* listener = new llarp::udp_listener(fd, l);
|
||||
listener->listener_id = reinterpret_cast< ULONG_PTR >(listener);
|
||||
if(!::CreateIoCompletionPort(reinterpret_cast< HANDLE >(fd), iocpfd,
|
||||
listener->listener_id, 0))
|
||||
{
|
||||
delete listener;
|
||||
return false;
|
||||
}
|
||||
l->impl = listener;
|
||||
udp_listeners.push_back(l);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
udp_close(llarp_udp_io* l)
|
||||
{
|
||||
bool ret = false;
|
||||
llarp::udp_listener* listener =
|
||||
static_cast< llarp::udp_listener* >(l->impl);
|
||||
if(listener)
|
||||
{
|
||||
ret = close_ev(listener);
|
||||
l->impl = nullptr;
|
||||
delete listener;
|
||||
udp_listeners.remove(l);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
stop()
|
||||
{
|
||||
// do nothing, cancel io in close_ev()
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,4 +1,7 @@
|
|||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/exit_info.h>
|
||||
#include <llarp/mem.h>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/exit_route.h>
|
||||
#include <llarp/string.h>
|
||||
|
|
13
llarp/fs.hpp
13
llarp/fs.hpp
|
@ -8,15 +8,20 @@
|
|||
#endif
|
||||
|
||||
#include "filesystem.h"
|
||||
|
||||
// mingw32 in the only one that doesn't use cpp17::filesystem
|
||||
#if defined(__MINGW32__)
|
||||
#if defined(CPP17) && defined(USE_CXX17_FILESYSTEM)
|
||||
// win32 is the only one that doesn't use cpp17::filesystem
|
||||
// because cpp17::filesystem is unimplemented for Windows
|
||||
// -despair86
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#else
|
||||
namespace fs = std::filesystem;
|
||||
#endif // end win32
|
||||
#else
|
||||
// not CPP17 needs this
|
||||
// openbsd needs this
|
||||
// linux gcc 7.2 needs this
|
||||
namespace fs = cpp17::filesystem;
|
||||
#endif // end mingw32
|
||||
#endif
|
||||
|
||||
#endif // end LLARP_FS_HPP
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ini
|
|||
{
|
||||
struct Level
|
||||
{
|
||||
Level() : parent(NULL), depth(0)
|
||||
Level() : parent(nullptr), depth(0)
|
||||
{
|
||||
}
|
||||
Level(Level *p) : parent(p), depth(0)
|
||||
|
@ -156,7 +156,7 @@ namespace ini
|
|||
Parser::err(const char *s)
|
||||
{
|
||||
char buf[256];
|
||||
sprintf(buf, "%s on line #%ld", s, ln_);
|
||||
sprintf(buf, "%s on line #%d", s, ln_);
|
||||
throw std::runtime_error(buf);
|
||||
}
|
||||
|
||||
|
@ -210,8 +210,7 @@ namespace ini
|
|||
size_t depth;
|
||||
std::string sname;
|
||||
parseSLine(sname, depth);
|
||||
|
||||
Level *lp = NULL;
|
||||
Level *lp = nullptr;
|
||||
Level *parent = &l;
|
||||
if(depth > l.depth + 1)
|
||||
err("section with wrong depth");
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#ifdef _MSC_VER
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include "llarp/iwp/frame_state.hpp"
|
||||
#include "buffer.hpp"
|
||||
#include "llarp/crypto.hpp"
|
||||
|
@ -7,6 +11,7 @@
|
|||
#include "llarp/logger.hpp"
|
||||
#include "mem.hpp"
|
||||
#include "router.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
llarp_router *
|
||||
frame_state::Router()
|
||||
|
@ -21,17 +26,14 @@ frame_state::process_inbound_queue()
|
|||
InboundMessage::OrderCompare >
|
||||
q;
|
||||
recvqueue.Process(q);
|
||||
|
||||
uint64_t last = 0;
|
||||
while(q.size())
|
||||
{
|
||||
// TODO: is this right?
|
||||
auto &front = q.top();
|
||||
|
||||
if(front->msgid < nextMsgID && nextMsgID - front->msgid > 1)
|
||||
{
|
||||
// re-queue because of an ordering gap
|
||||
recvqueue.Put(front);
|
||||
}
|
||||
else
|
||||
if(last != front->msgid)
|
||||
{
|
||||
auto buffer = front->Buffer();
|
||||
if(!Router()->HandleRecvLinkMessage(parent, buffer))
|
||||
|
@ -39,12 +41,14 @@ frame_state::process_inbound_queue()
|
|||
llarp::LogWarn("failed to process inbound message ", front->msgid);
|
||||
llarp::DumpBuffer< llarp_buffer_t, 128 >(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextMsgID = std::max(front->msgid, nextMsgID + 1);
|
||||
}
|
||||
delete front;
|
||||
last = front->msgid;
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("duplicate inbound message ", last);
|
||||
}
|
||||
delete front;
|
||||
|
||||
q.pop();
|
||||
}
|
||||
// TODO: this isn't right
|
||||
|
|
|
@ -213,8 +213,8 @@ llarp_link::RemoveSession(llarp_link_session* s)
|
|||
UnmapAddr(s->addr);
|
||||
s->done();
|
||||
m_sessions.erase(itr);
|
||||
delete s;
|
||||
}
|
||||
delete s;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
#ifdef _MSC_VER
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <llarp/iwp.h>
|
||||
#include <algorithm>
|
||||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/iwp/server.hpp>
|
||||
#include <llarp/iwp/session.hpp>
|
||||
|
@ -463,7 +467,6 @@ static void
|
|||
handle_verify_session_start(iwp_async_session_start *s)
|
||||
{
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(s->user);
|
||||
self->serv->remove_intro_from(self->addr);
|
||||
if(!s->buf)
|
||||
{
|
||||
// verify fail
|
||||
|
@ -472,6 +475,7 @@ handle_verify_session_start(iwp_async_session_start *s)
|
|||
self->serv->RemoveSession(self);
|
||||
return;
|
||||
}
|
||||
self->serv->remove_intro_from(self->addr);
|
||||
self->send_LIM();
|
||||
self->working = false;
|
||||
}
|
||||
|
@ -520,7 +524,7 @@ handle_generated_intro(iwp_async_intro *i)
|
|||
}
|
||||
link->EnterState(llarp_link_session::eIntroSent);
|
||||
link->lastIntroSentAt = llarp_time_now_ms();
|
||||
auto dlt = (link->createdAt - link->lastIntroSentAt);
|
||||
auto dlt = (link->createdAt - link->lastIntroSentAt) + 500;
|
||||
auto logic = link->serv->logic;
|
||||
link->intro_resend_job_id = llarp_logic_call_later(
|
||||
logic, {dlt, link, &llarp_link_session::handle_introack_timeout});
|
||||
|
@ -649,6 +653,11 @@ llarp_link_session::on_session_start(const void *buf, size_t sz)
|
|||
llarp::LogDebug("session start too big");
|
||||
return;
|
||||
}
|
||||
if(working)
|
||||
{
|
||||
llarp::LogError("duplicate session start from ", addr);
|
||||
return;
|
||||
}
|
||||
// own the buffer
|
||||
memcpy(workbuf, buf, sz);
|
||||
// verify session start
|
||||
|
|
|
@ -12,8 +12,17 @@ namespace llarp
|
|||
}
|
||||
} // namespace llarp
|
||||
|
||||
void
|
||||
cSetLogLevel(LogLevel lvl)
|
||||
extern "C"
|
||||
{
|
||||
llarp::SetLogLevel((llarp::LogLevel)lvl);
|
||||
}
|
||||
void
|
||||
cSetLogLevel(LogLevel lvl)
|
||||
{
|
||||
llarp::SetLogLevel((llarp::LogLevel)lvl);
|
||||
}
|
||||
|
||||
void
|
||||
cSetLogNodeName(const char* name)
|
||||
{
|
||||
llarp::_glog.nodeName = name;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ namespace llarp
|
|||
DumpBuffer(const T &buff)
|
||||
{
|
||||
size_t idx = 0;
|
||||
printf("buffer of size %ld\n", buff.sz);
|
||||
printf("buffer of size %u\n", buff.sz);
|
||||
while(idx < buff.sz)
|
||||
{
|
||||
if(buff.base + idx == buff.cur)
|
||||
|
|
703
llarp/net.cpp
703
llarp/net.cpp
|
@ -2,13 +2,12 @@
|
|||
#include "str.hpp"
|
||||
#ifdef ANDROID
|
||||
#include "android/ifaddrs.h"
|
||||
#else
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <ifaddrs.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include "logger.hpp"
|
||||
|
||||
|
@ -42,6 +41,692 @@ operator<(const in6_addr& a, const in6_addr& b)
|
|||
return memcmp(&a, &b, sizeof(in6_addr)) < 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <strsafe.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
// current strategy: mingw 32-bit builds call an inlined version of the function
|
||||
// microsoft c++ and mingw 64-bit builds call the normal function
|
||||
#define DEFAULT_BUFFER_SIZE 15000
|
||||
|
||||
// the inline monkey patch for downlevel platforms
|
||||
#ifndef _MSC_VER
|
||||
extern "C" DWORD FAR PASCAL
|
||||
_GetAdaptersAddresses(ULONG Family, ULONG Flags, PVOID Reserved,
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
|
||||
PULONG pOutBufLen);
|
||||
#endif
|
||||
|
||||
// in any case, we still need to implement some form of
|
||||
// getifaddrs(3) with compatible semantics on NT...
|
||||
// daemon.ini section [bind] will have something like
|
||||
// [bind]
|
||||
// Ethernet=1090
|
||||
// inside, since that's what we use in windows to refer to
|
||||
// network interfaces
|
||||
struct llarp_nt_ifaddrs_t
|
||||
{
|
||||
struct llarp_nt_ifaddrs_t* ifa_next; /* Pointer to the next structure. */
|
||||
char* ifa_name; /* Name of this network interface. */
|
||||
unsigned int ifa_flags; /* Flags as from SIOCGIFFLAGS ioctl. */
|
||||
struct sockaddr* ifa_addr; /* Network address of this interface. */
|
||||
struct sockaddr* ifa_netmask; /* Netmask of this interface. */
|
||||
};
|
||||
|
||||
// internal struct
|
||||
struct _llarp_nt_ifaddrs_t
|
||||
{
|
||||
struct llarp_nt_ifaddrs_t _ifa;
|
||||
char _name[256];
|
||||
struct sockaddr_storage _addr;
|
||||
struct sockaddr_storage _netmask;
|
||||
};
|
||||
|
||||
static inline void*
|
||||
_llarp_nt_heap_alloc(const size_t n_bytes)
|
||||
{
|
||||
/* Does not appear very safe with re-entrant calls on XP */
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, n_bytes);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_llarp_nt_heap_free(void* mem)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, mem);
|
||||
}
|
||||
#define llarp_nt_new0(struct_type, n_structs) \
|
||||
((struct_type*)malloc((size_t)sizeof(struct_type) * (size_t)(n_structs)))
|
||||
|
||||
int
|
||||
llarp_nt_sockaddr_pton(const char* src, struct sockaddr* dst)
|
||||
{
|
||||
struct addrinfo hints = {0}, *result = nullptr;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
const int status = getaddrinfo(src, nullptr, &hints, &result);
|
||||
if(!status)
|
||||
{
|
||||
memcpy(dst, result->ai_addr, result->ai_addrlen);
|
||||
freeaddrinfo(result);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* NB: IP_ADAPTER_INFO size varies size due to sizeof (time_t), the API assumes
|
||||
* 4-byte datatype whilst compiler uses an 8-byte datatype. Size can be forced
|
||||
* with -D_USE_32BIT_TIME_T with side effects to everything else.
|
||||
*
|
||||
* Only supports IPv4 addressing similar to SIOCGIFCONF socket option.
|
||||
*
|
||||
* Interfaces that are not "operationally up" will return the address 0.0.0.0,
|
||||
* this includes adapters with static IP addresses but with disconnected cable.
|
||||
* This is documented under the GetIpAddrTable API. Interface status can only
|
||||
* be determined by the address, a separate flag is introduced with the
|
||||
* GetAdapterAddresses API.
|
||||
*
|
||||
* The IPv4 loopback interface is not included.
|
||||
*
|
||||
* Available in Windows 2000 and Wine 1.0.
|
||||
*/
|
||||
static bool
|
||||
_llarp_nt_getadaptersinfo(struct llarp_nt_ifaddrs_t** ifap)
|
||||
{
|
||||
DWORD dwRet;
|
||||
ULONG ulOutBufLen = DEFAULT_BUFFER_SIZE;
|
||||
PIP_ADAPTER_INFO pAdapterInfo = nullptr;
|
||||
PIP_ADAPTER_INFO pAdapter = nullptr;
|
||||
|
||||
/* loop to handle interfaces coming online causing a buffer overflow
|
||||
* between first call to list buffer length and second call to enumerate.
|
||||
*/
|
||||
for(unsigned i = 3; i; i--)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "IP_ADAPTER_INFO buffer length %lu bytes.\n", ulOutBufLen);
|
||||
#endif
|
||||
pAdapterInfo = (IP_ADAPTER_INFO*)_llarp_nt_heap_alloc(ulOutBufLen);
|
||||
dwRet = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
|
||||
if(ERROR_BUFFER_OVERFLOW == dwRet)
|
||||
{
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
pAdapterInfo = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(dwRet)
|
||||
{
|
||||
case ERROR_SUCCESS: /* NO_ERROR */
|
||||
break;
|
||||
case ERROR_BUFFER_OVERFLOW:
|
||||
errno = ENOBUFS;
|
||||
if(pAdapterInfo)
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
return false;
|
||||
default:
|
||||
errno = dwRet;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "system call failed: %lu\n", GetLastError());
|
||||
#endif
|
||||
if(pAdapterInfo)
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* count valid adapters */
|
||||
int n = 0, k = 0;
|
||||
for(pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next)
|
||||
{
|
||||
for(IP_ADDR_STRING* pIPAddr = &pAdapter->IpAddressList; pIPAddr;
|
||||
pIPAddr = pIPAddr->Next)
|
||||
{
|
||||
/* skip null adapters */
|
||||
if(strlen(pIPAddr->IpAddress.String) == 0)
|
||||
continue;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "GetAdaptersInfo() discovered %d interfaces.\n", n);
|
||||
#endif
|
||||
|
||||
/* contiguous block for adapter list */
|
||||
struct _llarp_nt_ifaddrs_t* ifa =
|
||||
llarp_nt_new0(struct _llarp_nt_ifaddrs_t, n);
|
||||
struct _llarp_nt_ifaddrs_t* ift = ifa;
|
||||
|
||||
/* now populate list */
|
||||
for(pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next)
|
||||
{
|
||||
for(IP_ADDR_STRING* pIPAddr = &pAdapter->IpAddressList; pIPAddr;
|
||||
pIPAddr = pIPAddr->Next)
|
||||
{
|
||||
/* skip null adapters */
|
||||
if(strlen(pIPAddr->IpAddress.String) == 0)
|
||||
continue;
|
||||
|
||||
/* address */
|
||||
ift->_ifa.ifa_addr = (struct sockaddr*)&ift->_addr;
|
||||
assert(1 == llarp_nt_sockaddr_pton(pIPAddr->IpAddress.String,ift->_ifa.ifa_addr));
|
||||
|
||||
/* name */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "name:%s IPv4 index:%lu\n", pAdapter->AdapterName,
|
||||
pAdapter->Index);
|
||||
#endif
|
||||
ift->_ifa.ifa_name = ift->_name;
|
||||
StringCchCopyN(ift->_ifa.ifa_name, 128, pAdapter->AdapterName, 128);
|
||||
|
||||
/* flags: assume up, broadcast and multicast */
|
||||
ift->_ifa.ifa_flags = IFF_UP | IFF_BROADCAST | IFF_MULTICAST;
|
||||
if(pAdapter->Type == MIB_IF_TYPE_LOOPBACK)
|
||||
ift->_ifa.ifa_flags |= IFF_LOOPBACK;
|
||||
|
||||
/* netmask */
|
||||
ift->_ifa.ifa_netmask = (sockaddr*)&ift->_netmask;
|
||||
assert(1 == llarp_nt_sockaddr_pton(pIPAddr->IpMask.String, ift->_ifa.ifa_netmask));
|
||||
|
||||
/* next */
|
||||
if(k++ < (n - 1))
|
||||
{
|
||||
ift->_ifa.ifa_next = (struct llarp_nt_ifaddrs_t*)(ift + 1);
|
||||
ift = (struct _llarp_nt_ifaddrs_t*)(ift->_ifa.ifa_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pAdapterInfo)
|
||||
_llarp_nt_heap_free(pAdapterInfo);
|
||||
*ifap = (struct llarp_nt_ifaddrs_t*)ifa;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Supports both IPv4 and IPv6 addressing. The size of IP_ADAPTER_ADDRESSES
|
||||
* changes between Windows XP, XP SP1, and Vista with additional members.
|
||||
*
|
||||
* Interfaces that are not "operationally up" will typically return a host
|
||||
* IP address with the defined IPv4 link-local prefix 169.254.0.0/16.
|
||||
* Adapters with a static configured IP address but down will return both
|
||||
* the IPv4 link-local prefix and the static address.
|
||||
*
|
||||
* It is easier to say "not up" rather than "down" as this API returns six
|
||||
* effective down status values: down, testing, unknown, dormant, not present,
|
||||
* and lower layer down.
|
||||
*
|
||||
* Available in Windows XP and Wine 1.3.
|
||||
*
|
||||
* NOTE(despair): an inline implementation is provided, much like
|
||||
* getaddrinfo(3) for old hosts. See "win32_intrnl.*"
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
static bool
|
||||
_llarp_nt_getadaptersaddresses(struct llarp_nt_ifaddrs_t** ifap)
|
||||
{
|
||||
DWORD dwSize = DEFAULT_BUFFER_SIZE, dwRet;
|
||||
IP_ADAPTER_ADDRESSES *pAdapterAddresses = nullptr, *adapter;
|
||||
|
||||
/* loop to handle interfaces coming online causing a buffer overflow
|
||||
* between first call to list buffer length and second call to enumerate.
|
||||
*/
|
||||
for(unsigned i = 3; i; i--)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "IP_ADAPTER_ADDRESSES buffer length %lu bytes.\n", dwSize);
|
||||
#endif
|
||||
pAdapterAddresses = (IP_ADAPTER_ADDRESSES*)_llarp_nt_heap_alloc(dwSize);
|
||||
#if defined(_MSC_VER) || defined(_WIN64)
|
||||
dwRet = GetAdaptersAddresses(AF_UNSPEC,
|
||||
/* requires Windows XP SP1 */
|
||||
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST
|
||||
| GAA_FLAG_SKIP_DNS_SERVER
|
||||
| GAA_FLAG_SKIP_FRIENDLY_NAME
|
||||
| GAA_FLAG_SKIP_MULTICAST,
|
||||
nullptr, pAdapterAddresses, &dwSize);
|
||||
#else
|
||||
dwRet = _GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST
|
||||
| GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME
|
||||
| GAA_FLAG_SKIP_MULTICAST,
|
||||
nullptr, pAdapterAddresses, &dwSize);
|
||||
#endif
|
||||
if(ERROR_BUFFER_OVERFLOW == dwRet)
|
||||
{
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
pAdapterAddresses = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(dwRet)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
break;
|
||||
case ERROR_BUFFER_OVERFLOW:
|
||||
errno = ENOBUFS;
|
||||
if(pAdapterAddresses)
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
return FALSE;
|
||||
default:
|
||||
errno = _doserrno;
|
||||
if(pAdapterAddresses)
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* count valid adapters */
|
||||
int n = 0, k = 0;
|
||||
for(adapter = pAdapterAddresses; adapter; adapter = adapter->Next)
|
||||
{
|
||||
for(IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress;
|
||||
unicast; unicast = unicast->Next)
|
||||
{
|
||||
/* ensure IP adapter */
|
||||
if(AF_INET != unicast->Address.lpSockaddr->sa_family
|
||||
&& AF_INET6 != unicast->Address.lpSockaddr->sa_family)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
/* contiguous block for adapter list */
|
||||
struct _llarp_nt_ifaddrs_t* ifa =
|
||||
llarp_nt_new0(struct _llarp_nt_ifaddrs_t, n);
|
||||
struct _llarp_nt_ifaddrs_t* ift = ifa;
|
||||
|
||||
/* now populate list */
|
||||
for(adapter = pAdapterAddresses; adapter; adapter = adapter->Next)
|
||||
{
|
||||
int unicastIndex = 0;
|
||||
for(IP_ADAPTER_UNICAST_ADDRESS *unicast = adapter->FirstUnicastAddress;
|
||||
unicast; unicast = unicast->Next, ++unicastIndex)
|
||||
{
|
||||
/* ensure IP adapter */
|
||||
if(AF_INET != unicast->Address.lpSockaddr->sa_family
|
||||
&& AF_INET6 != unicast->Address.lpSockaddr->sa_family)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* address */
|
||||
ift->_ifa.ifa_addr = (sockaddr*)&ift->_addr;
|
||||
memcpy(ift->_ifa.ifa_addr, unicast->Address.lpSockaddr,
|
||||
unicast->Address.iSockaddrLength);
|
||||
|
||||
/* name */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "name:%s IPv4 index:%lu IPv6 index:%lu\n",
|
||||
adapter->AdapterName, adapter->IfIndex, adapter->Ipv6IfIndex);
|
||||
#endif
|
||||
ift->_ifa.ifa_name = ift->_name;
|
||||
StringCchCopyN(ift->_ifa.ifa_name, 256, adapter->AdapterName, 256);
|
||||
|
||||
/* flags */
|
||||
ift->_ifa.ifa_flags = 0;
|
||||
if(IfOperStatusUp == adapter->OperStatus)
|
||||
ift->_ifa.ifa_flags |= IFF_UP;
|
||||
if(IF_TYPE_SOFTWARE_LOOPBACK == adapter->IfType)
|
||||
ift->_ifa.ifa_flags |= IFF_LOOPBACK;
|
||||
if(!(adapter->Flags & IP_ADAPTER_NO_MULTICAST))
|
||||
ift->_ifa.ifa_flags |= IFF_MULTICAST;
|
||||
|
||||
/* netmask */
|
||||
ift->_ifa.ifa_netmask = (sockaddr*)&ift->_netmask;
|
||||
|
||||
/* pre-Vista must hunt for matching prefix in linked list, otherwise use
|
||||
* OnLinkPrefixLength from IP_ADAPTER_UNICAST_ADDRESS structure.
|
||||
* FirstPrefix requires Windows XP SP1, from SP1 to pre-Vista provides a
|
||||
* single adapter prefix for each IP address. Vista and later provides
|
||||
* host IP address prefix, subnet IP address, and subnet broadcast IP
|
||||
* address. In addition there is a multicast and broadcast address
|
||||
* prefix.
|
||||
*/
|
||||
ULONG prefixLength = 0;
|
||||
|
||||
#if defined(_WIN32) && (_WIN32_WINNT >= 0x0600)
|
||||
/* For a unicast IPv4 address, any value greater than 32 is an illegal
|
||||
* value. For a unicast IPv6 address, any value greater than 128 is an
|
||||
* illegal value. A value of 255 is commonly used to represent an illegal
|
||||
* value.
|
||||
*
|
||||
* Windows 7 SP1 returns 64 for Teredo links which is incorrect.
|
||||
*/
|
||||
|
||||
#define IN6_IS_ADDR_TEREDO(addr) \
|
||||
(((const uint32_t*)(addr))[0] == ntohl(0x20010000))
|
||||
|
||||
if(AF_INET6 == unicast->Address.lpSockaddr->sa_family &&
|
||||
/* TunnelType only applies to one interface on the adapter and no
|
||||
* convenient method is provided to determine which.
|
||||
*/
|
||||
TUNNEL_TYPE_TEREDO == adapter->TunnelType &&
|
||||
/* Test the interface with the known Teredo network prefix.
|
||||
*/
|
||||
IN6_IS_ADDR_TEREDO(
|
||||
&((struct sockaddr_in6*)(unicast->Address.lpSockaddr))->sin6_addr)
|
||||
&&
|
||||
/* Test that this version is actually wrong, subsequent releases from
|
||||
* Microsoft may resolve the issue.
|
||||
*/
|
||||
32 != unicast->OnLinkPrefixLength)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"IPv6 Teredo tunneling adapter %s prefix length is an "
|
||||
"illegal value %lu, overriding to 32.\n",
|
||||
adapter->AdapterName, unicast->OnLinkPrefixLength);
|
||||
#endif
|
||||
prefixLength = 32;
|
||||
}
|
||||
else
|
||||
prefixLength = unicast->OnLinkPrefixLength;
|
||||
#else
|
||||
/* The order of linked IP_ADAPTER_UNICAST_ADDRESS structures pointed to by
|
||||
* the FirstUnicastAddress member does not have any relationship with the
|
||||
* order of linked IP_ADAPTER_PREFIX structures pointed to by the
|
||||
* FirstPrefix member.
|
||||
*
|
||||
* Example enumeration:
|
||||
* [ no subnet ]
|
||||
* ::1/128 - address
|
||||
* ff00::%1/8 - multicast (no IPv6 broadcast)
|
||||
* 127.0.0.0/8 - subnet
|
||||
* 127.0.0.1/32 - address
|
||||
* 127.255.255.255/32 - subnet broadcast
|
||||
* 224.0.0.0/4 - multicast
|
||||
* 255.255.255.255/32 - broadcast
|
||||
*
|
||||
* Which differs from most adapters listing three IPv6:
|
||||
* fe80::%10/64 - subnet
|
||||
* fe80::51e9:5fe5:4202:325a%10/128 - address
|
||||
* ff00::%10/8 - multicast
|
||||
*
|
||||
* !IfOperStatusUp IPv4 addresses are skipped:
|
||||
* fe80::%13/64 - subnet
|
||||
* fe80::d530:946d:e8df:8c91%13/128 - address
|
||||
* ff00::%13/8 - multicast
|
||||
* [ no subnet ]
|
||||
* [ no address ]
|
||||
* 224.0.0.0/4 - multicast
|
||||
* 255.255.255.255/32 - broadcast
|
||||
*
|
||||
* On PTP links no multicast or broadcast addresses are returned:
|
||||
* [ no subnet ]
|
||||
* fe80::5efe:10.203.9.30/128 - address
|
||||
* [ no multicast ]
|
||||
* [ no multicast ]
|
||||
* [ no broadcast ]
|
||||
*
|
||||
* Active primary IPv6 interfaces are a bit overloaded:
|
||||
* ::/0 - default route
|
||||
* 2001::/32 - global subnet
|
||||
* 2001:0:4137:9e76:2443:d6:ba87:1a2a/128 - global address
|
||||
* fe80::/64 - link-local subnet
|
||||
* fe80::2443:d6:ba87:1a2a/128 - link-local address
|
||||
* ff00::/8 - multicast
|
||||
*/
|
||||
|
||||
#define IN_LINKLOCAL(a) ((((uint32_t)(a)) & 0xaffff0000) == 0xa9fe0000)
|
||||
|
||||
for(IP_ADAPTER_PREFIX* prefix = adapter->FirstPrefix; prefix;
|
||||
prefix = prefix->Next)
|
||||
{
|
||||
LPSOCKADDR lpSockaddr = prefix->Address.lpSockaddr;
|
||||
if(lpSockaddr->sa_family != unicast->Address.lpSockaddr->sa_family)
|
||||
continue;
|
||||
/* special cases */
|
||||
/* RFC2863: IPv4 interface not up */
|
||||
if(AF_INET == lpSockaddr->sa_family
|
||||
&& adapter->OperStatus != IfOperStatusUp)
|
||||
{
|
||||
/* RFC3927: link-local IPv4 always has 16-bit CIDR */
|
||||
if(IN_LINKLOCAL(
|
||||
ntohl(((struct sockaddr_in*)(unicast->Address.lpSockaddr))
|
||||
->sin_addr.s_addr)))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"Assuming 16-bit prefix length for link-local IPv4 "
|
||||
"adapter %s.\n",
|
||||
adapter->AdapterName);
|
||||
#endif
|
||||
prefixLength = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Prefix length unavailable for IPv4 adapter %s.\n",
|
||||
adapter->AdapterName);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* default IPv6 route */
|
||||
if(AF_INET6 == lpSockaddr->sa_family && 0 == prefix->PrefixLength
|
||||
&& IN6_IS_ADDR_UNSPECIFIED(
|
||||
&((struct sockaddr_in6*)(lpSockaddr))->sin6_addr))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"Ingoring unspecified address prefix on IPv6 adapter %s.\n",
|
||||
adapter->AdapterName);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
/* Assume unicast address for first prefix of operational adapter */
|
||||
if(AF_INET == lpSockaddr->sa_family)
|
||||
assert(!IN_MULTICAST(
|
||||
ntohl(((struct sockaddr_in*)(lpSockaddr))->sin_addr.s_addr)));
|
||||
if(AF_INET6 == lpSockaddr->sa_family)
|
||||
assert(!IN6_IS_ADDR_MULTICAST(
|
||||
&((struct sockaddr_in6*)(lpSockaddr))->sin6_addr));
|
||||
/* Assume subnet or host IP address for XP backward compatibility */
|
||||
|
||||
prefixLength = prefix->PrefixLength;
|
||||
break;
|
||||
}
|
||||
#endif /* defined( _WIN32 ) && ( _WIN32_WINNT >= 0x0600 ) */
|
||||
|
||||
/* map prefix to netmask */
|
||||
ift->_ifa.ifa_netmask->sa_family = unicast->Address.lpSockaddr->sa_family;
|
||||
switch(unicast->Address.lpSockaddr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
if(0 == prefixLength || prefixLength > 32)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"IPv4 adapter %s prefix length is an illegal value "
|
||||
"%lu, overriding to 32.\n",
|
||||
adapter->AdapterName, prefixLength);
|
||||
#endif
|
||||
prefixLength = 32;
|
||||
}
|
||||
/* NB: left-shift of full bit-width is undefined in C standard. */
|
||||
((struct sockaddr_in*)ift->_ifa.ifa_netmask)->sin_addr.s_addr =
|
||||
htonl(0xffffffffU << (32 - prefixLength));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
if(0 == prefixLength || prefixLength > 128)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
"IPv6 adapter %s prefix length is an illegal value "
|
||||
"%lu, overriding to 128.\n",
|
||||
adapter->AdapterName, prefixLength);
|
||||
#endif
|
||||
prefixLength = 128;
|
||||
}
|
||||
for(LONG i = prefixLength, j = 0; i > 0; i -= 8, ++j)
|
||||
{
|
||||
((struct sockaddr_in6*)ift->_ifa.ifa_netmask)
|
||||
->sin6_addr.s6_addr[j] =
|
||||
i >= 8 ? 0xff : (ULONG)((0xffU << (8 - i)) & 0xffU);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* next */
|
||||
if(k++ < (n - 1))
|
||||
{
|
||||
ift->_ifa.ifa_next = (struct llarp_nt_ifaddrs_t*)(ift + 1);
|
||||
ift = (struct _llarp_nt_ifaddrs_t*)(ift->_ifa.ifa_next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pAdapterAddresses)
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
*ifap = (struct llarp_nt_ifaddrs_t*)ifa;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// an implementation of if_nametoindex(3) based on GetAdapterIndex(2)
|
||||
// with a fallback to GetAdaptersAddresses(2) commented out for now
|
||||
// unless it becomes evident that the first codepath fails in certain
|
||||
// edge cases?
|
||||
static unsigned
|
||||
_llarp_nt_getadaptersaddresses_nametoindex(const char* ifname)
|
||||
{
|
||||
ULONG ifIndex;
|
||||
DWORD /* dwSize = 4096,*/ dwRet;
|
||||
// IP_ADAPTER_ADDRESSES *pAdapterAddresses = nullptr, *adapter;
|
||||
char szAdapterName[256];
|
||||
|
||||
if(!ifname)
|
||||
return 0;
|
||||
|
||||
StringCchCopyN(szAdapterName, sizeof(szAdapterName), ifname, 256);
|
||||
dwRet = GetAdapterIndex((LPWSTR)szAdapterName, &ifIndex);
|
||||
|
||||
if(!dwRet)
|
||||
return ifIndex;
|
||||
else
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
/* fallback to finding index via iterating adapter list */
|
||||
|
||||
/* loop to handle interfaces coming online causing a buffer overflow
|
||||
* between first call to list buffer length and second call to enumerate.
|
||||
*/
|
||||
for(unsigned i = 3; i; i--)
|
||||
{
|
||||
pAdapterAddresses = (IP_ADAPTER_ADDRESSES*)_llarp_nt_heap_alloc(dwSize);
|
||||
#ifdef _MSC_VER
|
||||
dwRet = GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER
|
||||
| GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_MULTICAST,
|
||||
nullptr, pAdapterAddresses, &dwSize);
|
||||
#else
|
||||
dwRet = _GetAdaptersAddresses(
|
||||
AF_UNSPEC,
|
||||
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER
|
||||
| GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_MULTICAST,
|
||||
nullptr, pAdapterAddresses, &dwSize);
|
||||
#endif
|
||||
|
||||
if(ERROR_BUFFER_OVERFLOW == dwRet)
|
||||
{
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
pAdapterAddresses = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(dwRet)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
break;
|
||||
case ERROR_BUFFER_OVERFLOW:
|
||||
errno = ENOBUFS;
|
||||
if(pAdapterAddresses)
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
return 0;
|
||||
default:
|
||||
errno = _doserrno;
|
||||
if(pAdapterAddresses)
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(adapter = pAdapterAddresses; adapter; adapter = adapter->Next)
|
||||
{
|
||||
if(0 == strcmp(szAdapterName, adapter->AdapterName))
|
||||
{
|
||||
//ifIndex = AF_INET6 == iffamily ? adapter->Ipv6IfIndex : adapter->IfIndex;
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
return ifIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if(pAdapterAddresses)
|
||||
_llarp_nt_heap_free(pAdapterAddresses);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// the emulated getifaddrs(3) itself.
|
||||
static bool
|
||||
llarp_nt_getifaddrs(struct llarp_nt_ifaddrs_t** ifap)
|
||||
{
|
||||
assert(nullptr != ifap);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "llarp_nt_getifaddrs (ifap:%p error:%p)\n", (void*)ifap,(void*)errno);
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
return _llarp_nt_getadaptersaddresses(ifap);
|
||||
#else
|
||||
return _llarp_nt_getadaptersinfo(ifap);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
llarp_nt_freeifaddrs(struct llarp_nt_ifaddrs_t* ifa)
|
||||
{
|
||||
if(!ifa)
|
||||
return;
|
||||
free(ifa);
|
||||
}
|
||||
|
||||
// emulated if_nametoindex(3)
|
||||
static unsigned
|
||||
llarp_nt_if_nametoindex(const char* ifname)
|
||||
{
|
||||
if(!ifname)
|
||||
return 0;
|
||||
return _llarp_nt_getadaptersaddresses_nametoindex(ifname);
|
||||
}
|
||||
|
||||
// fix up names for win32
|
||||
#define ifaddrs llarp_nt_ifaddrs_t
|
||||
#define getifaddrs llarp_nt_getifaddrs
|
||||
#define freeifaddrs llarp_nt_freeifaddrs
|
||||
#define if_nametoindex llarp_nt_if_nametoindex
|
||||
#endif
|
||||
|
||||
// jeff's original code
|
||||
bool
|
||||
llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
|
||||
{
|
||||
|
@ -51,7 +736,11 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
|
|||
if(af == AF_INET)
|
||||
sl = sizeof(sockaddr_in);
|
||||
|
||||
#ifndef _WIN32
|
||||
if(getifaddrs(&ifa) == -1)
|
||||
#else
|
||||
if(!getifaddrs(&ifa))
|
||||
#endif
|
||||
return false;
|
||||
ifaddrs* i = ifa;
|
||||
while(i)
|
||||
|
@ -86,7 +775,6 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
|
|||
freeifaddrs(ifa);
|
||||
return found;
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
bool
|
||||
|
@ -94,8 +782,11 @@ namespace llarp
|
|||
{
|
||||
ifaddrs* ifa = nullptr;
|
||||
bool found = false;
|
||||
|
||||
#ifndef _WIN32
|
||||
if(getifaddrs(&ifa) == -1)
|
||||
#else
|
||||
if(!getifaddrs(&ifa))
|
||||
#endif
|
||||
return false;
|
||||
ifaddrs* i = ifa;
|
||||
while(i)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "mem.hpp"
|
||||
|
||||
static const char skiplist_subdirs[] = "0123456789abcdef";
|
||||
static const std::string RC_FILE_EXT = ".signed";
|
||||
|
||||
struct llarp_nodedb
|
||||
{
|
||||
|
@ -21,7 +22,7 @@ struct llarp_nodedb
|
|||
|
||||
llarp_crypto *crypto;
|
||||
// std::map< llarp::pubkey, llarp_rc > entries;
|
||||
std::unordered_map< llarp::PubKey, llarp_rc, llarp::PubKeyHash > entries;
|
||||
std::unordered_map< llarp::PubKey, llarp_rc, llarp::PubKey::Hash > entries;
|
||||
fs::path nodePath;
|
||||
|
||||
void
|
||||
|
@ -38,11 +39,11 @@ struct llarp_nodedb
|
|||
llarp_rc *
|
||||
getRC(const llarp::PubKey &pk)
|
||||
{
|
||||
return &entries[pk];
|
||||
return &entries.at(pk);
|
||||
}
|
||||
|
||||
bool
|
||||
Has(const llarp::PubKey &pk)
|
||||
Has(const llarp::PubKey &pk) const
|
||||
{
|
||||
return entries.find(pk) != entries.end();
|
||||
}
|
||||
|
@ -66,7 +67,7 @@ struct llarp_nodedb
|
|||
*/
|
||||
|
||||
bool
|
||||
pubKeyExists(llarp_rc *rc)
|
||||
pubKeyExists(llarp_rc *rc) const
|
||||
{
|
||||
// extract pk from rc
|
||||
llarp::PubKey pk = rc->pubkey;
|
||||
|
@ -85,6 +86,8 @@ struct llarp_nodedb
|
|||
llarp::PubKey pk = rc->pubkey;
|
||||
|
||||
// TODO: zero out any fields you don't want to compare
|
||||
// XXX: make a copy and then do modifications on the copy
|
||||
// touching external data in here is HARAM >:[
|
||||
|
||||
// serialize both and memcmp
|
||||
byte_t nodetmp[MAX_RC_SIZE];
|
||||
|
@ -103,19 +106,17 @@ struct llarp_nodedb
|
|||
}
|
||||
|
||||
std::string
|
||||
getRCFilePath(const byte_t *pubkey)
|
||||
getRCFilePath(const byte_t *pubkey) const
|
||||
{
|
||||
char ftmp[68] = {0};
|
||||
const char *hexname =
|
||||
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(pubkey, ftmp);
|
||||
std::string hexString(hexname);
|
||||
std::string filepath = nodePath;
|
||||
filepath.append(PATH_SEP);
|
||||
filepath.append(&hexString[hexString.length() - 1]);
|
||||
filepath.append(PATH_SEP);
|
||||
filepath.append(hexname);
|
||||
filepath.append(".signed");
|
||||
return filepath;
|
||||
hexString += RC_FILE_EXT;
|
||||
std::string skiplistDir;
|
||||
skiplistDir += hexString[hexString.length() - 1];
|
||||
fs::path filepath = nodePath / skiplistDir / hexString;
|
||||
return filepath.string();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -166,6 +167,8 @@ struct llarp_nodedb
|
|||
|
||||
for(const char &ch : skiplist_subdirs)
|
||||
{
|
||||
if(!ch)
|
||||
continue;
|
||||
std::string p;
|
||||
p += ch;
|
||||
fs::path sub = path / p;
|
||||
|
@ -182,7 +185,7 @@ struct llarp_nodedb
|
|||
{
|
||||
ssize_t sz = 0;
|
||||
fs::directory_iterator i(dir);
|
||||
#if __has_include(<filesystem>) && !defined(__OpenBSD__)
|
||||
#if defined(CPP17) && defined(USE_CXX17_FILESYSTEM)
|
||||
auto itr = fs::begin(i);
|
||||
while(itr != fs::end(i))
|
||||
#else
|
||||
|
@ -190,7 +193,7 @@ struct llarp_nodedb
|
|||
while(itr != itr.end())
|
||||
#endif
|
||||
{
|
||||
if(fs::is_regular_file(itr->symlink_status()) && loadfile(*itr))
|
||||
if(fs::is_regular_file(itr->path()) && loadfile(*itr))
|
||||
sz++;
|
||||
|
||||
++itr;
|
||||
|
@ -201,16 +204,12 @@ struct llarp_nodedb
|
|||
bool
|
||||
loadfile(const fs::path &fpath)
|
||||
{
|
||||
#if __APPLE__ && __MACH__
|
||||
// skip .DS_Store files
|
||||
if(strstr(fpath.c_str(), ".DS_Store") != 0)
|
||||
{
|
||||
if(fpath.extension() != RC_FILE_EXT)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
llarp_rc rc;
|
||||
llarp_rc_clear(&rc);
|
||||
if(!llarp_rc_read(fpath.c_str(), &rc))
|
||||
|
||||
if(!llarp_rc_read(fpath.string().c_str(), &rc))
|
||||
{
|
||||
llarp::LogError("Signature read failed", fpath);
|
||||
return false;
|
||||
|
@ -287,7 +286,7 @@ crypto_threadworker_verifyrc(void *user)
|
|||
verify_request->valid =
|
||||
llarp_rc_verify_sig(verify_request->nodedb->crypto, &verify_request->rc);
|
||||
// if it's valid we need to set it
|
||||
if(verify_request->valid)
|
||||
if(verify_request->valid && llarp_rc_is_public_router(&verify_request->rc))
|
||||
{
|
||||
llarp::LogDebug("RC is valid, saving to disk");
|
||||
llarp_threadpool_queue_job(verify_request->diskworker,
|
||||
|
@ -296,7 +295,8 @@ crypto_threadworker_verifyrc(void *user)
|
|||
else
|
||||
{
|
||||
// callback to logic thread
|
||||
llarp::LogWarn("RC is not valid, can't save to disk");
|
||||
if(!verify_request->valid)
|
||||
llarp::LogWarn("RC is not valid, can't save to disk");
|
||||
llarp_logic_queue_job(verify_request->logic,
|
||||
{verify_request, &logic_threadworker_callback});
|
||||
}
|
||||
|
@ -347,6 +347,7 @@ llarp_nodedb_ensure_dir(const char *dir)
|
|||
{
|
||||
fs::path path(dir);
|
||||
std::error_code ec;
|
||||
|
||||
if(!fs::exists(dir, ec))
|
||||
fs::create_directories(path, ec);
|
||||
|
||||
|
@ -358,6 +359,11 @@ llarp_nodedb_ensure_dir(const char *dir)
|
|||
|
||||
for(const char &ch : skiplist_subdirs)
|
||||
{
|
||||
// this seems to be a problem on all targets
|
||||
// perhaps cpp17::fs is just as screwed-up
|
||||
// attempting to create a folder with no name
|
||||
if(!ch)
|
||||
return true;
|
||||
std::string p;
|
||||
p += ch;
|
||||
fs::path sub = path / p;
|
||||
|
@ -435,7 +441,8 @@ void
|
|||
llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
|
||||
struct llarp_rc *result, size_t N)
|
||||
{
|
||||
/// TODO: check for "guard" status for N = 0?
|
||||
/// checking for "guard" status for N = 0 is done by caller inside of
|
||||
/// pathbuilder's scope
|
||||
auto sz = n->entries.size();
|
||||
|
||||
if(prev)
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "buffer.hpp"
|
||||
#include "router.hpp"
|
||||
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace path
|
||||
|
@ -463,6 +462,14 @@ namespace llarp
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Path::HandleHiddenServiceFrame(const llarp::service::ProtocolFrame* frame)
|
||||
{
|
||||
if(m_DataHandler)
|
||||
return m_DataHandler(frame);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Path::HandlePathLatencyMessage(
|
||||
const llarp::routing::PathLatencyMessage* msg, llarp_router* r)
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace llarp
|
|||
user = u;
|
||||
result = func;
|
||||
worker = pool;
|
||||
LRCM = new LR_CommitMessage;
|
||||
LRCM = new LR_CommitMessage();
|
||||
|
||||
for(size_t idx = 0; idx < MAXHOPS; ++idx)
|
||||
{
|
||||
|
@ -187,6 +187,7 @@ llarp_pathbuilder_context::llarp_pathbuilder_context(
|
|||
: llarp::path::PathSet(pathNum), router(p_router), dht(p_dht), numHops(hops)
|
||||
{
|
||||
p_router->paths.AddPathBuilder(this);
|
||||
p_router->crypto.encryption_keygen(enckey);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -200,6 +201,12 @@ llarp_pathbuilder_context::SelectHop(llarp_nodedb* db, llarp_rc* prev,
|
|||
return true;
|
||||
}
|
||||
|
||||
byte_t*
|
||||
llarp_pathbuilder_context::GetTunnelEncryptionSecretKey()
|
||||
{
|
||||
return enckey;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_pathbuilder_context::BuildOne()
|
||||
{
|
||||
|
|
|
@ -46,7 +46,27 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PathSet::GetPathByRouter(const RouterID& id)
|
||||
PathSet::GetEstablishedPathClosestTo(const AlignedBuffer< 32 >& id) const
|
||||
{
|
||||
Path* path = nullptr;
|
||||
AlignedBuffer< 32 > dist;
|
||||
dist.Fill(0xff);
|
||||
for(const auto& item : m_Paths)
|
||||
{
|
||||
if(!item.second->IsReady())
|
||||
continue;
|
||||
AlignedBuffer< 32 > localDist = item.second->Endpoint() ^ id;
|
||||
if(localDist < dist)
|
||||
{
|
||||
dist = localDist;
|
||||
path = item.second;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
Path*
|
||||
PathSet::GetPathByRouter(const RouterID& id) const
|
||||
{
|
||||
auto itr = m_Paths.begin();
|
||||
while(itr != m_Paths.end())
|
||||
|
@ -89,7 +109,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PathSet::GetByUpstream(const RouterID& remote, const PathID_t& rxid)
|
||||
PathSet::GetByUpstream(const RouterID& remote, const PathID_t& rxid) const
|
||||
{
|
||||
auto itr = m_Paths.find({remote, rxid});
|
||||
if(itr == m_Paths.end())
|
||||
|
@ -125,7 +145,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
Path*
|
||||
PathSet::PickRandomEstablishedPath()
|
||||
PathSet::PickRandomEstablishedPath() const
|
||||
{
|
||||
std::vector< Path* > established;
|
||||
auto itr = m_Paths.begin();
|
||||
|
|
|
@ -166,7 +166,7 @@ llarp_router::try_connect(fs::path rcfile)
|
|||
{
|
||||
llarp_rc remote;
|
||||
llarp_rc_new(&remote);
|
||||
if(!llarp_rc_read(rcfile.c_str(), &remote))
|
||||
if(!llarp_rc_read(rcfile.string().c_str(), &remote))
|
||||
{
|
||||
llarp::LogError("failure to decode or verify of remote RC");
|
||||
return;
|
||||
|
@ -196,14 +196,15 @@ llarp_router::EnsureIdentity()
|
|||
{
|
||||
if(!EnsureEncryptionKey())
|
||||
return false;
|
||||
return llarp_findOrCreateIdentity(&crypto, ident_keyfile.c_str(), identity);
|
||||
return llarp_findOrCreateIdentity(&crypto, ident_keyfile.string().c_str(),
|
||||
identity);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_router::EnsureEncryptionKey()
|
||||
{
|
||||
return llarp_findOrCreateEncryption(&crypto, encryption_keyfile.c_str(),
|
||||
&this->encryption);
|
||||
return llarp_findOrCreateEncryption(
|
||||
&crypto, encryption_keyfile.string().c_str(), &this->encryption);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -233,15 +234,16 @@ llarp_router::SaveRC()
|
|||
|
||||
if(llarp_rc_bencode(&rc, &buf))
|
||||
{
|
||||
std::ofstream f(our_rc_file);
|
||||
std::ofstream f(our_rc_file.string());
|
||||
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)buf.base, buf.cur - buf.base);
|
||||
llarp::LogInfo("our RC saved to ", our_rc_file.c_str());
|
||||
llarp::LogInfo("our RC saved to ", our_rc_file.string().c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
llarp::LogError("did not save RC to ", our_rc_file.c_str());
|
||||
llarp::LogError("did not save RC to ", our_rc_file.string().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -384,7 +386,6 @@ llarp_router::Tick()
|
|||
paths.TickPaths();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llarp_router::SendTo(llarp::RouterID remote, const llarp::ILinkMessage *msg,
|
||||
llarp_link *link)
|
||||
|
@ -500,8 +501,8 @@ llarp_router::on_try_connect_result(llarp_link_establish_job *job)
|
|||
if(job->session)
|
||||
{
|
||||
// llarp::LogDebug("try_connect got session");
|
||||
auto session = job->session;
|
||||
router->async_verify_RC(session->get_remote_router(), false, job);
|
||||
// auto session = job->session;
|
||||
// router->async_verify_RC(session->get_remote_router(), false, job);
|
||||
return;
|
||||
}
|
||||
// llarp::LogDebug("try_connect no session");
|
||||
|
@ -574,20 +575,16 @@ llarp_router::async_verify_RC(llarp_rc *rc, bool isExpectingClient,
|
|||
job->hook = &llarp_router::on_verify_client_rc;
|
||||
else
|
||||
job->hook = &llarp_router::on_verify_server_rc;
|
||||
|
||||
llarp_nodedb_async_verify(job);
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
llarp_router::Run()
|
||||
{
|
||||
// zero out router contact
|
||||
llarp::Zero(&rc, sizeof(llarp_rc));
|
||||
// fill our address list
|
||||
rc.addrs = llarp_ai_list_new();
|
||||
bool publicFound = false;
|
||||
rc.addrs = llarp_ai_list_new();
|
||||
|
||||
sockaddr *dest = (sockaddr *)&this->ip4addr;
|
||||
llarp::Addr publicAddr(*dest);
|
||||
|
@ -596,7 +593,6 @@ llarp_router::Run()
|
|||
if(publicAddr)
|
||||
{
|
||||
llarp::LogInfo("public address:port ", publicAddr);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -609,17 +605,8 @@ llarp_router::Run()
|
|||
if(this->publicOverride && a.sameAddr(publicAddr))
|
||||
{
|
||||
llarp::LogInfo("Found adapter for public address");
|
||||
publicFound = true;
|
||||
}
|
||||
if(a.isPrivate())
|
||||
{
|
||||
if(!this->publicOverride)
|
||||
{
|
||||
llarp::LogWarn("Skipping private network link: ", a);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(!a.isPrivate())
|
||||
{
|
||||
llarp::LogInfo("Loading Addr: ", a, " into our RC");
|
||||
llarp_ai_list_pushback(rc.addrs, &addr);
|
||||
|
@ -758,11 +745,7 @@ llarp_router::InitOutboundLink()
|
|||
return true;
|
||||
|
||||
llarp_iwp_args args = {
|
||||
.crypto = &crypto,
|
||||
.logic = logic,
|
||||
.cryptoworker = tp,
|
||||
.router = this,
|
||||
.keyfile = transport_keyfile.c_str(),
|
||||
&crypto, logic, tp, this, transport_keyfile.string().c_str(),
|
||||
};
|
||||
|
||||
auto link = new(std::nothrow) llarp_link(args);
|
||||
|
@ -915,7 +898,9 @@ llarp_rc_read(const char *fpath, llarp_rc *result)
|
|||
printf("File[%s] not found\n", fpath);
|
||||
return false;
|
||||
}
|
||||
std::ifstream f(our_rc_file, std::ios::binary);
|
||||
|
||||
std::ifstream f(our_rc_file.string(), std::ios::binary);
|
||||
|
||||
if(!f.is_open())
|
||||
{
|
||||
printf("Can't open file [%s]\n", fpath);
|
||||
|
@ -935,7 +920,7 @@ llarp_rc_read(const char *fpath, llarp_rc *result)
|
|||
llarp::Zero(result, sizeof(llarp_rc));
|
||||
if(!llarp_rc_bdecode(result, &buf))
|
||||
{
|
||||
printf("Can't decode [%s]\n", fpath);
|
||||
llarp::LogError("Can't decode ", fpath);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -969,7 +954,7 @@ llarp_rc_write(struct llarp_rc *rc, const char *fpath)
|
|||
|
||||
if(llarp_rc_bencode(rc, &buf))
|
||||
{
|
||||
std::ofstream f(our_rc_file, std::ios::binary);
|
||||
std::ofstream f(our_rc_file.string(), std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)buf.base, buf.cur - buf.base);
|
||||
|
@ -1041,13 +1026,13 @@ llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
|
|||
{
|
||||
llarp::LogInfo("generating new identity key");
|
||||
crypto->identity_keygen(secretkey);
|
||||
std::ofstream f(path, std::ios::binary);
|
||||
std::ofstream f(path.string(), std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)secretkey, SECKEYSIZE);
|
||||
}
|
||||
}
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
std::ifstream f(path.string(), std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.read((char *)secretkey, SECKEYSIZE);
|
||||
|
@ -1069,13 +1054,14 @@ llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
|
|||
{
|
||||
llarp::LogInfo("generating new encryption key");
|
||||
crypto->encryption_keygen(*encryption);
|
||||
std::ofstream f(path, std::ios::binary);
|
||||
std::ofstream f(path.string(), std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)encryption, SECKEYSIZE);
|
||||
}
|
||||
}
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
|
||||
std::ifstream f(path.string(), std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.read((char *)encryption, SECKEYSIZE);
|
||||
|
@ -1132,12 +1118,13 @@ namespace llarp
|
|||
if(!StrEq(key, "*"))
|
||||
{
|
||||
llarp::LogInfo("interface specific binding activated");
|
||||
|
||||
llarp_iwp_args args = {
|
||||
.crypto = &self->crypto,
|
||||
.logic = self->logic,
|
||||
.cryptoworker = self->tp,
|
||||
.router = self,
|
||||
.keyfile = self->transport_keyfile.c_str(),
|
||||
&self->crypto,
|
||||
self->logic,
|
||||
self->tp,
|
||||
self,
|
||||
self->transport_keyfile.string().c_str(),
|
||||
};
|
||||
|
||||
link = new(std::nothrow) llarp_link(args);
|
||||
|
@ -1190,6 +1177,16 @@ namespace llarp
|
|||
}
|
||||
else if(StrEq(section, "router"))
|
||||
{
|
||||
if(StrEq(key, "nickname"))
|
||||
{
|
||||
if(llarp_rc_set_nickname(&self->rc, val))
|
||||
{
|
||||
// set logger name here
|
||||
_glog.nodeName = self->rc.Nick();
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("failed to set nickname to ", val);
|
||||
}
|
||||
if(StrEq(key, "encryption-privkey"))
|
||||
{
|
||||
self->encryption_keyfile = val;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <llarp/crypto.hpp>
|
||||
#include "buffer.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "mem.hpp"
|
||||
|
||||
bool
|
||||
llarp_rc_new(struct llarp_rc *rc)
|
||||
|
@ -11,6 +12,7 @@ llarp_rc_new(struct llarp_rc *rc)
|
|||
rc->addrs = llarp_ai_list_new();
|
||||
rc->exits = llarp_xi_list_new();
|
||||
rc->last_updated = 0;
|
||||
llarp::Zero(rc->nickname, sizeof(rc->nickname));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,6 +64,17 @@ llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
|
|||
return true;
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "n"))
|
||||
{
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz > sizeof(rc->nickname))
|
||||
return false;
|
||||
llarp::Zero(rc->nickname, sizeof(rc->nickname));
|
||||
memcpy(rc->nickname, strbuf.base, strbuf.sz);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "p"))
|
||||
{
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
|
@ -115,6 +128,14 @@ llarp_rc_is_public_router(const struct llarp_rc *const rc)
|
|||
return rc->addrs && llarp_ai_list_size(rc->addrs) > 0;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_set_nickname(struct llarp_rc *rc, const char *nick)
|
||||
{
|
||||
strncpy((char *)rc->nickname, nick, sizeof(rc->nickname));
|
||||
/// TODO: report nickname truncation
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src)
|
||||
{
|
||||
|
@ -135,6 +156,7 @@ llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src)
|
|||
dst->exits = llarp_xi_list_new();
|
||||
llarp_xi_list_copy(dst->exits, src->exits);
|
||||
}
|
||||
memcpy(dst->nickname, src->nickname, sizeof(dst->nickname));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -198,6 +220,14 @@ llarp_rc_bencode(const struct llarp_rc *rc, llarp_buffer_t *buff)
|
|||
if(!bencode_write_bytestring(buff, rc->pubkey, PUBKEYSIZE))
|
||||
return false;
|
||||
|
||||
/* write nickname */
|
||||
if(!bencode_write_bytestring(buff, "n", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(
|
||||
buff, rc->nickname,
|
||||
strnlen((char *)rc->nickname, sizeof(rc->nickname))))
|
||||
return false;
|
||||
|
||||
/* write encryption pubkey */
|
||||
if(!bencode_write_bytestring(buff, "p", 1))
|
||||
return false;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#ifdef _MSC_VER
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <llarp/service.hpp>
|
||||
#include "buffer.hpp"
|
||||
#include "fs.hpp"
|
||||
|
|
|
@ -11,5 +11,15 @@ namespace llarp
|
|||
std::string str = Base32Encode(*this, tmp);
|
||||
return str + ".loki";
|
||||
}
|
||||
|
||||
bool
|
||||
Address::FromString(const std::string& str)
|
||||
{
|
||||
auto pos = str.find(".loki");
|
||||
if(pos == std::string::npos)
|
||||
return false;
|
||||
auto sub = str.substr(0, pos);
|
||||
return Base32Decode(sub, *this);
|
||||
}
|
||||
} // namespace service
|
||||
} // namespace llarp
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#include <llarp/dht/messages/findintro.hpp>
|
||||
#include <llarp/messages/dht.hpp>
|
||||
#include <llarp/service/endpoint.hpp>
|
||||
|
@ -31,6 +32,12 @@ namespace llarp
|
|||
{
|
||||
m_PrefetchTags.insert(v);
|
||||
}
|
||||
if(k == "prefetch-addr")
|
||||
{
|
||||
Address addr;
|
||||
if(addr.FromString(v))
|
||||
m_PrefetchAddrs.insert(addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -47,6 +54,7 @@ namespace llarp
|
|||
{
|
||||
if(context)
|
||||
{
|
||||
llarp::LogInfo("BEEP");
|
||||
byte_t tmp[128] = {0};
|
||||
memcpy(tmp, "BEEP", 4);
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
|
@ -109,6 +117,22 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
|
||||
for(const auto& addr : m_PrefetchAddrs)
|
||||
{
|
||||
if(!HasPathToService(addr))
|
||||
{
|
||||
PathAlignJob* j = new PathAlignJob(addr);
|
||||
if(!EnsurePathToService(j->remote,
|
||||
std::bind(&PathAlignJob::HandleResult, j,
|
||||
std::placeholders::_1),
|
||||
10000))
|
||||
{
|
||||
llarp::LogWarn("failed to ensure path to ", addr);
|
||||
delete j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prefetch tags
|
||||
for(const auto& tag : m_PrefetchTags)
|
||||
{
|
||||
|
@ -116,7 +140,8 @@ namespace llarp
|
|||
if(itr == m_PrefetchedTags.end())
|
||||
{
|
||||
itr = m_PrefetchedTags
|
||||
.insert(std::make_pair(tag, CachedTagResult(tag, now)))
|
||||
.insert(std::make_pair(
|
||||
tag, CachedTagResult(this, tag, GenTXID())))
|
||||
.first;
|
||||
}
|
||||
for(const auto& introset : itr->second.result)
|
||||
|
@ -126,7 +151,11 @@ namespace llarp
|
|||
std::bind(&PathAlignJob::HandleResult, j,
|
||||
std::placeholders::_1),
|
||||
10000))
|
||||
{
|
||||
llarp::LogWarn("failed to ensure path to ", introset.A.Addr(),
|
||||
" for tag");
|
||||
delete j;
|
||||
}
|
||||
}
|
||||
itr->second.Expire(now);
|
||||
if(itr->second.ShouldRefresh(now))
|
||||
|
@ -134,8 +163,7 @@ namespace llarp
|
|||
auto path = PickRandomEstablishedPath();
|
||||
if(path)
|
||||
{
|
||||
itr->second.pendingTX = GenTXID();
|
||||
m_PendingLookups[itr->second.pendingTX] = &itr->second;
|
||||
itr->second.txid = GenTXID();
|
||||
itr->second.SendRequestViaPath(path, m_Router);
|
||||
}
|
||||
}
|
||||
|
@ -172,6 +200,18 @@ namespace llarp
|
|||
return m_Name + ":" + m_Identity.pub.Name();
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::HasPathToService(const Address& addr) const
|
||||
{
|
||||
return m_RemoteSessions.find(addr) != m_RemoteSessions.end();
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::PutLookup(IServiceLookup* lookup, uint64_t txid)
|
||||
{
|
||||
m_PendingLookups.insert(std::make_pair(txid, lookup));
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg)
|
||||
{
|
||||
|
@ -245,7 +285,7 @@ namespace llarp
|
|||
{
|
||||
auto now = llarp_time_now_ms();
|
||||
|
||||
pendingTX = 0;
|
||||
txid = 0;
|
||||
for(const auto& introset : introsets)
|
||||
if(result.insert(introset).second)
|
||||
lastModified = now;
|
||||
|
@ -279,21 +319,22 @@ namespace llarp
|
|||
Endpoint::CachedTagResult::BuildRequestMessage()
|
||||
{
|
||||
llarp::routing::DHTMessage* msg = new llarp::routing::DHTMessage();
|
||||
msg->M.push_back(new llarp::dht::FindIntroMessage(tag, pendingTX));
|
||||
msg->M.push_back(new llarp::dht::FindIntroMessage(tag, txid));
|
||||
lastRequest = llarp_time_now_ms();
|
||||
parent->PutLookup(this, txid);
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::PublishIntroSet(llarp_router* r)
|
||||
{
|
||||
auto path = PickRandomEstablishedPath();
|
||||
auto path = GetEstablishedPathClosestTo(m_Identity.pub.Addr());
|
||||
if(path)
|
||||
{
|
||||
m_CurrentPublishTX = llarp_randint();
|
||||
llarp::routing::DHTMessage msg;
|
||||
msg.M.push_back(new llarp::dht::PublishIntroMessage(
|
||||
m_IntroSet, m_CurrentPublishTX, 3));
|
||||
m_IntroSet, m_CurrentPublishTX, 4));
|
||||
if(path->SendRoutingMessage(&msg, r))
|
||||
{
|
||||
m_LastPublishAttempt = llarp_time_now_ms();
|
||||
|
@ -301,7 +342,7 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
}
|
||||
llarp::LogWarn(Name(), " publish introset failed");
|
||||
llarp::LogWarn(Name(), " publish introset failed, no path");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -332,12 +373,11 @@ namespace llarp
|
|||
|
||||
struct HiddenServiceAddressLookup : public IServiceLookup
|
||||
{
|
||||
Endpoint* endpoint;
|
||||
Address remote;
|
||||
uint64_t txid;
|
||||
HiddenServiceAddressLookup(Endpoint* parent, const Address& addr,
|
||||
uint64_t tx)
|
||||
: endpoint(parent), remote(addr), txid(tx)
|
||||
Endpoint* endpoint;
|
||||
|
||||
HiddenServiceAddressLookup(Endpoint* p, const Address& addr, uint64_t tx)
|
||||
: IServiceLookup(p, tx), remote(addr), endpoint(p)
|
||||
{
|
||||
llarp::LogInfo("New hidden service lookup for ", addr.ToString());
|
||||
}
|
||||
|
@ -392,16 +432,52 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::HandlePathBuilt(path::Path* p)
|
||||
{
|
||||
p->SetDataHandler(std::bind(&Endpoint::HandleHiddenServiceFrame, this,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::HandleHiddenServiceFrame(const ProtocolFrame* frame)
|
||||
{
|
||||
llarp::LogInfo("handle hidden service frame");
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::OutboundContext::HandlePathBuilt(path::Path* p)
|
||||
{
|
||||
p->SetDataHandler(
|
||||
std::bind(&Endpoint::OutboundContext::HandleHiddenServiceFrame, this,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::OutboundContext::PutLookup(IServiceLookup* lookup, uint64_t txid)
|
||||
{
|
||||
m_Parent->PutLookup(lookup, txid);
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::OutboundContext::HandleHiddenServiceFrame(
|
||||
const ProtocolFrame* frame)
|
||||
{
|
||||
return m_Parent->HandleHiddenServiceFrame(frame);
|
||||
}
|
||||
|
||||
bool
|
||||
Endpoint::EnsurePathToService(const Address& remote, PathEnsureHook hook,
|
||||
llarp_time_t timeoutMS)
|
||||
{
|
||||
auto path = PickRandomEstablishedPath();
|
||||
auto path = GetEstablishedPathClosestTo(remote);
|
||||
if(!path)
|
||||
{
|
||||
llarp::LogWarn("No outbound path for lookup yet");
|
||||
return false;
|
||||
}
|
||||
llarp::LogInfo(Name(), " Ensure Path to ", remote.ToString());
|
||||
{
|
||||
auto itr = m_RemoteSessions.find(remote);
|
||||
if(itr != m_RemoteSessions.end())
|
||||
|
@ -414,15 +490,15 @@ namespace llarp
|
|||
if(itr != m_PendingServiceLookups.end())
|
||||
{
|
||||
// duplicate
|
||||
llarp::LogWarn("duplicate pending service lookup to ",
|
||||
remote.ToString());
|
||||
return false;
|
||||
}
|
||||
llarp::LogInfo(Name(), " Ensure Path to ", remote.ToString());
|
||||
|
||||
m_PendingServiceLookups.insert(std::make_pair(remote, hook));
|
||||
|
||||
HiddenServiceAddressLookup* job =
|
||||
new HiddenServiceAddressLookup(this, remote, GenTXID());
|
||||
m_PendingLookups.insert(std::make_pair(job->txid, job));
|
||||
|
||||
return job->SendRequestViaPath(path, Router());
|
||||
}
|
||||
|
@ -459,20 +535,30 @@ namespace llarp
|
|||
Endpoint::OutboundContext::HandleGotIntroMessage(
|
||||
const llarp::dht::GotIntroMessage* msg)
|
||||
{
|
||||
if(msg->T != m_UpdateIntrosetTX)
|
||||
{
|
||||
llarp::LogError("unwarrented introset message txid=", msg->T);
|
||||
return false;
|
||||
}
|
||||
auto crypto = m_Parent->Crypto();
|
||||
if(msg->I.size() == 1)
|
||||
{
|
||||
// found intro set
|
||||
auto itr = msg->I.begin();
|
||||
if(itr->VerifySignature(crypto) && currentIntroSet.A == itr->A)
|
||||
const auto& introset = msg->I[0];
|
||||
if(introset.VerifySignature(crypto) && currentIntroSet.A == introset.A)
|
||||
{
|
||||
currentIntroSet = *itr;
|
||||
// update
|
||||
currentIntroSet = introset;
|
||||
// reset tx
|
||||
m_UpdateIntrosetTX = 0;
|
||||
// shift to newest intro
|
||||
// TODO: check timestamp on introset to make sure it's new enough
|
||||
ShiftIntroduction();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogError("Signature Error for intro set ", *itr);
|
||||
llarp::LogError("Signature Error for intro set ", introset);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -575,7 +661,7 @@ namespace llarp
|
|||
transfer.Y.Randomize();
|
||||
transfer.P = selectedIntro.pathID;
|
||||
llarp::LogInfo("sending frame via ", path->Upstream(), " to ",
|
||||
path->Endpoint());
|
||||
path->Endpoint(), " for ", Name());
|
||||
path->SendRoutingMessage(&transfer, m_Parent->Router());
|
||||
}
|
||||
else
|
||||
|
@ -584,17 +670,27 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Endpoint::OutboundContext::Name() const
|
||||
{
|
||||
return "OBContext:" + m_Parent->Name() + "-"
|
||||
+ currentIntroSet.A.Addr().ToString();
|
||||
}
|
||||
|
||||
void
|
||||
Endpoint::OutboundContext::UpdateIntroSet()
|
||||
{
|
||||
auto path = PickRandomEstablishedPath();
|
||||
auto path = GetEstablishedPathClosestTo(currentIntroSet.A.Addr());
|
||||
if(path)
|
||||
{
|
||||
uint64_t txid = llarp_randint();
|
||||
routing::DHTMessage msg;
|
||||
msg.M.push_back(
|
||||
new llarp::dht::FindIntroMessage(currentIntroSet.A.Addr(), txid));
|
||||
path->SendRoutingMessage(&msg, m_Parent->Router());
|
||||
if(m_UpdateIntrosetTX == 0)
|
||||
{
|
||||
m_UpdateIntrosetTX = llarp_randint();
|
||||
routing::DHTMessage msg;
|
||||
msg.M.push_back(new llarp::dht::FindIntroMessage(
|
||||
currentIntroSet.A.Addr(), m_UpdateIntrosetTX));
|
||||
path->SendRoutingMessage(&msg, m_Parent->Router());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
#include <llarp/path.hpp>
|
||||
#include <llarp/service/endpoint.hpp>
|
||||
#include <llarp/service/lookup.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace service
|
||||
{
|
||||
IServiceLookup::IServiceLookup(ILookupHolder *p, uint64_t tx)
|
||||
: parent(p), txid(tx)
|
||||
{
|
||||
p->PutLookup(this, tx);
|
||||
}
|
||||
|
||||
bool
|
||||
IServiceLookup::SendRequestViaPath(llarp::path::Path *path, llarp_router *r)
|
||||
{
|
||||
|
|
|
@ -17,8 +17,9 @@ namespace llarp
|
|||
bool
|
||||
ProtocolMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
// TODO: implement me
|
||||
return false;
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "threadpool.hpp"
|
||||
#ifndef _MSC_VER
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <cstring>
|
||||
|
||||
#include <llarp/time.h>
|
||||
|
@ -11,6 +13,12 @@
|
|||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
extern "C" void
|
||||
SetThreadName(DWORD dwThreadID, LPCSTR szThreadName);
|
||||
#endif
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace thread
|
||||
|
@ -27,8 +35,10 @@ namespace llarp
|
|||
pthread_setname_np(name);
|
||||
#elif(__FreeBSD__) || (__OpenBSD__) || (__NetBSD__)
|
||||
pthread_set_name_np(pthread_self(), name);
|
||||
#else
|
||||
#elif !defined(_MSC_VER) || !defined(_WIN32)
|
||||
pthread_setname_np(pthread_self(), name);
|
||||
#else
|
||||
SetThreadName(GetCurrentThreadId(), name);
|
||||
#endif
|
||||
}
|
||||
for(;;)
|
||||
|
@ -93,6 +103,7 @@ struct llarp_threadpool
|
|||
{
|
||||
llarp::thread::Pool *impl;
|
||||
|
||||
std::mutex m_access;
|
||||
std::queue< llarp_thread_job * > jobs;
|
||||
|
||||
llarp_threadpool(int workers, const char *name)
|
||||
|
@ -159,8 +170,16 @@ llarp_threadpool_queue_job(struct llarp_threadpool *pool,
|
|||
{
|
||||
if(pool->impl)
|
||||
pool->impl->QueueJob(job);
|
||||
else
|
||||
pool->jobs.push(new llarp_thread_job(job));
|
||||
else if(job.user && job.work)
|
||||
{
|
||||
auto j = new llarp_thread_job;
|
||||
j->work = job.work;
|
||||
j->user = job.user;
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(pool->m_access);
|
||||
pool->jobs.push(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -168,11 +187,14 @@ llarp_threadpool_tick(struct llarp_threadpool *pool)
|
|||
{
|
||||
while(pool->jobs.size())
|
||||
{
|
||||
auto &job = pool->jobs.front();
|
||||
if(job && job->work && job->user)
|
||||
job->work(job->user);
|
||||
llarp_thread_job *job;
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(pool->m_access);
|
||||
job = pool->jobs.front();
|
||||
pool->jobs.pop();
|
||||
}
|
||||
job->work(job->user);
|
||||
delete job;
|
||||
pool->jobs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
/*
|
||||
* Contains routines missing from WS2_32.DLL until 2006, if yer using
|
||||
* Microsoft C/C++, then this code is irrelevant, as the official
|
||||
* Platform SDK already links against these routines in the correct
|
||||
* libraries.
|
||||
*
|
||||
* -despair86 30/07/18
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <llarp/net.h>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#include "win32_intrnl.h"
|
||||
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
int address_length;
|
||||
DWORD string_length = size;
|
||||
struct sockaddr_storage sa;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
address_length = sizeof(struct sockaddr_in);
|
||||
sin->sin_family = af;
|
||||
memcpy(&sin->sin_addr, src, sizeof(struct in_addr));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
address_length = sizeof(struct sockaddr_in6);
|
||||
sin6->sin6_family = af;
|
||||
memcpy(&sin6->sin6_addr, src, sizeof(struct in6_addr));
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(WSAAddressToString((LPSOCKADDR)&sa, address_length, NULL, dst,
|
||||
&string_length)
|
||||
== 0)
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
int address_length;
|
||||
struct sockaddr_storage sa;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
|
||||
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
address_length = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
address_length = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(WSAStringToAddress((LPTSTR)src, af, NULL, (LPSOCKADDR)&sa, &address_length)
|
||||
== 0)
|
||||
{
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
memcpy(dst, &sin->sin_addr, sizeof(struct in_addr));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
memcpy(dst, &sin6->sin6_addr, sizeof(struct in6_addr));
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _InterfaceIndexTable
|
||||
{
|
||||
DWORD numIndexes;
|
||||
IF_INDEX indexes[1];
|
||||
} InterfaceIndexTable;
|
||||
|
||||
// windows 2000
|
||||
// todo(despair86): implement IPv6 detection using
|
||||
// the ipv6 preview stack/adv net pack from 1999/2001
|
||||
DWORD FAR PASCAL
|
||||
_GetAdaptersAddresses(ULONG Family, ULONG Flags, PVOID Reserved,
|
||||
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
|
||||
PULONG pOutBufLen)
|
||||
{
|
||||
InterfaceIndexTable *indexTable;
|
||||
IFInfo ifInfo;
|
||||
int i;
|
||||
ULONG ret, requiredSize = 0;
|
||||
PIP_ADAPTER_ADDRESSES currentAddress;
|
||||
PUCHAR currentLocation;
|
||||
HANDLE tcpFile;
|
||||
|
||||
if(!pOutBufLen)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if(Reserved)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
indexTable = getInterfaceIndexTable();
|
||||
if(!indexTable)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
ret = openTcpFile(&tcpFile, FILE_READ_DATA);
|
||||
if(!NT_SUCCESS(ret))
|
||||
return ERROR_NO_DATA;
|
||||
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
/* The whole struct */
|
||||
requiredSize += sizeof(IP_ADAPTER_ADDRESSES);
|
||||
|
||||
/* Friendly name */
|
||||
if(!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||
requiredSize +=
|
||||
strlen((char *)ifInfo.if_info.ent.if_descr) + 1; // FIXME
|
||||
|
||||
/* Adapter name */
|
||||
requiredSize += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||
|
||||
/* Unicast address */
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
requiredSize += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
|
||||
/* FIXME: Implement dns suffix and description */
|
||||
requiredSize += 2 * sizeof(WCHAR);
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "size: %ld, requiredSize: %ld\n", *pOutBufLen, requiredSize);
|
||||
#endif
|
||||
if(!pAdapterAddresses || *pOutBufLen < requiredSize)
|
||||
{
|
||||
*pOutBufLen = requiredSize;
|
||||
closeTcpFile(tcpFile);
|
||||
free(indexTable);
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
RtlZeroMemory(pAdapterAddresses, requiredSize);
|
||||
|
||||
/* Let's set up the pointers */
|
||||
currentAddress = pAdapterAddresses;
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
currentLocation =
|
||||
(PUCHAR)currentAddress + (ULONG_PTR)sizeof(IP_ADAPTER_ADDRESSES);
|
||||
|
||||
/* FIXME: Friendly name */
|
||||
if(!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
||||
{
|
||||
currentAddress->FriendlyName = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Adapter name */
|
||||
currentAddress->AdapterName = (PVOID)currentLocation;
|
||||
currentLocation += strlen((char *)ifInfo.if_info.ent.if_descr) + 1;
|
||||
|
||||
/* Unicast address */
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
{
|
||||
currentAddress->FirstUnicastAddress = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
currentAddress->FirstUnicastAddress->Address.lpSockaddr =
|
||||
(PVOID)currentLocation;
|
||||
currentLocation += sizeof(struct sockaddr);
|
||||
}
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
|
||||
/* FIXME: Implement dns suffix and description */
|
||||
currentAddress->DnsSuffix = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
|
||||
currentAddress->Description = (PVOID)currentLocation;
|
||||
currentLocation += sizeof(WCHAR);
|
||||
|
||||
currentAddress->Next = (PVOID)currentLocation;
|
||||
/* Terminate the last address correctly */
|
||||
if(i == 0)
|
||||
currentAddress->Next = NULL;
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now again, for real this time */
|
||||
|
||||
currentAddress = pAdapterAddresses;
|
||||
for(i = indexTable->numIndexes; i >= 0; i--)
|
||||
{
|
||||
if(NT_SUCCESS(
|
||||
getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
||||
{
|
||||
/* Make sure we're not looping more than we hoped for */
|
||||
assert(currentAddress);
|
||||
|
||||
/* Alignment information */
|
||||
currentAddress->Length = sizeof(IP_ADAPTER_ADDRESSES);
|
||||
currentAddress->IfIndex = indexTable->indexes[i];
|
||||
|
||||
/* Adapter name */
|
||||
strcpy(currentAddress->AdapterName, (char *)ifInfo.if_info.ent.if_descr);
|
||||
|
||||
if(!(Flags & GAA_FLAG_SKIP_UNICAST))
|
||||
{
|
||||
currentAddress->FirstUnicastAddress->Length =
|
||||
sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
currentAddress->FirstUnicastAddress->Flags = 0; // FIXME
|
||||
currentAddress->FirstUnicastAddress->Next =
|
||||
NULL; // FIXME: Support more than one address per adapter
|
||||
currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_family =
|
||||
AF_INET;
|
||||
memcpy(currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_data,
|
||||
&ifInfo.ip_addr.iae_addr, sizeof(ifInfo.ip_addr.iae_addr));
|
||||
currentAddress->FirstUnicastAddress->Address.iSockaddrLength =
|
||||
sizeof(ifInfo.ip_addr.iae_addr) + sizeof(USHORT);
|
||||
currentAddress->FirstUnicastAddress->PrefixOrigin =
|
||||
IpPrefixOriginOther; // FIXME
|
||||
currentAddress->FirstUnicastAddress->SuffixOrigin =
|
||||
IpPrefixOriginOther; // FIXME
|
||||
currentAddress->FirstUnicastAddress->DadState =
|
||||
IpDadStatePreferred; // FIXME
|
||||
currentAddress->FirstUnicastAddress->ValidLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
currentAddress->FirstUnicastAddress->PreferredLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
currentAddress->FirstUnicastAddress->LeaseLifetime =
|
||||
0xFFFFFFFF; // FIXME
|
||||
}
|
||||
|
||||
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
||||
currentAddress->FirstAnycastAddress = NULL;
|
||||
currentAddress->FirstMulticastAddress = NULL;
|
||||
currentAddress->FirstDnsServerAddress = NULL;
|
||||
|
||||
/* FIXME: Implement dns suffix, description, and friendly name */
|
||||
currentAddress->DnsSuffix[0] = UNICODE_NULL;
|
||||
currentAddress->Description[0] = UNICODE_NULL;
|
||||
currentAddress->FriendlyName[0] = UNICODE_NULL;
|
||||
|
||||
/* Physical Address */
|
||||
memcpy(currentAddress->PhysicalAddress, ifInfo.if_info.ent.if_physaddr,
|
||||
ifInfo.if_info.ent.if_physaddrlen);
|
||||
currentAddress->PhysicalAddressLength = ifInfo.if_info.ent.if_physaddrlen;
|
||||
|
||||
/* Flags */
|
||||
currentAddress->Flags = 0; // FIXME
|
||||
|
||||
/* MTU */
|
||||
currentAddress->Mtu = ifInfo.if_info.ent.if_mtu;
|
||||
|
||||
/* Interface type */
|
||||
currentAddress->IfType = ifInfo.if_info.ent.if_type;
|
||||
|
||||
/* Operational status */
|
||||
if(ifInfo.if_info.ent.if_operstatus >= IF_OPER_STATUS_CONNECTING)
|
||||
currentAddress->OperStatus = IfOperStatusUp;
|
||||
else
|
||||
currentAddress->OperStatus = IfOperStatusDown;
|
||||
|
||||
/* We're only going to implement what's required for XP SP0 */
|
||||
|
||||
/* Move to the next address */
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
}
|
||||
|
||||
closeTcpFile(tcpFile);
|
||||
free(indexTable);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
#elif _MSC_VER
|
||||
/* just a comment */
|
||||
static void* unused;
|
||||
#endif
|
|
@ -0,0 +1,540 @@
|
|||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
/*
|
||||
* All the user-mode scaffolding necessary to backport GetAdaptersAddresses(2))
|
||||
* to the NT 5.x series. See further comments for any limitations.
|
||||
*
|
||||
* -despair86 30/07/18
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// apparently mingw-w64 loses its shit over this
|
||||
// but only for 32-bit builds, naturally
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <tdi.h>
|
||||
#include "win32_intrnl.h"
|
||||
|
||||
const PWCHAR TcpFileName = L"\\Device\\Tcp";
|
||||
|
||||
// from ntdll.dll
|
||||
typedef void(FAR PASCAL *pRtlInitUString)(UNICODE_STRING *, const WCHAR *);
|
||||
typedef NTSTATUS(FAR PASCAL *pNTOpenFile)(HANDLE *, ACCESS_MASK,
|
||||
OBJECT_ATTRIBUTES *,
|
||||
IO_STATUS_BLOCK *, ULONG, ULONG);
|
||||
typedef NTSTATUS(FAR PASCAL *pNTClose)(HANDLE);
|
||||
|
||||
#define FSCTL_TCP_BASE FILE_DEVICE_NETWORK
|
||||
|
||||
#define _TCP_CTL_CODE(Function, Method, Access) \
|
||||
CTL_CODE(FSCTL_TCP_BASE, Function, Method, Access)
|
||||
|
||||
#define IOCTL_TCP_QUERY_INFORMATION_EX \
|
||||
_TCP_CTL_CODE(0, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _InterfaceIndexTable
|
||||
{
|
||||
DWORD numIndexes;
|
||||
DWORD numAllocated;
|
||||
DWORD indexes[1];
|
||||
} InterfaceIndexTable;
|
||||
|
||||
NTSTATUS
|
||||
tdiGetMibForIfEntity(HANDLE tcpFile, TDIEntityID *ent,
|
||||
IFEntrySafelySized *entry)
|
||||
{
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req = {{{0}}};
|
||||
NTSTATUS status = 0;
|
||||
DWORD returnSize;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "TdiGetMibForIfEntity(tcpFile %x,entityId %x)\n", (int)tcpFile,
|
||||
(int)ent->tei_instance);
|
||||
#endif
|
||||
|
||||
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = 1;
|
||||
req.ID.toi_entity = *ent;
|
||||
|
||||
status =
|
||||
DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), entry, sizeof(*entry), &returnSize, NULL);
|
||||
|
||||
if(!status)
|
||||
{
|
||||
perror("IOCTL Failed\n");
|
||||
return 0xc0000001;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"TdiGetMibForIfEntity() => {\n"
|
||||
" if_index ....................... %lx\n"
|
||||
" if_type ........................ %lx\n"
|
||||
" if_mtu ......................... %ld\n"
|
||||
" if_speed ....................... %lx\n"
|
||||
" if_physaddrlen ................. %ld\n",
|
||||
entry->ent.if_index, entry->ent.if_type, entry->ent.if_mtu,
|
||||
entry->ent.if_speed, entry->ent.if_physaddrlen);
|
||||
fprintf(stderr,
|
||||
" if_physaddr .................... %02x:%02x:%02x:%02x:%02x:%02x\n"
|
||||
" if_descr ....................... %s\n",
|
||||
entry->ent.if_physaddr[0] & 0xff, entry->ent.if_physaddr[1] & 0xff,
|
||||
entry->ent.if_physaddr[2] & 0xff, entry->ent.if_physaddr[3] & 0xff,
|
||||
entry->ent.if_physaddr[4] & 0xff, entry->ent.if_physaddr[5] & 0xff,
|
||||
entry->ent.if_descr);
|
||||
fprintf(stderr, "} status %08lx\n", status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
tdiGetSetOfThings(HANDLE tcpFile, DWORD toiClass, DWORD toiType, DWORD toiId,
|
||||
DWORD teiEntity, DWORD teiInstance, DWORD fixedPart,
|
||||
DWORD entrySize, PVOID *tdiEntitySet, PDWORD numEntries)
|
||||
{
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req = {{{0}}};
|
||||
PVOID entitySet = 0;
|
||||
NTSTATUS status = 0;
|
||||
DWORD allocationSizeForEntityArray = entrySize * MAX_TDI_ENTITIES,
|
||||
arraySize = entrySize * MAX_TDI_ENTITIES;
|
||||
|
||||
req.ID.toi_class = toiClass;
|
||||
req.ID.toi_type = toiType;
|
||||
req.ID.toi_id = toiId;
|
||||
req.ID.toi_entity.tei_entity = teiEntity;
|
||||
req.ID.toi_entity.tei_instance = teiInstance;
|
||||
|
||||
/* There's a subtle problem here...
|
||||
* If an interface is added at this exact instant, (as if by a PCMCIA
|
||||
* card insertion), the array will still not have enough entries after
|
||||
* have allocated it after the first DeviceIoControl call.
|
||||
*
|
||||
* We'll get around this by repeating until the number of interfaces
|
||||
* stabilizes.
|
||||
*/
|
||||
do
|
||||
{
|
||||
status =
|
||||
DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), 0, 0, &allocationSizeForEntityArray, NULL);
|
||||
|
||||
if(!status)
|
||||
return 0xc0000001;
|
||||
|
||||
arraySize = allocationSizeForEntityArray;
|
||||
entitySet = HeapAlloc(GetProcessHeap(), 0, arraySize);
|
||||
|
||||
if(!entitySet)
|
||||
{
|
||||
status = ((NTSTATUS)0xC000009A);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = DeviceIoControl(tcpFile, IOCTL_TCP_QUERY_INFORMATION_EX, &req,
|
||||
sizeof(req), entitySet, arraySize,
|
||||
&allocationSizeForEntityArray, NULL);
|
||||
|
||||
/* This is why we have the loop -- we might have added an adapter */
|
||||
if(arraySize == allocationSizeForEntityArray)
|
||||
break;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, entitySet);
|
||||
entitySet = 0;
|
||||
|
||||
if(!status)
|
||||
return 0xc0000001;
|
||||
} while(TRUE); /* We break if the array we received was the size we
|
||||
* expected. Therefore, we got here because it wasn't */
|
||||
|
||||
*numEntries = (arraySize - fixedPart) / entrySize;
|
||||
*tdiEntitySet = entitySet;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
tdiGetEntityIDSet(HANDLE tcpFile, TDIEntityID **entitySet,
|
||||
PDWORD numEntities)
|
||||
{
|
||||
NTSTATUS status = tdiGetSetOfThings(tcpFile,
|
||||
INFO_CLASS_GENERIC,
|
||||
INFO_TYPE_PROVIDER,
|
||||
ENTITY_LIST_ID,
|
||||
GENERIC_ENTITY,
|
||||
0,
|
||||
0,
|
||||
sizeof(TDIEntityID),
|
||||
(PVOID *)entitySet,
|
||||
numEntities);
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
tdiGetIpAddrsForIpEntity(HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs,
|
||||
PDWORD numAddrs)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
fprintf(stderr,"TdiGetIpAddrsForIpEntity(tcpFile 0x%p, entityId 0x%lx)\n", tcpFile,
|
||||
ent->tei_instance);
|
||||
|
||||
status = tdiGetSetOfThings(tcpFile, INFO_CLASS_PROTOCOL, INFO_TYPE_PROVIDER,
|
||||
0x102, CL_NL_ENTITY,
|
||||
ent->tei_instance, 0, sizeof(IPAddrEntry),
|
||||
(PVOID *)addrs, numAddrs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VOID
|
||||
tdiFreeThingSet(PVOID things)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, things);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess)
|
||||
{
|
||||
UNICODE_STRING fileName;
|
||||
OBJECT_ATTRIBUTES objectAttributes;
|
||||
IO_STATUS_BLOCK ioStatusBlock;
|
||||
NTSTATUS status;
|
||||
pRtlInitUString _RtlInitUnicodeString;
|
||||
pNTOpenFile _NTOpenFile;
|
||||
HANDLE ntdll;
|
||||
|
||||
ntdll = GetModuleHandle("ntdll.dll");
|
||||
_RtlInitUnicodeString = (pRtlInitUString)GetProcAddress(ntdll, "RtlInitUnicodeString");
|
||||
_NTOpenFile = (pNTOpenFile)GetProcAddress(ntdll, "NtOpenFile");
|
||||
_RtlInitUnicodeString(&fileName, TcpFileName);
|
||||
InitializeObjectAttributes(&objectAttributes, &fileName, OBJ_CASE_INSENSITIVE,
|
||||
NULL, NULL);
|
||||
status = _NTOpenFile(tcpFile, DesiredAccess | SYNCHRONIZE, &objectAttributes,
|
||||
&ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
/* String does not need to be freed: it points to the constant
|
||||
* string we provided */
|
||||
if(!NT_SUCCESS(status))
|
||||
*tcpFile = INVALID_HANDLE_VALUE;
|
||||
return status;
|
||||
}
|
||||
VOID
|
||||
closeTcpFile(HANDLE h)
|
||||
{
|
||||
pNTClose _NTClose;
|
||||
HANDLE ntdll = GetModuleHandle("ntdll.dll");
|
||||
_NTClose = (pNTClose)GetProcAddress(ntdll, "NtClose");
|
||||
assert(h != INVALID_HANDLE_VALUE);
|
||||
_NTClose(h);
|
||||
}
|
||||
|
||||
BOOL
|
||||
isLoopback(HANDLE tcpFile, TDIEntityID *loop_maybe)
|
||||
{
|
||||
IFEntrySafelySized entryInfo;
|
||||
NTSTATUS status;
|
||||
|
||||
status = tdiGetMibForIfEntity(tcpFile, loop_maybe, &entryInfo);
|
||||
|
||||
return NT_SUCCESS(status)
|
||||
&& (entryInfo.ent.if_type == IFENT_SOFTWARE_LOOPBACK);
|
||||
}
|
||||
|
||||
BOOL
|
||||
isIpEntity(HANDLE tcpFile, TDIEntityID *ent)
|
||||
{
|
||||
return (ent->tei_entity == CL_NL_ENTITY || ent->tei_entity == CO_NL_ENTITY);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getNthIpEntity(HANDLE tcpFile, DWORD index, TDIEntityID *ent)
|
||||
{
|
||||
DWORD numEntities = 0;
|
||||
DWORD numRoutes = 0;
|
||||
TDIEntityID *entitySet = 0;
|
||||
NTSTATUS status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities);
|
||||
int i;
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
for(i = 0; i < numEntities; i++)
|
||||
{
|
||||
if(isIpEntity(tcpFile, &entitySet[i]))
|
||||
{
|
||||
fprintf(stderr, "Entity %d is an IP Entity\n", i);
|
||||
if(numRoutes == index)
|
||||
break;
|
||||
else
|
||||
numRoutes++;
|
||||
}
|
||||
}
|
||||
|
||||
if(numRoutes == index && i < numEntities)
|
||||
{
|
||||
fprintf(stderr,"Index %lu is entity #%d - %04lx:%08lx\n", index, i,
|
||||
entitySet[i].tei_entity, entitySet[i].tei_instance);
|
||||
memcpy(ent, &entitySet[i], sizeof(*ent));
|
||||
tdiFreeThingSet(entitySet);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdiFreeThingSet(entitySet);
|
||||
return 0xc000001;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
isInterface(TDIEntityID *if_maybe)
|
||||
{
|
||||
return if_maybe->tei_entity == IF_ENTITY;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoSet(HANDLE tcpFile, IFInfo **infoSet, PDWORD numInterfaces)
|
||||
{
|
||||
DWORD numEntities;
|
||||
TDIEntityID *entIDSet = NULL;
|
||||
NTSTATUS status = tdiGetEntityIDSet(tcpFile, &entIDSet, &numEntities);
|
||||
IFInfo *infoSetInt = 0;
|
||||
int curInterf = 0, i;
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
{
|
||||
fprintf(stderr, "getInterfaceInfoSet: tdiGetEntityIDSet() failed: 0x%lx\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
infoSetInt = HeapAlloc(GetProcessHeap(), 0, sizeof(IFInfo) * numEntities);
|
||||
|
||||
if(infoSetInt)
|
||||
{
|
||||
for(i = 0; i < numEntities; i++)
|
||||
{
|
||||
if(isInterface(&entIDSet[i]))
|
||||
{
|
||||
infoSetInt[curInterf].entity_id = entIDSet[i];
|
||||
status = tdiGetMibForIfEntity(tcpFile, &entIDSet[i],
|
||||
&infoSetInt[curInterf].if_info);
|
||||
fprintf(stderr, "tdiGetMibForIfEntity: %08lx\n", status);
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
DWORD numAddrs;
|
||||
IPAddrEntry *addrs;
|
||||
TDIEntityID ip_ent;
|
||||
int j;
|
||||
|
||||
status = getNthIpEntity(tcpFile, curInterf, &ip_ent);
|
||||
if(NT_SUCCESS(status))
|
||||
status =
|
||||
tdiGetIpAddrsForIpEntity(tcpFile, &ip_ent, &addrs, &numAddrs);
|
||||
for(j = 0; NT_SUCCESS(status) && j < numAddrs; j++)
|
||||
{
|
||||
fprintf(stderr, "ADDR %d: index %ld (target %ld)\n", j, addrs[j].iae_index,
|
||||
infoSetInt[curInterf].if_info.ent.if_index);
|
||||
if(addrs[j].iae_index == infoSetInt[curInterf].if_info.ent.if_index)
|
||||
{
|
||||
memcpy(&infoSetInt[curInterf].ip_addr, &addrs[j],
|
||||
sizeof(addrs[j]));
|
||||
curInterf++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(NT_SUCCESS(status))
|
||||
tdiFreeThingSet(addrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tdiFreeThingSet(entIDSet);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
*infoSet = infoSetInt;
|
||||
*numInterfaces = curInterf;
|
||||
}
|
||||
else
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, infoSetInt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdiFreeThingSet(entIDSet);
|
||||
return ((NTSTATUS)0xC000009A);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByName(HANDLE tcpFile, char *name, IFInfo *info)
|
||||
{
|
||||
IFInfo *ifInfo;
|
||||
DWORD numInterfaces;
|
||||
int i;
|
||||
NTSTATUS status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
if(!strcmp((PCHAR)ifInfo[i].if_info.ent.if_descr, name))
|
||||
{
|
||||
memcpy(info, &ifInfo[i], sizeof(*info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ifInfo);
|
||||
|
||||
return i < numInterfaces ? 0 : 0xc0000001;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByIndex(HANDLE tcpFile, DWORD index, IFInfo *info)
|
||||
{
|
||||
IFInfo *ifInfo;
|
||||
DWORD numInterfaces;
|
||||
NTSTATUS status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
int i;
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
if(ifInfo[i].if_info.ent.if_index == index)
|
||||
{
|
||||
memcpy(info, &ifInfo[i], sizeof(*info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ifInfo);
|
||||
|
||||
return i < numInterfaces ? 0 : 0xc0000001;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
getIPAddrEntryForIf(HANDLE tcpFile, char *name, DWORD index, IFInfo *ifInfo)
|
||||
{
|
||||
NTSTATUS status = name ? getInterfaceInfoByName(tcpFile, name, ifInfo)
|
||||
: getInterfaceInfoByIndex(tcpFile, index, ifInfo);
|
||||
|
||||
if(!NT_SUCCESS(status))
|
||||
{
|
||||
fprintf(stderr,"getIPAddrEntryForIf returning %lx\n", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *
|
||||
getInterfaceIndexTableInt(BOOL nonLoopbackOnly)
|
||||
{
|
||||
DWORD numInterfaces, curInterface = 0;
|
||||
int i;
|
||||
IFInfo *ifInfo;
|
||||
InterfaceIndexTable *ret = 0;
|
||||
HANDLE tcpFile;
|
||||
NTSTATUS status = openTcpFile(&tcpFile, FILE_READ_DATA);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
status = getInterfaceInfoSet(tcpFile, &ifInfo, &numInterfaces);
|
||||
|
||||
fprintf(stderr,"InterfaceInfoSet: %08lx, %04lx:%08lx\n", status,
|
||||
ifInfo->entity_id.tei_entity, ifInfo->entity_id.tei_instance);
|
||||
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
ret = (InterfaceIndexTable *)calloc(
|
||||
1, sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
||||
|
||||
if(ret)
|
||||
{
|
||||
ret->numAllocated = numInterfaces;
|
||||
fprintf(stderr,"NumInterfaces = %ld\n", numInterfaces);
|
||||
|
||||
for(i = 0; i < numInterfaces; i++)
|
||||
{
|
||||
fprintf(stderr,"Examining interface %d\n", i);
|
||||
if(!nonLoopbackOnly || !isLoopback(tcpFile, &ifInfo[i].entity_id))
|
||||
{
|
||||
fprintf(stderr,"Interface %d matches (%ld)\n", i, curInterface);
|
||||
ret->indexes[curInterface++] = ifInfo[i].if_info.ent.if_index;
|
||||
}
|
||||
}
|
||||
|
||||
ret->numIndexes = curInterface;
|
||||
}
|
||||
|
||||
tdiFreeThingSet(ifInfo);
|
||||
}
|
||||
closeTcpFile(tcpFile);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *
|
||||
getInterfaceIndexTable(void)
|
||||
{
|
||||
return getInterfaceIndexTableInt(FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need this in the Microsoft C/C++ port, as we're not using Pthreads, and jeff insists
|
||||
* on naming the threads at runtime.
|
||||
* Apparently throwing exception 1080890248 is only visible when running under a machine
|
||||
* code monitor.
|
||||
*
|
||||
* -despair86 30/07/18
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#define EXCEPTION_SET_THREAD_NAME ((DWORD)0x406D1388)
|
||||
typedef struct _THREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; /* must be 0x1000 */
|
||||
LPCSTR szName; /* pointer to name (in user addr space) */
|
||||
DWORD dwThreadID; /* thread ID (-1=caller thread) */
|
||||
DWORD dwFlags; /* reserved for future use, must be zero */
|
||||
} THREADNAME_INFO;
|
||||
|
||||
void
|
||||
SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
DWORD infosize;
|
||||
|
||||
info.dwType = 0x1000;
|
||||
info.szName = szThreadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
|
||||
infosize = sizeof(info) / sizeof(DWORD);
|
||||
|
||||
__try
|
||||
{
|
||||
RaiseException(EXCEPTION_SET_THREAD_NAME, 0, infosize, (DWORD *)&info);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
#ifndef WIN32_INTRNL_H
|
||||
#define WIN32_INTRNL_H
|
||||
/* if yer using Microsoft C++, then downlevel platforms are irrelevant to you */
|
||||
#if defined(__MINGW32__) && !defined(_WIN64)
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
#include <tdiinfo.h>
|
||||
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned int uint;
|
||||
|
||||
/* forward declare, each module has their own idea of what this is */
|
||||
typedef struct _InterfaceIndexTable InterfaceIndexTable;
|
||||
|
||||
typedef struct IFEntry
|
||||
{
|
||||
ulong if_index;
|
||||
ulong if_type;
|
||||
ulong if_mtu;
|
||||
ulong if_speed;
|
||||
ulong if_physaddrlen;
|
||||
uchar if_physaddr[8];
|
||||
ulong if_adminstatus;
|
||||
ulong if_operstatus;
|
||||
ulong if_lastchange;
|
||||
ulong if_inoctets;
|
||||
ulong if_inucastpkts;
|
||||
ulong if_innucastpkts;
|
||||
ulong if_indiscards;
|
||||
ulong if_inerrors;
|
||||
ulong if_inunknownprotos;
|
||||
ulong if_outoctets;
|
||||
ulong if_outucastpkts;
|
||||
ulong if_outnucastpkts;
|
||||
ulong if_outdiscards;
|
||||
ulong if_outerrors;
|
||||
ulong if_outqlen;
|
||||
ulong if_descrlen;
|
||||
uchar if_descr[1];
|
||||
} IFEntry;
|
||||
|
||||
typedef struct IPAddrEntry
|
||||
{
|
||||
ulong iae_addr;
|
||||
ulong iae_index;
|
||||
ulong iae_mask;
|
||||
ulong iae_bcastaddr;
|
||||
ulong iae_reasmsize;
|
||||
ushort iae_context;
|
||||
ushort iae_pad;
|
||||
} IPAddrEntry;
|
||||
|
||||
typedef union _IFEntrySafelySized {
|
||||
CHAR MaxSize[sizeof(DWORD) + sizeof(IFEntry) + 128 + 1];
|
||||
IFEntry ent;
|
||||
} IFEntrySafelySized;
|
||||
|
||||
#ifndef IFENT_SOFTWARE_LOOPBACK
|
||||
#define IFENT_SOFTWARE_LOOPBACK 24 /* This is an SNMP constant from rfc1213 */
|
||||
#endif /*IFENT_SOFTWARE_LOOPBACK*/
|
||||
|
||||
/* Encapsulates information about an interface */
|
||||
typedef struct _IFInfo
|
||||
{
|
||||
TDIEntityID entity_id;
|
||||
IFEntrySafelySized if_info;
|
||||
IPAddrEntry ip_addr;
|
||||
} IFInfo;
|
||||
|
||||
/* functions */
|
||||
NTSTATUS
|
||||
openTcpFile(PHANDLE tcpFile, ACCESS_MASK DesiredAccess);
|
||||
|
||||
VOID
|
||||
closeTcpFile(HANDLE h);
|
||||
|
||||
BOOL
|
||||
isLoopback(HANDLE tcpFile, TDIEntityID* loop_maybe);
|
||||
|
||||
BOOL
|
||||
isIpEntity(HANDLE tcpFile, TDIEntityID* ent);
|
||||
|
||||
NTSTATUS
|
||||
getNthIpEntity(HANDLE tcpFile, DWORD index, TDIEntityID* ent);
|
||||
|
||||
BOOL
|
||||
isInterface(TDIEntityID* if_maybe);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoSet(HANDLE tcpFile, IFInfo** infoSet, PDWORD numInterfaces);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByName(HANDLE tcpFile, char* name, IFInfo* info);
|
||||
|
||||
NTSTATUS
|
||||
getInterfaceInfoByIndex(HANDLE tcpFile, DWORD index, IFInfo* info);
|
||||
|
||||
NTSTATUS
|
||||
getIPAddrEntryForIf(HANDLE tcpFile, char* name, DWORD index, IFInfo* ifInfo);
|
||||
|
||||
InterfaceIndexTable*
|
||||
getInterfaceIndexTableInt(BOOL nonLoopbackOnly);
|
||||
|
||||
InterfaceIndexTable*
|
||||
getInterfaceIndexTable(void);
|
||||
#endif
|
||||
|
||||
#endif
|
28
readme.md
28
readme.md
|
@ -3,31 +3,7 @@
|
|||
Lokinet is a private, decentralized and Sybil resistant overlay network for the internet, it uses a new routing protocol called LLARP (Low latency anonymous routing protocol)
|
||||
|
||||
You can learn more about the high level design of LLARP [here](doc/high-level.txt)
|
||||
|
||||
And you can read the LLARP protocol specification [here](doc/proto_v0.txt)
|
||||
|
||||
## Building
|
||||
|
||||
$ sudo apt install build-essential libtool autoconf cmake git
|
||||
$ git clone --recursive https://github.com/loki-project/lokinet-builder
|
||||
$ cd lokinet-builder
|
||||
$ make
|
||||
|
||||
## Running
|
||||
|
||||
$ ./lokinet
|
||||
|
||||
### Development
|
||||
|
||||
Please note development builds are likely to be unstable
|
||||
|
||||
Build requirements:
|
||||
|
||||
* CMake
|
||||
* ninja
|
||||
* libsodium >= 1.0.14
|
||||
* c++ 11 capable C++ compiler
|
||||
|
||||
|
||||
Building a debug build:
|
||||
|
||||
$ make
|
||||
To build lokinet see the [lokinet-builder](https://github.com/loki-project/lokinet-builder) repository.
|
|
@ -22,6 +22,7 @@ struct HiddenServiceTest : public ::testing::Test
|
|||
{
|
||||
ident.RegenerateKeys(Crypto());
|
||||
ident.pub.vanity.Randomize();
|
||||
ident.pub.UpdateAddr();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -40,4 +41,12 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
|
|||
}
|
||||
ASSERT_TRUE(ident.SignIntroSet(I, Crypto()));
|
||||
ASSERT_TRUE(I.VerifySignature(Crypto()));
|
||||
};
|
||||
};
|
||||
|
||||
TEST_F(HiddenServiceTest, TestAddressToFromString)
|
||||
{
|
||||
auto str = ident.pub.Addr().ToString();
|
||||
llarp::service::Address addr;
|
||||
ASSERT_TRUE(addr.FromString(str));
|
||||
ASSERT_TRUE(addr == ident.pub.Addr());
|
||||
}
|
|
@ -30,18 +30,21 @@
|
|||
#ifndef PBL_CPP_FILESYSTEM_H
|
||||
#define PBL_CPP_FILESYSTEM_H
|
||||
|
||||
#if _MSC_VER >= 1910
|
||||
#define CPP17
|
||||
#define CPP11
|
||||
#define CPP14
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
|
||||
// linux gcc 7.2 has CPP17 but doesn't have filesystem.h
|
||||
#if defined(CPP17) && !defined(__OpenBSD__) && __has_include(<filesystem>)
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
// mingw32 needs experimental
|
||||
#if defined(CPP17) && defined(USE_CXX17_FILESYSTEM)
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
// win32 needs experimental
|
||||
#include <experimental/filesystem>
|
||||
#else
|
||||
#include <filesystem>
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OpenBSD needs this
|
||||
// MacOS llvm 3.8 needs this
|
||||
|
@ -61,6 +64,6 @@
|
|||
#include "fs/remove.h"
|
||||
#include "fs/rename.h"
|
||||
#include "fs/tempdir.h"
|
||||
#endif // if not cpp17 and not openbsd
|
||||
#endif // if not cpp17 and not openbsd
|
||||
|
||||
#endif // PBL_CPP_FILESYSTEM_H
|
||||
|
|
|
@ -64,7 +64,8 @@ namespace
|
|||
{
|
||||
t = file_type::fifo;
|
||||
}
|
||||
else if ( S_ISLNK(m) )
|
||||
#ifndef _WIN32 // these only work on cygnus or msys2!
|
||||
else if(S_ISLNK(m))
|
||||
{
|
||||
t = file_type::symlink;
|
||||
}
|
||||
|
@ -72,9 +73,8 @@ namespace
|
|||
{
|
||||
t = file_type::socket;
|
||||
}
|
||||
|
||||
#endif
|
||||
return ::cpp17::filesystem::file_status(t, p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -156,13 +156,15 @@ file_status symlink_status(const path& path_)
|
|||
if ( !path_.empty() )
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if ( ::lstat(path_.c_str(), &st) == 0 )
|
||||
#ifndef _WIN32
|
||||
if(::lstat(path_.c_str(), &st) == 0)
|
||||
#else
|
||||
if(::stat(path_.c_str(), &st) == 0)
|
||||
#endif
|
||||
{
|
||||
return from_mode_t(st.st_mode);
|
||||
}
|
||||
}
|
||||
|
||||
return file_status();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#if defined Windows
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
|
Loading…
Reference in New Issue