Compare commits

..
1 Commits
Author SHA1 Message Date
Adrien Béraud 68485faf58 crypto: improve authenticated encryption performance 2019-10-22 13:04:30 -04:00
157 changed files with 6475 additions and 9233 deletions

No files matched your search

-12
View File
@@ -1,12 +0,0 @@
{
"name": "C++",
"build": {
"dockerfile": "../docker/DockerfileDepsLlvm",
},
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
"settings": {},
"extensions": [
"ms-vscode.cpptools"
],
"forwardPorts": [4222],
}
-68
View File
@@ -1,68 +0,0 @@
name: C/C++ CI
on: [push]
jobs:
build-ubuntu:
name: Ubuntu/GCC build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: deps
run: |
sudo apt install libncurses5-dev libreadline-dev nettle-dev \
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev libargon2-0-dev
- name: autogen
run: ./autogen.sh
- name: asio
run: |
wget https://github.com/aberaud/asio/archive/b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz \
&& tar -xvf b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz && cd asio-b2b7a1c166390459e1c169c8ae9ef3234b361e3f/asio \
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
&& sudo make install \
&& cd ../../ && rm -rf asio*
- name: configure
run: ./configure
- name: make
run: make
- name: make check
run: make check
build-macos:
name: macOS/Clang build
runs-on: macos-11
steps:
- uses: actions/checkout@v3
- name: deps
run: |
brew install msgpack-cxx asio gnutls nettle readline fmt jsoncpp argon2 openssl http-parser cppunit
- name: restinio
run: |
mkdir restinio && cd restinio
wget https://github.com/aberaud/restinio/archive/e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz
ls -l && tar -xzf e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz
cd restinio-e0a261dd8488246a3cb8bbb3ea781ea5139c3c94/dev
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none .
make -j8 && sudo make install
cd ../../.. && rm -rf restinio
- name: cmake
run: |
mkdir build && cd build
export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@3/include"
export PKG_CONFIG_PATH="/usr/local/opt/openssl@3/lib/pkgconfig"
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Debug \
-DOPENDHT_C=On -DOPENDHT_TESTS=On -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off \
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On
- name: make
run: cd build && make
- name: make check
run: cd build && ./opendht_unit_tests
-35
View File
@@ -1,35 +0,0 @@
name: Clang Static Analysis
on:
push
jobs:
clang-analyzer:
name: Clang Static Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: deps
run: |
sudo apt install libncurses5-dev libreadline-dev nettle-dev \
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev libargon2-0-dev libasio-dev \
llvm llvm-dev clang clang-tools && \
sudo apt remove gcc g++
- name: restinio
run: |
mkdir restinio && cd restinio \
&& wget https://github.com/aberaud/restinio/archive/e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
&& ls -l && tar -xzf e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
&& cd restinio-e0a261dd8488246a3cb8bbb3ea781ea5139c3c94/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none . \
&& make -j8 && sudo make install \
&& cd ../../.. && rm -rf restinio
- name: cmake
run: |
mkdir build && cd build && \
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DOPENDHT_C=On -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off -DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On
- name: scan-build
run: cd build && scan-build --status-bugs make
-4
View File
@@ -19,9 +19,6 @@
*.exe
*.out
*.app
**/dhtnode
**/dhtchat
**/dhtscanner
# Autotools
/ac
@@ -76,4 +73,3 @@ doc/Doxyfile
# build dir
build
.DS_Store
+4
View File
@@ -0,0 +1,4 @@
[submodule "argon2"]
path = argon2
url = https://github.com/P-H-C/phc-winner-argon2
ignore = dirty
+68
View File
@@ -0,0 +1,68 @@
dist: xenial
sudo: required
services:
- docker
language: cpp
env:
matrix:
- OPENDHT_TEST_JOB="opendht.classic"
- OPENDHT_TEST_JOB="opendht.llvm"
- OPENDHT_TEST_JOB="opendht.proxyserver"
- OPENDHT_TEST_JOB="opendht.proxyclient"
- OPENDHT_TEST_JOB="opendht.push"
before_install:
- |
# non llvm builds
if [[ "$OPENDHT_TEST_JOB" != *"opendht.llvm"* ]]; then
docker pull aberaud/opendht-deps;
fi
- |
# classic build
if [[ "$OPENDHT_TEST_JOB" == *"opendht.llvm"* ]]; then
docker pull aberaud/opendht-deps-llvm
fi
script:
- |
# classic build
if [[ "$OPENDHT_TEST_JOB" == *"opendht.classic"* ]]; then
docker build -t opendht -f docker/DockerfileTravis .;
fi
- |
# proxy builds
if [[ "$OPENDHT_TEST_JOB" != *"opendht.llvm"* ]] && [[ "$OPENDHT_TEST_JOB" != *"opendht.classic"* ]]; then
docker build -t opendht-proxy -f docker/DockerfileTravisProxy .;
options='-DOPENDHT_SANITIZE=On ';
if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyserver"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.push"* ]]; then
options+='-DOPENDHT_PROXY_SERVER=ON ';
else
options+='-DOPENDHT_PROXY_SERVER=OFF ';
fi
if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyclient"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.push"* ]]; then
options+='-DOPENDHT_PROXY_CLIENT=ON ';
else
options+='-DOPENDHT_PROXY_CLIENT=OFF ';
fi
if [[ "$OPENDHT_TEST_JOB" == *"opendht.push"* ]]; then
options+='-DOPENDHT_PUSH_NOTIFICATIONS=ON ';
else
options+='-DOPENDHT_PUSH_NOTIFICATIONS=OFF ';
fi
docker run opendht-proxy /bin/sh -c "cd /root/opendht && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=ON -DOPENDHT_LTO=ON -DOPENDHT_TESTS=ON $options .. && make -j8 && ./opendht_unit_tests && make install";
fi
- |
# llvm build
if [[ "$OPENDHT_TEST_JOB" == *"opendht.llvm"* ]]; then
docker build -f docker/DockerfileTravisLlvm .
fi
notifications:
email:
- adrien.beraud@savoirfairelinux.com
-54
View File
@@ -1,54 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "dhtnode",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/tools/dhtnode",
"args": ["-v", "-p", "4222"],
"cwd": "${workspaceFolder}/build",
"environment": [],
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "build",
"linux": {
"MIMode": "gdb",
"externalConsole": false,
},
"osx": {
"MIMode": "lldb",
"externalConsole": true,
},
},
{
"name": "tests",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/opendht_unit_tests",
"cwd": "${workspaceFolder}/build",
"environment": [],
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "build",
"linux": {
"MIMode": "gdb",
"externalConsole": false,
},
"osx": {
"MIMode": "lldb",
"externalConsole": true,
},
}
]
}
-44
View File
@@ -1,44 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"options": {
"cwd": "${workspaceRoot}/build"
},
"command": "make",
"args": ["-j4"],
"dependsOn": "cmake"
},
{
"label": "cmake",
"type": "shell",
"options": {
"cwd": "${workspaceRoot}/build"
},
"command": "cmake",
"args": [
"${workspaceRoot}",
"-DCMAKE_BUILD_TYPE=Debug",
"-DOPENDHT_PROXY_CLIENT=On",
"-DOPENDHT_PROXY_SERVER=On",
"-DOPENDHT_TESTS=On",
"-DOPENDHT_C=On"
],
"dependsOn": "builddir"
},
{
"label": "builddir",
"type": "shell",
"options": {
"cwd": "${workspaceRoot}"
},
"command": "mkdir",
"args": [
"-p",
"${workspaceRoot}/build"
]
},
]
}
+140 -238
View File
@@ -1,25 +1,7 @@
cmake_minimum_required (VERSION 3.10)
if(POLICY CMP0065)
cmake_policy(SET CMP0065 NEW)
endif()
if(POLICY CMP0069)
cmake_policy(SET CMP0069 NEW)
endif()
if(POLICY CMP0073)
cmake_policy(SET CMP0073 NEW)
endif()
if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
cmake_minimum_required (VERSION 3.1)
project (opendht)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
include(FindPkgConfig)
include(cmake/CheckAtomic.cmake)
set (opendht_VERSION_MAJOR 2)
set (opendht_VERSION_MINOR 4.0)
set (opendht_VERSION_MINOR 0.0)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
set (VERSION "${opendht_VERSION}")
@@ -31,18 +13,17 @@ option (OPENDHT_LOG "Build with logs" ON)
option (OPENDHT_PYTHON "Build Python bindings" OFF)
option (OPENDHT_TOOLS "Build DHT tools" ON)
option (OPENDHT_SYSTEMD "Install systemd module" OFF)
option (OPENDHT_SYSTEMD_UNIT_FILE_LOCATION "Where to install systemd unit file")
option (OPENDHT_ARGON2 "Use included argon2 sources" OFF)
option (OPENDHT_LTO "Build with LTO" OFF)
option (OPENDHT_SANITIZE "Build with address sanitizer and stack protector" OFF)
option (OPENDHT_PROXY_SERVER "Enable DHT proxy server, use Restinio and jsoncpp" OFF)
option (OPENDHT_PUSH_NOTIFICATIONS "Enable push notifications support" OFF)
option (OPENDHT_PROXY_SERVER_IDENTITY "Allow clients to use the node identity" OFF)
option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restinio and jsoncpp" OFF)
option (OPENDHT_PROXY_OPENSSL "Build DHT proxy with OpenSSL" ON)
CMAKE_DEPENDENT_OPTION(OPENDHT_HTTP "Build embedded http(s) client" OFF "NOT OPENDHT_PROXY_SERVER;NOT OPENDHT_PROXY_CLIENT" ON)
option (OPENDHT_PEER_DISCOVERY "Enable multicast peer discovery" ON)
option (OPENDHT_PROXY_HTTP_PARSER_FORK "Build DHT proxy with custom http_parser to support old API" OFF)
option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
option (OPENDHT_TESTS "Add unit tests executable" OFF)
option (OPENDHT_TESTS_NETWORK "Enable unit tests that require network access" ON)
option (OPENDHT_C "Build C bindings" OFF)
find_package(Doxygen)
@@ -50,100 +31,70 @@ option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentati
# Dependencies
list (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
if (NOT MSVC)
set (THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package (Threads)
find_package (PkgConfig REQUIRED)
find_package (GnuTLS 3.3 REQUIRED)
pkg_search_module (Nettle REQUIRED nettle)
find_package (msgpack REQUIRED)
if (OPENDHT_TOOLS)
find_package (Readline 6 REQUIRED)
endif ()
pkg_search_module(argon2 REQUIRED libargon2)
pkg_search_module(Jsoncpp jsoncpp)
if (Jsoncpp_FOUND)
add_definitions(-DOPENDHT_JSONCPP)
list (APPEND opendht_SOURCES
src/base64.h
src/base64.cpp
)
find_package (Threads)
find_package (PkgConfig)
find_package (GnuTLS 3.3 REQUIRED)
pkg_search_module (Nettle nettle)
find_package (Msgpack 1.2 REQUIRED)
if (OPENDHT_TOOLS)
find_package (Readline 6 REQUIRED)
endif ()
if (NOT OPENDHT_ARGON2)
find_package(PkgConfig)
pkg_search_module(argon2 libargon2)
if (argon2_FOUND)
message("-- Found Argon2: " ${argon2_LIBRARY_DIRS} " (found version \"" ${argon2_VERSION} "\")")
link_directories (${argon2_LIBRARY_DIRS})
else ()
message("Argon2 not found, using included version.")
set(OPENDHT_ARGON2 ON)
endif()
endif ()
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED)
endif ()
pkg_search_module(Jsoncpp jsoncpp)
if (Jsoncpp_FOUND)
add_definitions(-DOPENDHT_JSONCPP)
list (APPEND opendht_SOURCES
src/base64.h
src/base64.cpp
)
endif()
if (OPENDHT_HTTP)
find_package(Restinio REQUIRED)
if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
find_package(Restinio REQUIRED)
if (Restinio_FOUND)
add_definitions(-DASIO_STANDALONE)
find_library(FMT_LIBRARY fmt)
add_library(fmt SHARED IMPORTED)
find_library(HTTP_PARSER_LIBRARY http_parser)
add_library(http_parser SHARED IMPORTED)
if (NOT Jsoncpp_FOUND)
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
endif()
if (NOT Jsoncpp_FOUND)
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
endif()
if (OPENDHT_PROXY_OPENSSL)
# https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
pkg_search_module(OPENSSL REQUIRED openssl)
if (OPENSSL_FOUND)
message(STATUS "Found OpenSSL ${OPENSSL_VERSION}")
include_directories(${OPENSSL_INCLUDE_DIRS})
else ()
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
endif()
if (OPENDHT_PROXY_OPENSSL)
# https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
pkg_search_module(OPENSSL REQUIRED openssl)
if (OPENSSL_FOUND)
message(STATUS "Found OpenSSL ${OPENSSL_VERSION} ${OPENSSL_INCLUDE_DIRS}")
include_directories(SYSTEM ${OPENSSL_INCLUDE_DIRS})
link_directories (${OPENSSL_LIBRARY_DIRS})
else ()
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
endif()
endif()
else ()
set(OPENDHT_PROXY_OPENSSL OFF)
endif ()
else ()
set (WIN32_DEP_DIR ${PROJECT_SOURCE_DIR}/../)
include_directories(${WIN32_DEP_DIR}/../msvc/include) # SMP gnutls
include_directories(${WIN32_DEP_DIR}/argon2/include)
include_directories(${WIN32_DEP_DIR}/jsoncpp/include)
list (APPEND opendht_SOURCES
src/base64.h
src/base64.cpp
)
add_definitions(-DOPENDHT_JSONCPP)
include_directories(${WIN32_DEP_DIR}/msgpack-c/include)
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
include_directories(
${WIN32_DEP_DIR}/asio/asio/include
${WIN32_DEP_DIR}/openssl/include
${WIN32_DEP_DIR}/restinio/dev
${WIN32_DEP_DIR}/fmt/include
${WIN32_DEP_DIR}/http_parser
)
endif ()
endif ()
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
add_definitions(-DASIO_STANDALONE)
endif()
if (OPENDHT_PROXY_HTTP_PARSER_FORK)
add_definitions(-DOPENDHT_PROXY_HTTP_PARSER_FORK)
endif()
endif()
# Build flags
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD_REQUIRED on)
if (NOT MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
if (OPENDHT_SANITIZE)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-protector-strong")
endif ()
else ()
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS
-D_CRT_SECURE_NO_WARNINGS
-DWIN32_LEAN_AND_MEAN
-DSTATIC_GETOPT
-DGNUTLS_INTERNAL_BUILD)
set(DISABLE_MSC_WARNINGS "/wd4101 /wd4244 /wd4267 /wd4273 /wd4804 /wd4834 /wd4996")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DISABLE_MSC_WARNINGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
if (OPENDHT_SANITIZE)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-protector-strong")
endif ()
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif ()
@@ -153,6 +104,15 @@ if (OPENDHT_LOG)
else ()
add_definitions(-DOPENDHT_LOG=false)
endif()
if (OPENDHT_LTO)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
if (CMAKE_COMPILER_IS_GNUCC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-linker-plugin")
set (CMAKE_AR "gcc-ar")
set (CMAKE_NM "gcc-nm")
set (CMAKE_RANLIB "gcc-ranlib")
endif ()
endif ()
if (MSGPACK_INCLUDE_DIRS)
include_directories (SYSTEM "${MSGPACK_INCLUDE_DIRS}")
@@ -163,18 +123,17 @@ endif ()
if (Nettle_INCLUDE_DIRS)
include_directories (SYSTEM "${Nettle_INCLUDE_DIRS}")
endif ()
if (ASIO_INCLUDE_DIR)
include_directories (SYSTEM "${ASIO_INCLUDE_DIR}")
endif ()
if (Restinio_INCLUDE_DIR)
include_directories (SYSTEM "${Restinio_INCLUDE_DIR}")
endif ()
if (Jsoncpp_INCLUDE_DIRS)
include_directories (SYSTEM "${Jsoncpp_INCLUDE_DIRS}")
endif ()
if (OpenSSL_INCLUDE_DIR)
include_directories (SYSTEM "${OpenSSL_INCLUDE_DIR}")
endif ()
link_directories (${Nettle_LIBRARY_DIRS})
link_directories (${Jsoncpp_LIBRARY_DIRS})
link_directories (${argon2_LIBRARY_DIRS})
include_directories (
./
include/
@@ -217,6 +176,7 @@ list (APPEND opendht_SOURCES
src/securedht.cpp
src/dhtrunner.cpp
src/log.cpp
src/peer_discovery.cpp
src/network_utils.cpp
src/thread_pool.cpp
)
@@ -242,17 +202,12 @@ list (APPEND opendht_HEADERS
include/opendht/securedht.h
include/opendht/log.h
include/opendht/log_enable.h
include/opendht/peer_discovery.h
include/opendht/thread_pool.h
include/opendht/network_utils.h
include/opendht.h
)
if (OPENDHT_PEER_DISCOVERY)
list (APPEND opendht_SOURCES src/peer_discovery.cpp)
list (APPEND opendht_HEADERS include/opendht/peer_discovery.h)
add_definitions(-DOPENDHT_PEER_DISCOVERY)
endif()
if (OPENDHT_PYTHON)
message("Indexation enabled since it is required for Python support")
set(OPENDHT_INDEX ON)
@@ -286,7 +241,7 @@ if (OPENDHT_PROXY_CLIENT)
)
endif ()
if (OPENDHT_HTTP)
if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
if (OPENDHT_PUSH_NOTIFICATIONS)
message("Using push notification")
add_definitions(-DOPENDHT_PUSH_NOTIFICATIONS)
@@ -294,80 +249,46 @@ if (OPENDHT_HTTP)
list (APPEND opendht_HEADERS
include/opendht/proxy.h
include/opendht/http.h
src/compat/os_cert.h
)
list (APPEND opendht_SOURCES
src/http.cpp
src/compat/os_cert.cpp
)
endif ()
if (MSVC)
list (APPEND opendht_HEADERS src/compat/msvc/unistd.h)
endif ()
if(OPENDHT_ARGON2)
# make sure argon2 submodule is up to date and initialized
message("Initializing Argon2 submodule")
execute_process(COMMAND git submodule update --init)
# add local argon2 files to build
list (APPEND opendht_SOURCES
argon2/src/argon2.c
argon2/src/core.c
argon2/src/blake2/blake2b.c
argon2/src/thread.c
argon2/src/ref.c
argon2/src/encoding.c
)
include_directories(argon2/include/)
endif()
# Targets
if (OPENDHT_STATIC)
if (NOT MSVC)
add_library (opendht-static STATIC
${opendht_SOURCES}
${opendht_HEADERS}
)
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "opendht")
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
target_link_libraries(opendht-static
PRIVATE ${argon2_LIBRARIES}
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_STATIC_LIBRARIES}
${Jsoncpp_STATIC_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
${OPENSSL_STATIC_LIBRARIES})
add_library (opendht-static STATIC
${opendht_SOURCES}
${opendht_HEADERS}
)
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "opendht")
if (OPENDHT_ARGON2)
target_include_directories(opendht-static SYSTEM PRIVATE argon2)
else ()
if (OPENDHT_TOOLS)
function (add_obj_lib name libfile)
add_library(${name} OBJECT IMPORTED)
set_property(TARGET ${name} PROPERTY IMPORTED_OBJECTS ${libfile})
endfunction ()
add_obj_lib (win32_json ${WIN32_DEP_DIR}/../msvc/lib/x64/lib_json.lib)
add_obj_lib (win32_gnutls ${WIN32_DEP_DIR}/../msvc/lib/x64/libgnutls.lib)
add_obj_lib (win32_argon2 ${WIN32_DEP_DIR}/argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib)
list (APPEND obj_libs
$<TARGET_OBJECTS:win32_json>
$<TARGET_OBJECTS:win32_gnutls>
$<TARGET_OBJECTS:win32_argon2>
)
if (OPENDHT_HTTP)
add_obj_lib (win32_fmt ${WIN32_DEP_DIR}/fmt/msvc/Release/fmt.lib)
add_obj_lib (win32_http_parser ${WIN32_DEP_DIR}/http_parser/x64/Release/http-parser.lib)
add_obj_lib (win32_ssl ${WIN32_DEP_DIR}/openssl/libssl_static.lib)
add_obj_lib (win32_crypto ${WIN32_DEP_DIR}/openssl/libcrypto_static.lib)
list (APPEND obj_libs
$<TARGET_OBJECTS:win32_fmt>
$<TARGET_OBJECTS:win32_http_parser>
$<TARGET_OBJECTS:win32_ssl>
$<TARGET_OBJECTS:win32_crypto>
)
endif ()
else ()
list (APPEND win32_Libs
${PROJECT_SOURCE_DIR}/../../msvc/lib/x64/libgnutls.lib
${PROJECT_SOURCE_DIR}/../../msvc/lib/x64/lib_json.lib
${PROJECT_SOURCE_DIR}/../argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib
)
list (APPEND win32_Libs
${PROJECT_SOURCE_DIR}/../fmt/msvc/Release/fmt.lib
${PROJECT_SOURCE_DIR}/../http_parser/x64/Release/http-parser.lib
${PROJECT_SOURCE_DIR}/../openssl/libssl.lib
${PROJECT_SOURCE_DIR}/../openssl/libcrypto.lib
)
endif ()
add_library (opendht-static STATIC
${opendht_SOURCES}
${opendht_HEADERS}
${obj_libs}
)
target_link_libraries(opendht-static PUBLIC ${Win32_STATIC_LIBRARIES} ${Win32_IMPORT_LIBRARIES})
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4006")
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "libopendht")
endif()
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht-static
PRIVATE ${argon2_LIBRARIES}
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
${OPENSSL_LIBRARIES})
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
@@ -379,21 +300,17 @@ if (OPENDHT_SHARED)
set_target_properties (opendht PROPERTIES IMPORT_SUFFIX "_import.lib")
set_target_properties (opendht PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
target_compile_definitions(opendht PRIVATE OPENDHT_BUILD)
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
if (APPLE)
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${argon2_LIBRARIES}
SYSTEM "-framework CoreFoundation" "-framework Security")
if (OPENDHT_ARGON2)
target_include_directories(opendht SYSTEM PRIVATE argon2)
else ()
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${argon2_LIBRARIES})
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
@@ -404,12 +321,7 @@ if (OPENDHT_C)
c/opendht_c.h
)
target_compile_definitions(opendht-c PRIVATE OPENDHT_C_BUILD)
if (OPENDHT_SHARED)
target_link_libraries(opendht-c opendht)
else ()
target_link_libraries(opendht-c opendht-static)
endif ()
target_link_libraries(opendht-c opendht)
# PkgConfig module
configure_file (
opendht-c.pc.in
@@ -418,7 +330,6 @@ if (OPENDHT_C)
)
install (TARGETS opendht-c DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht-c)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht-c.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install (FILES c/opendht_c.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/opendht)
endif ()
if (OPENDHT_TOOLS)
@@ -431,6 +342,7 @@ if (OPENDHT_PYTHON)
endif ()
# CMake module
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake"
VERSION ${opendht_VERSION}
COMPATIBILITY AnyNewerVersion
@@ -450,56 +362,46 @@ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATIO
# Unit tests
if (OPENDHT_TESTS)
pkg_search_module(Cppunit REQUIRED cppunit)
# unit testing
FIND_PACKAGE(Cppunit REQUIRED)
# unit testing
list (APPEND test_FILES
tests/infohashtester.h
tests/infohashtester.cpp
tests/valuetester.h
tests/valuetester.cpp
tests/cryptotester.h
tests/cryptotester.cpp
tests/dhtrunnertester.h
tests/dhtrunnertester.cpp
tests/threadpooltester.h
tests/threadpooltester.cpp
tests/infohashtester.h
tests/infohashtester.cpp
tests/valuetester.h
tests/valuetester.cpp
tests/cryptotester.h
tests/cryptotester.cpp
tests/dhtrunnertester.h
tests/dhtrunnertester.cpp
tests/peerdiscoverytester.h
tests/peerdiscoverytester.cpp
tests/threadpooltester.h
tests/threadpooltester.cpp
)
if (OPENDHT_TESTS_NETWORK)
if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT)
list (APPEND test_FILES
tests/httptester.h
tests/httptester.cpp
tests/dhtproxytester.h
tests/dhtproxytester.cpp
)
endif()
if (OPENDHT_PEER_DISCOVERY)
list (APPEND test_FILES
tests/peerdiscoverytester.h
tests/peerdiscoverytester.cpp
)
endif()
if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT)
list (APPEND test_FILES
tests/httptester.h
tests/httptester.cpp
tests/dhtproxytester.h
tests/dhtproxytester.cpp
)
endif()
add_executable(opendht_unit_tests
tests/tests_runner.cpp
${test_FILES}
tests/tests_runner.cpp
${test_FILES}
)
target_include_directories(opendht_unit_tests SYSTEM PRIVATE ${Cppunit_INCLUDE_DIR})
target_link_directories(opendht_unit_tests PRIVATE ${Cppunit_LIBRARY_DIRS})
target_include_directories(opendht_unit_tests SYSTEM PRIVATE ${CPPUNIT_INCLUDE_DIRS})
if (OPENDHT_SHARED)
target_link_libraries(opendht_unit_tests opendht)
target_link_libraries(opendht_unit_tests opendht)
else ()
target_link_libraries(opendht_unit_tests opendht-static)
target_link_libraries(opendht_unit_tests opendht-static)
endif ()
target_link_libraries(opendht_unit_tests
${CMAKE_THREAD_LIBS_INIT}
${Cppunit_LIBRARIES}
${CPPUNIT_LIBRARIES}
${GNUTLS_LIBRARIES}
${Jsoncpp_LIBRARIES}
ssl crypto jsoncpp
)
if (OPENDHT_PROXY_OPENSSL)
target_link_libraries(opendht_unit_tests ${OPENSSL_LIBRARIES})
endif()
enable_testing()
add_test(TEST opendht_unit_tests)
endif()
+248
View File
@@ -0,0 +1,248 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
#output directories
DebugLib/
Debug/
ReleaseLib/
Release/
.config/
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
*.VC.VC.opendb
*.VC.db
*.db
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/
!config.h
contrib/build/
+168
View File
@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}</ProjectGuid>
<RootNamespace>dhtchat</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(ProjectDir)..\..\bin\x64</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\tools\dhtchat.cpp" />
<ClCompile Include="wingetopt.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\tools\tools_common.h" />
<ClInclude Include="wingetopt.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+168
View File
@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}</ProjectGuid>
<RootNamespace>dhtnode</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(ProjectDir)..\..\bin\x64</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\tools\dhtnode.cpp" />
<ClCompile Include="wingetopt.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\tools\tools_common.h" />
<ClInclude Include="wingetopt.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+168
View File
@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{78443BCD-4689-4007-A246-F8F34B27F561}</ProjectGuid>
<RootNamespace>dhtscanner</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(ProjectDir)..\..\bin\x64</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\tools\dhtscanner.cpp" />
<ClCompile Include="wingetopt.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\tools\tools_common.h" />
<ClInclude Include="wingetopt.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+257
View File
@@ -0,0 +1,257 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opendht", "opendht.vcxproj", "{711397CE-E5D5-467D-9457-8716C047E50C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
DebugDLL|x64 = DebugDLL|x64
DebugDLL|x86 = DebugDLL|x86
DebugDLLStaticDeps|x64 = DebugDLLStaticDeps|x64
DebugDLLStaticDeps|x86 = DebugDLLStaticDeps|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
ReleaseDLL|x64 = ReleaseDLL|x64
ReleaseDLL|x86 = ReleaseDLL|x86
ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64
ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86
ReleaseLTO|x64 = ReleaseLTO|x64
ReleaseLTO|x86 = ReleaseLTO|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.ActiveCfg = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.Build.0 = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.ActiveCfg = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.Build.0 = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.ActiveCfg = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.Build.0 = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.ActiveCfg = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.Build.0 = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.Build.0 = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.Build.0 = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.ActiveCfg = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.Build.0 = Release|x64
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.Build.0 = Release|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.ActiveCfg = Debug|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.Build.0 = Debug|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.ActiveCfg = Debug|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.Build.0 = Debug|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.Build.0 = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.ActiveCfg = Release|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.Build.0 = Release|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.ActiveCfg = Release|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.Build.0 = Release|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.ActiveCfg = Debug|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.Build.0 = Debug|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.ActiveCfg = Debug|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.Build.0 = Debug|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.Build.0 = DebugDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.ActiveCfg = Release|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.Build.0 = Release|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.ActiveCfg = Release|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.Build.0 = Release|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.ActiveCfg = Debug|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.Build.0 = Debug|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.ActiveCfg = Debug|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.Build.0 = Debug|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.Build.0 = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.ActiveCfg = Release|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.Build.0 = Release|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.ActiveCfg = Release|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.Build.0 = Release|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.ActiveCfg = Debug|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.Build.0 = Debug|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.ActiveCfg = Debug|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.Build.0 = Debug|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.Build.0 = DebugDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.ActiveCfg = Release|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.Build.0 = Release|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.ActiveCfg = Release|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.Build.0 = Release|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.ActiveCfg = Debug|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.Build.0 = Debug|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.ActiveCfg = Debug|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.Build.0 = Debug|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.Build.0 = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.ActiveCfg = Release|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.Build.0 = Release|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.ActiveCfg = Release|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.Build.0 = Release|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.ActiveCfg = Debug|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.Build.0 = Debug|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.ActiveCfg = Debug|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.Build.0 = Debug|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.Build.0 = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.Build.0 = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.ActiveCfg = Release|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.Build.0 = Release|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.ActiveCfg = Release|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.Build.0 = Release|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.ActiveCfg = Debug|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.Build.0 = Debug|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.ActiveCfg = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.Build.0 = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.ActiveCfg = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.Build.0 = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.ActiveCfg = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.Build.0 = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.ActiveCfg = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.Build.0 = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x64.ActiveCfg = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x64.Build.0 = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.ActiveCfg = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.Build.0 = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.ActiveCfg = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.Build.0 = Release|x64
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.ActiveCfg = Release|Win32
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+271
View File
@@ -0,0 +1,271 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\dht_proxy_client.cpp" />
<ClCompile Include="..\src\http.cpp" />
<ClCompile Include="..\src\network_utils.cpp" />
<ClCompile Include="..\src\op_cache.cpp" />
<ClCompile Include="..\src\peer_discovery.cpp" />
<ClCompile Include="..\src\rng.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\src\thread_pool.cpp" />
<ClCompile Include="wingetopt.c" />
<ClCompile Include="..\src\base64.cpp" />
<ClCompile Include="..\src\callbacks.cpp" />
<ClCompile Include="..\src\crypto.cpp" />
<ClCompile Include="..\src\default_types.cpp" />
<ClCompile Include="..\src\dht.cpp" />
<ClCompile Include="..\src\dhtrunner.cpp" />
<ClCompile Include="..\src\dht_proxy_server.cpp" />
<ClCompile Include="..\src\indexation\pht.cpp" />
<ClCompile Include="..\src\infohash.cpp" />
<ClCompile Include="..\src\log.cpp" />
<ClCompile Include="..\src\network_engine.cpp" />
<ClCompile Include="..\src\node.cpp" />
<ClCompile Include="..\src\node_cache.cpp" />
<ClCompile Include="..\src\routing_table.cpp" />
<ClCompile Include="..\src\securedht.cpp" />
<ClCompile Include="..\src\utils.cpp" />
<ClCompile Include="..\src\value.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\opendht\http.h" />
<ClInclude Include="..\src\network_utils.h" />
<ClInclude Include="..\src\thread_pool.h" />
<ClInclude Include="unistd.h" />
<ClInclude Include="wingetopt.h" />
<ClInclude Include="..\include\opendht.h" />
<ClInclude Include="..\include\opendht\callbacks.h" />
<ClInclude Include="..\include\opendht\crypto.h" />
<ClInclude Include="..\include\opendht\def.h" />
<ClInclude Include="..\include\opendht\default_types.h" />
<ClInclude Include="..\include\opendht\dht.h" />
<ClInclude Include="..\include\opendht\dhtrunner.h" />
<ClInclude Include="..\include\opendht\dht_proxy_server.h" />
<ClInclude Include="..\include\opendht\indexation\pht.h" />
<ClInclude Include="..\include\opendht\infohash.h" />
<ClInclude Include="..\include\opendht\log.h" />
<ClInclude Include="..\include\opendht\log_enable.h" />
<ClInclude Include="..\include\opendht\network_engine.h" />
<ClInclude Include="..\include\opendht\node.h" />
<ClInclude Include="..\include\opendht\node_cache.h" />
<ClInclude Include="..\include\opendht\rate_limiter.h" />
<ClInclude Include="..\include\opendht\rng.h" />
<ClInclude Include="..\include\opendht\routing_table.h" />
<ClInclude Include="..\include\opendht\scheduler.h" />
<ClInclude Include="..\include\opendht\securedht.h" />
<ClInclude Include="..\include\opendht\sockaddr.h" />
<ClInclude Include="..\include\opendht\utils.h" />
<ClInclude Include="..\include\opendht\value.h" />
<ClInclude Include="..\src\base64.h" />
<ClInclude Include="..\src\listener.h" />
<ClInclude Include="..\src\net.h" />
<ClInclude Include="..\src\parsed_message.h" />
<ClInclude Include="..\src\request.h" />
<ClInclude Include="..\src\search.h" />
<ClInclude Include="..\src\storage.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{711397CE-E5D5-467D-9457-8716C047E50C}</ProjectGuid>
<RootNamespace>opendht</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
<TargetName>libopendht</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
<SuppressStartupBanner>false</SuppressStartupBanner>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<PostBuildEvent>
<Command>mkdir $(OutDir)\include
mkdir $(OutDir)\include\opendht
mkdir $(OutDir)\include\opendht\indexation
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<PostBuildEvent>
<Command>mkdir $(OutDir)\include
mkdir $(OutDir)\include\opendht
mkdir $(OutDir)\include\opendht\indexation
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>mkdir $(OutDir)\include
mkdir $(OutDir)\include\opendht
mkdir $(OutDir)\include\opendht\indexation
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PostBuildEvent>
<Command>mkdir $(OutDir)\include
mkdir $(OutDir)\include\opendht
mkdir $(OutDir)\include\opendht\indexation
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
copy ..\include\opendht\*.h $(OutDir)\include\opendht
copy ..\include\opendht.h $(OutDir)\include\</Command>
</PostBuildEvent>
<Lib>
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+198
View File
@@ -0,0 +1,198 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\src\callbacks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\crypto.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\default_types.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\dht.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\dhtrunner.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\infohash.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\log.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\network_engine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\node.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\node_cache.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\routing_table.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\securedht.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\value.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\base64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\dht_proxy_server.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\indexation\pht.cpp">
<Filter>Source Files\indexation</Filter>
</ClCompile>
<ClCompile Include="wingetopt.c" />
<ClCompile Include="..\src\rng.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\op_cache.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\dht_proxy_client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\peer_discovery.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\network_utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\thread_pool.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\http.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\opendht.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\callbacks.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\crypto.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\default_types.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\dht.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\dht_proxy_server.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\dhtrunner.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\infohash.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\log.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\log_enable.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\network_engine.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\node.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\node_cache.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\rate_limiter.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\rng.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\routing_table.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\scheduler.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\securedht.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\utils.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\value.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\indexation\pht.h">
<Filter>Header Files\opendht\indexation</Filter>
</ClInclude>
<ClInclude Include="unistd.h" />
<ClInclude Include="wingetopt.h" />
<ClInclude Include="..\include\opendht\def.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\net.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\parsed_message.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\sockaddr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\network_utils.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\src\thread_pool.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
<ClInclude Include="..\src\listener.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\base64.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\search.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\request.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\storage.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\include\opendht\http.h">
<Filter>Header Files\opendht</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{be73d179-6cf2-4c05-8d91-53c8499a7134}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{d1ab5bfe-3ab1-45ee-9324-b4b071887668}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\indexation">
<UniqueIdentifier>{939134d3-d5a2-4458-bca8-a10ea9042ea2}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\opendht">
<UniqueIdentifier>{0b46e2d0-4874-404c-bae3-fae8d49b85b8}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\opendht\indexation">
<UniqueIdentifier>{03bd5139-2ae5-41b0-a77b-944814e1b2b6}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
*
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
File renamed without changes.
File renamed without changes.
+2
View File
@@ -16,7 +16,9 @@ if ENABLE_TESTS
SUBDIRS += tests
endif
if HAVE_DOXYGEN
SUBDIRS += doc
endif
ACLOCAL_AMFLAGS = -I m4
+11 -11
View File
@@ -4,7 +4,7 @@
<a id="user-content-opendht-" class="anchor" href="/savoirfairelinux/opendht/blob/master/README.md#opendht-" aria-hidden="true"></a>OpenDHT
</h1>
A lightweight C++17 Distributed Hash Table implementation.
A lightweight C++14 Distributed Hash Table implementation.
OpenDHT provides an easy to use distributed in-memory data store.
Every node in the network can read and write values to the store.
@@ -14,9 +14,9 @@ Values are distributed over the network, with redundancy.
* High resilience to network disruption
* Public key cryptography layer providing optional data signature and encryption (using GnuTLS)
* IPv4 and IPv6 support
* Clean and powerful **C++17** map API
* Bindings for **C, Rust & Python 3**
* REST API with optional HTTP client+server with push notification support
* Clean and powerful C++14 map API
* Python 3 bindings
* REST API
## Documentation
See the wiki: <https://github.com/savoirfairelinux/opendht/wiki>
@@ -27,7 +27,7 @@ Build instructions: <https://github.com/savoirfairelinux/opendht/wiki/Build-the-
#### How-to build a simple client app
```bash
g++ main.cpp -std=c++17 -lopendht
g++ main.cpp -std=c++14 -lopendht -lgnutls
```
## Examples
@@ -51,7 +51,7 @@ int main()
// Join the network through any running node,
// here using a known bootstrap node.
node.bootstrap("bootstrap.jami.net", "4222");
node.bootstrap("bootstrap.ring.cx", "4222");
// put some data on the dht
std::vector<uint8_t> some_data(5, 10);
@@ -82,7 +82,7 @@ node.run()
# Join the network through any running node,
# here using a known bootstrap node.
node.bootstrap("bootstrap.jami.net", "4222")
node.bootstrap("bootstrap.ring.cx", "4222")
# blocking call (provide callback arguments to make the call non-blocking)
node.put(dht.InfoHash.get("unique_key"), dht.Value(b'some binary data'))
@@ -98,15 +98,15 @@ for r in results:
- Nettle 2.4+, a GnuTLS dependency for crypto.
- (optional) restinio used for the REST API.
- (optional) jsoncpp 1.7.4-3+, used for the REST API.
- Build tested with GCC 7+ (GNU/Linux, Windows with MinGW), Clang/LLVM (GNU/Linux, Android, macOS, iOS).
- Build tested with Microsoft Visual Studio 2017, 2019, 2022
- Build tested with GCC 5.2+ (GNU/Linux, Windows with MinGW), Clang/LLVM (GNU/Linux, Android, macOS, iOS).
- Build tested with Microsoft Visual Studio 2015, 2017, 2019
## Contact
IRC: join us on Libera.chat at [`#opendht`](https://web.libera.chat/#opendht).
IRC: join us on Freenode at [`#opendht`](https://webchat.freenode.net/?channels=%23opendht).
## License
Copyright (C) 2014-2022 Savoir-faire Linux Inc.
Copyright (C) 2014-2019 Savoir-faire Linux Inc.
OpenDHT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
Submodule
+1
Submodule argon2 added at 670229c849.
+1
View File
@@ -1 +1,2 @@
git submodule update --init
autoreconf --install --verbose -Wall
+61 -246
View File
@@ -1,49 +1,15 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "opendht_c.h"
#include "opendht.h"
using ValueSp = std::shared_ptr<dht::Value>;
using PrivkeySp = std::shared_ptr<dht::crypto::PrivateKey>;
using PubkeySp = std::shared_ptr<const dht::crypto::PublicKey>;
using CertSp = std::shared_ptr<dht::crypto::Certificate>;
#ifdef __cplusplus
extern "C" {
#endif
#include <errno.h>
// dht::InfoHash
inline dht_infohash dht_infohash_to_c(const dht::InfoHash& h) {
dht_infohash ret;
*reinterpret_cast<dht::InfoHash*>(&ret) = h;
return ret;
}
inline dht_pkid dht_pkid_to_c(const dht::PkId& h) {
dht_pkid ret;
*reinterpret_cast<dht::PkId*>(&ret) = h;
return ret;
}
const char* dht_infohash_print(const dht_infohash* h) {
return reinterpret_cast<const dht::InfoHash*>(h)->to_c_str();
}
@@ -60,18 +26,10 @@ void dht_infohash_get(dht_infohash* h, const uint8_t* dat, size_t dat_size) {
*reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::get(dat, dat_size);
}
void dht_infohash_get_from_string(dht_infohash* h, const char* dat) {
*reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::get((const uint8_t*)dat, (size_t)strlen(dat));
}
bool dht_infohash_is_zero(const dht_infohash* h) {
return !static_cast<bool>(*reinterpret_cast<const dht::InfoHash*>(h));
}
void dht_infohash_from_hex(dht_infohash* h, const char* dat) {
*h = dht_infohash_to_c(dht::InfoHash(std::string(dat, HASH_LEN*2)));
}
const char* dht_pkid_print(const dht_pkid* h) {
return reinterpret_cast<const dht::PkId*>(h)->to_c_str();
}
@@ -102,35 +60,10 @@ dht_value_id dht_value_get_id(const dht_value* data) {
return vsp->id;
}
dht_publickey* dht_value_get_owner(const dht_value* data) {
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
return vsp->owner ? reinterpret_cast<dht_publickey*>(new PubkeySp(vsp->owner)) : nullptr;
}
dht_infohash dht_value_get_recipient(const dht_value* data) {
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
return dht_infohash_to_c(vsp->recipient);
}
const char* dht_value_get_user_type(const dht_value* data) {
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
return vsp->user_type.c_str();
}
void dht_value_set_user_type(dht_value* data, const char* user_type) {
(*reinterpret_cast<ValueSp*>(data))->user_type = user_type;
}
dht_value* dht_value_new(const uint8_t* data, size_t size) {
return reinterpret_cast<dht_value*>(new ValueSp(std::make_shared<dht::Value>(data, size)));
}
dht_value* dht_value_new_from_string(const char* str) {
ValueSp value = std::make_shared<dht::Value>((const uint8_t*)str, strlen(str));
value->user_type = "text/plain";
return reinterpret_cast<dht_value*>(new ValueSp(std::move(value)));
}
dht_value* dht_value_ref(const dht_value* v) {
return reinterpret_cast<dht_value*>(new ValueSp(*reinterpret_cast<const ValueSp*>(v)));
}
@@ -140,50 +73,51 @@ void dht_value_unref(dht_value* v) {
}
// dht::crypto::PublicKey
dht_publickey* dht_publickey_import(const uint8_t* dat, size_t dat_size) {
try {
return reinterpret_cast<dht_publickey*>(new PubkeySp(std::make_shared<const dht::crypto::PublicKey>(dat, dat_size)));
} catch (const dht::crypto::CryptoException& e) {
return nullptr;
}
dht_publickey* dht_publickey_new() {
return reinterpret_cast<dht_publickey*>(new dht::crypto::PublicKey);
}
void dht_publickey_delete(dht_publickey* pk) {
delete reinterpret_cast<PubkeySp*>(pk);
delete reinterpret_cast<dht::crypto::PublicKey*>(pk);
}
int dht_publickey_export(const dht_publickey* pk, char* out, size_t* outlen) {
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
return pkey->pack((uint8_t*)out, outlen);
int dht_publickey_unpack(dht_publickey* pk, const uint8_t* dat, size_t dat_size) {
try {
reinterpret_cast<dht::crypto::PublicKey*>(pk)->unpack(dat, dat_size);
} catch (const dht::crypto::CryptoException& e) {
return -1;
}
return 0;
}
int dht_publickey_pack(dht_publickey* pk, char* out, size_t* outlen) {
return gnutls_pubkey_export(reinterpret_cast<dht::crypto::PublicKey*>(pk)->pk, GNUTLS_X509_FMT_DER, out, outlen);
}
dht_infohash dht_publickey_get_id(const dht_publickey* pk) {
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
return dht_infohash_to_c(pkey->getId());
auto pkey = reinterpret_cast<const dht::crypto::PublicKey*>(pk);
dht_infohash h;
*reinterpret_cast<dht::InfoHash*>(&h) = pkey->getId();
return h;
}
dht_pkid dht_publickey_get_long_id(const dht_publickey* pk) {
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
return dht_pkid_to_c(pkey->getLongId());
auto pkey = reinterpret_cast<const dht::crypto::PublicKey*>(pk);
dht_pkid h;
*reinterpret_cast<dht::PkId*>(&h) = pkey->getLongId();
return h;
}
bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, size_t data_size, const char* signature, size_t signature_size) {
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
return pkey->checkSignature((const uint8_t*)data, data_size, (const uint8_t*)signature, signature_size);
return reinterpret_cast<const dht::crypto::PublicKey*>(pk)->checkSignature((const uint8_t*)data, data_size, (const uint8_t*)signature, signature_size);
}
dht_blob* dht_publickey_encrypt(const dht_publickey* pk, const char* data, size_t data_size) {
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
try {
auto rdata = std::make_unique<dht::Blob>();
*rdata = pkey->encrypt((const uint8_t*)data, data_size);
return (dht_blob*)rdata.release();
} catch (...) {
return nullptr;
}
auto rdata = new dht::Blob;
*rdata = reinterpret_cast<const dht::crypto::PublicKey*>(pk)->encrypt((const uint8_t*)data, data_size);
return (dht_blob*)rdata;
}
// dht::crypto::PrivateKey
dht_privatekey* dht_privatekey_generate(unsigned key_length_bits) {
if (key_length_bits == 0)
key_length_bits = 4096;
@@ -198,93 +132,15 @@ dht_privatekey* dht_privatekey_import(const uint8_t* dat, size_t dat_size, const
}
}
int dht_privatekey_export(const dht_privatekey* k, char* out, size_t* out_size, const char* password) {
if (!out or !out_size or !*out_size)
return -1;
const auto& key = *reinterpret_cast<const PrivkeySp*>(k);
return key->serialize((uint8_t*)out, out_size, password);
}
dht_publickey* dht_privatekey_get_publickey(const dht_privatekey* k) {
const auto& key = *reinterpret_cast<const PrivkeySp*>(k);
return reinterpret_cast<dht_publickey*>(new PubkeySp(key->getSharedPublicKey()));
}
dht_blob* dht_privatekey_decrypt(const dht_privatekey* k, const char* data, size_t data_size) {
const auto& key = *reinterpret_cast<const PrivkeySp*>(k);
try {
auto rdata = std::make_unique<dht::Blob>();
*rdata = key->decrypt((const uint8_t*)data, data_size);
return (dht_blob*)rdata.release();
} catch (...) {
return nullptr;
}
return reinterpret_cast<dht_publickey*>(new dht::crypto::PublicKey(key->getPublicKey()));
}
void dht_privatekey_delete(dht_privatekey* pk) {
delete reinterpret_cast<PrivkeySp*>(pk);
}
// dht::crypto::Certificate
dht_certificate* dht_certificate_import(const uint8_t* dat, size_t dat_size) {
try {
return reinterpret_cast<dht_certificate*>(new CertSp(std::make_shared<dht::crypto::Certificate>(dat, dat_size)));
} catch (const dht::crypto::CryptoException& e) {
return nullptr;
}
}
void dht_certificate_delete(dht_certificate* c) {
delete reinterpret_cast<CertSp*>(c);
}
dht_infohash dht_certificate_get_id(const dht_certificate* c) {
const auto& cert = *reinterpret_cast<const CertSp*>(c);
return dht_infohash_to_c(cert->getId());
}
dht_pkid dht_certificate_get_long_id(const dht_certificate* c) {
const auto& cert = *reinterpret_cast<const CertSp*>(c);
return dht_pkid_to_c(cert->getLongId());
}
dht_publickey* dht_certificate_get_publickey(const dht_certificate* c) {
const auto& cert = *reinterpret_cast<const CertSp*>(c);
return reinterpret_cast<dht_publickey*>(new PubkeySp(std::make_shared<dht::crypto::PublicKey>(cert->getPublicKey())));
}
// dht::crypto::Identity
inline dht::crypto::Identity dht_identity_from_c(const dht_identity* cid) {
dht::crypto::Identity id {};
if (cid and cid->privatekey)
id.first = *reinterpret_cast<const PrivkeySp*>(cid->privatekey);
if (cid and cid->certificate)
id.second = *reinterpret_cast<const CertSp*>(cid->certificate);
return id;
}
inline dht_identity dht_identity_to_c(const dht::crypto::Identity& id) {
dht_identity cid {};
cid.privatekey = id.first ? reinterpret_cast<dht_privatekey*>(new PrivkeySp(id.first)) : NULL;
cid.certificate = id.second ? reinterpret_cast<dht_certificate*>(new CertSp(id.second)) : NULL;
return cid;
}
OPENDHT_C_PUBLIC dht_identity dht_identity_generate(const char* common_name, const dht_identity* ca) {
return dht_identity_to_c(dht::crypto::generateIdentity(common_name, dht_identity_from_c(ca)));
}
OPENDHT_C_PUBLIC void dht_identity_delete(dht_identity* id) {
if (id->certificate) {
dht_certificate_delete(id->certificate);
id->certificate = NULL;
}
if (id->privatekey) {
dht_privatekey_delete(id->privatekey);
id->privatekey = NULL;
}
}
// config
void dht_runner_config_default(dht_runner_config* config) {
bzero(config, sizeof(dht_runner_config));
@@ -292,7 +148,7 @@ void dht_runner_config_default(dht_runner_config* config) {
}
// dht::DhtRunner
dht_runner* dht_runner_new(void) {
dht_runner* dht_runner_new() {
return reinterpret_cast<dht_runner*>(new dht::DhtRunner);
}
@@ -300,55 +156,39 @@ void dht_runner_delete(dht_runner* runner) {
delete reinterpret_cast<dht::DhtRunner*>(runner);
}
int dht_runner_run(dht_runner* r, in_port_t port) {
void dht_runner_run(dht_runner* r, in_port_t port) {
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
try {
runner->run(port, {}, true);
} catch(...) {
return ENOTCONN;
}
return 0;
runner->run(port, {}, true);
}
int dht_runner_run_config(dht_runner* r, in_port_t port, const dht_runner_config* conf) {
void dht_runner_run_config(dht_runner* r, in_port_t port, const dht_runner_config* conf) {
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
try {
dht::DhtRunner::Config config;
config.dht_config.node_config.is_bootstrap = conf->dht_config.node_config.is_bootstrap;
config.dht_config.node_config.maintain_storage = conf->dht_config.node_config.maintain_storage;
config.dht_config.node_config.node_id = *reinterpret_cast<const dht::InfoHash*>(&conf->dht_config.node_config.node_id);
config.dht_config.node_config.network = conf->dht_config.node_config.network;
config.dht_config.node_config.persist_path = conf->dht_config.node_config.persist_path
? std::string(conf->dht_config.node_config.persist_path) : std::string{};
dht::DhtRunner::Config config;
config.dht_config.node_config.is_bootstrap = conf->dht_config.node_config.is_bootstrap;
config.dht_config.node_config.maintain_storage = conf->dht_config.node_config.maintain_storage;
config.dht_config.node_config.node_id = *reinterpret_cast<const dht::InfoHash*>(&conf->dht_config.node_config.node_id);
config.dht_config.node_config.network = conf->dht_config.node_config.network;
config.dht_config.node_config.persist_path = conf->dht_config.node_config.persist_path
? std::string(conf->dht_config.node_config.persist_path) : std::string{};
if (conf->dht_config.id.privatekey)
config.dht_config.id.first = *reinterpret_cast<const PrivkeySp*>(conf->dht_config.id.privatekey);
if (conf->dht_config.id.privkey)
config.dht_config.id.first = *reinterpret_cast<const PrivkeySp*>(conf->dht_config.id.privkey);
if (conf->dht_config.id.certificate)
config.dht_config.id.second = *reinterpret_cast<const CertSp*>(conf->dht_config.id.certificate);
if (conf->dht_config.id.certificate)
config.dht_config.id.second = *reinterpret_cast<const CertSp*>(conf->dht_config.id.certificate);
config.threaded = conf->threaded;
config.proxy_server = conf->proxy_server ? std::string(conf->proxy_server) : std::string{};
config.push_node_id = conf->push_node_id ? std::string(conf->push_node_id) : std::string{};
config.push_token = conf->push_token ? std::string(conf->push_token) : std::string{};
config.peer_discovery = conf->peer_discovery;
config.peer_publish = conf->peer_publish;
runner->run(port, config);
} catch(...) {
return ENOTCONN;
}
return 0;
config.threaded = conf->threaded;
config.proxy_server = conf->proxy_server ? std::string(conf->proxy_server) : std::string{};
config.push_node_id = conf->push_node_id ? std::string(conf->push_node_id) : std::string{};
config.push_token = conf->push_token ? std::string(conf->push_token) : std::string{};
config.peer_discovery = conf->peer_discovery;
config.peer_publish = conf->peer_publish;
runner->run(port, config);
}
void dht_runner_ping(dht_runner* r, struct sockaddr* addr, socklen_t addr_len, dht_done_cb done_cb, void* cb_user_data) {
void dht_runner_ping(dht_runner* r, struct sockaddr* addr, socklen_t addr_len) {
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
if (done_cb) {
runner->bootstrap(dht::SockAddr(addr, addr_len), [done_cb, cb_user_data](bool ok){
done_cb(ok, cb_user_data);
});
} else {
runner->bootstrap(dht::SockAddr(addr, addr_len));
}
runner->bootstrap(dht::SockAddr(addr, addr_len));
}
void dht_runner_bootstrap(dht_runner* r, const char* host, const char* service) {
@@ -387,11 +227,8 @@ dht_op_token* dht_runner_listen(dht_runner* r, const dht_infohash* h, dht_value_
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
auto fret = new std::future<size_t>;
*fret = runner->listen(*hash, [
cb,
cb_user_data,
guard = done_cb ? std::make_shared<ScopeGuardCb>(done_cb, cb_user_data) : std::shared_ptr<ScopeGuardCb>{}
](const std::vector<std::shared_ptr<dht::Value>>& values, bool expired) {
auto guard = done_cb ? std::make_shared<ScopeGuardCb>(done_cb, cb_user_data) : std::shared_ptr<ScopeGuardCb>{};
*fret = runner->listen(*hash, [cb,cb_user_data, guard](const std::vector<std::shared_ptr<dht::Value>>& values, bool expired) {
for (const auto& value : values) {
if (not cb(reinterpret_cast<const dht_value*>(&value), expired, cb_user_data))
return false;
@@ -412,35 +249,24 @@ void dht_op_token_delete(dht_op_token* token) {
delete reinterpret_cast<std::future<size_t>*>(token);
}
void dht_runner_put(dht_runner* r, const dht_infohash* h, const dht_value* v, dht_done_cb done_cb, void* cb_user_data, bool permanent) {
void dht_runner_put(dht_runner* r, const dht_infohash* h, const dht_value* v, dht_done_cb done_cb, void* cb_user_data) {
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
auto value = reinterpret_cast<const ValueSp*>(v);
runner->put(*hash, *value, [done_cb, cb_user_data](bool ok){
if (done_cb)
done_cb(ok, cb_user_data);
}, dht::time_point::max(), permanent);
});
}
void dht_runner_put_signed(dht_runner* r, const dht_infohash* h, const dht_value* v, dht_done_cb done_cb, void* cb_user_data, bool permanent) {
void dht_runner_put_permanent(dht_runner* r, const dht_infohash* h, const dht_value* v, dht_done_cb done_cb, void* cb_user_data) {
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
auto value = reinterpret_cast<const ValueSp*>(v);
runner->putSigned(*hash, *value, [done_cb, cb_user_data](bool ok){
runner->put(*hash, *value, [done_cb, cb_user_data](bool ok){
if (done_cb)
done_cb(ok, cb_user_data);
}, permanent);
}
void dht_runner_put_encrypted(dht_runner* r, const dht_infohash* h, const dht_infohash* to, const dht_value* v, dht_done_cb done_cb, void* cb_user_data, bool permanent) {
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
auto toHash = reinterpret_cast<const dht::InfoHash*>(to);
auto value = reinterpret_cast<const ValueSp*>(v);
runner->putEncrypted(*hash, *toHash, *value, [done_cb, cb_user_data](bool ok){
if (done_cb)
done_cb(ok, cb_user_data);
}, permanent);
}, dht::time_point::max(), true);
}
void dht_runner_cancel_put(dht_runner* r, const dht_infohash* h, dht_value_id value_id) {
@@ -457,17 +283,6 @@ void dht_runner_shutdown(dht_runner* r, dht_shutdown_cb done_cb, void* cb_user_d
});
}
bool dht_runner_is_running(const dht_runner* r) {
if (not r) return false;
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
return runner->isRunning();
}
in_port_t dht_runner_get_bound_port(const dht_runner* r, sa_family_t af) {
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
return runner->getBoundPort(af);
}
dht_infohash dht_runner_get_node_id(const dht_runner* r) {
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
dht_infohash ret;
@@ -489,9 +304,9 @@ struct sockaddr** dht_runner_get_public_address(const dht_runner* r) {
return nullptr;
auto ret = (struct sockaddr**)malloc(sizeof(struct sockaddr*) * (addrs.size() + 1));
for (size_t i=0; i<addrs.size(); i++) {
if (const auto& addr = addrs[i]) {
ret[i] = (struct sockaddr*)malloc(addr.getLength());
memcpy((struct sockaddr*)ret[i], addr.get(), addr.getLength());
if (auto len = addrs[i].getLength()) {
ret[i] = (struct sockaddr*)malloc(len);
memcpy((struct sockaddr*)ret[i], addrs[i].get(), len);
} else {
ret[i] = nullptr;
}
+24 -62
View File
@@ -1,21 +1,3 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef __cplusplus
@@ -36,6 +18,16 @@ struct OPENDHT_C_PUBLIC dht_data_view {
};
typedef struct dht_data_view dht_data_view;
// dht::Value
struct OPENDHT_C_PUBLIC dht_value;
typedef struct dht_value dht_value;
typedef uint64_t dht_value_id;
OPENDHT_C_PUBLIC dht_data_view dht_value_get_data(const dht_value* data);
OPENDHT_C_PUBLIC dht_value_id dht_value_get_id(const dht_value* data);
OPENDHT_C_PUBLIC dht_value* dht_value_new(const uint8_t* data, size_t size);
OPENDHT_C_PUBLIC dht_value* dht_value_ref(const dht_value*);
OPENDHT_C_PUBLIC void dht_value_unref(dht_value*);
// dht::Blob
struct OPENDHT_C_PUBLIC dht_blob;
typedef struct dht_blob dht_blob;
@@ -47,9 +39,7 @@ struct OPENDHT_C_PUBLIC dht_infohash { uint8_t d[HASH_LEN]; };
typedef struct dht_infohash dht_infohash;
OPENDHT_C_PUBLIC void dht_infohash_zero(dht_infohash* h);
OPENDHT_C_PUBLIC void dht_infohash_random(dht_infohash* h);
OPENDHT_C_PUBLIC void dht_infohash_from_hex(dht_infohash* h, const char* dat);
OPENDHT_C_PUBLIC void dht_infohash_get(dht_infohash* h, const uint8_t* dat, size_t dat_size);
OPENDHT_C_PUBLIC void dht_infohash_get_from_string(dht_infohash* h, const char* str);
OPENDHT_C_PUBLIC const char* dht_infohash_print(const dht_infohash* h);
OPENDHT_C_PUBLIC bool dht_infohash_is_zero(const dht_infohash* h);
@@ -61,9 +51,10 @@ OPENDHT_C_PUBLIC const char* dht_pkid_print(const dht_pkid* h);
// dht::crypto::PublicKey
struct OPENDHT_C_PUBLIC dht_publickey;
typedef struct dht_publickey dht_publickey;
OPENDHT_C_PUBLIC dht_publickey* dht_publickey_import(const uint8_t* dat, size_t dat_size);
OPENDHT_C_PUBLIC dht_publickey* dht_publickey_new();
OPENDHT_C_PUBLIC void dht_publickey_delete(dht_publickey* pk);
OPENDHT_C_PUBLIC int dht_publickey_export(const dht_publickey* pk, char* out, size_t* out_size);
OPENDHT_C_PUBLIC int dht_publickey_unpack(dht_publickey* pk, const uint8_t* dat, size_t dat_size);
OPENDHT_C_PUBLIC int dht_publickey_pack(dht_publickey* pk, char* out, size_t* out_size);
OPENDHT_C_PUBLIC dht_infohash dht_publickey_get_id(const dht_publickey* pk);
OPENDHT_C_PUBLIC dht_pkid dht_publickey_get_long_id(const dht_publickey* pk);
OPENDHT_C_PUBLIC bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, size_t data_size, const char* signature, size_t signature_size);
@@ -74,48 +65,24 @@ struct OPENDHT_C_PUBLIC dht_privatekey;
typedef struct dht_privatekey dht_privatekey;
OPENDHT_C_PUBLIC dht_privatekey* dht_privatekey_generate(unsigned key_length_bits);
OPENDHT_C_PUBLIC dht_privatekey* dht_privatekey_import(const uint8_t* dat, size_t dat_size, const char* password);
OPENDHT_C_PUBLIC int dht_privatekey_export(const dht_privatekey*, char* out, size_t* out_size, const char* password);
OPENDHT_C_PUBLIC dht_publickey* dht_privatekey_get_publickey(const dht_privatekey*);
OPENDHT_C_PUBLIC dht_blob* dht_privatekey_decrypt(const dht_privatekey*, const char* data, size_t data_size);
OPENDHT_C_PUBLIC void dht_privatekey_delete(dht_privatekey*);
// dht::crypto::Certificate
struct OPENDHT_C_PUBLIC dht_certificate;
typedef struct dht_certificate dht_certificate;
OPENDHT_C_PUBLIC dht_certificate* dht_certificate_import(const uint8_t* dat, size_t dat_size);
OPENDHT_C_PUBLIC dht_infohash dht_certificate_get_id(const dht_certificate*);
OPENDHT_C_PUBLIC dht_pkid dht_certificate_get_long_id(const dht_certificate*);
OPENDHT_C_PUBLIC dht_publickey* dht_certificate_get_publickey(const dht_certificate*);
OPENDHT_C_PUBLIC void dht_certificate_delete(dht_certificate*);
struct OPENDHT_PUBLIC dht_identity {
dht_privatekey* privatekey;
dht_privatekey* privkey;
dht_certificate* certificate;
};
typedef struct dht_identity dht_identity;
OPENDHT_C_PUBLIC dht_identity dht_identity_generate(const char* common_name, const dht_identity* ca);
OPENDHT_C_PUBLIC void dht_identity_delete(dht_identity*);
// dht::Value
struct OPENDHT_C_PUBLIC dht_value;
typedef struct dht_value dht_value;
typedef uint64_t dht_value_id;
OPENDHT_C_PUBLIC dht_value* dht_value_new(const uint8_t* data, size_t size);
OPENDHT_C_PUBLIC dht_value* dht_value_new_from_string(const char* str);
OPENDHT_C_PUBLIC dht_value* dht_value_ref(const dht_value*);
OPENDHT_C_PUBLIC void dht_value_unref(dht_value*);
OPENDHT_C_PUBLIC dht_data_view dht_value_get_data(const dht_value* data);
OPENDHT_C_PUBLIC dht_value_id dht_value_get_id(const dht_value* data);
OPENDHT_C_PUBLIC dht_publickey* dht_value_get_owner(const dht_value* data);
OPENDHT_C_PUBLIC dht_infohash dht_value_get_recipient(const dht_value* data);
OPENDHT_C_PUBLIC const char* dht_value_get_user_type(const dht_value* data);
OPENDHT_C_PUBLIC void dht_value_set_user_type(dht_value* data, const char* user_type);
// callbacks
typedef bool (*dht_get_cb)(const dht_value* value, void* user_data);
typedef bool (*dht_value_cb)(const dht_value* value, bool expired, void* user_data);
typedef void (*dht_done_cb)(bool ok, void* user_data);
typedef void (*dht_shutdown_cb)(void* user_data);
typedef bool (*dht_done_cb)(bool ok, void* user_data);
typedef bool (*dht_shutdown_cb)(void* user_data);
struct OPENDHT_C_PUBLIC dht_op_token;
typedef struct dht_op_token dht_op_token;
@@ -131,7 +98,8 @@ struct OPENDHT_PUBLIC dht_node_config {
};
typedef struct dht_node_config dht_node_config;
struct OPENDHT_PUBLIC dht_secure_config {
struct OPENDHT_PUBLIC dht_secure_config
{
dht_node_config node_config;
dht_identity id;
};
@@ -154,27 +122,21 @@ OPENDHT_C_PUBLIC void dht_runner_config_default(dht_runner_config* config);
// dht::DhtRunner
struct OPENDHT_C_PUBLIC dht_runner;
typedef struct dht_runner dht_runner;
OPENDHT_C_PUBLIC dht_runner* dht_runner_new(void);
OPENDHT_C_PUBLIC dht_runner* dht_runner_new();
OPENDHT_C_PUBLIC void dht_runner_delete(dht_runner* runner);
/* Returns 0 on success, standard error code on failure */
OPENDHT_C_PUBLIC int dht_runner_run(dht_runner* runner, in_port_t port);
/* Returns 0 on success, standard error code on failure */
OPENDHT_C_PUBLIC int dht_runner_run_config(dht_runner* runner, in_port_t port, const dht_runner_config* config);
OPENDHT_C_PUBLIC void dht_runner_ping(dht_runner* runner, struct sockaddr* addr, socklen_t addr_len, dht_done_cb done_cb, void* cb_user_data);
OPENDHT_C_PUBLIC void dht_runner_run(dht_runner* runner, in_port_t port);
OPENDHT_C_PUBLIC void dht_runner_run_config(dht_runner* runner, in_port_t port, const dht_runner_config* config);
OPENDHT_C_PUBLIC void dht_runner_ping(dht_runner* runner, struct sockaddr* addr, socklen_t addr_len);
OPENDHT_C_PUBLIC void dht_runner_bootstrap(dht_runner* runner, const char* host, const char* service);
OPENDHT_C_PUBLIC void dht_runner_get(dht_runner* runner, const dht_infohash* hash, dht_get_cb cb, dht_done_cb done_cb, void* cb_user_data);
OPENDHT_C_PUBLIC dht_op_token* dht_runner_listen(dht_runner* runner, const dht_infohash* hash, dht_value_cb cb, dht_shutdown_cb done_cb, void* cb_user_data);
OPENDHT_C_PUBLIC void dht_runner_cancel_listen(dht_runner* runner, const dht_infohash* hash, dht_op_token* token);
OPENDHT_C_PUBLIC void dht_runner_put(dht_runner* runner, const dht_infohash* hash, const dht_value* value, dht_done_cb done_cb, void* cb_user_data, bool permanent);
OPENDHT_C_PUBLIC void dht_runner_put_signed(dht_runner* runner, const dht_infohash* hash, const dht_value* value, dht_done_cb done_cb, void* cb_user_data, bool permanent);
OPENDHT_C_PUBLIC void dht_runner_put_encrypted(dht_runner* runner, const dht_infohash* hash, const dht_infohash* to, const dht_value* value, dht_done_cb done_cb, void* cb_user_data, bool permanent);
OPENDHT_C_PUBLIC void dht_runner_put(dht_runner* runner, const dht_infohash* hash, const dht_value* value, dht_done_cb done_cb, void* cb_user_data);
OPENDHT_C_PUBLIC void dht_runner_put_permanent(dht_runner* runner, const dht_infohash* hash, const dht_value* value, dht_done_cb done_cb, void* cb_user_data);
OPENDHT_C_PUBLIC void dht_runner_cancel_put(dht_runner* runner, const dht_infohash* hash, dht_value_id value_id);
OPENDHT_C_PUBLIC void dht_runner_shutdown(dht_runner* runner, dht_shutdown_cb done_cb, void* cb_user_data);
OPENDHT_C_PUBLIC dht_infohash dht_runner_get_node_id(const dht_runner* runner);
OPENDHT_C_PUBLIC dht_infohash dht_runner_get_id(const dht_runner* runner);
OPENDHT_C_PUBLIC bool dht_runner_is_running(const dht_runner* runner);
OPENDHT_C_PUBLIC in_port_t dht_runner_get_bound_port(const dht_runner* runner, sa_family_t af);
/** Returns null-terminated array that must be freed after use as well as each element */
OPENDHT_C_PUBLIC struct sockaddr** dht_runner_get_public_address(const dht_runner* runner);
#ifdef __cplusplus
-100
View File
@@ -1,100 +0,0 @@
# atomic builtins are required for threading support.
INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckLibraryExists)
# Sometimes linking against libatomic is required for atomic ops, if
# the platform doesn't support lock-free atomics.
function(check_working_cxx_atomics varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
std::atomic<int> x;
std::atomic<short> y;
std::atomic<char> z;
int main() {
++z;
++y;
return ++x;
}
" ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
endfunction(check_working_cxx_atomics)
function(check_working_cxx_atomics64 varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
#include <cstdint>
std::atomic<uint64_t> x (0);
int main() {
uint64_t i = x.load(std::memory_order_relaxed);
return 0;
}
" ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
endfunction(check_working_cxx_atomics64)
# This isn't necessary on MSVC, so avoid command-line switch annoyance
# by only running on GCC-like hosts.
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
# First check if atomics work without the library.
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
endif()
endif()
# Check for 64 bit atomic operations.
if(MSVC)
set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
else()
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
endif()
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
endif()
endif()
## TODO: This define is only used for the legacy atomic operations in
## llvm's Atomic.h, which should be replaced. Other code simply
## assumes C++11 <atomic> works.
CHECK_CXX_SOURCE_COMPILES("
#ifdef _MSC_VER
#include <windows.h>
#endif
int main() {
#ifdef _MSC_VER
volatile LONG val = 1;
MemoryBarrier();
InterlockedCompareExchange(&val, 0, 1);
InterlockedIncrement(&val);
InterlockedDecrement(&val);
#else
volatile unsigned long val = 1;
__sync_synchronize();
__sync_val_compare_and_swap(&val, 1, 0);
__sync_add_and_fetch(&val, 1);
__sync_sub_and_fetch(&val, 1);
#endif
return 0;
}
" LLVM_HAS_ATOMICS)
if( NOT LLVM_HAS_ATOMICS )
message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
endif()
+28
View File
@@ -0,0 +1,28 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_CPPUNIT "cppunit")
FIND_PATH(CPPUNIT_INCLUDE_DIRS
NAMES cppunit/TestCase.h
HINTS ${PC_CPPUNIT_INCLUDE_DIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS
/usr/local/include
/usr/include
)
FIND_LIBRARY(CPPUNIT_LIBRARIES
NAMES cppunit
HINTS ${PC_CPPUNIT_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
PATHS
${CPPUNIT_INCLUDE_DIRS}/../lib
/usr/local/lib
/usr/lib
)
LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
+64
View File
@@ -0,0 +1,64 @@
# - Try to find msgpack
# Once done this will define
# MSGPACK_FOUND - System has msgpack
# MSGPACK_INCLUDE_DIRS - The msgpack include directories
# MSGPACK_LIBRARIES - The libraries needed to use msgpack
if(NOT MSGPACK_USE_BUNDLED)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_search_module(PC_MSGPACK QUIET
msgpackc>=${Msgpack_FIND_VERSION}
msgpack>=${Msgpack_FIND_VERSION})
endif()
else()
set(PC_MSGPACK_INCLUDEDIR)
set(PC_MSGPACK_INCLUDE_DIRS)
set(PC_MSGPACK_LIBDIR)
set(PC_MSGPACK_LIBRARY_DIRS)
set(LIMIT_SEARCH NO_DEFAULT_PATH)
endif()
set(MSGPACK_DEFINITIONS ${PC_MSGPACK_CFLAGS_OTHER})
find_path(MSGPACK_INCLUDE_DIR msgpack/version_master.h
HINTS ${PC_MSGPACK_INCLUDEDIR} ${PC_MSGPACK_INCLUDE_DIRS}
${LIMIT_SEARCH})
if(MSGPACK_INCLUDE_DIR)
file(READ ${MSGPACK_INCLUDE_DIR}/msgpack/version_master.h msgpack_version_h)
string(REGEX REPLACE ".*MSGPACK_VERSION_MAJOR +([0-9]+).*" "\\1" MSGPACK_VERSION_MAJOR "${msgpack_version_h}")
string(REGEX REPLACE ".*MSGPACK_VERSION_MINOR +([0-9]+).*" "\\1" MSGPACK_VERSION_MINOR "${msgpack_version_h}")
string(REGEX REPLACE ".*MSGPACK_VERSION_REVISION +([0-9]+).*" "\\1" MSGPACK_VERSION_REVISION "${msgpack_version_h}")
set(MSGPACK_VERSION_STRING "${MSGPACK_VERSION_MAJOR}.${MSGPACK_VERSION_MINOR}.${MSGPACK_VERSION_REVISION}")
else()
set(MSGPACK_VERSION_STRING)
endif()
# If we're asked to use static linkage, add libmsgpack{,c}.a as a preferred library name.
if(MSGPACK_USE_STATIC)
list(APPEND MSGPACK_NAMES
"${CMAKE_STATIC_LIBRARY_PREFIX}msgpackc${CMAKE_STATIC_LIBRARY_SUFFIX}"
"${CMAKE_STATIC_LIBRARY_PREFIX}msgpack${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()
list(APPEND MSGPACK_NAMES msgpackc msgpack)
find_library(MSGPACK_LIBRARY NAMES ${MSGPACK_NAMES}
# Check each directory for all names to avoid using headers/libraries from
# different places.
NAMES_PER_DIR
HINTS ${PC_MSGPACK_LIBDIR} ${PC_MSGPACK_LIBRARY_DIRS}
${LIMIT_SEARCH})
mark_as_advanced(MSGPACK_INCLUDE_DIR MSGPACK_LIBRARY)
set(MSGPACK_LIBRARIES ${MSGPACK_LIBRARY})
set(MSGPACK_INCLUDE_DIRS ${MSGPACK_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set MSGPACK_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(Msgpack
REQUIRED_VARS MSGPACK_LIBRARY MSGPACK_INCLUDE_DIR
VERSION_VAR MSGPACK_VERSION_STRING)
+48 -25
View File
@@ -1,6 +1,6 @@
dnl define macros
m4_define([opendht_major_version], 2)
m4_define([opendht_minor_version], 4)
m4_define([opendht_minor_version], 0)
m4_define([opendht_patch_version], 0)
m4_define([opendht_version],
[opendht_major_version.opendht_minor_version.opendht_patch_version])
@@ -35,14 +35,10 @@ AS_IF([test "x$enable_logs" != "xno"], [
dnl Check for indexation
AC_ARG_ENABLE([indexation], [AS_HELP_STRING([--disable-indexation], [Disable DHT indexation])])
AM_CONDITIONAL(ENABLE_INDEXATION, test x$enable_indexation != "xno")
AM_COND_IF(ENABLE_INDEXATION, [
AC_DEFINE([OPENDHT_INDEXATION], [], [Define if DHT indexation is enabled])
AS_IF([test "x$enable_indexation" != "xno"], [
AC_DEFINE([OPENDHT_INDEXATION], [1], [Define if DHT indexation is enabled])
])
AC_ARG_ENABLE([peer-discovery], [AS_HELP_STRING([--disable-peer-discovery], [Disable peer-discovery])])
AM_CONDITIONAL(ENABLE_PEER_DISCOVERY, test x$enable_peer_discovery != "xno")
AM_COND_IF(ENABLE_PEER_DISCOVERY, [AC_DEFINE([OPENDHT_PEER_DISCOVERY], [], [Define if peer discovery is enabled])])
dnl Check for Doxygen
AC_ARG_ENABLE([doc], AS_HELP_STRING([--enable-doc], [Enable documentation generation (doxygen)]))
AS_IF([test "x$enable_doc" = "xyes"], [
@@ -102,7 +98,7 @@ AS_IF([test "x$SYS" = "xandroid"],
LT_INIT()
LT_LANG(C++)
AX_CXX_COMPILE_STDCXX(17,[noext],[mandatory])
AX_CXX_COMPILE_STDCXX(11,[noext],[mandatory])
PKG_PROG_PKG_CONFIG()
@@ -132,8 +128,6 @@ AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes || test x$pro
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
PKG_CHECK_MODULES([Argon2], [libargon2])
AC_SUBST(argon2_lib, [", libargon2"])
AC_ARG_WITH([jsoncpp], AS_HELP_STRING([--without-jsoncpp], [Build without JsonCpp support]))
AS_IF([test "x$with_jsoncpp" != "xno"],
@@ -141,8 +135,7 @@ AS_IF([test "x$with_jsoncpp" != "xno"],
[have_jsoncpp=no])
AS_IF([test "x$have_jsoncpp" = "xyes"], [
AC_MSG_NOTICE([Using JsonCpp])
CPPFLAGS+=" -DOPENDHT_JSONCPP"
AC_SUBST(jsoncpp_lib, [", jsoncpp"])
CPPFLAGS+=" -DOPENDHT_JSONCPP=1"
], [
AC_MSG_NOTICE([Not using JsonCpp])
AM_COND_IF(PROXY_CLIENT_OR_SERVER, AC_MSG_ERROR(["JsonCpp is required for proxy/push notification support"]))
@@ -154,11 +147,18 @@ AS_IF([test "x$with_openssl" != "xno"],
[have_openssl=no])
AS_IF([test "x$have_openssl" = "xyes"], [
AC_MSG_NOTICE([Using OpenSSL])
AC_SUBST(openssl_lib, [", openssl"])
], [
AC_MSG_NOTICE([Not using OpenSSL])
])
AC_ARG_WITH([http_parser_fork], AS_HELP_STRING([--with-http-parser-fork], [Build with http_parser fork to support old API]))
AS_IF([test "x$with_http_parser_fork" = "xyes"],[
AC_MSG_NOTICE([Using http_parser fork])
CPPFLAGS+=" -DOPENDHT_PROXY_HTTP_PARSER_FORK"
], [
AC_MSG_NOTICE([Not using http_parser fork])
])
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
AC_CHECK_HEADERS([asio.hpp], exit,, AC_MSG_ERROR([Missing Asio headers files]))
CXXFLAGS="${CXXFLAGS} -DASIO_STANDALONE"
@@ -171,11 +171,31 @@ AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
# http_parser has no pkgconfig, instead we check with:
AC_CHECK_LIB(http_parser, exit,, AC_MSG_ERROR([Missing HttpParser library files]))
AC_CHECK_HEADERS([http_parser.h], [http_parser_headers=yes; break;])
AC_SUBST(http_parser_lib, ["-lhttp_parser"])
AS_IF([test "x$http_parser_headers" != "xyes"], AC_MSG_ERROR([Missing HttpParser headers files]))
])
CXXFLAGS="${CXXFLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
dnl Check for Argon2
AC_ARG_WITH([argon2], AS_HELP_STRING([--without-argon2], [Use included Argon2]))
AS_IF([test "x$with_argon2" != "xno"],
[PKG_CHECK_MODULES([Argon2], [libargon2], [have_argon2=yes], [have_argon2=no])],
[have_argon2=no])
AS_IF([test "x$have_argon2" = "xyes"], [
AC_MSG_NOTICE([Using system Argon2])
AC_SUBST(argon2_lib, [", libargon2"])
], [
AS_IF([test "x$with_argon2" = "xyes"], [
AC_MSG_ERROR([Argon2 requested but not found])
],[
AC_MSG_NOTICE([Using included Argon2])
AC_SUBST(Argon2_CFLAGS, "-I\${top_srcdir}/argon2/src -I\${top_srcdir}/argon2/include")
AC_SUBST(Argon2_LIBS, "libargon2.la")
AC_SUBST(Argon2_LDFLAGS, "-L\${abs_top_srcdir}/argon2/src/.libs")
])
])
AM_CONDITIONAL([WITH_INCLUDED_ARGON2], [test "x$have_argon2" = "xno"])
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
AM_CONDITIONAL(ENABLE_TOOLS, test x$build_tools == xyes)
@@ -185,24 +205,27 @@ AM_COND_IF([ENABLE_TOOLS], [
])
])
AM_COND_IF(ENABLE_PROXY_SERVER, AC_DEFINE([OPENDHT_PROXY_SERVER], [], [Building with proxy server]))
AM_COND_IF(ENABLE_PROXY_CLIENT, AC_DEFINE([OPENDHT_PROXY_CLIENT], [], [Building with proxy client]))
AM_COND_IF(ENABLE_PROXY_SERVER, [CPPFLAGS+=" -DOPENDHT_PROXY_SERVER"], [])
AM_COND_IF(ENABLE_PROXY_CLIENT, [CPPFLAGS+=" -DOPENDHT_PROXY_CLIENT"], [])
AM_COND_IF(ENABLE_PUSH_NOTIFICATIONS, [CPPFLAGS+=" -DOPENDHT_PUSH_NOTIFICATIONS"], [])
AM_COND_IF(ENABLE_PROXY_SERVER_IDENTITY, [CPPFLAGS+=" -DOPENDHT_PROXY_SERVER_IDENTITY"], [])
AM_COND_IF([HAVE_DOXYGEN], [
AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])
])
dnl Configure setup.py if we build the python module
AC_SUBST(CURRENT_SOURCE_DIR, ".")
AC_SUBST(CURRENT_BINARY_DIR, ".")
AC_SUBST(PROJECT_SOURCE_DIR, "..")
AC_SUBST(PROJECT_BINARY_DIR, "../src/.libs")
AM_COND_IF([USE_CYTHON], [
AC_SUBST(CURRENT_SOURCE_DIR, ".")
AC_SUBST(CURRENT_BINARY_DIR, ".")
AC_SUBST(PROJECT_SOURCE_DIR, "..")
AC_SUBST(PROJECT_BINARY_DIR, "../src/.libs")
AC_CONFIG_FILES([python/Makefile python/setup.py])
])
AC_CONFIG_FILES([Makefile
src/Makefile
tools/Makefile
python/Makefile
python/setup.py
tests/Makefile
doc/Makefile
doc/Doxyfile
opendht.pc])
AC_OUTPUT
+1 -4
View File
@@ -1,10 +1,7 @@
dist_man1_MANS = dhtnode.1
noinst_HEADERS = \
Doxyfile
if HAVE_DOXYGEN
doxyfile.stamp: Doxyfile
doxyfile.stamp:
$(DOXYGEN) Doxyfile
echo stamp > doxyfile.stamp
+3 -13
View File
@@ -1,16 +1,6 @@
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps:latest
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
FROM aberaud/opendht-deps
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN git clone https://github.com/savoirfairelinux/opendht.git \
&& cd opendht && mkdir build && cd build \
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
-DOPENDHT_C=On \
-DOPENDHT_PEER_DISCOVERY=On \
-DOPENDHT_PYTHON=On \
-DOPENDHT_TOOLS=On \
-DOPENDHT_PROXY_SERVER=On \
-DOPENDHT_PROXY_CLIENT=On \
&& make -j8 && make install \
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On && make -j8 && make install \
&& cd ../.. && rm -rf opendht
-16
View File
@@ -1,16 +0,0 @@
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-bionic:latest
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
RUN git clone https://github.com/savoirfairelinux/opendht.git \
&& cd opendht && mkdir build && cd build \
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
-DOPENDHT_C=On \
-DOPENDHT_PEER_DISCOVERY=On \
-DOPENDHT_PYTHON=On \
-DOPENDHT_TOOLS=On \
-DOPENDHT_PROXY_SERVER=On \
-DOPENDHT_PROXY_CLIENT=On \
&& make -j8 && make install \
&& cd ../.. && rm -rf opendht
+50 -19
View File
@@ -1,28 +1,59 @@
FROM ubuntu:20.04
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
FROM ubuntu:16.04
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get update && apt-get install -y \
dialog apt-utils \
&& apt-get clean \
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev \
libgnutls28-dev libuv1-dev cython3 python3-dev libcppunit-dev libjsoncpp-dev \
autotools-dev autoconf libasio-dev \
&& apt-get clean
RUN apt-get update && apt-get install -y \
build-essential pkg-config cmake git wget \
autotools-dev autoconf \
cython3 python3-dev python3-setuptools \
libncurses5-dev libreadline-dev nettle-dev libcppunit-dev \
libgnutls28-dev libuv1-dev libjsoncpp-dev libargon2-dev \
libssl-dev libfmt-dev libhttp-parser-dev libasio-dev libmsgpack-dev \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
RUN echo "*** Installing libfmt ***" \
&& wget https://github.com/fmtlib/fmt/archive/5.3.0.tar.gz \
&& tar -xzf 5.3.0.tar.gz && cd fmt-5.3.0/ \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=On . \
&& make -j8 && make install \
&& cd ../ && rm -rf fmt*
# libhttp-parser-dev is 2.1-2 which is too old
RUN echo "*** Building nodejs/http_parser dependency ***" \
&& wget https://github.com/nodejs/http-parser/archive/v2.9.2.tar.gz \
&& tar xvf v2.9.2.tar.gz && cd http-parser-2.9.2/ \
&& PREFIX=/usr make -j8 && make install \
&& cd ../ && rm -rf http-parser*
# libasio-dev (1.10.6-3) is too old
RUN echo "** Building a recent version of asio ***" \
&& wget https://github.com/chriskohlhoff/asio/archive/asio-1-12-2.tar.gz \
&& tar -xvf asio-1-12-2.tar.gz && cd asio-asio-1-12-2/asio \
&& ./autogen.sh && ./configure --prefix=/usr --without-boost \
&& make install \
&& cd ../../ && rm -rf asio*
#patch for https://github.com/Stiffstream/restinio-conan-example/issues/2
RUN apt-get update && apt-get install -y python3-pip && pip3 install --upgrade cmake
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/aberaud/restinio/archive/e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
&& ls -l && tar -xzf e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
&& cd restinio-e0a261dd8488246a3cb8bbb3ea781ea5139c3c94/dev \
&& wget https://github.com/Stiffstream/restinio/archive/v.0.5.1.2.tar.gz \
&& ls -l && tar -xzf v.0.5.1.2.tar.gz \
&& cd restinio-v.0.5.1.2/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none . \
&& make -j8 && make install \
&& cd ../../.. && rm -rf restinio
&& cd ../../ && rm -rf restinio*
# build restbed from sources
RUN git clone --recursive https://github.com/corvusoft/restbed.git \
&& cd restbed && mkdir build && cd build \
&& cmake -DBUILD_TESTS=NO -DBUILD_EXAMPLES=NO -DBUILD_SSL=NO -DBUILD_SHARED=YES -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib .. \
&& make -j8 install \
&& cd .. && rm -rf restbed
#build msgpack from source
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.1.5/msgpack-2.1.5.tar.gz \
&& tar -xzf msgpack-2.1.5.tar.gz \
&& cd msgpack-2.1.5 && mkdir build && cd build \
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
&& make -j8 && make install \
&& cd ../.. && rm -rf msgpack-2.1.5 msgpack-2.1.5.tar.gz
-32
View File
@@ -1,32 +0,0 @@
FROM ubuntu:18.04
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
RUN echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
RUN apt-get update && apt-get install -y \
apt-transport-https build-essential pkg-config git wget libncurses5-dev libreadline-dev nettle-dev \
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
libargon2-0-dev \
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev libssl-dev python3-pip \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
RUN pip3 install --upgrade cmake
# libasio-dev (1.10) is too old
RUN echo "** Building a recent version of asio ***" \
&& wget https://github.com/aberaud/asio/archive/a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz \
&& tar -xvf a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz && cd asio-a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571/asio \
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
&& make install \
&& cd ../../ && rm -rf asio*
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/aberaud/restinio/archive/8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59.tar.gz \
&& ls -l && tar -xzf 8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59.tar.gz \
&& cd restinio-8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none . \
&& make -j8 && make install \
&& cd ../../ && rm -rf restinio*
+49 -18
View File
@@ -1,31 +1,62 @@
FROM ubuntu:20.04
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
RUN apt-get update && apt-get install -y \
dialog apt-utils \
&& apt-get clean \
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
FROM ubuntu:16.04
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
RUN apt-get update \
&& apt-get install -y llvm llvm-dev lldb clang gdb make cmake pkg-config git wget libncurses5-dev libreadline-dev \
nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libjsoncpp-dev cython3 python3-dev \
&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev \
nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libjsoncpp-dev libasio-dev cython3 python3-dev \
python3-setuptools libcppunit-dev python3-pip \
autotools-dev autoconf libssl-dev libargon2-dev \
libfmt-dev libhttp-parser-dev libasio-dev \
&& apt-get remove -y gcc g++ && apt-get autoremove -y \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
autotools-dev autoconf libasio-dev \
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
ENV CC cc
ENV CXX c++
RUN echo "*** Installing libfmt ***" \
&& wget https://github.com/fmtlib/fmt/archive/5.3.0.tar.gz \
&& tar -xzf 5.3.0.tar.gz && cd fmt-5.3.0/ \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=On . \
&& make -j8 && make install \
&& cd ../ && rm -rf fmt*
# libhttp-parser-dev is 2.1-2 which is too old
RUN echo "*** Building nodejs/http_parser dependency ***" \
&& wget https://github.com/nodejs/http-parser/archive/v2.9.2.tar.gz \
&& tar xvf v2.9.2.tar.gz && cd http-parser-2.9.2/ \
&& PREFIX=/usr make -j8 && make install \
&& cd ../ && rm -rf http-parser*
# libasio-dev (1.10.6-3) is too old
RUN echo "** Building a recent version of asio ***" \
&& wget https://github.com/chriskohlhoff/asio/archive/asio-1-12-2.tar.gz \
&& tar -xvf asio-1-12-2.tar.gz && cd asio-asio-1-12-2/asio \
&& ./autogen.sh && ./configure --prefix=/usr --without-boost \
&& make install \
&& cd ../../ && rm -rf asio*
#patch for https://github.com/Stiffstream/restinio-conan-example/issues/2
RUN apt-get update && apt-get install -y python3-pip && pip3 install --upgrade cmake
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/aberaud/restinio/archive/e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
&& ls -l && tar -xzf e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
&& cd restinio-e0a261dd8488246a3cb8bbb3ea781ea5139c3c94/dev \
&& wget https://github.com/Stiffstream/restinio/archive/v.0.5.1.2.tar.gz \
&& ls -l && tar -xzf v.0.5.1.2.tar.gz \
&& cd restinio-v.0.5.1.2/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none . \
&& make -j8 && make install \
&& cd ../../ && rm -rf restinio*
# build restbed from sources
RUN git clone --recursive https://github.com/corvusoft/restbed.git \
&& cd restbed && mkdir build && cd build \
&& cmake -DBUILD_TESTS=NO -DBUILD_EXAMPLES=NO -DBUILD_SSL=NO -DBUILD_SHARED=YES -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib .. \
&& make -j8 install \
&& cd .. && rm -rf restbed
#build msgpack from source
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.1.5/msgpack-2.1.5.tar.gz \
&& tar -xzf msgpack-2.1.5.tar.gz \
&& cd msgpack-2.1.5 && mkdir build && cd build \
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
&& make -j8 && make install \
&& cd ../.. && rm -rf msgpack-2.1.5 msgpack-2.1.5.tar.gz
-16
View File
@@ -1,16 +0,0 @@
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-llvm:latest
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
RUN git clone https://github.com/savoirfairelinux/opendht.git \
&& cd opendht && mkdir build && cd build \
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
-DOPENDHT_C=On \
-DOPENDHT_PEER_DISCOVERY=On \
-DOPENDHT_PYTHON=On \
-DOPENDHT_TOOLS=On \
-DOPENDHT_PROXY_SERVER=On \
-DOPENDHT_PROXY_CLIENT=On \
&& make -j8 && make install \
&& cd ../.. && rm -rf opendht
+7
View File
@@ -0,0 +1,7 @@
FROM aberaud/opendht-deps
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
COPY . /root/opendht
RUN cd /root/opendht && mkdir build && cd build \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On -DOPENDHT_TESTS=ON .. \
&& make -j8 && ./opendht_unit_tests && make install
+7
View File
@@ -0,0 +1,7 @@
FROM aberaud/opendht-deps-llvm
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
COPY . /root/opendht
RUN cd /root/opendht && mkdir build && cd build \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_TESTS=ON .. \
&& make -j8 && ./opendht_unit_tests && make install
+4
View File
@@ -0,0 +1,4 @@
FROM aberaud/opendht-deps
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
COPY . /root/opendht
+7 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -19,4 +19,10 @@
#pragma once
#include "opendht/dhtrunner.h"
#ifdef OPENDHT_PROXY_SERVER
#include "opendht/dht_proxy_server.h"
#endif
#include "opendht/default_types.h"
#ifdef OPENDHT_INDEXATION
#include "opendht/indexation/pht.h"
#endif
+11 -50
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
@@ -26,7 +26,6 @@
#include <vector>
#include <memory>
#include <functional>
#include <string>
#ifdef OPENDHT_JSONCPP
#include <json/json.h>
@@ -45,21 +44,12 @@ enum class NodeStatus {
Connected // 1+ good nodes
};
inline constexpr const char*
statusToStr(NodeStatus status) {
return status == NodeStatus::Connected ? "connected" : (
status == NodeStatus::Connecting ? "connecting" :
"disconnected");
}
struct OPENDHT_PUBLIC NodeStats {
unsigned good_nodes {0},
dubious_nodes {0},
cached_nodes {0},
incoming_nodes {0};
unsigned table_depth {0};
unsigned searches {0};
unsigned node_cache_size {0};
unsigned getKnownNodes() const { return good_nodes + dubious_nodes; }
unsigned long getNetworkSizeEstimation() const { return 8 * std::exp2(table_depth); }
std::string toString() const;
@@ -73,17 +63,14 @@ struct OPENDHT_PUBLIC NodeStats {
explicit NodeStats(const Json::Value& v);
#endif
MSGPACK_DEFINE_MAP(good_nodes, dubious_nodes, cached_nodes, incoming_nodes, table_depth, searches, node_cache_size)
MSGPACK_DEFINE_MAP(good_nodes, dubious_nodes, cached_nodes, incoming_nodes, table_depth)
};
struct OPENDHT_PUBLIC NodeInfo {
InfoHash id;
InfoHash node_id;
NodeStats ipv4 {};
NodeStats ipv6 {};
size_t ongoing_ops {0};
in_port_t bound4 {0};
in_port_t bound6 {0};
NodeStats ipv4;
NodeStats ipv6;
#ifdef OPENDHT_JSONCPP
/**
@@ -119,25 +106,6 @@ struct OPENDHT_PUBLIC Config {
/** If set, the dht will load its state from this file on start and save its state in this file on shutdown */
std::string persist_path {};
/** If non-0, overrides the default global rate-limit. -1 means no limit. */
ssize_t max_req_per_sec {0};
/** If non-0, overrides the default per-IP address rate-limit. -1 means no limit. */
ssize_t max_peer_req_per_sec {0};
/* If non-0, overrides the default maximum number of searches. -1 means no limit. */
ssize_t max_searches {0};
/* If non-0, overrides the default maximum store size. -1 means no limit. */
ssize_t max_store_size {0};
/**
* Use appropriate bahavior for a public IP, stable node:
* - No connectivity change triggered when a search fails
* - Larger listen refresh time
*/
bool public_stable {false};
};
/**
@@ -147,12 +115,6 @@ struct OPENDHT_PUBLIC SecureDhtConfig
{
Config node_config {};
crypto::Identity id {};
/**
* Cache all encountered public keys and certificates,
* for use by the certificate store, putEncrypted and putSigned
*/
bool cert_cache_all {false};
};
static constexpr size_t DEFAULT_STORAGE_LIMIT {1024 * 1024 * 64};
@@ -164,7 +126,6 @@ using GetCallback = std::function<bool(const std::vector<std::shared_ptr<Value>>
using ValueCallback = std::function<bool(const std::vector<std::shared_ptr<Value>>& values, bool expired)>;
using GetCallbackSimple = std::function<bool(std::shared_ptr<Value> value)>;
using ShutdownCallback = std::function<void()>;
using IdentityAnnouncedCb = std::function<void(bool)>;
using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::Certificate>>(const InfoHash& pk_id)>;
@@ -179,13 +140,13 @@ typedef bool (*FilterRaw)(const Value&, void *user_data);
using DoneCallbackSimple = std::function<void(bool success)>;
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
OPENDHT_PUBLIC GetCallback bindGetCb(GetCallbackSimple cb);
OPENDHT_PUBLIC ValueCallback bindValueCb(ValueCallbackRaw raw_cb, void* user_data);
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data);
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(const GetCallbackRaw& raw_cb, void* user_data);
OPENDHT_PUBLIC GetCallback bindGetCb(const GetCallbackSimple& cb);
OPENDHT_PUBLIC ValueCallback bindValueCb(const ValueCallbackRaw& raw_cb, void* user_data);
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(const ShutdownCallbackRaw& shutdown_cb_raw, void* user_data);
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackSimple donecb);
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackRaw raw_cb, void* user_data);
OPENDHT_PUBLIC DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data);
OPENDHT_PUBLIC Value::Filter bindFilterRaw(FilterRaw raw_filter, void* user_data);
OPENDHT_PUBLIC DoneCallback bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data);
OPENDHT_PUBLIC DoneCallbackSimple bindDoneCbSimple(const DoneCallbackSimpleRaw& raw_cb, void* user_data);
OPENDHT_PUBLIC Value::Filter bindFilterRaw(const FilterRaw& raw_filter, void* user_data);
}
+20 -105
View File
@@ -1,7 +1,6 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,7 +26,6 @@ extern "C" {
#include <gnutls/gnutls.h>
#include <gnutls/abstract.h>
#include <gnutls/x509.h>
#include <gnutls/ocsp.h>
}
#include <vector>
@@ -45,22 +43,16 @@ namespace dht {
namespace crypto {
class OPENDHT_PUBLIC CryptoException : public std::runtime_error {
public:
explicit CryptoException(const std::string& str) : std::runtime_error(str) {};
explicit CryptoException(const char* str) : std::runtime_error(str) {};
CryptoException(const CryptoException& e) noexcept = default;
CryptoException& operator=(const CryptoException&) noexcept = default;
public:
CryptoException(const std::string& str) : std::runtime_error(str) {};
};
/**
* Exception thrown when a decryption error happened.
*/
class OPENDHT_PUBLIC DecryptError : public CryptoException {
public:
explicit DecryptError(const std::string& str) : CryptoException(str) {};
explicit DecryptError(const char* str) : CryptoException(str) {};
DecryptError(const DecryptError& e) noexcept = default;
DecryptError& operator=(const DecryptError&) noexcept = default;
public:
DecryptError(const std::string& str = "") : CryptoException(str) {};
};
struct PrivateKey;
@@ -80,10 +72,7 @@ struct OPENDHT_PUBLIC PublicKey
* Takes ownership of an existing gnutls_pubkey.
*/
PublicKey(gnutls_pubkey_t k) : pk(k) {}
/** Import public key from serialized data */
PublicKey(const uint8_t* dat, size_t dat_size);
PublicKey(const Blob& pk) : PublicKey(pk.data(), pk.size()) {}
PublicKey(const Blob& pk);
PublicKey(PublicKey&& o) noexcept : pk(o.pk) { o.pk = nullptr; };
~PublicKey();
@@ -108,17 +97,16 @@ struct OPENDHT_PUBLIC PublicKey
PkId getLongId() const;
bool checkSignature(const uint8_t* data, size_t data_len, const uint8_t* signature, size_t signature_len) const;
inline bool checkSignature(const Blob& data, const Blob& signature) const {
bool checkSignature(const Blob& data, const Blob& signature) const {
return checkSignature(data.data(), data.size(), signature.data(), signature.size());
}
Blob encrypt(const uint8_t* data, size_t data_len) const;
inline Blob encrypt(const Blob& data) const {
Blob encrypt(const Blob& data) const {
return encrypt(data.data(), data.size());
}
void pack(Blob& b) const;
int pack(uint8_t* out, size_t* out_len) const;
void unpack(const uint8_t* dat, size_t dat_size);
std::string toString() const;
@@ -132,7 +120,7 @@ struct OPENDHT_PUBLIC PublicKey
p.pack_bin_body((const char*)b.data(), b.size());
}
void msgpack_unpack(const msgpack::object& o);
void msgpack_unpack(msgpack::object o);
gnutls_digest_algorithm_t getPreferredDigest() const;
@@ -164,26 +152,21 @@ struct OPENDHT_PUBLIC PrivateKey
~PrivateKey();
explicit operator bool() const { return key; }
const PublicKey& getPublicKey() const;
const std::shared_ptr<PublicKey>& getSharedPublicKey() const;
int serialize(uint8_t* out, size_t* out_len, const std::string& password = {}) const;
PublicKey getPublicKey() const;
Blob serialize(const std::string& password = {}) const;
/**
* Sign the provided binary object.
* @returns the signature data.
*/
Blob sign(const uint8_t* data, size_t data_len) const;
inline Blob sign(const Blob& dat) const { return sign(dat.data(), dat.size()); }
Blob sign(const Blob&) const;
/**
* Try to decrypt the provided cypher text.
* In case of failure a CryptoException is thrown.
* @returns the decrypted data.
*/
Blob decrypt(const uint8_t* cypher, size_t cypher_len) const;
Blob decrypt(const Blob& cypher) const { return decrypt(cypher.data(), cypher.size()); }
Blob decrypt(const Blob& cypher) const;
/**
* Generate a new RSA key pair
@@ -201,9 +184,10 @@ private:
PrivateKey& operator=(const PrivateKey&) = delete;
Blob decryptBloc(const uint8_t* src, size_t src_size) const;
mutable std::shared_ptr<PublicKey> publicKey_ {};
//friend dht::crypto::Identity dht::crypto::generateIdentity(const std::string&, dht::crypto::Identity, unsigned key_length);
};
class OPENDHT_PUBLIC RevocationList
{
using clock = std::chrono::system_clock;
@@ -233,7 +217,7 @@ public:
p.pack_bin_body((const char*)b.data(), b.size());
}
void msgpack_unpack(const msgpack::object& o);
void msgpack_unpack(msgpack::object o);
void revoke(const Certificate& crt, time_point t = time_point::min());
@@ -316,55 +300,6 @@ private:
gnutls_x509_crq_t request {nullptr};
};
class OPENDHT_PUBLIC OcspRequest
{
public:
OcspRequest(gnutls_ocsp_req_t r) : request(r) {};
OcspRequest(const uint8_t* dat_ptr, size_t dat_size);
~OcspRequest();
/*
* Get OCSP Request in readable format.
*/
std::string toString(const bool compact = true) const;
Blob pack() const;
Blob getNonce() const;
private:
gnutls_ocsp_req_t request;
};
class OPENDHT_PUBLIC OcspResponse
{
public:
OcspResponse(const uint8_t* dat_ptr, size_t dat_size);
OcspResponse(const std::string& response) : OcspResponse((const uint8_t*)response.data(), response.size()) {};
~OcspResponse();
Blob pack() const;
/*
* Get OCSP Response in readable format.
*/
std::string toString(const bool compact = true) const;
/*
* Get OCSP response certificate status.
* Return certificate status.
* http://www.gnu.org/software/gnutls/reference/gnutls-ocsp.html#gnutls-ocsp-cert-status-t
*/
gnutls_ocsp_cert_status_t getCertificateStatus() const;
/*
* Verify OCSP response and return OCSP status.
* Throws CryptoException in case of error in the response.
* http://www.gnu.org/software/gnutls/reference/gnutls-ocsp.html#gnutls-ocsp-verify-reason-t
*/
gnutls_ocsp_cert_status_t verifyDirect(const Certificate& crt, const Blob& nonce);
private:
gnutls_ocsp_resp_t response;
};
struct OPENDHT_PUBLIC Certificate {
Certificate() noexcept {}
@@ -480,7 +415,7 @@ struct OPENDHT_PUBLIC Certificate {
p.pack_bin_body((const char*)b.data(), b.size());
}
void msgpack_unpack(const msgpack::object& o);
void msgpack_unpack(msgpack::object o);
explicit operator bool() const { return cert; }
PublicKey getPublicKey() const;
@@ -490,8 +425,6 @@ struct OPENDHT_PUBLIC Certificate {
/** Same as getPublicKey().getLongId() */
PkId getLongId() const;
Blob getSerialNumber() const;
/** Read certificate Common Name (CN) */
std::string getName() const;
@@ -541,8 +474,8 @@ struct OPENDHT_PUBLIC Certificate {
void addRevocationList(RevocationList&&);
void addRevocationList(std::shared_ptr<RevocationList>);
static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", const Identity& ca = {}, bool is_ca = false, int64_t validity = 0);
static Certificate generate(const CertificateRequest& request, const Identity& ca, int64_t validity = 0);
static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", const Identity& ca = {}, bool is_ca = false);
static Certificate generate(const CertificateRequest& request, const Identity& ca);
gnutls_x509_crt_t getCopy() const {
if (not cert)
@@ -585,27 +518,11 @@ struct OPENDHT_PUBLIC Certificate {
gnutls_digest_algorithm_t getPreferredDigest() const;
/*
* Generate OCSP request.
* Return GnuTLS error code.
* https://www.gnutls.org/manual/html_node/Error-codes.html
*/
std::pair<std::string, Blob> generateOcspRequest(gnutls_x509_crt_t& issuer);
/**
* Change certificate's expiration
*/
void setValidity(const Identity& ca, int64_t validity);
void setValidity(const PrivateKey& key, int64_t validity);
gnutls_x509_crt_t cert {nullptr};
std::shared_ptr<Certificate> issuer {};
std::shared_ptr<OcspResponse> ocspResponse;
private:
Certificate(const Certificate&) = delete;
Certificate& operator=(const Certificate&) = delete;
mutable InfoHash cachedId_ {};
mutable PkId cachedLongId_ {};
struct crlNumberCmp {
bool operator() (const std::shared_ptr<RevocationList>& lhs, const std::shared_ptr<RevocationList>& rhs) const {
@@ -781,10 +698,8 @@ OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
/**
* AES-GCM decryption.
*/
OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key);
OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const Blob& key) { return aesDecrypt(data.data(), data.size(), key); }
OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const std::string& password);
OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const std::string& password) { return aesDecrypt(data.data(), data.size(), password); }
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const Blob& key);
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const std::string& password);
}
}
+7 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -66,10 +66,8 @@ private:
public:
virtual void unpackValue(const Value& v) override {
if (v.owner) {
owner = v.owner;
if (v.owner)
from = v.owner->getId();
}
BaseClass::unpackValue(v);
}
@@ -77,7 +75,6 @@ public:
return [](const Value& v){ return v.isSigned(); };
}
Sp<crypto::PublicKey> owner;
dht::InfoHash from;
};
@@ -147,18 +144,17 @@ public:
static const ValueType TYPE;
TrustRequest() {}
TrustRequest(std::string s, std::string ci = {}) : service(s), conversationId(ci) {}
TrustRequest(std::string s, std::string ci, const Blob& d) : service(s), conversationId(ci), payload(d) {}
TrustRequest(std::string s) : service(s) {}
TrustRequest(std::string s, const Blob& d) : service(s), payload(d) {}
static Value::Filter getFilter() {
return EncryptedValue::getFilter();
}
std::string service;
std::string conversationId;
Blob payload;
bool confirm {false};
MSGPACK_DEFINE_MAP(service, conversationId, payload, confirm)
MSGPACK_DEFINE_MAP(service, payload, confirm)
};
class OPENDHT_PUBLIC IceCandidates : public EncryptedValue<IceCandidates>
@@ -193,7 +189,7 @@ public:
#endif
}
virtual void msgpack_unpack(const msgpack::object& o)
virtual void msgpack_unpack(msgpack::object o)
{
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
if (o.via.array.size < 2) throw msgpack::type_error();
@@ -233,7 +229,7 @@ public:
pk.pack_bin_body((const char*)addr.get(), addr.getLength());
}
virtual void msgpack_unpack(const msgpack::object& o)
virtual void msgpack_unpack(msgpack::object o)
{
if (o.type == msgpack::type::BIN)
addr = {(sockaddr*)o.via.bin.ptr, (socklen_t)o.via.bin.size};
+34 -76
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
@@ -61,15 +61,14 @@ struct LocalListener;
*/
class OPENDHT_PUBLIC Dht final : public DhtInterface {
public:
Dht();
/**
* Initialise the Dht with two open sockets (for IPv4 and IP6)
* and an ID for the node.
*/
Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Sp<Logger>& l = {});
Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Logger& l = {})
: Dht(std::move(sock), config, std::make_shared<Logger>(l)) {}
Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Logger& l = {});
virtual ~Dht();
/**
@@ -77,14 +76,10 @@ public:
*/
inline const InfoHash& getNodeId() const override { return myid; }
NodeStatus updateStatus(sa_family_t af) override;
/**
* Get the current status of the node for the given family.
*/
NodeStatus getStatus(sa_family_t af) const override {
return dht(af).status;
}
NodeStatus getStatus(sa_family_t af) const override;
NodeStatus getStatus() const override {
return std::max(getStatus(AF_INET), getStatus(AF_INET6));
@@ -95,7 +90,7 @@ public:
/**
* Performs final operations before quitting.
*/
void shutdown(ShutdownCallback cb, bool stop = false) override;
void shutdown(ShutdownCallback cb) override;
/**
* Returns true if the node is running (have access to an open socket).
@@ -112,15 +107,6 @@ public:
return types.getType(type_id);
}
void addBootstrap(const std::string& host, const std::string& service) override {
bootstrap_nodes.emplace_back(host, service);
startBootstrap();
}
void clearBootstrap() override {
bootstrap_nodes.clear();
}
/**
* Insert a node in the main routing table.
* The node is not pinged, so this should be
@@ -133,9 +119,9 @@ public:
void pingNode(SockAddr, DoneCallbackSimple&& cb={}) override;
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr, const time_point& now) override;
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen, const time_point& now) override {
return periodic(buf, buflen, SockAddr(from, fromlen), now);
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr) override;
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
return periodic(buf, buflen, SockAddr(from, fromlen));
}
/**
@@ -340,10 +326,10 @@ private:
static constexpr unsigned LISTEN_NODES {4};
/* The maximum number of hashes we're willing to track. */
static constexpr unsigned MAX_HASHES {1024 * 1024};
static constexpr unsigned MAX_HASHES {64 * 1024};
/* The maximum number of searches we keep data about. */
static constexpr unsigned MAX_SEARCHES {1024 * 1024};
static constexpr unsigned MAX_SEARCHES {64 * 1024};
static constexpr std::chrono::minutes MAX_STORAGE_MAINTENANCE_EXPIRE_TIME {10};
@@ -351,12 +337,9 @@ private:
static constexpr std::chrono::minutes SEARCH_EXPIRE_TIME {62};
/* Timeout for listen */
static constexpr duration LISTEN_EXPIRE_TIME {std::chrono::seconds(30)};
static constexpr duration LISTEN_EXPIRE_TIME_PUBLIC {std::chrono::minutes(5)};
static constexpr std::chrono::seconds LISTEN_EXPIRE_TIME {30};
static constexpr duration REANNOUNCE_MARGIN {std::chrono::seconds(10)};
static constexpr std::chrono::seconds BOOTSTRAP_PERIOD {10};
static constexpr std::chrono::seconds REANNOUNCE_MARGIN {10};
static constexpr size_t TOKEN_SIZE {32};
@@ -370,8 +353,6 @@ private:
Dht(const Dht&) = delete;
Dht& operator=(const Dht&) = delete;
std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
InfoHash myid {};
uint64_t secret {};
@@ -380,49 +361,40 @@ private:
// registred types
TypeStore types;
using SearchMap = std::map<InfoHash, Sp<Search>>;
struct Kad {
RoutingTable buckets {};
SearchMap searches {};
unsigned pending_pings {0};
NodeStatus status;
NodeStatus getStatus(time_point now) const;
NodeStats getNodesStats(time_point now, const InfoHash& myid) const;
};
Kad dht4 {};
Kad dht6 {};
std::vector<std::pair<std::string,std::string>> bootstrap_nodes {};
std::chrono::steady_clock::duration bootstrap_period {BOOTSTRAP_PERIOD};
Sp<Scheduler::Job> bootstrapJob {};
// the stuff
RoutingTable buckets4 {};
RoutingTable buckets6 {};
std::map<InfoHash, Storage> store;
std::map<SockAddr, StorageBucket, SockAddr::ipCmp> store_quota;
size_t total_values {0};
size_t total_store_size {0};
size_t max_store_keys {MAX_HASHES};
size_t max_store_size {DEFAULT_STORAGE_LIMIT};
size_t max_searches {MAX_SEARCHES};
size_t search_id {0};
using SearchMap = std::map<InfoHash, Sp<Search>>;
SearchMap searches4 {};
SearchMap searches6 {};
uint16_t search_id {0};
// map a global listen token to IPv4, IPv6 specific listen tokens.
// 0 is the invalid token.
std::map<size_t, std::tuple<size_t, size_t, size_t>> listeners {};
size_t listener_token {1};
// timing
Scheduler scheduler;
Sp<Scheduler::Job> nextNodesConfirmation {};
Sp<Scheduler::Job> nextStorageMaintenance {};
net::NetworkEngine network_engine;
unsigned pending_pings4 {0};
unsigned pending_pings6 {0};
using ReportedAddr = std::pair<unsigned, SockAddr>;
std::vector<ReportedAddr> reported_addr;
std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
std::string persistPath;
// are we a bootstrap node ?
@@ -431,11 +403,6 @@ private:
// be put in bootstrap mode.
const bool is_bootstrap {false};
const bool maintain_storage {false};
const bool public_stable {false};
inline const duration& getListenExpiration() const {
return public_stable ? LISTEN_EXPIRE_TIME_PUBLIC : LISTEN_EXPIRE_TIME;
}
void rotateSecrets();
@@ -445,7 +412,7 @@ private:
void reportedAddr(const SockAddr&);
// Storage
void storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t tid, Query&& = {}, int version = 0);
void storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t tid, Query&& = {});
bool storageStore(const InfoHash& id, const Sp<Value>& value, time_point created, const SockAddr& sa = {}, bool permanent = false);
bool storageErase(const InfoHash& id, Value::Id vid);
bool storageRefresh(const InfoHash& id, Value::Id vid);
@@ -465,10 +432,8 @@ private:
size_t maintainStorage(decltype(store)::value_type&, bool force=false, const DoneCallback& donecb={});
// Buckets
Kad& dht(sa_family_t af) { return af == AF_INET ? dht4 : dht6; }
const Kad& dht(sa_family_t af) const { return af == AF_INET ? dht4 : dht6; }
RoutingTable& buckets(sa_family_t af) { return dht(af).buckets; }
const RoutingTable& buckets(sa_family_t af) const { return dht(af).buckets; }
RoutingTable& buckets(sa_family_t af) { return af == AF_INET ? buckets4 : buckets6; }
const RoutingTable& buckets(sa_family_t af) const { return af == AF_INET ? buckets4 : buckets6; }
Bucket* findBucket(const InfoHash& id, sa_family_t af) {
auto& b = buckets(af);
auto it = b.findBucket(id);
@@ -482,9 +447,6 @@ private:
void sendCachedPing(Bucket& b);
bool bucketMaintenance(RoutingTable&);
void dumpBucket(const Bucket& b, std::ostream& out) const;
void bootstrap();
void startBootstrap();
void stopBootstrap();
// Nodes
void onNewNode(const Sp<Node>& node, int confirm);
@@ -492,8 +454,9 @@ private:
bool trySearchInsert(const Sp<Node>& node);
// Searches
inline SearchMap& searches(sa_family_t af) { return dht(af).searches; }
inline const SearchMap& searches(sa_family_t af) const { return dht(af).searches; }
inline SearchMap& searches(sa_family_t af) { return af == AF_INET ? searches4 : searches6; }
inline const SearchMap& searches(sa_family_t af) const { return af == AF_INET ? searches4 : searches6; }
/**
* Low-level method that will perform a search on the DHT for the specified
@@ -517,9 +480,6 @@ private:
void confirmNodes();
void expire();
void onConnected();
void onDisconnected();
/**
* Generic function to execute when a 'get' request has completed.
*
@@ -573,8 +533,7 @@ private:
*
* @param sr The search to execute its operations.
*/
void searchStep(std::weak_ptr<Search> ws);
void searchStep(Sp<Search>);
void searchSynchedNodeListen(const Sp<Search>&, SearchNode&);
void dumpSearch(const Search& sr, std::ostream& out) const;
@@ -605,8 +564,7 @@ private:
const InfoHash& hash,
const Blob& token,
size_t socket_id,
const Query& query,
int version = 0);
const Query& query);
void onListenDone(const Sp<Node>& status,
net::RequestAnswer& a,
Sp<Search>& sr);
+13 -36
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -21,8 +21,6 @@
#include "infohash.h"
#include "log_enable.h"
#include <queue>
namespace dht {
namespace net {
@@ -32,8 +30,7 @@ namespace net {
class OPENDHT_PUBLIC DhtInterface {
public:
DhtInterface() = default;
DhtInterface(const Logger& l) : logger_(std::make_shared<Logger>(l)) {};
DhtInterface(const std::shared_ptr<Logger>& l) : logger_(l) {};
DhtInterface(const Logger& l) : DHT_LOG(l) {};
virtual ~DhtInterface() = default;
// [[deprecated]]
@@ -44,14 +41,9 @@ public:
/**
* Get the current status of the node for the given family.
*/
virtual NodeStatus updateStatus(sa_family_t af) { return getStatus(af); };
virtual NodeStatus getStatus(sa_family_t af) const = 0;
virtual NodeStatus getStatus() const = 0;
void addOnConnectedCallback(std::function<void()> cb) {
onConnectCallbacks_.emplace(std::move(cb));
}
virtual net::DatagramSocket* getSocket() const { return {}; };
/**
@@ -61,10 +53,8 @@ public:
/**
* Performs final operations before quitting.
* stop: if true, cancel ongoing operations and call their 'done'
* callbacks synchronously.
*/
virtual void shutdown(ShutdownCallback cb, bool stop = false) = 0;
virtual void shutdown(ShutdownCallback cb) = 0;
/**
* Returns true if the node is running (have access to an open socket).
@@ -78,9 +68,6 @@ public:
virtual const ValueType& getType(ValueType::Id type_id) const = 0;
virtual void addBootstrap(const std::string& /*host*/, const std::string& /*service*/) {};
virtual void clearBootstrap() {};
/**
* Insert a node in the main routing table.
* The node is not pinged, so this should be
@@ -91,8 +78,8 @@ public:
virtual void pingNode(SockAddr, DoneCallbackSimple&& cb={}) = 0;
virtual time_point periodic(const uint8_t *buf, size_t buflen, SockAddr, const time_point& now) = 0;
virtual time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen, const time_point& now) = 0;
virtual time_point periodic(const uint8_t *buf, size_t buflen, SockAddr) = 0;
virtual time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) = 0;
/**
* Get a value by searching on all available protocols (IPv4, IPv6),
@@ -234,23 +221,15 @@ public:
* Enable or disable logging of DHT internal messages
*/
virtual void setLoggers(LogMethod error = {}, LogMethod warn = {}, LogMethod debug = {}) {
if (logger_) {
logger_->DBG = std::move(debug);
logger_->WARN = std::move(warn);
logger_->ERR = std::move(error);
} else
logger_= std::make_shared<Logger>(std::move(error), std::move(warn), std::move(debug));
DHT_LOG.DBG = debug;
DHT_LOG.WARN = warn;
DHT_LOG.ERR = error;
}
virtual void setLogger(const Logger& l) {
if (logger_)
*logger_ = l;
else
logger_= std::make_shared<Logger>(l);
}
virtual void setLogger(const std::shared_ptr<Logger>& l) {
logger_ = l;
DHT_LOG.DBG = l.DBG;
DHT_LOG.WARN = l.WARN;
DHT_LOG.ERR = l.ERR;
}
/**
@@ -258,8 +237,7 @@ public:
*/
virtual void setLogFilter(const InfoHash& f)
{
if (logger_)
logger_->setFilter(f);
DHT_LOG.setFilter(f);
}
virtual void setPushNotificationToken(const std::string&) {};
@@ -271,8 +249,7 @@ public:
virtual void pushNotificationReceived(const std::map<std::string, std::string>& data) = 0;
protected:
std::shared_ptr<Logger> logger_ {};
std::queue<std::function<void()>> onConnectCallbacks_ {};
Logger DHT_LOG;
};
} // namespace dht
+51 -51
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
@@ -53,9 +53,9 @@ public:
DhtProxyClient();
explicit DhtProxyClient(
std::shared_ptr<crypto::Certificate> serverCA, crypto::Identity clientIdentity,
std::shared_ptr<dht::crypto::Certificate> serverCA, dht::crypto::Identity clientIdentity,
std::function<void()> loopSignal, const std::string& serverHost,
const std::string& pushClientId = "", std::shared_ptr<Logger> logger = {});
const std::string& pushClientId = "", std::shared_ptr<dht::Logger> logger = {});
void setHeaderFields(http::Request& request);
@@ -85,7 +85,7 @@ public:
/**
* Performs final operations before quitting.
*/
void shutdown(ShutdownCallback cb, bool) override;
void shutdown(ShutdownCallback cb) override;
/**
* Returns true if the node is running (have access to an open socket).
@@ -107,13 +107,13 @@ public:
*/
virtual void get(const InfoHash& key, GetCallback cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {}) override;
virtual void get(const InfoHash& key, GetCallback cb, DoneCallbackSimple donecb={}, Value::Filter&& f={}, Where&& w = {}) override {
get(key, cb, bindDoneCb(std::move(donecb)), std::forward<Value::Filter>(f), std::forward<Where>(w));
get(key, cb, bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
}
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {}) override {
get(key, bindGetCb(cb), std::move(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
get(key, bindGetCb(cb), donecb, std::forward<Value::Filter>(f), std::forward<Where>(w));
}
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallbackSimple donecb, Value::Filter&& f={}, Where&& w = {}) override {
get(key, bindGetCb(cb), bindDoneCb(std::move(donecb)), std::forward<Value::Filter>(f), std::forward<Where>(w));
get(key, bindGetCb(cb), bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
}
/**
@@ -134,7 +134,7 @@ public:
time_point created=time_point::max(),
bool permanent = false) override
{
put(key, v, bindDoneCb(std::move(cb)), created, permanent);
put(key, v, bindDoneCb(cb), created, permanent);
}
void put(const InfoHash& key,
@@ -143,7 +143,7 @@ public:
time_point created=time_point::max(),
bool permanent = false) override
{
put(key, std::make_shared<Value>(std::move(v)), std::move(cb), created, permanent);
put(key, std::make_shared<Value>(std::move(v)), cb, created, permanent);
}
void put(const InfoHash& key,
Value&& v,
@@ -151,7 +151,7 @@ public:
time_point created=time_point::max(),
bool permanent = false) override
{
put(key, std::forward<Value>(v), bindDoneCb(std::move(cb)), created, permanent);
put(key, std::forward<Value>(v), bindDoneCb(cb), created, permanent);
}
/**
@@ -176,14 +176,14 @@ public:
virtual size_t listen(const InfoHash&, ValueCallback, Value::Filter={}, Where={}) override;
virtual size_t listen(const InfoHash& key, GetCallback cb, Value::Filter f={}, Where w={}) override {
return listen(key, [cb=std::move(cb)](const std::vector<Sp<Value>>& vals, bool expired){
return listen(key, [cb](const std::vector<Sp<Value>>& vals, bool expired){
if (not expired)
return cb(vals);
return true;
}, std::forward<Value::Filter>(f), std::forward<Where>(w));
}
virtual size_t listen(const InfoHash& key, GetCallbackSimple cb, Value::Filter f={}, Where w={}) override {
return listen(key, bindGetCb(std::move(cb)), std::forward<Value::Filter>(f), std::forward<Where>(w));
return listen(key, bindGetCb(cb), std::forward<Value::Filter>(f), std::forward<Where>(w));
}
/*
* This function relies on the cache implementation.
@@ -197,9 +197,9 @@ public:
*/
void pushNotificationReceived(const std::map<std::string, std::string>& notification) override;
time_point periodic(const uint8_t*, size_t, SockAddr, const time_point& now) override;
time_point periodic(const uint8_t* buf, size_t buflen, const sockaddr* from, socklen_t fromlen, const time_point& now) override {
return periodic(buf, buflen, SockAddr(from, fromlen), now);
time_point periodic(const uint8_t*, size_t, SockAddr) override;
time_point periodic(const uint8_t* buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
return periodic(buf, buflen, SockAddr(from, fromlen));
}
/**
@@ -214,7 +214,7 @@ public:
*/
virtual void query(const InfoHash& /*key*/, QueryCallback /*cb*/, DoneCallback /*done_cb*/ = {}, Query&& /*q*/ = {}) override { }
virtual void query(const InfoHash& key, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query&& q = {}) override {
query(key, cb, bindDoneCb(std::move(done_cb)), std::forward<Query>(q));
query(key, cb, bindDoneCb(done_cb), std::forward<Query>(q));
}
/**
@@ -264,10 +264,11 @@ public:
std::vector<unsigned> getNodeMessageStats(bool) override { return {}; }
void setStorageLimit(size_t) override {}
void connectivityChanged(sa_family_t) override {
getProxyInfos();
restartListeners();
}
void connectivityChanged() override {
getProxyInfos();
restartListeners();
loopSignal_();
}
@@ -284,7 +285,9 @@ private:
*/
struct InfoState;
void getProxyInfos();
void queryProxyInfo(const std::shared_ptr<InfoState>& infoState, const std::shared_ptr<http::Resolver>& resolver, sa_family_t family);
void handleProxyStatus(const asio::error_code &ec, std::shared_ptr<InfoState> infoState);
void queryProxyInfo(std::shared_ptr<InfoState> infoState, const sa_family_t family,
std::vector<asio::ip::tcp::endpoint>&& endpoints);
void onProxyInfos(const Json::Value& val, const sa_family_t family);
SockAddr parsePublicAddress(const Json::Value& val);
@@ -299,18 +302,17 @@ private:
SUBSCRIBE,
RESUBSCRIBE,
};
using CacheValueCallback = std::function<bool(const std::vector<std::shared_ptr<Value>>& values, bool expired, system_clock::time_point)>;
/**
* Send Listen with httpClient_
*/
void sendListen(const restinio::http_request_header_t& header, const CacheValueCallback& cb,
void sendListen(const restinio::http_request_header_t header, const ValueCallback& cb,
const Sp<OperationState>& opstate, Listener& listener, ListenMethod method = ListenMethod::LISTEN);
void handleResubscribe(const asio::error_code& ec, const InfoHash& key,
const size_t token, std::shared_ptr<OperationState> opstate);
void doPut(const InfoHash&, Sp<Value>, DoneCallbackSimple, time_point created, bool permanent);
void handleRefreshPut(const asio::error_code& ec, InfoHash key, Value::Id id);
void doPut(const InfoHash&, Sp<Value>, DoneCallback, time_point created, bool permanent);
void handleRefreshPut(const asio::error_code& ec, const InfoHash& key, const Value::Id id,
std::shared_ptr<std::atomic_bool> ok);
/**
* Initialize statusIpvX_
@@ -320,15 +322,27 @@ private:
* cancel all Listeners
*/
void cancelAllListeners();
/**
* cancel all Operations
*/
void cancelAllOperations();
std::atomic_bool isDestroying_ {false};
std::string proxyUrl_;
dht::crypto::Identity clientIdentity_;
std::shared_ptr<dht::crypto::Certificate> serverCertificate_;
//std::pair<std::string, std::string> serverHostService_;
std::pair<std::string, std::string> serverHostService_;
std::string pushClientId_;
std::string pushSessionId_;
/*
* ASIO I/O Context for sockets in httpClient_
* Note: Each context is used in one thread only
*/
asio::io_context httpContext_;
std::shared_ptr<http::Resolver> resolver_;
std::map<unsigned int /*id*/, std::shared_ptr<http::Request>> requests_;
/*
* Thread for executing the http io_context.run() blocking call
*/
std::thread httpClientThread_;
mutable std::mutex lockCurrentProxyInfos_;
NodeStatus statusIpv4_ {NodeStatus::Disconnected};
@@ -337,55 +351,42 @@ private:
NodeStats stats6_ {};
SockAddr publicAddressV4_;
SockAddr publicAddressV6_;
std::atomic_bool launchConnectedCbs_ {false};
InfoHash myid {};
// registred types
TypeStore types;
/*
* ASIO I/O Context for sockets in httpClient_
* Note: Each context is used in one thread only
*/
asio::io_context httpContext_;
std::shared_ptr<http::Resolver> resolver_;
mutable std::mutex requestLock_;
std::map<unsigned, std::shared_ptr<http::Request>> requests_;
/*
* Thread for executing the http io_context.run() blocking call
*/
std::thread httpClientThread_;
/**
* Store listen requests.
*/
struct ProxySearch;
mutable std::mutex searchLock_;
size_t listenerToken_ {0};
std::map<InfoHash, ProxySearch> searches_;
mutable std::mutex searchLock_;
/**
* Callbacks should be executed in the main thread.
*/
std::mutex lockCallbacks_;
std::vector<std::function<void()>> callbacks_;
std::mutex lockCallbacks_;
Sp<InfoState> infoState_;
Sp<asio::steady_timer> statusTimer_;
mutable std::mutex statusLock_;
/**
* Retrieve if we can connect to the proxy (update statusIpvX_)
*/
void handleProxyConfirm(const asio::error_code &ec);
std::unique_ptr<asio::steady_timer> nextProxyConfirmationTimer_;
std::unique_ptr<asio::steady_timer> listenerRestartTimer_;
Sp<asio::steady_timer> nextProxyConfirmationTimer_;
Sp<asio::steady_timer> listenerRestartTimer_;
/**
* Relaunch LISTEN requests if the client disconnect/reconnect.
*/
void restartListeners(const asio::error_code &ec);
void restartListeners();
/**
* Refresh a listen via a token
@@ -406,10 +407,9 @@ private:
void getPushRequest(Json::Value&) const;
#endif // OPENDHT_PUSH_NOTIFICATIONS
Json::StreamWriterBuilder jsonBuilder_;
std::unique_ptr<Json::CharReader> jsonReader_;
std::atomic_bool isDestroying_ {false};
std::shared_ptr<http::Request> buildRequest(const std::string& target = {});
std::shared_ptr<dht::Logger> logger_;
};
}
+40 -114
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
@@ -31,20 +31,14 @@
#include <restinio/all.hpp>
#include <restinio/tls.hpp>
#ifdef OPENDHT_JSONCPP
#include <json/json.h>
#endif
#include <memory>
#include <mutex>
namespace dht {
enum class PushType {
None = 0,
Android,
iOS
};
}
MSGPACK_ADD_ENUM(dht::PushType)
namespace http {
class Request;
struct ListenerSession;
@@ -60,13 +54,8 @@ class DhtRunner;
using RestRouter = restinio::router::express_router_t<>;
using RequestStatus = restinio::request_handling_status_t;
struct ProxyServerConfig {
in_port_t port {8000};
std::string pushServer {};
std::string persistStatePath {};
dht::crypto::Identity identity {};
};
using ResponseByParts = restinio::chunked_output_t;
using ResponseByPartsBuilder = restinio::response_builder_t<ResponseByParts>;
/**
* Describes the REST API
@@ -82,9 +71,10 @@ public:
* @note if the server fails to start (if port is already used or reserved),
* it will fails silently
*/
DhtProxyServer(const std::shared_ptr<DhtRunner>& dht,
const ProxyServerConfig& config = {},
const std::shared_ptr<dht::Logger>& logger = {});
DhtProxyServer(
dht::crypto::Identity identity,
std::shared_ptr<DhtRunner> dht, in_port_t port = 8000, const std::string& pushServer = "",
std::shared_ptr<dht::Logger> logger = {});
virtual ~DhtProxyServer();
@@ -97,33 +87,33 @@ public:
struct ServerStats {
/** Current number of listen operations */
size_t listenCount {0};
/** Current number of permanent put operations (hash used) */
size_t putCount {0};
/** Current number of permanent put values */
size_t totalPermanentPuts {0};
size_t listenCount;
/** Current number of permanent put operations */
size_t putCount;
/** Current number of push tokens with at least one listen operation */
size_t pushListenersCount {0};
size_t pushListenersCount;
/** Average requests per second */
double requestRate {0};
double requestRate;
/** Node Info **/
std::shared_ptr<NodeInfo> nodeInfo {};
NodeInfo nodeInfo;
std::string toString() const {
std::ostringstream ss;
ss << "Listens: " << listenCount << " Puts: " << putCount << " PushListeners: " << pushListenersCount << std::endl;
ss << "Requests: " << requestRate << " per second." << std::endl;
if (nodeInfo) {
auto& ipv4 = nodeInfo->ipv4;
if (ipv4.table_depth > 1)
ss << "IPv4 Network estimation: " << ipv4.getNetworkSizeEstimation() << std::endl;;
auto& ipv6 = nodeInfo->ipv6;
if (ipv6.table_depth > 1)
ss << "IPv6 Network estimation: " << ipv6.getNetworkSizeEstimation() << std::endl;;
auto& ni = nodeInfo;
auto& ipv4 = ni.ipv4;
if (ipv4.table_depth > 1) {
ss << "IPv4 Network estimation: " << ipv4.getNetworkSizeEstimation() << std::endl;;
}
auto& ipv6 = ni.ipv6;
if (ipv6.table_depth > 1) {
ss << "IPv6 Network estimation: " << ipv6.getNetworkSizeEstimation() << std::endl;;
}
return ss.str();
}
#ifdef OPENDHT_JSONCPP
/**
* Build a json object from a NodeStats
*/
@@ -131,18 +121,17 @@ public:
Json::Value result;
result["listenCount"] = static_cast<Json::UInt64>(listenCount);
result["putCount"] = static_cast<Json::UInt64>(putCount);
result["totalPermanentPuts"] = static_cast<Json::UInt64>(totalPermanentPuts);
result["pushListenersCount"] = static_cast<Json::UInt64>(pushListenersCount);
result["requestRate"] = requestRate;
if (nodeInfo)
result["nodeInfo"] = nodeInfo->toJson();
result["nodeInfo"] = nodeInfo.toJson();
return result;
}
#endif
};
std::shared_ptr<ServerStats> stats() const { return stats_; }
ServerStats stats() const { return stats_; }
std::shared_ptr<ServerStats> updateStats(std::shared_ptr<NodeInfo> info) const;
void updateStats() const;
std::shared_ptr<DhtRunner> getNode() const { return dht_; }
@@ -152,8 +141,7 @@ private:
struct RestRouterTraits;
template <typename HttpResponse>
static HttpResponse initHttpResponse(HttpResponse response);
static restinio::request_handling_status_t serverError(restinio::request_t& request);
HttpResponse initHttpResponse(HttpResponse response) const;
template< typename ServerSettings >
void addServerSettings(ServerSettings& serverSettings,
@@ -161,8 +149,6 @@ private:
std::unique_ptr<RestRouter> createRestRouter();
void onConnectionClosed(restinio::connection_id_t);
/**
* Return the PublicKey id, the node id and node stats
* Method: GET "/"
@@ -300,17 +286,17 @@ private:
* @param key of the device
* @param json, the content to send
*/
void sendPushNotification(const std::string& key, Json::Value&& json, PushType type, bool highPriority);
void sendPushNotification(const std::string& key, Json::Value&& json, bool isAndroid);
/**
* Send push notification with an expire timeout.
* @param ec
* @param pushToken
* @param json
* @param type
* @param isAndroid
*/
void handleNotifyPushListenExpire(const asio::error_code &ec, const std::string pushToken,
std::function<Json::Value()> json, PushType type);
Json::Value json, const bool isAndroid);
/**
* Remove a push listener between a client and a hash
@@ -325,24 +311,12 @@ private:
#endif //OPENDHT_PUSH_NOTIFICATIONS
void handlePrintStats(const asio::error_code &ec);
void updateStats();
template <typename Os>
void saveState(Os& stream);
template <typename Is>
void loadState(Is& is, size_t size);
using clock = std::chrono::steady_clock;
using time_point = clock::time_point;
std::shared_ptr<asio::io_context> ioContext_;
std::shared_ptr<DhtRunner> dht_;
Json::StreamWriterBuilder jsonBuilder_;
Json::CharReaderBuilder jsonReaderBuilder_;
std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
std::string persistPath_;
// http server
std::thread serverThread_;
@@ -351,62 +325,32 @@ private:
// http client
std::pair<std::string, std::string> pushHostPort_;
mutable std::mutex requestLock_;
std::map<unsigned int /*id*/, std::shared_ptr<http::Request>> requests_;
std::shared_ptr<dht::Logger> logger_;
std::shared_ptr<ServerStats> stats_;
std::shared_ptr<NodeInfo> nodeInfo_ {};
mutable std::mutex statsMutex_;
mutable ServerStats stats_;
mutable NodeInfo nodeInfo_ {};
std::unique_ptr<asio::steady_timer> printStatsTimer_;
// Thread-safe access to listeners map.
std::mutex lockListener_;
std::shared_ptr<std::mutex> lockListener_;
// Shared with connection listener.
std::map<restinio::connection_id_t, http::ListenerSession> listeners_;
std::shared_ptr<std::map<restinio::connection_id_t,
http::ListenerSession>> listeners_;
// Connection Listener observing conn state changes.
std::shared_ptr<ConnectionListener> connListener_;
struct PushSessionContext {
std::mutex lock;
std::string sessionId;
PushSessionContext(const std::string& id) : sessionId(id) {}
};
struct PermanentPut {
time_point expiration;
std::string pushToken;
std::string clientId;
std::shared_ptr<PushSessionContext> sessionCtx;
std::unique_ptr<asio::steady_timer> expireTimer;
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
Sp<Value> value;
PushType type;
template <typename Packer>
void msgpack_pack(Packer& p) const
{
p.pack_map(2 + (sessionCtx ? 1 : 0) + (clientId.empty() ? 0 : 1) + (type == PushType::None ? 0 : 2));
p.pack("value"); p.pack(value);
p.pack("exp"); p.pack(to_time_t(expiration));
if (not clientId.empty()) {
p.pack("cid"); p.pack(clientId);
}
if (sessionCtx) {
std::lock_guard<std::mutex> l(sessionCtx->lock);
p.pack("sid"); p.pack(sessionCtx->sessionId);
}
if (type != PushType::None) {
p.pack("t"); p.pack(type);
p.pack("token"); p.pack(pushToken);
}
}
void msgpack_unpack(const msgpack::object& o);
};
struct SearchPuts {
std::map<dht::Value::Id, PermanentPut> puts;
MSGPACK_DEFINE_ARRAY(puts)
};
std::mutex lockSearchPuts_;
std::map<InfoHash, SearchPuts> puts_;
@@ -418,33 +362,15 @@ private:
#ifdef OPENDHT_PUSH_NOTIFICATIONS
struct Listener {
time_point expiration;
std::string clientId;
std::shared_ptr<PushSessionContext> sessionCtx;
std::future<size_t> internalToken;
std::unique_ptr<asio::steady_timer> expireTimer;
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
PushType type;
template <typename Packer>
void msgpack_pack(Packer& p) const
{
p.pack_map(sessionCtx ? 4 : 3);
p.pack("cid"); p.pack(clientId);
p.pack("exp"); p.pack(to_time_t(expiration));
if (sessionCtx) {
std::lock_guard<std::mutex> l(sessionCtx->lock);
p.pack("sid"); p.pack(sessionCtx->sessionId);
}
p.pack("t"); p.pack(type);
}
void msgpack_unpack(const msgpack::object& o);
};
struct PushListener {
std::map<InfoHash, std::vector<Listener>> listeners;
MSGPACK_DEFINE_ARRAY(listeners)
};
std::mutex lockPushListeners_;
std::map<std::string, PushListener> pushListeners_;
proxy::ListenToken tokenPushNotif_ {0};
#endif //OPENDHT_PUSH_NOTIFICATIONS
+64 -68
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
@@ -65,7 +65,6 @@ public:
bool peer_publish {false};
std::shared_ptr<dht::crypto::Certificate> server_ca;
dht::crypto::Identity client_identity;
SockAddr bind4 {}, bind6 {};
};
struct Context {
@@ -74,7 +73,6 @@ public:
std::shared_ptr<PeerDiscovery> peerDiscovery {};
StatusCallback statusChangedCallback {};
CertificateStoreQuery certificateStore {};
IdentityAnnouncedCb identityAnnouncedCb {};
Context() {}
};
@@ -99,7 +97,7 @@ public:
template <class T>
void get(InfoHash hash, std::function<bool(std::vector<T>&&)> cb, DoneCallbackSimple dcb={})
{
get(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
get(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
return cb(unpackVector<T>(vals));
},
dcb,
@@ -108,7 +106,7 @@ public:
template <class T>
void get(InfoHash hash, std::function<bool(T&&)> cb, DoneCallbackSimple dcb={})
{
get(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
get(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
for (const auto& v : vals) {
try {
if (not cb(Value::unpack<T>(*v)))
@@ -157,7 +155,7 @@ public:
std::future<size_t> listen(InfoHash key, ValueCallback vcb, Value::Filter f = {}, Where w = {});
std::future<size_t> listen(InfoHash key, GetCallback cb, Value::Filter f={}, Where w={}) {
return listen(key, [cb=std::move(cb)](const std::vector<Sp<Value>>& vals, bool expired){
return listen(key, [cb](const std::vector<Sp<Value>>& vals, bool expired){
if (not expired)
return cb(vals);
return true;
@@ -171,7 +169,7 @@ public:
template <class T>
std::future<size_t> listen(InfoHash hash, std::function<bool(std::vector<T>&&)> cb)
{
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
return cb(unpackVector<T>(vals));
},
getFilterSet<T>());
@@ -179,7 +177,7 @@ public:
template <class T>
std::future<size_t> listen(InfoHash hash, std::function<bool(std::vector<T>&&, bool)> cb)
{
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
return cb(unpackVector<T>(vals), expired);
},
getFilterSet<T>());
@@ -188,7 +186,7 @@ public:
template <typename T>
std::future<size_t> listen(InfoHash hash, std::function<bool(T&&)> cb, Value::Filter f = {}, Where w = {})
{
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
for (const auto& v : vals) {
try {
if (not cb(Value::unpack<T>(*v)))
@@ -204,7 +202,7 @@ public:
template <typename T>
std::future<size_t> listen(InfoHash hash, std::function<bool(T&&, bool)> cb, Value::Filter f = {}, Where w = {})
{
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
for (const auto& v : vals) {
try {
if (not cb(Value::unpack<T>(*v), expired))
@@ -232,48 +230,36 @@ public:
}
void put(const std::string& key, Value&& value, DoneCallbackSimple cb={}, time_point created=time_point::max(), bool permanent = false);
void cancelPut(const InfoHash& h, Value::Id id);
void cancelPut(const InfoHash& h, const std::shared_ptr<Value>& value);
void cancelPut(const InfoHash& h, const Value::Id& id);
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
putSigned(hash, value, bindDoneCb(cb), permanent);
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={});
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb) {
putSigned(hash, value, bindDoneCb(cb));
}
void putSigned(InfoHash hash, Value&& value, DoneCallback cb={}, bool permanent = false);
void putSigned(InfoHash hash, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
putSigned(hash, std::forward<Value>(value), bindDoneCb(cb), permanent);
void putSigned(InfoHash hash, Value&& value, DoneCallback cb={});
void putSigned(InfoHash hash, Value&& value, DoneCallbackSimple cb) {
putSigned(hash, std::forward<Value>(value), bindDoneCb(cb));
}
void putSigned(const std::string& key, Value&& value, DoneCallbackSimple cb={}, bool permanent = false);
void putSigned(const std::string& key, Value&& value, DoneCallbackSimple cb={});
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallback cb={});
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallbackSimple cb) {
putEncrypted(hash, to, value, bindDoneCb(cb));
}
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallback cb={});
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallbackSimple cb) {
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb));
}
void putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
}
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
}
void putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb={});
/**
* Insert known nodes to the routing table, without necessarly ping them.
* Usefull to restart a node and get things running fast without putting load on the network.
*/
void bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple cb={});
void bootstrap(const SockAddr& addr, DoneCallbackSimple cb={});
void bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple&& cb={});
void bootstrap(const SockAddr& addr, DoneCallbackSimple&& cb={});
/**
* Insert known nodes to the routing table, without necessarly ping them.
@@ -314,7 +300,6 @@ public:
* Get the public key fingerprint if an identity is used with this node, 0 otherwise.
*/
InfoHash getId() const;
std::shared_ptr<crypto::PublicKey> getPublicKey() const;
/**
* Get the ID of the DHT node.
@@ -331,7 +316,9 @@ public:
* Returns the currently bound port, in host byte order.
* @param f: address family of the bound port to retreive.
*/
in_port_t getBoundPort(sa_family_t f = AF_INET) const;
in_port_t getBoundPort(sa_family_t f = AF_INET) const {
return getBound(f).getPort();
}
std::pair<size_t, size_t> getStoreSize() const;
@@ -341,10 +328,7 @@ public:
std::vector<ValuesExport> exportValues() const;
void setLogger(const Sp<Logger>& logger = {});
void setLogger(const Logger& logger) {
setLogger(std::make_shared<Logger>(logger));
}
void setLogger(const Logger& logger = {});
void setLoggers(LogMethod err = {}, LogMethod warn = {}, LogMethod debug = {});
/**
@@ -357,13 +341,12 @@ public:
void importValues(const std::vector<ValuesExport>& values);
bool isRunning() const {
return running != State::Idle;
return running;
}
NodeStats getNodesStats(sa_family_t af) const;
unsigned getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_return, unsigned *cached_return, unsigned *incoming_return) const;
NodeInfo getNodeInfo() const;
void getNodeInfo(std::function<void(std::shared_ptr<NodeInfo>)>);
std::vector<unsigned> getNodeMessageStats(bool in = false) const;
std::string getStorageLog() const;
@@ -373,11 +356,10 @@ public:
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
std::vector<SockAddr> getPublicAddress(sa_family_t af = AF_UNSPEC);
std::vector<std::string> getPublicAddressStr(sa_family_t af = AF_UNSPEC);
void getPublicAddress(std::function<void(std::vector<SockAddr>&&)>, sa_family_t af = AF_UNSPEC);
// securedht methods
void findCertificate(InfoHash hash, std::function<void(const std::shared_ptr<crypto::Certificate>&)>);
void findCertificate(InfoHash hash, std::function<void(const std::shared_ptr<crypto::Certificate>)>);
void registerCertificate(std::shared_ptr<crypto::Certificate> cert);
void setLocalCertificateStore(CertificateStoreQuery&& query_method);
@@ -394,12 +376,22 @@ public:
config.threaded = threaded;
run(port, config);
}
void run(in_port_t port, Config& config, Context&& context = {});
void run(in_port_t port, const Config& config, Context&& context = {});
/**
* @param local4: Local IPv4 address and port to bind. Can be null.
* @param local6: Local IPv6 address and port to bind. Can be null.
* You should allways bind to a global IPv6 address.
* @param identity: RSA key pair to use for cryptographic operations.
* @param threaded: If false, loop() must be called periodically. Otherwise a thread is launched.
* @param cb: Optional callback to receive general state information.
*/
void run(const SockAddr& local4, const SockAddr& local6, const Config& config, Context&& context = {});
/**
* Same as @run(sockaddr_in, sockaddr_in6, Identity, bool, StatusCallback), but with string IP addresses and service (port).
*/
void run(const char* ip4, const char* ip6, const char* service, Config& config, Context&& context = {});
void run(const char* ip4, const char* ip6, const char* service, const Config& config, Context&& context = {});
void run(const Config& config, Context&& context);
@@ -420,7 +412,7 @@ public:
/**
* Gracefuly disconnect from network.
*/
void shutdown(ShutdownCallback cb = {}, bool stop = false);
void shutdown(ShutdownCallback cb);
/**
* Quit and wait for all threads to terminate.
@@ -456,11 +448,15 @@ public:
void forwardAllMessages(bool forward);
private:
enum class State {
Idle,
Running,
Stopping
};
static constexpr std::chrono::seconds BOOTSTRAP_PERIOD {10};
/**
* Will try to resolve the list of hostnames `bootstrap_nodes` on seperate
* thread and then queue ping requests. This list should contain reliable
* nodes so that the DHT node can recover quickly from losing connection
* with the network.
*/
void tryBootstrapContinuously();
time_point loop_();
@@ -468,11 +464,6 @@ private:
return std::max(status4, status6);
}
bool checkShutdown();
void opEnded();
DoneCallback bindOpDoneCallback(DoneCallback&& cb);
DoneCallbackSimple bindOpDoneCallback(DoneCallbackSimple&& cb);
/** Local DHT instance */
std::unique_ptr<SecureDht> dht_;
@@ -484,7 +475,6 @@ private:
/** Current configuration */
Config config_;
IdentityAnnouncedCb identityAnnouncedCb_;
/**
* reset dht clients
@@ -506,16 +496,22 @@ private:
std::thread dht_thread {};
std::condition_variable cv {};
std::mutex sock_mtx {};
net::PacketList rcv {};
decltype(rcv) rcv_free {};
std::queue<std::unique_ptr<net::ReceivedPacket>> rcv {};
/** true if currently actively boostraping */
std::atomic_bool bootstraping {false};
/* bootstrap nodes given as (host, service) pairs */
std::vector<std::pair<std::string,std::string>> bootstrap_nodes_all {};
std::vector<std::pair<std::string,std::string>> bootstrap_nodes {};
std::thread bootstrap_thread {};
std::mutex bootstrap_mtx {};
std::condition_variable bootstrap_cv {};
std::queue<std::function<void(SecureDht&)>> pending_ops_prio {};
std::queue<std::function<void(SecureDht&)>> pending_ops {};
std::mutex storage_mtx {};
std::atomic<State> running {State::Idle};
std::atomic_size_t ongoing_ops {0};
std::vector<ShutdownCallback> shutdownCallbacks_;
std::atomic_bool running {false};
NodeStatus status4 {NodeStatus::Disconnected},
status6 {NodeStatus::Disconnected};
+58 -87
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
* Author: Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,6 @@
#include <memory>
#include <queue>
#include <mutex>
namespace Json {
class Value;
@@ -62,7 +61,7 @@ struct Certificate;
namespace http {
using HandlerCb = std::function<void(const asio::error_code& ec)>;
using BytesHandlerCb = std::function<void(const asio::error_code& ec, size_t bytes)>;
using BytesHandlerCb = std::function<void(const asio::error_code& ec, const size_t bytes)>;
using ConnectHandlerCb = std::function<void(const asio::error_code& ec,
const asio::ip::tcp::endpoint& endpoint)>;
@@ -72,20 +71,18 @@ using socket_t = asio::ip::tcp::socket;
class OPENDHT_PUBLIC Url
{
public:
Url() = default;
Url(){};
Url(const std::string& url);
std::string url;
std::string protocol {"http"};
std::string host;
std::string service;
std::string target;
std::string service {"80"};
std::string target {"/"};
std::string query;
std::string fragment;
std::string toString() const;
};
class OPENDHT_PUBLIC Connection : public std::enable_shared_from_this<Connection>
class OPENDHT_PUBLIC Connection
{
public:
Connection(asio::io_context& ctx, const bool ssl = true, std::shared_ptr<dht::Logger> l = {});
@@ -93,43 +90,30 @@ public:
const dht::crypto::Identity& identity, std::shared_ptr<dht::Logger> l = {});
~Connection();
inline unsigned int id() const { return id_; };
bool is_open() const;
bool is_ssl() const;
void checkOcsp(bool check = true) { checkOcsp_ = check; }
unsigned int id();
bool is_open();
bool is_ssl();
void set_ssl_verification(const std::string& hostname, const asio::ssl::verify_mode verify_mode);
void set_ssl_verification(const asio::ip::tcp::endpoint& endpoint, const asio::ssl::verify_mode verify_mode);
asio::streambuf& input();
std::istream& data() { return istream_; }
asio::streambuf& data();
std::string read_bytes(size_t bytes = 0);
std::string read_bytes(const size_t bytes);
std::string read_until(const char delim);
void async_connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, ConnectHandlerCb);
void async_handshake(HandlerCb cb);
void async_write(BytesHandlerCb cb);
void async_read_until(const char* delim, BytesHandlerCb cb);
void async_read_until(char delim, BytesHandlerCb cb);
void async_read(size_t bytes, BytesHandlerCb cb);
void async_read_some(size_t bytes, BytesHandlerCb cb);
void async_read(const size_t bytes, BytesHandlerCb cb);
void timeout(const std::chrono::seconds timeout, HandlerCb cb = {});
void close();
private:
template<typename T>
T wrapCallabck(T cb) const {
return [t=shared_from_this(),cb=std::move(cb)](auto ...params) {
cb(params...);
};
}
mutable std::mutex mutex_;
unsigned int id_;
static std::atomic_uint ids_;
static unsigned int ids_;
asio::io_context& ctx_;
std::unique_ptr<socket_t> socket_;
@@ -140,11 +124,9 @@ private:
asio::streambuf write_buf_;
asio::streambuf read_buf_;
std::istream istream_;
std::unique_ptr<asio::steady_timer> timeout_timer_;
std::shared_ptr<dht::Logger> logger_;
bool checkOcsp_ {false};
};
/**
@@ -165,7 +147,7 @@ class OPENDHT_PUBLIC Resolver
{
public:
using ResolverCb = std::function<void(const asio::error_code& ec,
const std::vector<asio::ip::tcp::endpoint>& endpoints)>;
std::vector<asio::ip::tcp::endpoint> endpoints)>;
Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger = {});
Resolver(asio::io_context& ctx, const std::string& host, const std::string& service,
@@ -174,25 +156,19 @@ public:
// use already resolved endpoints with classes using this resolver
Resolver(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint> endpoints,
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
Resolver(asio::io_context& ctx, const std::string& url, std::vector<asio::ip::tcp::endpoint> endpoints,
std::shared_ptr<dht::Logger> logger = {});
~Resolver();
inline const Url& get_url() const {
return url_;
}
};
void add_callback(ResolverCb cb, sa_family_t family = AF_UNSPEC);
std::shared_ptr<Logger> getLogger() const {
return logger_;
}
void add_callback(ResolverCb cb);
private:
void resolve(const std::string& host, const std::string& service);
mutable std::mutex mutex_;
std::mutex mutex_;
Url url_;
asio::error_code ec_;
@@ -206,18 +182,14 @@ private:
std::shared_ptr<dht::Logger> logger_;
};
class Request;
struct Response
{
unsigned status_code {0};
unsigned int status_code;
std::map<std::string, std::string> headers;
std::string body;
bool aborted {false};
std::weak_ptr<Request> request;
};
class OPENDHT_PUBLIC Request : public std::enable_shared_from_this<Request>
class OPENDHT_PUBLIC Request
{
public:
enum class State {
@@ -227,26 +199,20 @@ public:
RECEIVING,
DONE
};
using OnStatusCb = std::function<void(unsigned status_code)>;
using OnStatusCb = std::function<void(unsigned int status_code)>;
using OnDataCb = std::function<void(const char* at, size_t length)>;
using OnStateChangeCb = std::function<void(State state, const Response& response)>;
using OnJsonCb = std::function<void(Json::Value value, const Response& response)>;
using OnDoneCb = std::function<void(const Response& response)>;
using OnJsonCb = std::function<void(Json::Value value, unsigned int status_code)>;
// resolves implicitly
Request(asio::io_context& ctx, const std::string& url, const Json::Value& json, OnJsonCb jsoncb,
std::shared_ptr<dht::Logger> logger = {});
Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb,
std::shared_ptr<dht::Logger> logger = {});
Request(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger = {});
Request(asio::io_context& ctx, const std::string& host, const std::string& service,
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, std::shared_ptr<dht::Logger> logger = {});
// user defined resolver
Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, sa_family_t family = AF_UNSPEC);
Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, const std::string& target, sa_family_t family = AF_UNSPEC);
Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, std::shared_ptr<dht::Logger> logger = {});
// user defined resolved endpoints
Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints,
@@ -254,18 +220,12 @@ public:
~Request();
inline unsigned int id() const { return id_; };
unsigned int id() const;
void set_connection(std::shared_ptr<Connection> connection);
std::shared_ptr<Connection> get_connection() const;
inline const Url& get_url() const {
return resolver_->get_url();
};
/** The previous request in case of redirect following */
std::shared_ptr<Request> getPrevious() const {
return prev_.lock();
}
inline std::string& to_string() {
return request_;
}
@@ -288,33 +248,31 @@ public:
void add_on_status_callback(OnStatusCb cb);
void add_on_body_callback(OnDataCb cb);
void add_on_state_change_callback(OnStateChangeCb cb);
void add_on_done_callback(OnDoneCb cb);
void send();
/** Send and block for response */
const Response& await();
/**
* User action to cancel the Request and call the completion callbacks.
*/
void cancel();
void terminate(const asio::error_code& ec);
private:
using OnCompleteCb = std::function<void()>;
struct Callbacks {
Callbacks(){}
OnStatusCb on_status;
OnDataCb on_header_field;
OnDataCb on_header_value;
OnDataCb on_body;
OnCompleteCb on_headers_complete;
OnCompleteCb on_message_complete;
OnStateChangeCb on_state_change;
};
static std::string getRelativePath(const Url& origin, const std::string& path);
void notify_state_change(State state);
void notify_state_change(const State state);
void build();
@@ -326,25 +284,30 @@ private:
void connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb = {});
void terminate(const asio::error_code& ec);
void post();
void handle_request(const asio::error_code& ec);
void handle_response(const asio::error_code& ec, size_t bytes);
void onHeadersComplete();
void onBody(const char* at, size_t length);
void onComplete();
void handle_response_header(const asio::error_code& ec);
mutable std::mutex mutex_;
void handle_response_body(const asio::error_code& ec, const size_t bytes);
std::shared_ptr<dht::Logger> logger_;
/**
* Parse the request with http_parser.
* Return how many bytes were parsed.
* Note: we pass requerst.size()==0 to signal that EOF has been received.
*/
size_t parse_request(const std::string& request);
restinio::http_request_header_t header_;
std::map<restinio::http_field_t, std::string> headers_;
restinio::http_connection_header_t connection_type_ {restinio::http_connection_header_t::close};
restinio::http_connection_header_t connection_type_;
std::string body_;
Callbacks cbs_;
std::mutex cbs_mutex_;
std::unique_ptr<Callbacks> cbs_;
State state_;
dht::crypto::Identity client_identity_;
@@ -353,25 +316,33 @@ private:
std::string host_;
unsigned int id_;
static std::atomic_uint ids_;
static unsigned int ids_;
asio::io_context& ctx_;
sa_family_t family_ = AF_UNSPEC;
std::shared_ptr<Connection> conn_;
std::shared_ptr<Resolver> resolver_;
Response response_ {};
std::string request_;
std::atomic<bool> message_complete_ {false};
std::atomic<bool> finishing_ {false};
std::unique_ptr<http_parser> parser_;
std::unique_ptr<http_parser_settings> parser_s_;
// Next request in case of redirect following
std::shared_ptr<Request> next_;
std::weak_ptr<Request> prev_;
unsigned num_redirect {0};
bool follow_redirect {true};
std::shared_ptr<dht::Logger> logger_;
};
} // namespace http
} // namespace dht
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
namespace restinio
{
/* Custom HTTP-methods for RESTinio > 0.5.0.
* https://github.com/Stiffstream/restinio/issues/26
*/
constexpr const restinio::http_method_id_t method_listen {HTTP_LISTEN, "LISTEN"};
constexpr const restinio::http_method_id_t method_stats {HTTP_STATS, "STATS"};
constexpr const restinio::http_method_id_t method_sign {HTTP_SIGN, "SIGN"};
constexpr const restinio::http_method_id_t method_encrypt {HTTP_ENCRYPT, "ENCRYPT"};
} // namespace restinio
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Nicolas Reynaud <nicolas.reynaud@savoirfairelinux.com>
@@ -335,7 +335,7 @@ public:
void lookup(Key k, LookupCallback cb = {}, DoneCallbackSimple done_cb = {}, bool exact_match = true);
void lookup(Key k, LookupCallbackSimple cb = {}, DoneCallbackSimple done_cb = {}, bool exact_match = true)
{
lookup(k, [cb=std::move(cb)](std::vector<std::shared_ptr<Value>>& values, Prefix) { cb(values); }, done_cb, exact_match);
lookup(k, [=](std::vector<std::shared_ptr<Value>>& values, Prefix) { cb(values); }, done_cb, exact_match);
}
/**
+32 -63
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -40,12 +40,10 @@ typedef uint16_t in_port_t;
#include <iomanip>
#include <array>
#include <vector>
#include <string_view>
#include <algorithm>
#include <stdexcept>
#include <sstream>
#include <cstring>
#include <cstddef>
namespace dht {
@@ -56,9 +54,9 @@ namespace crypto {
}
/**
* Represents an Hash,
* a byte array of N bytes.
* Hashes identify nodes and values in the Dht.
* Represents an InfoHash.
* An InfoHash is a byte array of HASH_LEN bytes.
* InfoHashes identify nodes and values in the Dht.
*/
template <size_t N>
class OPENDHT_PUBLIC Hash {
@@ -67,10 +65,10 @@ public:
typedef typename T::iterator iterator;
typedef typename T::const_iterator const_iterator;
Hash() noexcept {
Hash () noexcept {
data_.fill(0);
}
Hash(const uint8_t* h, size_t data_len) {
Hash (const uint8_t* h, size_t data_len) {
if (data_len < N)
data_.fill(0);
else
@@ -81,12 +79,7 @@ public:
* hex must be at least 2.HASH_LEN characters long.
* If too long, only the first 2.HASH_LEN characters are read.
*/
explicit Hash(std::string_view hex) {
if (hex.size() < 2*N)
data_.fill(0);
else
fromString(hex.data());
}
explicit Hash(const std::string& hex);
Hash(const msgpack::object& o) {
msgpack_unpack(o);
@@ -100,8 +93,6 @@ public:
iterator end() { return data_.end(); }
const_iterator cend() const { return data_.cend(); }
static constexpr inline Hash zero() noexcept { return Hash{}; }
bool operator==(const Hash& h) const {
auto a = reinterpret_cast<const uint32_t*>(data_.data());
auto b = reinterpret_cast<const uint32_t*>(h.data_.data());
@@ -121,14 +112,6 @@ public:
return false;
}
Hash operator^(const Hash& o) const {
Hash result;
for(auto i = 0u; i < N; i++) {
result[i] = data_[i] ^ o.data_[i];
}
return result;
}
explicit operator bool() const {
auto a = reinterpret_cast<const uint32_t*>(data_.data());
auto b = reinterpret_cast<const uint32_t*>(data_.data() + N);
@@ -159,6 +142,10 @@ public:
return 8 * i + j;
}
/**
* Forget about the ``XOR-metric''. An id is just a path from the
* root of the tree, so bits are numbered from the start.
*/
static inline int cmp(const Hash& id1, const Hash& id2) {
return std::memcmp(id1.data_.data(), id2.data_.data(), N);
}
@@ -192,12 +179,16 @@ public:
int
xorCmp(const Hash& id1, const Hash& id2) const
{
for (unsigned i = 0; i < N; i++) {
for(unsigned i = 0; i < N; i++) {
uint8_t xor1, xor2;
if(id1.data_[i] == id2.data_[i])
continue;
uint8_t xor1 = id1.data_[i] ^ data_[i];
uint8_t xor2 = id2.data_[i] ^ data_[i];
return (xor1 < xor2) ? -1 : 1;
xor1 = id1.data_[i] ^ data_[i];
xor2 = id2.data_[i] ^ data_[i];
if(xor1 < xor2)
return -1;
else
return 1;
}
return 0;
}
@@ -226,7 +217,7 @@ public:
return v;
}
static inline Hash get(std::string_view data) {
static inline Hash get(const std::string& data) {
return get((const uint8_t*)data.data(), data.size());
}
@@ -246,9 +237,6 @@ public:
static Hash getRandom();
template <typename Rd>
static Hash getRandom(Rd&);
template <size_t M>
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Hash<M>& h);
@@ -298,6 +286,14 @@ std::istream& operator>> (std::istream& s, Hash<N>& h)
return s;
}
template <size_t N>
Hash<N>::Hash(const std::string& hex) {
if (hex.size() < 2*N)
data_.fill(0);
else
fromString(hex.c_str());
}
template <size_t N>
void
Hash<N>::fromString(const char* in) {
@@ -328,20 +324,7 @@ Hash<N>::getRandom()
return h;
}
template <size_t N>
template <typename Rd>
Hash<N>
Hash<N>::getRandom(Rd& rdev)
{
Hash h;
std::uniform_int_distribution<uint32_t> rand_int;
auto a = reinterpret_cast<uint32_t*>(h.data());
auto b = reinterpret_cast<uint32_t*>(h.data() + h.size());
std::generate(a, b, std::bind(rand_int, std::ref(rdev)));
return h;
}
struct alignas(std::max_align_t) HexMap : public std::array<std::array<char, 2>, 256> {
struct HexMap : public std::array<std::array<char, 2>, 256> {
HexMap() {
for (size_t i=0; i<size(); i++) {
auto& e = (*this)[i];
@@ -355,27 +338,11 @@ private:
OPENDHT_PUBLIC extern const HexMap hex_map;
inline std::string
toHex(const uint8_t* data, size_t size) {
std::string ret(size * 2, '\0');
for (size_t i=0; i<size; i++) {
auto b = ret.data()+i*2;
const auto& m = hex_map[data[i]];
*((uint16_t*)b) = *((uint16_t*)&m);
}
return ret;
}
inline std::string
toHex(const std::vector<uint8_t>& data) {
return toHex(data.data(), data.size());
}
template <size_t N>
const char*
Hash<N>::to_c_str() const
{
alignas(std::max_align_t) thread_local std::array<char, N*2+1> buf;
thread_local std::array<char, N*2+1> buf;
for (size_t i=0; i<N; i++) {
auto b = buf.data()+i*2;
const auto& m = hex_map[data_[i]];
@@ -391,6 +358,8 @@ Hash<N>::toString() const
return std::string(to_c_str(), N*2);
}
const InfoHash zeroes {};
struct OPENDHT_PUBLIC NodeExport {
InfoHash id;
sockaddr_storage ss;
+4 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
@@ -71,13 +71,13 @@ OPENDHT_PUBLIC void
printLog(std::ostream &s, char const *m, va_list args);
OPENDHT_PUBLIC
std::shared_ptr<Logger> getStdLogger();
std::unique_ptr<Logger> getStdLogger();
OPENDHT_PUBLIC
std::shared_ptr<Logger> getFileLogger(const std::string &path);
std::unique_ptr<Logger> getFileLogger(const std::string &path);
OPENDHT_PUBLIC
std::shared_ptr<Logger> getSyslogLogger(const char* name);
std::unique_ptr<Logger> getSyslogLogger(const char* name);
OPENDHT_PUBLIC void
enableLogging(dht::DhtRunner &dht);
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -64,7 +64,7 @@ struct LogMethod {
func(format, args);
va_end(args);
}
inline void log(char const* format, va_list args) const {
void log(char const* format, va_list args) const {
func(format, args);
}
explicit operator bool() const {
@@ -82,13 +82,13 @@ private:
};
struct Logger {
LogMethod ERR = {};
LogMethod WARN = {};
LogMethod DBG = {};
LogMethod WARN = {};
LogMethod ERR = {};
Logger() = default;
Logger(LogMethod&& err, LogMethod&& warn, LogMethod&& dbg)
: ERR(std::move(err)), WARN(std::move(warn)), DBG(std::move(dbg)) {}
: DBG(std::move(dbg)), WARN(std::move(warn)), ERR(std::move(err)) {}
void setFilter(const InfoHash& f) {
filter_ = f;
filterEnable_ = static_cast<bool>(filter_);
+35 -86
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
@@ -48,12 +48,6 @@ struct TransId;
#define MSG_CONFIRM 0
#endif
struct NetworkConfig {
NetId network {0};
ssize_t max_req_per_sec {0};
ssize_t max_peer_req_per_sec {0};
};
class DhtProtocolException : public DhtException {
public:
// sent to another peer (http-like).
@@ -180,8 +174,7 @@ private:
const InfoHash&,
const Blob&,
Tid,
const Query&,
int)> onListen {};
const Query&)> onListen {};
/**
* Called on announce request.
*
@@ -211,16 +204,10 @@ private:
public:
using RequestCb = std::function<void(const Request&, RequestAnswer&&)>;
using RequestErrorCb = std::function<bool(const Request&, DhtProtocolException&&)>;
using RequestExpiredCb = std::function<void(const Request&, bool)>;
NetworkEngine(
InfoHash& myid,
NetworkConfig config,
std::unique_ptr<DatagramSocket>&& sock,
const Sp<Logger>& log,
std::mt19937_64& rd,
Scheduler& scheduler,
NetworkEngine(Logger& log, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock);
NetworkEngine(InfoHash& myid, NetId net, std::unique_ptr<DatagramSocket>&& sock, Logger& log, Scheduler& scheduler,
decltype(NetworkEngine::onError)&& onError,
decltype(NetworkEngine::onNewNode)&& onNewNode,
decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
@@ -238,10 +225,9 @@ public:
void clear();
/**
* Sends values (with closest nodes) to a listener.
* Sends values (with closest nodes) to a listenner.
*
* @deprecated
* @param sa The address of the listener.
* @param sa The address of the listenner.
* @param sslen The length of the sockaddr structure.
* @param socket_id The tid to use to write to the request socket.
* @param hash The hash key of the value.
@@ -250,14 +236,13 @@ public:
* @param nodes The ipv4 closest nodes.
* @param nodes6 The ipv6 closest nodes.
* @param values The values to send.
* @param version If version = 1, a request will be used to answer to the listener
*/
void tellListener(Sp<Node> n, Tid socket_id, const InfoHash& hash, want_t want, const Blob& ntoken,
std::vector<Sp<Node>>&& nodes, std::vector<Sp<Node>>&& nodes6,
std::vector<Sp<Value>>&& values, const Query& q, int version);
std::vector<Sp<Value>>&& values, const Query& q);
void tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
void tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
void tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values);
void tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values);
bool isRunning(sa_family_t af) const;
inline want_t want () const { return dht_socket->hasIPv4() and dht_socket->hasIPv6() ? (WANT4 | WANT6) : -1; }
@@ -278,8 +263,7 @@ public:
* @return the request with information concerning its success.
*/
Sp<Request>
sendPing(Sp<Node> n, RequestCb&& on_done, RequestExpiredCb&& on_expired);
sendPing(Sp<Node> n, RequestCb&& on_done, RequestExpiredCb&& on_expired);
/**
* Send a "ping" request to a given node.
*
@@ -291,12 +275,11 @@ public:
* @return the request with information concerning its success.
*/
Sp<Request>
sendPing(SockAddr&& sa, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
return sendPing(std::make_shared<Node>(InfoHash::zero(), std::move(sa), rd),
std::forward<RequestCb>(on_done),
std::forward<RequestExpiredCb>(on_expired));
}
sendPing(SockAddr&& sa, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
return sendPing(std::make_shared<Node>(zeroes, std::move(sa)),
std::forward<RequestCb>(on_done),
std::forward<RequestExpiredCb>(on_expired));
}
/**
* Send a "find node" request to a given node.
*
@@ -361,9 +344,10 @@ public:
const InfoHash& hash,
const Query& query,
const Blob& token,
Tid socketId,
Sp<Request> previous,
RequestCb&& on_done,
RequestExpiredCb&& on_expired);
RequestExpiredCb&& on_expired,
SocketCb&& socket_cb);
/**
* Send a "announce" request to a given node.
*
@@ -402,26 +386,7 @@ public:
const Value::Id& vid,
const Blob& token,
RequestCb&& on_done,
RequestErrorCb&& on_error,
RequestExpiredCb&& on_expired);
/**
* Send a "update" request to a given node. Used for Listen operations
*
* @param n The node.
* @param hash The target hash.
* @param values The values.
* @param created Time id.
* @param token A security token.
* @param sid The socket id.
*
* @return the request with information concerning its success.
*/
Sp<Request> sendUpdateValues(Sp<Node> n,
const InfoHash& infohash,
const std::vector<Sp<Value>>& values,
time_point created,
const Blob& token,
const size_t& sid);
/**
* Parses a message and calls appropriate callbacks.
@@ -434,8 +399,8 @@ public:
*/
void processMessage(const uint8_t *buf, size_t buflen, SockAddr addr);
Sp<Node> insertNode(const InfoHash& id, const SockAddr& addr) {
auto n = cache.getNode(id, addr, scheduler.time(), 0);
Sp<Node> insertNode(const InfoHash& myid, const SockAddr& addr) {
auto n = cache.getNode(myid, addr, scheduler.time(), 0);
onNewNode(n, 0);
return n;
}
@@ -453,21 +418,6 @@ public:
return cache.getCachedNodes(id, sa_f, count);
}
size_t getNodeCacheSize() const {
return cache.size();
}
size_t getNodeCacheSize(sa_family_t af) const {
return cache.size(af);
}
size_t getRateLimiterSize() const {
return address_rate_limiter.size();
}
size_t getPartialCount() const {
return partial_messages.size();
}
private:
struct PartialMessage;
@@ -475,6 +425,7 @@ private:
/***************
* Constants *
***************/
static constexpr size_t MAX_REQUESTS_PER_SEC {1600};
/* the length of a node info buffer in ipv4 format */
static const constexpr size_t NODE4_INFO_BUF_LEN {HASH_LEN + sizeof(in_addr) + sizeof(in_port_t)};
/* the length of a node info buffer in ipv6 format */
@@ -511,20 +462,19 @@ private:
void sendRequest(const Sp<Request>& request);
struct MessageStats {
unsigned ping {0};
unsigned find {0};
unsigned get {0};
unsigned put {0};
unsigned listen {0};
unsigned refresh {0};
unsigned updateValue {0};
unsigned ping {0};
unsigned find {0};
unsigned get {0};
unsigned put {0};
unsigned listen {0};
unsigned refresh {0};
};
// basic wrapper for socket sendto function
int send(const SockAddr& addr, const char *buf, size_t len, bool confirmed = false);
void sendValueParts(Tid tid, const std::vector<Blob>& svals, const SockAddr& addr);
void sendValueParts(const TransId& tid, const std::vector<Blob>& svals, const SockAddr& addr);
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<Sp<Value>>&);
void maintainRxBuffer(Tid tid);
@@ -563,19 +513,18 @@ private:
/* DHT info */
const InfoHash& myid;
const NetworkConfig config {};
const NetId network {0};
const std::unique_ptr<DatagramSocket> dht_socket;
Sp<Logger> logger_;
std::mt19937_64& rd;
const Logger& DHT_LOG;
NodeCache cache;
NodeCache cache {};
// global limiting should be triggered by at least 8 different IPs
using IpLimiter = RateLimiter;
using IpLimiter = RateLimiter<MAX_REQUESTS_PER_SEC/8>;
using IpLimiterMap = std::map<SockAddr, IpLimiter, SockAddr::ipCmp>;
IpLimiterMap address_rate_limiter;
RateLimiter rate_limiter;
ssize_t limiter_maintenance {0};
IpLimiterMap address_rate_limiter {};
RateLimiter<MAX_REQUESTS_PER_SEC> rate_limiter {};
size_t limiter_maintenance {0};
// requests handling
std::map<Tid, Sp<Request>> requests {};
+14 -58
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -35,15 +35,12 @@
#include <functional>
#include <thread>
#include <atomic>
#include <mutex>
#include <list>
#include <iostream>
namespace dht {
namespace net {
static const constexpr in_port_t DHT_DEFAULT_PORT = 4222;
static const constexpr size_t RX_QUEUE_MAX_SIZE = 1024 * 16;
static const constexpr std::chrono::milliseconds RX_QUEUE_MAX_DELAY(650);
int bindSocket(const SockAddr& addr, SockAddr& bound);
@@ -57,96 +54,55 @@ struct ReceivedPacket {
SockAddr from;
time_point received;
};
using PacketList = std::list<ReceivedPacket>;
class OPENDHT_PUBLIC DatagramSocket {
public:
/** A function that takes a list of new received packets and
* optionally returns consumed packets for recycling.
**/
using OnReceive = std::function<PacketList(PacketList&& packets)>;
using OnReceive = std::function<void(std::unique_ptr<ReceivedPacket>&& packet)>;
virtual ~DatagramSocket() {};
virtual int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) = 0;
inline void setOnReceive(OnReceive&& cb) {
std::lock_guard<std::mutex> lk(lock);
rx_callback = std::move(cb);
}
virtual const SockAddr& getBound(sa_family_t family = AF_UNSPEC) const = 0;
virtual bool hasIPv4() const = 0;
virtual bool hasIPv6() const = 0;
SockAddr getBound(sa_family_t family = AF_UNSPEC) const {
std::lock_guard<std::mutex> lk(lock);
return getBoundRef(family);
}
in_port_t getPort(sa_family_t family = AF_UNSPEC) const {
std::lock_guard<std::mutex> lk(lock);
return getBoundRef(family).getPort();
}
virtual const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const = 0;
/** Virtual resolver mothod allows to implement custom resolver */
virtual std::vector<SockAddr> resolve(const std::string& host, const std::string& service = {}) {
return SockAddr::resolve(host, service);
return getBound(family).getPort();
}
virtual void stop() = 0;
protected:
PacketList getNewPacket() {
PacketList pkts;
if (toRecycle_.empty()) {
pkts.emplace_back();
} else {
auto begIt = toRecycle_.begin();
auto begItNext = std::next(begIt);
pkts.splice(pkts.end(), toRecycle_, begIt, begItNext);
}
return pkts;
inline void onReceived(std::unique_ptr<ReceivedPacket>&& packet) {
if (rx_callback)
rx_callback(std::move(packet));
}
inline void onReceived(PacketList&& packets) {
std::lock_guard<std::mutex> lk(lock);
if (rx_callback) {
auto r = rx_callback(std::move(packets));
if (not r.empty() and toRecycle_.size() < RX_QUEUE_MAX_SIZE)
toRecycle_.splice(toRecycle_.end(), std::move(r));
}
}
protected:
mutable std::mutex lock;
private:
OnReceive rx_callback;
PacketList toRecycle_;
};
class OPENDHT_PUBLIC UdpSocket : public DatagramSocket {
public:
UdpSocket(in_port_t port, const std::shared_ptr<Logger>& l = {});
UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const std::shared_ptr<Logger>& l = {});
UdpSocket(in_port_t port, const Logger& l = {});
UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const Logger& l = {});
~UdpSocket();
int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) override;
const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const override {
const SockAddr& getBound(sa_family_t family = AF_UNSPEC) const override {
return (family == AF_INET6) ? bound6 : bound4;
}
bool hasIPv4() const override {
std::lock_guard<std::mutex> lk(lock);
return s4 != -1;
}
bool hasIPv6() const override {
std::lock_guard<std::mutex> lk(lock);
return s6 != -1;
}
bool hasIPv4() const override { return s4 != -1; }
bool hasIPv6() const override { return s6 != -1; }
void stop() override;
private:
std::shared_ptr<Logger> logger;
Logger logger;
int s4 {-1};
int s6 {-1};
int stopfd {-1};
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
@@ -47,10 +47,10 @@ struct Socket {
struct Node {
const InfoHash id;
Node(const InfoHash& id, const SockAddr& addr, std::mt19937_64& rd, bool client=false);
Node(const InfoHash& id, SockAddr&& addr, std::mt19937_64& rd, bool client=false);
Node(const InfoHash& id, const sockaddr* sa, socklen_t salen, std::mt19937_64& rd)
: Node(id, SockAddr(sa, salen), rd) {}
Node(const InfoHash& id, const SockAddr& addr, bool client=false);
Node(const InfoHash& id, SockAddr&& addr, bool client=false);
Node(const InfoHash& id, const sockaddr* sa, socklen_t salen)
: Node(id, SockAddr(sa, salen)) {}
InfoHash getId() const {
return id;
+2 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -26,13 +26,6 @@
namespace dht {
struct NodeCache {
size_t size(sa_family_t family) const {
return cache(family).count();
}
size_t size() const {
return size(AF_INET) + size(AF_INET6);
}
Sp<Node> getNode(const InfoHash& id, sa_family_t family);
Sp<Node> getNode(const InfoHash& id, const SockAddr&, time_point now, bool confirmed, bool client=false);
std::vector<Sp<Node>> getCachedNodes(const InfoHash& id, sa_family_t sa_f, size_t count) const;
@@ -44,19 +37,17 @@ struct NodeCache {
*/
void clearBadNodes(sa_family_t family = 0);
NodeCache(std::mt19937_64& r) : rd(r) {};
~NodeCache();
private:
class NodeMap : private std::map<InfoHash, std::weak_ptr<Node>> {
public:
Sp<Node> getNode(const InfoHash& id);
Sp<Node> getNode(const InfoHash& id, const SockAddr&, time_point now, bool confirmed, bool client, std::mt19937_64& rd);
Sp<Node> getNode(const InfoHash& id, const SockAddr&, time_point now, bool confirmed, bool client);
std::vector<Sp<Node>> getCachedNodes(const InfoHash& id, size_t count) const;
void clearBadNodes();
void setExpired();
void cleanup();
size_t count() const { return size(); }
private:
size_t cleanup_counter {0};
};
@@ -65,7 +56,6 @@ private:
NodeMap& cache(sa_family_t af) { return af == AF_INET ? cache_4 : cache_6; }
NodeMap cache_4;
NodeMap cache_6;
std::mt19937_64& rd;
};
}
+14 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
*
@@ -22,13 +22,10 @@
#include "def.h"
#include "sockaddr.h"
#include "infohash.h"
#include "log_enable.h"
#include <thread>
namespace asio {
class io_context;
}
#include <mutex>
#include <condition_variable>
namespace dht {
@@ -38,7 +35,7 @@ public:
static constexpr in_port_t DEFAULT_PORT = 8888;
using ServiceDiscoveredCallback = std::function<void(msgpack::object&&, SockAddr&&)>;
PeerDiscovery(in_port_t port = DEFAULT_PORT, std::shared_ptr<asio::io_context> ioContext = {}, std::shared_ptr<Logger> logger = {});
PeerDiscovery(in_port_t port = DEFAULT_PORT);
~PeerDiscovery();
/**
@@ -54,7 +51,7 @@ public:
}
/**
* startPublish - Keeping sending data until node is joinned or stop is called
* startPublish - Keeping sending data until node is joinned or stop is called - msgpack
*/
void startPublish(const std::string &type, const msgpack::sbuffer &pack_buf);
void startPublish(sa_family_t domain, const std::string &type, const msgpack::sbuffer &pack_buf);
@@ -82,14 +79,20 @@ public:
bool stopPublish(const std::string &type);
bool stopPublish(sa_family_t domain, const std::string &type);
void connectivityChanged();
/**
* Configure the sockopt to be able to listen multicast group
*/
static void joinMulticast(int sockfd, sa_family_t family);
/**
* Join the threads
*/
void join();
private:
class DomainPeerDiscovery;
std::unique_ptr<DomainPeerDiscovery> peerDiscovery4_;
std::unique_ptr<DomainPeerDiscovery> peerDiscovery6_;
std::shared_ptr<asio::io_context> ioContext_;
std::thread ioRunnner_;
};
}
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -22,8 +22,8 @@
namespace dht {
namespace proxy {
constexpr const std::chrono::hours OP_TIMEOUT {24}; // one day
constexpr const std::chrono::hours OP_MARGIN {2}; // two hours
constexpr const std::chrono::seconds OP_TIMEOUT {1 * 60 * 60}; // one hour
constexpr const std::chrono::seconds OP_MARGIN {5 * 60}; // 5 minutes
constexpr const char* const HTTP_PROTO {"http://"};
using ListenToken = uint64_t;
+4 -10
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2017-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -23,23 +23,19 @@
namespace dht {
template<size_t Quota, unsigned long Period=1>
class RateLimiter {
public:
RateLimiter(size_t quota, const duration& period = std::chrono::seconds(1))
: quota_(quota), period_(period) {}
/** Clear outdated records and return current quota usage */
size_t maintain(const time_point& now) {
auto limit = now - period_;
auto limit = now - std::chrono::seconds(Period);
while (not records.empty() and records.front() < limit)
records.pop();
return records.size();
}
/** Return false if quota is reached, insert record and return true otherwise. */
bool limit(const time_point& now) {
if (quota_ == std::numeric_limits<size_t>::max())
return true;
if (maintain(now) >= quota_)
if (maintain(now) >= Quota)
return false;
records.emplace(now);
return true;
@@ -48,8 +44,6 @@ public:
return records.empty();
}
private:
const size_t quota_;
const duration period_;
std::queue<time_point> records {};
};
+6 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -21,8 +21,6 @@
#include <random>
#include <algorithm>
#include <functional>
#include <thread>
#include <stdexcept>
namespace dht {
namespace crypto {
@@ -113,18 +111,11 @@ using random_device = std::random_device;
template<class T = std::mt19937, std::size_t N = T::state_size>
auto getSeededRandomEngine () -> typename std::enable_if<!!N, T>::type {
typename T::result_type random_data[N];
for (unsigned i=0; i<256; i++) {
try {
random_device source;
std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
std::seed_seq seeds(std::begin(random_data), std::end(random_data));
T seededEngine (seeds);
return seededEngine;
} catch (...) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
throw std::runtime_error("Can't seed random engine");
random_device source;
std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
std::seed_seq seeds(std::begin(random_data), std::end(random_data));
T seededEngine (seeds);
return seededEngine;
}
}} // dht::crypto
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
@@ -39,7 +39,7 @@ struct Bucket {
Sp<Node> cached; /* the address of a likely candidate */
/** Return a random node in a bucket. */
Sp<Node> randomNode(std::mt19937_64& rd);
Sp<Node> randomNode();
void sendCachedPing(net::NetworkEngine& ne);
void connectivityChanged() {
@@ -89,7 +89,7 @@ public:
/**
* Return a random id in the bucket's range.
*/
InfoHash randomId(const RoutingTable::const_iterator& bucket, std::mt19937_64& rd) const;
InfoHash randomId(const RoutingTable::const_iterator& bucket) const;
unsigned depth(const RoutingTable::const_iterator& bucket) const;
+12 -21
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
@@ -36,9 +36,8 @@ namespace dht {
class Scheduler {
public:
struct Job {
Job(std::function<void()>&& f, time_point t) : do_(std::move(f)), t_(t) {}
Job(std::function<void()>&& f) : do_(std::move(f)) {}
std::function<void()> do_;
const time_point t_;
void cancel() { do_ = {}; }
};
@@ -51,12 +50,17 @@ public:
* @return pointer to the newly scheduled job.
*/
Sp<Scheduler::Job> add(time_point t, std::function<void()>&& job_func) {
auto job = std::make_shared<Job>(std::move(job_func), t);
auto job = std::make_shared<Job>(std::move(job_func));
if (t != time_point::max())
timers.emplace(std::move(t), job);
return job;
}
void add(const Sp<Scheduler::Job>& job, time_point t) {
if (t != time_point::max())
timers.emplace(std::move(t), job);
}
/**
* Reschedules a job.
*
@@ -64,35 +68,23 @@ public:
* @param t The time at which the job shall be rescheduled.
*/
void edit(Sp<Scheduler::Job>& job, time_point t) {
if (not job)
if (not job) {
return;
}
// std::function move doesn't garantee to leave the object empty.
// Force clearing old value.
auto task = std::move(job->do_);
cancel(job);
job->do_ = {};
job = add(t, std::move(task));
}
bool cancel(Sp<Scheduler::Job>& job) {
if (job) {
job->cancel();
for (auto r = timers.equal_range(job->t_); r.first != r.second; ++r.first) {
if (r.first->second == job) {
timers.erase(r.first);
job.reset();
return true;
}
}
}
return false;
}
/**
* Runs the jobs to do up to now.
*
* @return The time for the next job to run.
*/
time_point run() {
syncTime();
while (not timers.empty()) {
auto timer = timers.begin();
/*
@@ -122,7 +114,6 @@ public:
*/
inline const time_point& time() const { return now; }
inline time_point syncTime() { return (now = clock::now()); }
inline void syncTime(const time_point& n) { now = n; }
private:
time_point now {clock::now()};
+16 -36
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
@@ -45,13 +45,15 @@ public:
return c;
}
SecureDht() {}
/**
* s, s6: bound socket descriptors for IPv4 and IPv6, respectively.
* For the Dht to be initialised, at least one of them must be >= 0.
* id: the identity to use for the crypto layer and to compute
* our own hash on the Dht.
*/
SecureDht(std::unique_ptr<DhtInterface> dht, Config config, IdentityAnnouncedCb iacb = {}, const std::shared_ptr<Logger>& l = {});
SecureDht(std::unique_ptr<DhtInterface> dht, Config config);
virtual ~SecureDht();
@@ -61,9 +63,6 @@ public:
PkId getLongId() const {
return key_ ? key_->getPublicKey().getLongId() : PkId();
}
Sp<crypto::PublicKey> getPublicKey() const {
return key_ ? key_->getSharedPublicKey() : Sp<crypto::PublicKey>{};
}
ValueType secureType(ValueType&& type);
@@ -118,10 +117,6 @@ public:
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
/**
* Take ownership of the value and sign it using our private key.
@@ -133,13 +128,13 @@ public:
Value decrypt(const Value& v);
void findCertificate(const InfoHash& node, const std::function<void(const Sp<crypto::Certificate>)>& cb);
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<crypto::PublicKey>)>& cb);
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<const crypto::PublicKey>)>& cb);
Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
const Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
void registerCertificate(Sp<crypto::Certificate>& cert);
Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
Sp<crypto::PublicKey> getPublicKey(const InfoHash& node) const;
const Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
const Sp<const crypto::PublicKey> getPublicKey(const InfoHash& node) const;
/**
* Allows to set a custom callback called by the library to find a locally-stored certificate.
@@ -153,8 +148,8 @@ public:
/**
* SecureDht to Dht proxy
*/
void shutdown(ShutdownCallback cb, bool stop = false) override {
dht_->shutdown(cb, stop);
void shutdown(ShutdownCallback cb) override {
dht_->shutdown(cb);
}
void dumpTables() const override {
dht_->dumpTables();
@@ -200,14 +195,11 @@ public:
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) override {
return dht_->getPublicAddress(family);
}
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr sa, const time_point& now) override {
return dht_->periodic(buf, buflen, std::move(sa), now);
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr sa) override {
return dht_->periodic(buf, buflen, std::move(sa));
}
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen, const time_point& now) override {
return dht_->periodic(buf, buflen, from, fromlen, now);
}
NodeStatus updateStatus(sa_family_t af) override {
return dht_->updateStatus(af);
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
return dht_->periodic(buf, buflen, from, fromlen);
}
NodeStatus getStatus(sa_family_t af) const override {
return dht_->getStatus(af);
@@ -224,12 +216,6 @@ public:
const ValueType& getType(ValueType::Id type_id) const override {
return dht_->getType(type_id);
}
void addBootstrap(const std::string& host, const std::string& service) override {
dht_->addBootstrap(host, service);
}
void clearBootstrap() override {
dht_->clearBootstrap();
}
void insertNode(const InfoHash& id, const SockAddr& sa) override {
dht_->insertNode(id, sa);
}
@@ -330,16 +316,11 @@ public:
dht_->setLogger(logger);
}
void setLogger(const std::shared_ptr<Logger>& logger) override {
DhtInterface::setLogger(logger);
dht_->setLogger(logger);
}
/**
* Only print logs related to the given InfoHash (if given), or disable filter (if zeroes).
*/
void setLogFilter(const InfoHash& f) override {
DhtInterface::setLogFilter(f);
DHT_LOG.setFilter(f);
dht_->setLogFilter(f);
}
@@ -361,10 +342,9 @@ private:
// our certificate cache
std::map<InfoHash, Sp<crypto::Certificate>> nodesCertificates_ {};
std::map<InfoHash, Sp<crypto::PublicKey>> nodesPubKeys_ {};
std::map<InfoHash, Sp<const crypto::PublicKey>> nodesPubKeys_ {};
std::atomic_bool forward_all_ {false};
bool enableCache_ {false};
};
const ValueType CERTIFICATE_TYPE = {
+7 -7
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -68,7 +68,7 @@ public:
* Build from existing address.
*/
SockAddr(const sockaddr* sa, socklen_t length) {
if (length > static_cast<socklen_t>(sizeof(sockaddr_storage)))
if (length > sizeof(sockaddr_storage))
throw std::runtime_error("Socket address length is too large");
set(sa, length);
}
@@ -144,7 +144,7 @@ public:
if (len) addr.reset((sockaddr*)::calloc(len, 1));
else addr.reset();
}
if (len)
if (len > sizeof(sa_family_t))
addr->sa_family = af;
}
@@ -223,16 +223,16 @@ public:
*/
sockaddr* get() { return addr.get(); }
inline const sockaddr_in& getIPv4() const {
const sockaddr_in& getIPv4() const {
return *reinterpret_cast<const sockaddr_in*>(get());
}
inline const sockaddr_in6& getIPv6() const {
const sockaddr_in6& getIPv6() const {
return *reinterpret_cast<const sockaddr_in6*>(get());
}
inline sockaddr_in& getIPv4() {
sockaddr_in& getIPv4() {
return *reinterpret_cast<sockaddr_in*>(get());
}
inline sockaddr_in6& getIPv6() {
sockaddr_in6& getIPv6() {
return *reinterpret_cast<sockaddr_in6*>(get());
}
+9 -83
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
@@ -27,8 +27,6 @@
#include <future>
#include <functional>
#include <ciso646> // fix windows compiler bug
namespace dht {
class OPENDHT_PUBLIC ThreadPool {
@@ -45,15 +43,9 @@ public:
template<class T>
std::future<T> get(std::function<T()>&& cb) {
auto ret = std::make_shared<std::promise<T>>();
run([cb = std::move(cb), ret]() mutable {
try {
ret->set_value(cb());
} catch (...) {
try {
ret->set_exception(std::current_exception());
} catch(...) {}
}
});
run(std::bind([=](std::function<T()>& mcb) mutable {
ret->set_value(mcb());
}, std::move(cb)));
return ret->get_future();
}
template<class T>
@@ -65,14 +57,15 @@ public:
void join();
private:
struct ThreadState;
std::queue<std::function<void()>> tasks_ {};
std::vector<std::unique_ptr<ThreadState>> threads_;
unsigned readyThreads_ {0};
std::mutex lock_ {};
std::condition_variable cv_ {};
std::queue<std::function<void()>> tasks_ {};
std::vector<std::unique_ptr<std::thread>> threads_;
unsigned readyThreads_ {0};
bool running_ {true};
const unsigned maxThreads_;
bool running_ {true};
};
class OPENDHT_PUBLIC Executor : public std::enable_shared_from_this<Executor> {
@@ -94,71 +87,4 @@ private:
void schedule();
};
class OPENDHT_PUBLIC ExecutionContext {
public:
ExecutionContext(ThreadPool& pool)
: threadPool_(pool), state_(std::make_shared<SharedState>())
{}
~ExecutionContext() {
state_->destroy();
}
/** Wait for ongoing tasks to complete execution and drop other pending tasks */
void stop() {
state_->destroy(false);
}
void run(std::function<void()>&& task) {
std::lock_guard<std::mutex> lock(state_->mtx);
if (state_->shutdown_) return;
state_->pendingTasks++;
threadPool_.get().run([task = std::move(task), state = state_] {
state->run(task);
});
}
private:
struct SharedState {
std::mutex mtx {};
std::condition_variable cv {};
unsigned pendingTasks {0};
unsigned ongoingTasks {0};
/** When true, prevents new tasks to be scheduled */
bool shutdown_ {false};
/** When true, prevents scheduled tasks to be executed */
std::atomic_bool destroyed {false};
void destroy(bool wait = true) {
std::unique_lock<std::mutex> lock(mtx);
if (destroyed) return;
if (wait) {
cv.wait(lock, [this] { return pendingTasks == 0 && ongoingTasks == 0; });
}
shutdown_ = true;
if (not wait) {
cv.wait(lock, [this] { return ongoingTasks == 0; });
}
destroyed = true;
}
void run(const std::function<void()>& task) {
{
std::lock_guard<std::mutex> lock(mtx);
pendingTasks--;
ongoingTasks++;
}
if (destroyed) return;
task();
{
std::lock_guard<std::mutex> lock(mtx);
ongoingTasks--;
cv.notify_all();
}
}
};
std::reference_wrapper<ThreadPool> threadPool_;
std::shared_ptr<SharedState> state_;
};
}
+10 -37
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -77,20 +77,12 @@ public:
// Time related definitions and utility functions
using clock = std::chrono::steady_clock;
using system_clock = std::chrono::system_clock;
using time_point = clock::time_point;
using duration = clock::duration;
time_point from_time_t(std::time_t t);
std::time_t to_time_t(time_point t);
inline std::string
to_str(double d) {
char buf[16];
auto ret = snprintf(buf, sizeof(buf), "%.3g", d);
return (ret < 0) ? std::to_string(d) : std::string(buf, ret);
}
/**
* Converts std::chrono::duration to floating-point seconds.
*/
@@ -105,26 +97,14 @@ static std::string
print_duration(DT d) {
if (d < std::chrono::seconds(0)) {
return "-" + print_duration(-d);
} else if (d < std::chrono::milliseconds(1)) {
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count()) + " us";
} else if (d < std::chrono::seconds(1)) {
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count()) + " ms";
} else if (d < std::chrono::minutes(1)) {
return to_str(std::chrono::duration_cast<std::chrono::duration<double>>(d).count()) + " s";
} else if (d < std::chrono::hours(1)) {
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::ratio<60>>>(d).count()) + " min";
} else {
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::ratio<3600>>>(d).count()) + " h";
}
}
template <class TimePoint>
static std::string
print_time_relative(TimePoint now, TimePoint d) {
if (d == TimePoint::min()) return "never";
if (d == now) return "now";
return (d > now) ? std::string("in ") + print_duration(d - now)
: print_duration(now - d) + std::string(" ago");
if (d < std::chrono::milliseconds(1)) {
return std::to_string(std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count()) + " us";
} else if (d < std::chrono::seconds(1)) {
return std::to_string(std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count()) + " ms";
} else {
return std::to_string(print_dt(d)) + " s";
}
}
template <typename Duration = duration>
@@ -153,7 +133,7 @@ using Blob = std::vector<uint8_t>;
/**
* Provides backward compatibility with msgpack 1.0
*/
OPENDHT_PUBLIC Blob unpackBlob(const msgpack::object& o);
OPENDHT_PUBLIC Blob unpackBlob(msgpack::object& o);
template <typename Type>
Blob
@@ -173,13 +153,6 @@ unpackMsg(Blob b) {
msgpack::unpacked unpackMsg(Blob b);
msgpack::object* findMapValue(const msgpack::object& map, const char* key, size_t length);
inline msgpack::object* findMapValue(const msgpack::object& map, const char* key) {
return findMapValue(map, key, strlen(key));
}
inline msgpack::object* findMapValue(const msgpack::object& map, std::string_view key) {
return findMapValue(map, key.data(), key.size());
}
msgpack::object* findMapValue(msgpack::object& map, const std::string& key);
} // namespace dht
+46 -84
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
*
@@ -27,7 +27,6 @@
#include <msgpack.hpp>
#include <string>
#include <string_view>
#include <sstream>
#include <bitset>
#include <vector>
@@ -43,20 +42,6 @@
#endif
namespace dht {
using namespace std::literals;
static constexpr auto VALUE_KEY_ID("id");
static const std::string VALUE_KEY_DAT("dat");
static const std::string VALUE_KEY_PRIO("p");
static const std::string VALUE_KEY_SIGNATURE("sig");
static const std::string VALUE_KEY_SEQ("seq");
static const std::string VALUE_KEY_DATA("data");
static const std::string VALUE_KEY_OWNER("owner");
static const std::string VALUE_KEY_TYPE("type");
static const std::string VALUE_KEY_TO("to");
static const std::string VALUE_KEY_BODY("body");
static const std::string VALUE_KEY_USERTYPE("utype");
struct Value;
struct Query;
@@ -119,7 +104,7 @@ struct OPENDHT_PUBLIC ValueType {
Id id {0};
std::string name {};
duration expiration {std::chrono::minutes(10)};
duration expiration {60 * 10};
StorePolicy storePolicy {DEFAULT_STORE_POLICY};
EditPolicy editPolicy {DEFAULT_EDIT_POLICY};
};
@@ -182,7 +167,7 @@ struct OPENDHT_PUBLIC Value
static Filter chain(Filter&& f1, Filter&& f2) {
if (not f1) return std::move(f2);
if (not f2) return std::move(f1);
return [f1 = std::move(f1), f2 = std::move(f2)](const Value& v) {
return [f1,f2](const Value& v) {
return f1(v) and f2(v);
};
}
@@ -195,19 +180,19 @@ struct OPENDHT_PUBLIC Value
}
static Filter chainAll(std::vector<Filter>&& set) {
if (set.empty()) return {};
return [set = std::move(set)](const Value& v) {
for (const auto& f : set)
return std::bind([](const Value& v, std::vector<Filter>& s) {
for (const auto& f : s)
if (f and not f(v))
return false;
return true;
};
}, std::placeholders::_1, std::move(set));
}
static Filter chain(std::initializer_list<Filter> l) {
return chainAll(std::vector<Filter>(l.begin(), l.end()));
}
static Filter chainOr(Filter&& f1, Filter&& f2) {
if (not f1 or not f2) return {};
return [f1=std::move(f1),f2=std::move(f2)](const Value& v) {
return [f1,f2](const Value& v) {
return f1(v) or f2(v);
};
}
@@ -233,7 +218,8 @@ struct OPENDHT_PUBLIC Value
}
static Filter TypeFilter(const ValueType& t) {
return [tid = t.id](const Value& v) {
const auto tid = t.id;
return [tid](const Value& v) {
return v.type == tid;
};
}
@@ -271,8 +257,8 @@ struct OPENDHT_PUBLIC Value
};
}
static Filter UserTypeFilter(std::string ut) {
return [ut = std::move(ut)](const Value& v) {
static Filter UserTypeFilter(const std::string& ut) {
return [ut](const Value& v) {
return v.user_type == ut;
};
}
@@ -358,7 +344,7 @@ struct OPENDHT_PUBLIC Value
void sign(const crypto::PrivateKey& key) {
if (isEncrypted())
throw DhtException("Can't sign encrypted data.");
owner = key.getSharedPublicKey();
owner = std::make_shared<const crypto::PublicKey>(key.getPublicKey());
signature = key.sign(getToSign());
}
@@ -370,8 +356,8 @@ struct OPENDHT_PUBLIC Value
return isSigned() and owner->checkSignature(getToSign(), signature);
}
std::shared_ptr<crypto::PublicKey> getOwner() const {
return std::static_pointer_cast<crypto::PublicKey>(owner);
std::shared_ptr<const crypto::PublicKey> getOwner() const {
return std::static_pointer_cast<const crypto::PublicKey>(owner);
}
/**
@@ -404,7 +390,7 @@ struct OPENDHT_PUBLIC Value
* Build a value from a json object
* @param json
*/
Value(const Json::Value& json);
Value(Json::Value& json);
#endif
template <typename Type>
@@ -422,9 +408,7 @@ struct OPENDHT_PUBLIC Value
Value(Value&& o) noexcept
: id(o.id), owner(std::move(o.owner)), recipient(o.recipient),
type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq)
, signature(std::move(o.signature)), cypher(std::move(o.cypher))
, priority(o.priority) {}
type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq), signature(std::move(o.signature)), cypher(std::move(o.cypher)) {}
template <typename Type>
Value(const Type& vs)
@@ -437,20 +421,10 @@ struct OPENDHT_PUBLIC Value
msgpack_unpack(o);
}
/**
* Returns true if value contents are equals (not considering the value ID)
*/
inline bool contentEquals(const Value& o) {
return isEncrypted() ? cypher == o.cypher :
((owner == o.owner || (owner and o.owner and *owner == *o.owner))
&& type == o.type
&& data == o.data
&& user_type == o.user_type
&& signature == o.signature);
}
inline bool operator== (const Value& o) {
return id == o.id and contentEquals(o);
return id == o.id &&
(isEncrypted() ? cypher == o.cypher :
((owner == o.owner || *owner == *o.owner) && type == o.type && data == o.data && user_type == o.user_type && signature == o.signature));
}
void setRecipient(const InfoHash& r) {
@@ -511,17 +485,17 @@ struct OPENDHT_PUBLIC Value
bool has_owner = owner && *owner;
pk.pack_map((user_type.empty()?0:1) + (has_owner?(recipient ? 5 : 4):2));
if (has_owner) { // isSigned
pk.pack(VALUE_KEY_SEQ); pk.pack(seq);
pk.pack(VALUE_KEY_OWNER); owner->msgpack_pack(pk);
pk.pack(std::string("seq")); pk.pack(seq);
pk.pack(std::string("owner")); owner->msgpack_pack(pk);
if (recipient) {
pk.pack(VALUE_KEY_TO); pk.pack(recipient);
pk.pack(std::string("to")); pk.pack(recipient);
}
}
pk.pack(VALUE_KEY_TYPE); pk.pack(type);
pk.pack(VALUE_KEY_DATA); pk.pack_bin(data.size());
pk.pack_bin_body((const char*)data.data(), data.size());
pk.pack(std::string("type")); pk.pack(type);
pk.pack(std::string("data")); pk.pack_bin(data.size());
pk.pack_bin_body((const char*)data.data(), data.size());
if (not user_type.empty()) {
pk.pack(VALUE_KEY_USERTYPE); pk.pack(user_type);
pk.pack(std::string("utype")); pk.pack(user_type);
}
}
@@ -533,10 +507,10 @@ struct OPENDHT_PUBLIC Value
pk.pack_bin_body((const char*)cypher.data(), cypher.size());
} else {
pk.pack_map(isSigned() ? 2 : 1);
pk.pack(VALUE_KEY_BODY); msgpack_pack_to_sign(pk);
pk.pack(std::string("body")); msgpack_pack_to_sign(pk);
if (isSigned()) {
pk.pack(VALUE_KEY_SIGNATURE); pk.pack_bin(signature.size());
pk.pack_bin_body((const char*)signature.data(), signature.size());
pk.pack(std::string("sig")); pk.pack_bin(signature.size());
pk.pack_bin_body((const char*)signature.data(), signature.size());
}
}
}
@@ -544,12 +518,9 @@ struct OPENDHT_PUBLIC Value
template <typename Packer>
void msgpack_pack(Packer& pk) const
{
pk.pack_map(2 + (priority?1:0));
pk.pack(VALUE_KEY_ID); pk.pack(id);
pk.pack(VALUE_KEY_DAT); msgpack_pack_to_encrypt(pk);
if (priority) {
pk.pack(VALUE_KEY_PRIO); pk.pack(priority);
}
pk.pack_map(2);
pk.pack(std::string("id")); pk.pack(id);
pk.pack(std::string("dat")); msgpack_pack_to_encrypt(pk);
}
template <typename Packer>
@@ -580,7 +551,7 @@ struct OPENDHT_PUBLIC Value
}
}
void msgpack_unpack(const msgpack::object& o);
void msgpack_unpack(msgpack::object o);
void msgpack_unpack_body(const msgpack::object& o);
Blob getPacked() const {
msgpack::sbuffer buffer;
@@ -596,7 +567,7 @@ struct OPENDHT_PUBLIC Value
/**
* Public key of the signer.
*/
std::shared_ptr<crypto::PublicKey> owner {};
std::shared_ptr<const crypto::PublicKey> owner {};
/**
* Hash of the recipient (optional).
@@ -631,13 +602,6 @@ struct OPENDHT_PUBLIC Value
*/
Blob cypher {};
/**
* Priority of this value (used for push notifications)
* 0 = high priority
* 1 = normal priority
*/
unsigned priority {0};
private:
friend class SecureDht;
/* Cache for crypto ops */
@@ -661,7 +625,7 @@ struct OPENDHT_PUBLIC FieldValue
FieldValue() {}
FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
FieldValue(Value::Field f, InfoHash hash_value) : field(f), hashValue(hash_value) {}
FieldValue(Value::Field f, Blob blob_value) : field(f), blobValue(std::move(blob_value)) {}
FieldValue(Value::Field f, Blob blob_value) : field(f), blobValue(blob_value) {}
bool operator==(const FieldValue& fd) const;
@@ -674,9 +638,9 @@ struct OPENDHT_PUBLIC FieldValue
template <typename Packer>
void msgpack_pack(Packer& p) const {
p.pack_map(2);
p.pack("f"sv); p.pack(static_cast<uint8_t>(field));
p.pack(std::string("f")); p.pack(static_cast<uint8_t>(field));
p.pack("v"sv);
p.pack(std::string("v"));
switch (field) {
case Value::Field::Id:
case Value::Field::ValueType:
@@ -694,16 +658,16 @@ struct OPENDHT_PUBLIC FieldValue
}
}
void msgpack_unpack(const msgpack::object& msg) {
void msgpack_unpack(msgpack::object msg) {
hashValue = {};
blobValue.clear();
if (auto f = findMapValue(msg, "f"sv))
if (auto f = findMapValue(msg, "f"))
field = (Value::Field)f->as<unsigned>();
else
throw msgpack::type_error();
auto v = findMapValue(msg, "v"sv);
auto v = findMapValue(msg, "v");
if (not v)
throw msgpack::type_error();
else
@@ -743,7 +707,7 @@ private:
struct OPENDHT_PUBLIC Select
{
Select() { }
Select(std::string_view q_str);
Select(const std::string& q_str);
bool isSatisfiedBy(const Select& os) const;
@@ -781,8 +745,6 @@ struct OPENDHT_PUBLIC Select
return ss.str();
}
bool empty() const { return fieldSelection_.empty(); }
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Select& q);
private:
std::vector<Value::Field> fieldSelection_ {};
@@ -798,7 +760,7 @@ private:
struct OPENDHT_PUBLIC Where
{
Where() { }
Where(std::string_view q_str);
Where(const std::string& q_str);
bool isSatisfiedBy(const Where& where) const;
@@ -865,7 +827,7 @@ struct OPENDHT_PUBLIC Where
*
* @return the resulting Where instance.
*/
Where& userType(std::string_view user_type) {
Where& userType(std::string user_type) {
FieldValue fv {Value::Field::UserType, Blob {user_type.begin(), user_type.end()}};
if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
filters_.emplace_back(std::move(fv));
@@ -938,11 +900,11 @@ struct OPENDHT_PUBLIC Query
* - $string$: a simple string WITHOUT SPACES.
* - $integer$: a simple integer.
*/
Query(std::string_view q_str) {
Query(std::string q_str) {
auto pos_W = q_str.find("WHERE");
auto pos_w = q_str.find("where");
auto pos = std::min(pos_W != std::string_view::npos ? pos_W : q_str.size(),
pos_w != std::string_view::npos ? pos_w : q_str.size());
auto pos = std::min(pos_W != std::string::npos ? pos_W : q_str.size(),
pos_w != std::string::npos ? pos_w : q_str.size());
select = q_str.substr(0, pos);
where = q_str.substr(pos, q_str.size()-pos);
}
+34 -477
View File
@@ -1,5 +1,5 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
# ===========================================================================
#
# SYNOPSIS
@@ -10,13 +10,13 @@
#
# Check for baseline language coverage in the compiler for the specified
# version of the C++ standard. If necessary, add switches to CXX and
# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for
# the respective C++ standard version.
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
# or '14' (for the C++14 standard).
#
# The second argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for no added switch, and then for an extended mode.
# preference for an extended mode.
#
# The third argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline support for the specified C++ standard is
@@ -33,26 +33,21 @@
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
# Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 14
#serial 4
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
dnl (serial version number 13).
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
[$1], [20], [ax_cxx_compile_alternatives="20"],
m4_if([$1], [11], [],
[$1], [14], [],
[$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])],
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$2], [], [],
[$2], [ext], [],
@@ -64,21 +59,18 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
AC_LANG_PUSH([C++])dnl
ac_success=no
m4_if([$2], [], [dnl
AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
ax_cv_cxx_compile_cxx$1,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[ax_cv_cxx_compile_cxx$1=yes],
[ax_cv_cxx_compile_cxx$1=no])])
if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
ac_success=yes
fi])
AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
ax_cv_cxx_compile_cxx$1,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[ax_cv_cxx_compile_cxx$1=yes],
[ax_cv_cxx_compile_cxx$1=no])])
if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
ac_success=yes
fi
m4_if([$2], [noext], [], [dnl
if test x$ac_success = xno; then
for alternative in ${ax_cxx_compile_alternatives}; do
switch="-std=gnu++${alternative}"
for switch in -std=gnu++$1 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
@@ -104,27 +96,22 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
dnl Cray's crayCC needs "-h std=c++11"
for alternative in ${ax_cxx_compile_alternatives}; do
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
done
if test x$ac_success = xyes; then
ac_success=yes
break
fi
done
@@ -153,6 +140,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
@@ -160,23 +148,6 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
dnl Test body for checking C++17 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
dnl Test body for checking C++20 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
_AX_CXX_COMPILE_STDCXX_testbody_new_in_20
)
dnl Tests for new features in C++11
@@ -214,13 +185,11 @@ namespace cxx11
struct Base
{
virtual ~Base() {}
virtual void f() {}
};
struct Derived : public Base
{
virtual ~Derived() override {}
virtual void f() override {}
};
@@ -549,7 +518,7 @@ namespace cxx14
}
namespace test_digit_separators
namespace test_digit_seperators
{
constexpr auto ten_million = 100'000'000;
@@ -591,415 +560,3 @@ namespace cxx14
#endif // __cplusplus >= 201402L
]])
dnl Tests for new features in C++17
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
// If the compiler admits that it is not ready for C++17, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#else
#include <initializer_list>
#include <utility>
#include <type_traits>
namespace cxx17
{
namespace test_constexpr_lambdas
{
constexpr int foo = [](){return 42;}();
}
namespace test::nested_namespace::definitions
{
}
namespace test_fold_expression
{
template<typename... Args>
int multiply(Args... args)
{
return (args * ... * 1);
}
template<typename... Args>
bool all(Args... args)
{
return (args && ...);
}
}
namespace test_extended_static_assert
{
static_assert (true);
}
namespace test_auto_brace_init_list
{
auto foo = {5};
auto bar {5};
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
static_assert(std::is_same<int, decltype(bar)>::value);
}
namespace test_typename_in_template_template_parameter
{
template<template<typename> typename X> struct D;
}
namespace test_fallthrough_nodiscard_maybe_unused_attributes
{
int f1()
{
return 42;
}
[[nodiscard]] int f2()
{
[[maybe_unused]] auto unused = f1();
switch (f1())
{
case 17:
f1();
[[fallthrough]];
case 42:
f1();
}
return f1();
}
}
namespace test_extended_aggregate_initialization
{
struct base1
{
int b1, b2 = 42;
};
struct base2
{
base2() {
b3 = 42;
}
int b3;
};
struct derived : base1, base2
{
int d;
};
derived d1 {{1, 2}, {}, 4}; // full initialization
derived d2 {{}, {}, 4}; // value-initialized bases
}
namespace test_general_range_based_for_loop
{
struct iter
{
int i;
int& operator* ()
{
return i;
}
const int& operator* () const
{
return i;
}
iter& operator++()
{
++i;
return *this;
}
};
struct sentinel
{
int i;
};
bool operator== (const iter& i, const sentinel& s)
{
return i.i == s.i;
}
bool operator!= (const iter& i, const sentinel& s)
{
return !(i == s);
}
struct range
{
iter begin() const
{
return {0};
}
sentinel end() const
{
return {5};
}
};
void f()
{
range r {};
for (auto i : r)
{
[[maybe_unused]] auto v = i;
}
}
}
namespace test_lambda_capture_asterisk_this_by_value
{
struct t
{
int i;
int foo()
{
return [*this]()
{
return i;
}();
}
};
}
namespace test_enum_class_construction
{
enum class byte : unsigned char
{};
byte foo {42};
}
namespace test_constexpr_if
{
template <bool cond>
int f ()
{
if constexpr(cond)
{
return 13;
}
else
{
return 42;
}
}
}
namespace test_selection_statement_with_initializer
{
int f()
{
return 13;
}
int f2()
{
if (auto i = f(); i > 0)
{
return 3;
}
switch (auto i = f(); i + 4)
{
case 17:
return 2;
default:
return 1;
}
}
}
namespace test_template_argument_deduction_for_class_templates
{
template <typename T1, typename T2>
struct pair
{
pair (T1 p1, T2 p2)
: m1 {p1},
m2 {p2}
{}
T1 m1;
T2 m2;
};
void f()
{
[[maybe_unused]] auto p = pair{13, 42u};
}
}
namespace test_non_type_auto_template_parameters
{
template <auto n>
struct B
{};
B<5> b1;
B<'a'> b2;
}
namespace test_structured_bindings
{
int arr[2] = { 1, 2 };
std::pair<int, int> pr = { 1, 2 };
auto f1() -> int(&)[2]
{
return arr;
}
auto f2() -> std::pair<int, int>&
{
return pr;
}
struct S
{
int x1 : 2;
volatile double y1;
};
S f3()
{
return {};
}
auto [ x1, y1 ] = f1();
auto& [ xr1, yr1 ] = f1();
auto [ x2, y2 ] = f2();
auto& [ xr2, yr2 ] = f2();
const auto [ x3, y3 ] = f3();
}
namespace test_exception_spec_type_system
{
struct Good {};
struct Bad {};
void g1() noexcept;
void g2();
template<typename T>
Bad
f(T*, T*);
template<typename T1, typename T2>
Good
f(T1*, T2*);
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
}
namespace test_inline_variables
{
template<class T> void f(T)
{}
template<class T> inline T g(T)
{
return T{};
}
template<> inline void f<>(int)
{}
template<> int g<>(int)
{
return 5;
}
}
} // namespace cxx17
#endif // __cplusplus < 201703L
]])
dnl Tests for new features in C++20
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 202002L
#error "This is not a C++20 compiler"
#else
#include <version>
namespace cxx20
{
// As C++20 supports feature test macros in the standard, there is no
// immediate need to actually test for feature availability on the
// Autoconf side.
} // namespace cxx20
#endif // __cplusplus < 202002L
]])
+3 -3
View File
@@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: OpenDHT
Description: C++14 Distributed Hash Table library
Description: C++ Distributed Hash Table library
Version: @VERSION@
Libs: -L${libdir} -lopendht
Libs.private: @http_parser_lib@ -pthread
Requires.private: gnutls >= 3.3, nettle >= 2.4@argon2_lib@@jsoncpp_lib@@openssl_lib@
Libs.private: -lpthread
Requires.private: gnutls >= 3.1@argon2_lib@
Cflags: -I${includedir}
+10 -25
View File
@@ -1,11 +1,11 @@
# distutils: language = c++
# distutils: extra_compile_args = -std=c++17
# distutils: extra_compile_args = -std=c++14
# distutils: include_dirs = ../../include
# distutils: library_dirs = ../../src
# distutils: libraries = opendht gnutls
# cython: language_level=3
#
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
# Author(s): Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
# Adrien Béraud <adrien.beraud@savoirfairelinux.com>
# Simon Désaulniers <sim.desaulniers@gmail.com>
@@ -36,7 +36,6 @@ from libcpp.memory cimport shared_ptr
from cython.parallel import parallel, prange
from cython.operator cimport dereference as deref, preincrement as inc, predecrement as dec
from cpython cimport ref
from datetime import timedelta
cimport opendht_cpp as cpp
@@ -236,9 +235,8 @@ cdef class Where(object):
cdef class Value(object):
cdef shared_ptr[cpp.Value] _value
def __init__(self, bytes val=b'', cpp.uint16_t id=0):
self._value.reset(new cpp.Value(id, val, len(val)))
def __init__(self, bytes val=b''):
self._value.reset(new cpp.Value(val, len(val)))
def __str__(self):
return self._value.get().toString().decode()
property owner:
@@ -272,14 +270,6 @@ cdef class Value(object):
def __get__(self):
return self._value.get().size()
cdef class ValueType(object):
cdef cpp.ValueType * _value
def __init__(self, cpp.uint16_t id, str name, expiration: timedelta):
if not isinstance(expiration, timedelta):
raise TypeError("expiration argument must be of type timedelta")
cdef cpp.seconds duration = cpp.seconds(int(expiration.total_seconds()))
self._value = new cpp.ValueType(id, name.encode(), duration)
cdef class NodeSetIter(object):
cdef map[cpp.InfoHash, shared_ptr[cpp.Node]]* _nodes
cdef map[cpp.InfoHash, shared_ptr[cpp.Node]].iterator _curIter
@@ -329,11 +319,11 @@ cdef class PrivateKey(_WithID):
cdef shared_ptr[cpp.PrivateKey] _key
def getId(self):
h = InfoHash()
h._infohash = self._key.get().getSharedPublicKey().get().getId()
h._infohash = self._key.get().getPublicKey().getId()
return h
def getPublicKey(self):
pk = PublicKey()
pk._key = self._key.get().getSharedPublicKey()
pk._key = self._key.get().getPublicKey()
return pk
def decrypt(self, bytes dat):
cdef size_t d_len = len(dat)
@@ -358,17 +348,17 @@ cdef class PrivateKey(_WithID):
return k
cdef class PublicKey(_WithID):
cdef cpp.shared_ptr[cpp.PublicKey] _key
cdef cpp.PublicKey _key
def getId(self):
h = InfoHash()
h._infohash = self._key.get().getId()
h._infohash = self._key.getId()
return h
def encrypt(self, bytes dat):
cdef size_t d_len = len(dat)
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
cdef cpp.Blob indat
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
cdef cpp.Blob encrypted = self._key.get().encrypt(indat)
cdef cpp.Blob encrypted = self._key.encrypt(indat)
cdef char* encrypted_c_str = <char *>encrypted.data()
cdef Py_ssize_t length = encrypted.size()
return encrypted_c_str[:length]
@@ -440,7 +430,7 @@ cdef class Identity(object):
property publickey:
def __get__(self):
k = PublicKey()
k._key = self._id.first.get().getSharedPublicKey()
k._key = self._id.first.get().getPublicKey()
return k
property certificate:
def __get__(self):
@@ -468,9 +458,6 @@ cdef class DhtConfig(object):
self._config.dht_config.node_config.network = netid
def setMaintainStorage(self, bool maintain_storage):
self._config.dht_config.node_config.maintain_storage = maintain_storage
def setRateLimit(self, ssize_t max_req_per_sec, ssize_t max_peer_req_per_sec):
self._config.dht_config.node_config.max_req_per_sec = max_req_per_sec
self._config.dht_config.node_config.max_peer_req_per_sec = max_peer_req_per_sec
cdef class DhtRunner(_WithID):
cdef cpp.shared_ptr[cpp.DhtRunner] thisptr
@@ -523,8 +510,6 @@ cdef class DhtRunner(_WithID):
cb_obj = {'shutdown':shutdown_cb}
ref.Py_INCREF(cb_obj)
self.thisptr.get().shutdown(cpp.bindShutdownCb(shutdown_callback, <void*>cb_obj))
def registerType(self, ValueType type):
self.thisptr.get().registerType(deref(type._value))
def enableLogging(self):
cpp.enableLogging(self.thisptr.get()[0])
def disableLogging(self):
+4 -21
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
# Simon Désaulniers <sim.desaulniers@gmail.com>
#
@@ -26,14 +26,6 @@ from libc.string cimport const_char, const_uchar
ctypedef uint16_t in_port_t
ctypedef unsigned short int sa_family_t;
cdef extern from "<iostream>" namespace "std::chrono" nogil:
cdef cppclass duration[ulong]:
duration() except +
cdef cppclass seconds:
duration seconds(uint64_t) except +
duration seconds()
cdef extern from "<memory>" namespace "std" nogil:
cdef cppclass shared_ptr[T]:
shared_ptr() except +
@@ -97,7 +89,7 @@ cdef extern from "opendht/crypto.h" namespace "dht::crypto":
cdef cppclass PrivateKey:
PrivateKey()
shared_ptr[PublicKey] getSharedPublicKey() const
PublicKey getPublicKey() const
Blob decrypt(Blob data) const
@staticmethod
PrivateKey generate()
@@ -139,6 +131,7 @@ cdef extern from "opendht/value.h" namespace "dht::Value":
cdef extern from "opendht/value.h" namespace "dht::Value::Field":
cdef Field None
cdef Field Id
cdef Field ValueType
cdef Field OwnerPk
cdef Field SeqNum
cdef Field UserType
@@ -148,7 +141,7 @@ cdef extern from "opendht/value.h" namespace "dht":
cdef cppclass Value:
Value() except +
Value(vector[uint8_t]) except +
Value(const uint16_t t, const uint8_t* dat_ptr, size_t dat_len) except +
Value(const uint8_t* dat_ptr, size_t dat_len) except +
string toString() const
size_t size() const
uint64_t id
@@ -157,12 +150,6 @@ cdef extern from "opendht/value.h" namespace "dht":
vector[uint8_t] data
string user_type
cdef cppclass ValueType:
ValueType(uint16_t id, string name, seconds expiration) except +
uint16_t id
string name
seconds expiration
cdef cppclass Query:
Query() except +
Query(Select s, Where w) except +
@@ -224,9 +211,6 @@ cdef extern from "opendht/callbacks.h" namespace "dht":
uint32_t network
bool is_bootstrap
bool maintain_storage
string persist_path
size_t max_req_per_sec
size_t max_peer_req_per_sec
cppclass SecureDhtConfig:
Config node_config
Identity id
@@ -247,7 +231,6 @@ cdef extern from "opendht/dhtrunner.h" namespace "dht":
void run(const_char*, const_char*, const_char*, Config config)
void join()
void shutdown(ShutdownCallback)
void registerType(ValueType& value);
bool isRunning()
SockAddr getBound(sa_family_t af) const
string getStorageLog() const
+3 -3
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
# Copyright (C) 2015-2019 Savoir-faire Linux Inc.
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
@@ -50,8 +50,8 @@ setup(name="opendht",
["@CURRENT_SOURCE_DIR@/opendht.pyx"],
include_dirs = ['@PROJECT_SOURCE_DIR@/include'],
language="c++",
extra_compile_args=["-std=c++17"],
extra_link_args=["-std=c++17"],
extra_compile_args=["-std=c++14"],
extra_link_args=["-std=c++14"],
libraries=["opendht"],
library_dirs = ['@CURRENT_BINARY_DIR@', '@PROJECT_BINARY_DIR@']
))
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
# Copyright (C) 2015-2019 Savoir-faire Linux Inc.
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
# Simon Désaulniers <sim.desaulniers@gmail.com>
#
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
# Simon Désaulniers <sim.desaulniers@gmail.com>
#
+1 -1
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2015-2022 Savoir-Faire Linux Inc.
# Copyright (C) 2015-2019 Savoir-Faire Linux Inc.
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
# Simon Désaulniers <sim.desaulniers@gmail.com>
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
# Copyright (C) 2015-2019 Savoir-faire Linux Inc.
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2016-2022 Savoir-faire Linux Inc.
# Copyright (c) 2016-2019 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
+6 -23
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -19,40 +19,30 @@ import opendht as dht
import time
import asyncio
config = dht.DhtConfig()
config.setRateLimit(-1, -1)
ping_node = dht.DhtRunner()
ping_node.run(config=config)
ping_node.run()
#ping_node.enableLogging()
#ping_node.bootstrap("bootstrap.ring.cx", "4222")
pong_node = dht.DhtRunner()
pong_node.run(config=config)
pong_node.run()
#pong_node.enableLogging()
pong_node.ping(ping_node.getBound())
loc_ping = dht.InfoHash.get("toto99")
loc_pong = dht.InfoHash.get(str(loc_ping))
net = []
for i in range(1,10):
node = dht.DhtRunner()
node.run(config=config)
node.ping(ping_node.getBound())
net.append(node)
i = 0
MAX = 2048
loop = asyncio.get_event_loop()
def done(h, ok):
pass
#print(h, "over", ok)
print(h, "over", ok)
def ping(node, h):
global i
time.sleep(0.0075)
i += 1
if i < MAX:
node.put(h, dht.Value(b"hey"), lambda ok, nodes: done(node.getNodeId().decode(), ok))
@@ -60,20 +50,13 @@ def ping(node, h):
loop.stop()
def pong(node, h):
#print(node.getNodeId().decode(), "got ping", h, i)
print(node.getNodeId().decode(), "got ping", h, i)
loop.call_soon_threadsafe(ping, node, h)
return True
t1 = time.time()
ping_node.listen(loc_ping, lambda v, e: pong(pong_node, loc_pong) if not e else True)
pong_node.listen(loc_pong, lambda v, e: pong(ping_node, loc_ping) if not e else True)
ping(pong_node, loc_ping)
loop.run_forever()
t2 = time.time()
print(MAX, "ping-pong done, took", t2 - t1, "s")
print(1000 * (t2 - t1)/MAX, "ms per rt", MAX/(t2 - t1), "rt per s")
+27 -12
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -21,7 +21,6 @@ from math import cos, sin, pi
import urllib3
import gzip
import queue
from geoip import geolite2
sys.path.append('..')
from opendht import *
@@ -56,7 +55,7 @@ plt.ion()
plt.figaspect(2.)
fig, axes = plt.subplots(2, 1)
#fig.set_size_inches(8,16,forward=True)
fig.set_size_inches(8,16,forward=True)
fig.tight_layout()
fig.canvas.set_window_title('OpenDHT scanner')
@@ -91,12 +90,27 @@ def exitcb(arg):
run = False
exitbtn.on_clicked(exitcb)
def check_dl(fname, url):
if os.path.isfile(fname):
return
print('downloading', url)
ghandle = gzip.GzipFile(fileobj=http.request('GET', url, headers={'User-Agent': 'Mozilla/5.0'}, preload_content=False))
with open(fname, 'wb') as out:
for line in ghandle:
out.write(line)
check_dl("GeoLiteCity.dat", "http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz")
check_dl("GeoLiteCityv6.dat", "http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz")
gi = GeoIP.open("GeoLiteCity.dat", GeoIP.GEOIP_INDEX_CACHE | GeoIP.GEOIP_CHECK_CACHE)
gi6 = GeoIP.open("GeoLiteCityv6.dat", GeoIP.GEOIP_INDEX_CACHE | GeoIP.GEOIP_CHECK_CACHE)
def gcb(v):
return True
r = DhtRunner()
r.run(port=4112)
r.bootstrap("bootstrap.jami.net", "4222")
r.bootstrap("bootstrap.ring.cx", "4222")
plt.pause(1)
@@ -129,9 +143,9 @@ def nextstep(cur_h, cur_depth, ok, nodes):
depth = min(8, commonBits+6)
if cur_depth < depth:
for b in range(cur_depth, depth):
new_h = InfoHash(cur_h.toString())
new_h.setBit(b, 1)
step(new_h, b+1)
new_h = InfoHash(cur_h.toString());
new_h.setBit(b, 1);
step(new_h, b+1);
else:
print("step done with no nodes", ok, cur_h.toString().decode())
done -= 1
@@ -172,22 +186,23 @@ def appendNewNode(n):
if addr in nodes_ip6s:
nodes_ip6s[addr][1] += 1
else:
georecord = geolite2.lookup(addr)
georecord = gi6.record_by_name_v6(addr)
nodes_ip6s[addr] = [n, 1, georecord]
else:
if addr in nodes_ip4s:
nodes_ip4s[addr][1] += 1
else:
georecord = geolite2.lookup(addr)
georecord = gi.record_by_name(addr)
nodes_ip4s[addr] = [n, 1, georecord]
if georecord:
appendMapPoint(georecord)
def appendMapPoint(res):
global lons, lats, cities
lons.append(res.location[1])
lats.append(res.location[0])
cities.append(res.city if res.city else (str(int(res.location[0]))+'-'+str(int(res.location[1]))))
lons.append(res['longitude'])
lats.append(res['latitude'])
cities.append(res['city'] if res['city'] else (str(int(res['latitude']))+'-'+str(int(res['longitude']))))
def restart(arg):
global collection, all_lines, all_nodes, points, done, nodes_ip4s, nodes_ip6s, lats, lons, cities, xys, colors
+3 -14
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,6 @@ extern crate opendht;
use std::{ thread, time };
use opendht::{ InfoHash, DhtRunner, DhtRunnerConfig, Value };
// use opendht::crypto::*;
fn main() {
println!("{}", InfoHash::random());
@@ -29,24 +28,15 @@ fn main() {
println!("{}", InfoHash::get("alice"));
println!("{}", InfoHash::get("alice").is_zero());
let mut dht = DhtRunner::new();
let /*mut*/ config = DhtRunnerConfig::new();
//// If you want to inject a certificate, uncomment the following lines and previous mut.
//// Note: you can generate a certificate with
//// openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout example.key -out example.crt -subj /CN=example.com
//let cert = DhtCertificate::import("example.crt").ok().expect("Invalid cert file");
//let pk = PrivateKey::import("example.key", "");
//config.set_identity(cert, pk);
let config = DhtRunnerConfig::new();
dht.run_config(1412, config);
dht.bootstrap("bootstrap.jami.net", 4222);
println!("Current node id: {}", dht.node_id());
let /* mut */ data = 42;
let mut get_cb = |v: Box<Value>| {
//data += 1;
println!("GET: VALUE CB - data: {} - v: {}", data, v);
true
};
let mut done_cb = |ok: bool| {
println!("GET: DONE CB - data: {} - ok: {}", data, ok);
@@ -57,13 +47,12 @@ fn main() {
let mut put_done_cb = |ok: bool| {
println!("PUT: DONE CB - data: {} - ok: {}", data, ok);
};
dht.put(&InfoHash::get("bob"), Value::new("hi!"), &mut put_done_cb, false);
dht.put(&InfoHash::get("bob"), Value::new("hi!"), &mut put_done_cb);
println!("Start listening /foo");
let mut value_cb = |v, expired| {
println!("LISTEN: DONE CB - data: {} - v: {} - expired: {}", data, v, expired);
true
};
let token = dht.listen(&InfoHash::get("foo"), &mut value_cb);
let one_min = time::Duration::from_secs(10);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
+8 -88
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,17 +18,13 @@
#![allow(dead_code)]
pub use crate::ffi::*;
use crate::ffi::*;
use std::ffi::CString;
use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::ptr;
impl PublicKey {
pub fn new(data: &str) -> Box<PublicKey> {
pub fn new() -> Box<PublicKey> {
unsafe {
Box::from_raw(dht_publickey_import(data.as_ptr(), data.len()))
Box::from_raw(dht_publickey_new())
}
}
@@ -93,17 +89,11 @@ impl PrivateKey {
}
}
pub fn import(file: &str, password: &str) -> io::Result<Box<PrivateKey>> {
let mut f = File::open(file)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
Ok(PrivateKey::from_bytes(&buffer, password))
}
pub fn from_bytes(buffer: &Vec<u8>, password: &str) -> Box<PrivateKey> {
pub fn import(data: &str, password: &str) -> Box<PrivateKey> {
let password = CString::new(password).unwrap();
unsafe {
Box::from_raw(dht_privatekey_import((&*buffer).as_ptr(), buffer.len(),
password.as_ptr() as *const i8))
Box::from_raw(dht_privatekey_import(data.as_ptr(),
data.as_bytes().len(), password.as_ptr()))
}
}
@@ -121,74 +111,4 @@ impl Drop for PrivateKey {
dht_privatekey_delete(&mut *self)
}
}
}
impl DhtCertificate {
pub fn import(file: &str) -> io::Result<Box<DhtCertificate>> {
let mut f = File::open(file)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
Ok(DhtCertificate::from_bytes(&buffer))
}
pub fn from_bytes(buffer: &Vec<u8>) -> Box<DhtCertificate> {
unsafe {
Box::from_raw(dht_certificate_import((&*buffer).as_ptr(), buffer.len()))
}
}
pub fn from_slice(buffer: &str) -> Box<DhtCertificate> {
unsafe {
Box::from_raw(dht_certificate_import((&*buffer).as_ptr(), buffer.len()))
}
}
pub fn id(&self) -> InfoHash {
unsafe {
dht_certificate_get_id(&*self)
}
}
pub fn long_id(&self) -> PkId {
unsafe {
dht_certificate_get_long_id(&*self)
}
}
pub fn publickey(&self) -> Box<PublicKey> {
unsafe {
Box::from_raw(dht_certificate_get_publickey(&*self))
}
}
}
impl Drop for DhtCertificate {
fn drop(&mut self) {
unsafe {
dht_certificate_delete(&mut *self)
}
}
}
impl DhtIdentity {
pub fn new(common_name: &str) -> DhtIdentity {
unsafe {
DhtIdentity::generate(common_name, Box::from_raw(ptr::null_mut()))
}
}
pub fn generate(common_name: &str, ca: Box<DhtIdentity>) -> DhtIdentity {
let common_name = CString::new(common_name).unwrap();
unsafe {
dht_identity_generate(common_name.as_ptr(), &*ca)
}
}
}
impl Drop for DhtIdentity {
fn drop(&mut self) {
unsafe {
dht_identity_delete(&mut *self)
}
}
}
+17 -33
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -39,7 +39,7 @@ impl DhtRunnerConfig {
persist_path: ptr::null(),
},
id: DhtIdentity {
privatekey: ptr::null_mut(),
privkey: ptr::null_mut(),
certificate: ptr::null_mut(),
},
},
@@ -51,7 +51,7 @@ impl DhtRunnerConfig {
peer_publish: false,
server_ca: ptr::null_mut(),
client_identity: DhtIdentity {
privatekey: ptr::null_mut(),
privkey: ptr::null_mut(),
certificate: ptr::null_mut(),
},
});
@@ -73,11 +73,6 @@ impl DhtRunnerConfig {
self.push_token = CString::new(push_token).unwrap().as_ptr();
}
pub fn set_identity(&mut self, certificate: Box<DhtCertificate>, privatekey: Box<PrivateKey>) {
self.dht_config.id.privatekey = Box::into_raw(privatekey);
self.dht_config.id.certificate = Box::into_raw(certificate);
}
}
impl DhtNodeConfig
@@ -89,13 +84,13 @@ impl DhtNodeConfig
struct GetHandler<'a>
{
get_cb: &'a mut(dyn FnMut(Box<Value>) -> bool),
get_cb: &'a mut(dyn FnMut(Box<Value>)),
done_cb: &'a mut(dyn FnMut(bool))
}
impl<'a> GetHandler<'a>
{
fn get_cb(&mut self, v: Box<Value>) -> bool{
fn get_cb(&mut self, v: Box<Value>) {
(self.get_cb)(v)
}
@@ -104,9 +99,9 @@ impl<'a> GetHandler<'a>
}
}
extern fn get_handler_cb(v: *mut Value, ptr: *mut c_void) -> bool {
extern fn get_handler_cb(v: *mut Value, ptr: *mut c_void) {
if ptr.is_null() {
return true;
return;
}
unsafe {
let handler = ptr as *mut GetHandler;
@@ -142,17 +137,17 @@ extern fn put_handler_done(ok: bool, ptr: *mut c_void) {
struct ListenHandler<'a>
{
cb: &'a mut(dyn FnMut(Box<Value>, bool) -> bool)
cb: &'a mut(dyn FnMut(Box<Value>, bool))
}
impl<'a> ListenHandler<'a>
{
fn cb(&mut self, v: Box<Value>, expired: bool) -> bool {
fn cb(&mut self, v: Box<Value>, expired: bool) {
(self.cb)(v, expired)
}
}
extern fn listen_handler(v: *mut Value, expired: bool, ptr: *mut c_void) -> bool {
extern fn listen_handler(v: *mut Value, expired: bool, ptr: *mut c_void) {
unsafe {
let handler = ptr as *mut ListenHandler;
(*handler).cb((*v).boxed(), expired)
@@ -205,7 +200,7 @@ impl DhtRunner {
}
pub fn get<'a>(&mut self, h: &InfoHash,
get_cb: &'a mut(dyn FnMut(Box<Value>) -> bool),
get_cb: &'a mut(dyn FnMut(Box<Value>)),
done_cb: &'a mut(dyn FnMut(bool))) {
let handler = Box::new(GetHandler {
get_cb,
@@ -218,35 +213,24 @@ impl DhtRunner {
}
pub fn put<'a>(&mut self, h: &InfoHash, v: Box<Value>,
done_cb: &'a mut(dyn FnMut(bool)), permanent: bool) {
done_cb: &'a mut(dyn FnMut(bool))) {
let handler = Box::new(PutHandler {
done_cb,
});
let handler = Box::into_raw(handler) as *mut c_void;
unsafe {
dht_runner_put(&mut *self, h, &*v, put_handler_done, handler, permanent)
dht_runner_put(&mut *self, h, &*v, put_handler_done, handler)
}
}
pub fn put_signed<'a>(&mut self, h: &InfoHash, v: Box<Value>,
done_cb: &'a mut(dyn FnMut(bool)), permanent: bool) {
pub fn permanent_put<'a>(&mut self, h: &InfoHash, v: Box<Value>,
done_cb: &'a mut(dyn FnMut(bool))) {
let handler = Box::new(PutHandler {
done_cb,
});
let handler = Box::into_raw(handler) as *mut c_void;
unsafe {
dht_runner_put_signed(&mut *self, h, &*v, put_handler_done, handler, permanent)
}
}
pub fn put_encrypted<'a>(&mut self, h: &InfoHash, to: &InfoHash, v: Box<Value>,
done_cb: &'a mut(dyn FnMut(bool)), permanent: bool) {
let handler = Box::new(PutHandler {
done_cb,
});
let handler = Box::into_raw(handler) as *mut c_void;
unsafe {
dht_runner_put_encrypted(&mut *self, h, to, &*v, put_handler_done, handler, permanent)
dht_runner_put_permanent(&mut *self, h, &*v, put_handler_done, handler)
}
}
@@ -257,7 +241,7 @@ impl DhtRunner {
}
pub fn listen<'a>(&mut self, h: &InfoHash,
cb: &'a mut(dyn FnMut(Box<Value>, bool) -> bool)) -> Box<OpToken> {
cb: &'a mut(dyn FnMut(Box<Value>, bool))) -> Box<OpToken> {
let handler = Box::new(ListenHandler {
cb,
});
+11 -36
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -44,7 +44,6 @@ pub struct Blob
}
#[repr(C)]
#[derive(PartialEq)]
pub struct InfoHash
{
pub d: [u8; HASH_LEN],
@@ -99,7 +98,7 @@ pub struct DhtCertificate
#[repr(C)]
pub struct DhtIdentity
{
pub privatekey: *mut PrivateKey,
pub privkey: *mut PrivateKey,
pub certificate: *mut DhtCertificate,
}
@@ -128,14 +127,11 @@ pub struct DhtRunnerConfig
#[link(name = "opendht-c")]
extern {
// dht::Value
pub fn dht_value_get_id(data: *const Value) -> u64;
pub fn dht_value_get_data(data: *const Value) -> DataView;
pub fn dht_value_new(data: *const u8, size: size_t) -> *mut Value;
pub fn dht_value_ref(data: *const Value) -> *mut Value;
pub fn dht_value_unref(data: *mut Value);
pub fn dht_value_get_data(data: *const Value) -> DataView;
pub fn dht_value_get_id(data: *const Value) -> u64;
pub fn dht_value_get_owner(data: *const Value) -> *mut PublicKey;
pub fn dht_value_get_recipient(data: *const Value) -> InfoHash;
pub fn dht_value_get_user_type(data: *const Value) -> *const c_char;
// dht::Blob
pub fn dht_blob_get_data(data: *const Blob) -> DataView;
@@ -145,14 +141,13 @@ extern {
pub fn dht_infohash_print(h: *const InfoHash) -> *const c_char;
pub fn dht_infohash_random(h: *mut InfoHash);
pub fn dht_infohash_get(h: *mut InfoHash, dat: *mut u8, dat_size: size_t);
pub fn dht_infohash_from_hex(h: *mut InfoHash, dat: *const c_char);
pub fn dht_infohash_is_zero(j: *const InfoHash) -> bool;
// dht::PkId
pub fn dht_pkid_print(h: *const PkId) -> *const c_char;
// dht::crypto::PublicKey
pub fn dht_publickey_import(dat: *const u8, dat_size: size_t) -> *mut PublicKey;
pub fn dht_publickey_new() -> *mut PublicKey;
pub fn dht_publickey_delete(pk: *mut PublicKey);
pub fn dht_publickey_unpack(pk: *mut PublicKey, dat: *const u8, dat_size: size_t) -> c_int;
pub fn dht_publickey_pack(pk: *mut PublicKey, out: *const c_char, out_size: size_t) -> c_int;
@@ -167,16 +162,6 @@ extern {
pub fn dht_privatekey_get_publickey(pk: *const PrivateKey) -> *mut PublicKey;
pub fn dht_privatekey_delete(pk: *mut PrivateKey);
// dht::crypto::Certificate
pub fn dht_certificate_import(dat: *const u8, dat_size: size_t) -> *mut DhtCertificate;
pub fn dht_certificate_get_id(cert: *const DhtCertificate) -> InfoHash;
pub fn dht_certificate_get_long_id(cert: *const DhtCertificate) -> PkId;
pub fn dht_certificate_get_publickey(cert: *const DhtCertificate) -> *mut PublicKey;
pub fn dht_certificate_delete(cert: *mut DhtCertificate);
pub fn dht_identity_generate(common_name: *const c_char, ca: *const DhtIdentity) -> DhtIdentity;
pub fn dht_identity_delete(ca: *mut DhtIdentity);
// dht::OpToken
pub fn dht_op_token_delete(token: *mut OpToken);
@@ -190,28 +175,18 @@ extern {
pub fn dht_runner_run_config(dht: *mut DhtRunner, port: in_port_t, config: *const DhtRunnerConfig);
pub fn dht_runner_bootstrap(dht: *mut DhtRunner, host: *const c_char, service: *const c_char);
pub fn dht_runner_get(dht: *mut DhtRunner, h: *const InfoHash,
get_cb: extern fn(*mut Value, *mut c_void) -> bool,
done_cb: extern fn(bool, *mut c_void),
cb_user_data: *mut c_void);
get_cb: extern fn(*mut Value, *mut c_void),
done_cb: extern fn(bool, *mut c_void),
cb_user_data: *mut c_void);
pub fn dht_runner_put(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value,
done_cb: extern fn(bool, *mut c_void),
cb_user_data: *mut c_void,
permanent: bool);
pub fn dht_runner_put_signed(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value,
done_cb: extern fn(bool, *mut c_void),
cb_user_data: *mut c_void,
permanent: bool);
pub fn dht_runner_put_encrypted(dht: *mut DhtRunner, h: *const InfoHash,
to: *const InfoHash, v: *const Value,
done_cb: extern fn(bool, *mut c_void),
cb_user_data: *mut c_void,
permanent: bool);
done_cb: extern fn(bool, *mut c_void),
cb_user_data: *mut c_void);
pub fn dht_runner_put_permanent(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value,
done_cb: extern fn(bool, *mut c_void),
cb_user_data: *mut c_void);
pub fn dht_runner_cancel_put(dht: *mut DhtRunner, h: *const InfoHash, vid: u64);
pub fn dht_runner_listen(dht: *mut DhtRunner, h: *const InfoHash,
cb: extern fn(*mut Value, bool, *mut c_void) -> bool,
cb: extern fn(*mut Value, bool, *mut c_void),
done_cb: extern fn(*mut c_void),
cb_user_data: *mut c_void) -> *mut OpToken;
pub fn dht_runner_cancel_listen(dht: *mut DhtRunner, h: *const InfoHash,
+1 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -47,23 +47,6 @@ impl InfoHash {
h
}
pub fn from_bytes(data: &Vec<u8>) -> InfoHash {
let mut h = InfoHash::new();
unsafe {
dht_infohash_get(&mut h, data.as_ptr() as *mut u8, data.len());
}
h
}
pub fn from_hex(data: &str) -> InfoHash {
let mut h = InfoHash::new();
unsafe {
let c_str = CString::new(data).unwrap();
dht_infohash_from_hex(&mut h, c_str.as_ptr());
}
h
}
pub fn is_zero(&self) -> bool {
unsafe {
dht_infohash_is_zero(self)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
+1 -25
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -15,11 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#![allow(dead_code)]
use crate::ffi::*;
use std::fmt;
use std::ffi::{ CString, IntoStringError };
use std::str;
use std::slice;
@@ -64,28 +62,6 @@ impl Value {
Box::from_raw(dht_value_ref(self))
}
}
pub fn recipient(&self) -> InfoHash {
unsafe {
dht_value_get_recipient(self)
}
}
pub fn owner(&self) -> Option<Box<PublicKey>> {
unsafe {
let ptr = dht_value_get_owner(self);
if ptr.is_null() {
return None;
}
Some(Box::from_raw(ptr))
}
}
pub fn user_type(&self) -> Result<String, IntoStringError> {
unsafe {
CString::from_raw(dht_value_get_user_type(self) as *mut _).into_string()
}
}
}
impl Drop for Value {
+32 -8
View File
@@ -2,7 +2,7 @@ lib_LTLIBRARIES = libopendht.la
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@ @OpenSSL_CFLAGS@ @Fmt_CFLAGS@
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@ @OpenSSL_LIBS@ @Fmt_LIBS@
libopendht_la_LDFLAGS = @LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
libopendht_la_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@ @OpenSSL_LDFLAGS@ @Fmt_LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
libopendht_la_SOURCES = \
dht.cpp \
storage.h \
@@ -27,6 +27,7 @@ libopendht_la_SOURCES = \
dhtrunner.cpp \
default_types.cpp \
log.cpp \
peer_discovery.cpp \
network_utils.cpp \
thread_pool.cpp
@@ -55,6 +56,7 @@ nobase_include_HEADERS = \
../include/opendht/default_types.h \
../include/opendht/log.h \
../include/opendht/log_enable.h \
../include/opendht/peer_discovery.h \
../include/opendht/network_utils.h \
../include/opendht/rng.h \
../include/opendht/thread_pool.h
@@ -71,13 +73,8 @@ endif
libopendht_la_SOURCES += base64.h base64.cpp
if PROXY_CLIENT_OR_SERVER
libopendht_la_SOURCES += http.cpp compat/os_cert.cpp
nobase_include_HEADERS += ../include/opendht/proxy.h ../include/opendht/http.h compat/os_cert.h
endif
if ENABLE_PEER_DISCOVERY
libopendht_la_SOURCES += peer_discovery.cpp
nobase_include_HEADERS += ../include/opendht/peer_discovery.h
libopendht_la_SOURCES += http.cpp
nobase_include_HEADERS += ../include/opendht/proxy.h ../include/opendht/http.h
endif
if ENABLE_INDEXATION
@@ -87,3 +84,30 @@ endif
clean-local:
rm -rf libargon2.la
######################
# ARGON2 submodule #
######################
if WITH_INCLUDED_ARGON2
noinst_LTLIBRARIES = libargon2.la
libopendht_la_DEPENDENCIES = libargon2.la
libargon2_la_CFLAGS = -std=c89 -fPIC -pthread -O3 -Wall -I@top_builddir@/argon2/include -I@top_builddir@/argon2/src
libargon2_la_SOURCES = \
@top_builddir@/argon2/src/argon2.c \
@top_builddir@/argon2/src/core.c \
@top_builddir@/argon2/src/blake2/blake2b.c \
@top_builddir@/argon2/src/thread.c \
@top_builddir@/argon2/src/ref.c \
@top_builddir@/argon2/src/encoding.c
noinst_HEADERS = \
@top_builddir@/argon2/include/argon2.h \
@top_builddir@/argon2/src/blake2/blake2.h \
@top_builddir@/argon2/src/blake2/blake2-impl.h \
@top_builddir@/argon2/src/blake2/blamka-round-ref.h \
@top_builddir@/argon2/src/core.h \
@top_builddir@/argon2/src/encoding.h \
@top_builddir@/argon2/src/thread.h
endif
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2004-2019 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -131,7 +131,7 @@ base64_encode(const std::vector<unsigned char>& str)
return base64_encode(str.cbegin(), str.cend());
}
std::vector<unsigned char>
std::string
base64_decode(const std::string& str)
{
size_t output_length = str.length() / 4 * 3 + 2;
@@ -139,5 +139,5 @@ base64_decode(const std::string& str)
output.resize(output_length);
base64_decode(str.data(), str.size(), output.data(), &output_length);
output.resize(output_length);
return output;
return std::string(output.begin(), output.end());
}
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2004-2019 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,4 +33,4 @@ std::string base64_encode(const std::vector<unsigned char>& str);
* @param str the input buffer
* @return a base64-decoded buffer
*/
std::vector<unsigned char> base64_decode(const std::string& str);
std::string base64_decode(const std::string& str);
+8 -33
View File
@@ -1,32 +1,10 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "callbacks.h"
namespace dht {
GetCallbackSimple
bindGetCb(GetCallbackRaw raw_cb, void* user_data)
bindGetCb(const GetCallbackRaw& raw_cb, void* user_data)
{
if (not raw_cb) return {};
return [=](const std::shared_ptr<Value>& value) {
@@ -35,10 +13,10 @@ bindGetCb(GetCallbackRaw raw_cb, void* user_data)
}
GetCallback
bindGetCb(GetCallbackSimple cb)
bindGetCb(const GetCallbackSimple& cb)
{
if (not cb) return {};
return [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& values) {
return [=](const std::vector<std::shared_ptr<Value>>& values) {
for (const auto& v : values)
if (not cb(v))
return false;
@@ -47,7 +25,7 @@ bindGetCb(GetCallbackSimple cb)
}
ValueCallback
bindValueCb(ValueCallbackRaw raw_cb, void* user_data)
bindValueCb(const ValueCallbackRaw& raw_cb, void* user_data)
{
if (not raw_cb) return {};
return [=](const std::vector<std::shared_ptr<Value>>& values, bool expired) {
@@ -59,7 +37,7 @@ bindValueCb(ValueCallbackRaw raw_cb, void* user_data)
}
ShutdownCallback
bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data)
bindShutdownCb(const ShutdownCallbackRaw& shutdown_cb_raw, void* user_data)
{
return [=]() { shutdown_cb_raw(user_data); };
}
@@ -69,11 +47,11 @@ bindDoneCb(DoneCallbackSimple donecb)
{
if (not donecb) return {};
using namespace std::placeholders;
return std::bind(std::move(donecb), _1);
return std::bind(donecb, _1);
}
DoneCallback
bindDoneCb(DoneCallbackRaw raw_cb, void* user_data)
bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data)
{
if (not raw_cb) return {};
return [=](bool success, const std::vector<std::shared_ptr<Node>>& nodes) {
@@ -82,7 +60,7 @@ bindDoneCb(DoneCallbackRaw raw_cb, void* user_data)
}
DoneCallbackSimple
bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data) {
bindDoneCbSimple(const DoneCallbackSimpleRaw& raw_cb, void* user_data) {
if (not raw_cb) return {};
return [=](bool success) {
raw_cb(success, user_data);
@@ -94,7 +72,6 @@ NodeStats::toString() const
{
std::stringstream ss;
ss << "Known nodes: " << good_nodes << " good, " << dubious_nodes << " dubious, " << incoming_nodes << " incoming." << std::endl;
ss << searches << " searches, " << node_cache_size << " total cached nodes" << std::endl;
if (table_depth > 1) {
ss << "Routing table depth: " << table_depth << std::endl;
ss << "Network size estimation: " << getNetworkSizeEstimation() << " nodes" << std::endl;
@@ -144,7 +121,6 @@ NodeInfo::toJson() const
val["node_id"] = node_id.toString();
val["ipv4"] = ipv4.toJson();
val["ipv6"] = ipv6.toJson();
val["ops"] = Json::Value::LargestUInt(ongoing_ops);
return val;
}
@@ -155,7 +131,6 @@ NodeInfo::NodeInfo(const Json::Value& v)
node_id = InfoHash(v["node_id"].asString());
ipv4 = NodeStats(v["ipv4"]);
ipv6 = NodeStats(v["ipv6"]);
ongoing_ops = v["ops"].asLargestUInt();
}
#endif
-204
View File
@@ -1,204 +0,0 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "os_cert.h"
#include "log_enable.h"
#ifdef _WIN32
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")
#endif
#include <openssl/ssl.h>
#ifdef TARGET_OS_OSX
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#endif /*TARGET_OS_OSX*/
#if EMBEDDED_ASN1_TIME_PARSE
#undef X509_NAME
#undef OCSP_REQUEST
#undef OCSP_RESPONSE
#define GENTIME_LENGTH 15
#define UTCTIME_LENGTH 13
#define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0'))
extern "C" {
// Taken from libressl/src/crypto/asn1/a_time_tm.c
int
ASN1_time_parse(const char* bytes, size_t len, struct tm* tm, int mode)
{
size_t i;
int type = 0;
struct tm ltm;
struct tm* lt;
const char* p;
if (bytes == NULL)
return (-1);
/* Constrain to valid lengths. */
if (len != UTCTIME_LENGTH && len != GENTIME_LENGTH)
return (-1);
lt = tm;
if (lt == NULL) {
memset(&ltm, 0, sizeof(ltm));
lt = &ltm;
}
/* Timezone is required and must be GMT (Zulu). */
if (bytes[len - 1] != 'Z')
return (-1);
/* Make sure everything else is digits. */
for (i = 0; i < len - 1; i++) {
if (isdigit((unsigned char) bytes[i]))
continue;
return (-1);
}
/*
* Validate and convert the time
*/
p = bytes;
switch (len) {
case GENTIME_LENGTH:
if (mode == V_ASN1_UTCTIME)
return (-1);
lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */
type = V_ASN1_GENERALIZEDTIME;
/* FALLTHROUGH */
case UTCTIME_LENGTH:
if (type == 0) {
if (mode == V_ASN1_GENERALIZEDTIME)
return (-1);
type = V_ASN1_UTCTIME;
}
lt->tm_year += ATOI2(p); /* yy */
if (type == V_ASN1_UTCTIME) {
if (lt->tm_year < 50)
lt->tm_year += 100;
}
lt->tm_mon = ATOI2(p) - 1; /* mm */
if (lt->tm_mon < 0 || lt->tm_mon > 11)
return (-1);
lt->tm_mday = ATOI2(p); /* dd */
if (lt->tm_mday < 1 || lt->tm_mday > 31)
return (-1);
lt->tm_hour = ATOI2(p); /* HH */
if (lt->tm_hour < 0 || lt->tm_hour > 23)
return (-1);
lt->tm_min = ATOI2(p); /* MM */
if (lt->tm_min < 0 || lt->tm_min > 59)
return (-1);
lt->tm_sec = ATOI2(p); /* SS */
/* Leap second 60 is not accepted. Reconsider later? */
if (lt->tm_sec < 0 || lt->tm_sec > 59)
return (-1);
break;
default:
return (-1);
}
return type;
}
}
#endif /* EMBEDDED_ASN1_TIME_PARSE */
namespace dht {
namespace http {
PEMCache::PEMCache(const std::shared_ptr<Logger>& l)
: logger(l)
{
#ifdef _WIN32
PCCERT_CONTEXT pContext = NULL;
HCERTSTORE hSystemStore;
hSystemStore = CertOpenSystemStore(NULL, "ROOT");
if (!hSystemStore) {
if (logger)
logger->e("couldn't open the system cert store");
return;
}
while (pContext = CertEnumCertificatesInStore(hSystemStore, pContext)) {
const uint8_t* encoded_cert = pContext->pbCertEncoded;
X509Ptr x509cert(d2i_X509(nullptr, &encoded_cert, pContext->cbCertEncoded), &X509_free);
if (x509cert)
pems_.emplace_back(std::move(x509cert));
}
CertCloseStore(hSystemStore, 0);
#elif TARGET_OS_OSX
CFArrayRef result = NULL;
OSStatus osStatus;
if ((osStatus = SecTrustCopyAnchorCertificates(&result)) != 0) {
if (logger) {
CFStringRef statusString = SecCopyErrorMessageString(osStatus, NULL);
logger->d("Error enumerating certificates: %s",
CFStringGetCStringPtr(statusString, kCFStringEncodingASCII));
CFRelease(statusString);
}
if (result != NULL) {
CFRelease(result);
}
return;
}
CFDataRef rawData = NULL;
for (CFIndex i = 0; i < CFArrayGetCount(result); i++) {
SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(result, i);
rawData = SecCertificateCopyData(cert);
if (!rawData) {
if (logger)
logger->e("couldn't copy raw certificate data");
break;
}
const uint8_t* rawDataPtr = CFDataGetBytePtr(rawData);
X509Ptr x509cert(d2i_X509(nullptr, &rawDataPtr, CFDataGetLength(rawData)), &X509_free);
if (x509cert)
pems_.emplace_back(std::move(x509cert));
CFRelease(rawData);
rawData = NULL;
}
if (result != NULL) {
CFRelease(result);
}
if (rawData != NULL) {
CFRelease(rawData);
}
#endif /*TARGET_OS_OSX, _WIN32*/
}
void
PEMCache::fillX509Store(SSL_CTX* ctx)
{
if (logger)
logger->d("adding %d decoded certs to X509 store", pems_.size());
if (X509_STORE* store = SSL_CTX_get_cert_store(ctx)) {
for (const auto& pem : pems_) {
if (X509_STORE_add_cert(store, pem.get()) != 1)
if (logger)
logger->w("couldn't add local certificate");
}
} else if (logger)
logger->e("couldn't get the context cert store");
}
} /*namespace http*/
} /*namespace dht*/
-81
View File
@@ -1,81 +0,0 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "log_enable.h"
#include <memory>
#include <openssl/x509.h>
#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER > 0x20501000L))
#define EMBEDDED_ASN1_TIME_PARSE 0
#else
#define EMBEDDED_ASN1_TIME_PARSE 1
#endif
#if EMBEDDED_ASN1_TIME_PARSE
#define V_ASN1_UTCTIME 23
#define V_ASN1_GENERALIZEDTIME 24
extern "C" {
/*
* Parse an RFC 5280 format ASN.1 time string.
*
* mode must be:
* 0 if we expect to parse a time as specified in RFC 5280 for an X509 object.
* V_ASN1_UTCTIME if we wish to parse an RFC5280 format UTC time.
* V_ASN1_GENERALIZEDTIME if we wish to parse an RFC5280 format Generalized time.
*
* Returns:
* -1 if the string was invalid.
* V_ASN1_UTCTIME if the string validated as a UTC time string.
* V_ASN1_GENERALIZEDTIME if the string validated as a Generalized time string.
*
* Fills in *tm with the corresponding time if tm is non NULL.
*/
int ASN1_time_parse(const char* bytes, size_t len, struct tm* tm, int mode);
}
#endif
namespace dht {
namespace http {
// A singleton class used to cache the decoded certificates
// loaded from local cert stores that need to be added to the
// ssl context prior to each request.
class PEMCache
{
PEMCache(const std::shared_ptr<Logger>& l);
using X509Ptr = std::unique_ptr<X509, void(*)(X509*)>;
std::vector<X509Ptr> pems_;
std::shared_ptr<Logger> logger;
public:
static PEMCache& instance(const std::shared_ptr<Logger>& l)
{
static PEMCache instance_(l);
return instance_;
}
void fillX509Store(SSL_CTX* ctx);
};
}
} // namespace dht
+66 -355
View File
@@ -1,7 +1,6 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +25,6 @@ extern "C" {
#include <gnutls/x509.h>
#include <nettle/gcm.h>
#include <nettle/aes.h>
#include <gnutls/crypto.h>
#include <argon2.h>
}
@@ -54,9 +52,6 @@ static std::uniform_int_distribution<uint8_t> rand_byte;
#define GNUTLS_PKCS_PBES2_AES_256 GNUTLS_PKCS_USE_PBES2_AES_256
#endif
#define DHT_AES_LEGACY_ENCRYPT 0
#define DHT_AES_LEGACY_DECRYPT 1
namespace dht {
namespace crypto {
@@ -69,7 +64,7 @@ constexpr gnutls_digest_algorithm_t gnutlsHashAlgo(size_t min_res) {
GNUTLS_DIG_SHA1));
}
constexpr size_t gnutlsHashSize(gnutls_digest_algorithm_t algo) {
constexpr size_t gnutlsHashSize(int algo) {
return (algo == GNUTLS_DIG_SHA512) ? 512/8 : (
(algo == GNUTLS_DIG_SHA256) ? 256/8 : (
(algo == GNUTLS_DIG_SHA1) ? 160/8 : 0 ));
@@ -110,9 +105,6 @@ Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key)
struct gcm_aes_ctx aes;
gcm_aes_set_key(&aes, key.size(), key.data());
gcm_aes_set_iv(&aes, GCM_IV_SIZE, ret.data());
#if DHT_AES_LEGACY_ENCRYPT
gcm_aes_update(&aes, data_length, data);
#endif
gcm_aes_encrypt(&aes, data_length, ret.data() + GCM_IV_SIZE, data);
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, ret.data() + GCM_IV_SIZE + data_length);
@@ -128,53 +120,39 @@ Blob aesEncrypt(const Blob& data, const std::string& password)
return encrypted;
}
Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key)
Blob aesDecrypt(const Blob& data, const Blob& key)
{
if (not aesKeySizeGood(key.size()))
throw DecryptError("Wrong key size");
if (data_length <= GCM_IV_SIZE + GCM_DIGEST_SIZE)
if (data.size() <= GCM_IV_SIZE + GCM_DIGEST_SIZE)
throw DecryptError("Wrong data size");
std::array<uint8_t, GCM_DIGEST_SIZE> digest;
struct gcm_aes_ctx aes;
gcm_aes_set_key(&aes, key.size(), key.data());
gcm_aes_set_iv(&aes, GCM_IV_SIZE, data);
gcm_aes_set_iv(&aes, GCM_IV_SIZE, data.data());
size_t data_sz = data_length - GCM_IV_SIZE - GCM_DIGEST_SIZE;
size_t data_sz = data.size() - GCM_IV_SIZE - GCM_DIGEST_SIZE;
Blob ret(data_sz);
gcm_aes_decrypt(&aes, data_sz, ret.data(), data + GCM_IV_SIZE);
gcm_aes_decrypt(&aes, data_sz, ret.data(), data.data() + GCM_IV_SIZE);
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, digest.data());
if (not std::equal(digest.begin(), digest.end(), data + data_length - GCM_DIGEST_SIZE)) {
#if DHT_AES_LEGACY_DECRYPT
//gcm_aes_decrypt(&aes, data_sz, ret.data(), data + GCM_IV_SIZE);
Blob ret_tmp(data_sz);
struct gcm_aes_ctx aes_d;
gcm_aes_set_key(&aes_d, key.size(), key.data());
gcm_aes_set_iv(&aes_d, GCM_IV_SIZE, data);
gcm_aes_update(&aes_d, ret.size(), ret.data());
gcm_aes_encrypt(&aes_d, ret.size(), ret_tmp.data(), ret.data());
gcm_aes_digest(&aes_d, GCM_DIGEST_SIZE, digest.data());
if (not std::equal(digest.begin(), digest.end(), data + data_length - GCM_DIGEST_SIZE))
throw DecryptError("Can't decrypt data");
#else
if (not std::equal(digest.begin(), digest.end(), data.end() - GCM_DIGEST_SIZE))
throw DecryptError("Can't decrypt data");
#endif
}
return ret;
}
Blob aesDecrypt(const uint8_t* data, size_t data_len, const std::string& password)
Blob aesDecrypt(const Blob& data, const std::string& password)
{
if (data_len <= PASSWORD_SALT_LENGTH)
if (data.size() <= PASSWORD_SALT_LENGTH)
throw DecryptError("Wrong data size");
Blob salt {data, data+PASSWORD_SALT_LENGTH};
Blob salt {data.begin(), data.begin()+PASSWORD_SALT_LENGTH};
Blob key = stretchKey(password, salt, 256/8);
return aesDecrypt(data+PASSWORD_SALT_LENGTH, data_len - PASSWORD_SALT_LENGTH, key);
Blob encrypted {data.begin()+PASSWORD_SALT_LENGTH, data.end()};
return aesDecrypt(encrypted, key);
}
Blob stretchKey(const std::string& password, Blob& salt, size_t key_length)
@@ -291,14 +269,14 @@ PrivateKey::operator=(PrivateKey&& o) noexcept
}
Blob
PrivateKey::sign(const uint8_t* data, size_t data_length) const
PrivateKey::sign(const Blob& data) const
{
if (!key)
throw CryptoException("Can't sign data: no private key set !");
if (std::numeric_limits<unsigned>::max() < data_length)
if (std::numeric_limits<unsigned>::max() < data.size())
throw CryptoException("Can't sign data: too large !");
gnutls_datum_t sig;
const gnutls_datum_t dat {(unsigned char*)data, (unsigned)data_length};
const gnutls_datum_t dat {(unsigned char*)data.data(), (unsigned)data.size()};
if (gnutls_privkey_sign_data(key, GNUTLS_DIG_SHA512, 0, &dat, &sig) != GNUTLS_E_SUCCESS)
throw CryptoException("Can't sign data !");
Blob ret(sig.data, sig.data+sig.size);
@@ -320,7 +298,7 @@ PrivateKey::decryptBloc(const uint8_t* src, size_t src_size) const
}
Blob
PrivateKey::decrypt(const uint8_t* cypher, size_t cypher_len) const
PrivateKey::decrypt(const Blob& cipher) const
{
if (!key)
throw CryptoException("Can't decrypt data without private key !");
@@ -333,12 +311,12 @@ PrivateKey::decrypt(const uint8_t* cypher, size_t cypher_len) const
throw CryptoException("Must be an RSA key");
unsigned cypher_block_sz = key_len / 8;
if (cypher_len < cypher_block_sz)
if (cipher.size() < cypher_block_sz)
throw DecryptError("Unexpected cipher length");
else if (cypher_len == cypher_block_sz)
return decryptBloc(cypher, cypher_block_sz);
else if (cipher.size() == cypher_block_sz)
return decryptBloc(cipher.data(), cypher_block_sz);
return aesDecrypt(cypher + cypher_block_sz, cypher_len - cypher_block_sz, decryptBloc(cypher, cypher_block_sz));
return aesDecrypt(Blob {cipher.begin() + cypher_block_sz, cipher.end()}, decryptBloc(cipher.data(), cypher_block_sz));
}
Blob
@@ -349,7 +327,9 @@ PrivateKey::serialize(const std::string& password) const
size_t buf_sz = 8192;
Blob buffer;
buffer.resize(buf_sz);
auto err = serialize(buffer.data(), &buf_sz, password);
int err = password.empty()
? gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN, buffer.data(), &buf_sz)
: gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, buffer.data(), &buf_sz);
if (err != GNUTLS_E_SUCCESS) {
std::cerr << "Could not export private key - " << gnutls_strerror(err) << std::endl;
return {};
@@ -358,32 +338,13 @@ PrivateKey::serialize(const std::string& password) const
return buffer;
}
int
PrivateKey::serialize(uint8_t* out, size_t* out_len, const std::string& password) const
{
if (!x509_key)
return -1;
return password.empty()
? gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN, out, out_len)
: gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, out, out_len);
}
const PublicKey&
PublicKey
PrivateKey::getPublicKey() const
{
return *getSharedPublicKey();
}
const std::shared_ptr<PublicKey>&
PrivateKey::getSharedPublicKey() const
{
if (publicKey_)
return publicKey_;
auto pk = std::make_shared<PublicKey>();
if (auto err = gnutls_pubkey_import_privkey(pk->pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))
PublicKey pk;
if (auto err = gnutls_pubkey_import_privkey(pk.pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))
throw CryptoException(std::string("Can't retreive public key: ") + gnutls_strerror(err));
publicKey_ = pk;
return publicKey_;
return pk;
}
PublicKey::PublicKey()
@@ -392,9 +353,9 @@ PublicKey::PublicKey()
throw CryptoException(std::string("Can't initialize public key: ") + gnutls_strerror(err));
}
PublicKey::PublicKey(const uint8_t* dat, size_t dat_size) : PublicKey()
PublicKey::PublicKey(const Blob& dat) : PublicKey()
{
unpack(dat, dat_size);
unpack(dat.data(), dat.size());
}
PublicKey::~PublicKey()
@@ -422,18 +383,12 @@ PublicKey::pack(Blob& b) const
throw CryptoException(std::string("Could not export public key: null key"));
std::vector<uint8_t> tmp(2048);
size_t sz = tmp.size();
if (int err = pack(tmp.data(), &sz))
if (int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_DER, tmp.data(), &sz))
throw CryptoException(std::string("Could not export public key: ") + gnutls_strerror(err));
tmp.resize(sz);
b.insert(b.end(), tmp.begin(), tmp.end());
}
int
PublicKey::pack(uint8_t* out, size_t* out_len) const
{
return gnutls_pubkey_export(pk, GNUTLS_X509_FMT_DER, out, out_len);
}
void
PublicKey::unpack(const uint8_t* data, size_t data_size)
{
@@ -463,7 +418,7 @@ PublicKey::toString() const
}
void
PublicKey::msgpack_unpack(const msgpack::object& o)
PublicKey::msgpack_unpack(msgpack::object o)
{
if (o.type == msgpack::type::BIN)
unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
@@ -549,7 +504,12 @@ PublicKey::getId() const
return {};
InfoHash id;
size_t sz = id.size();
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
#if GNUTLS_VERSION_NUMBER < 0x030401
const int flags = 0;
#else
const int flags = (id.size() == 32) ? GNUTLS_KEYID_USE_SHA256 : 0;
#endif
if (auto err = gnutls_pubkey_get_key_id(pk, flags, id.data(), &sz))
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get public key ID: wrong output length.");
@@ -714,13 +674,13 @@ CertificateRequest::sign(const PrivateKey& key, const std::string& password)
}
bool
CertificateRequest::verify() const
CertificateRequest::verify() const
{
return gnutls_x509_crq_verify(request, 0) >= 0;
}
Blob
CertificateRequest::pack() const
Blob
CertificateRequest::pack() const
{
gnutls_datum_t dat {nullptr, 0};
if (auto err = gnutls_x509_crq_export2(request, GNUTLS_X509_FMT_PEM, &dat))
@@ -731,7 +691,7 @@ CertificateRequest::pack() const
}
std::string
CertificateRequest::toString() const
CertificateRequest::toString() const
{
gnutls_datum_t dat {nullptr, 0};
if (auto err = gnutls_x509_crq_export2(request, GNUTLS_X509_FMT_PEM, &dat))
@@ -803,7 +763,7 @@ Certificate::unpack(const uint8_t* dat, size_t dat_size)
}
void
Certificate::msgpack_unpack(const msgpack::object& o)
Certificate::msgpack_unpack(msgpack::object o)
{
if (o.type == msgpack::type::BIN)
unpack((const uint8_t*)o.via.bin.ptr, o.via.bin.size);
@@ -853,15 +813,12 @@ Certificate::getId() const
{
if (not cert)
return {};
if (cachedId_)
return cachedId_;
InfoHash id;
size_t sz = id.size();
if (auto err = gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz))
throw CryptoException(std::string("Can't get certificate public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get certificate public key ID: wrong output length.");
cachedId_ = id;
return id;
}
@@ -870,8 +827,6 @@ Certificate::getLongId() const
{
if (not cert)
return {};
if (cachedLongId_)
return cachedLongId_;
#if GNUTLS_VERSION_NUMBER < 0x030401
throw CryptoException("Can't get certificate 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
#else
@@ -881,23 +836,10 @@ Certificate::getLongId() const
throw CryptoException(std::string("Can't get certificate 256 bits public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get certificate 256 bits public key ID: wrong output length.");
cachedLongId_ = id;
return id;
#endif
}
Blob
Certificate::getSerialNumber() const
{
if (not cert)
return {};
// extract from certificate
unsigned char serial[64];
auto size = sizeof(serial);
gnutls_x509_crt_get_serial(cert, &serial, &size);
return {serial, serial + size};
}
std::string
Certificate::getName() const
{
@@ -1043,34 +985,6 @@ Certificate::getPreferredDigest() const
return getPublicKey().getPreferredDigest();
}
std::pair<std::string, Blob>
Certificate::generateOcspRequest(gnutls_x509_crt_t& issuer)
{
gnutls_ocsp_req_t rreq;
int err = gnutls_ocsp_req_init(&rreq);
if (err < 0)
throw CryptoException(gnutls_strerror(err));
std::unique_ptr<struct gnutls_ocsp_req_int, decltype(&gnutls_ocsp_req_deinit)> req(rreq, &gnutls_ocsp_req_deinit);
err = gnutls_ocsp_req_add_cert(req.get(), GNUTLS_DIG_SHA1, issuer, cert);
if (err < 0)
throw CryptoException(gnutls_strerror(err));
Blob noncebuf(32);
gnutls_datum_t nonce = { noncebuf.data(), (unsigned)noncebuf.size() };
err = gnutls_rnd(GNUTLS_RND_NONCE, nonce.data, nonce.size);
if (err < 0)
throw CryptoException(gnutls_strerror(err));
err = gnutls_ocsp_req_set_nonce(req.get(), 0, &nonce);
if (err < 0)
throw CryptoException(gnutls_strerror(err));
gnutls_datum_t rdata;
err = gnutls_ocsp_req_export(req.get(), &rdata);
if (err != 0)
throw CryptoException(gnutls_strerror(err));
std::string ret((char*)rdata.data, (char*)rdata.data + rdata.size);
gnutls_free(rdata.data);
return std::make_pair<std::string, Blob>(std::move(ret), std::move(noncebuf));
}
// PrivateKey
PrivateKey
@@ -1159,29 +1073,31 @@ void
setRandomSerial(gnutls_x509_crt_t cert)
{
random_device rdev;
std::uniform_int_distribution<int64_t> dist{1};
int64_t cert_serial = dist(rdev);
std::uniform_int_distribution<uint64_t> dist{};
uint64_t cert_serial = dist(rdev);
gnutls_x509_crt_set_serial(cert, &cert_serial, sizeof(cert_serial));
}
Certificate
Certificate::generate(const PrivateKey& key, const std::string& name, const Identity& ca, bool is_ca, int64_t validity)
Certificate::generate(const PrivateKey& key, const std::string& name, const Identity& ca, bool is_ca)
{
gnutls_x509_crt_t cert;
if (not key.x509_key or gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS)
return {};
Certificate ret {cert};
setValidityPeriod(cert, validity <= 0 ? 10 * 365 * 24 * 60 * 60 : validity);
if (int err = gnutls_x509_crt_set_key(cert, key.x509_key)) {
throw CryptoException(std::string("Error when setting certificate key ") + gnutls_strerror(err));
setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60);
if (gnutls_x509_crt_set_key(cert, key.x509_key) != GNUTLS_E_SUCCESS) {
std::cerr << "Error when setting certificate key" << std::endl;
return {};
}
if (int err = gnutls_x509_crt_set_version(cert, 3)) {
throw CryptoException(std::string("Error when setting certificate version ") + gnutls_strerror(err));
if (gnutls_x509_crt_set_version(cert, 3) != GNUTLS_E_SUCCESS) {
std::cerr << "Error when setting certificate version" << std::endl;
return {};
}
// TODO: compute the subject key using the recommended RFC method
const auto& pk = key.getPublicKey();
auto pk = key.getPublicKey();
auto pk_id = pk.getId();
const std::string uid_str = pk_id.toString();
@@ -1202,15 +1118,18 @@ Certificate::generate(const PrivateKey& key, const std::string& name, const Iden
if (ca.first && ca.second) {
if (not ca.second->isCA()) {
throw CryptoException("Signing certificate must be CA");
// Signing certificate must be CA.
return {};
}
if (int err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, pk.getPreferredDigest(), 0)) {
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
if (gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, pk.getPreferredDigest(), 0) != GNUTLS_E_SUCCESS) {
std::cerr << "Error when signing certificate" << std::endl;
return {};
}
ret.issuer = ca.second;
} else {
if (int err = gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0)) {
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
if (gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0) != GNUTLS_E_SUCCESS) {
std::cerr << "Error when signing certificate" << std::endl;
return {};
}
}
@@ -1218,7 +1137,7 @@ Certificate::generate(const PrivateKey& key, const std::string& name, const Iden
}
Certificate
Certificate::generate(const CertificateRequest& request, const Identity& ca, int64_t validity)
Certificate::generate(const CertificateRequest& request, const Identity& ca)
{
gnutls_x509_crt_t cert;
if (auto err = gnutls_x509_crt_init(&cert))
@@ -1231,7 +1150,7 @@ Certificate::generate(const CertificateRequest& request, const Identity& ca, int
throw CryptoException(std::string("Can't set certificate version: ") + gnutls_strerror(err));
}
setValidityPeriod(cert, validity <= 0 ? 10 * 365 * 24 * 60 * 60 : validity);
setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60);
setRandomSerial(cert);
if (auto err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, ca.second->getPreferredDigest(), 0)) {
@@ -1242,32 +1161,6 @@ Certificate::generate(const CertificateRequest& request, const Identity& ca, int
return ret.getPacked();
}
void
Certificate::setValidity(const Identity& ca, int64_t validity)
{
setValidityPeriod(cert, validity);
setRandomSerial(cert);
if (ca.first && ca.second) {
if (not ca.second->isCA()) {
throw CryptoException("Signing certificate must be CA");
}
if (int err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, ca.second->getPreferredDigest(), 0)) {
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
}
}
}
void
Certificate::setValidity(const PrivateKey& key, int64_t validity)
{
setValidityPeriod(cert, validity);
setRandomSerial(cert);
const auto& pk = key.getPublicKey();
if (int err = gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0)) {
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
}
}
std::vector<std::shared_ptr<RevocationList>>
Certificate::getRevocationLists() const
{
@@ -1278,188 +1171,6 @@ Certificate::getRevocationLists() const
return ret;
}
// OcspRequest
OcspRequest::OcspRequest(const uint8_t* dat_ptr, size_t dat_size)
{
int ret = gnutls_ocsp_req_init(&request);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
gnutls_datum_t dat = {(unsigned char*)dat_ptr,(unsigned int)dat_size};
ret = gnutls_ocsp_req_import(request, &dat);
if (ret < 0){
gnutls_ocsp_req_deinit(request);
throw CryptoException(gnutls_strerror(ret));
}
}
OcspRequest::~OcspRequest()
{
if (request) {
gnutls_ocsp_req_deinit(request);
request = nullptr;
}
}
std::string
OcspRequest::toString(const bool compact) const
{
int ret;
gnutls_datum_t dat;
ret = gnutls_ocsp_req_print(request, compact ? GNUTLS_OCSP_PRINT_COMPACT : GNUTLS_OCSP_PRINT_FULL, &dat);
std::string str;
if (ret == 0) {
str = std::string((const char*)dat.data, (size_t)dat.size);
gnutls_free(dat.data);
} else
throw CryptoException(gnutls_strerror(ret));
return str;
}
Blob
OcspRequest::pack() const
{
gnutls_datum_t dat;
int err = gnutls_ocsp_req_export(request, &dat);
if (err < 0)
throw CryptoException(gnutls_strerror(err));
Blob ret {dat.data, dat.data + dat.size};
gnutls_free(dat.data);
return ret;
}
Blob
OcspRequest::getNonce() const
{
gnutls_datum_t dat;
unsigned critical;
int err = gnutls_ocsp_req_get_nonce(request, &critical, &dat);
if (err < 0)
throw CryptoException(gnutls_strerror(err));
Blob ret {dat.data, dat.data + dat.size};
gnutls_free(dat.data);
return ret;
}
// OcspResponse
OcspResponse::OcspResponse(const uint8_t* dat_ptr, size_t dat_size)
{
int ret = gnutls_ocsp_resp_init(&response);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
gnutls_datum_t dat = {(unsigned char*)dat_ptr,(unsigned int)dat_size};
ret = gnutls_ocsp_resp_import(response, &dat);
if (ret < 0){
gnutls_ocsp_resp_deinit(response);
throw CryptoException(gnutls_strerror(ret));
}
}
OcspResponse::~OcspResponse()
{
gnutls_ocsp_resp_deinit(response);
}
Blob
OcspResponse::pack() const
{
gnutls_datum_t dat;
int err = gnutls_ocsp_resp_export(response, &dat);
if (err < 0)
throw CryptoException(gnutls_strerror(err));
Blob ret {dat.data, dat.data + dat.size};
gnutls_free(dat.data);
return ret;
}
std::string
OcspResponse::toString(const bool compact) const
{
int ret;
std::string str;
gnutls_datum_t dat;
ret = gnutls_ocsp_resp_print(response, compact ? GNUTLS_OCSP_PRINT_COMPACT : GNUTLS_OCSP_PRINT_FULL, &dat);
if (ret == 0)
str = std::string((const char*)dat.data, (size_t)dat.size);
gnutls_free(dat.data);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
return str;
}
gnutls_ocsp_cert_status_t
OcspResponse::getCertificateStatus() const
{
int ret;
unsigned int status;
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status, NULL, NULL, NULL, NULL);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
return (gnutls_ocsp_cert_status_t) status;
}
gnutls_ocsp_cert_status_t
OcspResponse::verifyDirect(const Certificate& crt, const Blob& nonce)
{
// Check OCSP response
int ret = gnutls_ocsp_resp_get_status(response);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
gnutls_ocsp_resp_status_t status = (gnutls_ocsp_resp_status_t)ret;
if (status != GNUTLS_OCSP_RESP_SUCCESSFUL)
throw CryptoException("OCSP request unsuccessful: " + std::to_string(ret));
if (not nonce.empty()) {
// Ensure no replay attack has been done
gnutls_datum_t rnonce;
ret = gnutls_ocsp_resp_get_nonce(response, NULL, &rnonce);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
if (rnonce.size != nonce.size() || memcmp(nonce.data(), rnonce.data, nonce.size()) != 0){
gnutls_free(rnonce.data);
throw CryptoException(gnutls_strerror(GNUTLS_E_OCSP_RESPONSE_ERROR));
}
gnutls_free(rnonce.data);
}
// Verify signature of the Basic OCSP response against the public key in the issuer certificate.
unsigned int verify = 0;
ret = gnutls_ocsp_resp_verify_direct(response, crt.issuer->cert, &verify, 0);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
if (verify) {
if (verify & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
throw CryptoException("Signer cert not found");
if (verify & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
throw CryptoException("Signer cert keyusage error");
if (verify & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
throw CryptoException("Signer cert is not trusted");
if (verify & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
throw CryptoException("Insecure algorithm");
if (verify & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
throw CryptoException("Signature failure");
if (verify & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
throw CryptoException("Signer cert not yet activated");
if (verify & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
throw CryptoException("Signer cert expired");
throw CryptoException(gnutls_strerror(GNUTLS_E_OCSP_RESPONSE_ERROR));
}
// Check whether the OCSP response is about the provided certificate.
if ((ret = gnutls_ocsp_resp_check_crt(response, 0, crt.cert)) < 0)
throw CryptoException(gnutls_strerror(ret));
// Check certificate revocation status
unsigned status_ocsp;
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status_ocsp, NULL, NULL, NULL, NULL);
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
return (gnutls_ocsp_cert_status_t)status_ocsp;
}
// RevocationList
RevocationList::RevocationList()
@@ -1475,7 +1186,7 @@ RevocationList::RevocationList(const Blob& b)
} catch (const std::exception& e) {
gnutls_x509_crl_deinit(crl);
crl = nullptr;
throw;
throw e;
}
}
@@ -1512,7 +1223,7 @@ RevocationList::unpack(const uint8_t* dat, size_t dat_size)
}
void
RevocationList::msgpack_unpack(const msgpack::object& o)
RevocationList::msgpack_unpack(msgpack::object o)
{
try {
if (o.type == msgpack::type::BIN)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
+373 -569
View File
File diff suppressed because it is too large. Load diff
Loaded 100 of 157 files, more files were not shown because too many files have changed in this diff. Show more