mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 20:37:23 +00:00
Compare commits
103
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed18fa915e | ||
|
|
8b91c24414 | ||
|
|
dbebaae1f3 | ||
|
|
7cc743ff5e | ||
|
|
3b02cee495 | ||
|
|
2e520bea4f | ||
|
|
f9f57b50b1 | ||
|
|
fb9e6eee48 | ||
|
|
b53af75a7f | ||
|
|
2ed40aeefe | ||
|
|
bb61b8468b | ||
|
|
55688a25aa | ||
|
|
21fd58a39c | ||
|
|
ae56d4e9be | ||
|
|
982896a718 | ||
|
|
2ae092e266 | ||
|
|
27ce8b00ed | ||
|
|
3a8adb4e17 | ||
|
|
899d18968e | ||
|
|
285105c8d1 | ||
|
|
9e0ad9d926 | ||
|
|
0fdded0606 | ||
|
|
9947172abb | ||
|
|
b034a823a9 | ||
|
|
7baee925f6 | ||
|
|
ed6c5381d8 | ||
|
|
d58e4c8a89 | ||
|
|
2f2ed9bca7 | ||
|
|
3e888d8e2d | ||
|
|
f461eaa191 | ||
|
|
411d8dbe62 | ||
|
|
825cf98bf4 | ||
|
|
aff1ed4575 | ||
|
|
6b1e7513b3 | ||
|
|
8c94dc8f89 | ||
|
|
a7f459eab9 | ||
|
|
7383e3ea29 | ||
|
|
a416d472fb | ||
|
|
8fb707824e | ||
|
|
e646636bde | ||
|
|
fafd2f0233 | ||
|
|
9f031303a2 | ||
|
|
9a2e69ea9c | ||
|
|
54eff3b0aa | ||
|
|
817a5baef2 | ||
|
|
79dfc0403a | ||
|
|
675d892fc1 | ||
|
|
2654970499 | ||
|
|
b3c5c2fcfa | ||
|
|
6919df592f | ||
|
|
6cfede0868 | ||
|
|
e176e4baa6 | ||
|
|
4041b69800 | ||
|
|
da6579132c | ||
|
|
24628ff13d | ||
|
|
d2f29b72c3 | ||
|
|
546a960951 | ||
|
|
27978f3b9f | ||
|
|
a831afdc1e | ||
|
|
13bb50b863 | ||
|
|
d16d30c483 | ||
|
|
4480436cb3 | ||
|
|
d4114830be | ||
|
|
9fbac2707d | ||
|
|
7cdd6948bf | ||
|
|
d9c5ff9624 | ||
|
|
47691b8242 | ||
|
|
adf57ce2f0 | ||
|
|
aea84977fd | ||
|
|
2f1aef272a | ||
|
|
76089d09a4 | ||
|
|
f88f99959b | ||
|
|
dc6aca83c6 | ||
|
|
b0e18e9ca4 | ||
|
|
8516e35e5f | ||
|
|
41eabc7261 | ||
|
|
424fe61a49 | ||
|
|
02e03771d4 | ||
|
|
e35f8c29ee | ||
|
|
64e3bcf0dc | ||
|
|
a9f3883bfa | ||
|
|
3c3b3dc303 | ||
|
|
970e71d215 | ||
|
|
b6552ec300 | ||
|
|
58bc772256 | ||
|
|
31af08feaa | ||
|
|
9e60a681f3 | ||
|
|
51525d144b | ||
|
|
965fbb43c7 | ||
|
|
133d77d985 | ||
|
|
9451861f51 | ||
|
|
4b489fb7d7 | ||
|
|
7fcaf19ca3 | ||
|
|
c51d59a3a3 | ||
|
|
bcc02837d3 | ||
|
|
611017e187 | ||
|
|
7f7bff6a28 | ||
|
|
b9d7957bf6 | ||
|
|
fa31cec73e | ||
|
|
550a8cf362 | ||
|
|
50996eaf7e | ||
|
|
813c3b43d2 | ||
|
|
4ce9292b28 |
No files matched your search
+31
-23
@@ -4,55 +4,63 @@ on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-ubuntu:
|
||||
name: Ubuntu/GCC build
|
||||
name: Ubuntu/GCC Autotools build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: deps
|
||||
- name: Dependencies
|
||||
run: |
|
||||
sudo apt install libncurses5-dev libreadline-dev nettle-dev \
|
||||
sudo apt install libncurses5-dev libreadline-dev nettle-dev libasio-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
|
||||
- name: Configure
|
||||
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
|
||||
./autogen.sh
|
||||
./configure
|
||||
- name: Build
|
||||
run: make
|
||||
- name: make check
|
||||
run: make check
|
||||
|
||||
build-ubuntu-meson:
|
||||
name: Ubuntu/GCC Meson build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Dependencies
|
||||
run: |
|
||||
sudo apt install meson ninja-build libncurses5-dev libreadline-dev nettle-dev libasio-dev \
|
||||
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
|
||||
libfmt-dev libhttp-parser-dev libmsgpack-dev libargon2-0-dev
|
||||
- name: Configure
|
||||
run: meson setup build .
|
||||
- name: Build
|
||||
run: cd build && ninja
|
||||
|
||||
build-ubuntu-minimal:
|
||||
name: Ubuntu/GCC minimal build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: deps
|
||||
- name: Dependencies
|
||||
run: |
|
||||
sudo apt install libncurses5-dev libreadline-dev nettle-dev \
|
||||
sudo apt install libncurses5-dev libreadline-dev nettle-dev libfmt-dev \
|
||||
libgnutls28-dev libcppunit-dev libmsgpack-dev libargon2-0-dev
|
||||
- name: cmake
|
||||
- name: Configure
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Debug \
|
||||
-DOPENDHT_C=Off -DOPENDHT_TESTS=On -DOPENDHT_PEER_DISCOVERY=Off -DOPENDHT_PYTHON=Off \
|
||||
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=Off -DOPENDHT_PROXY_CLIENT=Off
|
||||
- name: make
|
||||
- name: Build
|
||||
run: cd build && make
|
||||
- name: Unit tests
|
||||
run: cd build && ./opendht_unit_tests
|
||||
|
||||
build-macos:
|
||||
name: macOS/Clang build
|
||||
runs-on: macos-11
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: deps
|
||||
- name: Dependencies
|
||||
run: |
|
||||
brew install msgpack-cxx asio gnutls nettle readline fmt jsoncpp argon2 openssl http-parser cppunit
|
||||
|
||||
@@ -68,7 +76,7 @@ jobs:
|
||||
make -j8 && sudo make install
|
||||
cd ../../.. && rm -rf restinio
|
||||
|
||||
- name: cmake
|
||||
- name: Configure
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"
|
||||
@@ -79,6 +87,6 @@ jobs:
|
||||
-DOPENDHT_C=On -DOPENDHT_TESTS=On -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off \
|
||||
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On -DOPENDHT_PUSH_NOTIFICATIONS=On
|
||||
|
||||
- name: make
|
||||
- name: Build
|
||||
run: cd build && make
|
||||
|
||||
@@ -12,6 +12,8 @@ env:
|
||||
IMAGE_NAME_DEPS_LLVM: ${{ github.repository }}/opendht-deps-llvm
|
||||
IMAGE_NAME_LLVM: ${{ github.repository }}/opendht-llvm
|
||||
IMAGE_NAME_DHTNODE: ${{ github.repository }}/dhtnode
|
||||
IMAGE_NAME_ALPINE: ${{ github.repository }}/opendht-alpine
|
||||
IMAGE_NAME_ALPINE_DEPS: ${{ github.repository }}/opendht-deps-alpine
|
||||
|
||||
jobs:
|
||||
build-and-push-deps-image:
|
||||
@@ -182,6 +184,74 @@ jobs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-and-push-image-alpine-deps:
|
||||
name: Alpine Deps Docker image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_ALPINE_DEPS }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileDepsAlpine
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-and-push-image-alpine:
|
||||
name: Alpine Docker image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_ALPINE }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileAlpine
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-python-wheel:
|
||||
name: Release and build Python Wheel package
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
+68
-100
@@ -12,17 +12,17 @@ include(CMakeDependentOption)
|
||||
include(CheckIncludeFileCXX)
|
||||
include(FindPkgConfig)
|
||||
include(cmake/CheckAtomic.cmake)
|
||||
include(CTest)
|
||||
|
||||
set (opendht_VERSION_MAJOR 2)
|
||||
set (opendht_VERSION_MINOR 4.12)
|
||||
set (opendht_VERSION_MINOR 6.0)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
|
||||
# Options
|
||||
option (OPENDHT_STATIC "Build static library" ON)
|
||||
option (OPENDHT_SHARED "Build shared library" ON)
|
||||
option (OPENDHT_LOG "Build with logs" ON)
|
||||
option (BUILD_SHARED_LIBS "Build shared library" ON)
|
||||
CMAKE_DEPENDENT_OPTION (OPENDHT_STATIC "Build static library" OFF BUILD_SHARED_LIBS ON)
|
||||
option (OPENDHT_PYTHON "Build Python bindings" OFF)
|
||||
option (OPENDHT_TOOLS "Build DHT tools" ON)
|
||||
option (OPENDHT_SYSTEMD "Install systemd module" OFF)
|
||||
@@ -36,7 +36,6 @@ 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_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)
|
||||
|
||||
@@ -59,7 +58,16 @@ if (NOT MSVC)
|
||||
find_package (PkgConfig REQUIRED)
|
||||
pkg_search_module (GnuTLS REQUIRED IMPORTED_TARGET gnutls)
|
||||
pkg_search_module (Nettle REQUIRED IMPORTED_TARGET nettle)
|
||||
find_package (msgpack REQUIRED NAMES msgpackc-cxx msgpack msgpack-cxx)
|
||||
check_include_file_cxx(msgpack.hpp HAVE_MSGPACKCXX)
|
||||
if (NOT HAVE_MSGPACKCXX)
|
||||
find_package(msgpack QUIET CONFIG NAMES msgpack msgpackc-cxx)
|
||||
if (NOT msgpack_FOUND)
|
||||
find_package(msgpack REQUIRED CONFIG NAMES msgpack-cxx)
|
||||
set(MSGPACK_TARGET "msgpack-cxx")
|
||||
else()
|
||||
set(MSGPACK_TARGET "msgpackc-cxx")
|
||||
endif()
|
||||
endif()
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
@@ -79,10 +87,10 @@ if (NOT MSVC)
|
||||
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED)
|
||||
endif ()
|
||||
|
||||
find_package(fmt)
|
||||
|
||||
if (OPENDHT_HTTP)
|
||||
find_package(Restinio REQUIRED)
|
||||
find_library(FMT_LIBRARY fmt)
|
||||
add_library(fmt SHARED IMPORTED)
|
||||
find_library(HTTP_PARSER_LIBRARY http_parser)
|
||||
add_library(http_parser SHARED IMPORTED)
|
||||
set(http_parser_lib "-lhttp_parser")
|
||||
@@ -132,6 +140,7 @@ if (NOT MSVC)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type -Wno-deprecated -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
|
||||
if (OPENDHT_SANITIZE)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-protector-strong")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fstack-protector-strong")
|
||||
endif ()
|
||||
else ()
|
||||
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
@@ -145,15 +154,7 @@ else ()
|
||||
endif ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif ()
|
||||
add_definitions(-DPACKAGE_VERSION="${opendht_VERSION}")
|
||||
if (OPENDHT_LOG)
|
||||
add_definitions(-DOPENDHT_LOG=true)
|
||||
else ()
|
||||
add_definitions(-DOPENDHT_LOG=false)
|
||||
endif()
|
||||
|
||||
if (ASIO_INCLUDE_DIR)
|
||||
include_directories (SYSTEM "${ASIO_INCLUDE_DIR}")
|
||||
@@ -172,8 +173,8 @@ include_directories (
|
||||
include (GNUInstallDirs)
|
||||
set (prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set (exec_prefix "\${prefix}")
|
||||
set (libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set (includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set (libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
|
||||
set (includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
||||
set (bindir "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||
set (sysconfdir "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
|
||||
set (top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
@@ -181,7 +182,6 @@ set (top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
# Sources
|
||||
list (APPEND opendht_SOURCES
|
||||
src/utils.cpp
|
||||
src/infohash.cpp
|
||||
src/crypto.cpp
|
||||
src/default_types.cpp
|
||||
src/node.cpp
|
||||
@@ -227,7 +227,7 @@ list (APPEND opendht_HEADERS
|
||||
include/opendht/rate_limiter.h
|
||||
include/opendht/securedht.h
|
||||
include/opendht/log.h
|
||||
include/opendht/log_enable.h
|
||||
include/opendht/logger.h
|
||||
include/opendht/thread_pool.h
|
||||
include/opendht/network_utils.h
|
||||
include/opendht.h
|
||||
@@ -293,28 +293,8 @@ if (MSVC)
|
||||
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 PkgConfig::argon2
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} PkgConfig::GnuTLS PkgConfig::Nettle msgpackc-cxx
|
||||
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
|
||||
if (Jsoncpp_FOUND)
|
||||
target_link_libraries(opendht-static PUBLIC PkgConfig::Jsoncpp)
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht-static PUBLIC PkgConfig::OPENSSL)
|
||||
endif()
|
||||
if (APPLE)
|
||||
target_link_libraries(opendht-static PRIVATE SYSTEM "-framework CoreFoundation" "-framework Security")
|
||||
endif()
|
||||
else ()
|
||||
if (MSVC)
|
||||
if (OPENDHT_STATIC)
|
||||
if (OPENDHT_TOOLS)
|
||||
function (add_obj_lib name libfile)
|
||||
add_library(${name} OBJECT IMPORTED)
|
||||
@@ -353,64 +333,63 @@ if (OPENDHT_STATIC)
|
||||
${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()
|
||||
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_SHARED)
|
||||
add_library (opendht SHARED
|
||||
${opendht_SOURCES}
|
||||
${opendht_HEADERS}
|
||||
)
|
||||
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)
|
||||
add_library (opendht
|
||||
${opendht_SOURCES}
|
||||
${opendht_HEADERS}
|
||||
${obj_libs}
|
||||
)
|
||||
set_target_properties (opendht PROPERTIES OUTPUT_NAME "opendht")
|
||||
|
||||
if (NOT HAVE_MSGPACKCXX)
|
||||
target_link_libraries(opendht PUBLIC ${MSGPACK_TARGET})
|
||||
endif()
|
||||
if (APPLE)
|
||||
target_link_libraries(opendht PRIVATE "-framework CoreFoundation" "-framework Security")
|
||||
endif()
|
||||
if (MSVC)
|
||||
if (OPENDHT_STATIC)
|
||||
target_link_libraries(opendht PUBLIC ${Win32_STATIC_LIBRARIES} ${Win32_IMPORT_LIBRARIES})
|
||||
set_target_properties (opendht PROPERTIES OUTPUT_NAME "libopendht")
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(opendht
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} msgpackc-cxx
|
||||
PRIVATE PkgConfig::GnuTLS PkgConfig::Nettle
|
||||
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} PkgConfig::argon2)
|
||||
PRIVATE
|
||||
PkgConfig::argon2
|
||||
PkgConfig::Nettle
|
||||
${HTTP_PARSER_LIBRARY}
|
||||
PUBLIC
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
PkgConfig::GnuTLS
|
||||
fmt::fmt
|
||||
)
|
||||
if (Jsoncpp_FOUND)
|
||||
target_link_libraries(opendht PUBLIC PkgConfig::Jsoncpp)
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht PUBLIC PkgConfig::OPENSSL)
|
||||
endif()
|
||||
if (APPLE)
|
||||
target_link_libraries(opendht PRIVATE SYSTEM "-framework CoreFoundation" "-framework Security")
|
||||
endif ()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
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)
|
||||
endif ()
|
||||
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
|
||||
if (OPENDHT_C)
|
||||
if (OPENDHT_SHARED)
|
||||
add_library (opendht-c SHARED
|
||||
c/opendht.cpp
|
||||
c/opendht_c.h
|
||||
)
|
||||
target_compile_definitions(opendht-c PRIVATE OPENDHT_C_BUILD)
|
||||
target_link_libraries(opendht-c PRIVATE opendht)
|
||||
set_target_properties (opendht-c PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
install (TARGETS opendht-c DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht-c)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_STATIC)
|
||||
add_library (opendht-c-static STATIC
|
||||
c/opendht.cpp
|
||||
c/opendht_c.h
|
||||
)
|
||||
set_target_properties (opendht-c-static PROPERTIES OUTPUT_NAME "opendht-c")
|
||||
target_link_libraries(opendht-c-static PRIVATE opendht-static)
|
||||
install (TARGETS opendht-c-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht-c-static)
|
||||
endif ()
|
||||
add_library (opendht-c
|
||||
c/opendht.cpp
|
||||
c/opendht_c.h
|
||||
)
|
||||
target_compile_definitions(opendht-c PRIVATE OPENDHT_C_BUILD)
|
||||
target_link_libraries(opendht-c PRIVATE opendht)
|
||||
set_target_properties (opendht-c PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
install (TARGETS opendht-c DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht-c)
|
||||
|
||||
# PkgConfig module
|
||||
configure_file (
|
||||
@@ -450,7 +429,7 @@ install (EXPORT opendht DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht FILE o
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht)
|
||||
|
||||
# Unit tests
|
||||
if (OPENDHT_TESTS)
|
||||
if (BUILD_TESTING AND NOT MSVC)
|
||||
pkg_search_module(Cppunit REQUIRED IMPORTED_TARGET cppunit)
|
||||
# unit testing
|
||||
list (APPEND test_FILES
|
||||
@@ -485,21 +464,10 @@ if (OPENDHT_TESTS)
|
||||
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})
|
||||
if (OPENDHT_SHARED)
|
||||
target_link_libraries(opendht_unit_tests opendht)
|
||||
else ()
|
||||
target_link_libraries(opendht_unit_tests opendht-static)
|
||||
endif ()
|
||||
target_link_libraries(opendht_unit_tests
|
||||
target_link_libraries(opendht_unit_tests PRIVATE
|
||||
opendht
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
PkgConfig::Cppunit
|
||||
${GNUTLS_LIBRARIES}
|
||||
)
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht_unit_tests PkgConfig::OPENSSL)
|
||||
endif()
|
||||
enable_testing()
|
||||
add_test(TEST opendht_unit_tests)
|
||||
endif()
|
||||
@@ -21,15 +21,15 @@ Values are distributed over the network, with redundancy.
|
||||
## Documentation
|
||||
See the wiki: <https://github.com/savoirfairelinux/opendht/wiki>
|
||||
|
||||
#### How to run a node
|
||||
|
||||
You can help contributing to the public network by running a stable node with a public IP address.
|
||||
https://github.com/savoirfairelinux/opendht/wiki/Running-a-node-with-dhtnode
|
||||
|
||||
#### How-to build and install
|
||||
|
||||
Build instructions: <https://github.com/savoirfairelinux/opendht/wiki/Build-the-library>
|
||||
|
||||
#### How-to build a simple client app
|
||||
```bash
|
||||
g++ main.cpp -std=c++17 -lopendht
|
||||
```
|
||||
|
||||
## Examples
|
||||
### C++ example
|
||||
The `tools` directory includes simple example programs :
|
||||
@@ -96,17 +96,18 @@ for r in results:
|
||||
- msgpack-c 1.2+, used for data serialization.
|
||||
- GnuTLS 3.3+, used for cryptographic operations.
|
||||
- Nettle 2.4+, a GnuTLS dependency for crypto.
|
||||
- {fmt} 9.0+, for log formatting.
|
||||
- (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 Microsoft Visual Studio 2019, 2022
|
||||
|
||||
## Contact
|
||||
|
||||
IRC: join us on Libera.chat at [`#opendht`](https://web.libera.chat/#opendht).
|
||||
|
||||
## License
|
||||
Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
Copyright (C) 2014-2023 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.
|
||||
|
||||
@@ -117,6 +118,3 @@ See COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html for the full GPLv3 l
|
||||
## Acknowledgements
|
||||
This project was originally based on https://github.com/jech/dht by Juliusz Chroboczek.
|
||||
It is independent from another project called OpenDHT (Sean Rhea. Ph.D. Thesis, 2005), now extinct.
|
||||
|
||||
## Donations
|
||||
We gratefully accept Bitcoin donations to support OpenDHT development at: `bitcoin:3EykSd1An888efq4Bq3KaV3hJ3JQ4FPnwm`.
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -261,7 +261,7 @@ dht_pkid dht_certificate_get_long_id(const dht_certificate* c) {
|
||||
|
||||
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())));
|
||||
return reinterpret_cast<dht_publickey*>(new PubkeySp(cert->getSharedPublicKey()));
|
||||
}
|
||||
|
||||
// dht::crypto::Identity
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+9
-14
@@ -1,7 +1,7 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 2)
|
||||
m4_define([opendht_minor_version], 4)
|
||||
m4_define([opendht_patch_version], 12)
|
||||
m4_define([opendht_minor_version], 6)
|
||||
m4_define([opendht_patch_version], 0)
|
||||
m4_define([opendht_version],
|
||||
[opendht_major_version.opendht_minor_version.opendht_patch_version])
|
||||
|
||||
@@ -34,12 +34,6 @@ AC_LANG(C++)
|
||||
AC_PROG_CXX
|
||||
AX_CXX_COMPILE_STDCXX(17,[noext],[mandatory])
|
||||
|
||||
dnl Check for logs
|
||||
AC_ARG_ENABLE([logs], [AS_HELP_STRING([--disable-logs], [Disable DHT logs])])
|
||||
AS_IF([test "x$enable_logs" != "xno"], [], [
|
||||
AC_DEFINE([OPENDHT_LOG], [false], [Define if DHT logs are disabled])
|
||||
])
|
||||
|
||||
dnl Check for C binding
|
||||
AC_ARG_ENABLE([c], [AS_HELP_STRING([--disable-c], [Disable DHT C binding])])
|
||||
AM_CONDITIONAL(ENABLE_C, test x$enable_c != "xno")
|
||||
@@ -171,15 +165,16 @@ AS_IF([test "x$have_openssl" = "xyes"], [
|
||||
AC_MSG_NOTICE([Not using OpenSSL])
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([Fmt], [fmt >= 5.3.0], [have_fmt=yes], [have_fmt=no])
|
||||
AS_IF([test "x$have_fmt" = "xyes"], [
|
||||
AC_MSG_NOTICE([Using libfmt])
|
||||
], [
|
||||
AC_MSG_NOTICE([Missing libfmt files])
|
||||
])
|
||||
|
||||
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
|
||||
AC_CHECK_HEADERS([asio.hpp],, AC_MSG_ERROR([Missing Asio headers files]))
|
||||
CXXFLAGS="${CXXFLAGS} -DASIO_STANDALONE"
|
||||
PKG_CHECK_MODULES([Fmt], [fmt >= 5.3.0], [have_fmt=yes], [have_fmt=no])
|
||||
AS_IF([test "x$have_fmt" = "xyes"], [
|
||||
AC_MSG_NOTICE([Using libfmt])
|
||||
], [
|
||||
AC_MSG_NOTICE([Missing libfmt files])
|
||||
])
|
||||
# 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;])
|
||||
|
||||
+2
-1
@@ -19,7 +19,7 @@
|
||||
.SH DESCRIPTION
|
||||
Runs an OpenDHT node, with a CLI (default) or as a daemon (with \fB'-d'\fP or \fB'-s'\fP).
|
||||
Commands available in the interactive shell are:
|
||||
.EE
|
||||
.EX
|
||||
h, help Print this help message.
|
||||
q, quit Quit the program.
|
||||
log Start/stop printing DHT logs.
|
||||
@@ -39,6 +39,7 @@ Commands available in the interactive shell are:
|
||||
private key.
|
||||
e [key] [dest] [str] Put string value at [key], encrypted for [dest] with
|
||||
its public key (if found).
|
||||
.EE
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-h\fP
|
||||
|
||||
+3
-2
@@ -2,8 +2,9 @@ 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
|
||||
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
COPY . opendht
|
||||
|
||||
RUN cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-alpine:latest AS build
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
COPY . opendht
|
||||
|
||||
RUN mkdir /install
|
||||
ENV DESTDIR /install
|
||||
|
||||
RUN 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 \
|
||||
-DOPENDHT_SYSTEMD=On \
|
||||
&& make -j8 && make install
|
||||
|
||||
FROM alpine:3.18 AS install
|
||||
COPY --from=build /install /
|
||||
RUN apk add --no-cache \
|
||||
libstdc++ \
|
||||
gnutls \
|
||||
nettle \
|
||||
openssl \
|
||||
argon2-dev \
|
||||
jsoncpp \
|
||||
fmt \
|
||||
http-parser \
|
||||
readline \
|
||||
ncurses
|
||||
CMD ["dhtnode", "-b", "bootstrap.jami.net", "-p", "4222", "--proxyserver", "8080"]
|
||||
EXPOSE 4222/udp
|
||||
EXPOSE 8080/tcp
|
||||
@@ -2,8 +2,9 @@ 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 \
|
||||
COPY . opendht
|
||||
|
||||
RUN cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
FROM alpine:3.18
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apk add --no-cache \
|
||||
build-base cmake ninja git wget \
|
||||
cython python3-dev py3-setuptools \
|
||||
ncurses-dev readline-dev nettle-dev \
|
||||
cppunit-dev gnutls-dev jsoncpp-dev \
|
||||
argon2-dev openssl-dev fmt-dev \
|
||||
http-parser-dev asio-dev msgpack-cxx-dev \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/aberaud/restinio/archive/bbaa034dbcc7555ce67df0f8a1475591a7441733.tar.gz \
|
||||
&& tar -xzf bbaa034dbcc7555ce67df0f8a1475591a7441733.tar.gz \
|
||||
&& cd restinio-bbaa034dbcc7555ce67df0f8a1475591a7441733/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
|
||||
@@ -2,8 +2,9 @@ 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 \
|
||||
COPY . opendht
|
||||
|
||||
RUN cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
|
||||
@@ -2,8 +2,9 @@ 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 \
|
||||
COPY . opendht
|
||||
|
||||
RUN cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -170,19 +170,19 @@ using ValueCallback = std::function<bool(const std::vector<std::shared_ptr<Value
|
||||
using GetCallbackSimple = std::function<bool(std::shared_ptr<Value> value)>;
|
||||
using ShutdownCallback = std::function<void()>;
|
||||
using IdentityAnnouncedCb = std::function<void(bool)>;
|
||||
using PublicAddressChangedCb = std::function<void(std::vector<SockAddr>)>;
|
||||
|
||||
using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::Certificate>>(const InfoHash& pk_id)>;
|
||||
using DoneCallback = std::function<void(bool success, const std::vector<std::shared_ptr<Node>>& nodes)>;
|
||||
using DoneCallbackSimple = std::function<void(bool success)>;
|
||||
|
||||
typedef bool (*GetCallbackRaw)(std::shared_ptr<Value>, void *user_data);
|
||||
typedef bool (*ValueCallbackRaw)(std::shared_ptr<Value>, bool expired, void *user_data);
|
||||
|
||||
using DoneCallback = std::function<void(bool success, const std::vector<std::shared_ptr<Node>>& nodes)>;
|
||||
typedef void (*DoneCallbackRaw)(bool, std::vector<std::shared_ptr<Node>>*, void *user_data);
|
||||
typedef void (*ShutdownCallbackRaw)(void *user_data);
|
||||
typedef void (*DoneCallbackSimpleRaw)(bool, void *user_data);
|
||||
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);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
@@ -390,7 +390,11 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
*/
|
||||
Certificate(gnutls_x509_crt_t crt) noexcept : cert(crt) {}
|
||||
|
||||
Certificate(Certificate&& o) noexcept : cert(o.cert), issuer(std::move(o.issuer)) { o.cert = nullptr; };
|
||||
Certificate(Certificate&& o) noexcept
|
||||
: cert(o.cert)
|
||||
, issuer(std::move(o.issuer))
|
||||
, publicKey_(std::move(o.publicKey_))
|
||||
{ o.cert = nullptr; };
|
||||
|
||||
/**
|
||||
* Import certificate (PEM or DER) or certificate chain (PEM),
|
||||
@@ -498,7 +502,8 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
void msgpack_unpack(const msgpack::object& o);
|
||||
|
||||
explicit operator bool() const { return cert; }
|
||||
PublicKey getPublicKey() const;
|
||||
const PublicKey& getPublicKey() const;
|
||||
const std::shared_ptr<PublicKey>& getSharedPublicKey() const;
|
||||
|
||||
/** Same as getPublicKey().getId() */
|
||||
const InfoHash& getId() const;
|
||||
@@ -631,6 +636,9 @@ private:
|
||||
};
|
||||
|
||||
std::set<std::shared_ptr<RevocationList>, crlNumberCmp> revocation_lists;
|
||||
|
||||
mutable std::mutex publicKeyMutex_ {};
|
||||
mutable std::shared_ptr<PublicKey> publicKey_ {};
|
||||
};
|
||||
|
||||
struct OPENDHT_PUBLIC TrustList
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+10
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -67,15 +67,15 @@ public:
|
||||
*/
|
||||
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)) {}
|
||||
|
||||
virtual ~Dht();
|
||||
|
||||
/**
|
||||
* Get the ID of the node.
|
||||
*/
|
||||
inline const InfoHash& getNodeId() const override { return myid; }
|
||||
void setOnPublicAddressChanged(PublicAddressChangedCb cb) override {
|
||||
publicAddressChangedCb_ = std::move(cb);
|
||||
}
|
||||
|
||||
NodeStatus updateStatus(sa_family_t af) override;
|
||||
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
*/
|
||||
void insertNode(const InfoHash& id, const SockAddr&) override;
|
||||
void insertNode(const NodeExport& n) override {
|
||||
insertNode(n.id, SockAddr(n.ss, n.sslen));
|
||||
insertNode(n.id, n.addr);
|
||||
}
|
||||
|
||||
void pingNode(SockAddr, DoneCallbackSimple&& cb={}) override;
|
||||
@@ -265,7 +265,6 @@ public:
|
||||
*/
|
||||
void connectivityChanged(sa_family_t) override;
|
||||
void connectivityChanged() override {
|
||||
reported_addr.clear();
|
||||
connectivityChanged(AF_INET);
|
||||
connectivityChanged(AF_INET6);
|
||||
}
|
||||
@@ -384,11 +383,14 @@ private:
|
||||
TypeStore types;
|
||||
|
||||
using SearchMap = std::map<InfoHash, Sp<Search>>;
|
||||
using ReportedAddr = std::pair<unsigned, SockAddr>;
|
||||
|
||||
struct Kad {
|
||||
RoutingTable buckets {};
|
||||
SearchMap searches {};
|
||||
unsigned pending_pings {0};
|
||||
NodeStatus status;
|
||||
std::vector<ReportedAddr> reported_addr;
|
||||
|
||||
NodeStatus getStatus(time_point now) const;
|
||||
NodeStats getNodesStats(time_point now, const InfoHash& myid) const;
|
||||
@@ -396,6 +398,7 @@ private:
|
||||
|
||||
Kad dht4 {};
|
||||
Kad dht6 {};
|
||||
PublicAddressChangedCb publicAddressChangedCb_ {};
|
||||
|
||||
std::vector<std::pair<std::string,std::string>> bootstrap_nodes {};
|
||||
std::chrono::steady_clock::duration bootstrap_period {BOOTSTRAP_PERIOD};
|
||||
@@ -423,8 +426,6 @@ private:
|
||||
Sp<Scheduler::Job> nextStorageMaintenance {};
|
||||
|
||||
net::NetworkEngine network_engine;
|
||||
using ReportedAddr = std::pair<unsigned, SockAddr>;
|
||||
std::vector<ReportedAddr> reported_addr;
|
||||
|
||||
std::string persistPath;
|
||||
|
||||
@@ -567,7 +568,7 @@ private:
|
||||
* @param sr The search for which we want to announce a value.
|
||||
* @param announce The 'announce' structure.
|
||||
*/
|
||||
void searchSendAnnounceValue(const Sp<Search>& sr);
|
||||
void searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel = TARGET_NODES);
|
||||
|
||||
/**
|
||||
* Main process of a Search's operations. This function will demand the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -19,7 +19,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "infohash.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
#include "node_export.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
@@ -32,8 +33,8 @@ 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) : logger_(std::make_shared<Logger>(l)) {}
|
||||
DhtInterface(const std::shared_ptr<Logger>& l) : logger_(l) {}
|
||||
virtual ~DhtInterface() = default;
|
||||
|
||||
// [[deprecated]]
|
||||
@@ -44,15 +45,16 @@ public:
|
||||
/**
|
||||
* Get the current status of the node for the given family.
|
||||
*/
|
||||
virtual NodeStatus updateStatus(sa_family_t af) { return getStatus(af); };
|
||||
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 void setOnPublicAddressChanged(PublicAddressChangedCb) {}
|
||||
|
||||
virtual net::DatagramSocket* getSocket() const { return {}; };
|
||||
virtual net::DatagramSocket* getSocket() const { return {}; }
|
||||
|
||||
/**
|
||||
* Get the ID of the DHT node.
|
||||
@@ -231,18 +233,6 @@ public:
|
||||
|
||||
virtual std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) = 0;
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
virtual void setLogger(const Logger& l) {
|
||||
if (logger_)
|
||||
*logger_ = l;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -89,6 +89,9 @@ public:
|
||||
* Get the ID of the node.
|
||||
*/
|
||||
inline const InfoHash& getNodeId() const override { return myid; }
|
||||
void setOnPublicAddressChanged(PublicAddressChangedCb cb) override {
|
||||
publicAddressChangedCb_ = std::move(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current status of the node for the given family.
|
||||
@@ -357,6 +360,7 @@ private:
|
||||
SockAddr publicAddressV4_;
|
||||
SockAddr publicAddressV6_;
|
||||
std::atomic_bool launchConnectedCbs_ {false};
|
||||
PublicAddressChangedCb publicAddressChangedCb_ {};
|
||||
|
||||
InfoHash myid {};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
*/
|
||||
DhtProxyServer(const std::shared_ptr<DhtRunner>& dht,
|
||||
const ProxyServerConfig& config = {},
|
||||
const std::shared_ptr<dht::Logger>& logger = {});
|
||||
const std::shared_ptr<log::Logger>& logger = {});
|
||||
|
||||
virtual ~DhtProxyServer();
|
||||
|
||||
@@ -364,7 +364,7 @@ private:
|
||||
mutable std::mutex requestLock_;
|
||||
std::map<unsigned int /*id*/, std::shared_ptr<http::Request>> requests_;
|
||||
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
std::shared_ptr<log::Logger> logger_;
|
||||
|
||||
std::shared_ptr<ServerStats> stats_;
|
||||
std::shared_ptr<NodeInfo> nodeInfo_ {};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -25,8 +25,9 @@
|
||||
#include "value.h"
|
||||
#include "callbacks.h"
|
||||
#include "sockaddr.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
#include "network_utils.h"
|
||||
#include "node_export.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
@@ -77,6 +78,7 @@ public:
|
||||
StatusCallback statusChangedCallback {};
|
||||
CertificateStoreQuery certificateStore {};
|
||||
IdentityAnnouncedCb identityAnnouncedCb {};
|
||||
PublicAddressChangedCb publicAddressChangedCb {};
|
||||
Context() {}
|
||||
};
|
||||
|
||||
@@ -348,7 +350,6 @@ public:
|
||||
void setLogger(const Logger& logger) {
|
||||
setLogger(std::make_shared<Logger>(logger));
|
||||
}
|
||||
void setLoggers(LogMethod err = {}, LogMethod warn = {}, LogMethod debug = {});
|
||||
|
||||
/**
|
||||
* Only print logs related to the given InfoHash (if given), or disable filter (if zeroes).
|
||||
|
||||
+22
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author: Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -53,7 +53,9 @@ class tls_socket_t;
|
||||
}
|
||||
|
||||
namespace dht {
|
||||
namespace log {
|
||||
struct Logger;
|
||||
}
|
||||
|
||||
namespace crypto {
|
||||
struct Certificate;
|
||||
@@ -88,9 +90,9 @@ public:
|
||||
class OPENDHT_PUBLIC Connection : public std::enable_shared_from_this<Connection>
|
||||
{
|
||||
public:
|
||||
Connection(asio::io_context& ctx, const bool ssl = true, std::shared_ptr<dht::Logger> l = {});
|
||||
Connection(asio::io_context& ctx, const bool ssl = true, std::shared_ptr<log::Logger> l = {});
|
||||
Connection(asio::io_context& ctx, std::shared_ptr<dht::crypto::Certificate> server_ca,
|
||||
const dht::crypto::Identity& identity, std::shared_ptr<dht::Logger> l = {});
|
||||
const dht::crypto::Identity& identity, std::shared_ptr<log::Logger> l = {});
|
||||
~Connection();
|
||||
|
||||
inline unsigned int id() const { return id_; };
|
||||
@@ -148,7 +150,7 @@ private:
|
||||
asio::ip::address local_address_;
|
||||
|
||||
std::unique_ptr<asio::steady_timer> timeout_timer_;
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
std::shared_ptr<log::Logger> logger_;
|
||||
bool checkOcsp_ {false};
|
||||
};
|
||||
|
||||
@@ -172,15 +174,15 @@ public:
|
||||
using ResolverCb = std::function<void(const asio::error_code& ec,
|
||||
const 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& url, std::shared_ptr<log::Logger> logger = {});
|
||||
Resolver(asio::io_context& ctx, const std::string& host, const std::string& service,
|
||||
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
|
||||
const bool ssl = false, std::shared_ptr<log::Logger> logger = {});
|
||||
|
||||
// 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 = {});
|
||||
const bool ssl = false, std::shared_ptr<log::Logger> logger = {});
|
||||
Resolver(asio::io_context& ctx, const std::string& url, std::vector<asio::ip::tcp::endpoint> endpoints,
|
||||
std::shared_ptr<dht::Logger> logger = {});
|
||||
std::shared_ptr<log::Logger> logger = {});
|
||||
|
||||
~Resolver();
|
||||
|
||||
@@ -190,7 +192,7 @@ public:
|
||||
|
||||
void add_callback(ResolverCb cb, sa_family_t family = AF_UNSPEC);
|
||||
|
||||
std::shared_ptr<Logger> getLogger() const {
|
||||
std::shared_ptr<log::Logger> getLogger() const {
|
||||
return logger_;
|
||||
}
|
||||
|
||||
@@ -208,7 +210,7 @@ private:
|
||||
bool completed_ {false};
|
||||
std::queue<ResolverCb> cbs_;
|
||||
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
std::shared_ptr<log::Logger> logger_;
|
||||
};
|
||||
|
||||
class Request;
|
||||
@@ -240,14 +242,14 @@ public:
|
||||
|
||||
// resolves implicitly
|
||||
Request(asio::io_context& ctx, const std::string& url, const Json::Value& json, OnJsonCb jsoncb,
|
||||
std::shared_ptr<dht::Logger> logger = {});
|
||||
std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb,
|
||||
std::shared_ptr<dht::Logger> logger = {});
|
||||
std::shared_ptr<log::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& url, std::shared_ptr<log::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 = {});
|
||||
const bool ssl = false, std::shared_ptr<log::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, std::shared_ptr<log::Logger> logger = {});
|
||||
|
||||
// user defined resolver
|
||||
Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, sa_family_t family = AF_UNSPEC);
|
||||
@@ -255,7 +257,7 @@ public:
|
||||
|
||||
// user defined resolved endpoints
|
||||
Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints,
|
||||
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
|
||||
const bool ssl = false, std::shared_ptr<log::Logger> logger = {});
|
||||
|
||||
~Request();
|
||||
|
||||
@@ -282,7 +284,7 @@ public:
|
||||
|
||||
void set_certificate_authority(std::shared_ptr<dht::crypto::Certificate> certificate);
|
||||
void set_identity(const dht::crypto::Identity& identity);
|
||||
void set_logger(std::shared_ptr<dht::Logger> logger);
|
||||
void set_logger(std::shared_ptr<log::Logger> logger);
|
||||
|
||||
/**
|
||||
* Define the HTTP header/body as per https://tools.ietf.org/html/rfc7230.
|
||||
@@ -328,6 +330,8 @@ private:
|
||||
|
||||
void build();
|
||||
|
||||
static std::string url_encode(std::string_view value);
|
||||
|
||||
void init_default_headers();
|
||||
/**
|
||||
* Initialized and wraps the http_parser callbacks with our user defined callbacks.
|
||||
@@ -347,7 +351,7 @@ private:
|
||||
|
||||
mutable std::mutex mutex_;
|
||||
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
std::shared_ptr<log::Logger> logger_;
|
||||
|
||||
restinio::http_request_header_t header_;
|
||||
std::map<restinio::http_field_t, std::string> headers_;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
|
||||
+15
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,6 +22,7 @@
|
||||
#include "rng.h"
|
||||
|
||||
#include <msgpack.hpp>
|
||||
#include <fmt/core.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
@@ -44,6 +45,7 @@ typedef uint16_t in_port_t;
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -228,6 +230,11 @@ public:
|
||||
return get(data.data(), data.size());
|
||||
}
|
||||
|
||||
template <size_t H>
|
||||
static Hash get(const Hash<H>& o) {
|
||||
return get(o.data(), o.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the hash from a given data buffer of size data_len.
|
||||
*/
|
||||
@@ -387,25 +394,11 @@ Hash<N>::toString() const
|
||||
return std::string(to_c_str(), N*2);
|
||||
}
|
||||
|
||||
struct OPENDHT_PUBLIC NodeExport {
|
||||
InfoHash id;
|
||||
sockaddr_storage ss;
|
||||
socklen_t sslen;
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& pk) const
|
||||
{
|
||||
pk.pack_map(2);
|
||||
pk.pack(std::string("id"));
|
||||
pk.pack(id);
|
||||
pk.pack(std::string("addr"));
|
||||
pk.pack_bin(sslen);
|
||||
pk.pack_bin_body((char*)&ss, sslen);
|
||||
}
|
||||
|
||||
void msgpack_unpack(msgpack::object o);
|
||||
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const NodeExport& h);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
struct fmt::formatter<dht::Hash<N>>: formatter<string_view> {
|
||||
constexpr auto format(const dht::Hash<N>& c, format_context& ctx) const {
|
||||
return formatter<string_view>::format(c.to_view(), ctx);
|
||||
}
|
||||
};
|
||||
+2
-38
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
@@ -20,7 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "def.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
@@ -34,42 +34,6 @@ class DhtRunner;
|
||||
*/
|
||||
namespace log {
|
||||
|
||||
/**
|
||||
* Terminal colors for logging
|
||||
*/
|
||||
namespace Color {
|
||||
enum Code {
|
||||
FG_RED = 31,
|
||||
FG_GREEN = 32,
|
||||
FG_YELLOW = 33,
|
||||
FG_BLUE = 34,
|
||||
FG_DEFAULT = 39,
|
||||
BG_RED = 41,
|
||||
BG_GREEN = 42,
|
||||
BG_BLUE = 44,
|
||||
BG_DEFAULT = 49
|
||||
};
|
||||
class Modifier {
|
||||
const Code code;
|
||||
public:
|
||||
constexpr Modifier(Code pCode) : code(pCode) {}
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Modifier& mod) {
|
||||
return os << "\033[" << mod.code << 'm';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
constexpr const Color::Modifier def(Color::FG_DEFAULT);
|
||||
constexpr const Color::Modifier red(Color::FG_RED);
|
||||
constexpr const Color::Modifier yellow(Color::FG_YELLOW);
|
||||
|
||||
/**
|
||||
* Print va_list to std::ostream (used for logging).
|
||||
*/
|
||||
OPENDHT_PUBLIC void
|
||||
printLog(std::ostream &s, char const *m, va_list args);
|
||||
|
||||
OPENDHT_PUBLIC
|
||||
std::shared_ptr<Logger> getStdLogger();
|
||||
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* 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 HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "infohash.h"
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
#ifndef OPENDHT_LOG
|
||||
#define OPENDHT_LOG true
|
||||
#endif
|
||||
|
||||
namespace dht {
|
||||
|
||||
// Logging related utility functions
|
||||
|
||||
/**
|
||||
* Wrapper for logging methods
|
||||
*/
|
||||
struct LogMethod {
|
||||
LogMethod() = default;
|
||||
|
||||
LogMethod(LogMethod&& l) : func(std::move(l.func)) {}
|
||||
LogMethod(const LogMethod& l) : func(l.func) {}
|
||||
|
||||
LogMethod& operator=(dht::LogMethod&& l) {
|
||||
func = std::forward<LogMethod>(l.func);
|
||||
return *this;
|
||||
}
|
||||
LogMethod& operator=(const dht::LogMethod& l) {
|
||||
func = l.func;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
explicit LogMethod(T&& t) : func(std::forward<T>(t)) {}
|
||||
|
||||
template<typename T>
|
||||
LogMethod(const T& t) : func(t) {}
|
||||
|
||||
void operator()(char const* format, ...) const {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
func(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
inline void log(char const* format, va_list args) const {
|
||||
func(format, args);
|
||||
}
|
||||
explicit operator bool() const {
|
||||
return (bool)func;
|
||||
}
|
||||
|
||||
void logPrintable(const uint8_t *buf, size_t buflen) const {
|
||||
std::string buf_clean(buflen, '\0');
|
||||
for (size_t i=0; i<buflen; i++)
|
||||
buf_clean[i] = isprint(buf[i]) ? buf[i] : '.';
|
||||
(*this)("%s", buf_clean.c_str());
|
||||
}
|
||||
private:
|
||||
std::function<void(char const*, va_list)> func;
|
||||
};
|
||||
|
||||
struct Logger {
|
||||
LogMethod ERR = {};
|
||||
LogMethod WARN = {};
|
||||
LogMethod DBG = {};
|
||||
|
||||
Logger() = default;
|
||||
Logger(LogMethod&& err, LogMethod&& warn, LogMethod&& dbg)
|
||||
: ERR(std::move(err)), WARN(std::move(warn)), DBG(std::move(dbg)) {}
|
||||
void setFilter(const InfoHash& f) {
|
||||
filter_ = f;
|
||||
filterEnable_ = static_cast<bool>(filter_);
|
||||
}
|
||||
inline void log0(const LogMethod& logger, char const* format, va_list args) const {
|
||||
#if OPENDHT_LOG
|
||||
if (logger and not filterEnable_)
|
||||
logger.log(format, args);
|
||||
#endif
|
||||
}
|
||||
inline void log1(const LogMethod& logger, const InfoHash& f, char const* format, va_list args) const {
|
||||
#if OPENDHT_LOG
|
||||
if (logger and (not filterEnable_ or f == filter_))
|
||||
logger.log(format, args);
|
||||
#endif
|
||||
}
|
||||
inline void log2(const LogMethod& logger, const InfoHash& f1, const InfoHash& f2, char const* format, va_list args) const {
|
||||
#if OPENDHT_LOG
|
||||
if (logger and (not filterEnable_ or f1 == filter_ or f2 == filter_))
|
||||
logger.log(format, args);
|
||||
#endif
|
||||
}
|
||||
inline void d(char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log0(DBG, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void d(const InfoHash& f, char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log1(DBG, f, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void d(const InfoHash& f1, const InfoHash& f2, char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log2(DBG, f1, f2, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void w(char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log0(WARN, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void w(const InfoHash& f, char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log1(WARN, f, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void w(const InfoHash& f1, const InfoHash& f2, char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log2(WARN, f1, f2, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void e(char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log0(ERR, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void e(const InfoHash& f, char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log1(ERR, f, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
inline void e(const InfoHash& f1, const InfoHash& f2, char const* format, ...) const {
|
||||
#if OPENDHT_LOG
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
log2(ERR, f1, f2, format, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
bool filterEnable_ {false};
|
||||
InfoHash filter_ {};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
#include "infohash.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/printf.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace dht {
|
||||
namespace log {
|
||||
|
||||
enum class LogLevel {
|
||||
debug, warning, error
|
||||
};
|
||||
|
||||
using LogMethod = std::function<void(LogLevel, std::string&&)>;
|
||||
|
||||
struct OPENDHT_PUBLIC Logger {
|
||||
Logger() = delete;
|
||||
Logger(LogMethod&& l)
|
||||
: logger(std::move(l)) {
|
||||
if (!logger)
|
||||
throw std::invalid_argument{"logger and loggerf must be set"};
|
||||
}
|
||||
void setFilter(const InfoHash& f) {
|
||||
filter_ = f;
|
||||
filterEnable_ = static_cast<bool>(filter_);
|
||||
}
|
||||
inline void log0(LogLevel level, fmt::string_view format, fmt::printf_args args) const {
|
||||
if (not filterEnable_)
|
||||
logger(level, fmt::vsprintf(format, args));
|
||||
}
|
||||
inline void log1(LogLevel level, const InfoHash& f, fmt::string_view format, fmt::printf_args args) const {
|
||||
if (not filterEnable_ or f == filter_)
|
||||
logger(level, fmt::vsprintf(format, args));
|
||||
}
|
||||
inline void log2(LogLevel level, const InfoHash& f1, const InfoHash& f2, fmt::string_view format, fmt::printf_args args) const {
|
||||
if (not filterEnable_ or f1 == filter_ or f2 == filter_)
|
||||
logger(level, fmt::vsprintf(format, args));
|
||||
}
|
||||
template<typename S, typename... Args>
|
||||
inline void debug(S&& format, Args&&... args) const {
|
||||
logger(LogLevel::debug, fmt::format(format, args...));
|
||||
}
|
||||
template<typename S, typename... Args>
|
||||
inline void warn(S&& format, Args&&... args) const {
|
||||
logger(LogLevel::warning, fmt::format(format, args...));
|
||||
}
|
||||
template<typename S, typename... Args>
|
||||
inline void error(S&& format, Args&&... args) const {
|
||||
logger(LogLevel::error, fmt::format(format, args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void d(fmt::format_string<T...> format, T&&... args) const {
|
||||
log0(LogLevel::debug, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void d(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const {
|
||||
log1(LogLevel::debug, f, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void d(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const {
|
||||
log2(LogLevel::debug, f1, f2, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void w(fmt::format_string<T...> format, T&&... args) const {
|
||||
log0(LogLevel::warning, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void w(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const {
|
||||
log1(LogLevel::warning, f, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void w(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const {
|
||||
log2(LogLevel::warning, f1, f2, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void e(fmt::format_string<T...> format, T&&... args) const {
|
||||
log0(LogLevel::error, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void e(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const {
|
||||
log1(LogLevel::error, f, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template <typename... T>
|
||||
inline void e(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const {
|
||||
log2(LogLevel::error, f1, f2, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
private:
|
||||
LogMethod logger = {};
|
||||
bool filterEnable_ {false};
|
||||
InfoHash filter_ {};
|
||||
};
|
||||
|
||||
}
|
||||
using Logger = log::Logger;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "utils.h"
|
||||
#include "rng.h"
|
||||
#include "rate_limiter.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
#include "network_utils.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -416,12 +416,19 @@ public:
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request> sendUpdateValues(const Sp<Node>& n,
|
||||
void sendUpdateValues(const Sp<Node>& n,
|
||||
const InfoHash& infohash,
|
||||
const std::vector<Sp<Value>>& values,
|
||||
std::vector<Sp<Value>>&& values,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
const size_t& sid);
|
||||
size_t sid);
|
||||
Sp<Request> sendUpdateValues(const Sp<Node>& n,
|
||||
const InfoHash& infohash,
|
||||
std::vector<Sp<Value>>::iterator begin,
|
||||
std::vector<Sp<Value>>::iterator end,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
size_t sid);
|
||||
|
||||
/**
|
||||
* Parses a message and calls appropriate callbacks.
|
||||
@@ -492,8 +499,7 @@ private:
|
||||
|
||||
static constexpr size_t MTU {1280};
|
||||
static constexpr size_t MAX_PACKET_VALUE_SIZE {600};
|
||||
|
||||
static const std::string my_v;
|
||||
static constexpr size_t MAX_MESSAGE_VALUE_SIZE {56 * 1024};
|
||||
|
||||
void process(std::unique_ptr<ParsedMessage>&&, const SockAddr& from);
|
||||
|
||||
@@ -525,7 +531,10 @@ private:
|
||||
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);
|
||||
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<Sp<Value>>&);
|
||||
std::vector<Blob> packValueHeader(msgpack::sbuffer&, std::vector<Sp<Value>>::const_iterator, std::vector<Sp<Value>>::const_iterator) const;
|
||||
std::vector<Blob> packValueHeader(msgpack::sbuffer& buf, const std::vector<Sp<Value>>& values) const {
|
||||
return packValueHeader(buf, values.begin(), values.end());
|
||||
}
|
||||
void maintainRxBuffer(Tid tid);
|
||||
|
||||
/*************
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "sockaddr.h"
|
||||
#include "utils.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "infohash.h" // includes socket structures
|
||||
#include "utils.h"
|
||||
#include "sockaddr.h"
|
||||
#include "node_export.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
@@ -52,7 +53,7 @@ struct Node {
|
||||
Node(const InfoHash& id, const sockaddr* sa, socklen_t salen, std::mt19937_64& rd)
|
||||
: Node(id, SockAddr(sa, salen), rd) {}
|
||||
|
||||
InfoHash getId() const {
|
||||
const InfoHash& getId() const {
|
||||
return id;
|
||||
}
|
||||
const SockAddr& getAddr() const { return addr; }
|
||||
@@ -92,8 +93,7 @@ struct Node {
|
||||
NodeExport exportNode() const {
|
||||
NodeExport ne;
|
||||
ne.id = id;
|
||||
ne.sslen = addr.getLength();
|
||||
std::memcpy(&ne.ss, addr.get(), ne.sslen);
|
||||
ne.addr = addr;
|
||||
return ne;
|
||||
}
|
||||
sa_family_t getFamily() const { return addr.getFamily(); }
|
||||
@@ -139,7 +139,7 @@ struct Node {
|
||||
*/
|
||||
Tid getNewTid() {
|
||||
++transaction_id;
|
||||
return transaction_id ? ++transaction_id : transaction_id;
|
||||
return transaction_id ? transaction_id : ++transaction_id;
|
||||
}
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2023 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
|
||||
* 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 "def.h"
|
||||
#include "infohash.h"
|
||||
#include "sockaddr.h"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace dht {
|
||||
using namespace std::literals;
|
||||
|
||||
struct OPENDHT_PUBLIC NodeExport {
|
||||
InfoHash id;
|
||||
SockAddr addr;
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& pk) const
|
||||
{
|
||||
pk.pack_map(2);
|
||||
pk.pack("id"sv);
|
||||
pk.pack(id);
|
||||
pk.pack("addr"sv);
|
||||
pk.pack_bin(addr.getLength());
|
||||
pk.pack_bin_body((const char*)addr.get(), (size_t)addr.getLength());
|
||||
}
|
||||
|
||||
void msgpack_unpack(msgpack::object o);
|
||||
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const NodeExport& h);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "def.h"
|
||||
#include "sockaddr.h"
|
||||
#include "infohash.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -149,6 +149,9 @@ public:
|
||||
void setLocalCertificateStore(CertificateStoreQuery&& query_method) {
|
||||
localQueryMethod_ = std::move(query_method);
|
||||
}
|
||||
void setOnPublicAddressChanged(PublicAddressChangedCb cb) override {
|
||||
dht_->setOnPublicAddressChanged(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* SecureDht to Dht proxy
|
||||
@@ -378,7 +381,7 @@ const ValueType CERTIFICATE_TYPE = {
|
||||
try {
|
||||
crypto::Certificate crt(v->data);
|
||||
// TODO check certificate signature
|
||||
return crt.getPublicKey().getId() == id;
|
||||
return crt.getPublicKey().getId() == id || InfoHash::get(crt.getPublicKey().getLongId()) == id;
|
||||
} catch (const std::exception& e) {}
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -20,6 +20,10 @@
|
||||
|
||||
#include "def.h"
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -48,6 +52,7 @@ typedef uint16_t in_port_t;
|
||||
|
||||
namespace dht {
|
||||
|
||||
OPENDHT_PUBLIC void print_addr(std::ostream& os, const sockaddr* sa, socklen_t slen);
|
||||
OPENDHT_PUBLIC std::string print_addr(const sockaddr* sa, socklen_t slen);
|
||||
OPENDHT_PUBLIC std::string print_addr(const sockaddr_storage& ss, socklen_t sslen);
|
||||
|
||||
@@ -289,6 +294,11 @@ public:
|
||||
(uint8_t*)b.get()+start, len) < 0;
|
||||
}
|
||||
};
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const SockAddr& h) {
|
||||
print_addr(s, h.get(), h.getLength());
|
||||
return s;
|
||||
}
|
||||
|
||||
private:
|
||||
struct free_delete { void operator()(void* p) { ::free(p); } };
|
||||
std::unique_ptr<sockaddr, free_delete> addr {};
|
||||
@@ -309,3 +319,7 @@ private:
|
||||
OPENDHT_PUBLIC bool operator==(const SockAddr& a, const SockAddr& b);
|
||||
|
||||
}
|
||||
|
||||
#if FMT_VERSION >= 90000
|
||||
template <> struct fmt::formatter<dht::SockAddr> : ostream_formatter {};
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
static ThreadPool& io();
|
||||
|
||||
ThreadPool();
|
||||
ThreadPool(size_t maxThreads);
|
||||
ThreadPool(unsigned minThreads, unsigned maxThreads = 0);
|
||||
~ThreadPool();
|
||||
|
||||
void run(std::function<void()>&& cb);
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
return get(std::move(cb));
|
||||
}
|
||||
|
||||
void stop();
|
||||
void stop(bool wait = true);
|
||||
void join();
|
||||
|
||||
private:
|
||||
@@ -72,7 +72,12 @@ private:
|
||||
unsigned readyThreads_ {0};
|
||||
bool running_ {true};
|
||||
|
||||
unsigned minThreads_;
|
||||
const unsigned maxThreads_;
|
||||
std::chrono::steady_clock::duration threadExpirationDelay {std::chrono::minutes(5)};
|
||||
double threadDelayRatio_ {2};
|
||||
|
||||
void threadEnded(std::thread&);
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC Executor : public std::enable_shared_from_this<Executor> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -475,7 +475,7 @@ struct OPENDHT_PUBLIC Value
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Value& v);
|
||||
|
||||
inline std::string toString() const {
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
}
|
||||
@@ -774,7 +774,7 @@ struct OPENDHT_PUBLIC Select
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
}
|
||||
@@ -897,7 +897,7 @@ struct OPENDHT_PUBLIC Where
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
}
|
||||
@@ -963,7 +963,7 @@ struct OPENDHT_PUBLIC Query
|
||||
void msgpack_unpack(const msgpack::object& o);
|
||||
|
||||
std::string toString() const {
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
ss << *this;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
project('opendht', 'c', 'cpp',
|
||||
version: '2.6.0',
|
||||
default_options: [
|
||||
'cpp_std=c++17',
|
||||
'warning_level=3'
|
||||
])
|
||||
|
||||
gnutls = dependency('gnutls')
|
||||
nettle = dependency('nettle')
|
||||
msgpack = dependency('msgpack-cxx', required : false)
|
||||
argon2 = dependency('libargon2')
|
||||
openssl = dependency('openssl', required: get_option('proxy_client'))
|
||||
jsoncpp = dependency('jsoncpp', required: get_option('proxy_client'))
|
||||
fmt = dependency('fmt')
|
||||
|
||||
dirs=[]
|
||||
if host_machine.system() == 'freebsd'
|
||||
dirs+='/usr/local/lib'
|
||||
elif host_machine.system() == 'darwin'
|
||||
dirs+='/opt/homebrew/lib'
|
||||
endif
|
||||
http_parser = meson.get_compiler('c').find_library('http_parser', dirs: dirs, required: get_option('proxy_client'))
|
||||
deps = [fmt, gnutls, nettle, msgpack, argon2, openssl, jsoncpp, http_parser]
|
||||
|
||||
add_project_arguments('-DMSGPACK_NO_BOOST', language : 'cpp')
|
||||
add_project_arguments(['-Wno-return-type','-Wno-deprecated','-Wnon-virtual-dtor','-pedantic-errors','-fvisibility=hidden'], language : 'cpp')
|
||||
|
||||
opendht_inc = include_directories('include/opendht')
|
||||
opendht_interface_inc = include_directories('include', is_system: true)
|
||||
opendht_src = [
|
||||
'src/utils.cpp',
|
||||
'src/crypto.cpp',
|
||||
'src/default_types.cpp',
|
||||
'src/node.cpp',
|
||||
'src/value.cpp',
|
||||
'src/dht.cpp',
|
||||
'src/callbacks.cpp',
|
||||
'src/routing_table.cpp',
|
||||
'src/node_cache.cpp',
|
||||
'src/network_engine.cpp',
|
||||
'src/securedht.cpp',
|
||||
'src/dhtrunner.cpp',
|
||||
'src/log.cpp',
|
||||
'src/op_cache.cpp',
|
||||
'src/network_utils.cpp'
|
||||
]
|
||||
if jsoncpp.found()
|
||||
opendht_src += ['src/base64.cpp']
|
||||
add_project_arguments('-DOPENDHT_JSONCPP', language : 'cpp')
|
||||
endif
|
||||
if http_parser.found()
|
||||
opendht_src += ['src/http.cpp', 'src/compat/os_cert.cpp']
|
||||
if host_machine.system() == 'darwin'
|
||||
deps+=dependency('appleframeworks', modules : ['CoreFoundation', 'Security'])
|
||||
endif
|
||||
endif
|
||||
if get_option('proxy_client').enabled()
|
||||
opendht_src += ['src/dht_proxy_client.cpp']
|
||||
add_project_arguments('-DOPENDHT_PROXY_CLIENT', language : 'cpp')
|
||||
endif
|
||||
if get_option('proxy_server').enabled()
|
||||
opendht_src += 'src/dht_proxy_server.cpp'
|
||||
add_project_arguments('-DOPENDHT_PROXY_SERVER', language : 'cpp')
|
||||
endif
|
||||
if get_option('peer_discovery').enabled()
|
||||
opendht_src += 'src/peer_discovery.cpp'
|
||||
add_project_arguments('-DOPENDHT_PEER_DISCOVERY', language : 'cpp')
|
||||
endif
|
||||
opendht = shared_library('opendht',
|
||||
opendht_src,
|
||||
include_directories : opendht_inc,
|
||||
dependencies : deps,
|
||||
cpp_args : ['-DOPENHT_BUILD', '-Dopendht_EXPORTS'],
|
||||
install : true)
|
||||
|
||||
readline = meson.get_compiler('c').find_library('readline', required: get_option('tools'))
|
||||
if get_option('tools').enabled()
|
||||
dhtnode = executable('dhtnode', 'tools/dhtnode.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [readline, msgpack, fmt],
|
||||
install : true)
|
||||
dhtchat = executable('dhtchat', 'tools/dhtchat.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [readline, msgpack, fmt],
|
||||
install : true)
|
||||
dhtscanner = executable('dhtscanner', 'tools/dhtscanner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [readline, msgpack, fmt],
|
||||
install : true)
|
||||
if http_parser.found()
|
||||
durl = executable('durl', 'tools/durl.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [msgpack, openssl])
|
||||
endif
|
||||
endif
|
||||
@@ -0,0 +1,4 @@
|
||||
option('proxy_client', type : 'feature', value : 'disabled')
|
||||
option('proxy_server', type : 'feature', value : 'disabled')
|
||||
option('peer_discovery', type : 'feature', value : 'enabled')
|
||||
option('tools', type : 'feature', value : 'enabled')
|
||||
+2
-1
@@ -7,5 +7,6 @@ Description: C++17 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@
|
||||
Requires: gnutls >= 3.3@jsoncpp_lib@@openssl_lib@
|
||||
Requires.private: nettle >= 2.4@argon2_lib@
|
||||
Cflags: -I${includedir}
|
||||
+7
-7
@@ -5,7 +5,7 @@
|
||||
# distutils: libraries = opendht gnutls
|
||||
# cython: language_level=3
|
||||
#
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 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>
|
||||
@@ -42,7 +42,7 @@ cimport opendht_cpp as cpp
|
||||
|
||||
import threading
|
||||
|
||||
cdef inline void lookup_callback(cpp.vector[cpp.shared_ptr[cpp.IndexValue]]* values, cpp.Prefix* p, void *user_data) with gil:
|
||||
cdef inline void lookup_callback(cpp.vector[cpp.shared_ptr[cpp.IndexValue]]* values, cpp.Prefix* p, void *user_data) noexcept with gil:
|
||||
cbs = <object>user_data
|
||||
if 'lookup' in cbs and cbs['lookup']:
|
||||
vals = []
|
||||
@@ -52,13 +52,13 @@ cdef inline void lookup_callback(cpp.vector[cpp.shared_ptr[cpp.IndexValue]]* val
|
||||
vals.append(v)
|
||||
cbs['lookup'](vals, p.toString())
|
||||
|
||||
cdef inline void shutdown_callback(void* user_data) with gil:
|
||||
cdef inline void shutdown_callback(void* user_data) noexcept with gil:
|
||||
cbs = <object>user_data
|
||||
if 'shutdown' in cbs and cbs['shutdown']:
|
||||
cbs['shutdown']()
|
||||
ref.Py_DECREF(cbs)
|
||||
|
||||
cdef inline bool get_callback(shared_ptr[cpp.Value] value, void *user_data) with gil:
|
||||
cdef inline bool get_callback(shared_ptr[cpp.Value] value, void *user_data) noexcept with gil:
|
||||
cbs = <object>user_data
|
||||
cb = cbs['get']
|
||||
f = cbs['filter'] if 'filter' in cbs else None
|
||||
@@ -66,7 +66,7 @@ cdef inline bool get_callback(shared_ptr[cpp.Value] value, void *user_data) with
|
||||
pv._value = value
|
||||
return cb(pv) if not f or f(pv) else True
|
||||
|
||||
cdef inline bool value_callback(shared_ptr[cpp.Value] value, bool expired, void *user_data) with gil:
|
||||
cdef inline bool value_callback(shared_ptr[cpp.Value] value, bool expired, void *user_data) noexcept with gil:
|
||||
cbs = <object>user_data
|
||||
cb = cbs['valcb']
|
||||
f = cbs['filter'] if 'filter' in cbs else None
|
||||
@@ -74,7 +74,7 @@ cdef inline bool value_callback(shared_ptr[cpp.Value] value, bool expired, void
|
||||
pv._value = value
|
||||
return cb(pv, expired) if not f or f(pv) else True
|
||||
|
||||
cdef inline void done_callback(bool done, cpp.vector[shared_ptr[cpp.Node]]* nodes, void *user_data) with gil:
|
||||
cdef inline void done_callback(bool done, cpp.vector[shared_ptr[cpp.Node]]* nodes, void *user_data) noexcept with gil:
|
||||
node_ids = []
|
||||
for n in deref(nodes):
|
||||
h = NodeEntry()
|
||||
@@ -86,7 +86,7 @@ cdef inline void done_callback(bool done, cpp.vector[shared_ptr[cpp.Node]]* node
|
||||
cbs['done'](done, node_ids)
|
||||
ref.Py_DECREF(cbs)
|
||||
|
||||
cdef inline void done_callback_simple(bool done, void *user_data) with gil:
|
||||
cdef inline void done_callback_simple(bool done, void *user_data) noexcept with gil:
|
||||
cbs = <object>user_data
|
||||
if 'done' in cbs and cbs['done']:
|
||||
cbs['done'](done)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
+3
-6
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
@@ -32,17 +32,14 @@ setup(name="opendht",
|
||||
author="Adrien Béraud, Guillaume Roguez, Simon Désaulniers",
|
||||
license="GPLv3",
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: System :: Distributed Computing',
|
||||
'Topic :: System :: Networking'
|
||||
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
],
|
||||
cmdclass = { 'build_ext' : build_ext },
|
||||
ext_modules = cythonize(Extension(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015-2022 Savoir-Faire Linux Inc.
|
||||
# Copyright (C) 2015-2023 Savoir-Faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 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,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2016-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2016-2023 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -72,7 +72,7 @@ if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Launch an OpenDHT node with an HTTP control interface')
|
||||
parser.add_argument('-p', '--port', help='OpenDHT port to bind', type=int, default=4222)
|
||||
parser.add_argument('-hp', '--http-port', help='HTTP port to bind', type=int, default=8080)
|
||||
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default="bootstrap.ring.cx:4222")
|
||||
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default="bootstrap.jami.net:4222")
|
||||
args = parser.parse_args()
|
||||
endpoints.serverFromString(reactor, "tcp:"+str(args.http_port)).listen(server.Site(DhtServer(args.port, args.bootstrap)))
|
||||
reactor.run()
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -24,7 +24,7 @@ from datetime import datetime
|
||||
import opendht as dht
|
||||
|
||||
parser = argparse.ArgumentParser(description='Create a dht network of -n nodes')
|
||||
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default='bootstrap.ring.cx')
|
||||
parser.add_argument('-b', '--bootstrap', help='bootstrap address', default='bootstrap.jami.net')
|
||||
parser.add_argument('-n', '--num-ops', help='number of concurrent operations on the DHT', type=int, default=8)
|
||||
parser.add_argument('-p', '--period', help='duration between each test (seconds)', type=int, default=60)
|
||||
parser.add_argument('-t', '--timeout', help='timeout for a test to complete (seconds)', type=float, default=15)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -25,8 +25,7 @@ config.setRateLimit(-1, -1)
|
||||
ping_node = dht.DhtRunner()
|
||||
ping_node.run(config=config)
|
||||
#ping_node.enableLogging()
|
||||
#ping_node.bootstrap("bootstrap.ring.cx", "4222")
|
||||
|
||||
#ping_node.bootstrap("bootstrap.jami.net", "4222")
|
||||
pong_node = dht.DhtRunner()
|
||||
pong_node.run(config=config)
|
||||
#pong_node.enableLogging()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+2
-2
@@ -19,7 +19,6 @@ libopendht_la_SOURCES = \
|
||||
routing_table.cpp \
|
||||
network_engine.cpp \
|
||||
utils.cpp \
|
||||
infohash.cpp \
|
||||
node.cpp \
|
||||
value.cpp \
|
||||
crypto.cpp \
|
||||
@@ -40,6 +39,7 @@ nobase_include_HEADERS = \
|
||||
../include/opendht/dht.h \
|
||||
../include/opendht/callbacks.h \
|
||||
../include/opendht/node_cache.h \
|
||||
../include/opendht/node_export.h \
|
||||
../include/opendht/routing_table.h \
|
||||
../include/opendht/network_engine.h \
|
||||
../include/opendht/scheduler.h \
|
||||
@@ -54,7 +54,7 @@ nobase_include_HEADERS = \
|
||||
../include/opendht/dhtrunner.h \
|
||||
../include/opendht/default_types.h \
|
||||
../include/opendht/log.h \
|
||||
../include/opendht/log_enable.h \
|
||||
../include/opendht/logger.h \
|
||||
../include/opendht/network_utils.h \
|
||||
../include/opendht/rng.h \
|
||||
../include/opendht/thread_pool.h
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -92,7 +92,7 @@ bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data) {
|
||||
std::string
|
||||
NodeStats::toString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream 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) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "os_cert.h"
|
||||
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
+17
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
@@ -366,7 +366,7 @@ PrivateKey::getSharedPublicKey() const
|
||||
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))
|
||||
throw CryptoException(std::string("Can't retreive public key: ") + gnutls_strerror(err));
|
||||
publicKey_ = pk;
|
||||
publicKey_ = std::move(pk);
|
||||
}
|
||||
return publicKey_;
|
||||
}
|
||||
@@ -824,13 +824,23 @@ Certificate::~Certificate()
|
||||
}
|
||||
}
|
||||
|
||||
PublicKey
|
||||
const PublicKey&
|
||||
Certificate::getPublicKey() const
|
||||
{
|
||||
PublicKey pk_ret;
|
||||
if (auto err = gnutls_pubkey_import_x509(pk_ret.pk, cert, 0))
|
||||
throw CryptoException(std::string("Can't get certificate public key: ") + gnutls_strerror(err));
|
||||
return pk_ret;
|
||||
return *getSharedPublicKey();
|
||||
}
|
||||
|
||||
const std::shared_ptr<PublicKey>&
|
||||
Certificate::getSharedPublicKey() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(publicKeyMutex_);
|
||||
if (not publicKey_) {
|
||||
auto pk = std::make_shared<PublicKey>();
|
||||
if (auto err = gnutls_pubkey_import_x509(pk->pk, cert, 0))
|
||||
throw CryptoException(std::string("Can't get certificate public key: ") + gnutls_strerror(err));
|
||||
publicKey_ = std::move(pk);
|
||||
}
|
||||
return publicKey_;
|
||||
}
|
||||
|
||||
const InfoHash&
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+96
-70
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -154,10 +154,18 @@ Dht::sendCachedPing(Bucket& b)
|
||||
std::vector<SockAddr>
|
||||
Dht::getPublicAddress(sa_family_t family)
|
||||
{
|
||||
std::sort(reported_addr.begin(), reported_addr.end(), [](const ReportedAddr& a, const ReportedAddr& b) {
|
||||
return a.first > b.first;
|
||||
});
|
||||
std::vector<SockAddr> ret;
|
||||
if (family == AF_UNSPEC) {
|
||||
auto& d4 = dht(AF_INET).reported_addr;
|
||||
auto& d6 = dht(AF_INET6).reported_addr;
|
||||
ret.reserve(d4.size() + d6.size());
|
||||
for (const auto& a : d4)
|
||||
ret.emplace_back(a.second);
|
||||
for (const auto& a : d6)
|
||||
ret.emplace_back(a.second);
|
||||
return ret;
|
||||
}
|
||||
auto& reported_addr = dht(family).reported_addr;
|
||||
ret.reserve(!family ? reported_addr.size() : reported_addr.size()/2);
|
||||
for (const auto& addr : reported_addr)
|
||||
if (!family || family == addr.second.getFamily())
|
||||
@@ -200,6 +208,8 @@ Dht::trySearchInsert(const Sp<Node>& node)
|
||||
void
|
||||
Dht::reportedAddr(const SockAddr& addr)
|
||||
{
|
||||
auto& reported_addr = dht(addr.getFamily()).reported_addr;
|
||||
auto firstBefore = reported_addr.empty() ? nullptr : reported_addr.begin()->second.get();
|
||||
auto it = std::find_if(reported_addr.begin(), reported_addr.end(), [&](const ReportedAddr& a){
|
||||
return a.second == addr;
|
||||
});
|
||||
@@ -208,6 +218,21 @@ Dht::reportedAddr(const SockAddr& addr)
|
||||
reported_addr.emplace_back(1, addr);
|
||||
} else
|
||||
it->first++;
|
||||
std::sort(reported_addr.begin(), reported_addr.end(), [](const ReportedAddr& a, const ReportedAddr& b) {
|
||||
return a.first > b.first;
|
||||
});
|
||||
if (publicAddressChangedCb_) {
|
||||
auto firstAfter = reported_addr.begin()->second.get();
|
||||
if (firstBefore != firstAfter) {
|
||||
auto& otherDht = dht(addr.getFamily() == AF_INET ? AF_INET6 : AF_INET).reported_addr;
|
||||
std::vector<SockAddr> v;
|
||||
v.reserve(otherDht.empty() ? 1 : 2);
|
||||
v.emplace_back(reported_addr.begin()->second);
|
||||
if (not otherDht.empty())
|
||||
v.emplace_back(otherDht.begin()->second);
|
||||
publicAddressChangedCb_(std::move(v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We just learnt about a node, not necessarily a new one. Confirm is 1 if
|
||||
@@ -437,10 +462,9 @@ Dht::searchSendGetValues(Sp<Search> sr, SearchNode* pn, bool update)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Dht::searchSendAnnounceValue(const Sp<Search>& sr) {
|
||||
void Dht::searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel) {
|
||||
if (sr->announce.empty())
|
||||
return;
|
||||
unsigned i = 0;
|
||||
std::weak_ptr<Search> ws = sr;
|
||||
|
||||
auto onDone = [this,ws](const net::Request& req, net::RequestAnswer&& answer)
|
||||
@@ -552,6 +576,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr) {
|
||||
static const auto PROBE_QUERY = std::make_shared<Query>(Select {}.field(Value::Field::Id).field(Value::Field::SeqNum));
|
||||
|
||||
const auto& now = scheduler.time();
|
||||
unsigned i = 0;
|
||||
for (auto& np : sr->nodes) {
|
||||
auto& n = *np;
|
||||
if (not n.isSynced(now))
|
||||
@@ -592,7 +617,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr) {
|
||||
std::bind(&Dht::searchNodeGetExpired, this, _1, _2, ws, PROBE_QUERY));
|
||||
n.getStatus[PROBE_QUERY] = std::move(req);
|
||||
}
|
||||
if (not n.candidate and ++i == TARGET_NODES)
|
||||
if (not n.candidate and ++i == syncLevel)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -675,6 +700,10 @@ Dht::searchStep(std::weak_ptr<Search> ws)
|
||||
if (not sr or sr->expired or sr->done) return;
|
||||
|
||||
const auto& now = scheduler.time();
|
||||
auto level = sr->syncLevel(now);
|
||||
constexpr auto MARGIN = 1;
|
||||
bool preSynced = level > MARGIN;
|
||||
auto syncLevel = preSynced ? level - MARGIN : 0;
|
||||
/*if (auto req_count = sr->currentlySolicitedNodeCount())
|
||||
if (logger_)
|
||||
logger_->d(sr->id, "[search %s IPv%c] step (%d requests)",
|
||||
@@ -735,6 +764,21 @@ Dht::searchStep(std::weak_ptr<Search> ws)
|
||||
|
||||
if (sr->callbacks.empty() && sr->announce.empty() && sr->listeners.empty())
|
||||
sr->setDone();
|
||||
} else if (preSynced) {
|
||||
if (not sr->listeners.empty()) {
|
||||
auto nl = std::min(syncLevel, LISTEN_NODES);
|
||||
unsigned i = 0;
|
||||
for (auto& n : sr->nodes) {
|
||||
if (not n->isSynced(now))
|
||||
break;
|
||||
searchSynchedNodeListen(sr, *n);
|
||||
if (++i == nl)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Announce requests
|
||||
searchSendAnnounceValue(sr, syncLevel);
|
||||
}
|
||||
|
||||
while (sr->currentlySolicitedNodeCount() < MAX_REQUESTED_SEARCH_NODES and searchSendGetValues(sr));
|
||||
@@ -870,7 +914,7 @@ Dht::listenTo(const InfoHash& id, sa_family_t af, ValueCallback cb, Value::Filte
|
||||
throw DhtException("Can't create search");
|
||||
if (logger_)
|
||||
logger_->w(id, "[search %s IPv%c] listen", id.to_c_str(), (af == AF_INET) ? '4' : '6');
|
||||
return sr->listen(cb, f, q, scheduler);
|
||||
return sr->listen(cb, std::move(f), q, scheduler);
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -889,7 +933,7 @@ Dht::listen(const InfoHash& id, ValueCallback cb, Value::Filter f, Where where)
|
||||
});
|
||||
|
||||
auto query = std::make_shared<Query>(Select{}, std::move(where));
|
||||
auto filter = f.chain(query->where.getFilter());
|
||||
auto filter = Value::Filter::chain(std::move(f), query->where.getFilter());
|
||||
auto st = store.find(id);
|
||||
if (st == store.end() && store.size() < max_store_keys)
|
||||
st = store.emplace(id, scheduler.time() + MAX_STORAGE_MAINTENANCE_EXPIRE_TIME).first;
|
||||
@@ -1439,11 +1483,10 @@ Dht::connectivityChanged(sa_family_t af)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
scheduler.edit(nextNodesConfirmation, now);
|
||||
buckets(af).connectivityChanged(now);
|
||||
auto& dht = this->dht(af);
|
||||
dht.buckets.connectivityChanged(now);
|
||||
dht.reported_addr.clear();
|
||||
network_engine.connectivityChanged(af);
|
||||
reported_addr.erase(std::remove_if(reported_addr.begin(), reported_addr.end(), [&](const ReportedAddr& addr){
|
||||
return addr.second.getFamily() == af;
|
||||
}), reported_addr.end());
|
||||
startBootstrap(); // will only happen if disconnected
|
||||
}
|
||||
|
||||
@@ -1560,21 +1603,20 @@ Dht::dumpSearch(const Search& sr, std::ostream& out) const
|
||||
const auto& now = scheduler.time();
|
||||
const auto& listen_expire = getListenExpiration();
|
||||
using namespace std::chrono;
|
||||
out << std::endl << "Search IPv" << (sr.af == AF_INET6 ? '6' : '4') << ' ' << sr.id << " gets: " << sr.callbacks.size();
|
||||
out << ", last step: " << print_time_relative(now, sr.step_time);
|
||||
if (sr.done)
|
||||
out << " [done]";
|
||||
if (sr.expired)
|
||||
out << " [expired]";
|
||||
bool synced = sr.isSynced(now);
|
||||
out << (synced ? " [synced]" : " [not synced]");
|
||||
if (synced && sr.isListening(now, listen_expire))
|
||||
out << " [listening]";
|
||||
out << std::endl;
|
||||
fmt::print(out, "Search IPv{} {} gets: {} last step: {}{}{}{}{}\n",
|
||||
(sr.af == AF_INET6 ? '6' : '4'),
|
||||
sr.id,
|
||||
sr.callbacks.size(),
|
||||
print_time_relative(now, sr.step_time),
|
||||
(sr.done ? " [done]"sv : ""sv),
|
||||
(sr.expired ? " [expired]"sv : ""sv),
|
||||
(sr.isSynced(now) ? " [synced]"sv : " [not synced]"sv),
|
||||
(sr.isListening(now, listen_expire) ? " [listening]"sv : ""sv)
|
||||
);
|
||||
|
||||
/*printing the queries*/
|
||||
// printing the queries
|
||||
if (sr.callbacks.size() + sr.listeners.size() > 0)
|
||||
out << "Queries:" << std::endl;
|
||||
fmt::print(out, "Queries:\n");
|
||||
for (const auto& cb : sr.callbacks) {
|
||||
out << *cb.second.query << std::endl;
|
||||
}
|
||||
@@ -1587,62 +1629,46 @@ Dht::dumpSearch(const Search& sr, std::ostream& out) const
|
||||
out << "Announcement: " << *a.value << (announced ? " [announced]" : "") << std::endl;
|
||||
}
|
||||
|
||||
out << " Common bits InfoHash Conn. Get Ops IP" << std::endl;
|
||||
fmt::print(out, " Common bits InfoHash Conn. Get Ops IP\n");
|
||||
auto last_get = sr.getLastGetTime();
|
||||
for (const auto& np : sr.nodes) {
|
||||
auto& n = *np;
|
||||
out << std::setfill (' ') << std::setw(3) << InfoHash::commonBits(sr.id, n.node->id) << ' ' << n.node->id;
|
||||
out << ' ' << (findNode(n.node->id, sr.af) ? '*' : ' ');
|
||||
out << " [";
|
||||
if (auto pendingCount = n.node->getPendingMessageCount())
|
||||
out << pendingCount;
|
||||
else
|
||||
out << ' ';
|
||||
out << (n.node->isExpired() ? 'x' : ' ') << "]";
|
||||
|
||||
// Get status
|
||||
{
|
||||
char g_i = n.pending(n.getStatus) ? (n.candidate ? 'c' : 'f') : ' ';
|
||||
char s_i = n.isSynced(now) ? (n.last_get_reply > last_get ? 'u' : 's') : '-';
|
||||
out << " [" << s_i << g_i << "] ";
|
||||
}
|
||||
|
||||
// Listen status
|
||||
if (not sr.listeners.empty()) {
|
||||
if (n.listenStatus.empty())
|
||||
out << " ";
|
||||
else
|
||||
out << "["
|
||||
<< (n.isListening(now,listen_expire) ? 'l' : (n.pending(n.listenStatus) ? 'f' : ' ')) << "] ";
|
||||
}
|
||||
|
||||
// Announce status
|
||||
auto listen = (not sr.listeners.empty() ? (n.listenStatus.empty() ? " " : fmt::format("[{}] ", (n.isListening(now,listen_expire) ? 'l' : (n.pending(n.listenStatus) ? 'f' : ' ')))) : "");
|
||||
std::string announce;
|
||||
if (not sr.announce.empty()) {
|
||||
if (n.acked.empty()) {
|
||||
out << " ";
|
||||
for (size_t a=0; a < sr.announce.size(); a++)
|
||||
out << ' ';
|
||||
announce = std::string(sr.announce.size() + 3, ' ');
|
||||
} else {
|
||||
out << "[";
|
||||
announce = "[";
|
||||
for (const auto& a : sr.announce) {
|
||||
auto ack = n.acked.find(a.value->id);
|
||||
if (ack == n.acked.end() or not ack->second.req) {
|
||||
out << ' ';
|
||||
announce += ' ';
|
||||
} else {
|
||||
out << ack->second.req->getStateChar();
|
||||
announce += ack->second.req->getStateChar();
|
||||
}
|
||||
}
|
||||
out << "] ";
|
||||
announce += "] ";
|
||||
}
|
||||
}
|
||||
out << n.node->getAddrStr() << std::endl;
|
||||
|
||||
fmt::print(out, "{:3} {} {} [{}{}] {}{}{}\n",
|
||||
InfoHash::commonBits(sr.id, n.node->id),
|
||||
n.node->id,
|
||||
(findNode(n.node->id, sr.af) ? '*' : ' '),
|
||||
(n.pending(n.getStatus) ? (n.candidate ? 'c' : 'f') : ' '),
|
||||
(n.isSynced(now) ? (n.last_get_reply > last_get ? 'u' : 's') : '-'),
|
||||
listen,
|
||||
announce,
|
||||
n.node->getAddrStr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dht::dumpTables() const
|
||||
{
|
||||
std::stringstream out;
|
||||
std::ostringstream out;
|
||||
out << "My id " << myid << std::endl;
|
||||
|
||||
out << "Buckets IPv4 :" << std::endl;
|
||||
@@ -1694,7 +1720,7 @@ Dht::getStorageLog(const InfoHash& h) const
|
||||
{
|
||||
auto s = store.find(h);
|
||||
if (s == store.end()) {
|
||||
std::stringstream out;
|
||||
std::ostringstream out;
|
||||
out << "Storage " << h << " empty" << std::endl;
|
||||
return out.str();
|
||||
}
|
||||
@@ -1704,7 +1730,7 @@ Dht::getStorageLog(const InfoHash& h) const
|
||||
std::string
|
||||
Dht::printStorageLog(const decltype(store)::value_type& s) const
|
||||
{
|
||||
std::stringstream out;
|
||||
std::ostringstream out;
|
||||
using namespace std::chrono;
|
||||
const auto& st = s.second;
|
||||
out << "Storage " << s.first << " "
|
||||
@@ -1723,7 +1749,7 @@ Dht::printStorageLog(const decltype(store)::value_type& s) const
|
||||
std::string
|
||||
Dht::getRoutingTablesLog(sa_family_t af) const
|
||||
{
|
||||
std::stringstream out;
|
||||
std::ostringstream out;
|
||||
for (const auto& b : buckets(af))
|
||||
dumpBucket(b, out);
|
||||
return out.str();
|
||||
@@ -1732,7 +1758,7 @@ Dht::getRoutingTablesLog(sa_family_t af) const
|
||||
std::string
|
||||
Dht::getSearchesLog(sa_family_t af) const
|
||||
{
|
||||
std::stringstream out;
|
||||
std::ostringstream out;
|
||||
auto num_searches = dht4.searches.size() + dht6.searches.size();
|
||||
if (num_searches > 8) {
|
||||
if (not af or af == AF_INET)
|
||||
@@ -1757,7 +1783,7 @@ Dht::getSearchesLog(sa_family_t af) const
|
||||
std::string
|
||||
Dht::getSearchLog(const InfoHash& id, sa_family_t af) const
|
||||
{
|
||||
std::stringstream out;
|
||||
std::ostringstream out;
|
||||
if (af == AF_UNSPEC) {
|
||||
out << getSearchLog(id, AF_INET) << getSearchLog(id, AF_INET6);
|
||||
} else {
|
||||
@@ -1840,7 +1866,7 @@ Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, cons
|
||||
expire();
|
||||
|
||||
if (logger_)
|
||||
logger_->d("DHT node initialised with ID %s", myid.toString().c_str());
|
||||
logger_->debug("DHT node initialised with ID {:s}", myid);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -2232,7 +2258,7 @@ Dht::pingNode(SockAddr sa, DoneCallbackSimple&& cb)
|
||||
{
|
||||
scheduler.syncTime();
|
||||
if (logger_)
|
||||
logger_->d("Sending ping to %s", sa.toString().c_str());
|
||||
logger_->debug("Sending ping to {}", sa);
|
||||
auto& count = dht(sa.getFamily()).pending_pings;
|
||||
count++;
|
||||
network_engine.sendPing(std::move(sa), [&count,cb](const net::Request&, net::RequestAnswer&&) {
|
||||
@@ -2638,7 +2664,7 @@ Dht::loadState(const std::string& path)
|
||||
std::vector<Sp<Node>> tmpNodes;
|
||||
tmpNodes.reserve(state.nodes.size());
|
||||
for (const auto& node : state.nodes)
|
||||
tmpNodes.emplace_back(network_engine.insertNode(node.id, SockAddr(node.ss, node.sslen)));
|
||||
tmpNodes.emplace_back(network_engine.insertNode(node.id, node.addr));
|
||||
importValues(state.values);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -721,7 +721,7 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t fa
|
||||
}
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->d("[proxy:client] [info] got proxy reply for %s",
|
||||
logger_->debug("[proxy:client] [info] got proxy reply for {}",
|
||||
family == AF_INET ? "ipv4" : "ipv6");
|
||||
try {
|
||||
myid = InfoHash(proxyInfos["node_id"].asString());
|
||||
@@ -729,6 +729,7 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t fa
|
||||
stats6_ = NodeStats(proxyInfos["ipv6"]);
|
||||
auto publicIp = parsePublicAddress(proxyInfos["public_ip"]);
|
||||
ipChanged = pubAddress && pubAddress.toString() != publicIp.toString();
|
||||
bool pub = ipChanged || !pubAddress;
|
||||
pubAddress = publicIp;
|
||||
|
||||
if (proxyInfos.isMember("local_ip")) {
|
||||
@@ -739,6 +740,18 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t fa
|
||||
}
|
||||
}
|
||||
|
||||
if (pub && publicAddressChangedCb_) {
|
||||
std::vector<SockAddr> addresses;
|
||||
if (publicAddressV4_)
|
||||
addresses.emplace_back(publicAddressV4_);
|
||||
if (publicAddressV6_)
|
||||
addresses.emplace_back(publicAddressV6_);
|
||||
std::lock_guard<std::mutex> lock(lockCallbacks_);
|
||||
callbacks_.emplace_back([cb=publicAddressChangedCb_, addresses = std::move(addresses)](){
|
||||
cb(std::move(addresses));
|
||||
});
|
||||
}
|
||||
|
||||
if (!ipChanged && stats4_.good_nodes + stats6_.good_nodes)
|
||||
status = NodeStatus::Connected;
|
||||
else if (!ipChanged && stats4_.dubious_nodes + stats6_.dubious_nodes)
|
||||
@@ -1193,7 +1206,7 @@ DhtProxyClient::restartListeners(const asio::error_code &ec)
|
||||
}
|
||||
|
||||
void
|
||||
DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string>& notification)
|
||||
DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::string, std::string>& notification)
|
||||
{
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
{
|
||||
@@ -1292,13 +1305,11 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
|
||||
}
|
||||
if (launchLoop)
|
||||
loopSignal_();
|
||||
#else
|
||||
(void) notification;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
DhtProxyClient::resubscribe(const InfoHash& key, const size_t token, Listener& listener)
|
||||
DhtProxyClient::resubscribe([[maybe_unused]] const InfoHash& key, [[maybe_unused]] const size_t token, [[maybe_unused]] Listener& listener)
|
||||
{
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
if (deviceKey_.empty())
|
||||
@@ -1322,9 +1333,6 @@ DhtProxyClient::resubscribe(const InfoHash& key, const size_t token, Listener& l
|
||||
std::placeholders::_1, key, token, opstate));
|
||||
auto vcb = listener.cb;
|
||||
sendListen(header, vcb, opstate, listener, ListenMethod::RESUBSCRIBE);
|
||||
#else
|
||||
(void) key;
|
||||
(void) listener;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -704,7 +704,7 @@ DhtProxyServer::get(restinio::request_handle_t request,
|
||||
initHttpResponse(request->create_response<ResponseByParts>()));
|
||||
response->flush();
|
||||
dht_->get(infoHash, [this, response](const std::vector<Sp<Value>>& values) {
|
||||
std::stringstream output;
|
||||
std::ostringstream output;
|
||||
for (const auto& value : values) {
|
||||
output << Json::writeString(jsonBuilder_, value->toJson()) << "\n";
|
||||
}
|
||||
@@ -1053,7 +1053,7 @@ DhtProxyServer::handleCancelPushListen(const asio::error_code &ec, const std::st
|
||||
void
|
||||
DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& json, PushType type, bool highPriority, const std::string& topic)
|
||||
{
|
||||
if (pushServer_.empty())
|
||||
if (pushServer_.empty() && type != PushType::UnifiedPush)
|
||||
return;
|
||||
|
||||
unsigned reqid = 0;
|
||||
@@ -1095,12 +1095,14 @@ DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& jso
|
||||
notification["expiration"] = exp;
|
||||
if (!topic.empty())
|
||||
notification["topic"] = topic;
|
||||
if (highPriority) {
|
||||
auto isResubscribe = !notification["data"]["timeout"].isNull();
|
||||
if (highPriority || isResubscribe) {
|
||||
Json::Value alert(Json::objectValue);
|
||||
alert["title"]="hello";
|
||||
notification["push_type"] = "alert";
|
||||
notification["alert"] = alert;
|
||||
notification["mutable_content"] = true;
|
||||
notification["priority"] = "high";
|
||||
} else {
|
||||
notification["push_type"] = "background";
|
||||
notification["content_available"] = true;
|
||||
|
||||
+15
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -93,7 +93,7 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
auto expected = State::Idle;
|
||||
if (not running.compare_exchange_strong(expected, State::Running)) {
|
||||
if (context.logger)
|
||||
context.logger->w("[runner %p] Node is already running. Call join() first before calling run() again.", this);
|
||||
context.logger->w("[runner %p] Node is already running. Call join() first before calling run() again.", fmt::ptr(this));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
auto local6 = config.bind6;
|
||||
if (not local4 and not local6) {
|
||||
if (context.logger)
|
||||
context.logger->w("[runner %p] No address to bind specified in the configuration, using default addresses", this);
|
||||
context.logger->w("[runner %p] No address to bind specified in the configuration, using default addresses", fmt::ptr(this));
|
||||
local4.setFamily(AF_INET);
|
||||
local6.setFamily(AF_INET6);
|
||||
}
|
||||
@@ -116,14 +116,14 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
if (inConfig >> port) {
|
||||
if (local4.getPort() == 0) {
|
||||
if (context.logger)
|
||||
context.logger->d("[runner %p] Using IPv4 port %hu from saved configuration", this, port);
|
||||
context.logger->d("[runner %p] Using IPv4 port %hu from saved configuration", fmt::ptr(this), port);
|
||||
local4.setPort(port);
|
||||
}
|
||||
}
|
||||
if (inConfig >> port) {
|
||||
if (local6.getPort() == 0) {
|
||||
if (context.logger)
|
||||
context.logger->d("[runner %p] Using IPv6 port %hu from saved configuration", this, port);
|
||||
context.logger->d("[runner %p] Using IPv6 port %hu from saved configuration", fmt::ptr(this), port);
|
||||
local6.setPort(port);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
|
||||
if (context.logger) {
|
||||
logger_ = context.logger;
|
||||
logger_->d("[runner %p] state changed to Running", this);
|
||||
logger_->d("[runner %p] state changed to Running", fmt::ptr(this));
|
||||
}
|
||||
|
||||
#ifdef OPENDHT_PROXY_CLIENT
|
||||
@@ -155,7 +155,7 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
dropped++;
|
||||
}
|
||||
if (dropped and logger_) {
|
||||
logger_->w("[runner %p] dropped %zu packets: queue is full!", this, dropped);
|
||||
logger_->w("[runner %p] dropped %zu packets: queue is full!", fmt::ptr(this), dropped);
|
||||
}
|
||||
ret = std::move(rcv_free);
|
||||
}
|
||||
@@ -186,6 +186,9 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
if (context.certificateStore) {
|
||||
dht_->setLocalCertificateStore(std::move(context.certificateStore));
|
||||
}
|
||||
if (context.publicAddressChangedCb) {
|
||||
dht_->setOnPublicAddressChanged(std::move(context.publicAddressChangedCb));
|
||||
}
|
||||
|
||||
if (not config.threaded)
|
||||
return;
|
||||
@@ -281,7 +284,7 @@ DhtRunner::shutdown(ShutdownCallback cb, bool stop) {
|
||||
return;
|
||||
}
|
||||
if (logger_)
|
||||
logger_->d("[runner %p] state changed to Stopping, %zu ongoing ops", this, ongoing_ops.load());
|
||||
logger_->d("[runner %p] state changed to Stopping, %zu ongoing ops", fmt::ptr(this), ongoing_ops.load());
|
||||
ongoing_ops++;
|
||||
shutdownCallbacks_.emplace_back(std::move(cb));
|
||||
pending_ops.emplace([=](SecureDht&) mutable {
|
||||
@@ -346,7 +349,7 @@ DhtRunner::join()
|
||||
if (auto sock = dht_->getSocket())
|
||||
sock->stop();
|
||||
if (logger_)
|
||||
logger_->d("[runner %p] state changed to Idle", this);
|
||||
logger_->d("[runner %p] state changed to Idle", fmt::ptr(this));
|
||||
}
|
||||
|
||||
if (dht_thread.joinable())
|
||||
@@ -355,7 +358,7 @@ DhtRunner::join()
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(storage_mtx);
|
||||
if (ongoing_ops and logger_) {
|
||||
logger_->w("[runner %p] stopping with %zu remaining ops", this, ongoing_ops.load());
|
||||
logger_->w("[runner %p] stopping with %zu remaining ops", fmt::ptr(this), ongoing_ops.load());
|
||||
}
|
||||
pending_ops = decltype(pending_ops)();
|
||||
pending_ops_prio = decltype(pending_ops_prio)();
|
||||
@@ -454,12 +457,6 @@ DhtRunner::setLogger(const Sp<Logger>& logger) {
|
||||
dht_->setLogger(logger);
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::setLoggers(LogMethod error, LogMethod warn, LogMethod debug) {
|
||||
Logger logger {std::move(error), std::move(warn), std::move(debug)};
|
||||
setLogger(logger);
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::setLogFilter(const InfoHash& f) {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
@@ -686,7 +683,7 @@ DhtRunner::loop_()
|
||||
}
|
||||
|
||||
if (dropped && logger_)
|
||||
logger_->e("[runner %p] Dropped %zu packets with high delay.", this, dropped);
|
||||
logger_->e("[runner %p] Dropped %zu packets with high delay.", fmt::ptr(this), dropped);
|
||||
|
||||
NodeStatus nstatus4 = dht_->updateStatus(AF_INET);
|
||||
NodeStatus nstatus6 = dht_->updateStatus(AF_INET6);
|
||||
@@ -1088,6 +1085,7 @@ DhtRunner::setProxyServer(const std::string& proxy, const std::string& pushNodeI
|
||||
#else
|
||||
if (not proxy.empty())
|
||||
throw std::runtime_error("DHT proxy requested but OpenDHT built without proxy support.");
|
||||
(void) pushNodeId;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+35
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author: Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "http.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
#include "crypto.h"
|
||||
#include "base64.h"
|
||||
#include "compat/os_cert.h"
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#define MAXAGE_SEC (14*24*60*60)
|
||||
#define JITTER_SEC (60)
|
||||
#define OCSP_MAX_RESPONSE_SIZE (20480)
|
||||
@@ -87,7 +91,7 @@ Url::Url(const std::string& url): url(url)
|
||||
std::string
|
||||
Url::toString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
if (not protocol.empty()) {
|
||||
ss << protocol << "://";
|
||||
}
|
||||
@@ -111,11 +115,11 @@ newTlsClientContext(const std::shared_ptr<dht::Logger>& logger)
|
||||
|
||||
if (char* path = getenv("CA_ROOT_FILE")) {
|
||||
if (logger)
|
||||
logger->d("Using CA file: %s", path);
|
||||
logger->debug("Using CA file: {}", path);
|
||||
ctx->load_verify_file(path);
|
||||
} else if (char* path = getenv("CA_ROOT_PATH")) {
|
||||
if (logger)
|
||||
logger->d("Using CA path: %s", path);
|
||||
logger->debug("Using CA path: {}", path);
|
||||
ctx->add_verify_path(path);
|
||||
} else {
|
||||
#ifdef __ANDROID__
|
||||
@@ -1044,7 +1048,7 @@ Request::set_auth(const std::string& username, const std::string& password)
|
||||
void
|
||||
Request::build()
|
||||
{
|
||||
std::stringstream request;
|
||||
std::ostringstream request;
|
||||
bool append_body = !body_.empty();
|
||||
|
||||
// first header
|
||||
@@ -1084,6 +1088,30 @@ Request::build()
|
||||
request_ = request.str();
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/17708801
|
||||
std::string
|
||||
Request::url_encode(std::string_view value)
|
||||
{
|
||||
std::ostringstream escaped;
|
||||
escaped.fill('0');
|
||||
escaped << std::hex;
|
||||
|
||||
for (const char& c : value) {
|
||||
// Keep alphanumeric and other accepted characters intact
|
||||
if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
escaped << c;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Any other characters are percent-encoded
|
||||
escaped << std::uppercase;
|
||||
escaped << '%' << std::setw(2) << static_cast<int>(static_cast<unsigned char>(c));
|
||||
escaped << std::nouppercase;
|
||||
}
|
||||
|
||||
return escaped.str();
|
||||
}
|
||||
|
||||
void
|
||||
Request::add_on_status_callback(OnStatusCb cb) {
|
||||
cbs_.on_status = std::move(cb);
|
||||
@@ -1289,7 +1317,7 @@ Request::post()
|
||||
init_parser();
|
||||
|
||||
if (logger_)
|
||||
logger_->d("[http:request:%i] sending %zu bytes", id_, request_.size());
|
||||
logger_->debug("[http:request:{}] sending {} bytes", id_, request_.size());
|
||||
|
||||
// write the request to buffer
|
||||
std::ostream request_stream(&conn_->input());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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>
|
||||
@@ -32,7 +32,7 @@ namespace indexation {
|
||||
* @return string that represent the blob into a readable way
|
||||
*/
|
||||
static std::string blobToString(const Blob &bl) {
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
auto bn = bl.size() % 8;
|
||||
auto n = bl.size() / 8;
|
||||
|
||||
@@ -46,7 +46,7 @@ static std::string blobToString(const Blob &bl) {
|
||||
}
|
||||
|
||||
std::string Prefix::toString() const {
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "Prefix : " << std::endl << "\tContent_ : \"";
|
||||
ss << blobToString(content_);
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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 "infohash.h"
|
||||
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace dht {
|
||||
|
||||
const HexMap hex_map = {};
|
||||
|
||||
void
|
||||
NodeExport::msgpack_unpack(msgpack::object o)
|
||||
{
|
||||
if (o.type != msgpack::type::MAP)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.size < 2)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.ptr[0].key.as<std::string_view>() != "id"sv)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.ptr[1].key.as<std::string_view>() != "addr"sv)
|
||||
throw msgpack::type_error();
|
||||
const auto& addr = o.via.map.ptr[1].val;
|
||||
if (addr.type != msgpack::type::BIN)
|
||||
throw msgpack::type_error();
|
||||
if (addr.via.bin.size > sizeof(sockaddr_storage))
|
||||
throw msgpack::type_error();
|
||||
id.msgpack_unpack(o.via.map.ptr[0].val);
|
||||
sslen = addr.via.bin.size;
|
||||
std::copy_n(addr.via.bin.ptr, addr.via.bin.size, (char*)&ss);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, const NodeExport& h)
|
||||
{
|
||||
msgpack::pack(s, h);
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
+77
-36
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
@@ -20,6 +20,10 @@
|
||||
#include "log.h"
|
||||
#include "dhtrunner.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ostream.h>
|
||||
#include <fmt/printf.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
@@ -30,46 +34,70 @@
|
||||
namespace dht {
|
||||
namespace log {
|
||||
|
||||
/**
|
||||
* Terminal colors for logging
|
||||
*/
|
||||
namespace Color {
|
||||
enum Code {
|
||||
FG_RED = 31,
|
||||
FG_GREEN = 32,
|
||||
FG_YELLOW = 33,
|
||||
FG_BLUE = 34,
|
||||
FG_DEFAULT = 39,
|
||||
BG_RED = 41,
|
||||
BG_GREEN = 42,
|
||||
BG_BLUE = 44,
|
||||
BG_DEFAULT = 49
|
||||
};
|
||||
class Modifier {
|
||||
const Code code;
|
||||
public:
|
||||
constexpr Modifier(Code pCode) : code(pCode) {}
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Modifier& mod) {
|
||||
return os << "\033[" << mod.code << 'm';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
constexpr const Color::Modifier def(Color::FG_DEFAULT);
|
||||
constexpr const Color::Modifier red(Color::FG_RED);
|
||||
constexpr const Color::Modifier yellow(Color::FG_YELLOW);
|
||||
|
||||
/**
|
||||
* Print va_list to std::ostream (used for logging).
|
||||
*/
|
||||
void
|
||||
printLog(std::ostream& s, char const *m, va_list args) {
|
||||
// print log to buffer
|
||||
std::array<char, 8192> buffer;
|
||||
int ret = vsnprintf(buffer.data(), buffer.size(), m, args);
|
||||
if (ret <= 0)
|
||||
return;
|
||||
|
||||
// write timestamp
|
||||
printfLog(std::ostream& s, const std::string& message) {
|
||||
using namespace std::chrono;
|
||||
using log_precision = microseconds;
|
||||
constexpr auto den = log_precision::period::den;
|
||||
auto num = duration_cast<log_precision>(steady_clock::now().time_since_epoch()).count();
|
||||
s << "[" << std::setfill('0') << std::setw(6) << num / den << "."
|
||||
<< std::setfill('0') << std::setw(6) << num % den << "]" << " ";
|
||||
|
||||
// write log
|
||||
s.write(buffer.data(), std::min((size_t) ret, buffer.size()));
|
||||
if ((size_t) ret >= buffer.size())
|
||||
s << "[[TRUNCATED]]";
|
||||
constexpr auto den = log_precision::period::den;
|
||||
fmt::print(s, "[{:06d}.{:06d}] ", num / den, num % den);
|
||||
s << message << std::endl;
|
||||
}
|
||||
void
|
||||
printLog(std::ostream& s, fmt::string_view format, fmt::format_args args) {
|
||||
using namespace std::chrono;
|
||||
using log_precision = microseconds;
|
||||
auto num = duration_cast<log_precision>(steady_clock::now().time_since_epoch()).count();
|
||||
constexpr auto den = log_precision::period::den;
|
||||
fmt::print(s, "[{:06d}.{:06d}] ", num / den, num % den);
|
||||
fmt::vprint(s, format, args);
|
||||
s << std::endl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Logger>
|
||||
getStdLogger() {
|
||||
return std::make_shared<Logger>(
|
||||
[](char const *m, va_list args) {
|
||||
std::cerr << red;
|
||||
printLog(std::cerr, m, args);
|
||||
[](LogLevel level, std::string&& message) {
|
||||
if (level == LogLevel::error)
|
||||
std::cerr << red;
|
||||
else if (level == LogLevel::warning)
|
||||
std::cerr << yellow;
|
||||
printfLog(std::cerr, message);
|
||||
std::cerr << def;
|
||||
},
|
||||
[](char const *m, va_list args) {
|
||||
std::cout << yellow;
|
||||
printLog(std::cout, m, args);
|
||||
std::cout << def;
|
||||
},
|
||||
[](char const *m, va_list args) { printLog(std::cout, m, args); }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -77,14 +105,28 @@ std::shared_ptr<Logger>
|
||||
getFileLogger(const std::string &path) {
|
||||
auto logfile = std::make_shared<std::ofstream>();
|
||||
logfile->open(path, std::ios::out);
|
||||
|
||||
return std::make_shared<Logger>(
|
||||
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
|
||||
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
|
||||
[=](char const *m, va_list args) { printLog(*logfile, m, args); }
|
||||
[logfile](LogLevel /*level*/, std::string&& message) {
|
||||
printfLog(*logfile, message);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
constexpr
|
||||
int syslogLevel(LogLevel level) {
|
||||
switch (level) {
|
||||
case LogLevel::error:
|
||||
return LOG_ERR;
|
||||
case LogLevel::warning:
|
||||
return LOG_WARNING;
|
||||
case LogLevel::debug:
|
||||
return LOG_INFO;
|
||||
}
|
||||
return LOG_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::shared_ptr<Logger>
|
||||
getSyslogLogger(const char* name) {
|
||||
#ifndef _WIN32
|
||||
@@ -104,12 +146,11 @@ getSyslogLogger(const char* name) {
|
||||
opened_logfile = logfile;
|
||||
}
|
||||
return std::make_shared<Logger>(
|
||||
[logfile](char const *m, va_list args) { vsyslog(LOG_ERR, m, args); },
|
||||
[logfile](char const *m, va_list args) { vsyslog(LOG_WARNING, m, args); },
|
||||
[logfile](char const *m, va_list args) { vsyslog(LOG_INFO, m, args); }
|
||||
);
|
||||
[logfile](LogLevel level, std::string&& message) {
|
||||
syslog(syslogLevel(level), "%s", message.c_str());
|
||||
});
|
||||
#else
|
||||
return std::make_shared<Logger>();
|
||||
return getStdLogger();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
+61
-30
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -20,10 +20,12 @@
|
||||
#include "network_engine.h"
|
||||
#include "request.h"
|
||||
#include "default_types.h"
|
||||
#include "log_enable.h"
|
||||
#include "logger.h"
|
||||
#include "parsed_message.h"
|
||||
|
||||
#include <msgpack.hpp>
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
@@ -41,7 +43,8 @@ constexpr std::chrono::seconds NetworkEngine::UDP_REPLY_TIME;
|
||||
constexpr std::chrono::seconds NetworkEngine::RX_MAX_PACKET_TIME;
|
||||
constexpr std::chrono::seconds NetworkEngine::RX_TIMEOUT;
|
||||
|
||||
const std::string NetworkEngine::my_v {"RNG1"};
|
||||
/* OpenDHT User Agent (UA) */
|
||||
constexpr std::string_view OPENDHT_UA {"o2"};
|
||||
|
||||
static constexpr uint8_t v4prefix[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0};
|
||||
|
||||
@@ -124,9 +127,9 @@ NetworkEngine::tellListener(const Sp<Node>& node, Tid socket_id, const InfoHash&
|
||||
auto nnodes = bufferNodes(node->getFamily(), hash, want, nodes, nodes6);
|
||||
try {
|
||||
if (version >= 1) {
|
||||
sendUpdateValues(node, hash, values, scheduler.time(), ntoken, socket_id);
|
||||
sendUpdateValues(node, hash, std::move(values), scheduler.time(), ntoken, socket_id);
|
||||
} else {
|
||||
sendNodesValues(node->getAddr(), socket_id, nnodes.first, nnodes.second, values, query, ntoken);
|
||||
sendNodesValues(node->getAddr(), socket_id, nnodes.first, nnodes.second, std::move(values), query, ntoken);
|
||||
}
|
||||
} catch (const std::overflow_error& e) {
|
||||
if (logger_)
|
||||
@@ -159,7 +162,7 @@ NetworkEngine::tellListenerRefreshed(const Sp<Node>& n, Tid socket_id, const Inf
|
||||
}
|
||||
|
||||
pk.pack(KEY_Y); pk.pack(version >= 1 ? KEY_Q : KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -210,7 +213,7 @@ NetworkEngine::tellListenerExpired(const Sp<Node>& n, Tid socket_id, const InfoH
|
||||
}
|
||||
|
||||
pk.pack(KEY_Y); pk.pack(version >= 1 ? KEY_Q : KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -375,7 +378,6 @@ NetworkEngine::isMartian(const SockAddr& addr)
|
||||
const auto& sin6 = addr.getIPv6();
|
||||
const uint8_t* address = (const uint8_t*)&sin6.sin6_addr;
|
||||
return address[0] == 0xFF ||
|
||||
(address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
|
||||
memcmp(address, InfoHash::zero().data(), 16) == 0 ||
|
||||
memcmp(address, v4prefix, 12) == 0;
|
||||
}
|
||||
@@ -501,9 +503,8 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, SockAddr f)
|
||||
pmsg.last_part = now;
|
||||
scheduler.add(now + RX_MAX_PACKET_TIME, std::bind(&NetworkEngine::maintainRxBuffer, this, k));
|
||||
scheduler.add(now + RX_TIMEOUT, std::bind(&NetworkEngine::maintainRxBuffer, this, k));
|
||||
} else
|
||||
if (logger_)
|
||||
logger_->e("Partial message with given TID already exists");
|
||||
} else if (logger_)
|
||||
logger_->e("Partial message with given TID %u already exists", k);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,7 +712,7 @@ NetworkEngine::sendPing(const Sp<Node>& node, RequestCb&& on_done, RequestExpire
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_PING);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -748,7 +749,7 @@ NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
|
||||
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -777,7 +778,7 @@ NetworkEngine::sendFindNode(const Sp<Node>& n, const InfoHash& target, want_t wa
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_FIND);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -830,7 +831,7 @@ NetworkEngine::sendGetValues(const Sp<Node>& n, const InfoHash& info_hash, const
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_GET);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -912,12 +913,16 @@ NetworkEngine::deserializeNodes(ParsedMessage& msg, const SockAddr& from) {
|
||||
}
|
||||
|
||||
std::vector<Blob>
|
||||
NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, const std::vector<Sp<Value>>& st)
|
||||
NetworkEngine::packValueHeader(msgpack::sbuffer& buffer, std::vector<Sp<Value>>::const_iterator b, std::vector<Sp<Value>>::const_iterator e) const
|
||||
{
|
||||
auto svals = serializeValues(st);
|
||||
std::vector<Blob> svals;
|
||||
size_t total_size = 0;
|
||||
for (const auto& v : svals)
|
||||
total_size += v.size();
|
||||
|
||||
svals.reserve(std::distance(b, e));
|
||||
for (; b != e; ++b) {
|
||||
svals.emplace_back(packMsg(*b));
|
||||
total_size += svals.back().size();
|
||||
}
|
||||
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack(KEY_REQ_VALUES);
|
||||
@@ -1009,7 +1014,7 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
|
||||
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -1100,7 +1105,7 @@ NetworkEngine::sendListen(const Sp<Node>& n,
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_LISTEN);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -1133,7 +1138,7 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
|
||||
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -1169,7 +1174,7 @@ NetworkEngine::sendAnnounceValue(const Sp<Node>& n,
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_PUT);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -1200,13 +1205,39 @@ NetworkEngine::sendAnnounceValue(const Sp<Node>& n,
|
||||
return req;
|
||||
}
|
||||
|
||||
void
|
||||
NetworkEngine::sendUpdateValues(const Sp<Node>& n,
|
||||
const InfoHash& infohash,
|
||||
std::vector<Sp<Value>>&& values,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
size_t socket_id)
|
||||
{
|
||||
size_t total_size = 0;
|
||||
|
||||
auto b = values.begin(), e = values.begin();
|
||||
while (e != values.end()) {
|
||||
if (total_size >= MAX_MESSAGE_VALUE_SIZE) {
|
||||
sendUpdateValues(n, infohash, b, e, created, token, socket_id);
|
||||
b = e;
|
||||
total_size = 0;
|
||||
}
|
||||
total_size += (*e)->size();
|
||||
++e;
|
||||
}
|
||||
if (b != e) {
|
||||
sendUpdateValues(n, infohash, b, e, created, token, socket_id);
|
||||
}
|
||||
}
|
||||
|
||||
Sp<Request>
|
||||
NetworkEngine::sendUpdateValues(const Sp<Node>& n,
|
||||
const InfoHash& infohash,
|
||||
const std::vector<Sp<Value>>& values,
|
||||
std::vector<Sp<Value>>::iterator begin,
|
||||
std::vector<Sp<Value>>::iterator end,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
const size_t& socket_id)
|
||||
size_t socket_id)
|
||||
{
|
||||
Tid tid (n->getNewTid());
|
||||
Tid sid (socket_id);
|
||||
@@ -1220,7 +1251,7 @@ NetworkEngine::sendUpdateValues(const Sp<Node>& n,
|
||||
pk.pack(KEY_VERSION); pk.pack(1);
|
||||
pk.pack(KEY_REQ_H); pk.pack(infohash);
|
||||
pk.pack(KEY_REQ_SID); pk.pack(sid);
|
||||
auto v = packValueHeader(buffer, values);
|
||||
auto v = packValueHeader(buffer, begin, end);
|
||||
if (created < scheduler.time()) {
|
||||
pk.pack(KEY_REQ_CREATION);
|
||||
pk.pack(to_time_t(created));
|
||||
@@ -1230,7 +1261,7 @@ NetworkEngine::sendUpdateValues(const Sp<Node>& n,
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_UPDATE);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -1269,7 +1300,7 @@ NetworkEngine::sendRefreshValue(const Sp<Node>& n,
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_REFRESH);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -1313,7 +1344,7 @@ NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid)
|
||||
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
@@ -1343,7 +1374,7 @@ NetworkEngine::sendError(const SockAddr& addr,
|
||||
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_E);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
pk.pack(KEY_UA); pk.pack(OPENDHT_UA);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
+28
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -160,7 +160,7 @@ Node::closeSocket(Tid id)
|
||||
std::string
|
||||
Node::toString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::ostringstream ss;
|
||||
ss << (*this);
|
||||
return ss.str();
|
||||
}
|
||||
@@ -171,4 +171,30 @@ std::ostream& operator<< (std::ostream& s, const Node& h)
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
NodeExport::msgpack_unpack(msgpack::object o)
|
||||
{
|
||||
if (o.type != msgpack::type::MAP)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.size < 2)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.ptr[0].key.as<std::string_view>() != "id"sv)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.ptr[1].key.as<std::string_view>() != "addr"sv)
|
||||
throw msgpack::type_error();
|
||||
const auto& maddr = o.via.map.ptr[1].val;
|
||||
if (maddr.type != msgpack::type::BIN)
|
||||
throw msgpack::type_error();
|
||||
if (maddr.via.bin.size > sizeof(sockaddr_storage))
|
||||
throw msgpack::type_error();
|
||||
id.msgpack_unpack(o.via.map.ptr[0].val);
|
||||
addr = {(const sockaddr*)maddr.via.bin.ptr, (socklen_t)maddr.via.bin.size};
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, const NodeExport& h)
|
||||
{
|
||||
msgpack::pack(s, h);
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
constexpr size_t CLEANUP_MAX_NODES {1024};
|
||||
constexpr size_t CLEANUP_FREQ {1024};
|
||||
constexpr size_t CLEANUP_MAX_NODES {4 * 1024};
|
||||
constexpr size_t CLEANUP_FREQ {4 * 1024};
|
||||
|
||||
NodeCache::~NodeCache()
|
||||
{
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -175,7 +175,7 @@ SearchCache::getOp(const Sp<Query>& q) const
|
||||
}
|
||||
|
||||
size_t
|
||||
SearchCache::listen(const ValueCallback& get_cb, const Sp<Query>& q, const Value::Filter& filter, const OnListen& onListen)
|
||||
SearchCache::listen(const ValueCallback& get_cb, const Sp<Query>& q, Value::Filter&& filter, const OnListen& onListen)
|
||||
{
|
||||
// find exact match
|
||||
auto op = getOp(q);
|
||||
@@ -192,7 +192,7 @@ SearchCache::listen(const ValueCallback& get_cb, const Sp<Query>& q, const Value
|
||||
auto token = nextToken_++;
|
||||
if (nextToken_ == 0)
|
||||
nextToken_++;
|
||||
return op->second->addListener(token, get_cb, q, filter) ? token : 0;
|
||||
return op->second->addListener(token, get_cb, q, std::move(filter)) ? token : 0;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -107,12 +107,12 @@ public:
|
||||
void onValuesAdded(const std::vector<Sp<Value>>& vals);
|
||||
void onValuesExpired(const std::vector<Sp<Value>>& vals);
|
||||
|
||||
bool addListener(size_t token, const ValueCallback& cb, const Sp<Query>& q, const Value::Filter& filter) {
|
||||
bool addListener(size_t token, const ValueCallback& cb, const Sp<Query>& q, Value::Filter&& filter) {
|
||||
auto cached = cache.get(filter);
|
||||
if (not cached.empty() and not cb(cached, false)) {
|
||||
return false;
|
||||
}
|
||||
listeners.emplace(token, LocalListener{q, filter, cb});
|
||||
listeners.emplace(token, LocalListener{q, std::move(filter), cb});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
SearchCache(SearchCache&&) = default;
|
||||
|
||||
using OnListen = std::function<size_t(Sp<Query>, ValueCallback, SyncCallback)>;
|
||||
size_t listen(const ValueCallback& get_cb, const Sp<Query>& q, const Value::Filter& filter, const OnListen& onListen);
|
||||
size_t listen(const ValueCallback& get_cb, const Sp<Query>& q, Value::Filter&& filter, const OnListen& onListen);
|
||||
|
||||
bool cancelListen(size_t gtoken, const time_point& now);
|
||||
void cancelAll(const std::function<void(size_t)>& onCancel);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -152,9 +152,10 @@ bool
|
||||
ParsedMessage::complete()
|
||||
{
|
||||
for (auto& e : value_parts) {
|
||||
//std::cout << "part " << e.first << ": " << e.second.second.size() << "/" << e.second.first << std::endl;
|
||||
if (e.second.first > e.second.second.size())
|
||||
if (e.second.first > e.second.second.size()) {
|
||||
//std::cout << "uncomplete part " << e.first << ": " << e.second.second.size() << "/" << e.second.first << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (auto& e : value_parts) {
|
||||
msgpack::unpacked msg;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
|
||||
+20
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2023 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
|
||||
@@ -485,6 +485,8 @@ struct Dht::Search {
|
||||
*/
|
||||
bool isSynced(time_point now) const;
|
||||
|
||||
unsigned syncLevel(time_point now) const;
|
||||
|
||||
/**
|
||||
* Get the time of the last "get" operation performed on this search,
|
||||
* or time_point::min() if no such operation have been performed.
|
||||
@@ -547,9 +549,9 @@ struct Dht::Search {
|
||||
}
|
||||
}
|
||||
|
||||
size_t listen(const ValueCallback& cb, const Value::Filter& f, const Sp<Query>& q, Scheduler& scheduler) {
|
||||
size_t listen(const ValueCallback& cb, Value::Filter&& f, const Sp<Query>& q, Scheduler& scheduler) {
|
||||
//DHT_LOG.e(id, "[search %s IPv%c] listen", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
|
||||
return cache.listen(cb, q, f, [&](const Sp<Query>& q, ValueCallback vcb, SyncCallback scb){
|
||||
return cache.listen(cb, q, std::move(f), [&](const Sp<Query>& q, ValueCallback vcb, SyncCallback scb){
|
||||
done = false;
|
||||
auto token = ++listener_token;
|
||||
listeners.emplace(token, SearchListener{q, vcb, scb});
|
||||
@@ -895,6 +897,21 @@ Dht::Search::isSynced(time_point now) const
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
Dht::Search::syncLevel(time_point now) const
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (const auto& n : nodes) {
|
||||
if (n->isBad())
|
||||
continue;
|
||||
if (not n->isSynced(now))
|
||||
return i;
|
||||
if (++i == TARGET_NODES)
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
time_point
|
||||
Dht::Search::getLastGetTime(const Query& q) const
|
||||
{
|
||||
|
||||
Loaded 100 of 134 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user