Compare commits

..
3 Commits
122 changed files with 710 additions and 1195 deletions

No files matched your search

+99 -127
View File
@@ -1,13 +1,5 @@
name: C/C++ CI
env:
LLHTTP_VERSION: "v9.2.1"
RESTINIO_VERSION: "0.7.6"
EXPECTED_LITE_URL: "https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp"
UBUNTU_FULL_DEPS: "libncurses5-dev libreadline-dev nettle-dev libasio-dev libgnutls28-dev libuv1-dev python3-pip python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev autotools-dev autoconf libfmt-dev libmsgpack-dev libargon2-dev"
UBUNTU_MESON_DEPS: "ninja-build libncurses5-dev libreadline-dev nettle-dev libasio-dev libgnutls28-dev libuv1-dev python3-dev python3-setuptools python3-pip libcppunit-dev libjsoncpp-dev libfmt-dev libmsgpack-dev libargon2-dev"
UBUNTU_MINIMAL_DEPS: "libncurses5-dev libreadline-dev nettle-dev libfmt-dev libgnutls28-dev libcppunit-dev libmsgpack-dev libargon2-dev"
on: [push, pull_request]
jobs:
@@ -15,142 +7,122 @@ jobs:
name: Ubuntu/GCC Autotools build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
echo "Installing Ubuntu full dependencies:"
sudo apt-get update
sudo apt-get install -y $UBUNTU_FULL_DEPS
- name: Install Cython
run: sudo pip3 install Cython
- name: Build llhttp dependency
run: |
mkdir llhttp
wget "https://github.com/nodejs/llhttp/archive/refs/tags/release/${LLHTTP_VERSION}.tar.gz" -O llhttp.tar.gz
tar -xzf llhttp.tar.gz -C llhttp --strip-components=1
cd llhttp && cmake -DCMAKE_INSTALL_PREFIX=/usr . && make -j2 && sudo make install
cd ../ && rm -rf llhttp*
- name: Install expected-lite header
run: |
sudo mkdir -p /usr/local/include/nonstd
sudo wget "${EXPECTED_LITE_URL}" -O /usr/local/include/nonstd/expected.hpp
- name: Build restinio dependency
run: |
mkdir restinio && cd restinio
wget "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2"
tar -xjf restinio-${RESTINIO_VERSION}.tar.bz2
cd restinio-${RESTINIO_VERSION}/dev
cmake -DCMAKE_INSTALL_PREFIX=/usr/local \
-DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off \
-DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
- uses: actions/checkout@v4
- name: Dependencies
run: |
sudo apt update && \
sudo apt install libncurses5-dev libreadline-dev nettle-dev libasio-dev \
libgnutls28-dev libuv1-dev python3-pip python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
autotools-dev autoconf libfmt-dev libmsgpack-dev libargon2-0-dev
- name: Cython
run: sudo pip3 install Cython
- name: llhttp
run: |
mkdir llhttp
wget https://github.com/nodejs/llhttp/archive/refs/tags/release/v9.2.0.tar.gz -O llhttp.tar.gz
tar -xzf llhttp.tar.gz -C llhttp --strip-components=1
cd llhttp && cmake -DCMAKE_INSTALL_PREFIX=/usr . && make -j2 && sudo make install
cd ../ && rm -rf llhttp*
- name: expected-lite
run: |
sudo mkdir /usr/local/include/nonstd && \
sudo wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
-O /usr/local/include/nonstd/expected.hpp
- name: restinio
run: |
mkdir restinio && cd restinio
wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2
ls -l && tar -xjf restinio-0.7.2.tar.bz2
cd restinio-0.7.2/dev
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system .
sudo make install
cd ../../ && rm -rf restinio*
- name: Configure project
run: |
./autogen.sh
./configure --enable-proxy-client
- name: Build
run: make
sudo make install
cd ../../ && rm -rf restinio*
- name: Configure
run: |
./autogen.sh
./configure --enable-proxy-client
- name: Build
run: make
build-ubuntu-meson:
name: Ubuntu/GCC Meson build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
echo "Installing Ubuntu meson dependencies:"
sudo apt update
sudo apt install -y $UBUNTU_MESON_DEPS
- name: Install Python dependencies
run: sudo pip3 install meson Cython
- name: Configure with Meson
run: meson setup build .
- name: Build with Ninja
run: cd build && ninja
- uses: actions/checkout@v4
- name: Dependencies
run: |
sudo apt update && \
sudo apt install ninja-build libncurses5-dev libreadline-dev nettle-dev libasio-dev \
libgnutls28-dev libuv1-dev python3-dev python3-setuptools python3-pip \
libcppunit-dev libjsoncpp-dev libfmt-dev libmsgpack-dev libargon2-0-dev
- name: Python dependencies
run: sudo pip3 install meson Cython
- 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@v4
- name: Install Minimal Dependencies
run: |
echo "Installing Ubuntu minimal dependencies:"
sudo apt-get update
sudo apt-get install -y $UBUNTU_MINIMAL_DEPS
- name: Configure project with CMake
run: |
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_BUILD_TYPE=Debug \
-DOPENDHT_C=Off -DBUILD_TESTING=On \
-DOPENDHT_PEER_DISCOVERY=Off -DOPENDHT_PYTHON=Off \
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=Off -DOPENDHT_PROXY_CLIENT=Off
- name: Build
run: cd build && make
- name: Run Unit tests
run: cd build && ./opendht_unit_tests
- uses: actions/checkout@v4
- name: Dependencies
run: |
sudo apt update && \
sudo apt install libncurses5-dev libreadline-dev nettle-dev libfmt-dev \
libgnutls28-dev libcppunit-dev libmsgpack-dev libargon2-0-dev
- name: Configure
run: |
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Debug \
-DOPENDHT_C=Off -DBUILD_TESTING=On -DOPENDHT_PEER_DISCOVERY=Off -DOPENDHT_PYTHON=Off \
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=Off -DOPENDHT_PROXY_CLIENT=Off
- name: Build
run: cd build && make
- name: Unit tests
run: cd build && ./opendht_unit_tests
build-macos:
name: macOS/Clang build
runs-on: macos-15
runs-on: macOS-15
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: Dependencies
run: |
brew install msgpack-cxx asio gnutls nettle readline fmt jsoncpp argon2 openssl cppunit
- name: Install Homebrew Dependencies
run: brew install msgpack-cxx asio gnutls nettle readline fmt jsoncpp argon2 openssl cppunit
- name: expected-lite
run: |
sudo mkdir -p /usr/local/include/nonstd && \
sudo wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
-O /usr/local/include/nonstd/expected.hpp
- name: Install expected-lite header
run: |
sudo mkdir -p /usr/local/include/nonstd
sudo wget "${EXPECTED_LITE_URL}" -O /usr/local/include/nonstd/expected.hpp
- name: Build restinio dependency
run: |
mkdir restinio && cd restinio
wget "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2"
tar -xjf restinio-${RESTINIO_VERSION}.tar.bz2
cd restinio-${RESTINIO_VERSION}/dev
cmake -DCMAKE_INSTALL_PREFIX=/usr/local \
-DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off \
-DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
- name: restinio
run: |
mkdir restinio && cd restinio
wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2
ls -l && tar -xjf restinio-0.7.2.tar.bz2
cd restinio-0.7.2/dev
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system .
make -j2 && sudo make install
cd ../../ && rm -rf restinio*
make -j2 && sudo make install
cd ../../ && rm -rf restinio*
- name: Configure project with CMake
run: |
mkdir build && cd build
# Set Homebrew OpenSSL paths
export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@3/include"
export PKG_CONFIG_PATH="/usr/local/opt/openssl@3/lib/pkgconfig"
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_BUILD_TYPE=Debug \
-DOPENDHT_C=On -DBUILD_TESTING=On \
-DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off \
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On \
-DOPENDHT_PROXY_CLIENT=On -DOPENDHT_PUSH_NOTIFICATIONS=On
- name: Configure
run: |
mkdir build && cd build
export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@3/include"
export PKG_CONFIG_PATH="/usr/local/opt/openssl@3/lib/pkgconfig"
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Debug \
-DOPENDHT_C=On -DBUILD_TESTING=On -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off \
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On -DOPENDHT_PUSH_NOTIFICATIONS=On
- name: Build
run: cd build && make
- name: Build
run: cd build && make
+4 -4
View File
@@ -12,7 +12,7 @@ jobs:
sudo apt update && \
sudo apt install libncurses5-dev libreadline-dev nettle-dev \
libgnutls28-dev libuv1-dev python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
autotools-dev autoconf libfmt-dev libmsgpack-dev libargon2-dev libasio-dev \
autotools-dev autoconf libfmt-dev libmsgpack-dev libargon2-0-dev libasio-dev \
llvm llvm-dev clang clang-tools && \
sudo apt remove gcc g++
@@ -25,9 +25,9 @@ jobs:
- name: restinio
run: |
mkdir restinio && cd restinio
wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2
ls -l && tar -xjf restinio-0.7.3.tar.bz2
cd restinio-0.7.3/dev
wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2
ls -l && tar -xjf restinio-0.7.2.tar.bz2
cd restinio-0.7.2/dev
cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system .
-6
View File
@@ -52,10 +52,6 @@ Makefile.in
# VSCode
.vscode/*
# Visual Studio
.vs/
CMakeSettings.json
# Eclipse CDT
.cproject
.project
@@ -82,5 +78,3 @@ doc/Doxyfile
build
build_dev
.DS_Store
build-*/
install/
+33 -39
View File
@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 3.16..3.31)
cmake_minimum_required (VERSION 3.16..3.28)
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
@@ -13,7 +13,7 @@ include(CTest)
include(FetchContent)
set (opendht_VERSION_MAJOR 3)
set (opendht_VERSION_MINOR 4.0)
set (opendht_VERSION_MINOR 2.0)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
set (VERSION "${opendht_VERSION}")
@@ -33,7 +33,6 @@ option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restinio and jsoncpp"
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_IO_URING "Use io_uring if available on the system (Linux only)" OFF)
option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
option (OPENDHT_TESTS_NETWORK "Enable unit tests that require network access" ON)
option (OPENDHT_C "Build C bindings" OFF)
@@ -97,39 +96,33 @@ if (NOT MSVC)
find_package(Restinio REQUIRED)
# llhttp
pkg_search_module(LLHTTP IMPORTED_TARGET llhttp libllhttp)
if (LLHTTP_FOUND)
message(STATUS "Found llhttp ${LLHTTP_INCLUDE_DIRS}")
set(llhttp_target PkgConfig::LLHTTP)
find_path(LLHTTP_INCLUDE_DIR llhttp.h)
find_library(LLHTTP_LIBRARY NAMES llhttp libllhttp)
if (LLHTTP_INCLUDE_DIR AND LLHTTP_LIBRARY)
message(STATUS "Found llhttp ${LLHTTP_INCLUDE_DIR} ${LLHTTP_LIBRARY}")
add_library(llhttp_static STATIC IMPORTED)
set_target_properties(llhttp_static PROPERTIES
IMPORTED_LOCATION ${LLHTTP_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${LLHTTP_INCLUDE_DIR}
)
set(llhttp_target llhttp_static)
else()
find_path(LLHTTP_INCLUDE_DIR llhttp.h)
find_library(LLHTTP_LIBRARY NAMES llhttp libllhttp)
if (LLHTTP_INCLUDE_DIR AND LLHTTP_LIBRARY)
message(STATUS "Found llhttp ${LLHTTP_INCLUDE_DIR} ${LLHTTP_LIBRARY}")
add_library(llhttp_static STATIC IMPORTED)
set_target_properties(llhttp_static PROPERTIES
IMPORTED_LOCATION ${LLHTTP_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${LLHTTP_INCLUDE_DIR}
)
set(llhttp_target llhttp_static)
FetchContent_Declare(llhttp-local URL "https://github.com/nodejs/llhttp/archive/refs/tags/release/v9.2.0.tar.gz")
if (BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON CACHE INTERNAL "")
else()
FetchContent_Declare(llhttp-local URL "https://github.com/nodejs/llhttp/archive/refs/tags/release/v9.2.1.tar.gz")
if (BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON CACHE INTERNAL "")
else()
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "")
set(BUILD_STATIC_LIBS ON CACHE INTERNAL "")
endif()
FetchContent_MakeAvailable(llhttp-local)
if (BUILD_SHARED_LIBS)
set(llhttp_target llhttp_shared)
else()
set(llhttp_target llhttp_static)
endif()
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "")
set(BUILD_STATIC_LIBS ON CACHE INTERNAL "")
endif()
FetchContent_MakeAvailable(llhttp-local)
if (BUILD_SHARED_LIBS)
set(llhttp_target llhttp_shared)
else()
set(llhttp_target llhttp_static)
endif()
endif()
set(http_lib "-lllhttp")
if (NOT Jsoncpp_FOUND)
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
endif()
@@ -163,20 +156,20 @@ else ()
${WIN32_DEP_DIR}/openssl/include
${WIN32_DEP_DIR}/restinio/dev
${WIN32_DEP_DIR}/fmt/include
${WIN32_DEP_DIR}/llhttp/include
${WIN32_DEP_DIR}/http_parser
)
endif ()
endif ()
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
add_definitions(-DASIO_STANDALONE)
if (OPENDHT_IO_URING AND UNIX AND NOT APPLE)
if (UNIX AND NOT APPLE)
pkg_search_module(liburing IMPORTED_TARGET liburing)
endif ()
endif()
if (NOT MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
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")
@@ -185,7 +178,8 @@ else ()
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS
-D_CRT_SECURE_NO_WARNINGS
-DWIN32_LEAN_AND_MEAN
-DSTATIC_GETOPT)
-DSTATIC_GETOPT
-DGNUTLS_INTERNAL_BUILD)
set(DISABLE_MSC_WARNINGS "/wd4101 /wd4244 /wd4267 /wd4273 /wd4804 /wd4834 /wd4996")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DISABLE_MSC_WARNINGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
@@ -349,12 +343,12 @@ if (MSVC)
)
if (OPENDHT_HTTP)
add_obj_lib (win32_fmt ${WIN32_DEP_DIR}/fmt/msvc/Release/fmt.lib)
add_obj_lib (win32_llhttp ${WIN32_DEP_DIR}/llhttp/build/Release/llhttp.lib)
add_obj_lib (win32_http_parser ${WIN32_DEP_DIR}/http_parser/x64/Release/http-parser.lib)
add_obj_lib (win32_ssl ${WIN32_DEP_DIR}/openssl/libssl_static.lib)
add_obj_lib (win32_crypto ${WIN32_DEP_DIR}/openssl/libcrypto_static.lib)
list (APPEND obj_libs
$<TARGET_OBJECTS:win32_fmt>
$<TARGET_OBJECTS:win32_llhttp>
$<TARGET_OBJECTS:win32_http_parser>
$<TARGET_OBJECTS:win32_ssl>
$<TARGET_OBJECTS:win32_crypto>
)
@@ -367,7 +361,7 @@ if (MSVC)
)
list (APPEND win32_Libs
${PROJECT_SOURCE_DIR}/../fmt/msvc/Release/fmt.lib
${PROJECT_SOURCE_DIR}/../llhttp/build/Release/llhttp.lib
${PROJECT_SOURCE_DIR}/../http_parser/x64/Release/http-parser.lib
${PROJECT_SOURCE_DIR}/../openssl/libssl.lib
${PROJECT_SOURCE_DIR}/../openssl/libcrypto.lib
)
@@ -413,7 +407,7 @@ else()
if (OPENDHT_PROXY_OPENSSL)
target_link_libraries(opendht PUBLIC PkgConfig::OPENSSL)
endif()
if (OPENDHT_IO_URING AND liburing_FOUND)
if (liburing_FOUND)
set(iouring_lib ", liburing")
target_link_libraries(opendht PUBLIC PkgConfig::liburing)
target_compile_definitions(opendht PUBLIC ASIO_HAS_IO_URING ASIO_DISABLE_EPOLL)
+2 -2
View File
@@ -108,7 +108,7 @@ for r in results:
IRC: join us on Libera.chat at [`#opendht`](https://web.libera.chat/#opendht).
## License
Copyright (C) 2014-2025 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.
@@ -118,4 +118,4 @@ 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 (now extinct) project called OpenDHT (Sean Rhea. Ph.D. Thesis, 2005).
It is independent from another project called OpenDHT (Sean Rhea. Ph.D. Thesis, 2005), now extinct.
+15 -23
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -132,12 +132,8 @@ void dht_value_set_user_type(dht_value* data, const char* user_type) {
(*reinterpret_cast<ValueSp*>(data))->user_type = user_type;
}
dht_value* dht_value_with_id_new(const uint8_t* data, size_t size, uint64_t value_id) {
return reinterpret_cast<dht_value*>(new ValueSp(std::make_shared<dht::Value>(dht::ValueType::USER_DATA.id, data, size, value_id)));
}
dht_value* dht_value_new(const uint8_t* data, size_t size) {
return dht_value_with_id_new(data, size, 0);
return reinterpret_cast<dht_value*>(new ValueSp(std::make_shared<dht::Value>(data, size)));
}
dht_value* dht_value_new_from_string(const char* str) {
@@ -329,13 +325,12 @@ int dht_runner_run_config(dht_runner* r, in_port_t port, const dht_runner_config
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
try {
dht::DhtRunner::Config config;
config.dht_config.node_config.is_bootstrap = conf->dht_config.node_config.is_bootstrap;
config.dht_config.node_config.is_bootstrap = conf->dht_config.node_config.is_bootstrap;
config.dht_config.node_config.maintain_storage = conf->dht_config.node_config.maintain_storage;
config.dht_config.node_config.node_id = *reinterpret_cast<const dht::InfoHash*>(&conf->dht_config.node_config.node_id);
config.dht_config.node_config.network = conf->dht_config.node_config.network;
config.dht_config.node_config.persist_path = conf->dht_config.node_config.persist_path
? std::string(conf->dht_config.node_config.persist_path)
: std::string{};
config.dht_config.node_config.node_id = *reinterpret_cast<const dht::InfoHash*>(&conf->dht_config.node_config.node_id);
config.dht_config.node_config.network = conf->dht_config.node_config.network;
config.dht_config.node_config.persist_path = conf->dht_config.node_config.persist_path
? std::string(conf->dht_config.node_config.persist_path) : std::string{};
if (conf->dht_config.id.privatekey)
config.dht_config.id.first = *reinterpret_cast<const PrivkeySp*>(conf->dht_config.id.privatekey);
@@ -343,18 +338,15 @@ int dht_runner_run_config(dht_runner* r, in_port_t port, const dht_runner_config
if (conf->dht_config.id.certificate)
config.dht_config.id.second = *reinterpret_cast<const CertSp*>(conf->dht_config.id.certificate);
config.threaded = conf->threaded;
config.proxy_server = conf->proxy_server ? std::string(conf->proxy_server) : std::string{};
config.push_node_id = conf->push_node_id ? std::string(conf->push_node_id) : std::string{};
config.push_token = conf->push_token ? std::string(conf->push_token) : std::string{};
config.push_topic = conf->push_topic ? std::string(conf->push_topic) : std::string{};
config.push_platform = conf->push_platform ? std::string(conf->push_platform) : std::string{};
config.threaded = conf->threaded;
config.proxy_server = conf->proxy_server ? std::string(conf->proxy_server) : std::string{};
config.push_node_id = conf->push_node_id ? std::string(conf->push_node_id) : std::string{};
config.push_token = conf->push_token ? std::string(conf->push_token) : std::string{};
config.push_topic = conf->push_topic ? std::string(conf->push_topic) : std::string{};
config.push_platform = conf->push_platform ? std::string(conf->push_platform) : std::string{};
config.proxy_user_agent = conf->proxy_user_agent ? std::string(conf->proxy_user_agent) : std::string{};
config.peer_discovery = conf->peer_discovery;
config.peer_publish = conf->peer_publish;
if (conf->server_ca)
config.server_ca = *reinterpret_cast<const CertSp*>(conf->server_ca);
config.client_identity = dht_identity_from_c(&conf->client_identity);
config.peer_discovery = conf->peer_discovery;
config.peer_publish = conf->peer_publish;
dht::DhtRunner::Context context;
if (conf->log) {
+2 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -91,7 +91,7 @@ OPENDHT_C_PUBLIC dht_pkid dht_certificate_get_long_id(const dht_certificate*);
OPENDHT_C_PUBLIC dht_publickey* dht_certificate_get_publickey(const dht_certificate*);
OPENDHT_C_PUBLIC void dht_certificate_delete(dht_certificate*);
struct OPENDHT_C_PUBLIC dht_identity {
struct OPENDHT_PUBLIC dht_identity {
dht_privatekey* privatekey;
dht_certificate* certificate;
};
@@ -104,7 +104,6 @@ struct OPENDHT_C_PUBLIC dht_value;
typedef struct dht_value dht_value;
typedef uint64_t dht_value_id;
OPENDHT_C_PUBLIC dht_value* dht_value_new(const uint8_t* data, size_t size);
OPENDHT_C_PUBLIC dht_value* dht_value_with_id_new(const uint8_t* data, size_t size, uint64_t value_id);
OPENDHT_C_PUBLIC dht_value* dht_value_new_from_string(const char* str);
OPENDHT_C_PUBLIC dht_value* dht_value_ref(const dht_value*);
OPENDHT_C_PUBLIC void dht_value_unref(dht_value*);
+8 -31
View File
@@ -49,15 +49,10 @@ elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
if(HAVE_LIBATOMIC)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
else()
#message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
endif()
endif()
@@ -70,32 +65,14 @@ elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
if(HAVE_CXX_LIBATOMICS64)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
endif()
else()
#message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
endif()
endif()
endif()
# Set variable LLVM_ATOMIC_LIB specifying flags for linking against libatomic.
if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB)
# Use options --push-state, --as-needed and --pop-state if linker is known to support them.
# Use single option -Wl of compiler driver to avoid incorrect re-ordering of options by CMake.
if(LLVM_LINKER_IS_GNULD OR LLVM_LINKER_IS_GOLD OR LLVM_LINKER_IS_LLD OR LLVM_LINKER_IS_MOLD)
set(LLVM_ATOMIC_LIB "-Wl,--push-state,--as-needed,-latomic,--pop-state")
else()
set(LLVM_ATOMIC_LIB "-latomic")
endif()
else()
set(LLVM_ATOMIC_LIB)
endif()
## TODO: This define is only used for the legacy atomic operations in
## llvm's Atomic.h, which should be replaced. Other code simply
## assumes C++11 <atomic> works.
+1 -1
View File
@@ -1,6 +1,6 @@
dnl define macros
m4_define([opendht_major_version], 3)
m4_define([opendht_minor_version], 4)
m4_define([opendht_minor_version], 2)
m4_define([opendht_patch_version], 0)
m4_define([opendht_version],
[opendht_major_version.opendht_minor_version.opendht_patch_version])
+3 -3
View File
@@ -24,9 +24,9 @@ RUN mkdir /usr/include/nonstd \
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.3.tar.bz2 \
&& cd restinio-0.7.3/dev \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.2.tar.bz2 \
&& cd restinio-0.7.2/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system . \
+3 -3
View File
@@ -17,9 +17,9 @@ RUN mkdir /usr/include/nonstd \
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.3.tar.bz2 \
&& cd restinio-0.7.3/dev \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.2.tar.bz2 \
&& cd restinio-0.7.2/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system . \
+3 -3
View File
@@ -26,9 +26,9 @@ RUN mkdir /usr/include/nonstd \
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.3.tar.bz2 \
&& cd restinio-0.7.3/dev \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.2.tar.bz2 \
&& cd restinio-0.7.2/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system . \
+3 -3
View File
@@ -24,9 +24,9 @@ RUN mkdir /usr/include/nonstd \
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.3.tar.bz2 \
&& cd restinio-0.7.3/dev \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.2.tar.bz2 \
&& cd restinio-0.7.2/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system . \
+6 -6
View File
@@ -1,4 +1,4 @@
FROM ubuntu:24.04
FROM ubuntu:22.04
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
@@ -8,7 +8,7 @@ RUN apt-get update && apt-get install -y \
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
RUN apt-get update \
&& apt-get install -y llvm llvm-dev lldb clang gdb make cmake meson pkg-config \
&& apt-get install -y llvm llvm-dev lldb clang gdb make cmake pkg-config \
libtool git wget libncurses5-dev libreadline-dev \
nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libjsoncpp-dev python3-dev \
python3-setuptools libcppunit-dev python3-pip python3-build python3-virtualenv \
@@ -17,7 +17,7 @@ RUN apt-get update \
&& apt-get remove -y gcc g++ && apt-get autoremove -y \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
RUN pip3 install Cython --break-system-packages
RUN pip3 install meson Cython
ENV CC cc
ENV CXX c++
@@ -28,9 +28,9 @@ RUN mkdir /usr/include/nonstd \
RUN echo "*** Downloading RESTinio ***" \
&& mkdir restinio && cd restinio \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.3.tar.bz2 \
&& cd restinio-0.7.3/dev \
&& wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.2/restinio-0.7.2.tar.bz2 \
&& ls -l && tar -xjf restinio-0.7.2.tar.bz2 \
&& cd restinio-0.7.2/dev \
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=Off -DRESTINIO_SAMPLE=Off -DRESTINIO_BENCHMARK=Off \
-DRESTINIO_WITH_SOBJECTIZER=Off -DRESTINIO_DEP_STANDALONE_ASIO=system -DRESTINIO_DEP_LLHTTP=system \
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system . \
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -163,20 +163,6 @@ struct OPENDHT_PUBLIC SecureDhtConfig
bool cert_cache_all {false};
};
enum class OPENDHT_PUBLIC PushNotificationResult: uint8_t {
/* success codes */
PutRefresh,
ListenRefresh,
Values,
ValuesExpired,
/* ignored/error codes */
IgnoredWrongSession = 0x80,
IgnoredNoOp,
IgnoredStopped,
IgnoredDisabled,
Error
};
static constexpr size_t DEFAULT_STORAGE_LIMIT {1024 * 1024 * 64};
using ValuesExport = std::pair<InfoHash, Blob>;
+2 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
*
@@ -512,18 +512,12 @@ struct OPENDHT_PUBLIC Certificate {
Blob getSerialNumber() const;
/** Read certificate full DN as described in RFC4514 */
std::string getDN() const;
/** Read certificate Common Name (CN) */
std::string getName() const;
/** Read certificate User ID (UID) */
std::string getUID() const;
/** Read certificate issuer DN as described in RFC4514 */
std::string getIssuerDN() const;
/** Read certificate issuer Common Name (CN) */
std::string getIssuerName() const;
@@ -754,7 +748,7 @@ OPENDHT_PUBLIC Blob aesGetSalt(const uint8_t* data, size_t data_length);
OPENDHT_PUBLIC Blob inline aesGetSalt(const Blob& data) {
return aesGetSalt(data.data(), data.size());
}
/** Get the encrypted data (ciphertext) part of data password-encrypted with `aesEncrypt(data, password)` */
/** Get the encrypted data part of data password-encrypted with `aesEncrypt(data, password)` */
OPENDHT_PUBLIC std::string_view aesGetEncrypted(const uint8_t* data, size_t data_length);
OPENDHT_PUBLIC std::string_view inline aesGetEncrypted(const Blob& data) {
return aesGetEncrypted(data.data(), data.size());
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+2 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -315,9 +315,7 @@ public:
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) override;
PushNotificationResult pushNotificationReceived(const std::map<std::string, std::string>&) override {
return PushNotificationResult::IgnoredDisabled;
}
void pushNotificationReceived(const std::map<std::string, std::string>&) override {}
void resubscribe(unsigned) {}
private:
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -262,7 +262,7 @@ public:
* Call linked callback with a push notification
* @param notification to process
*/
virtual PushNotificationResult pushNotificationReceived(const std::map<std::string, std::string>& data) = 0;
virtual void pushNotificationReceived(const std::map<std::string, std::string>& data) = 0;
protected:
std::shared_ptr<Logger> logger_ {};
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -216,7 +216,7 @@ public:
* Call linked callback with a push notification
* @param notification to process
*/
PushNotificationResult pushNotificationReceived(const std::map<std::string, std::string>& notification) override;
void pushNotificationReceived(const std::map<std::string, std::string>& notification) override;
time_point periodic(const uint8_t*, size_t, SockAddr, const time_point& now) override;
time_point periodic(const uint8_t* buf, size_t buflen, const sockaddr* from, socklen_t fromlen, const time_point& now) override {
+11 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -150,22 +150,22 @@ public:
std::shared_ptr<NodeInfo> nodeInfo {};
std::string toString() const {
auto ret = fmt::format("Listens: {}, Puts: {}, PushListeners: {}\n"
"Push requests in the last {}: [Android: {}], [iOS: {}], [Unified: {}]\n"
"Requests: {} per second.",
listenCount, putCount, pushListenersCount,
print_duration(lastUpdated - serverStartTime),
androidPush.toString(), iosPush.toString(), unifiedPush.toString(),
requestRate);
std::ostringstream ss;
ss << "Listens: " << listenCount << " Puts: " << putCount << " PushListeners: " << pushListenersCount << std::endl;
ss << "Push requests in the last " << print_duration(lastUpdated - serverStartTime) << ": "
<< "[Android: " << androidPush.toString() << "], "
<< "[iOS: " << iosPush.toString() << "], "
<< "[Unified: " << unifiedPush.toString() << "]" << std::endl;
ss << "Requests: " << requestRate << " per second." << std::endl;
if (nodeInfo) {
auto& ipv4 = nodeInfo->ipv4;
if (ipv4.table_depth > 1)
ret += fmt::format("IPv4 Network estimation: {}\n", ipv4.getNetworkSizeEstimation());
ss << "IPv4 Network estimation: " << ipv4.getNetworkSizeEstimation() << std::endl;;
auto& ipv6 = nodeInfo->ipv6;
if (ipv6.table_depth > 1)
ret += fmt::format("IPv6 Network estimation: {}\n", ipv6.getNetworkSizeEstimation());
ss << "IPv6 Network estimation: " << ipv6.getNetworkSizeEstimation() << std::endl;;
}
return ret;
return ss.str();
}
/**
+3 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -268,17 +268,11 @@ public:
putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
}
[[deprecated("Use the shared_ptr version instead")]]
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb={}, bool permanent = false);
[[deprecated("Use the shared_ptr version instead")]]
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
}
void putEncrypted(InfoHash hash, const PkId& to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, const PkId& to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
}
/**
* Insert known nodes to the routing table, without necessarly ping them.
@@ -390,9 +384,7 @@ public:
// securedht methods
void findCertificate(InfoHash hash, std::function<void(const std::shared_ptr<crypto::Certificate>&)>);
void findCertificate(PkId hash, std::function<void(const std::shared_ptr<crypto::Certificate>&)>);
void registerCertificate(const std::shared_ptr<crypto::Certificate>& cert);
void registerCertificate(std::shared_ptr<crypto::Certificate> cert);
void setLocalCertificateStore(CertificateStoreQuery&& query_method);
/**
@@ -474,7 +466,7 @@ public:
/**
* Insert a push notification to process for OpenDHT
*/
std::future<PushNotificationResult> pushNotificationReceived(const std::map<std::string, std::string>& data);
void pushNotificationReceived(const std::map<std::string, std::string>& data);
/* Proxy server mothods */
void forwardAllMessages(bool forward);
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -72,7 +72,7 @@ class OPENDHT_PUBLIC Url
{
public:
Url() = default;
Url(std::string_view url);
Url(const std::string& url);
std::string url;
std::string protocol {"http"};
std::string host;
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -409,7 +409,7 @@ private:
/**
* This mutlimap contains all prefix insert in the tree in time order
* We could then delete the last one if there are too many nodes
* We could then delete the last one if there is too much node
* The tree will self destroy is branch ( thanks to share_ptr )
*/
std::multimap<time_point, std::shared_ptr<Node>> leaves_;
+7 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -110,7 +110,7 @@ public:
bool operator!=(const Hash& h) const { return !(*this == h); }
bool operator<(const Hash& o) const {
for (unsigned i = 0; i < N; i++) {
for(unsigned i = 0; i < N; i++) {
if(data_[i] != o.data_[i])
return data_[i] < o.data_[i];
}
@@ -119,7 +119,7 @@ public:
Hash operator^(const Hash& o) const {
Hash result;
for (auto i = 0u; i < N; i++) {
for(auto i = 0u; i < N; i++) {
result[i] = data_[i] ^ o.data_[i];
}
return result;
@@ -345,8 +345,8 @@ Hash<N>::getRandom(Rd& rdev)
}
struct alignas(std::max_align_t) HexMap : public std::array<std::array<char, 2>, 256> {
constexpr HexMap() : std::array<std::array<char, 2>, 256>() {
for (size_t i = 0; i < size(); i++) {
HexMap() {
for (size_t i=0; i<size(); i++) {
auto& e = (*this)[i];
e[0] = hex_digits[(i >> 4) & 0x0F];
e[1] = hex_digits[i & 0x0F];
@@ -356,7 +356,7 @@ private:
static constexpr const char* hex_digits = "0123456789abcdef";
};
OPENDHT_PUBLIC constexpr HexMap hex_map = {};
OPENDHT_PUBLIC extern const HexMap hex_map;
inline std::string
toHex(const uint8_t* data, size_t size) {
@@ -380,11 +380,10 @@ Hash<N>::to_c_str() const
{
alignas(std::max_align_t) thread_local std::array<char, N*2+1> buf;
for (size_t i=0; i<N; i++) {
auto b = buf.data() + i*2;
auto b = buf.data()+i*2;
const auto& m = hex_map[data_[i]];
*((uint16_t*)b) = *((uint16_t*)&m);
}
buf[N*2] = '\0';
return buf.data();
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+9 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
*
@@ -49,10 +49,10 @@ public:
* startDiscovery - Keep Listening data from the sender until node is joinned
* or stop is called
*/
void startDiscovery(std::string_view type, ServiceDiscoveredCallback callback);
void startDiscovery(const std::string &type, ServiceDiscoveredCallback callback);
template <typename T>
void startDiscovery(std::string_view type, std::function<void(T &&, SockAddr &&)> cb) {
void startDiscovery(const std::string &type, std::function<void(T &&, SockAddr &&)> cb) {
startDiscovery(type, [cb](msgpack::object &&ob, SockAddr &&addr) {
cb(ob.as<T>(), std::move(addr));
});
@@ -61,11 +61,11 @@ public:
/**
* startPublish - Keeping sending data until node is joinned or stop is called
*/
void startPublish(std::string_view type, const msgpack::sbuffer &pack_buf);
void startPublish(sa_family_t domain, std::string_view type, const msgpack::sbuffer &pack_buf);
void startPublish(const std::string &type, const msgpack::sbuffer &pack_buf);
void startPublish(sa_family_t domain, const std::string &type, const msgpack::sbuffer &pack_buf);
template <typename T>
void startPublish(std::string_view type, const T &object) {
void startPublish(const std::string &type, const T &object) {
msgpack::sbuffer buf;
msgpack::pack(buf, object);
startPublish(type, buf);
@@ -79,13 +79,13 @@ public:
/**
* Remove possible callBack to discovery
*/
bool stopDiscovery(std::string_view type);
bool stopDiscovery(const std::string &type);
/**
* Remove different serivce message to send
*/
bool stopPublish(std::string_view type);
bool stopPublish(sa_family_t domain, std::string_view type);
bool stopPublish(const std::string &type);
bool stopPublish(sa_family_t domain, const std::string &type);
void connectivityChanged();
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -24,7 +24,7 @@ namespace proxy {
constexpr const std::chrono::hours OP_TIMEOUT {24}; // one day
constexpr const std::chrono::hours OP_MARGIN {2}; // two hours
constexpr const char* const HTTP_PROTO {"http://"};
using ListenToken = uint64_t;
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
*
+6 -22
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -115,20 +115,14 @@ public:
* The operation will be immediate if the recipient' public key is known (otherwise it will be retrived first).
*/
void putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
[[deprecated("Use the shared_ptr version instead")]]
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
[[deprecated("Use the shared_ptr version instead")]]
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
void putEncrypted(const InfoHash& hash, const PkId& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
/**
* Take ownership of the value and sign it using our private key.
*/
@@ -141,17 +135,12 @@ public:
void findCertificate(const InfoHash& node, const std::function<void(const Sp<crypto::Certificate>)>& cb);
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<crypto::PublicKey>)>& cb);
void findCertificate(const PkId& id, const std::function<void(const Sp<crypto::Certificate>)>& cb);
void findPublicKey(const PkId& id, const std::function<void(const Sp<crypto::PublicKey>)>& cb);
void registerCertificate(const Sp<crypto::Certificate>& cert);
Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
void registerCertificate(Sp<crypto::Certificate>& cert);
Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
Sp<crypto::PublicKey> getPublicKey(const InfoHash& node) const;
Sp<crypto::Certificate> getCertificate(const PkId& node) const;
Sp<crypto::PublicKey> getPublicKey(const PkId& node) const;
/**
* Allows to set a custom callback called by the library to find a locally-stored certificate.
* The search key used is the public key ID, so there may be multiple certificates retured, signed with
@@ -339,8 +328,8 @@ public:
* Call linked callback with push_notification
* @param notification to process
*/
PushNotificationResult pushNotificationReceived(const std::map<std::string, std::string>& notification) override {
return dht_->pushNotificationReceived(notification);
void pushNotificationReceived(const std::map<std::string, std::string>& notification) override {
dht_->pushNotificationReceived(notification);
}
void setLogger(const Logger& logger) override {
@@ -371,9 +360,6 @@ private:
ValueCallback getCallbackFilter(const ValueCallback&, Value::Filter&&);
GetCallback getCallbackFilter(const GetCallback&, Value::Filter&&);
Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
Sp<crypto::Certificate> registerCertificate(const PkId& node, const Blob& cert);
Sp<crypto::PrivateKey> key_ {};
Sp<crypto::Certificate> certificate_ {};
@@ -383,8 +369,6 @@ private:
// our certificate cache
std::map<InfoHash, Sp<crypto::Certificate>> nodesCertificates_ {};
std::map<InfoHash, Sp<crypto::PublicKey>> nodesPubKeys_ {};
std::map<PkId, Sp<crypto::Certificate>> nodesCertificatesLong_ {};
std::map<PkId, Sp<crypto::PublicKey>> nodesPubKeysLong_ {};
std::atomic_bool forward_all_ {false};
bool enableCache_ {false};
@@ -403,7 +387,7 @@ const ValueType CERTIFICATE_TYPE = {
},
[](InfoHash, const Sp<Value>& o, Sp<Value>& n, const InfoHash&, const SockAddr&) {
try {
return crypto::Certificate(o->data).getPublicKey().getLongId() == crypto::Certificate(n->data).getPublicKey().getLongId();
return crypto::Certificate(o->data).getPublicKey().getId() == crypto::Certificate(n->data).getPublicKey().getId();
} catch (const std::exception& e) {}
return false;
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
+23 -10
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -21,7 +21,6 @@
#include "def.h"
#include <msgpack.hpp>
#include <fmt/format.h>
#include <chrono>
#include <random>
@@ -61,7 +60,7 @@ void erase_if(std::map<Key, Item>& map, const Condition& condition)
* Split "[host]:port" or "host:port" to pair<"host", "port">.
*/
OPENDHT_PUBLIC std::pair<std::string, std::string>
splitPort(std::string_view s);
splitPort(const std::string& s);
class OPENDHT_PUBLIC DhtException : public std::runtime_error {
public:
@@ -85,23 +84,37 @@ using duration = clock::duration;
time_point from_time_t(std::time_t t);
std::time_t to_time_t(time_point t);
inline std::string
to_str(double d) {
char buf[16];
auto ret = snprintf(buf, sizeof(buf), "%.3g", d);
return (ret < 0) ? std::to_string(d) : std::string(buf, ret);
}
/**
* Converts std::chrono::duration to floating-point seconds.
*/
template <class DT>
static double
print_dt(DT d) {
return std::chrono::duration_cast<std::chrono::duration<double>>(d).count();
}
template <class DT>
static std::string
print_duration(DT d) {
if (d < std::chrono::seconds(0)) {
return "-" + print_duration(-d);
} else if (d < std::chrono::milliseconds(1)) {
return fmt::format("{:.3g} us", std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count());
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count()) + " us";
} else if (d < std::chrono::seconds(1)) {
return fmt::format("{:.3g} ms", std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count());
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count()) + " ms";
} else if (d < std::chrono::minutes(1)) {
return fmt::format("{:.3g} s", std::chrono::duration_cast<std::chrono::duration<double>>(d).count());
return to_str(std::chrono::duration_cast<std::chrono::duration<double>>(d).count()) + " s";
} else if (d < std::chrono::hours(1)) {
return fmt::format("{:.3g} min", std::chrono::duration_cast<std::chrono::duration<double, std::ratio<60>>>(d).count());
} else if (d < std::chrono::hours(72)) {
return fmt::format("{:.3g} h", std::chrono::duration_cast<std::chrono::duration<double, std::ratio<3600>>>(d).count());
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::ratio<60>>>(d).count()) + " min";
} else {
return fmt::format("{:.3g} days", std::chrono::duration_cast<std::chrono::duration<double, std::ratio<86400>>>(d).count());
return to_str(std::chrono::duration_cast<std::chrono::duration<double, std::ratio<3600>>>(d).count()) + " h";
}
}
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
*
@@ -137,6 +137,8 @@ private:
std::map<ValueType::Id, ValueType> types {};
};
struct CryptoValueCache;
/**
* A "value" is data potentially stored on the Dht, with some metadata.
*
+1 -1
View File
@@ -1,5 +1,5 @@
project('opendht', 'c', 'cpp', 'cython',
version: '3.4.0',
version: '3.2.0',
default_options: [
'cpp_std=c++17',
'warning_level=3'
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2014-2025 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>
#
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2025 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 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
File renamed without changes.
File renamed without changes.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+10 -66
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
*
@@ -646,7 +646,7 @@ GnuTLSFromType(NameType type)
}
static std::string
readDN(gnutls_x509_crq_t request, const char* oid)
getDN(gnutls_x509_crq_t request, const char* oid)
{
std::string dn;
dn.resize(512);
@@ -704,13 +704,13 @@ CertificateRequest::setName(const std::string& name)
std::string
CertificateRequest::getName() const
{
return readDN(request, GNUTLS_OID_X520_COMMON_NAME);
return getDN(request, GNUTLS_OID_X520_COMMON_NAME);
}
std::string
CertificateRequest::getUID() const
{
return readDN(request, GNUTLS_OID_LDAP_UID);
return getDN(request, GNUTLS_OID_LDAP_UID);
}
void
@@ -769,21 +769,7 @@ CertificateRequest::toString() const
// Certificate
static std::string
readDN(gnutls_x509_crt_t cert, bool issuer = false)
{
gnutls_datum_t dn;
int err = issuer
? gnutls_x509_crt_get_issuer_dn3(cert, &dn, 0)
: gnutls_x509_crt_get_dn3( cert, &dn, 0);
if (err != GNUTLS_E_SUCCESS)
return {};
std::string ret((const char*)dn.data, dn.size);
gnutls_free(dn.data);
return ret;
}
static std::string
readDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)
{
std::string dn;
dn.resize(512);
@@ -941,40 +927,28 @@ Certificate::getSerialNumber() const
return {serial, serial + size};
}
std::string
Certificate::getDN() const
{
return readDN(cert);
}
std::string
Certificate::getName() const
{
return readDN(cert, GNUTLS_OID_X520_COMMON_NAME);
return getDN(cert, GNUTLS_OID_X520_COMMON_NAME);
}
std::string
Certificate::getUID() const
{
return readDN(cert, GNUTLS_OID_LDAP_UID);
}
std::string
Certificate::getIssuerDN() const
{
return readDN(cert, true);
return getDN(cert, GNUTLS_OID_LDAP_UID);
}
std::string
Certificate::getIssuerName() const
{
return readDN(cert, GNUTLS_OID_X520_COMMON_NAME, true);
return getDN(cert, GNUTLS_OID_X520_COMMON_NAME, true);
}
std::string
Certificate::getIssuerUID() const
{
return readDN(cert, GNUTLS_OID_LDAP_UID, true);
return getDN(cert, GNUTLS_OID_LDAP_UID, true);
}
std::vector<std::pair<NameType, std::string>>
@@ -1501,22 +1475,7 @@ OcspResponse::getCertificateStatus() const
{
int ret;
unsigned int status;
// MSVC/vcpkg GnuTLS cast workaround
#if _WIN32 && (GNUTLS_VERSION_NUMBER >= 0x030807)
ret = gnutls_ocsp_resp_get_single(response,
0,
NULL,
NULL,
NULL,
NULL,
reinterpret_cast<gnutls_ocsp_cert_status_t*>(& status),
NULL,
NULL,
NULL,
NULL);
#else
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status, NULL, NULL, NULL, NULL);
#endif
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
return (gnutls_ocsp_cert_status_t) status;
@@ -1574,23 +1533,8 @@ OcspResponse::verifyDirect(const Certificate& crt, const Blob& nonce)
throw CryptoException(gnutls_strerror(ret));
// Check certificate revocation status
unsigned int status_ocsp;
// MSVC/vcpkg GnuTLS cast workaround
#if _WIN32 && (GNUTLS_VERSION_NUMBER >= 0x030807)
ret = gnutls_ocsp_resp_get_single(response,
0,
NULL,
NULL,
NULL,
NULL,
reinterpret_cast<gnutls_ocsp_cert_status_t*>(& status_ocsp),
NULL,
NULL,
NULL,
NULL);
#else
unsigned status_ocsp;
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status_ocsp, NULL, NULL, NULL, NULL);
#endif
if (ret < 0)
throw CryptoException(gnutls_strerror(ret));
return (gnutls_ocsp_cert_status_t)status_ocsp;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+68 -68
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
*
@@ -113,7 +113,7 @@ Dht::shutdown(ShutdownCallback cb, bool stop)
auto str_donecb = [=](bool, const std::vector<Sp<Node>>&) {
--*remaining;
if (logger_)
logger_->w("Shutting down node: %u ops remaining", *remaining);
logger_->w("shuting down node: %u ops remaining", *remaining);
if (!*remaining && cb) { cb(); }
};
@@ -121,7 +121,7 @@ Dht::shutdown(ShutdownCallback cb, bool stop)
*remaining += maintainStorage(str, true, str_donecb);
if (logger_)
logger_->w("Shutting down node: after storage, %u ops", *remaining);
logger_->w("shuting down node: after storage, %u ops", *remaining);
if (!*remaining) {
if (cb) cb();
@@ -147,7 +147,7 @@ Dht::sendCachedPing(Bucket& b)
{
if (b.cached)
if (logger_)
logger_->d(b.cached->id, "[node %s] Sending ping to cached node", b.cached->toString().c_str());
logger_->d(b.cached->id, "[node %s] sending ping to cached node", b.cached->toString().c_str());
b.sendCachedPing(network_engine);
}
@@ -280,7 +280,7 @@ Dht::expireSearches()
auto b = sr.callbacks.empty() && sr.announce.empty() && sr.listeners.empty() && sr.step_time < t;
if (b) {
if (logger_)
logger_->d(srp.first, "[search %s] Removing search", srp.first.toString().c_str());
logger_->d(srp.first, "[search %s] removing search", srp.first.toString().c_str());
sr.clear();
return b;
} else { return false; }
@@ -360,7 +360,7 @@ void Dht::paginate(std::weak_ptr<Search> ws, Sp<Query> query, SearchNode* n) {
auto query_for_vid = std::make_shared<Query>(Select {}, Where {}.id(vid));
sn->pagination_queries[query].push_back(query_for_vid);
if (logger_)
logger_->d(id, sn->node->id, "[search %s] [node %s] Sending %s",
logger_->d(id, sn->node->id, "[search %s] [node %s] sending %s",
id.toString().c_str(), sn->node->toString().c_str(), query_for_vid->toString().c_str());
sn->getStatus[query_for_vid] = network_engine.sendGetValues(status.node,
id,
@@ -371,8 +371,8 @@ void Dht::paginate(std::weak_ptr<Search> ws, Sp<Query> query, SearchNode* n) {
);
} catch (const std::out_of_range&) {
if (logger_)
logger_->e(id, sn->node->id, "[search %s] [node %s] Received non-id field in response to "\
"'SELECT id' request…",
logger_->e(id, sn->node->id, "[search %s] [node %s] received non-id field in response to "\
"'SELECT id' request...",
id.toString().c_str(), sn->node->toString().c_str());
}
}
@@ -381,7 +381,7 @@ void Dht::paginate(std::weak_ptr<Search> ws, Sp<Query> query, SearchNode* n) {
n->pagination_queries[query].push_back(select_q);
if (logger_)
logger_->d(sr->id, n->node->id, "[search %s] [node %s] Sending %s",
logger_->d(sr->id, n->node->id, "[search %s] [node %s] sending %s",
sr->id.toString().c_str(), n->node->toString().c_str(), select_q->toString().c_str());
n->getStatus[select_q] = network_engine.sendGetValues(n->node,
sr->id,
@@ -426,7 +426,7 @@ Dht::searchSendGetValues(Sp<Search> sr, SearchNode* pn, bool update)
return nullptr;
/* if (logger_)
logger_->d(sr->id, n->node->id, "[search %s] [node %s] Sending 'find_node'",
logger_->d(sr->id, n->node->id, "[search %s] [node %s] sending 'find_node'",
sr->id.toString().c_str(), n->node->toString().c_str());*/
n->getStatus[query] = network_engine.sendFindNode(n->node,
sr->id,
@@ -439,9 +439,9 @@ Dht::searchSendGetValues(Sp<Search> sr, SearchNode* pn, bool update)
continue;
if (query and not query->select.empty()) {
/* The request contains a select. No need to paginate… */
/* The request contains a select. No need to paginate... */
/* if (logger_)
logger_->d(sr->id, n->node->id, "[search %s] [node %s] Sending 'get'",
logger_->d(sr->id, n->node->id, "[search %s] [node %s] sending 'get'",
sr->id.toString().c_str(), n->node->toString().c_str());*/
n->getStatus[query] = network_engine.sendGetValues(n->node,
sr->id,
@@ -453,7 +453,7 @@ Dht::searchSendGetValues(Sp<Search> sr, SearchNode* pn, bool update)
paginate(ws, query, n);
}
/* We only attempt to send one request. Return. */
/* We only try to send one request. return. */
return n;
} while (++cb != sr->callbacks.end());
@@ -519,7 +519,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel) {
/* only put the value if the node doesn't already have it */
if (not hasValue or seq_no < a.value->seq) {
if (logger_)
logger_->d(sr->id, sn->node->id, "[search %s] [node %s] Sending 'put' (vid: %016" PRIx64 ")",
logger_->d(sr->id, sn->node->id, "[search %s] [node %s] sending 'put' (vid: %016" PRIx64 ")",
sr->id.toString().c_str(), sn->node->toString().c_str(), a.value->id);
auto created = a.permanent ? time_point::max() : a.created;
acked = {
@@ -528,7 +528,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel) {
};
} else if (hasValue and a.permanent) {
if (logger_)
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] Sending 'refresh' (vid: %016" PRIx64 ")",
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] sending 'refresh' (vid: %016" PRIx64 ")",
sr->id.toString().c_str(), sn->node->toString().c_str(), a.value->id);
acked = {
network_engine.sendRefreshValue(sn->node, sr->id, a.value->id, sn->token, onDone,
@@ -540,7 +540,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel) {
](const net::Request& /*req*/, net::DhtProtocolException&& e){
if (e.getCode() == net::DhtProtocolException::NOT_FOUND) {
if (logger_)
logger_->e(node->id, "[node %s] Returned error 404: storage not found", node->toString().c_str());
logger_->e(node->id, "[node %s] returned error 404: storage not found", node->toString().c_str());
if (auto sr = ws.lock()) {
if (auto sn = sr->getNode(node)) {
sn->acked[v->id] = {
@@ -558,7 +558,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel) {
};
} else {
if (logger_)
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] Already has value (vid: %016" PRIx64 "). Aborting.",
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] already has value (vid: %016" PRIx64 "). Aborting.",
sr->id.toString().c_str(), sn->node->toString().c_str(), a.value->id);
auto ack_req = std::make_shared<net::Request>(net::Request::State::COMPLETED);
ack_req->reply_time = now;
@@ -594,7 +594,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel) {
sendQuery = true;
} else {
if (logger_)
logger_->w(sr->id, n.node->id, "[search %s] [node %s] Sending 'put' (vid: %016" PRIx64 ")",
logger_->w(sr->id, n.node->id, "[search %s] [node %s] sending 'put' (vid: %016" PRIx64 ")",
sr->id.toString().c_str(), n.node->toString().c_str(), a.value->id);
n.acked[a.value->id] = {
network_engine.sendAnnounceValue(n.node, sr->id, a.value, a.created, n.token, onDone, onExpired),
@@ -607,7 +607,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr, unsigned syncLevel) {
if (sendQuery) {
n.probe_query = PROBE_QUERY;
if (logger_)
logger_->d(sr->id, n.node->id, "[search %s] [node %s] Sending %s",
logger_->d(sr->id, n.node->id, "[search %s] [node %s] sending %s",
sr->id.toString().c_str(), n.node->toString().c_str(), n.probe_query->toString().c_str());
auto req = network_engine.sendGetValues(n.node,
sr->id,
@@ -634,7 +634,7 @@ Dht::searchSynchedNodeListen(const Sp<Search>& sr, SearchNode& n)
if (n.getListenTime(r, listenExp) > scheduler.time())
continue;
// if (logger_)
// logger_->d(sr->id, n.node->id, "[search %s] [node %s] Sending 'listen'",
// logger_->d(sr->id, n.node->id, "[search %s] [node %s] sending 'listen'",
// sr->id.toString().c_str(), n.node->toString().c_str());
if (r == n.listenStatus.end()) {
@@ -706,7 +706,7 @@ Dht::searchStep(std::weak_ptr<Search> ws)
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)",
logger_->d(sr->id, "[search %s IPv%c] step (%d requests)",
sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', req_count);*/
sr->step_time = now;
@@ -787,7 +787,7 @@ Dht::searchStep(std::weak_ptr<Search> ws)
if (sr->getNumberOfConsecutiveBadNodes() >= std::min<size_t>(sr->nodes.size(), SEARCH_MAX_BAD_NODES))
{
if (logger_)
logger_->w(sr->id, "[search %s IPv%c] Expired", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6');
logger_->w(sr->id, "[search %s IPv%c] expired", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6');
sr->expire();
if (not public_stable)
connectivityChanged(sr->af);
@@ -804,7 +804,7 @@ unsigned Dht::refill(Dht::Search& sr) {
if (cached_nodes.empty()) {
if (logger_)
logger_->e(sr.id, "[search %s IPv%c] No nodes from cache while refilling search",
logger_->e(sr.id, "[search %s IPv%c] no nodes from cache while refilling search",
sr.id.toString().c_str(), (sr.af == AF_INET) ? '4' : '6');
return 0;
}
@@ -816,7 +816,7 @@ unsigned Dht::refill(Dht::Search& sr) {
++inserted;
}
if (logger_)
logger_->d(sr.id, "[search %s IPv%c] Refilled search with %u nodes from node cache",
logger_->d(sr.id, "[search %s IPv%c] refilled search with %u nodes from node cache",
sr.id.toString().c_str(), (sr.af == AF_INET) ? '4' : '6', inserted);
return inserted;
}
@@ -828,7 +828,7 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback gcb, QueryCallback q
{
if (!isRunning(af)) {
if (logger_)
logger_->e(id, "[search %s IPv%c] Unsupported protocol", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
logger_->e(id, "[search %s IPv%c] unsupported protocol", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
if (dcb)
dcb(false, {});
return {};
@@ -856,7 +856,7 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback gcb, QueryCallback q
}
if (not sr) {
if (logger_)
logger_->e(id, "[search %s IPv%c] Maximum number of searches reached!", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
logger_->e(id, "[search %s IPv%c] maximum number of searches reached !", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
return {};
}
}
@@ -870,7 +870,7 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback gcb, QueryCallback q
sr->nodes.reserve(SEARCH_NODES+1);
sr->nextSearchStep = scheduler.add(time_point::max(), std::bind(&Dht::searchStep, this, std::weak_ptr<Search>(sr)));
if (logger_)
logger_->w(id, "[search %s IPv%c] New search", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
logger_->w(id, "[search %s IPv%c] new search", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
if (search_id == 0)
search_id++;
}
@@ -904,16 +904,16 @@ Dht::listenTo(const InfoHash& id, sa_family_t af, ValueCallback cb, Value::Filte
{
if (!isRunning(af))
return 0;
// logger__ERR("[search %s IPv%c] Search_time is now in %lfs", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', print_duration(tm-clock::now()));
// logger__ERR("[search %s IPv%c] search_time is now in %lfs", sr->id.toString().c_str(), (sr->af == AF_INET) ? '4' : '6', print_dt(tm-clock::now()));
//logger__WARN("listenTo %s", id.toString().c_str());
auto& srs = searches(af);
auto srp = srs.find(id);
Sp<Search> sr = (srp == srs.end()) ? search(id, af) : srp->second;
if (!sr)
throw DhtException("Unable to create search");
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');
logger_->w(id, "[search %s IPv%c] listen", id.to_c_str(), (af == AF_INET) ? '4' : '6');
return sr->listen(cb, std::move(f), q, scheduler);
}
@@ -1022,7 +1022,7 @@ Dht::put(const InfoHash& id, Sp<Value> val, DoneCallback callback, time_point cr
storageStore(id, val, created, {}, permanent);
if (logger_)
logger_->d(id, "put: adding %s → %s", id.toString().c_str(), val->toString().c_str());
logger_->d(id, "put: adding %s -> %s", id.toString().c_str(), val->toString().c_str());
auto op = std::make_shared<OpStatus>();
auto donecb = [callback](const std::vector<Sp<Node>>& nodes, OpStatus& op) {
@@ -1265,7 +1265,7 @@ Dht::storageChanged(const InfoHash& id, Storage& st, const Sp<Value>& v, bool ne
vals.push_back(v);
if (not vals.empty()) {
if (logger_)
logger_->d(id, "[store %s] Sending update local listener with token %lu",
logger_->d(id, "[store %s] sending update local listener with token %lu",
id.toString().c_str(),
l.first);
cbs.emplace_back(l.second.get_cb, std::move(vals));
@@ -1286,7 +1286,7 @@ Dht::storageChanged(const InfoHash& id, Storage& st, const Sp<Value>& v, bool ne
if (f and not f(*v))
continue;
if (logger_)
logger_->w(id, node_listeners.first->id, "[store %s] [node %s] Sending update",
logger_->w(id, node_listeners.first->id, "[store %s] [node %s] sending update",
id.toString().c_str(),
node_listeners.first->toString().c_str());
std::vector<Sp<Value>> vals {};
@@ -1392,7 +1392,7 @@ void
Dht::storageRemoved(const InfoHash& id, Storage& st, const std::vector<Sp<Value>>& values, size_t totalSize)
{
if (logger_)
logger_->d(id, "[store %s] Discarded %ld values (%ld bytes)",
logger_->d(id, "[store %s] discarded %ld values (%ld bytes)",
id.toString().c_str(), values.size(), totalSize);
total_store_size -= totalSize;
@@ -1410,7 +1410,7 @@ Dht::storageRemoved(const InfoHash& id, Storage& st, const std::vector<Sp<Value>
for (const auto& node_listeners : st.listeners) {
for (const auto& l : node_listeners.second) {
if (logger_)
logger_->w(id, node_listeners.first->id, "[store %s] [node %s] Sending expired",
logger_->w(id, node_listeners.first->id, "[store %s] [node %s] sending expired",
id.toString().c_str(),
node_listeners.first->toString().c_str());
Blob ntoken = makeToken(node_listeners.first->getAddr(), false);
@@ -1432,7 +1432,7 @@ Dht::expireStore()
if (i->second.empty() && i->second.listeners.empty() && i->second.local_listeners.empty()) {
if (logger_)
logger_->d(i->first, "[store %s] Discarding empty storage", i->first.toString().c_str());
logger_->d(i->first, "[store %s] discarding empty storage", i->first.toString().c_str());
i = store.erase(i);
}
else
@@ -1900,7 +1900,7 @@ Dht::neighbourhoodMaintenance(RoutingTable& list)
auto n = q->randomNode(rd);
if (n) {
if (logger_)
logger_->d(id, n->id, "[node %s] Sending [find %s] for neighborhood maintenance",
logger_->d(id, n->id, "[node %s] sending [find %s] for neighborhood maintenance",
n->toString().c_str(), id.toString().c_str());
/* Since our node-id is the same in both DHTs, it's probably
profitable to query both families. */
@@ -1954,14 +1954,14 @@ Dht::bucketMaintenance(RoutingTable& list)
}
if (logger_)
logger_->d(id, n->id, "[node %s] Sending find %s for bucket maintenance", n->toString().c_str(), id.toString().c_str());
logger_->d(id, n->id, "[node %s] sending find %s for bucket maintenance", n->toString().c_str(), id.toString().c_str());
//auto start = scheduler.time();
network_engine.sendFindNode(n, id, want, nullptr, [this,n](const net::Request&, bool over) {
if (over) {
const auto& end = scheduler.time();
// using namespace std::chrono;
// if (logger_)
// logger_->d(n->id, "[node %s] Bucket maintenance op expired after %s", n->toString().c_str(), print_duration(end-start).c_str());
// logger_->d(n->id, "[node %s] bucket maintenance op expired after %s", n->toString().c_str(), print_duration(end-start).c_str());
scheduler.edit(nextNodesConfirmation, end + Node::MAX_RESPONSE_TIME);
}
});
@@ -1979,7 +1979,7 @@ Dht::dataPersistence(InfoHash id)
auto str = store.find(id);
if (str != store.end() and now > str->second.maintenance_time) {
if (logger_)
logger_->d(id, "[storage %s] Maintenance (%u values, %u bytes)",
logger_->d(id, "[storage %s] maintenance (%u values, %u bytes)",
id.toString().c_str(), str->second.valueCount(), str->second.totalSize());
maintainStorage(*str);
str->second.maintenance_time = now + MAX_STORAGE_MAINTENANCE_EXPIRE_TIME;
@@ -2033,7 +2033,7 @@ Dht::periodic(const uint8_t *buf, size_t buflen, SockAddr from, const time_point
network_engine.processMessage(buf, buflen, std::move(from));
} catch (const std::exception& e) {
if (logger_)
logger_->w("Unable to process message: %s", e.what());
logger_->w("Can't process message: %s", e.what());
}
}
return scheduler.run();
@@ -2087,7 +2087,7 @@ Dht::bootstrap()
}
} catch (const std::exception& e) {
if (logger_)
logger_->e(myid, "Unable to resolve %s:%s: %s", boootstrap.first.c_str(), boootstrap.second.c_str(), e.what());
logger_->e(myid, "Can't resolve %s:%s: %s", boootstrap.first.c_str(), boootstrap.second.c_str(), e.what());
}
}
scheduler.cancel(bootstrapJob);
@@ -2118,12 +2118,12 @@ Dht::confirmNodes()
if (dht4.searches.empty() and dht4.status == NodeStatus::Connected) {
if (logger_)
logger_->d(myid, "[confirm nodes] Initial IPv4 'get' for my id (%s)", myid.toString().c_str());
logger_->d(myid, "[confirm nodes] initial IPv4 'get' for my id (%s)", myid.toString().c_str());
search(myid, AF_INET);
}
if (dht6.searches.empty() and dht6.status == NodeStatus::Connected) {
if (logger_)
logger_->d(myid, "[confirm nodes] Initial IPv6 'get' for my id (%s)", myid.toString().c_str());
logger_->d(myid, "[confirm nodes] initial IPv6 'get' for my id (%s)", myid.toString().c_str());
search(myid, AF_INET6);
}
@@ -2281,7 +2281,7 @@ Dht::onError(Sp<net::Request> req, net::DhtProtocolException e) {
const auto& node = req->node;
if (e.getCode() == net::DhtProtocolException::UNAUTHORIZED) {
if (logger_)
logger_->e(node->id, "[node %s] Token flush", node->toString().c_str());
logger_->e(node->id, "[node %s] token flush", node->toString().c_str());
node->authError();
for (auto& srp : searches(node->getFamily())) {
auto& sr = srp.second;
@@ -2296,7 +2296,7 @@ Dht::onError(Sp<net::Request> req, net::DhtProtocolException e) {
}
} else if (e.getCode() == net::DhtProtocolException::NOT_FOUND) {
if (logger_)
logger_->e(node->id, "[node %s] Returned error 404: storage not found", node->toString().c_str());
logger_->e(node->id, "[node %s] returned error 404: storage not found", node->toString().c_str());
node->cancelRequest(req);
}
}
@@ -2347,7 +2347,7 @@ Dht::onGetValues(Sp<Node> node, const InfoHash& hash, want_t, const Query& query
if (st != store.end() && not st->second.empty()) {
answer.values = st->second.get(query.where.getFilter());
if (logger_)
logger_->d(hash, "[node %s] Sending %u values", node->toString().c_str(), answer.values.size());
logger_->d(hash, "[node %s] sending %u values", node->toString().c_str(), answer.values.size());
}
return answer;
}
@@ -2359,18 +2359,18 @@ void Dht::onGetValuesDone(const Sp<Node>& node,
{
if (not sr) {
if (logger_)
logger_->w("[search unknown] Got reply to 'get'. Ignoring.");
logger_->w("[search unknown] got reply to 'get'. Ignoring.");
return;
}
/* if (logger_)
logger_->d(sr->id, "[search %s] [node %s] Got reply to 'get' with %u nodes",
logger_->d(sr->id, "[search %s] [node %s] got reply to 'get' with %u nodes",
sr->id.toString().c_str(), node->toString().c_str(), a.nodes4.size()+a.nodes6.size());*/
if (not a.ntoken.empty()) {
if (not a.values.empty() or not a.fields.empty()) {
if (logger_)
logger_->d(sr->id, node->id, "[search %s] [node %s] Found %u values",
logger_->d(sr->id, node->id, "[search %s] [node %s] found %u values",
sr->id.toString().c_str(), node->toString().c_str(), a.values.size());
for (auto& getp : sr->callbacks) { /* call all callbacks for this search */
auto& get = getp.second;
@@ -2419,7 +2419,7 @@ void Dht::onGetValuesDone(const Sp<Node>& node,
}
} else {
if (logger_)
logger_->w(sr->id, "[node %s] No token provided. Ignoring response content.", node->toString().c_str());
logger_->w(sr->id, "[node %s] no token provided. Ignoring response content.", node->toString().c_str());
network_engine.blacklistNode(node);
}
@@ -2436,7 +2436,7 @@ Dht::onListen(Sp<Node> node, const InfoHash& hash, const Blob& token, size_t soc
{
if (not hash) {
if (logger_)
logger_->w(node->id, "[node %s] Listen with no info_hash", node->toString().c_str());
logger_->w(node->id, "[node %s] listen with no info_hash", node->toString().c_str());
throw net::DhtProtocolException {
net::DhtProtocolException::NON_AUTHORITATIVE_INFORMATION,
net::DhtProtocolException::LISTEN_NO_INFOHASH
@@ -2444,7 +2444,7 @@ Dht::onListen(Sp<Node> node, const InfoHash& hash, const Blob& token, size_t soc
}
if (not tokenMatch(token, node->getAddr())) {
if (logger_)
logger_->w(hash, node->id, "[node %s] Incorrect token %s for 'listen'", node->toString().c_str(), hash.toString().c_str());
logger_->w(hash, node->id, "[node %s] incorrect token %s for 'listen'", node->toString().c_str(), hash.toString().c_str());
throw net::DhtProtocolException {net::DhtProtocolException::UNAUTHORIZED, net::DhtProtocolException::LISTEN_WRONG_TOKEN};
}
Query q = query;
@@ -2456,7 +2456,7 @@ void
Dht::onListenDone(const Sp<Node>& /* node */, net::RequestAnswer& /* answer */, Sp<Search>& sr)
{
// if (logger_)
// logger_->d(sr->id, node->id, "[search %s] [node %s] Got listen confirmation",
// logger_->d(sr->id, node->id, "[search %s] [node %s] got listen confirmation",
// sr->id.toString().c_str(), node->toString().c_str(), answer.values.size());
if (not sr->done) {
@@ -2476,7 +2476,7 @@ Dht::onAnnounce(Sp<Node> n,
auto& node = *n;
if (not hash) {
if (logger_)
logger_->w(node.id, "Put with no info_hash");
logger_->w(node.id, "put with no info_hash");
throw net::DhtProtocolException {
net::DhtProtocolException::NON_AUTHORITATIVE_INFORMATION,
net::DhtProtocolException::PUT_NO_INFOHASH
@@ -2484,7 +2484,7 @@ Dht::onAnnounce(Sp<Node> n,
}
if (!tokenMatch(token, node.getAddr())) {
if (logger_)
logger_->w(hash, node.id, "[node %s] Incorrect token %s for 'put'", node.toString().c_str(), hash.toString().c_str());
logger_->w(hash, node.id, "[node %s] incorrect token %s for 'put'", node.toString().c_str(), hash.toString().c_str());
throw net::DhtProtocolException {net::DhtProtocolException::UNAUTHORIZED, net::DhtProtocolException::PUT_WRONG_TOKEN};
}
{
@@ -2493,7 +2493,7 @@ Dht::onAnnounce(Sp<Node> n,
auto closest_nodes = buckets(node.getFamily()).findClosestNodes(hash, scheduler.time(), SEARCH_NODES);
if (closest_nodes.size() >= TARGET_NODES and hash.xorCmp(closest_nodes.back()->id, myid) < 0) {
if (logger_)
logger_->w(hash, node.id, "[node %s] Announce too far from the target. Dropping value.", node.toString().c_str());
logger_->w(hash, node.id, "[node %s] announce too far from the target. Dropping value.", node.toString().c_str());
return {};
}
}
@@ -2502,7 +2502,7 @@ Dht::onAnnounce(Sp<Node> n,
for (const auto& v : values) {
if (v->id == Value::INVALID_ID) {
if (logger_)
logger_->w(hash, node.id, "[value %s] Incorrect value id", hash.toString().c_str());
logger_->w(hash, node.id, "[value %s] incorrect value id", hash.toString().c_str());
throw net::DhtProtocolException {
net::DhtProtocolException::NON_AUTHORITATIVE_INFORMATION,
net::DhtProtocolException::PUT_INVALID_ID
@@ -2514,17 +2514,17 @@ Dht::onAnnounce(Sp<Node> n,
if (*lv == *vc) {
storageRefresh(hash, v->id);
if (logger_)
logger_->d(hash, node.id, "[store %s] [node %s] Refreshed value %016" PRIx64, hash.toString().c_str(), node.toString().c_str(), v->id);
logger_->d(hash, node.id, "[store %s] [node %s] refreshed value %016" PRIx64, hash.toString().c_str(), node.toString().c_str(), v->id);
} else {
const auto& type = getType(lv->type);
if (type.editPolicy(hash, lv, vc, node.id, node.getAddr())) {
if (logger_)
logger_->d(hash, node.id, "[store %s] Editing %s",
logger_->d(hash, node.id, "[store %s] editing %s",
hash.toString().c_str(), vc->toString().c_str());
storageStore(hash, vc, created, node.getAddr());
} else {
if (logger_)
logger_->d(hash, node.id, "[store %s] Rejecting edition of %s because of storage policy",
logger_->d(hash, node.id, "[store %s] rejecting edition of %s because of storage policy",
hash.toString().c_str(), vc->toString().c_str());
}
}
@@ -2533,11 +2533,11 @@ Dht::onAnnounce(Sp<Node> n,
const auto& type = getType(vc->type);
if (type.storePolicy(hash, vc, node.id, node.getAddr())) {
// if (logger_)
// logger_->d(hash, node.id, "[store %s] Storing %s", hash.toString().c_str(), std::to_string(vc->id).c_str());
// logger_->d(hash, node.id, "[store %s] storing %s", hash.toString().c_str(), std::to_string(vc->id).c_str());
storageStore(hash, vc, created, node.getAddr());
} else {
if (logger_)
logger_->d(hash, node.id, "[store %s] Rejecting storage of %s",
logger_->d(hash, node.id, "[store %s] rejecting storage of %s",
hash.toString().c_str(), vc->toString().c_str());
}
}
@@ -2552,15 +2552,15 @@ Dht::onRefresh(Sp<Node> node, const InfoHash& hash, const Blob& token, const Val
if (not tokenMatch(token, node->getAddr())) {
if (logger_)
logger_->w(hash, node->id, "[node %s] Incorrect token %s for 'put'", node->toString().c_str(), hash.toString().c_str());
logger_->w(hash, node->id, "[node %s] incorrect token %s for 'put'", node->toString().c_str(), hash.toString().c_str());
throw DhtProtocolException {DhtProtocolException::UNAUTHORIZED, DhtProtocolException::PUT_WRONG_TOKEN};
}
if (storageRefresh(hash, vid)) {
if (logger_)
logger_->d(hash, node->id, "[store %s] [node %s] Refreshed value %016" PRIx64, hash.toString().c_str(), node->toString().c_str(), vid);
logger_->d(hash, node->id, "[store %s] [node %s] refreshed value %016" PRIx64, hash.toString().c_str(), node->toString().c_str(), vid);
} else {
if (logger_)
logger_->d(hash, node->id, "[store %s] [node %s] Got refresh for unknown value",
logger_->d(hash, node->id, "[store %s] [node %s] got refresh for unknown value",
hash.toString().c_str(), node->toString().c_str());
throw DhtProtocolException {DhtProtocolException::NOT_FOUND, DhtProtocolException::STORAGE_NOT_FOUND};
}
@@ -2583,7 +2583,7 @@ Dht::storageRefresh(const InfoHash& id, Value::Id vid)
for (const auto& node_listeners : st.listeners) {
for (const auto& l : node_listeners.second) {
if (logger_)
logger_->w(id, node_listeners.first->id, "[store %s] [node %s] Sending refresh",
logger_->w(id, node_listeners.first->id, "[store %s] [node %s] sending refresh",
id.toString().c_str(),
node_listeners.first->toString().c_str());
Blob ntoken = makeToken(node_listeners.first->getAddr(), false);
@@ -2608,7 +2608,7 @@ void
Dht::onAnnounceDone(const Sp<Node>& node, net::RequestAnswer& answer, Sp<Search>& sr)
{
if (logger_)
logger_->d(sr->id, node->id, "[search %s] [node %s] Got reply to put!",
logger_->d(sr->id, node->id, "[search %s] [node %s] got reply to put!",
sr->id.toString().c_str(), node->toString().c_str());
searchSendGetValues(sr);
sr->checkAnnounced(answer.vid);
+10 -17
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -813,8 +813,8 @@ SockAddr
DhtProxyClient::parsePublicAddress(const Json::Value& val)
{
auto public_ip = val.asString();
auto [host, service] = splitPort(public_ip);
auto sa = SockAddr::resolve(host);
auto hostAndService = splitPort(public_ip);
auto sa = SockAddr::resolve(hostAndService.first);
if (sa.empty()) return {};
return sa.front().getMappedIPv4();
}
@@ -1121,10 +1121,12 @@ DhtProxyClient::sendListen(const restinio::http_request_header_t& header,
std::lock_guard<std::mutex> l(requestLock_);
requests_[reqid] = request;
}
request->add_on_status_callback([request, seconds = this->listenKeepIdle()] (unsigned status_code) {
request->add_on_status_callback([r=std::weak_ptr(request), seconds = this->listenKeepIdle()] (unsigned status_code) {
if(status_code == 200) {
// increase TCP_KEEPIDLE to save power
request->get_connection()->set_keepalive(seconds);
if (auto request = r.lock()) {
request->get_connection()->set_keepalive(seconds);
}
}
});
request->send();
@@ -1233,10 +1235,9 @@ DhtProxyClient::restartListeners(const asio::error_code &ec)
}
}
PushNotificationResult
void
DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::string, std::string>& notification)
{
auto ret = PushNotificationResult::IgnoredNoOp;
#ifdef OPENDHT_PUSH_NOTIFICATIONS
{
// If a push notification is received, the proxy is up and running
@@ -1253,7 +1254,7 @@ DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::st
if (sessionId != notification.end() and sessionId->second != pushSessionId_) {
if (logger_)
logger_->d("[proxy:client] [push] ignoring push for other session");
return PushNotificationResult::IgnoredWrongSession;
return;
}
std::lock_guard<std::mutex> lock(searchLock_);
auto timeout = notification.find("timeout");
@@ -1270,12 +1271,10 @@ DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::st
else
put.refreshPutTimer->expires_at(std::chrono::steady_clock::now());
put.refreshPutTimer->async_wait(std::bind(&DhtProxyClient::handleRefreshPut, this, std::placeholders::_1, key, vid));
ret = PushNotificationResult::PutRefresh;
} else {
// Refresh listen
for (auto& list : search.listeners)
resubscribe(key, list.first, list.second);
ret = search.listeners.empty() ? PushNotificationResult::IgnoredNoOp : PushNotificationResult::ListenRefresh;
}
} else {
auto key = InfoHash(notification.at("key"));
@@ -1284,12 +1283,12 @@ DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::st
sendTime = system_clock::time_point(std::chrono::milliseconds(std::stoull(notification.at("t"))));
} catch (...) {}
auto& search = searches_.at(key);
auto expired = notification.find("exp");
for (auto& list : search.listeners) {
if (list.second.opstate->stop)
continue;
if (logger_)
logger_->d("[proxy:client] [push] [search %s] received", key.to_c_str());
auto expired = notification.find("exp");
auto token = list.first;
auto opstate = list.second.opstate;
if (expired == notification.end()) {
@@ -1302,7 +1301,6 @@ DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::st
// present in the new list
cb(oldValues, true, sendTime);
});
ret = PushNotificationResult::Values;
} else {
std::stringstream ss(expired->second);
std::vector<Value::Id> ids;
@@ -1328,21 +1326,16 @@ DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::st
});
}
launchLoop = true;
ret = PushNotificationResult::ValuesExpired;
}
}
}
} catch (const std::out_of_range& e) {
ret = PushNotificationResult::IgnoredNoOp;
} catch (const std::exception& e) {
if (logger_)
logger_->e("[proxy:client] [push] receive error: %s", e.what());
ret = PushNotificationResult::Error;
}
if (launchLoop)
loopSignal_();
#endif
return ret;
}
void
+1 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -631,8 +631,6 @@ DhtProxyServer::createRestRouter()
router->http_get("/key/:hash", std::bind(&DhtProxyServer::get, this, _1, _2));
// key.post
router->http_post("/key/:hash", std::bind(&DhtProxyServer::put, this, _1, _2));
router->add_handler(restinio::http_method_options(),
"/key/:hash/listen", std::bind(&DhtProxyServer::options, this, _1, _2));
// key.listen
router->http_get("/key/:hash/listen", std::bind(&DhtProxyServer::listen, this, _1, _2));
#ifdef OPENDHT_PUSH_NOTIFICATIONS
+8 -53
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -36,9 +36,7 @@
namespace dht {
using namespace std::literals;
constexpr auto PEER_DISCOVERY_DHT_SERVICE = "dht"sv;
static const std::string PEER_DISCOVERY_DHT_SERVICE = "dht";
struct NodeInsertionPack {
dht::InfoHash nodeId;
@@ -621,7 +619,7 @@ DhtRunner::getPublicAddress(std::function<void(std::vector<SockAddr>&&)> cb, sa_
}
void
DhtRunner::registerCertificate(const std::shared_ptr<crypto::Certificate>& cert) {
DhtRunner::registerCertificate(std::shared_ptr<crypto::Certificate> cert) {
std::lock_guard<std::mutex> lck(dht_mtx);
dht_->registerCertificate(cert);
}
@@ -890,25 +888,6 @@ DhtRunner::putSigned(const std::string& key, Value&& value, DoneCallbackSimple c
putSigned(InfoHash::get(key), std::forward<Value>(value), std::move(cb), permanent);
}
void
DhtRunner::putEncrypted(InfoHash hash, const PkId& to, std::shared_ptr<Value> value, DoneCallback cb, bool permanent)
{
std::unique_lock<std::mutex> lck(storage_mtx);
if (running != State::Running) {
lck.unlock();
if (cb) cb(false, {});
return;
}
ongoing_ops++;
pending_ops.emplace([=,
cb = std::move(cb),
value = std::move(value)
] (SecureDht& dht) mutable {
dht.putEncrypted(hash, to, value, bindOpDoneCallback(std::move(cb)), permanent);
});
cv.notify_all();
}
void
DhtRunner::putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallback cb, bool permanent)
{
@@ -1098,23 +1077,6 @@ DhtRunner::findCertificate(InfoHash hash, std::function<void(const Sp<crypto::Ce
cv.notify_all();
}
void DhtRunner::findCertificate(PkId hash, std::function<void(const std::shared_ptr<crypto::Certificate>&)> cb)
{
std::unique_lock<std::mutex> lck(storage_mtx);
if (running != State::Running) {
lck.unlock();
return;
}
ongoing_ops++;
pending_ops.emplace([this, hash, cb = std::move(cb)] (SecureDht& dht) {
dht.findCertificate(hash, [this, cb = std::move(cb)](const Sp<crypto::Certificate>& crt){
cb(crt);
opEnded();
});
});
cv.notify_all();
}
void
DhtRunner::resetDht()
{
@@ -1224,25 +1186,18 @@ DhtRunner::setPushNotificationPlatform(const std::string& platform) {
#endif
}
std::future<PushNotificationResult>
DhtRunner::pushNotificationReceived([[maybe_unused]] const std::map<std::string, std::string>& data)
void
DhtRunner::pushNotificationReceived(const std::map<std::string, std::string>& data)
{
#if defined(OPENDHT_PROXY_CLIENT) && defined(OPENDHT_PUSH_NOTIFICATIONS)
auto ret_token = std::make_shared<std::promise<PushNotificationResult>>();
auto future = ret_token->get_future();
std::lock_guard<std::mutex> lck(storage_mtx);
pending_ops_prio.emplace([ret_token, this, data](SecureDht&) {
pending_ops_prio.emplace([=](SecureDht&) {
if (dht_)
ret_token->set_value(dht_->pushNotificationReceived(data));
else
ret_token->set_value(PushNotificationResult::IgnoredStopped);
dht_->pushNotificationReceived(data);
});
cv.notify_all();
return future;
#else
std::promise<PushNotificationResult> p {};
p.set_value(PushNotificationResult::IgnoredDisabled);
return p.get_future();
(void) data;
#endif
}
+19 -29
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -54,7 +54,7 @@ constexpr const char HTTPS_PROTOCOL[] = "https://";
constexpr const char ORIGIN_PROTOCOL[] = "//";
constexpr unsigned MAX_REDIRECTS {5};
Url::Url(std::string_view url): url(url)
Url::Url(const std::string& url): url(url)
{
size_t addr_begin = 0;
// protocol
@@ -69,9 +69,10 @@ Url::Url(std::string_view url): url(url)
size_t addr_size = url.substr(addr_begin).find("/");
if (addr_size == std::string::npos)
addr_size = url.size() - addr_begin;
auto [h, s] = splitPort(url.substr(addr_begin, addr_size));
host = std::move(h);
service = std::move(s);
auto host_service = splitPort(url.substr(addr_begin, addr_size));
host = host_service.first;
if (!host_service.second.empty())
service = host_service.second;
// target, query and fragment
size_t query_begin = url.find("?");
auto addr_end = addr_begin + addr_size;
@@ -456,7 +457,7 @@ Connection::set_ssl_verification(const std::string& hostname, const asio::ssl::v
}
// starts from CA and goes down the presented chain
auto verifier = asio::ssl::host_name_verification(hostname);
auto verifier = asio::ssl::rfc2818_verification(hostname);
bool verified = verifier(preverified, ctx);
auto verify_ec = X509_STORE_CTX_get_error(ctx.native_handle());
if (verify_ec != 0 /*X509_V_OK*/ and logger)
@@ -591,12 +592,12 @@ Connection::async_write(BytesHandlerCb cb)
{
std::lock_guard<std::mutex> lock(mutex_);
if (!is_open()) {
if (cb) asio::post(ctx_, [cb](){ cb(asio::error::broken_pipe, 0); });
if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); });
return;
}
if (ssl_socket_) asio::async_write(*ssl_socket_, write_buf_, wrapCallback(std::move(cb)));
else if (socket_) asio::async_write(*socket_, write_buf_, wrapCallback(std::move(cb)));
else if (cb) asio::post(ctx_, [cb](){ cb(asio::error::operation_aborted, 0); });
else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); });
}
void
@@ -604,12 +605,12 @@ Connection::async_read_until(const char* delim, BytesHandlerCb cb)
{
std::lock_guard<std::mutex> lock(mutex_);
if (!is_open()) {
if (cb) asio::post(ctx_, [cb](){ cb(asio::error::broken_pipe, 0); });
if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); });
return;
}
if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallback(std::move(cb)));
else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallback(std::move(cb)));
else if (cb) asio::post(ctx_, [cb](){ cb(asio::error::operation_aborted, 0); });
else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); });
}
void
@@ -617,12 +618,12 @@ Connection::async_read_until(char delim, BytesHandlerCb cb)
{
std::lock_guard<std::mutex> lock(mutex_);
if (!is_open()) {
if (cb) asio::post(ctx_, [cb](){ cb(asio::error::broken_pipe, 0); });
if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); });
return;
}
if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallback(std::move(cb)));
else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallback(std::move(cb)));
else if (cb) asio::post(ctx_, [cb](){ cb(asio::error::operation_aborted, 0); });
else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); });
}
void
@@ -630,12 +631,12 @@ Connection::async_read(size_t bytes, BytesHandlerCb cb)
{
std::lock_guard<std::mutex> lock(mutex_);
if (!is_open()) {
if (cb) asio::post(ctx_, [cb](){ cb(asio::error::broken_pipe, 0); });
if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); });
return;
}
if (ssl_socket_) asio::async_read(*ssl_socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallback(std::move(cb)));
else if (socket_) asio::async_read(*socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallback(std::move(cb)));
else if (cb) asio::post(ctx_, [cb](){ cb(asio::error::operation_aborted, 0); });
else if (cb) ctx_.post([cb](){ cb(asio::error::operation_aborted, 0); });
}
void
@@ -643,7 +644,7 @@ Connection::async_read_some(size_t bytes, BytesHandlerCb cb)
{
std::lock_guard<std::mutex> lock(mutex_);
if (!is_open()) {
if (cb) asio::post(ctx_, [cb](){ cb(asio::error::broken_pipe, 0); });
if (cb) ctx_.post([cb](){ cb(asio::error::broken_pipe, 0); });
return;
}
auto buf = read_buf_.prepare(bytes);
@@ -818,21 +819,10 @@ Resolver::add_callback(ResolverCb cb, sa_family_t family)
}
void
Resolver::resolve(const std::string& host, const std::string& serviceName)
Resolver::resolve(const std::string& host, const std::string& service)
{
auto service = serviceName;
// The async_resolve function used below typically relies on the contents of the
// /etc/services (Linux/POSIX) or c:\windows\system32\drivers\etc\services (Windows)
// file in order to resolve a descriptive service name into a port number. A
// resolution attempt that would otherwise succeed can therefore fail if the file
// is inaccessible or corrupted (which is rare but can happen in practice). We
// hardcode the port numbers for http and https to prevent this failure mode.
if (service == "http") {
service = "80";
} else if (service == "https") {
service = "443";
}
resolver_.async_resolve(host, service, [this, host, service, destroyed = destroyed_]
asio::ip::tcp::resolver::query query_(host, service);
resolver_.async_resolve(query_, [this, host, service, destroyed = destroyed_]
(const asio::error_code& ec, asio::ip::tcp::resolver::results_type endpoints)
{
if (ec == asio::error::operation_aborted or *destroyed)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+8 -22
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
*
@@ -526,13 +526,8 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
throw DhtProtocolException {DhtProtocolException::UNKNOWN_TID, "Can't find socket", msg->id};
node->received(now, {});
onNewNode(node, 2);
try {
deserializeNodes(*msg, from);
rsocket->on_receive(node, std::move(*msg));
} catch (const DhtProtocolException& e) {
if (logger_)
logger_->w("Can't deserialize nodes %s", e.what());
}
deserializeNodes(*msg, from);
rsocket->on_receive(node, std::move(*msg));
}
else if (msg->type == MessageType::Error or msg->type == MessageType::Reply) {
auto rsocket = node->getSocket(msg->tid);
@@ -595,22 +590,13 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
r.node->authSuccess();
}
r.reply_time = scheduler.time();
try {
deserializeNodes(*msg, from);
r.setDone(std::move(*msg));
} catch (const DhtProtocolException& e) {
if (logger_)
logger_->w("Can't deserialize nodes %s", e.what());
}
deserializeNodes(*msg, from);
r.setDone(std::move(*msg));
break;
} else { /* request socket data */
try {
deserializeNodes(*msg, from);
rsocket->on_receive(node, std::move(*msg));
} catch (const DhtProtocolException& e) {
if (logger_)
logger_->w("Can't deserialize nodes %s", e.what());
}
deserializeNodes(*msg, from);
rsocket->on_receive(node, std::move(*msg));
}
break;
default:
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+24 -28
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -42,13 +42,13 @@ public:
DomainPeerDiscovery(asio::ip::udp domain, in_port_t port, Sp<asio::io_context> ioContext = {}, Sp<Logger> logger = {});
~DomainPeerDiscovery();
void startDiscovery(std::string_view type, ServiceDiscoveredCallback callback);
void startPublish(std::string_view type, const msgpack::sbuffer &pack_buf);
void startDiscovery(const std::string &type, ServiceDiscoveredCallback callback);
void startPublish(const std::string &type, const msgpack::sbuffer &pack_buf);
void stop();
bool stopDiscovery(std::string_view type);
bool stopPublish(std::string_view type);
bool stopDiscovery(const std::string &type);
bool stopPublish(const std::string &type);
void connectivityChanged();
@@ -75,7 +75,7 @@ private:
asio::ip::udp::endpoint receiveFrom_;
msgpack::sbuffer sbuf_;
std::map<std::string, msgpack::sbuffer, std::less<>> messages_;
std::map<std::string, msgpack::sbuffer> messages_;
std::map<std::string, ServiceDiscoveredCallback, std::less<>> callbackmap_;
bool lrunning_ {false};
bool drunning_ {false};
@@ -97,7 +97,7 @@ PeerDiscovery::DomainPeerDiscovery::DomainPeerDiscovery(asio::ip::udp domain, in
, ioContext_(ioContext)
, peerDiscoveryTimer(*ioContext_)
, sockFd_(*ioContext_, domain)
, sockAddrSend_(asio::ip::make_address(domain.family() == AF_INET ? MULTICAST_ADDRESS_IPV4
, sockAddrSend_(asio::ip::address::from_string(domain.family() == AF_INET ? MULTICAST_ADDRESS_IPV4
: MULTICAST_ADDRESS_IPV6), port)
{
try {
@@ -133,13 +133,13 @@ PeerDiscovery::DomainPeerDiscovery::~DomainPeerDiscovery()
}
void
PeerDiscovery::DomainPeerDiscovery::startDiscovery(std::string_view type, ServiceDiscoveredCallback callback)
PeerDiscovery::DomainPeerDiscovery::startDiscovery(const std::string &type, ServiceDiscoveredCallback callback)
{
std::lock_guard<std::mutex> lck(dmtx_);
callbackmap_[std::string(type)] = callback;
callbackmap_[type] = callback;
if (not drunning_) {
drunning_ = true;
asio::post(*ioContext_, [this] () {
ioContext_->post([this] () {
loopListener();
query(sockAddrSend_);
});
@@ -236,25 +236,23 @@ PeerDiscovery::DomainPeerDiscovery::publish(const asio::ip::udp::endpoint& peer)
void
PeerDiscovery::DomainPeerDiscovery::startPublish(std::string_view type, const msgpack::sbuffer &pack_buf)
PeerDiscovery::DomainPeerDiscovery::startPublish(const std::string &type, const msgpack::sbuffer &pack_buf)
{
msgpack::sbuffer pack_buf_c(pack_buf.size());
pack_buf_c.write(pack_buf.data(), pack_buf.size());
std::lock_guard<std::mutex> lck(mtx_);
messages_[std::string(type)] = std::move(pack_buf_c);
messages_[type] = std::move(pack_buf_c);
reloadMessages();
lrunning_ = true;
asio::post(*ioContext_, [this] () { publish(sockAddrSend_); });
ioContext_->post([this] () { publish(sockAddrSend_); });
}
bool
PeerDiscovery::DomainPeerDiscovery::stopDiscovery(std::string_view type)
PeerDiscovery::DomainPeerDiscovery::stopDiscovery(const std::string& type)
{
std::lock_guard<std::mutex> lck(dmtx_);
auto it = callbackmap_.find(type);
if (it != callbackmap_.end()) {
callbackmap_.erase(it);
if (callbackmap_.erase(type) > 0) {
if (callbackmap_.empty())
stopDiscovery();
return true;
@@ -263,12 +261,10 @@ PeerDiscovery::DomainPeerDiscovery::stopDiscovery(std::string_view type)
}
bool
PeerDiscovery::DomainPeerDiscovery::stopPublish(std::string_view type)
PeerDiscovery::DomainPeerDiscovery::stopPublish(const std::string& type)
{
std::lock_guard<std::mutex> lck(mtx_);
auto it = messages_.find(type);
if (it != messages_.end()) {
messages_.erase(it);
if (messages_.erase(type) > 0) {
if (messages_.empty())
stopPublish();
else
@@ -331,7 +327,7 @@ PeerDiscovery::DomainPeerDiscovery::reDiscover()
void
PeerDiscovery::DomainPeerDiscovery::connectivityChanged()
{
asio::post(*ioContext_, [this] () {
ioContext_->post([this] () {
reDiscover();
publish(sockAddrSend_);
});
@@ -401,21 +397,21 @@ PeerDiscovery::~PeerDiscovery() {
}
void
PeerDiscovery::startDiscovery(std::string_view type, ServiceDiscoveredCallback callback)
PeerDiscovery::startDiscovery(const std::string& type, ServiceDiscoveredCallback callback)
{
if (peerDiscovery4_) peerDiscovery4_->startDiscovery(type, callback);
if (peerDiscovery6_) peerDiscovery6_->startDiscovery(type, callback);
}
void
PeerDiscovery::startPublish(std::string_view type, const msgpack::sbuffer& pack_buf)
PeerDiscovery::startPublish(const std::string& type, const msgpack::sbuffer& pack_buf)
{
if (peerDiscovery4_) peerDiscovery4_->startPublish(type, pack_buf);
if (peerDiscovery6_) peerDiscovery6_->startPublish(type, pack_buf);
}
void
PeerDiscovery::startPublish(sa_family_t domain, std::string_view type, const msgpack::sbuffer& pack_buf)
PeerDiscovery::startPublish(sa_family_t domain, const std::string& type, const msgpack::sbuffer& pack_buf)
{
if (domain == AF_INET) {
if (peerDiscovery4_) peerDiscovery4_->startPublish(type, pack_buf);
@@ -432,7 +428,7 @@ PeerDiscovery::stop()
}
bool
PeerDiscovery::stopDiscovery(std::string_view type)
PeerDiscovery::stopDiscovery(const std::string &type)
{
bool stopped4 = peerDiscovery4_ and peerDiscovery4_->stopDiscovery(type);
bool stopped6 = peerDiscovery6_ and peerDiscovery6_->stopDiscovery(type);
@@ -440,7 +436,7 @@ PeerDiscovery::stopDiscovery(std::string_view type)
}
bool
PeerDiscovery::stopPublish(std::string_view type)
PeerDiscovery::stopPublish(const std::string &type)
{
bool stopped4 = peerDiscovery4_ and peerDiscovery4_->stopPublish(type);
bool stopped6 = peerDiscovery6_ and peerDiscovery6_->stopPublish(type);
@@ -448,7 +444,7 @@ PeerDiscovery::stopPublish(std::string_view type)
}
bool
PeerDiscovery::stopPublish(sa_family_t domain, std::string_view type)
PeerDiscovery::stopPublish(sa_family_t domain, const std::string& type)
{
if (domain == AF_INET) {
return peerDiscovery4_ and peerDiscovery4_->stopPublish(type);
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
+16 -157
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
@@ -50,10 +50,9 @@ SecureDht::SecureDht(std::unique_ptr<DhtInterface> dht, SecureDht::Config conf,
if (certificate_) {
auto certId = certificate_->getId();
auto certLongId = certificate_->getLongId();
if (key_ and (certId != key_->getPublicKey().getId() or certLongId != key_->getPublicKey().getLongId()))
if (key_ and certId != key_->getPublicKey().getId())
throw DhtException("SecureDht: provided certificate doesn't match private key.");
dht_->addOnConnectedCallback([this, certId, certLongId, cb=std::move(iacb)]{
dht_->addOnConnectedCallback([this, certId, cb=std::move(iacb)]{
dht_->put(certId, Value {
CERTIFICATE_TYPE,
*certificate_,
@@ -63,15 +62,6 @@ SecureDht::SecureDht(std::unique_ptr<DhtInterface> dht, SecureDht::Config conf,
if (logger_)
logger_->d(certId, "SecureDht: certificate announcement %s", ok ? "succeeded" : "failed");
}, {}, true);
dht_->put(InfoHash::get(certLongId), Value {
CERTIFICATE_TYPE,
*certificate_,
1
}, [this, cb=std::move(cb)](bool ok) {
if (cb) cb(ok);
if (logger_)
logger_->debug("SecureDht: certificate announcement {}", ok ? "succeeded" : "failed");
}, {}, true);
});
}
}
@@ -141,30 +131,6 @@ SecureDht::getPublicKey(const InfoHash& node) const
return it->second;
}
Sp<crypto::Certificate>
SecureDht::getCertificate(const PkId& node) const
{
if (node == getLongId())
return certificate_;
auto it = nodesCertificatesLong_.find(node);
if (it == nodesCertificatesLong_.end())
return nullptr;
else
return it->second;
}
Sp<crypto::PublicKey>
SecureDht::getPublicKey(const PkId& node) const
{
if (node == getLongId())
return certificate_->getSharedPublicKey();
auto it = nodesPubKeysLong_.find(node);
if (it == nodesPubKeysLong_.end())
return nullptr;
else
return it->second;
}
Sp<crypto::Certificate>
SecureDht::registerCertificate(const InfoHash& node, const Blob& data)
{
@@ -177,44 +143,25 @@ SecureDht::registerCertificate(const InfoHash& node, const Blob& data)
InfoHash h = crt->getPublicKey().getId();
if (node == h) {
if (logger_)
logger_->debug("Registering certificate for {}", h.toString());
registerCertificate(crt);
return crt;
logger_->d("Registering certificate for %s", h.toString().c_str());
auto it = nodesCertificates_.find(h);
if (it == nodesCertificates_.end())
std::tie(it, std::ignore) = nodesCertificates_.emplace(h, std::move(crt));
else
it->second = std::move(crt);
return it->second;
} else {
if (logger_)
logger_->w("Certificate {} for node {} does not match node id !", h.toString(), node.toString());
return nullptr;
}
}
Sp<crypto::Certificate>
SecureDht::registerCertificate(const PkId& node, const Blob& data)
{
Sp<crypto::Certificate> crt;
try {
crt = std::make_shared<crypto::Certificate>(data);
} catch (const std::exception& e) {
return nullptr;
}
auto h = crt->getPublicKey().getLongId();
if (node == h) {
if (logger_)
logger_->debug("Registering certificate for {}", h.toString());
registerCertificate(crt);
return crt;
} else {
if (logger_)
logger_->w("Certificate {} for node {} does not match node id !", h.toString(), node.toString());
logger_->w("Certificate %s for node %s does not match node id !", h.toString().c_str(), node.toString().c_str());
return nullptr;
}
}
void
SecureDht::registerCertificate(const Sp<crypto::Certificate>& cert)
SecureDht::registerCertificate(Sp<crypto::Certificate>& cert)
{
if (cert) {
if (cert)
nodesCertificates_[cert->getId()] = cert;
nodesCertificatesLong_[cert->getLongId()] = cert;
}
}
void
@@ -275,63 +222,6 @@ SecureDht::findPublicKey(const InfoHash& node, const std::function<void(const Sp
auto pk = crt->getSharedPublicKey();
if (*pk) {
nodesPubKeys_[pk->getId()] = pk;
nodesPubKeysLong_[pk->getLongId()] = pk;
if (cb) cb(pk);
return;
}
}
if (cb) cb(nullptr);
});
}
void
SecureDht::findCertificate(const PkId& node, const std::function<void(const Sp<crypto::Certificate>)>& cb)
{
Sp<crypto::Certificate> b = getCertificate(node);
if (b && *b) {
if (logger_)
logger_->debug("Using certificate from cache for {}", node.to_c_str());
if (cb)
cb(b);
return;
}
auto found = std::make_shared<bool>(false);
dht_->get(InfoHash::get(node), [cb,node,found,this](const std::vector<Sp<Value>>& vals) {
for (const auto& v : vals) {
if (auto cert = registerCertificate(node, v->data)) {
*found = true;
if (logger_)
logger_->debug("Found certificate for {}", node.to_c_str());
if (cb)
cb(cert);
return false;
}
}
return !*found;
}, [cb,found](bool) {
if (!*found and cb)
cb(nullptr);
}, Value::TypeFilter(CERTIFICATE_TYPE));
}
void
SecureDht::findPublicKey(const PkId& node, const std::function<void(const Sp<crypto::PublicKey>)>& cb)
{
auto pk = getPublicKey(node);
if (pk && *pk) {
if (logger_)
logger_->debug("Found public key from cache for {}", node.to_c_str());
if (cb)
cb(pk);
return;
}
findCertificate(node, [=](const Sp<crypto::Certificate>& crt) {
if (crt && *crt) {
auto pk = crt->getSharedPublicKey();
if (*pk) {
nodesPubKeys_[pk->getId()] = pk;
nodesPubKeysLong_[pk->getLongId()] = pk;
if (cb) cb(pk);
return;
}
@@ -356,10 +246,8 @@ SecureDht::checkValue(const Sp<Value>& v)
auto isDecrypted = v->isDecrypted();
if (auto decrypted_val = v->decrypt(*key_)) {
auto cacheValue = not isDecrypted and decrypted_val->owner;
if (cacheValue) {
if (cacheValue)
nodesPubKeys_[decrypted_val->owner->getId()] = decrypted_val->owner;
nodesPubKeysLong_[decrypted_val->owner->getLongId()] = decrypted_val->owner;
}
return decrypted_val;
}
} catch (const std::exception& e) {
@@ -371,10 +259,8 @@ SecureDht::checkValue(const Sp<Value>& v)
else if (v->isSigned()) {
auto cacheValue = not v->isSignatureChecked() and enableCache_ and v->owner;
if (v->checkSignature()) {
if (cacheValue) {
if (cacheValue)
nodesPubKeys_[v->owner->getId()] = v->owner;
nodesPubKeysLong_[v->owner->getLongId()] = v->owner;
}
return v;
} else if (logger_)
logger_->w("Signature verification failed for %s", v->toString().c_str());
@@ -515,33 +401,6 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val,
});
}
void
SecureDht::putEncrypted(const InfoHash& hash, const PkId& to, Sp<Value> val, DoneCallback callback, bool permanent)
{
if (not key_) {
if (callback)
callback(false, {});
return;
}
findPublicKey(to, [this, hash, val = std::move(val), callback = std::move(callback), permanent](const Sp<crypto::PublicKey>& pk) {
if(!pk || !*pk) {
if (callback)
callback(false, {});
return;
}
if (logger_)
logger_->warn("Encrypting data for PK: {}", pk->getLongId());
try {
dht_->put(hash, encrypt(*val, *pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
if (logger_)
logger_->e("Error putting encrypted data: %s", e.what());
if (callback)
callback(false, {});
}
});
}
void
SecureDht::putEncrypted(const InfoHash& hash, const crypto::PublicKey& pk, Sp<Value> val, DoneCallback callback, bool permanent)
{
@@ -551,7 +410,7 @@ SecureDht::putEncrypted(const InfoHash& hash, const crypto::PublicKey& pk, Sp<Va
return;
}
if (logger_)
logger_->warn("Encrypting data for PK: {}", pk.getLongId());
logger_->w("Encrypting data for PK: %s", pk.getLongId().to_c_str());
try {
dht_->put(hash, encrypt(*val, pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -224,7 +224,7 @@ Storage::store(const InfoHash& id, const Sp<Value>& value, time_point created, t
//DHT_LOG.DEBUG("Updating %s -> %s", id.toString().c_str(), value->toString().c_str());
// clear quota for previous value
if (it->store_bucket)
it->store_bucket->erase(id, *it->data, it->expiration);
it->store_bucket->erase(id, *value, it->expiration);
it->expiration = expiration;
// update quota for new value
it->store_bucket = sb;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
+12 -10
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
@@ -39,26 +39,28 @@ const char* version() {
return PACKAGE_VERSION;
}
const HexMap hex_map = {};
static constexpr std::array<uint8_t, 12> MAPPED_IPV4_PREFIX {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}};
std::pair<std::string, std::string>
splitPort(std::string_view s) {
splitPort(const std::string& s) {
if (s.empty())
return {};
if (s[0] == '[') {
std::size_t closure = s.find_first_of(']');
std::size_t found = s.find_last_of(':');
if (closure == std::string_view::npos)
return {std::string(s), ""};
if (found == std::string_view::npos or found < closure)
return {std::string(s.substr(1,closure-1)), ""};
return {std::string(s.substr(1,closure-1)), std::string(s.substr(found+1))};
if (closure == std::string::npos)
return {s, ""};
if (found == std::string::npos or found < closure)
return {s.substr(1,closure-1), ""};
return {s.substr(1,closure-1), s.substr(found+1)};
}
std::size_t found = s.find_last_of(':');
std::size_t first = s.find_first_of(':');
if (found == std::string_view::npos or found != first)
return {std::string(s), ""};
return {std::string(s.substr(0,found)), std::string(s.substr(found+1))};
if (found == std::string::npos or found != first)
return {s, ""};
return {s.substr(0,found), s.substr(found+1)};
}
std::vector<SockAddr>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 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
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
+3 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2025 Savoir-faire Linux Inc.
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
@@ -123,7 +123,7 @@ DhtRunnerTester::testPutOverride() {
auto val2 = std::make_shared<dht::Value>("hey");
val2->id = 42;
CPPUNIT_ASSERT_EQUAL(val->id, val2->id);
auto val_data = val2->data;
auto val_data = val->data;
std::promise<bool> p1;
std::promise<bool> p2;
node2.put(key, val, [&](bool ok){
@@ -358,8 +358,7 @@ DhtRunnerTester::testIdOps() {
{
std::unique_lock<std::mutex> lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 7; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCountEdit == 2; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 7 && valueCountEdit == 2; }));
}
// editValue->data = dht::packMsg("v2");
Loaded 100 of 122 files, more files were not shown because too many files have changed in this diff. Show more