mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 12:28:42 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
134b37861d | ||
|
|
078e0a0c3e | ||
|
|
c4857bf595 |
No files matched your search
@@ -1,99 +0,0 @@
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: Left
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: true
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: Inline
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- forever # avoids { wrapped to next line
|
||||
- foreach
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 150
|
||||
PenaltyBreakBeforeFirstCallParameter: 300
|
||||
PenaltyBreakComment: 500
|
||||
PenaltyBreakFirstLessLess: 400
|
||||
PenaltyBreakString: 600
|
||||
PenaltyExcessCharacter: 50
|
||||
PenaltyReturnTypeOnItsOwnLine: 300
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++17
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
@@ -4,12 +4,9 @@
|
||||
"dockerfile": "../docker/DockerfileDepsLlvm",
|
||||
},
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools"
|
||||
]
|
||||
}
|
||||
},
|
||||
"settings": {},
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools"
|
||||
],
|
||||
"forwardPorts": [4222],
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/docker"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "vcpkg"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "devcontainers"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "cargo"
|
||||
directory: "/rust"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
+99
-197
@@ -1,14 +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"
|
||||
DEBIAN12_DEPS: "git autotools-dev autoconf libtool m4 automake pkg-config wget cmake libncurses5-dev libreadline-dev nettle-dev libasio-dev libgnutls28-dev libuv1-dev python3-pip python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev libfmt-dev libmsgpack-dev libargon2-dev"
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
@@ -16,211 +7,122 @@ jobs:
|
||||
name: Ubuntu/GCC Autotools build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- 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: Install simdutf
|
||||
run: |
|
||||
wget https://github.com/simdutf/simdutf/archive/refs/tags/v7.7.0.tar.gz -O simdutf.tar.gz
|
||||
tar -xzf simdutf.tar.gz
|
||||
mv simdutf-7.7.0 simdutf
|
||||
mkdir simdutf/build && cd simdutf/build
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DSIMDUTF_CXX_STANDARD=17 -DSIMDUTF_TOOLS=Off -DSIMDUTF_TESTS=Off .. && make -j2 && sudo make install
|
||||
cd ../../ && rm -rf simdutf
|
||||
|
||||
- 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@v6
|
||||
|
||||
- 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@v6
|
||||
|
||||
- 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: ctest --output-on-failure --test-dir build
|
||||
|
||||
build-debian12:
|
||||
name: Debian 12/GCC build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: debian:12
|
||||
volumes:
|
||||
- .:/workspace
|
||||
options: --workdir /workspace
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y $DEBIAN12_DEPS
|
||||
|
||||
- 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 && make install
|
||||
cd ../ && rm -rf llhttp*
|
||||
|
||||
- name: Install expected-lite header
|
||||
run: |
|
||||
mkdir -p /usr/local/include/nonstd
|
||||
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 \
|
||||
-DRESTINIO_DEP_FMT=system -DRESTINIO_DEP_EXPECTED_LITE=system .
|
||||
make install
|
||||
cd ../../ && rm -rf restinio*
|
||||
|
||||
- name: Configure project with CMake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -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
|
||||
|
||||
- name: Build
|
||||
run: cd build && make
|
||||
- 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@v6
|
||||
- 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 \
|
||||
-DOPENDHT_DOWNLOAD_DEPS=ON \
|
||||
-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
|
||||
@@ -6,13 +6,13 @@ jobs:
|
||||
name: Clang Static Analysis
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: deps
|
||||
run: |
|
||||
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 .
|
||||
@@ -37,6 +37,6 @@ jobs:
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build && \
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DOPENDHT_C=On -DOPENDHT_DOWNLOAD_DEPS=ON -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off -DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On -DOPENDHT_PUSH_NOTIFICATIONS=On
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DOPENDHT_C=On -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off -DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On -DOPENDHT_PUSH_NOTIFICATIONS=On
|
||||
- name: scan-build
|
||||
run: cd build && scan-build --status-bugs make
|
||||
@@ -0,0 +1,53 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/savoirfairelinux/opendht/opendht-deps:latest
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -1,41 +0,0 @@
|
||||
name: "CodeQL Advanced"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
runs-on: 'ubuntu-latest'
|
||||
permissions:
|
||||
security-events: write
|
||||
packages: read
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: c-cpp
|
||||
build-mode: autobuild
|
||||
- language: actions
|
||||
build-mode: none
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
@@ -1,108 +0,0 @@
|
||||
name: Python Package
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_wheels:
|
||||
name: Build wheels on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Run locally with: pipx run cibuildwheel --platform linux python
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v3.3.0
|
||||
with:
|
||||
package-dir: python
|
||||
|
||||
- uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: opendht-wheels-${{ matrix.os }}
|
||||
path: ./wheelhouse/*.whl
|
||||
|
||||
build_wheels_windows:
|
||||
name: Build wheels on Windows
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCPKG_VERSION: "2025.07.25"
|
||||
VCPKG_INSTALLATION_ROOT: "C:\\vcpkg"
|
||||
VCPKG_DISABLE_METRICS: "1"
|
||||
VCPKG_DEFAULT_TRIPLET: x64-windows-release
|
||||
VCPKG_INSTALLED_DIR: ${{ github.workspace }}\vcpkg_installed
|
||||
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}\vcpkg_binary_cache
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Cache vcpkg installed packages
|
||||
id: cache-vcpkg
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}-${{ hashFiles('.github/workflows/windows-build.yml') }}
|
||||
|
||||
- name: Setup vcpkg and install dependencies
|
||||
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
New-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}" -ItemType Directory -Force
|
||||
New-Item -Path "${{ env.VCPKG_DEFAULT_BINARY_CACHE }}" -ItemType Directory -Force
|
||||
vcpkg install `
|
||||
--recurse `
|
||||
--clean-after-build `
|
||||
--triplet=${{ env.VCPKG_DEFAULT_TRIPLET }} `
|
||||
--x-install-root=${{ env.VCPKG_INSTALLED_DIR }}
|
||||
shell: pwsh
|
||||
|
||||
- name: Build wheels
|
||||
run: |
|
||||
pip install cython delvewheel build
|
||||
cmake -S . -B build `
|
||||
-DCMAKE_BUILD_TYPE=Release `
|
||||
-DVCPKG_TARGET_TRIPLET=${{ env.VCPKG_DEFAULT_TRIPLET }} `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}\scripts\buildsystems\vcpkg.cmake `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DBUILD_TESTING=OFF `
|
||||
-DOPENDHT_C=OFF `
|
||||
-DOPENDHT_TOOLS=OFF `
|
||||
-DOPENDHT_PYTHON=ON `
|
||||
-DOPENDHT_DOCUMENTATION=OFF `
|
||||
-DOPENDHT_PROXY_CLIENT=ON `
|
||||
-DOPENDHT_PROXY_SERVER=ON
|
||||
cd build
|
||||
pipx run cibuildwheel python
|
||||
shell: pwsh
|
||||
|
||||
- uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: opendht-wheels-win_amd64
|
||||
path: ./build/wheelhouse/*.whl
|
||||
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build_wheels, build_wheels_windows]
|
||||
steps:
|
||||
- uses: actions/download-artifact@v6
|
||||
with:
|
||||
pattern: opendht-wheels-*
|
||||
path: dist
|
||||
merge-multiple: true
|
||||
|
||||
- name: Publish package
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DEPS }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileDeps
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile
|
||||
@@ -92,7 +92,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DEPS_LLVM }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileDepsLlvm
|
||||
@@ -125,7 +125,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LLVM }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileLlvm
|
||||
@@ -159,7 +159,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -176,7 +176,7 @@ jobs:
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DHTNODE }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileDhtnode
|
||||
@@ -193,7 +193,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -210,7 +210,7 @@ jobs:
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_ALPINE_DEPS }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileDepsAlpine
|
||||
@@ -227,7 +227,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
@@ -244,7 +244,7 @@ jobs:
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME_ALPINE }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: docker/DockerfileAlpine
|
||||
@@ -252,219 +252,42 @@ jobs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-windows-msi:
|
||||
name: Build Windows MSI Installer
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCPKG_VERSION: "2025.07.25"
|
||||
VCPKG_INSTALLATION_ROOT: "C:\\vcpkg"
|
||||
VCPKG_DISABLE_METRICS: "1"
|
||||
VCPKG_DEFAULT_TRIPLET: x64-windows
|
||||
VCPKG_INSTALLED_DIR: ${{ github.workspace }}\vcpkg_installed
|
||||
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}\vcpkg_binary_cache
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up MSVC developer environment
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Install WIX using .net tools
|
||||
run: |
|
||||
dotnet tool install --global wix --version 6.0.1
|
||||
wix extension add --global WixToolset.UI.wixext/6.0.1
|
||||
shell: pwsh
|
||||
|
||||
- name: Cache vcpkg installed packages
|
||||
id: cache-vcpkg
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-x64-shared-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}-${{ hashFiles('.github/workflows/windows-build.yml') }}
|
||||
|
||||
- name: Setup vcpkg and install dependencies
|
||||
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
New-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}" -ItemType Directory -Force
|
||||
New-Item -Path "${{ env.VCPKG_DEFAULT_BINARY_CACHE }}" -ItemType Directory -Force
|
||||
vcpkg install `
|
||||
--recurse `
|
||||
--clean-after-build `
|
||||
--triplet=x64-windows `
|
||||
--x-install-root=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
--x-feature=test
|
||||
shell: pwsh
|
||||
|
||||
- name: Configure CMake for MSI
|
||||
shell: pwsh
|
||||
run: |
|
||||
mkdir build -ErrorAction SilentlyContinue
|
||||
cmake -B build `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
-DVCPKG_TARGET_TRIPLET=x64-windows `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
-DCMAKE_BUILD_TYPE=Release `
|
||||
-DOPENDHT_C=On `
|
||||
-DOPENDHT_TOOLS=On `
|
||||
-DOPENDHT_PYTHON=Off `
|
||||
-DOPENDHT_DOCUMENTATION=OFF `
|
||||
-DOPENDHT_PEER_DISCOVERY=On `
|
||||
-DOPENDHT_PROXY_SERVER=On `
|
||||
-DOPENDHT_PROXY_CLIENT=On `
|
||||
-DOPENDHT_HTTP=On `
|
||||
-DBUILD_TESTING=Off `
|
||||
-DOPENDHT_CPACK=On `
|
||||
-A x64
|
||||
|
||||
- name: Build with MSVC
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake --build build --config Release --parallel $([System.Environment]::ProcessorCount)
|
||||
# Copy vcpkg installed libraries to the build directory
|
||||
Copy-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}\x64-windows\lib\*.lib" -Destination "build" -Force
|
||||
Copy-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}\x64-windows\bin\*.dll" -Destination "build" -Force
|
||||
|
||||
- name: Package MSI with CPack
|
||||
shell: pwsh
|
||||
id: cpack_msi
|
||||
run: |
|
||||
cd build
|
||||
cpack -C Release -G WIX
|
||||
$msiFile = Get-ChildItem -Path . -Recurse -Filter *.msi | Select-Object -First 1
|
||||
if ($msiFile) {
|
||||
$msiOutputPath = "opendht-installer.msi" # Standardized artifact name
|
||||
Copy-Item $msiFile.FullName -Destination $msiOutputPath
|
||||
echo "msi_path=$msiOutputPath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
|
||||
Write-Host "MSI created at build/$msiOutputPath"
|
||||
} else {
|
||||
Write-Error "MSI file not found after cpack execution!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Upload MSI Artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: opendht-windows-msi
|
||||
path: build/${{ steps.cpack_msi.outputs.msi_path }} # Path to the MSI in the build directory
|
||||
retention-days: 7
|
||||
|
||||
build-windows-dhtnode:
|
||||
name: Build Windows dhtnode
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCPKG_VERSION: "2025.07.25"
|
||||
VCPKG_INSTALLATION_ROOT: "C:\\vcpkg"
|
||||
VCPKG_DISABLE_METRICS: "1"
|
||||
VCPKG_DEFAULT_TRIPLET: x64-windows-static-release
|
||||
VCPKG_INSTALLED_DIR: ${{ github.workspace }}\vcpkg_installed
|
||||
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}\vcpkg_binary_cache
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up MSVC developer environment
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Cache vcpkg static installed packages
|
||||
id: cache-vcpkg-static
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-x64-static-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}-${{ hashFiles('.github/workflows/windows-build.yml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-x64-static-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-x64-static-
|
||||
|
||||
- name: Setup vcpkg and install static dependencies
|
||||
if: steps.cache-vcpkg-static.outputs.cache-hit != 'true'
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}" -ItemType Directory -Force
|
||||
New-Item -Path "${{ env.VCPKG_DEFAULT_BINARY_CACHE }}" -ItemType Directory -Force
|
||||
vcpkg install `
|
||||
--recurse `
|
||||
--clean-after-build `
|
||||
--triplet=x64-windows-static-release `
|
||||
--x-install-root=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
--x-feature=test
|
||||
|
||||
- name: Configure CMake for Static Build
|
||||
shell: pwsh
|
||||
run: |
|
||||
mkdir build_static -ErrorAction SilentlyContinue
|
||||
cmake -B build_static `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
-DVCPKG_TARGET_TRIPLET=x64-windows-static-release `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
-DCMAKE_BUILD_TYPE=Release `
|
||||
-DBUILD_SHARED_LIBS=OFF `
|
||||
-DOPENDHT_PROXY_CLIENT=ON `
|
||||
-DOPENDHT_PROXY_SERVER=ON `
|
||||
-DOPENDHT_C=ON `
|
||||
-DOPENDHT_TOOLS=ON `
|
||||
-DOPENDHT_DOCUMENTATION=OFF `
|
||||
-DOPENDHT_PYTHON=OFF `
|
||||
-DOPENDHT_PEER_DISCOVERY=ON `
|
||||
-DOPENDHT_HTTP=ON `
|
||||
-A x64
|
||||
|
||||
- name: Build Static dhtnode
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake --build build_static --config Release --parallel $([System.Environment]::ProcessorCount)
|
||||
|
||||
- name: Upload Static dhtnode Artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: opendht-windows-dhtnode
|
||||
path: |
|
||||
build_static/**/*dhtnode.exe
|
||||
retention-days: 7
|
||||
|
||||
create-github-release:
|
||||
name: Create GitHub Release
|
||||
build-python-wheel:
|
||||
name: Release and build Python Wheel package
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-windows-msi, build-windows-dhtnode]
|
||||
container: ghcr.io/savoirfairelinux/opendht/opendht-deps:latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download Windows MSI artifact
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: opendht-windows-msi
|
||||
path: downloaded_artifacts/windows_msi
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build && \
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DOPENDHT_STATIC=Off \
|
||||
-DOPENDHT_PYTHON=On \
|
||||
-DOPENDHT_C=Off \
|
||||
-DOPENDHT_PEER_DISCOVERY=On \
|
||||
-DOPENDHT_TOOLS=Off \
|
||||
-DOPENDHT_PROXY_SERVER=On \
|
||||
-DOPENDHT_PROXY_CLIENT=On
|
||||
|
||||
- name: Download Static dhtnode artifact
|
||||
uses: actions/download-artifact@v6
|
||||
- name: build
|
||||
run: cd build && make dist
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: opendht-windows-dhtnode
|
||||
path: downloaded_artifacts/static_dhtnode
|
||||
name: opendht-wheels-linux
|
||||
path: build/python/dist/*.whl
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
draft: true
|
||||
files: |
|
||||
downloaded_artifacts/windows_msi/*.msi
|
||||
downloaded_artifacts/static_dhtnode/**/*dhtnode.exe
|
||||
files: build/python/dist/*.whl
|
||||
@@ -1,379 +0,0 @@
|
||||
name: Windows Build
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
|
||||
env:
|
||||
VCPKG_VERSION: "2025.07.25"
|
||||
VCPKG_INSTALLATION_ROOT: "C:\\vcpkg"
|
||||
VCPKG_DISABLE_METRICS: "1"
|
||||
VCPKG_INSTALLED_DIR: ${{ github.workspace }}\vcpkg_installed
|
||||
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}\vcpkg_binary_cache
|
||||
|
||||
jobs:
|
||||
prepare-dependencies:
|
||||
name: Prepare Windows Dependencies
|
||||
runs-on: windows-latest
|
||||
outputs:
|
||||
vcpkg_cache_key: ${{ steps.generate_cache_key.outputs.key }}
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x64]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Generate Cache Key
|
||||
id: generate_cache_key
|
||||
shell: pwsh
|
||||
run: |
|
||||
$key_value = "${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-shared-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}-${{ hashFiles('.github/workflows/windows-build.yml') }}"
|
||||
echo "key=$key_value" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Cache vcpkg installed packages
|
||||
id: cache-vcpkg
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ steps.generate_cache_key.outputs.key }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-shared-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-shared-
|
||||
|
||||
- name: Setup vcpkg and install dependencies
|
||||
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
New-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}" -ItemType Directory -Force
|
||||
New-Item -Path "${{ env.VCPKG_DEFAULT_BINARY_CACHE }}" -ItemType Directory -Force
|
||||
vcpkg install `
|
||||
--recurse `
|
||||
--clean-after-build `
|
||||
--triplet=${{ matrix.arch }}-windows `
|
||||
--x-install-root=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
--x-feature=test
|
||||
shell: pwsh
|
||||
|
||||
prepare-static-dependencies:
|
||||
name: Prepare Windows Static Dependencies
|
||||
runs-on: windows-latest
|
||||
outputs:
|
||||
vcpkg_static_cache_key: ${{ steps.generate_static_cache_key.outputs.key }}
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x64]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Generate Cache Key for Static Libs
|
||||
id: generate_static_cache_key
|
||||
shell: pwsh
|
||||
run: |
|
||||
$key_value = "${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-static-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}-${{ hashFiles('.github/workflows/windows-build.yml') }}"
|
||||
echo "key=$key_value" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Cache vcpkg static installed packages
|
||||
id: cache-vcpkg-static
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ steps.generate_static_cache_key.outputs.key }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-static-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-static-
|
||||
|
||||
- name: Setup vcpkg and install static dependencies
|
||||
if: steps.cache-vcpkg-static.outputs.cache-hit != 'true'
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}" -ItemType Directory -Force
|
||||
New-Item -Path "${{ env.VCPKG_DEFAULT_BINARY_CACHE }}" -ItemType Directory -Force
|
||||
vcpkg install `
|
||||
--recurse `
|
||||
--clean-after-build `
|
||||
--triplet=${{ matrix.arch }}-windows-static-release `
|
||||
--x-install-root=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
--x-feature=test
|
||||
|
||||
build-windows:
|
||||
name: Windows MSVC Build
|
||||
runs-on: windows-latest
|
||||
needs: prepare-dependencies
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Debug, Release]
|
||||
arch: [x64]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Restore vcpkg installed packages
|
||||
id: cache-vcpkg-restore
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ needs.prepare-dependencies.outputs.vcpkg_cache_key }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-shared-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-shared-
|
||||
|
||||
- name: Configure CMake
|
||||
shell: pwsh
|
||||
run: |
|
||||
mkdir build -ErrorAction SilentlyContinue
|
||||
cmake -B build `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} `
|
||||
-DBUILD_TESTING=ON `
|
||||
-DOPENDHT_PROXY_CLIENT=ON `
|
||||
-DOPENDHT_PROXY_SERVER=ON `
|
||||
-DOPENDHT_C=ON `
|
||||
-DOPENDHT_TOOLS=ON `
|
||||
-DOPENDHT_PYTHON=OFF `
|
||||
-DOPENDHT_DOCUMENTATION=OFF `
|
||||
-DOPENDHT_PEER_DISCOVERY=ON `
|
||||
-DOPENDHT_HTTP=ON `
|
||||
-A ${{ matrix.arch }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake --build build --config ${{ matrix.build_type }} --parallel 4
|
||||
# Copy vcpkg installed libraries to the build directory
|
||||
Copy-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}\${{ matrix.arch }}-windows\lib\*.lib" -Destination "build" -Force
|
||||
Copy-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}\${{ matrix.arch }}-windows\bin\*.dll" -Destination "build" -Force
|
||||
|
||||
- name: Test
|
||||
if: matrix.build_type == 'Release'
|
||||
run: |
|
||||
cd build
|
||||
ctest --build-config ${{ matrix.build_type }} --output-on-failure --parallel 4
|
||||
|
||||
- name: Upload build artifacts
|
||||
if: matrix.build_type == 'Release'
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: opendht-windows-${{ matrix.arch }}-${{ matrix.build_type }}
|
||||
path: |
|
||||
build/**/*.exe
|
||||
build/**/*.dll
|
||||
build/**/*.lib
|
||||
retention-days: 7
|
||||
|
||||
build-windows-static:
|
||||
name: Windows Static MSVC Build
|
||||
runs-on: windows-latest
|
||||
needs: prepare-static-dependencies
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Release]
|
||||
arch: [x64]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Restore vcpkg static installed packages
|
||||
id: cache-vcpkg-static-restore
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ needs.prepare-static-dependencies.outputs.vcpkg_static_cache_key }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-static-${{ hashFiles('**/vcpkg.json', '**/vcpkg-configuration.json') }}
|
||||
${{ runner.os }}-vcpkg-${{ env.VCPKG_VERSION }}-${{ matrix.arch }}-static-
|
||||
|
||||
- name: Configure CMake for Static Build
|
||||
shell: pwsh
|
||||
run: |
|
||||
mkdir build -ErrorAction SilentlyContinue
|
||||
cmake -B build `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static-release `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} `
|
||||
-DBUILD_SHARED_LIBS=OFF `
|
||||
-DBUILD_TESTING=ON `
|
||||
-DOPENDHT_PROXY_CLIENT=ON `
|
||||
-DOPENDHT_PROXY_SERVER=ON `
|
||||
-DOPENDHT_C=ON `
|
||||
-DOPENDHT_TOOLS=ON `
|
||||
-DOPENDHT_PYTHON=OFF `
|
||||
-DOPENDHT_DOCUMENTATION=OFF `
|
||||
-DOPENDHT_PEER_DISCOVERY=ON `
|
||||
-DOPENDHT_HTTP=ON `
|
||||
-A ${{ matrix.arch }}
|
||||
|
||||
- name: Build Static
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake --build build --config ${{ matrix.build_type }} --parallel 4
|
||||
|
||||
- name: Test Static Build
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd build
|
||||
ctest --build-config ${{ matrix.build_type }} --output-on-failure --parallel 4
|
||||
|
||||
- name: Upload static build artifacts
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: opendht-windows-static-${{ matrix.arch }}-${{ matrix.build_type }}
|
||||
path: |
|
||||
build/**/*.exe
|
||||
build/**/*.lib
|
||||
retention-days: 7
|
||||
|
||||
build-windows-mingw:
|
||||
name: Windows MinGW Build
|
||||
runs-on: windows-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Release]
|
||||
#build_type: [Debug, Release]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup MinGW
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
install: >-
|
||||
mingw-w64-x86_64-gcc
|
||||
mingw-w64-x86_64-cmake
|
||||
mingw-w64-x86_64-make
|
||||
mingw-w64-x86_64-ninja
|
||||
mingw-w64-x86_64-pkg-config
|
||||
mingw-w64-x86_64-cppunit
|
||||
mingw-w64-x86_64-readline
|
||||
mingw-w64-x86_64-ncurses
|
||||
mingw-w64-x86_64-gnutls
|
||||
mingw-w64-x86_64-nettle
|
||||
mingw-w64-x86_64-jsoncpp
|
||||
mingw-w64-x86_64-fmt
|
||||
mingw-w64-x86_64-asio
|
||||
mingw-w64-x86_64-argon2
|
||||
mingw-w64-x86_64-openssl
|
||||
mingw-w64-clang-x86_64-msgpack-cxx
|
||||
|
||||
- name: Prepare dependencies from source (expected-lite, llhttp, restinio)
|
||||
shell: msys2 {0}
|
||||
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"
|
||||
run: |
|
||||
MSYS2_SYSROOT=$(cygpath -u "$MSYSTEM_PREFIX")
|
||||
|
||||
# Install expected-lite header
|
||||
mkdir -p ${MSYS2_SYSROOT}/include/nonstd
|
||||
curl -L "${EXPECTED_LITE_URL}" -o ${MSYS2_SYSROOT}/include/nonstd/expected.hpp
|
||||
|
||||
# Build and install llhttp
|
||||
mkdir llhttp
|
||||
curl -L "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 -G "MinGW Makefiles" \
|
||||
-DCMAKE_INSTALL_PREFIX=${MSYS2_SYSROOT} \
|
||||
-DCMAKE_BUILD_TYPE=Release .
|
||||
cmake --build . --parallel 2
|
||||
cmake --install .
|
||||
cd ..
|
||||
rm -rf llhttp*
|
||||
|
||||
# Build and install restinio
|
||||
mkdir restinio && cd restinio
|
||||
curl -L "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2" -o restinio.tar.bz2
|
||||
tar -xjf restinio.tar.bz2
|
||||
cd restinio-${RESTINIO_VERSION}/dev
|
||||
cmake -G "MinGW Makefiles" \
|
||||
-DCMAKE_INSTALL_PREFIX=${MSYS2_SYSROOT} \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-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 .
|
||||
cmake --install .
|
||||
cd ../../..
|
||||
rm -rf restinio*
|
||||
|
||||
# Copy msgpack-cxx headers
|
||||
mkdir -p ${MSYS2_SYSROOT}/include/msgpack
|
||||
cp -r /clang64/include/msgpack/* ${MSYS2_SYSROOT}/include/msgpack/
|
||||
cp /clang64/include/msgpack.hpp ${MSYS2_SYSROOT}/include/msgpack.hpp
|
||||
|
||||
- name: Build with MinGW
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
mkdir build_mingw
|
||||
cd build_mingw
|
||||
cmake .. \
|
||||
-G "MinGW Makefiles" \
|
||||
-DHAVE_MSGPACKCXX=ON \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
|
||||
-DBUILD_TESTING=ON \
|
||||
-DOPENDHT_PROXY_CLIENT=ON \
|
||||
-DOPENDHT_PROXY_SERVER=ON \
|
||||
-DOPENDHT_C=ON \
|
||||
-DOPENDHT_TOOLS=ON \
|
||||
-DOPENDHT_PYTHON=OFF \
|
||||
-DOPENDHT_DOCUMENTATION=OFF \
|
||||
-DOPENDHT_PEER_DISCOVERY=ON \
|
||||
-DOPENDHT_HTTP=ON
|
||||
cmake --build . --parallel 4
|
||||
|
||||
#- name: Test MinGW Build
|
||||
# shell: msys2 {0}
|
||||
# run: |
|
||||
# cd build_mingw
|
||||
# ctest --output-on-failure --parallel 4
|
||||
|
||||
- name: Upload MinGW artifacts
|
||||
if: matrix.build_type == 'Release'
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: opendht-windows-mingw-${{ matrix.build_type }}
|
||||
path: |
|
||||
build_mingw/**/*.exe
|
||||
build_mingw/**/*.dll
|
||||
build_mingw/**/*.a
|
||||
retention-days: 7
|
||||
+3
-16
@@ -45,19 +45,13 @@ Makefile.in
|
||||
*~
|
||||
*.pc
|
||||
|
||||
# CMake
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
*ConfigVersion.cmake
|
||||
# KDevelop
|
||||
.kdev4/
|
||||
*.kdev4
|
||||
|
||||
# VSCode
|
||||
.vscode/*
|
||||
|
||||
# Visual Studio
|
||||
.vs/
|
||||
CMakeSettings.json
|
||||
|
||||
# Eclipse CDT
|
||||
.cproject
|
||||
.project
|
||||
@@ -69,9 +63,6 @@ language.settings.xml
|
||||
*.stamp
|
||||
python/opendht.cpp
|
||||
python/setup.py
|
||||
python/dist/
|
||||
wheelhouse/
|
||||
*.egg-info/
|
||||
|
||||
# Doxygen
|
||||
doc/Doxyfile
|
||||
@@ -87,7 +78,3 @@ doc/Doxyfile
|
||||
build
|
||||
build_dev
|
||||
.DS_Store
|
||||
build-*/
|
||||
install/
|
||||
vcpkg_installed/
|
||||
|
||||
Vendored
+4
-4
@@ -5,9 +5,9 @@
|
||||
"name": "dhtnode",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/tools/dhtnode",
|
||||
"program": "${workspaceFolder}/build_dev/tools/dhtnode",
|
||||
"args": ["-v", "-p", "4222"],
|
||||
"cwd": "${workspaceFolder}/build",
|
||||
"cwd": "${workspaceFolder}/build_dev",
|
||||
"environment": [],
|
||||
"setupCommands": [
|
||||
{
|
||||
@@ -30,8 +30,8 @@
|
||||
"name": "tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/opendht_unit_tests",
|
||||
"cwd": "${workspaceFolder}/build",
|
||||
"program": "${workspaceFolder}/build_dev/opendht_unit_tests",
|
||||
"cwd": "${workspaceFolder}/build_dev",
|
||||
"environment": [],
|
||||
"setupCommands": [
|
||||
{
|
||||
|
||||
Vendored
-10
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
"C_Cpp.default.cppStandard": "c++17",
|
||||
"C_Cpp.default.cStandard": "c11",
|
||||
"C_Cpp.autoAddFileAssociations": false,
|
||||
"cmake.configureOnOpen": false,
|
||||
"cmake.configureOnEdit": false,
|
||||
"editor.formatOnSave": true,
|
||||
"files.eol": "\n",
|
||||
}
|
||||
Vendored
+3
-3
@@ -5,7 +5,7 @@
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/build"
|
||||
"cwd": "${workspaceRoot}/build_dev"
|
||||
},
|
||||
"command": "make",
|
||||
"args": ["-j4"],
|
||||
@@ -15,7 +15,7 @@
|
||||
"label": "cmake",
|
||||
"type": "shell",
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/build"
|
||||
"cwd": "${workspaceRoot}/build_dev"
|
||||
},
|
||||
"command": "cmake",
|
||||
"args": [
|
||||
@@ -39,7 +39,7 @@
|
||||
"command": "mkdir",
|
||||
"args": [
|
||||
"-p",
|
||||
"${workspaceRoot}/build"
|
||||
"${workspaceRoot}/build_dev"
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
# Build the library
|
||||
|
||||
The build is currently tested on GNU/Linux, macOS, and Windows.
|
||||
|
||||
## Unix-like systems (Linux, macOS, MSYS2/MinGW, etc.)
|
||||
|
||||
## Install dependencies
|
||||
|
||||
### Debian 13
|
||||
|
||||
```sh
|
||||
# Install dependencies
|
||||
sudo apt install pkg-config libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libargon2-dev libmsgpack-dev libssl-dev libfmt-dev libjsoncpp-dev libhttp-parser-dev libasio-dev libmsgpack-cxx-dev
|
||||
|
||||
# Install Python binding dependencies
|
||||
sudo apt-get install cython3 python3-dev python3-setuptools python3-build
|
||||
```
|
||||
|
||||
Optionally, install RESTinio to enable the OpenDHT proxy client and server:
|
||||
```sh
|
||||
mkdir /usr/include/nonstd
|
||||
wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp -O /usr/include/nonstd/expected.hpp
|
||||
|
||||
wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2
|
||||
tar -xjf restinio-0.7.3.tar.bz2
|
||||
cd restinio-0.7.3/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 .
|
||||
make -j2 && make install
|
||||
```
|
||||
|
||||
To run openDHT on a different computer from the build computer, the following runtime dependencies are required:
|
||||
```sh
|
||||
sudo apt install libargon2-1 libjsoncpp26
|
||||
```
|
||||
|
||||
### Ubuntu 24.04 and Debian 12
|
||||
|
||||
```sh
|
||||
# Install dependencies
|
||||
sudo apt install pkg-config libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libargon2-0-dev libmsgpack-dev libssl-dev libfmt-dev libjsoncpp-dev libhttp-parser-dev libasio-dev
|
||||
|
||||
# Install Python binding dependencies
|
||||
sudo apt-get install cython3 python3-dev python3-setuptools python3-build
|
||||
```
|
||||
|
||||
Optionally, install RESTinio to enable the OpenDHT proxy client and server:
|
||||
```sh
|
||||
mkdir /usr/include/nonstd
|
||||
wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp -O /usr/include/nonstd/expected.hpp
|
||||
|
||||
wget https://github.com/Stiffstream/restinio/releases/download/v.0.7.3/restinio-0.7.3.tar.bz2
|
||||
tar -xjf restinio-0.7.3.tar.bz2
|
||||
cd restinio-0.7.3/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 .
|
||||
make -j2 && make install
|
||||
```
|
||||
|
||||
### Fedora
|
||||
|
||||
```sh
|
||||
# Install GnuTLS, Readline and msgpack-c
|
||||
sudo dnf install readline-devel gnutls-devel msgpack-devel asio-devel libargon2-devel fmt-devel
|
||||
# Install python binding dependencies
|
||||
sudo dnf install python3-Cython python3-devel redhat-rpm-config
|
||||
```
|
||||
|
||||
### macOS
|
||||
|
||||
```sh
|
||||
brew install gnutls msgpack-cxx argon2 asio readline jsoncpp fmt
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
Using CMake:
|
||||
|
||||
```sh
|
||||
# Clone the repository
|
||||
git clone https://github.com/savoirfairelinux/opendht.git
|
||||
|
||||
# Build and install
|
||||
cd opendht
|
||||
mkdir build && cd build
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
make -j$(nproc)
|
||||
sudo make install
|
||||
```
|
||||
|
||||
#### Example Configurations
|
||||
|
||||
Minimal build (libraries only):
|
||||
```sh
|
||||
cmake -DOPENDHT_TOOLS=OFF ..
|
||||
```
|
||||
|
||||
Full-featured build with proxy support, Python, and C bindings:
|
||||
```sh
|
||||
cmake -DOPENDHT_PYTHON=ON \
|
||||
-DOPENDHT_C=ON \
|
||||
-DOPENDHT_PROXY_SERVER=ON \
|
||||
-DOPENDHT_PROXY_SERVER_IDENTITY=ON \
|
||||
-DOPENDHT_PROXY_CLIENT=ON \
|
||||
-DOPENDHT_PUSH_NOTIFICATIONS=ON \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
```
|
||||
|
||||
## Windows/MSVC
|
||||
|
||||
Building on Windows with MSVC is supported with VCPKG and CMake.
|
||||
|
||||
### Build with VCPKG in manifest mode
|
||||
|
||||
1. Install [VCPKG](https://github.com/microsoft/vcpkg) and required dependencies:
|
||||
```ps1
|
||||
git clone https://github.com/microsoft/vcpkg.git
|
||||
cd vcpkg; .\bootstrap-vcpkg.bat
|
||||
```
|
||||
|
||||
2. Use CMake preset for vcpkg:
|
||||
```ps1
|
||||
cd opendht
|
||||
cmake --preset=vcpkg_manifest .
|
||||
cmake --build .
|
||||
```
|
||||
+191
-622
@@ -1,42 +1,28 @@
|
||||
cmake_minimum_required (VERSION 3.21..3.31)
|
||||
if(POLICY CMP0091)
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
endif()
|
||||
cmake_minimum_required (VERSION 3.16..3.28)
|
||||
if(POLICY CMP0135)
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0167)
|
||||
cmake_policy(SET CMP0167 NEW)
|
||||
endif()
|
||||
|
||||
set (opendht_VERSION_MAJOR 3)
|
||||
set (opendht_VERSION_MINOR 6.0)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
project (opendht
|
||||
VERSION ${opendht_VERSION}
|
||||
DESCRIPTION "OpenDHT: A lightweight C++17 Distributed Hash Table library."
|
||||
HOMEPAGE_URL "https://opendht.net/"
|
||||
)
|
||||
project (opendht)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
include(CheckIncludeFileCXX)
|
||||
set(POSSIBLE_PKGCONFIG OFF)
|
||||
if(NOT MSVC)
|
||||
include(FindPkgConfig)
|
||||
set(POSSIBLE_PKGCONFIG ON)
|
||||
endif()
|
||||
include(FindPkgConfig)
|
||||
include(cmake/CheckAtomic.cmake)
|
||||
include(CTest)
|
||||
include(FetchContent)
|
||||
|
||||
set (opendht_VERSION_MAJOR 3)
|
||||
set (opendht_VERSION_MINOR 2.0)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
|
||||
# Options
|
||||
option (BUILD_SHARED_LIBS "Build shared library" ON)
|
||||
option (OPENDHT_USE_PKGCONFIG "Use pkg-config to find installed libraries where possible" ${POSSIBLE_PKGCONFIG})
|
||||
CMAKE_DEPENDENT_OPTION (OPENDHT_STATIC "Build static library" OFF BUILD_SHARED_LIBS ON)
|
||||
option (OPENDHT_PYTHON "Build Python bindings" OFF)
|
||||
option (OPENDHT_TOOLS "Build DHT tools" ON)
|
||||
option (OPENDHT_EXAMPLES "Build DHT examples" OFF)
|
||||
option (OPENDHT_SYSTEMD "Install systemd module" OFF)
|
||||
option (OPENDHT_SYSTEMD_UNIT_FILE_LOCATION "Where to install systemd unit file")
|
||||
option (OPENDHT_SANITIZE "Build with address sanitizer and stack protector" OFF)
|
||||
@@ -47,228 +33,69 @@ 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 indexing feature" 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)
|
||||
option (OPENDHT_CPACK "Add CPack support" OFF)
|
||||
option (OPENDHT_DOWNLOAD_DEPS "Fetch automatically the missing dependency libraries from the network" ON)
|
||||
|
||||
find_package(Doxygen QUIET)
|
||||
if (DOXYGEN_FOUND)
|
||||
option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
|
||||
endif ()
|
||||
find_package(Doxygen)
|
||||
option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
|
||||
|
||||
# Build flags
|
||||
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED on)
|
||||
if(MSVC AND NOT BUILD_SHARED_LIBS AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
|
||||
if (OPENDHT_C)
|
||||
set (CMAKE_C_STANDARD 11)
|
||||
set (CMAKE_C_STANDARD_REQUIRED ON)
|
||||
if (MSVC)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /experimental:c11atomics")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /experimental:c11atomics")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Dependencies
|
||||
if (NOT HAVE_CXX_ATOMICS_WITHOUT_LIB
|
||||
# For ARM EABI (armel), little-endian MIPS (mipsel), etc.
|
||||
OR NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
link_libraries (atomic)
|
||||
endif ()
|
||||
|
||||
if(WIN32)
|
||||
include(cmake/WindowsUtils.cmake)
|
||||
get_WIN32_WINNT(WINNT_VERSION)
|
||||
message(STATUS "Windows NT version detection: ${WINNT_VERSION}")
|
||||
# Prevents MinGW from problems linking Windows networking and IPC functions on Windows 10/11
|
||||
# if _WIN32_WINNT is not defined correctly
|
||||
if(NOT MSVC)
|
||||
add_definitions(-D_WIN32_WINNT=${WINNT_VERSION} -DWINVER=${WINNT_VERSION})
|
||||
endif()
|
||||
set(CMAKE_DEBUG_POSTFIX "")
|
||||
endif()
|
||||
|
||||
# Dependencies
|
||||
if(OPENDHT_DOWNLOAD_DEPS)
|
||||
message(STATUS "Dependency downloader fallback activated")
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(MAP_IMPORTED_CONFIG_RELWITHDEBINFO RELEASE) # MSVC CMake cache workaround
|
||||
endif ()
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
if (NOT MSVC)
|
||||
# Initialize pkg-config substitution variables for llhttp before any detection
|
||||
set(http_lib "")
|
||||
set(llhttp_lib "")
|
||||
# Generalized UNIX/MSYS2 build pipeline
|
||||
set (THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package (Threads)
|
||||
if (OPENDHT_USE_PKGCONFIG)
|
||||
find_package (PkgConfig REQUIRED)
|
||||
# GNUTLS
|
||||
pkg_search_module (GnuTLS REQUIRED IMPORTED_TARGET gnutls)
|
||||
# libnettle
|
||||
pkg_search_module (Nettle REQUIRED IMPORTED_TARGET nettle)
|
||||
# libargon2
|
||||
pkg_search_module (argon2 REQUIRED IMPORTED_TARGET libargon2)
|
||||
set(argon2_lib ", libargon2")
|
||||
# jsoncpp
|
||||
pkg_search_module (Jsoncpp IMPORTED_TARGET jsoncpp)
|
||||
if(Jsoncpp_FOUND)
|
||||
set(JSONCPP_LIBRARIES PkgConfig::Jsoncpp)
|
||||
set(JSONCPP_INCLUDE_DIRS ${Jsoncpp_INCLUDE_DIRS})
|
||||
set(JSONCPP_FOUND ${Jsoncpp_FOUND})
|
||||
|
||||
pkg_search_module (simdutf IMPORTED_TARGET simdutf)
|
||||
if (NOT simdutf_FOUND)
|
||||
message(STATUS "simdutf not found with pkgconfig")
|
||||
if (OPENDHT_DOWNLOAD_DEPS)
|
||||
message(STATUS "Fallback mode specified, downloading simdutf")
|
||||
set(SIMDUTF_TESTS OFF CACHE INTERNAL "Disable tests for simdutf downloader")
|
||||
set(SIMDUTF_TOOLS OFF CACHE INTERNAL "Disable tools for simdutf downloader")
|
||||
set(SIMDUTF_CXX_STANDARD 17 CACHE INTERNAL "Set C++ standard for simdutf downloader")
|
||||
FetchContent_Declare(simdutf
|
||||
GIT_REPOSITORY "https://github.com/simdutf/simdutf.git"
|
||||
GIT_TAG "v7.5.0"
|
||||
)
|
||||
FetchContent_MakeAvailable(simdutf)
|
||||
set(SIMDUTF_LIBRARIES simdutf::simdutf)
|
||||
else()
|
||||
message(SEND_ERROR "simdutf not found and the fallback downloader is not set! Install simdutf or use OPENDHT_DOWNLOAD_DEPS option")
|
||||
endif()
|
||||
else()
|
||||
set(SIMDUTF_LIBRARIES PkgConfig::simdutf)
|
||||
set(simdutf_lib ", ${simdutf_MODULE_NAME}")
|
||||
endif()
|
||||
endif()
|
||||
# libfmt
|
||||
pkg_search_module (fmt REQUIRED IMPORTED_TARGET fmt)
|
||||
# libreadline
|
||||
if (OPENDHT_TOOLS AND NOT APPLE)
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
|
||||
# use OpenBSD-readline (not GNU)
|
||||
find_library(readline NAMES readline PATHS ${CMAKE_LIBRARY_PATH})
|
||||
if("${readline}" MATCHES "readline-NOTFOUND")
|
||||
message(SEND_ERROR "libreadline: not found")
|
||||
else()
|
||||
set(READLINE_LIBRARIES readline)
|
||||
endif()
|
||||
else()
|
||||
pkg_search_module(readline REQUIRED IMPORTED_TARGET readline)
|
||||
message(STATUS "libreadline: version ${readline_VERSION}")
|
||||
set(READLINE_VERSION ${readline_VERSION})
|
||||
if(READLINE_VERSION VERSION_LESS 6)
|
||||
message(SEND_ERROR "libreadline: required version 6.0 or later")
|
||||
endif()
|
||||
set(READLINE_LIBRARIES ${readline_LIBRARIES})
|
||||
link_directories(${readline_LIBRARY_DIRS})
|
||||
endif()
|
||||
endif ()
|
||||
# ASIO
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
pkg_search_module(asio IMPORTED_TARGET asio)
|
||||
if (NOT asio_FOUND)
|
||||
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED)
|
||||
endif()
|
||||
message(STATUS "Found ASIO: ${ASIO_INCLUDE_DIR}")
|
||||
endif ()
|
||||
# llhttp
|
||||
if (OPENDHT_HTTP)
|
||||
pkg_search_module(LLHTTP IMPORTED_TARGET llhttp libllhttp)
|
||||
if (LLHTTP_FOUND)
|
||||
message(STATUS "Found llhttp: ${LLHTTP_FOUND} ${LLHTTP_INCLUDE_DIR} (module: ${LLHTTP_MODULE_NAME})")
|
||||
set(llhttp_target PkgConfig::LLHTTP)
|
||||
set(llhttp_lib ", ${LLHTTP_MODULE_NAME}")
|
||||
else()
|
||||
message(STATUS "llhttp not found with pkgconfig")
|
||||
endif()
|
||||
else ()
|
||||
set(OPENDHT_PROXY_OPENSSL OFF)
|
||||
endif ()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
pkg_search_module(OPENSSL REQUIRED IMPORTED_TARGET openssl)
|
||||
if (OPENSSL_FOUND)
|
||||
message(STATUS "Found OpenSSL ${OPENSSL_VERSION} ${OPENSSL_INCLUDE_DIRS}")
|
||||
set(openssl_lib ", openssl")
|
||||
else ()
|
||||
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
|
||||
endif()
|
||||
endif()
|
||||
else ()
|
||||
find_package(GnuTLS REQUIRED)
|
||||
include_directories(${GNUTLS_INCLUDE_DIR})
|
||||
# jsoncpp
|
||||
find_package(jsoncpp CONFIG REQUIRED)
|
||||
set(JSONCPP_FOUND TRUE)
|
||||
# libfmt
|
||||
find_package(fmt CONFIG REQUIRED)
|
||||
# libargon2
|
||||
find_path(ARGON2_INCLUDE_DIR argon2.h REQUIRED)
|
||||
set(argon2_lib ", libargon2")
|
||||
# libreadline
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
# ASIO
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED)
|
||||
message(STATUS "Found ASIO ${ASIO_INCLUDE_DIR}")
|
||||
else()
|
||||
message(STATUS "ASIO not required")
|
||||
endif ()
|
||||
# llhttp
|
||||
if (OPENDHT_HTTP)
|
||||
find_package(llhttp CONFIG REQUIRED)
|
||||
set(llhttp_target llhttp::llhttp_static)
|
||||
set(http_lib "-lllhttp")
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
find_package(openssl REQUIRED)
|
||||
endif()
|
||||
else ()
|
||||
set(OPENDHT_PROXY_OPENSSL OFF)
|
||||
endif ()
|
||||
endif ()
|
||||
# File-based searches
|
||||
# msgpack
|
||||
find_package (PkgConfig REQUIRED)
|
||||
pkg_search_module (GnuTLS REQUIRED IMPORTED_TARGET gnutls)
|
||||
pkg_search_module (Nettle REQUIRED IMPORTED_TARGET nettle)
|
||||
check_include_file_cxx(msgpack.hpp HAVE_MSGPACKCXX)
|
||||
if (NOT HAVE_MSGPACKCXX)
|
||||
find_package(msgpack CONFIG NAMES msgpack-cxx)
|
||||
find_package(msgpack QUIET CONFIG NAMES msgpack msgpackc-cxx)
|
||||
if (NOT msgpack_FOUND)
|
||||
find_package(msgpack CONFIG NAMES msgpack msgpackc-cxx)
|
||||
if (msgpack_FOUND)
|
||||
set(MSGPACK_TARGET "msgpackc-cxx")
|
||||
else()
|
||||
if(OPENDHT_DOWNLOAD_DEPS)
|
||||
# Workaround for msgpack-cxx
|
||||
FetchContent_Declare(msgpack-c
|
||||
GIT_REPOSITORY "https://github.com/msgpack/msgpack-c.git"
|
||||
GIT_TAG "cpp-7.0.0"
|
||||
FIND_PACKAGE_ARGS NAMES msgpack-c
|
||||
)
|
||||
set(MSGPACK_USE_BOOST OFF CACHE INTERNAL "Workaround for Boost")
|
||||
FetchContent_MakeAvailable(msgpack-c)
|
||||
find_package(msgpack-cxx CONFIG REQUIRED)
|
||||
set(MSGPACK_TARGET msgpack-cxx)
|
||||
else()
|
||||
message(SEND_ERROR "msgpack not found and the fallback downloader is not set! Please install msgpack or use OPENDHT_DOWNLOAD_DEPS option")
|
||||
endif()
|
||||
endif ()
|
||||
else()
|
||||
find_package(msgpack REQUIRED CONFIG NAMES msgpack-cxx)
|
||||
set(MSGPACK_TARGET "msgpack-cxx")
|
||||
else()
|
||||
set(MSGPACK_TARGET "msgpackc-cxx")
|
||||
endif()
|
||||
endif()
|
||||
# llhttp
|
||||
if (OPENDHT_HTTP AND NOT LLHTTP_FOUND)
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
pkg_search_module(argon2 REQUIRED IMPORTED_TARGET libargon2)
|
||||
set(argon2_lib ", libargon2")
|
||||
pkg_search_module(Jsoncpp IMPORTED_TARGET jsoncpp)
|
||||
if (Jsoncpp_FOUND)
|
||||
add_definitions(-DOPENDHT_JSONCPP)
|
||||
set(jsoncpp_lib ", jsoncpp")
|
||||
list (APPEND opendht_SOURCES
|
||||
src/base64.h
|
||||
src/base64.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED)
|
||||
message(STATUS "Found ASIO ${ASIO_INCLUDE_DIR}")
|
||||
else()
|
||||
message(STATUS "ASIO not required")
|
||||
endif ()
|
||||
|
||||
find_package(fmt)
|
||||
|
||||
if (OPENDHT_HTTP)
|
||||
find_package(Restinio REQUIRED)
|
||||
|
||||
# llhttp
|
||||
find_path(LLHTTP_INCLUDE_DIR llhttp.h)
|
||||
find_library(LLHTTP_LIBRARY NAMES llhttp libllhttp)
|
||||
if (LLHTTP_INCLUDE_DIR AND LLHTTP_LIBRARY)
|
||||
@@ -279,14 +106,8 @@ if (NOT MSVC)
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${LLHTTP_INCLUDE_DIR}
|
||||
)
|
||||
set(llhttp_target llhttp_static)
|
||||
if (NOT llhttp_lib)
|
||||
set(http_lib "-lllhttp")
|
||||
endif()
|
||||
elseif (OPENDHT_DOWNLOAD_DEPS)
|
||||
message(STATUS "Fallback mode specified, downloading llhttp")
|
||||
FetchContent_Declare(llhttp-local REQUIRED
|
||||
URL "https://github.com/nodejs/llhttp/archive/refs/tags/release/v9.2.1.tar.gz"
|
||||
)
|
||||
else()
|
||||
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()
|
||||
@@ -294,125 +115,61 @@ if (NOT MSVC)
|
||||
set(BUILD_STATIC_LIBS ON CACHE INTERNAL "")
|
||||
endif()
|
||||
FetchContent_MakeAvailable(llhttp-local)
|
||||
include_directories(${llhttp-local_SOURCE_DIR}/include)
|
||||
link_directories(${llhttp-local_BINARY_DIR}) # MacOS library search workaround
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(llhttp_target llhttp_shared)
|
||||
else()
|
||||
set(llhttp_target llhttp_static)
|
||||
endif()
|
||||
if (NOT llhttp_lib)
|
||||
set(http_lib "-lllhttp")
|
||||
endif()
|
||||
else()
|
||||
message(SEND_ERROR "llhttp not found and fallback downloader disabled. Install llhttp or use OPENDHT_DOWNLOAD_DEPS option")
|
||||
endif ()
|
||||
endif ()
|
||||
# restinio: does not provide pkg-config PC file
|
||||
if(OPENDHT_HTTP)
|
||||
find_package(Restinio REQUIRED)
|
||||
set(restinio_target "")
|
||||
endif()
|
||||
# System-specific pipeline setup
|
||||
if(APPLE)
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
endif()
|
||||
else () # MSVC
|
||||
include_directories(src/compat/msvc)
|
||||
include_directories(src/compat/win32)
|
||||
|
||||
find_package(unofficial-argon2 CONFIG REQUIRED)
|
||||
include_directories(${ARGON2_INCLUDEDIR})
|
||||
set(argon2_lib ", libargon2")
|
||||
|
||||
find_package(GnuTLS REQUIRED)
|
||||
include_directories(${GNUTLS_INCLUDE_DIR})
|
||||
|
||||
find_package(msgpack-cxx CONFIG REQUIRED)
|
||||
get_target_property(MSGPACK_INCLUDEDIR msgpack-cxx INTERFACE_INCLUDE_DIRECTORIES)
|
||||
include_directories(${MSGPACK_INCLUDEDIR})
|
||||
|
||||
find_package(jsoncpp CONFIG REQUIRED)
|
||||
set(JSONCPP_FOUND TRUE)
|
||||
include_directories(${JSONCPP_INCLUDE_DIRS})
|
||||
|
||||
find_package(simdutf CONFIG REQUIRED)
|
||||
include_directories(${SIMDUTF_INCLUDE_DIRS})
|
||||
|
||||
find_package(fmt CONFIG REQUIRED)
|
||||
include_directories(${FMT_INCLUDEDIR})
|
||||
|
||||
if(OPENDHT_TOOLS)
|
||||
find_package(unofficial-readline-win32 CONFIG REQUIRED)
|
||||
include_directories(${READLINE_INCLUDEDIR})
|
||||
endif()
|
||||
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
find_package(asio CONFIG REQUIRED)
|
||||
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED HINTS ${ASIO_INCLUDE_DIRS}/asio/include)
|
||||
message(STATUS "Found ASIO ${ASIO_INCLUDE_DIR}")
|
||||
else()
|
||||
message(STATUS "ASIO not required")
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_HTTP)
|
||||
find_package(restinio CONFIG REQUIRED)
|
||||
set(restinio_target restinio::restinio)
|
||||
|
||||
find_package(llhttp CONFIG REQUIRED)
|
||||
set(http_lib "-lllhttp")
|
||||
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
set(openssl_lib ", openssl")
|
||||
endif()
|
||||
else()
|
||||
set(http_lib "-lllhttp")
|
||||
|
||||
if (NOT Jsoncpp_FOUND)
|
||||
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
# https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
|
||||
pkg_search_module(OPENSSL REQUIRED IMPORTED_TARGET openssl)
|
||||
if (OPENSSL_FOUND)
|
||||
message(STATUS "Found OpenSSL ${OPENSSL_VERSION} ${OPENSSL_INCLUDE_DIRS}")
|
||||
set(openssl_lib ", openssl")
|
||||
else ()
|
||||
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
|
||||
endif()
|
||||
endif()
|
||||
else ()
|
||||
set(OPENDHT_PROXY_OPENSSL OFF)
|
||||
endif()
|
||||
|
||||
message(STATUS "Discovering external non-CMake libraries")
|
||||
find_library(NETTLE_LIBRARY NAMES nettle libnettle REQUIRED)
|
||||
find_library(HOGWEED_LIBRARY NAMES hogweed REQUIRED)
|
||||
find_library(TASN_LIBRARY NAMES tasn1 REQUIRED)
|
||||
find_path(NETTLE_INCLUDE_DIR nettle/aes.h REQUIRED)
|
||||
|
||||
add_library(nettle_lib STATIC IMPORTED)
|
||||
set_target_properties(nettle_lib PROPERTIES
|
||||
IMPORTED_LOCATION ${NETTLE_LIBRARY}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${NETTLE_INCLUDE_DIR}
|
||||
)
|
||||
add_library(hogweed_lib STATIC IMPORTED)
|
||||
set_target_properties(hogweed_lib PROPERTIES
|
||||
IMPORTED_LOCATION ${HOGWEED_LIBRARY}
|
||||
)
|
||||
add_library(tasn1_lib STATIC IMPORTED)
|
||||
set_target_properties(tasn1_lib PROPERTIES
|
||||
IMPORTED_LOCATION ${TASN_LIBRARY}
|
||||
)
|
||||
|
||||
endif ()
|
||||
|
||||
# Definitions
|
||||
if(JSONCPP_FOUND)
|
||||
add_definitions(-DOPENDHT_JSONCPP)
|
||||
set(jsoncpp_lib ", jsoncpp")
|
||||
endif ()
|
||||
else ()
|
||||
set (WIN32_DEP_DIR ${PROJECT_SOURCE_DIR}/../)
|
||||
include_directories(${WIN32_DEP_DIR}/../msvc/include) # SMP gnutls
|
||||
include_directories(${WIN32_DEP_DIR}/argon2/include)
|
||||
include_directories(${WIN32_DEP_DIR}/jsoncpp/include)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/base64.h
|
||||
src/base64.cpp
|
||||
)
|
||||
endif()
|
||||
add_definitions(-DOPENDHT_JSONCPP)
|
||||
include_directories(${WIN32_DEP_DIR}/msgpack-c/include)
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
include_directories(
|
||||
${WIN32_DEP_DIR}/asio/asio/include
|
||||
${WIN32_DEP_DIR}/openssl/include
|
||||
${WIN32_DEP_DIR}/restinio/dev
|
||||
${WIN32_DEP_DIR}/fmt/include
|
||||
${WIN32_DEP_DIR}/http_parser
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
add_definitions(-DASIO_STANDALONE)
|
||||
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-attributes -Wno-return-type -Wno-deprecated -Wno-deprecated-declarations -Wno-unknown-pragmas -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")
|
||||
@@ -421,10 +178,11 @@ 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 /bigobj /utf-8 /EHsc")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
endif ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
|
||||
|
||||
@@ -484,11 +242,11 @@ list (APPEND opendht_SOURCES
|
||||
list (APPEND opendht_HEADERS
|
||||
include/opendht.h
|
||||
include/opendht/def.h
|
||||
include/opendht/rng.h
|
||||
include/opendht/infohash.h
|
||||
include/opendht/utils.h
|
||||
include/opendht/sockaddr.h
|
||||
include/opendht/rng.h
|
||||
include/opendht/crypto.h
|
||||
include/opendht/infohash.h
|
||||
include/opendht/default_types.h
|
||||
include/opendht/node.h
|
||||
include/opendht/value.h
|
||||
@@ -514,7 +272,7 @@ if (OPENDHT_PEER_DISCOVERY)
|
||||
add_definitions(-DOPENDHT_PEER_DISCOVERY)
|
||||
endif()
|
||||
|
||||
if (OPENDHT_PYTHON AND NOT OPENDHT_INDEX)
|
||||
if (OPENDHT_PYTHON)
|
||||
message("Indexation enabled since it is required for Python support")
|
||||
set(OPENDHT_INDEX ON)
|
||||
endif()
|
||||
@@ -549,7 +307,7 @@ endif ()
|
||||
|
||||
if (OPENDHT_HTTP)
|
||||
if (OPENDHT_PUSH_NOTIFICATIONS)
|
||||
message(STATUS "Using push notification capability")
|
||||
message("Using push notification")
|
||||
add_definitions(-DOPENDHT_PUSH_NOTIFICATIONS)
|
||||
endif ()
|
||||
list (APPEND opendht_HEADERS
|
||||
@@ -568,182 +326,100 @@ if (MSVC)
|
||||
endif ()
|
||||
|
||||
# Targets
|
||||
add_library(opendht ${opendht_SOURCES} ${opendht_HEADERS})
|
||||
target_include_directories(opendht
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
|
||||
set_target_properties(opendht PROPERTIES OUTPUT_NAME "opendht")
|
||||
|
||||
# Linker pipelines
|
||||
if (MSVC)
|
||||
message(STATUS "Build pipeline: Windows/MSVC + vcpkg")
|
||||
message(STATUS "Used GnuTLS library: ${GNUTLS_LIBRARIES}")
|
||||
message(STATUS "Used NETTLE library: ${NETTLE_LIBRARY}")
|
||||
target_link_libraries(opendht
|
||||
PRIVATE
|
||||
unofficial::argon2::libargon2
|
||||
nettle_lib
|
||||
hogweed_lib
|
||||
tasn1_lib
|
||||
PUBLIC
|
||||
${GNUTLS_LIBRARIES}
|
||||
msgpack-cxx
|
||||
JsonCpp::JsonCpp
|
||||
fmt::fmt
|
||||
simdutf::simdutf
|
||||
wsock32
|
||||
ws2_32
|
||||
)
|
||||
if (OPENDHT_TOOLS)
|
||||
target_link_libraries(opendht PUBLIC unofficial::readline-win32::readline)
|
||||
if (OPENDHT_STATIC)
|
||||
if (OPENDHT_TOOLS)
|
||||
function (add_obj_lib name libfile)
|
||||
add_library(${name} OBJECT IMPORTED)
|
||||
set_property(TARGET ${name} PROPERTY IMPORTED_OBJECTS ${libfile})
|
||||
endfunction ()
|
||||
add_obj_lib (win32_json ${WIN32_DEP_DIR}/../msvc/lib/x64/lib_json.lib)
|
||||
add_obj_lib (win32_gnutls ${WIN32_DEP_DIR}/../msvc/lib/x64/libgnutls.lib)
|
||||
add_obj_lib (win32_argon2 ${WIN32_DEP_DIR}/argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib)
|
||||
list (APPEND obj_libs
|
||||
$<TARGET_OBJECTS:win32_json>
|
||||
$<TARGET_OBJECTS:win32_gnutls>
|
||||
$<TARGET_OBJECTS:win32_argon2>
|
||||
)
|
||||
if (OPENDHT_HTTP)
|
||||
add_obj_lib (win32_fmt ${WIN32_DEP_DIR}/fmt/msvc/Release/fmt.lib)
|
||||
add_obj_lib (win32_http_parser ${WIN32_DEP_DIR}/http_parser/x64/Release/http-parser.lib)
|
||||
add_obj_lib (win32_ssl ${WIN32_DEP_DIR}/openssl/libssl_static.lib)
|
||||
add_obj_lib (win32_crypto ${WIN32_DEP_DIR}/openssl/libcrypto_static.lib)
|
||||
list (APPEND obj_libs
|
||||
$<TARGET_OBJECTS:win32_fmt>
|
||||
$<TARGET_OBJECTS:win32_http_parser>
|
||||
$<TARGET_OBJECTS:win32_ssl>
|
||||
$<TARGET_OBJECTS:win32_crypto>
|
||||
)
|
||||
endif ()
|
||||
else ()
|
||||
list (APPEND win32_Libs
|
||||
${PROJECT_SOURCE_DIR}/../../msvc/lib/x64/libgnutls.lib
|
||||
${PROJECT_SOURCE_DIR}/../../msvc/lib/x64/lib_json.lib
|
||||
${PROJECT_SOURCE_DIR}/../argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib
|
||||
)
|
||||
list (APPEND win32_Libs
|
||||
${PROJECT_SOURCE_DIR}/../fmt/msvc/Release/fmt.lib
|
||||
${PROJECT_SOURCE_DIR}/../http_parser/x64/Release/http-parser.lib
|
||||
${PROJECT_SOURCE_DIR}/../openssl/libssl.lib
|
||||
${PROJECT_SOURCE_DIR}/../openssl/libcrypto.lib
|
||||
)
|
||||
endif ()
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4006")
|
||||
endif()
|
||||
if (OPENDHT_HTTP)
|
||||
target_link_libraries(opendht
|
||||
PUBLIC restinio::restinio
|
||||
PRIVATE llhttp::llhttp_static)
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht PUBLIC OpenSSL::SSL OpenSSL::Crypto)
|
||||
endif()
|
||||
target_link_libraries(opendht PUBLIC llhttp::llhttp_static)
|
||||
endif ()
|
||||
|
||||
add_library (opendht
|
||||
${opendht_SOURCES}
|
||||
${opendht_HEADERS}
|
||||
${obj_libs}
|
||||
)
|
||||
set_target_properties (opendht PROPERTIES OUTPUT_NAME "opendht")
|
||||
|
||||
if (NOT HAVE_MSGPACKCXX)
|
||||
target_link_libraries(opendht PUBLIC ${MSGPACK_TARGET})
|
||||
endif()
|
||||
if (APPLE)
|
||||
target_link_libraries(opendht PRIVATE "-framework CoreFoundation" "-framework Security")
|
||||
endif()
|
||||
if (MSVC)
|
||||
if (OPENDHT_STATIC)
|
||||
target_link_libraries(opendht PUBLIC ${Win32_STATIC_LIBRARIES} ${Win32_IMPORT_LIBRARIES})
|
||||
set_target_properties (opendht PROPERTIES OUTPUT_NAME "libopendht")
|
||||
endif()
|
||||
else()
|
||||
if (APPLE)
|
||||
message(STATUS "Build pipeline: Apple/Darwin")
|
||||
target_link_libraries(opendht PRIVATE "-framework CoreFoundation" "-framework Security")
|
||||
endif ()
|
||||
# Generalized UNIX/MSYS2 build pipeline
|
||||
if (OPENDHT_USE_PKGCONFIG)
|
||||
target_link_libraries(opendht
|
||||
PRIVATE
|
||||
PkgConfig::argon2
|
||||
PkgConfig::Nettle
|
||||
${SIMDUTF_LIBRARIES}
|
||||
PUBLIC
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
PkgConfig::GnuTLS
|
||||
PkgConfig::fmt
|
||||
${JSONCPP_LIBRARIES}
|
||||
)
|
||||
if(OPENDHT_TOOLS)
|
||||
message(STATUS ${READLINE_LIBRARIES})
|
||||
target_link_libraries(opendht PUBLIC ${READLINE_LIBRARIES})
|
||||
endif()
|
||||
if(OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
if (asio_FOUND)
|
||||
target_link_libraries(opendht PUBLIC PkgConfig::asio)
|
||||
endif()
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht PUBLIC PkgConfig::OPENSSL)
|
||||
endif()
|
||||
else(OPENDHT_USE_PKGCONFIG)
|
||||
target_link_libraries(opendht
|
||||
PRIVATE
|
||||
argon2
|
||||
nettle
|
||||
PUBLIC
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${GNUTLS_LIBRARIES}
|
||||
jsoncpp
|
||||
)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_link_libraries(opendht PUBLIC fmt::fmt)
|
||||
else()
|
||||
target_link_libraries(opendht PUBLIC fmt::fmt-header-only)
|
||||
endif()
|
||||
if(OPENDHT_TOOLS)
|
||||
target_link_libraries(opendht PUBLIC ${READLINE_LIBRARIES})
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht PUBLIC OpenSSL::SSL OpenSSL::Crypto)
|
||||
endif()
|
||||
endif(OPENDHT_USE_PKGCONFIG)
|
||||
if (NOT HAVE_MSGPACKCXX)
|
||||
target_link_libraries(opendht PUBLIC ${MSGPACK_TARGET})
|
||||
endif()
|
||||
if(OPENDHT_HTTP)
|
||||
target_link_libraries(opendht
|
||||
PUBLIC # Required for linking tests
|
||||
${llhttp_target}
|
||||
${restinio_target}
|
||||
target_link_libraries(opendht
|
||||
PRIVATE
|
||||
PkgConfig::argon2
|
||||
PkgConfig::Nettle
|
||||
PUBLIC
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
PkgConfig::GnuTLS
|
||||
fmt::fmt
|
||||
)
|
||||
if (OPENDHT_HTTP)
|
||||
target_link_libraries(opendht PUBLIC ${llhttp_target})
|
||||
endif()
|
||||
if (OPENDHT_IO_URING AND liburing_FOUND)
|
||||
if (Jsoncpp_FOUND)
|
||||
target_link_libraries(opendht PUBLIC PkgConfig::Jsoncpp)
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht PUBLIC PkgConfig::OPENSSL)
|
||||
endif()
|
||||
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)
|
||||
endif()
|
||||
# System-specific linker pipelines
|
||||
if (WIN32 AND MINGW) # MSYS2
|
||||
message(STATUS "Build pipeline: Windows/MSYS2-MinGW")
|
||||
target_link_libraries(opendht PUBLIC wsock32 ws2_32)
|
||||
if(OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht PUBLIC Crypt32)
|
||||
endif()
|
||||
else() # UNIX / LLVM
|
||||
message(STATUS "Build pipeline: UNIX generalized")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set_target_properties (opendht PROPERTIES IMPORT_SUFFIX "_import.lib")
|
||||
set_target_properties (opendht PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
target_compile_definitions(opendht PRIVATE OPENDHT_BUILD)
|
||||
target_compile_definitions(opendht PUBLIC opendht_EXPORTS)
|
||||
target_compile_definitions(opendht PRIVATE OPENDHT_BUILD)
|
||||
endif ()
|
||||
|
||||
if(("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") OR
|
||||
("${CMAKE_SYSTEM_NAME}" MATCHES "NetBSD") OR
|
||||
("${CMAKE_SYSTEM_NAME}" MATCHES "DragonFly"))
|
||||
install (TARGETS opendht
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
EXPORT opendht
|
||||
)
|
||||
else()
|
||||
install (TARGETS opendht
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME_DEPENDENCY_SET opendht_rdeps
|
||||
EXPORT opendht
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
install(RUNTIME_DEPENDENCY_SET opendht_rdeps
|
||||
PRE_EXCLUDE_REGEXES
|
||||
"api-ms-win-.*\\.dll"
|
||||
"ext-ms-.*\\.dll"
|
||||
"d3d.*\\.dll"
|
||||
"dxgi.*\\.dll"
|
||||
"uxtheme\\.dll"
|
||||
"dwmapi\\.dll"
|
||||
"crypt32\\.dll"
|
||||
"bcrypt\\.dll"
|
||||
"ncrypt\\.dll"
|
||||
"sechost\\.dll"
|
||||
"user32\\.dll"
|
||||
"kernel32\\.dll"
|
||||
"gdi32\\.dll"
|
||||
"shell32\\.dll"
|
||||
"advapi32\\.dll"
|
||||
"ole32\\.dll"
|
||||
"oleaut32\\.dll"
|
||||
"shlwapi\\.dll"
|
||||
"comdlg32\\.dll"
|
||||
"winspool\\.drv"
|
||||
"mpr\\.dll"
|
||||
"version\\.dll"
|
||||
"ws2_32\\.dll"
|
||||
"vcruntime.*\\.dll"
|
||||
"msvcp.*\\.dll"
|
||||
"wpax.*\\.dll"
|
||||
"azure.*\\.dll"
|
||||
"lsasrv\\.dll"
|
||||
"samsrv\\.dll"
|
||||
)
|
||||
endif()
|
||||
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
|
||||
if (OPENDHT_C)
|
||||
add_library (opendht-c
|
||||
@@ -752,14 +428,7 @@ if (OPENDHT_C)
|
||||
)
|
||||
target_compile_definitions(opendht-c PRIVATE OPENDHT_C_BUILD)
|
||||
target_link_libraries(opendht-c PRIVATE opendht)
|
||||
if(OPENDHT_TOOLS)
|
||||
target_link_libraries(opendht-c PUBLIC ${READLINE_LIBRARIES})
|
||||
endif()
|
||||
if (BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(opendht-c PRIVATE OPENDHT_C_BUILD)
|
||||
target_compile_definitions(opendht-c PUBLIC opendht_c_EXPORTS)
|
||||
set_target_properties (opendht-c PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
endif()
|
||||
set_target_properties (opendht-c PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
install (TARGETS opendht-c DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht-c)
|
||||
|
||||
# PkgConfig module
|
||||
@@ -769,7 +438,7 @@ if (OPENDHT_C)
|
||||
@ONLY
|
||||
)
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht-c.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
install (FILES c/opendht_c.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opendht)
|
||||
install (FILES c/opendht_c.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/opendht)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_TOOLS)
|
||||
@@ -778,53 +447,6 @@ endif ()
|
||||
add_subdirectory(doc)
|
||||
|
||||
if (OPENDHT_PYTHON)
|
||||
if (JSONCPP_FOUND)
|
||||
list (APPEND OPENDHT_PYTHON_INCLUDE_DIRS_LIST ${JSONCPP_INCLUDE_DIRS})
|
||||
#if (OPENDHT_USE_PKGCONFIG)
|
||||
list (APPEND OPENDHT_PYTHON_LIBRARY_DIRS_LIST ${Jsoncpp_LIBRARY_DIRS})
|
||||
#endif()
|
||||
endif()
|
||||
if (NOT HAVE_MSGPACKCXX)
|
||||
get_target_property(MSGPACK_INCLUDEDIR msgpack-cxx INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_target_property(MSGPACK_LIBRARY_DIRS msgpack-cxx INTERFACE_LIBRARY_DIRS)
|
||||
list(APPEND OPENDHT_PYTHON_INCLUDE_DIRS_LIST ${MSGPACK_INCLUDEDIR})
|
||||
if (MSGPACK_LIBRARY_DIRS)
|
||||
list(APPEND OPENDHT_PYTHON_LIBRARY_DIRS_LIST ${MSGPACK_LIBRARY_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Add the directory where the OpenDHT library is built
|
||||
if(WIN32)
|
||||
# Append actual configuration-specific build directories instead of an unevaluated $<CONFIG> generator expression
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
foreach(cfg ${CMAKE_CONFIGURATION_TYPES})
|
||||
list(APPEND OPENDHT_PYTHON_LIBRARY_DIRS_LIST ${CMAKE_CURRENT_BINARY_DIR}/${cfg})
|
||||
endforeach()
|
||||
elseif(CMAKE_BUILD_TYPE)
|
||||
list(APPEND OPENDHT_PYTHON_LIBRARY_DIRS_LIST ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
|
||||
else()
|
||||
list(APPEND OPENDHT_PYTHON_LIBRARY_DIRS_LIST ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
# if using MSVC with vcpkg, add the vcpkg installed directory
|
||||
if (MSVC AND VCPKG_TARGET_TRIPLET)
|
||||
if (VCPKG_INSTALLED_DIR)
|
||||
list(APPEND OPENDHT_PYTHON_LIBRARY_DIRS_LIST "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib")
|
||||
else()
|
||||
list(APPEND OPENDHT_PYTHON_LIBRARY_DIRS_LIST "${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/lib")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (OPENDHT_PYTHON_INCLUDE_DIRS_LIST)
|
||||
list(REMOVE_DUPLICATES OPENDHT_PYTHON_INCLUDE_DIRS_LIST)
|
||||
string(JOIN "\", \"" OPENDHT_PYTHON_INCLUDE_DIRS ${OPENDHT_PYTHON_INCLUDE_DIRS_LIST})
|
||||
set(OPENDHT_PYTHON_INCLUDE_DIRS ", \"${OPENDHT_PYTHON_INCLUDE_DIRS}\"")
|
||||
endif()
|
||||
if (OPENDHT_PYTHON_LIBRARY_DIRS_LIST)
|
||||
list(REMOVE_DUPLICATES OPENDHT_PYTHON_LIBRARY_DIRS_LIST)
|
||||
string(JOIN "\", \"" OPENDHT_PYTHON_LIBRARY_DIRS ${OPENDHT_PYTHON_LIBRARY_DIRS_LIST})
|
||||
set(OPENDHT_PYTHON_LIBRARY_DIRS ", \"${OPENDHT_PYTHON_LIBRARY_DIRS}\"")
|
||||
endif()
|
||||
add_subdirectory(python)
|
||||
endif ()
|
||||
|
||||
@@ -833,7 +455,6 @@ write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersi
|
||||
VERSION ${opendht_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
# PkgConfig module
|
||||
configure_file (
|
||||
opendht.pc.in
|
||||
@@ -842,23 +463,14 @@ configure_file (
|
||||
)
|
||||
|
||||
# Install targets
|
||||
install (DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install (DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
install (EXPORT opendht DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht FILE opendhtConfig.cmake)
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/opendht)
|
||||
if(MSVC AND BUILD_SHARED_LIBS)
|
||||
install(FILES $<TARGET_PDB_FILE:opendht> CONFIGURATIONS "RelWithDebInfo" "Debug" DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
# Unit tests
|
||||
if (BUILD_TESTING)
|
||||
if (NOT MSVC)
|
||||
pkg_search_module(Cppunit REQUIRED IMPORTED_TARGET cppunit)
|
||||
set(cppunit_LIBRARIES PkgConfig::Cppunit)
|
||||
else()
|
||||
find_package(CppUnit CONFIG REQUIRED)
|
||||
set(cppunit_LIBRARIES CppUnit)
|
||||
endif()
|
||||
if (BUILD_TESTING AND NOT MSVC)
|
||||
pkg_search_module(Cppunit REQUIRED IMPORTED_TARGET cppunit)
|
||||
# unit testing
|
||||
list (APPEND test_FILES
|
||||
tests/infohashtester.h
|
||||
@@ -888,57 +500,14 @@ if (BUILD_TESTING)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
# Create one test executable per test implementation (.cpp) so they can be run independently.
|
||||
# We keep using the common tests_runner.cpp (CppUnit registry based) and compile it with each test file.
|
||||
foreach(test_src ${test_FILES})
|
||||
if (test_src MATCHES ".*\\.cpp$")
|
||||
get_filename_component(test_name ${test_src} NAME_WE) # e.g. infohashtester
|
||||
set(target_name ${test_name})
|
||||
add_executable(${target_name}
|
||||
tests/tests_runner.cpp
|
||||
${test_src}
|
||||
)
|
||||
target_link_libraries(${target_name} PRIVATE
|
||||
opendht
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${cppunit_LIBRARIES}
|
||||
)
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
if (WIN32 AND MINGW) # MSYS2
|
||||
target_link_libraries(${target_name} PRIVATE ${OPENSSL_LIBRARIES})
|
||||
elseif(NOT MSVC) # Clang on UNIX-pkgconfig
|
||||
target_link_libraries(${target_name} PRIVATE PkgConfig::OPENSSL)
|
||||
endif()
|
||||
endif()
|
||||
add_test(NAME ${test_name} COMMAND ${test_name})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if (OPENDHT_CPACK)
|
||||
set(CPACK_PACKAGE_NAME "OpenDHT")
|
||||
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
|
||||
set(CPACK_PACKAGE_VENDOR "Savoir-faire Linux, Inc.")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenDHT: A lightweight C++17 Distributed Hash Table library.")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://opendht.net/")
|
||||
set(CPACK_PACKAGE_CONTACT "support@savoirfairelinux.com") # Or a relevant contact/mailing list
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.txt")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "OpenDHT")
|
||||
|
||||
if(WIN32)
|
||||
# WiX specific settings
|
||||
set(CPACK_GENERATOR "WIX") # Can be overridden by -G on the command line
|
||||
set(CPACK_WIX_VERSION 4)
|
||||
set(CPACK_WIX_PRODUCT_GUID "5e2faa2b-a4f4-4431-ba15-ed94e732a949")
|
||||
set(CPACK_WIX_UPGRADE_GUID "cbff4222-9b41-48a2-94ea-6f8a228c5936")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/opendht_logo_512.ico")
|
||||
set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/resources/opendht_install_banner.bmp")
|
||||
set(CPACK_WIX_UI_DIALOG "${CMAKE_CURRENT_SOURCE_DIR}/resources/opendht_install_bg.bmp")
|
||||
set(CPACK_WIX_PROGRAM_MENU_FOLDER "${PROJECT_NAME}")
|
||||
set(CPACK_WIX_INSTALL_SCOPE "perMachine")
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_EXECUTABLES "dhtnode;DHT Node")
|
||||
set(CPACK_CREATE_DESKTOP_LINKS "dhtnode")
|
||||
include(CPack)
|
||||
add_executable(opendht_unit_tests
|
||||
tests/tests_runner.cpp
|
||||
${test_FILES}
|
||||
)
|
||||
target_link_libraries(opendht_unit_tests PRIVATE
|
||||
opendht
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
PkgConfig::Cppunit
|
||||
)
|
||||
add_test(TEST opendht_unit_tests)
|
||||
endif()
|
||||
@@ -1,250 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "unix-make",
|
||||
"description": "Unix Makefiles",
|
||||
"generator": "Unix Makefiles",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "unix-make-full",
|
||||
"description": "Unix Makefiles (Full build)",
|
||||
"inherits": "unix-make",
|
||||
"cacheVariables": {
|
||||
"OPENDHT_C": true,
|
||||
"OPENDHT_PROXY_CLIENT": true,
|
||||
"OPENDHT_PROXY_SERVER": true,
|
||||
"OPENDHT_PUSH_NOTIFICATIONS": true,
|
||||
"OPENDHT_PYTHON": true,
|
||||
"OPENDHT_INDEX": true,
|
||||
"BUILD_TESTING": true,
|
||||
"OPENDHT_EXAMPLES": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "unix-make-release",
|
||||
"description": "Unix Makefiles (Release build)",
|
||||
"inherits": "unix-make-full",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"BUILD_SHARED_LIBS": true,
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_SANITIZE": false,
|
||||
"OPENDHT_EXAMPLES": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ninja",
|
||||
"generator": "Ninja",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ninja-release",
|
||||
"inherits": "ninja",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"BUILD_SHARED_LIBS": true,
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_SANITIZE": false,
|
||||
"OPENDHT_CPACK": true,
|
||||
"OPENDHT_C": true,
|
||||
"OPENDHT_PROXY_CLIENT": true,
|
||||
"OPENDHT_PROXY_SERVER": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "msvc",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"BUILD_TESTING": true,
|
||||
"VCPKG_MANIFEST_FEATURES": "test",
|
||||
"OPENDHT_PROXY_CLIENT": false,
|
||||
"OPENDHT_PROXY_SERVER": false,
|
||||
"OPENDHT_C": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_manifest",
|
||||
"inherits": "msvc",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"BUILD_SHARED_LIBS": true,
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"VCPKG_MANIFEST_MODE": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_manifest_static",
|
||||
"inherits": "vcpkg_manifest",
|
||||
"cacheVariables": {
|
||||
"BUILD_SHARED_LIBS": false,
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-static"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_local",
|
||||
"inherits": "msvc",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"BUILD_SHARED_LIBS": true,
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"BUILD_TESTING": true,
|
||||
"VCPKG_MANIFEST_MODE": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release",
|
||||
"inherits": "vcpkg_manifest",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-release",
|
||||
"VCPKG_OVERLAY_TRIPLETS": "x64-windows-release;x64-windows-rel;x64-windows",
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_CPACK": true,
|
||||
"OPENDHT_C": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release_full",
|
||||
"inherits": "vcpkg_release",
|
||||
"cacheVariables": {
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_PROXY_CLIENT": true,
|
||||
"OPENDHT_PROXY_SERVER": true,
|
||||
"OPENDHT_C": true,
|
||||
"OPENDHT_PYTHON": true,
|
||||
"OPENDHT_CPACK": true,
|
||||
"OPENDHT_DOCUMENTATION": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release_static",
|
||||
"inherits": "vcpkg_manifest_static",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-static-release",
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_CPACK": true,
|
||||
"OPENDHT_C": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release_static_full",
|
||||
"inherits": "vcpkg_manifest_static",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-static-release",
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_PROXY_CLIENT": true,
|
||||
"OPENDHT_PROXY_SERVER": true,
|
||||
"OPENDHT_C": true,
|
||||
"OPENDHT_CPACK": true,
|
||||
"OPENDHT_DOCUMENTATION": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release_local",
|
||||
"inherits": "vcpkg_local",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-release",
|
||||
"VCPKG_OVERLAY_TRIPLETS": "x64-windows-release;x64-windows-rel;x64-windows",
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_CPACK": true,
|
||||
"OPENDHT_C": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release_local_full",
|
||||
"inherits": "vcpkg_local",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-release",
|
||||
"VCPKG_OVERLAY_TRIPLETS": "x64-windows-release;x64-windows-rel;x64-windows",
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_PROXY_CLIENT": true,
|
||||
"OPENDHT_PROXY_SERVER": true,
|
||||
"OPENDHT_CPACK": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release_static_local",
|
||||
"inherits": "vcpkg_local",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"BUILD_SHARED_LIBS": false,
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-static-release",
|
||||
"VCPKG_OVERLAY_TRIPLETS": "x64-windows-static-release;x64-windows-static-rel;x64-windows-static",
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_CPACK": true,
|
||||
"OPENDHT_C": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vcpkg_release_static_local_full",
|
||||
"inherits": "vcpkg_local",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"BUILD_SHARED_LIBS": false,
|
||||
"VCPKG_TARGET_TRIPLET": "x64-windows-static-release",
|
||||
"VCPKG_OVERLAY_TRIPLETS": "x64-windows-static-release;x64-windows-static-rel;x64-windows-static",
|
||||
"BUILD_TESTING": false,
|
||||
"OPENDHT_PROXY_CLIENT": true,
|
||||
"OPENDHT_PROXY_SERVER": true,
|
||||
"OPENDHT_CPACK": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"configurePreset": "default",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "unix-make",
|
||||
"inherits": "default",
|
||||
"configurePreset": "unix-make"
|
||||
},
|
||||
{
|
||||
"name": "ninja",
|
||||
"inherits": "default",
|
||||
"configurePreset": "ninja"
|
||||
},
|
||||
{
|
||||
"name": "msvc",
|
||||
"inherits": "default",
|
||||
"configurePreset": "msvc"
|
||||
},
|
||||
{
|
||||
"name": "vcpkg-dev",
|
||||
"inherits": "default",
|
||||
"configurePreset": "vcpkg_manifest"
|
||||
},
|
||||
{
|
||||
"name": "vcpkg-release-static",
|
||||
"inherits": "default",
|
||||
"configurePreset": "vcpkg_release_static_full",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "vcpkg-release",
|
||||
"inherits": "default",
|
||||
"configurePreset": "vcpkg_release_full",
|
||||
"configuration": "Release"
|
||||
}
|
||||
]
|
||||
}
|
||||
-674
@@ -1,674 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -4,8 +4,6 @@
|
||||
<a id="user-content-opendht-" class="anchor" href="/savoirfairelinux/opendht/blob/master/README.md#opendht-" aria-hidden="true"></a>OpenDHT
|
||||
</h1>
|
||||
|
||||

|
||||
|
||||
A lightweight C++17 Distributed Hash Table implementation.
|
||||
|
||||
OpenDHT provides an easy to use distributed in-memory data store.
|
||||
@@ -25,12 +23,12 @@ See the wiki: <https://github.com/savoirfairelinux/opendht/wiki>
|
||||
|
||||
#### How to run a node
|
||||
|
||||
You can help contribute to the public network by running a stable node with a public IP address.
|
||||
You can help contributing to the public network by running a stable node with a public IP address.
|
||||
https://github.com/savoirfairelinux/opendht/wiki/Running-a-node-with-dhtnode
|
||||
|
||||
#### How-to build and install
|
||||
|
||||
Build instructions: see [BUILD.md](BUILD.md)
|
||||
Build instructions: <https://github.com/savoirfairelinux/opendht/wiki/Build-the-library>
|
||||
|
||||
## Examples
|
||||
### C++ example
|
||||
@@ -75,22 +73,14 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Python 3 example
|
||||
|
||||
Install on Linux, macOS and Windows with:
|
||||
```sh
|
||||
pip install opendht
|
||||
```
|
||||
|
||||
Using the simple, blocking API:
|
||||
```python
|
||||
import opendht as dht
|
||||
|
||||
node = dht.DhtRunner()
|
||||
node.run()
|
||||
|
||||
# Join the DHT network through any running node,
|
||||
# Join the network through any running node,
|
||||
# here using a known bootstrap node.
|
||||
node.bootstrap("bootstrap.jami.net", "4222")
|
||||
|
||||
@@ -98,45 +88,8 @@ node.bootstrap("bootstrap.jami.net", "4222")
|
||||
node.put(dht.InfoHash.get("unique_key"), dht.Value(b'some binary data'))
|
||||
|
||||
results = node.get(dht.InfoHash.get("unique_key"))
|
||||
for value in results:
|
||||
print(value)
|
||||
```
|
||||
|
||||
Or using asyncio:
|
||||
```python
|
||||
import asyncio
|
||||
import opendht.aio as dht
|
||||
|
||||
async def dht_async_demo(key_str: str):
|
||||
# Start a new node using an async context manager.
|
||||
# It is also possible to call run()/await shutdown() manually.
|
||||
async with dht.DhtRunner(
|
||||
bootstrap=(("bootstrap.jami.net", "4222"),)
|
||||
) as node:
|
||||
# compute key hash
|
||||
key = dht.InfoHash.get(key_str)
|
||||
|
||||
# put data, waiting for completion
|
||||
await node.put(key, dht.Value(b'tata data'))
|
||||
|
||||
# get all values at key
|
||||
results = await node.getAll(key)
|
||||
for value in results:
|
||||
print(value)
|
||||
|
||||
# same operation, but stream values as they come from the network
|
||||
with node.get(key) as results:
|
||||
async for value in results:
|
||||
print(value)
|
||||
|
||||
# listen for change of values at key
|
||||
with node.listen(key) as values:
|
||||
async for value, expired in values:
|
||||
print(value)
|
||||
if value.data == b'tata data':
|
||||
break
|
||||
|
||||
asyncio.run(dht_async_demo("unique_key"))
|
||||
for r in results:
|
||||
print(r)
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
@@ -147,7 +100,7 @@ asyncio.run(dht_async_demo("unique_key"))
|
||||
- (optional) restinio used for the REST API.
|
||||
- (optional) llhttp used for the REST API.
|
||||
- (optional) jsoncpp 1.7.4-3+, used for the REST API.
|
||||
- Build tested with GCC 9+ (GNU/Linux, Windows with MinGW), Clang/LLVM (GNU/Linux, Android, macOS, iOS).
|
||||
- Build tested with GCC 7+ (GNU/Linux, Windows with MinGW), Clang/LLVM (GNU/Linux, Android, macOS, iOS).
|
||||
- Build tested with Microsoft Visual Studio 2019, 2022
|
||||
|
||||
## Contact
|
||||
@@ -155,7 +108,7 @@ asyncio.run(dht_async_demo("unique_key"))
|
||||
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.
|
||||
|
||||
@@ -165,3 +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 project called OpenDHT (Sean Rhea. Ph.D. Thesis, 2005), now extinct.
|
||||
+16
-33
@@ -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) {
|
||||
@@ -268,11 +264,6 @@ dht_publickey* dht_certificate_get_publickey(const dht_certificate* c) {
|
||||
return reinterpret_cast<dht_publickey*>(new PubkeySp(cert->getSharedPublicKey()));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
// Function with internal C++ linkage
|
||||
#endif
|
||||
|
||||
// dht::crypto::Identity
|
||||
inline dht::crypto::Identity dht_identity_from_c(const dht_identity* cid) {
|
||||
dht::crypto::Identity id {};
|
||||
@@ -290,10 +281,6 @@ inline dht_identity dht_identity_to_c(const dht::crypto::Identity& id) {
|
||||
return cid;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
OPENDHT_C_PUBLIC dht_identity dht_identity_generate(const char* common_name, const dht_identity* ca) {
|
||||
return dht_identity_to_c(dht::crypto::generateIdentity(common_name, dht_identity_from_c(ca)));
|
||||
}
|
||||
@@ -311,7 +298,7 @@ OPENDHT_C_PUBLIC void dht_identity_delete(dht_identity* id) {
|
||||
|
||||
// config
|
||||
void dht_runner_config_default(dht_runner_config* config) {
|
||||
memset(config, 0, sizeof(dht_runner_config));
|
||||
bzero(config, sizeof(dht_runner_config));
|
||||
config->threaded = true;
|
||||
}
|
||||
|
||||
@@ -338,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);
|
||||
@@ -352,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) {
|
||||
|
||||
+7
-17
@@ -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
|
||||
@@ -23,21 +23,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <opendht/def.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
typedef uint16_t sa_family_t;
|
||||
typedef uint16_t in_port_t;
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
// Non-owning data view
|
||||
struct OPENDHT_C_PUBLIC dht_data_view {
|
||||
const uint8_t* data;
|
||||
@@ -100,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;
|
||||
};
|
||||
@@ -113,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*);
|
||||
@@ -135,7 +125,7 @@ typedef struct dht_op_token dht_op_token;
|
||||
OPENDHT_C_PUBLIC void dht_op_token_delete(dht_op_token* token);
|
||||
|
||||
// config
|
||||
struct OPENDHT_C_PUBLIC dht_node_config {
|
||||
struct OPENDHT_PUBLIC dht_node_config {
|
||||
dht_infohash node_id;
|
||||
uint32_t network;
|
||||
bool is_bootstrap;
|
||||
@@ -144,13 +134,13 @@ struct OPENDHT_C_PUBLIC dht_node_config {
|
||||
};
|
||||
typedef struct dht_node_config dht_node_config;
|
||||
|
||||
struct OPENDHT_C_PUBLIC dht_secure_config {
|
||||
struct OPENDHT_PUBLIC dht_secure_config {
|
||||
dht_node_config node_config;
|
||||
dht_identity id;
|
||||
};
|
||||
typedef struct dht_secure_config dht_secure_config;
|
||||
|
||||
struct OPENDHT_C_PUBLIC dht_runner_config {
|
||||
struct OPENDHT_PUBLIC dht_runner_config {
|
||||
dht_secure_config dht_config;
|
||||
bool threaded;
|
||||
const char* proxy_server;
|
||||
|
||||
+9
-32
@@ -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 unable to 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 unable to 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.
|
||||
@@ -123,4 +100,4 @@ int main() {
|
||||
|
||||
if( NOT LLVM_HAS_ATOMICS )
|
||||
message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,21 +0,0 @@
|
||||
# Windows utility functions and macros
|
||||
|
||||
# Determine Windows NT version for compatibility
|
||||
# https://stackoverflow.com/a/40217291/9560245
|
||||
macro(get_WIN32_WINNT version)
|
||||
if(CMAKE_SYSTEM_VERSION)
|
||||
set(ver ${CMAKE_SYSTEM_VERSION})
|
||||
string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
|
||||
string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
|
||||
# Check for Windows 10, b/c we'll need to convert to hex 'A'.
|
||||
if("${verMajor}" MATCHES "10")
|
||||
set(verMajor "A")
|
||||
string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
|
||||
endif()
|
||||
# Remove all remaining '.' characters.
|
||||
string(REPLACE "." "" ver ${ver})
|
||||
# Prepend each digit with a zero.
|
||||
string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
|
||||
set(${version} "0x${ver}")
|
||||
endif()
|
||||
endmacro()
|
||||
+22
-37
@@ -1,12 +1,11 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 3)
|
||||
m4_define([opendht_minor_version], 6)
|
||||
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])
|
||||
|
||||
AC_INIT(opendht, [opendht_version])
|
||||
AC_MSG_WARN([The Autotools build system for OpenDHT is deprecated and will be removed in a future release. Please use CMake or Meson instead.])
|
||||
AC_CONFIG_AUX_DIR(ac)
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -57,25 +56,21 @@ dnl Check for Doxygen
|
||||
AC_ARG_ENABLE([doc], AS_HELP_STRING([--enable-doc], [Enable documentation generation (doxygen)]))
|
||||
AS_IF([test "x$enable_doc" = "xyes"], [
|
||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||
AS_IF([test -z "$DOXYGEN"],
|
||||
[AC_MSG_ERROR([Doxygen is required to generate the documentation.])])
|
||||
AS_IF([test -z "$DOXYGEN"], [AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
|
||||
|
||||
dnl Check for Python
|
||||
AC_ARG_ENABLE([python], [AS_HELP_STRING([--disable-python], [Disable python binding])])
|
||||
AS_IF([test "x$enable_python" = "xyes"], [
|
||||
AM_COND_IF([ENABLE_INDEXATION], [
|
||||
AM_PATH_PYTHON([3.3],, [:])
|
||||
AS_IF([test -n "$PYTHON"],[
|
||||
echo 'import Cython' | $PYTHON
|
||||
AS_IF([test $? == 0],
|
||||
[CYTHON=yes],
|
||||
[AC_MSG_ERROR([Cython not found, but required for Python support.])])
|
||||
AC_CHECK_PROGS([PIP], [pip3])
|
||||
AS_IF([test -z "$PIP"],
|
||||
[AC_MSG_WARN([pip not found - continuing without python uninstall support])])])
|
||||
], [AC_MSG_ERROR([Python support requires DHT indexation to be turned on.])])])
|
||||
AC_ARG_ENABLE([python], [AS_HELP_STRING([--disable-python], [Disble python binding])])
|
||||
AS_IF([test "x$enable_python" != "xno"], [
|
||||
AM_PATH_PYTHON([3.3],, [:])
|
||||
AS_IF([test -n "$PYTHON"],[
|
||||
echo 'import Cython' | $PYTHON
|
||||
AS_IF([test $? == 0],[CYTHON=yes],[AC_MSG_WARN([Cython not found - continuing without python support])])
|
||||
AC_CHECK_PROGS([PIP], [pip3])
|
||||
AS_IF([test -z "$PIP"],[AC_MSG_WARN([pip not found - continuing without python uninstall support])])
|
||||
])
|
||||
])
|
||||
AM_CONDITIONAL([USE_CYTHON], [test -n "$CYTHON"])
|
||||
AM_CONDITIONAL([HAVE_PIP], [test -n "$PIP"])
|
||||
|
||||
@@ -88,7 +83,6 @@ case "${host_os}" in
|
||||
;;
|
||||
linux*)
|
||||
SYS=linux
|
||||
CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200809L"
|
||||
;;
|
||||
darwin*)
|
||||
SYS=darwin
|
||||
@@ -142,27 +136,25 @@ AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes || test x$pro
|
||||
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
|
||||
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
|
||||
AC_CHECK_HEADERS([msgpack.hpp], [], [
|
||||
PKG_CHECK_MODULES([MsgPack], [msgpack-cxx >= 1.2])
|
||||
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
|
||||
])
|
||||
PKG_CHECK_MODULES([Argon2], [libargon2])
|
||||
AC_SUBST(argon2_lib, [", libargon2"])
|
||||
|
||||
AC_ARG_WITH([jsoncpp], AS_HELP_STRING([--without-jsoncpp], [Build without JsonCpp support]))
|
||||
AS_IF([test "x$with_jsoncpp" != "xno"],
|
||||
[PKG_CHECK_MODULES([JsonCpp], [jsoncpp >= 1.7.2], [have_jsoncpp=yes], [have_jsoncpp=no])
|
||||
PKG_CHECK_MODULES([simdutf], [simdutf >= 6], [have_simdutf=yes], [have_simdutf=no])],
|
||||
[PKG_CHECK_MODULES([JsonCpp], [jsoncpp >= 1.7.2], [have_jsoncpp=yes], [have_jsoncpp=no])],
|
||||
[have_jsoncpp=no])
|
||||
AS_IF([test "x$have_jsoncpp" = "xyes"], [
|
||||
AC_MSG_NOTICE([Using JsonCpp])
|
||||
CPPFLAGS="${CPPFLAGS} -DOPENDHT_JSONCPP"
|
||||
AC_SUBST(jsoncpp_lib, [", jsoncpp"])
|
||||
AC_SUBST(simdutf_lib, [", simdutf"])
|
||||
], [
|
||||
AC_MSG_NOTICE([Not using JsonCpp])
|
||||
AM_COND_IF(PROXY_CLIENT_OR_SERVER, AC_MSG_ERROR(["JsonCpp is required for proxy/push notification support"]))
|
||||
])
|
||||
|
||||
AC_ARG_WITH([openssl], AS_HELP_STRING([--without-openssl], [Build without OpenSSL support]))
|
||||
AC_ARG_WITH([openssl], AS_HELP_STRING([--without-openssl], [Build with OpenSSL support]))
|
||||
AS_IF([test "x$with_openssl" != "xno"],
|
||||
[PKG_CHECK_MODULES([OpenSSL], [openssl >= 1.1], [have_openssl=yes], [have_openssl=no])],
|
||||
[have_openssl=no])
|
||||
@@ -183,26 +175,20 @@ AS_IF([test "x$have_fmt" = "xyes"], [
|
||||
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
|
||||
AC_CHECK_HEADERS([asio.hpp],, AC_MSG_ERROR([Missing Asio headers files]))
|
||||
CXXFLAGS="${CXXFLAGS} -DASIO_STANDALONE"
|
||||
PKG_CHECK_MODULES([Llhttp], [libllhttp])
|
||||
llhttp_lib=", libllhttp"
|
||||
# llhttp has no pkgconfig, instead we check with:
|
||||
AC_CHECK_LIB(llhttp, exit,, AC_MSG_ERROR([Missing llhttp library files]))
|
||||
AC_CHECK_HEADERS([llhttp.h], [llhttp_headers=yes; break;])
|
||||
AC_SUBST(http_lib, ["-lllhttp"])
|
||||
AS_IF([test "x$llhttp_headers" != "xyes"], AC_MSG_ERROR([Missing llhttp headers files]))
|
||||
])
|
||||
AC_SUBST(llhttp_lib)
|
||||
|
||||
AC_ARG_WITH([liburing], AS_HELP_STRING([--with-liburing], [Build with io_uring support(Linux only)]),[], [with_liburing=no])
|
||||
AS_IF([test "x$with_liburing" != "xno"], [
|
||||
CXX_FLAGS="${CXXFLAGS} -DASIO_HAS_IO_URING -DASIO_DISABLE_EPOLL"
|
||||
PKG_CHECK_MODULES([Liburing], [liburing])
|
||||
iouring_lib=", liburing"
|
||||
])
|
||||
AC_SUBST(iouring_lib)
|
||||
|
||||
CXXFLAGS="${CXXFLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
|
||||
|
||||
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
|
||||
AM_CONDITIONAL(ENABLE_TOOLS, test x$build_tools == xyes)
|
||||
AM_COND_IF([ENABLE_TOOLS], [
|
||||
AC_CHECK_HEADERS([readline/readline.h readline/history.h], [],
|
||||
[AC_MSG_ERROR([Unable to find readline.h. Readline is required for the tools.])
|
||||
AC_CHECK_HEADERS([readline/readline.h readline/history.h], [], [
|
||||
AC_MSG_ERROR([unable to find readline.h])
|
||||
])
|
||||
])
|
||||
|
||||
@@ -227,5 +213,4 @@ AC_CONFIG_FILES([Makefile
|
||||
doc/Makefile
|
||||
doc/Doxyfile
|
||||
opendht.pc])
|
||||
AC_MSG_WARN([The Autotools build system for OpenDHT is deprecated and will be removed in a future release. Please use CMake or Meson instead.])
|
||||
AC_OUTPUT
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
if (OPENDHT_TOOLS)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dhtnode.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dhtnode.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_DOCUMENTATION)
|
||||
@@ -12,5 +12,5 @@ if (OPENDHT_DOCUMENTATION)
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
VERBATIM)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${CMAKE_INSTALL_DOCDIR}/opendht)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc/opendht)
|
||||
endif()
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps:latest
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
COPY . opendht
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-alpine:latest AS build
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
COPY . opendht
|
||||
|
||||
RUN mkdir /install
|
||||
ENV DESTDIR=/install
|
||||
ENV DESTDIR /install
|
||||
|
||||
RUN cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
@@ -19,7 +19,7 @@ RUN cd opendht && mkdir build && cd build \
|
||||
-DOPENDHT_SYSTEMD=On \
|
||||
&& make -j8 && make install
|
||||
|
||||
FROM alpine:3.22 AS install
|
||||
FROM alpine:3.19 AS install
|
||||
COPY --from=build /install /
|
||||
RUN apk add --no-cache \
|
||||
libstdc++ \
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
FROM opendht-alpine-edge-deps:latest AS build
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
|
||||
COPY . opendht
|
||||
|
||||
RUN mkdir /install
|
||||
ENV DESTDIR=/install
|
||||
|
||||
RUN cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DOPENDHT_DOWNLOAD_DEPS=Off \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
-DOPENDHT_PEER_DISCOVERY=On \
|
||||
-DOPENDHT_PYTHON=On \
|
||||
-DOPENDHT_TOOLS=On \
|
||||
-DOPENDHT_PROXY_SERVER=On \
|
||||
-DOPENDHT_PROXY_CLIENT=On \
|
||||
-DOPENDHT_SYSTEMD=On \
|
||||
&& make -j8 && make install
|
||||
|
||||
FROM alpine:edge AS install
|
||||
COPY --from=build /install /
|
||||
RUN apk add --no-cache \
|
||||
libstdc++ \
|
||||
gnutls \
|
||||
nettle \
|
||||
openssl \
|
||||
argon2-dev \
|
||||
jsoncpp \
|
||||
llhttp \
|
||||
fmt \
|
||||
readline \
|
||||
ncurses \
|
||||
gdb
|
||||
#CMD ["dhtnode", "-b", "bootstrap.jami.net", "-p", "4222", "--proxyserver", "8080"]
|
||||
EXPOSE 4222/udp
|
||||
EXPOSE 8080/tcp
|
||||
CMD ["/bin/sh"]
|
||||
@@ -0,0 +1,17 @@
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-bionic:latest
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
COPY . opendht
|
||||
|
||||
RUN cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
-DOPENDHT_PEER_DISCOVERY=On \
|
||||
-DOPENDHT_PYTHON=On \
|
||||
-DOPENDHT_TOOLS=On \
|
||||
-DOPENDHT_PROXY_SERVER=On \
|
||||
-DOPENDHT_PROXY_CLIENT=On \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
dialog apt-utils \
|
||||
@@ -8,23 +8,25 @@ 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 \
|
||||
build-essential pkg-config cmake git wget meson \
|
||||
build-essential pkg-config cmake git wget \
|
||||
libtool autotools-dev autoconf \
|
||||
python3-dev python3-setuptools python3-build python3-virtualenv cython3 \
|
||||
python3-pip python3-dev python3-setuptools python3-build python3-virtualenv \
|
||||
libncurses5-dev libreadline-dev nettle-dev libcppunit-dev \
|
||||
libgnutls28-dev libuv1-dev libjsoncpp-dev libargon2-dev \
|
||||
libssl-dev libfmt-dev libasio-dev libmsgpack-dev \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
||||
|
||||
RUN pip3 install meson Cython
|
||||
|
||||
RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
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,6 +1,6 @@
|
||||
FROM alpine:3.22
|
||||
FROM alpine:3.19
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apk add --no-cache \
|
||||
build-base cmake ninja git wget \
|
||||
@@ -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 . \
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
FROM alpine:edge
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apk add --no-cache \
|
||||
build-base cmake ninja git wget \
|
||||
cython python3-dev py3-setuptools \
|
||||
ncurses-dev readline-dev nettle-dev \
|
||||
cppunit-dev gnutls-dev jsoncpp-dev \
|
||||
argon2-dev openssl-dev fmt-dev \
|
||||
llhttp-dev asio-dev msgpack-cxx-dev \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
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 \
|
||||
&& 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 . \
|
||||
&& make -j2 && make install \
|
||||
&& cd ../../ && rm -rf restinio*
|
||||
@@ -0,0 +1,36 @@
|
||||
FROM ubuntu:18.04
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
|
||||
RUN apt-get update && apt-get install -y \
|
||||
apt-transport-https build-essential pkg-config git wget libncurses5-dev libreadline-dev nettle-dev \
|
||||
libgnutls28-dev libuv1-dev python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
|
||||
libargon2-0-dev \
|
||||
autotools-dev autoconf libfmt-dev libmsgpack-dev libssl-dev python3-pip \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
||||
|
||||
RUN pip3 install --upgrade cmake meson Cython
|
||||
|
||||
# libasio-dev (1.10) is too old
|
||||
RUN echo "** Building a recent version of asio ***" \
|
||||
&& wget https://github.com/aberaud/asio/archive/a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz \
|
||||
&& tar -xvf a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz && cd asio-a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571/asio \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
|
||||
&& make install \
|
||||
&& cd ../../ && rm -rf asio*
|
||||
|
||||
RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& 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 -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 && make install \
|
||||
&& cd ../../ && rm -rf restinio*
|
||||
@@ -1,6 +1,6 @@
|
||||
FROM ubuntu:20.04
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
dialog apt-utils \
|
||||
@@ -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 . \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
dialog apt-utils \
|
||||
@@ -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,10 +17,10 @@ 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++
|
||||
ENV CC cc
|
||||
ENV CXX c++
|
||||
|
||||
RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
@@ -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,6 +1,6 @@
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-focal:latest
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-bionic:latest
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
COPY . opendht
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-llvm:latest
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
COPY . opendht
|
||||
|
||||
|
||||
+1
-1
@@ -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,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>;
|
||||
@@ -189,9 +175,7 @@ using ShutdownCallback = std::function<void()>;
|
||||
using IdentityAnnouncedCb = std::function<void(bool)>;
|
||||
using PublicAddressChangedCb = std::function<void(std::vector<SockAddr>)>;
|
||||
|
||||
using CertificateStoreQueryLegacy = std::function<std::vector<std::shared_ptr<crypto::Certificate>>(const InfoHash& pk_id)>;
|
||||
using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::Certificate>>(const PkId& pk_id)>;
|
||||
|
||||
using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::Certificate>>(const InfoHash& pk_id)>;
|
||||
using DoneCallback = std::function<void(bool success, const std::vector<std::shared_ptr<Node>>& nodes)>;
|
||||
using DoneCallbackSimple = std::function<void(bool success)>;
|
||||
|
||||
|
||||
@@ -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>
|
||||
*
|
||||
@@ -204,9 +204,8 @@ struct OPENDHT_PUBLIC PrivateKey
|
||||
* @param key_length : size of the modulus in bits
|
||||
* Minimim value: 2048
|
||||
* Recommended values: 4096, 8192
|
||||
* @param algo : the public key algorithm to use, GNUTLS_PK_RSA or GNUTLS_PK_RSA_OAEP
|
||||
*/
|
||||
static PrivateKey generate(unsigned key_length = 4096, gnutls_pk_algorithm_t algo = GNUTLS_PK_RSA);
|
||||
static PrivateKey generate(unsigned key_length = 4096);
|
||||
static PrivateKey generateEC();
|
||||
|
||||
gnutls_privkey_t key {};
|
||||
@@ -513,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;
|
||||
|
||||
@@ -656,7 +649,7 @@ struct OPENDHT_PUBLIC TrustList
|
||||
bool hasError() const { return ret < 0; }
|
||||
bool isValid() const { return !hasError() and !(result & GNUTLS_CERT_INVALID); }
|
||||
explicit operator bool() const { return isValid(); }
|
||||
OPENDHT_PUBLIC std::string toString() const;
|
||||
std::string toString() const;
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const VerifyResult& h);
|
||||
};
|
||||
|
||||
@@ -755,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,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,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
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SignedValue : public Value::Serializable<T>
|
||||
class OPENDHT_PUBLIC SignedValue : public Value::Serializable<T>
|
||||
{
|
||||
private:
|
||||
using BaseClass = Value::Serializable<T>;
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class EncryptedValue : public SignedValue<T>
|
||||
class OPENDHT_PUBLIC EncryptedValue : public SignedValue<T>
|
||||
{
|
||||
public:
|
||||
using BaseClass = SignedValue<T>;
|
||||
@@ -127,10 +127,6 @@ public:
|
||||
SignedValue::unpackValue(v);
|
||||
}
|
||||
|
||||
static Value::Filter getFilter() {
|
||||
return SignedValue::getFilter();
|
||||
}
|
||||
|
||||
dht::InfoHash to;
|
||||
dht::Value::Id id {0};
|
||||
std::string msg;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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_ {};
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct OPENDHT_PUBLIC ServerStats {
|
||||
struct ServerStats {
|
||||
/** Current number of listen operations */
|
||||
size_t listenCount {0};
|
||||
/** Current number of permanent put operations (hash used) */
|
||||
@@ -149,12 +149,44 @@ public:
|
||||
/** Node Info **/
|
||||
std::shared_ptr<NodeInfo> nodeInfo {};
|
||||
|
||||
std::string toString() const;
|
||||
std::string toString() const {
|
||||
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)
|
||||
ss << "IPv4 Network estimation: " << ipv4.getNetworkSizeEstimation() << std::endl;;
|
||||
auto& ipv6 = nodeInfo->ipv6;
|
||||
if (ipv6.table_depth > 1)
|
||||
ss << "IPv6 Network estimation: " << ipv6.getNetworkSizeEstimation() << std::endl;;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a json object from a NodeStats
|
||||
*/
|
||||
Json::Value toJson() const;
|
||||
Json::Value toJson() const {
|
||||
Json::Value result;
|
||||
result["listenCount"] = static_cast<Json::UInt64>(listenCount);
|
||||
result["putCount"] = static_cast<Json::UInt64>(putCount);
|
||||
result["totalPermanentPuts"] = static_cast<Json::UInt64>(totalPermanentPuts);
|
||||
result["pushListenersCount"] = static_cast<Json::UInt64>(pushListenersCount);
|
||||
result["serverStartTime"] = static_cast<Json::LargestInt>(to_time_t(serverStartTime));
|
||||
result["lastUpdated"] = static_cast<Json::LargestInt>(to_time_t(lastUpdated));
|
||||
result["androidPush"] = androidPush.toJson();
|
||||
result["iosPush"] = iosPush.toJson();
|
||||
result["unifiedPush"] = unifiedPush.toJson();
|
||||
result["requestRate"] = requestRate;
|
||||
if (nodeInfo)
|
||||
result["nodeInfo"] = nodeInfo->toJson();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<ServerStats> stats() const { return stats_; }
|
||||
|
||||
@@ -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>
|
||||
@@ -77,8 +77,7 @@ public:
|
||||
std::unique_ptr<net::DatagramSocket> sock;
|
||||
std::shared_ptr<PeerDiscovery> peerDiscovery {};
|
||||
StatusCallback statusChangedCallback {};
|
||||
CertificateStoreQueryLegacy certificateStore {};
|
||||
CertificateStoreQuery certificateStorePkId {};
|
||||
CertificateStoreQuery certificateStore {};
|
||||
IdentityAnnouncedCb identityAnnouncedCb {};
|
||||
PublicAddressChangedCb publicAddressChangedCb {};
|
||||
std::unique_ptr<std::mt19937_64> rng {};
|
||||
@@ -269,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.
|
||||
@@ -326,7 +319,7 @@ public:
|
||||
/**
|
||||
* Get the public key fingerprint if an identity is used with this node, 0 otherwise.
|
||||
*/
|
||||
[[deprecated("Use getPublicKey()->getLongId() instead")]] InfoHash getId() const;
|
||||
InfoHash getId() const;
|
||||
std::shared_ptr<crypto::PublicKey> getPublicKey() const;
|
||||
|
||||
/**
|
||||
@@ -391,10 +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 setLocalCertificateStore(CertificateStoreQueryLegacy&& query_method);
|
||||
void registerCertificate(std::shared_ptr<crypto::Certificate> cert);
|
||||
void setLocalCertificateStore(CertificateStoreQuery&& query_method);
|
||||
|
||||
/**
|
||||
@@ -440,11 +430,9 @@ public:
|
||||
void shutdown(ShutdownCallback cb = {}, bool stop = false);
|
||||
|
||||
/**
|
||||
* Stop the node and wait for all threads to terminate.
|
||||
* The node is reset to its default state. The DHT can then be run again with @run().
|
||||
* No DHT callbacks will run after this method returns.
|
||||
* Calling this method is optional. It allows to ensure the destructor won't block.
|
||||
* This method is unable to be called from a DHT callback.
|
||||
* Quit and wait for all threads to terminate.
|
||||
* No callbacks will be called after this method returns.
|
||||
* All internal state will be lost. The DHT can then be run again with @run().
|
||||
*/
|
||||
void join();
|
||||
|
||||
@@ -478,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
@@ -266,7 +266,7 @@ private:
|
||||
|
||||
using Value = std::pair<InfoHash, dht::Value::Id>;
|
||||
struct OPENDHT_PUBLIC IndexEntry : public dht::Value::Serializable<IndexEntry> {
|
||||
static const ValueType& TYPE;
|
||||
static const ValueType TYPE;
|
||||
|
||||
virtual void unpackValue(const dht::Value& v) {
|
||||
Serializable<IndexEntry>::unpackValue(v);
|
||||
@@ -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_;
|
||||
|
||||
+10
-11
@@ -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
|
||||
@@ -63,7 +63,7 @@ namespace crypto {
|
||||
* Hashes identify nodes and values in the Dht.
|
||||
*/
|
||||
template <size_t N>
|
||||
class Hash {
|
||||
class OPENDHT_PUBLIC Hash {
|
||||
public:
|
||||
using T = std::array<uint8_t, N>;
|
||||
typedef typename T::iterator iterator;
|
||||
@@ -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;
|
||||
@@ -251,10 +251,10 @@ public:
|
||||
static Hash getRandom(Rd&);
|
||||
|
||||
template <size_t M>
|
||||
friend std::ostream& operator<< (std::ostream& s, const Hash<M>& h);
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Hash<M>& h);
|
||||
|
||||
template <size_t M>
|
||||
friend std::istream& operator>> (std::istream& s, Hash<M>& h);
|
||||
OPENDHT_PUBLIC friend std::istream& operator>> (std::istream& s, Hash<M>& h);
|
||||
|
||||
/** Returns view to thread-allocated memory, only valid until the next call to this function. */
|
||||
std::string_view to_view() const { return std::string_view(to_c_str(), N*2); }
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
inline 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,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>
|
||||
*
|
||||
|
||||
+42
-60
@@ -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
|
||||
@@ -30,107 +30,89 @@
|
||||
namespace dht {
|
||||
namespace log {
|
||||
|
||||
enum class LogLevel { debug, warning, error };
|
||||
enum class LogLevel {
|
||||
debug, warning, error
|
||||
};
|
||||
|
||||
using LogMethod = std::function<void(LogLevel, std::string&&)>;
|
||||
|
||||
struct OPENDHT_PUBLIC Logger
|
||||
{
|
||||
struct OPENDHT_PUBLIC Logger {
|
||||
Logger() = delete;
|
||||
Logger(LogMethod&& l)
|
||||
: logger(std::move(l))
|
||||
{
|
||||
if (!logger)
|
||||
throw std::invalid_argument {"logger and loggerf must be set"};
|
||||
}
|
||||
void setFilter(const InfoHash& f)
|
||||
{
|
||||
: logger(std::move(l)) {
|
||||
if (!logger)
|
||||
throw std::invalid_argument{"logger and loggerf must be set"};
|
||||
}
|
||||
void setFilter(const InfoHash& f) {
|
||||
filter_ = f;
|
||||
filterEnable_ = static_cast<bool>(filter_);
|
||||
}
|
||||
inline void log0(LogLevel level, fmt::string_view format, fmt::printf_args args) const
|
||||
{
|
||||
inline void log0(LogLevel level, fmt::string_view format, fmt::printf_args args) const {
|
||||
if (not filterEnable_)
|
||||
logger(level, fmt::vsprintf(format, args));
|
||||
}
|
||||
inline void log1(LogLevel level, const InfoHash& f, fmt::string_view format, fmt::printf_args args) const
|
||||
{
|
||||
inline void log1(LogLevel level, const InfoHash& f, fmt::string_view format, fmt::printf_args args) const {
|
||||
if (not filterEnable_ or f == filter_)
|
||||
logger(level, fmt::vsprintf(format, args));
|
||||
}
|
||||
inline void log2(
|
||||
LogLevel level, const InfoHash& f1, const InfoHash& f2, fmt::string_view format, fmt::printf_args args) const
|
||||
{
|
||||
inline void log2(LogLevel level, const InfoHash& f1, const InfoHash& f2, fmt::string_view format, fmt::printf_args args) const {
|
||||
if (not filterEnable_ or f1 == filter_ or f2 == filter_)
|
||||
logger(level, fmt::vsprintf(format, args));
|
||||
}
|
||||
template<typename... Args>
|
||||
inline void debug(fmt::format_string<Args...> format, Args&&... args) const
|
||||
{
|
||||
logger(LogLevel::debug, fmt::format(format, std::forward<Args>(args)...));
|
||||
template<typename S, typename... Args>
|
||||
inline void debug(S&& format, Args&&... args) const {
|
||||
logger(LogLevel::debug, fmt::format(format, args...));
|
||||
}
|
||||
template<typename... Args>
|
||||
inline void warn(fmt::format_string<Args...> format, Args&&... args) const
|
||||
{
|
||||
logger(LogLevel::warning, fmt::format(format, std::forward<Args>(args)...));
|
||||
template<typename S, typename... Args>
|
||||
inline void warn(S&& format, Args&&... args) const {
|
||||
logger(LogLevel::warning, fmt::format(format, args...));
|
||||
}
|
||||
template<typename... Args>
|
||||
inline void error(fmt::format_string<Args...> format, Args&&... args) const
|
||||
{
|
||||
logger(LogLevel::error, fmt::format(format, std::forward<Args>(args)...));
|
||||
template<typename S, typename... Args>
|
||||
inline void error(S&& format, Args&&... args) const {
|
||||
logger(LogLevel::error, fmt::format(format, args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void d(fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void d(fmt::format_string<T...> format, T&&... args) const {
|
||||
log0(LogLevel::debug, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void d(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void d(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const {
|
||||
log1(LogLevel::debug, f, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void d(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void d(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const {
|
||||
log2(LogLevel::debug, f1, f2, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void w(fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void w(fmt::format_string<T...> format, T&&... args) const {
|
||||
log0(LogLevel::warning, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void w(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void w(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const {
|
||||
log1(LogLevel::warning, f, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void w(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void w(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const {
|
||||
log2(LogLevel::warning, f1, f2, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void e(fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void e(fmt::format_string<T...> format, T&&... args) const {
|
||||
log0(LogLevel::error, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void e(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void e(const InfoHash& f, fmt::format_string<T...> format, T&&... args) const {
|
||||
log1(LogLevel::error, f, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
template<typename... T>
|
||||
inline void e(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const
|
||||
{
|
||||
template <typename... T>
|
||||
inline void e(const InfoHash& f1, const InfoHash& f2, fmt::format_string<T...> format, T&&... args) const {
|
||||
log2(LogLevel::error, f1, f2, format, fmt::make_printf_args(args...));
|
||||
}
|
||||
|
||||
private:
|
||||
LogMethod logger = {};
|
||||
bool filterEnable_ {false};
|
||||
InfoHash filter_ {};
|
||||
};
|
||||
|
||||
} // namespace log
|
||||
}
|
||||
using Logger = log::Logger;
|
||||
} // namespace dht
|
||||
}
|
||||
@@ -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>
|
||||
*
|
||||
@@ -59,18 +59,18 @@ class DhtProtocolException : public DhtException {
|
||||
public:
|
||||
// sent to another peer (http-like).
|
||||
static const constexpr uint16_t NON_AUTHORITATIVE_INFORMATION {203}; /* incomplete request packet. */
|
||||
static const constexpr uint16_t UNAUTHORIZED {401}; /* incorrect tokens. */
|
||||
static const constexpr uint16_t UNAUTHORIZED {401}; /* wrong tokens. */
|
||||
static const constexpr uint16_t NOT_FOUND {404}; /* storage not found */
|
||||
// for internal use (custom).
|
||||
static const constexpr uint16_t INVALID_TID_SIZE {421}; /* id was truncated. */
|
||||
static const constexpr uint16_t UNKNOWN_TID {422}; /* unknown tid */
|
||||
static const constexpr uint16_t WRONG_NODE_INFO_BUF_LEN {423}; /* node info length is incorrect */
|
||||
static const constexpr uint16_t WRONG_NODE_INFO_BUF_LEN {423}; /* node info length is wrong */
|
||||
|
||||
static const std::string GET_NO_INFOHASH; /* received "get" request with no infohash */
|
||||
static const std::string LISTEN_NO_INFOHASH; /* got "listen" request without infohash */
|
||||
static const std::string LISTEN_WRONG_TOKEN; /* incorrect token in "listen" request */
|
||||
static const std::string LISTEN_WRONG_TOKEN; /* wrong token in "listen" request */
|
||||
static const std::string PUT_NO_INFOHASH; /* no infohash in "put" request */
|
||||
static const std::string PUT_WRONG_TOKEN; /* got "put" request with incorrect token */
|
||||
static const std::string PUT_WRONG_TOKEN; /* got "put" request with wrong token */
|
||||
static const std::string STORAGE_NOT_FOUND; /* got access request for an unknown storage */
|
||||
static const std::string PUT_INVALID_ID; /* invalid id in "put" request */
|
||||
|
||||
@@ -345,11 +345,11 @@ public:
|
||||
* @param previous The previous request "listen" sent to this node.
|
||||
* @param socket **UNUSED** The socket for further response.
|
||||
*
|
||||
* For backward compatibility purposes, sendListen has to
|
||||
* handle creation of the socket. Therefore, you are unable to
|
||||
* use openSocket yourself.
|
||||
* TODO: Once we don't support the old "listen" negotiation,
|
||||
* sendListen shall not create the socket itself.
|
||||
* For backward compatibility purpose, sendListen has to
|
||||
* handle creation of the socket. Therefor, you cannot
|
||||
* use openSocket yourself. TODO: Once we don't support
|
||||
* the old "listen" negociation, sendListen shall not
|
||||
* create the socket itself.
|
||||
*
|
||||
* @param on_done Request callback when the request is completed.
|
||||
* @param on_expired Request callback when the request expires.
|
||||
|
||||
@@ -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,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,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,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,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();
|
||||
|
||||
|
||||
@@ -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,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,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,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,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,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>
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
|
||||
/**
|
||||
* "Secure" get(), that will check the signature of signed data, and decrypt encrypted data.
|
||||
* If the signature is unable to be checked, or if the data is unable to be decrypted, it is not returned.
|
||||
* If the signature can't be checked, or if the data can't be decrypted, it is not returned.
|
||||
* Public, non-signed & non-encrypted data is retransmitted as-is.
|
||||
*/
|
||||
void get(const InfoHash& id, GetCallback cb, DoneCallback donecb={}, Value::Filter&& = {}, Where&& w = {}) override;
|
||||
@@ -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,25 +135,17 @@ 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
|
||||
* the same private key.
|
||||
*/
|
||||
void setLocalCertificateStore(CertificateStoreQueryLegacy&& query_method) {
|
||||
localQueryMethodLegacy_ = std::move(query_method);
|
||||
}
|
||||
void setLocalCertificateStore(CertificateStoreQuery&& query_method) {
|
||||
localQueryMethod_ = std::move(query_method);
|
||||
}
|
||||
@@ -342,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 {
|
||||
@@ -374,21 +360,15 @@ 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_ {};
|
||||
|
||||
// method to query the local certificate store
|
||||
CertificateStoreQuery localQueryMethod_ {};
|
||||
CertificateStoreQueryLegacy localQueryMethodLegacy_ {};
|
||||
|
||||
// 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};
|
||||
@@ -407,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,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
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Set address to any
|
||||
* Set Network Interface to any
|
||||
*/
|
||||
void setAny() {
|
||||
auto family = getFamily();
|
||||
@@ -168,21 +168,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set address to loopback.
|
||||
*/
|
||||
void setLoopback() {
|
||||
auto family = getFamily();
|
||||
switch(family) {
|
||||
case AF_INET:
|
||||
getIPv4().sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
break;
|
||||
case AF_INET6:
|
||||
getIPv6().sin6_addr = in6addr_loopback;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive the port (in host byte order) or 0 if the address is not
|
||||
* of a supported family.
|
||||
@@ -309,7 +294,7 @@ public:
|
||||
(uint8_t*)b.get()+start, len) < 0;
|
||||
}
|
||||
};
|
||||
friend std::ostream& operator<< (std::ostream& s, const SockAddr& h) {
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const SockAddr& h) {
|
||||
print_addr(s, h.get(), h.getLength());
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
*
|
||||
|
||||
+57
-72
@@ -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
|
||||
@@ -20,15 +20,12 @@
|
||||
|
||||
#include "def.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <msgpack.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <random>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
@@ -49,38 +46,32 @@ OPENDHT_PUBLIC const char* version();
|
||||
template<class T>
|
||||
using Sp = std::shared_ptr<T>;
|
||||
|
||||
template<typename Key, typename Item, typename Condition>
|
||||
void
|
||||
erase_if(std::map<Key, Item>& map, const Condition& condition)
|
||||
template <typename Key, typename Item, typename Condition>
|
||||
void erase_if(std::map<Key, Item>& map, const Condition& condition)
|
||||
{
|
||||
for (auto it = map.begin(); it != map.end();) {
|
||||
for (auto it = map.begin(); it != map.end(); ) {
|
||||
if (condition(*it)) {
|
||||
it = map.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
} else { ++it; }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split "[host]:port" or "host:port" to pair<"host", "port">.
|
||||
*/
|
||||
OPENDHT_PUBLIC std::pair<std::string, std::string> splitPort(std::string_view s);
|
||||
OPENDHT_PUBLIC std::pair<std::string, std::string>
|
||||
splitPort(const std::string& s);
|
||||
|
||||
class OPENDHT_PUBLIC DhtException : public std::runtime_error
|
||||
{
|
||||
class OPENDHT_PUBLIC DhtException : public std::runtime_error {
|
||||
public:
|
||||
DhtException(const std::string& str = "")
|
||||
: std::runtime_error("DhtException occurred: " + str)
|
||||
{}
|
||||
DhtException(const std::string &str = "") :
|
||||
std::runtime_error("DhtException occurred: " + str) {}
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC SocketException : public DhtException
|
||||
{
|
||||
class OPENDHT_PUBLIC SocketException : public DhtException {
|
||||
public:
|
||||
SocketException(int err)
|
||||
: DhtException(strerror(err))
|
||||
{}
|
||||
SocketException(int err) :
|
||||
DhtException(strerror(err)) {}
|
||||
};
|
||||
|
||||
// Time related definitions and utility functions
|
||||
@@ -93,61 +84,61 @@ using duration = clock::duration;
|
||||
time_point from_time_t(std::time_t t);
|
||||
std::time_t to_time_t(time_point t);
|
||||
|
||||
template<class DT>
|
||||
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)
|
||||
{
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
template<class TimePoint>
|
||||
template <class TimePoint>
|
||||
static std::string
|
||||
print_time_relative(TimePoint now, TimePoint d)
|
||||
{
|
||||
if (d == TimePoint::min())
|
||||
return "never";
|
||||
if (d == now)
|
||||
return "now";
|
||||
return (d > now) ? std::string("in ") + print_duration(d - now) : print_duration(now - d) + std::string(" ago");
|
||||
print_time_relative(TimePoint now, TimePoint d) {
|
||||
if (d == TimePoint::min()) return "never";
|
||||
if (d == now) return "now";
|
||||
return (d > now) ? std::string("in ") + print_duration(d - now)
|
||||
: print_duration(now - d) + std::string(" ago");
|
||||
}
|
||||
|
||||
template<typename Duration = duration>
|
||||
class uniform_duration_distribution : public std::uniform_int_distribution<typename Duration::rep>
|
||||
{
|
||||
template <typename Duration = duration>
|
||||
class uniform_duration_distribution : public std::uniform_int_distribution<typename Duration::rep> {
|
||||
using Base = std::uniform_int_distribution<typename Duration::rep>;
|
||||
using param_type = typename Base::param_type;
|
||||
|
||||
public:
|
||||
uniform_duration_distribution(Duration min, Duration max)
|
||||
: Base(min.count(), max.count())
|
||||
{}
|
||||
template<class Generator>
|
||||
Duration operator()(Generator&& g)
|
||||
{
|
||||
uniform_duration_distribution(Duration min, Duration max) : Base(min.count(), max.count()) {}
|
||||
template <class Generator>
|
||||
Duration operator()(Generator && g) {
|
||||
return Duration(Base::operator()(g));
|
||||
}
|
||||
template<class Generator>
|
||||
Duration operator()(Generator&& g, const param_type& params)
|
||||
{
|
||||
template< class Generator >
|
||||
Duration operator()( Generator && g, const param_type& params ) {
|
||||
return Duration(Base::operator()(g, params));
|
||||
}
|
||||
};
|
||||
@@ -164,21 +155,19 @@ using Blob = std::vector<uint8_t>;
|
||||
*/
|
||||
OPENDHT_PUBLIC Blob unpackBlob(const msgpack::object& o);
|
||||
|
||||
template<typename Type>
|
||||
template <typename Type>
|
||||
Blob
|
||||
packMsg(const Type& t)
|
||||
{
|
||||
packMsg(const Type& t) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack(t);
|
||||
return {buffer.data(), buffer.data() + buffer.size()};
|
||||
return {buffer.data(), buffer.data()+buffer.size()};
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
template <typename Type>
|
||||
Type
|
||||
unpackMsg(Blob b)
|
||||
{
|
||||
msgpack::unpacked msg_res = msgpack::unpack((const char*) b.data(), b.size());
|
||||
unpackMsg(Blob b) {
|
||||
msgpack::unpacked msg_res = msgpack::unpack((const char*)b.data(), b.size());
|
||||
return msg_res.get().as<Type>();
|
||||
}
|
||||
|
||||
@@ -186,14 +175,10 @@ msgpack::unpacked unpackMsg(Blob b);
|
||||
|
||||
msgpack::object* findMapValue(const msgpack::object& map, const char* key, size_t length);
|
||||
|
||||
inline msgpack::object*
|
||||
findMapValue(const msgpack::object& map, const char* key)
|
||||
{
|
||||
inline msgpack::object* findMapValue(const msgpack::object& map, const char* key) {
|
||||
return findMapValue(map, key, strlen(key));
|
||||
}
|
||||
inline msgpack::object*
|
||||
findMapValue(const msgpack::object& map, std::string_view key)
|
||||
{
|
||||
inline msgpack::object* findMapValue(const msgpack::object& map, std::string_view key) {
|
||||
return findMapValue(map, key.data(), key.size());
|
||||
}
|
||||
|
||||
|
||||
+10
-9
@@ -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>
|
||||
*
|
||||
@@ -90,19 +90,18 @@ using StorePolicy = std::function<bool(InfoHash key, std::shared_ptr<Value>& val
|
||||
using EditPolicy = std::function<bool(InfoHash key, const std::shared_ptr<Value>& old_val, std::shared_ptr<Value>& new_val, const InfoHash& from, const SockAddr& addr)>;
|
||||
|
||||
static constexpr const size_t MAX_VALUE_SIZE {1024 * 64};
|
||||
static constexpr const duration DEFAULT_VALUE_EXPIRATION {std::chrono::minutes(10)};
|
||||
|
||||
struct ValueType {
|
||||
struct OPENDHT_PUBLIC ValueType {
|
||||
typedef uint16_t Id;
|
||||
|
||||
OPENDHT_PUBLIC static bool DEFAULT_STORE_POLICY(InfoHash, const std::shared_ptr<Value>& v, const InfoHash&, const SockAddr&);
|
||||
static inline bool DEFAULT_EDIT_POLICY(InfoHash, const std::shared_ptr<Value>&, std::shared_ptr<Value>&, const InfoHash&, const SockAddr&) {
|
||||
static bool DEFAULT_STORE_POLICY(InfoHash, const std::shared_ptr<Value>& v, const InfoHash&, const SockAddr&);
|
||||
static bool DEFAULT_EDIT_POLICY(InfoHash, const std::shared_ptr<Value>&, std::shared_ptr<Value>&, const InfoHash&, const SockAddr&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueType () {}
|
||||
|
||||
ValueType (Id id, std::string name, duration e = DEFAULT_VALUE_EXPIRATION)
|
||||
ValueType (Id id, std::string name, duration e = std::chrono::minutes(10))
|
||||
: id(id), name(name), expiration(e) {}
|
||||
|
||||
ValueType (Id id, std::string name, duration e, StorePolicy sp, EditPolicy ep = DEFAULT_EDIT_POLICY)
|
||||
@@ -115,12 +114,12 @@ struct ValueType {
|
||||
}
|
||||
|
||||
// Generic value type
|
||||
OPENDHT_PUBLIC static const ValueType USER_DATA;
|
||||
static const ValueType USER_DATA;
|
||||
|
||||
|
||||
Id id {0};
|
||||
std::string name {};
|
||||
duration expiration {DEFAULT_VALUE_EXPIRATION};
|
||||
duration expiration {std::chrono::minutes(10)};
|
||||
StorePolicy storePolicy {DEFAULT_STORE_POLICY};
|
||||
EditPolicy editPolicy {DEFAULT_EDIT_POLICY};
|
||||
};
|
||||
@@ -138,6 +137,8 @@ private:
|
||||
std::map<ValueType::Id, ValueType> types {};
|
||||
};
|
||||
|
||||
struct CryptoValueCache;
|
||||
|
||||
/**
|
||||
* A "value" is data potentially stored on the Dht, with some metadata.
|
||||
*
|
||||
@@ -967,7 +968,7 @@ struct OPENDHT_PUBLIC Query
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const dht::Query& q) {
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<<(std::ostream& s, const dht::Query& q) {
|
||||
return s << "Query[" << q.select << " " << q.where << "]";
|
||||
}
|
||||
|
||||
|
||||
+119
-197
@@ -1,53 +1,29 @@
|
||||
project(
|
||||
'opendht',
|
||||
'c',
|
||||
'cpp',
|
||||
'cython',
|
||||
version: '3.6.0',
|
||||
meson_version: '>=1.1.0',
|
||||
default_options: ['cpp_std=c++17', 'warning_level=3'],
|
||||
)
|
||||
project('opendht', 'c', 'cpp', 'cython',
|
||||
version: '3.2.0',
|
||||
default_options: [
|
||||
'cpp_std=c++17',
|
||||
'warning_level=3'
|
||||
])
|
||||
|
||||
gnutls = dependency('gnutls')
|
||||
nettle = dependency('nettle')
|
||||
msgpack = dependency('msgpack-cxx', required: false)
|
||||
msgpack = dependency('msgpack-cxx', required : false)
|
||||
argon2 = dependency('libargon2')
|
||||
fmt = dependency('fmt')
|
||||
openssl = dependency('openssl', required: get_option('proxy_client'))
|
||||
jsoncpp = dependency('jsoncpp', required: get_option('proxy_client'))
|
||||
fmt = dependency('fmt')
|
||||
llhttp = dependency('llhttp', 'libllhttp', required: get_option('proxy_client'))
|
||||
simdutf = dependency('simdutf', required: get_option('proxy_client'))
|
||||
io_uring = host_machine.system() == 'linux' ? dependency('liburing', required: false) : disabler()
|
||||
io_uring = dependency('liburing', required: false)
|
||||
|
||||
deps = [
|
||||
fmt,
|
||||
gnutls,
|
||||
nettle,
|
||||
msgpack,
|
||||
argon2,
|
||||
openssl,
|
||||
jsoncpp,
|
||||
simdutf,
|
||||
llhttp,
|
||||
io_uring,
|
||||
]
|
||||
deps = [fmt, gnutls, nettle, msgpack, argon2, openssl, jsoncpp, llhttp, io_uring]
|
||||
conf_data = configuration_data()
|
||||
|
||||
add_project_arguments('-DMSGPACK_NO_BOOST', '-DASIO_STANDALONE', language: 'cpp')
|
||||
add_project_arguments('-DMSGPACK_NO_BOOST', '-DASIO_STANDALONE', language : 'cpp')
|
||||
if io_uring.found()
|
||||
add_project_arguments('-DASIO_HAS_IO_URING', '-DASIO_DISABLE_EPOLL', language: 'cpp')
|
||||
add_project_arguments('-DASIO_HAS_IO_URING', '-DASIO_DISABLE_EPOLL', language : 'cpp')
|
||||
conf_data.set('iouring_lib', ', liburing')
|
||||
endif
|
||||
add_project_arguments(
|
||||
[
|
||||
'-Wno-return-type',
|
||||
'-Wno-deprecated',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-pedantic-errors',
|
||||
'-fvisibility=hidden',
|
||||
],
|
||||
language: 'cpp',
|
||||
)
|
||||
add_project_arguments(['-Wno-return-type','-Wno-deprecated','-Wnon-virtual-dtor','-pedantic-errors','-fvisibility=hidden'], language : 'cpp')
|
||||
|
||||
opendht_inc = include_directories('include/opendht')
|
||||
opendht_interface_inc = include_directories('include', is_system: true)
|
||||
@@ -72,17 +48,17 @@ opendht_src = [
|
||||
|
||||
if get_option('indexation').enabled()
|
||||
opendht_src += 'src/indexation/pht.cpp'
|
||||
add_project_arguments('-DOPENDHT_INDEXATION', language: 'cpp')
|
||||
add_project_arguments('-DOPENDHT_INDEXATION', language : 'cpp')
|
||||
endif
|
||||
if jsoncpp.found()
|
||||
opendht_src += ['src/base64.cpp']
|
||||
add_project_arguments('-DOPENDHT_JSONCPP', language: 'cpp')
|
||||
add_project_arguments('-DOPENDHT_JSONCPP', language : 'cpp')
|
||||
conf_data.set('jsoncpp_lib', ', jsoncpp')
|
||||
endif
|
||||
if llhttp.found()
|
||||
opendht_src += ['src/http.cpp', 'src/compat/os_cert.cpp']
|
||||
if host_machine.system() == 'darwin'
|
||||
deps += dependency('appleframeworks', modules: ['CoreFoundation', 'Security'])
|
||||
deps+=dependency('appleframeworks', modules : ['CoreFoundation', 'Security'])
|
||||
endif
|
||||
conf_data.set('http_lib', '-lllhttp')
|
||||
endif
|
||||
@@ -91,27 +67,25 @@ if openssl.found()
|
||||
endif
|
||||
if get_option('proxy_client').enabled()
|
||||
opendht_src += ['src/dht_proxy_client.cpp']
|
||||
add_project_arguments('-DOPENDHT_PROXY_CLIENT', language: 'cpp')
|
||||
add_project_arguments('-DOPENDHT_PROXY_CLIENT', language : 'cpp')
|
||||
endif
|
||||
if get_option('proxy_server').enabled()
|
||||
opendht_src += 'src/dht_proxy_server.cpp'
|
||||
add_project_arguments('-DOPENDHT_PROXY_SERVER', language: 'cpp')
|
||||
add_project_arguments('-DOPENDHT_PROXY_SERVER', language : 'cpp')
|
||||
endif
|
||||
if get_option('push_notifications').enabled()
|
||||
add_project_arguments('-DOPENDHT_PUSH_NOTIFICATIONS', language: 'cpp')
|
||||
add_project_arguments('-DOPENDHT_PUSH_NOTIFICATIONS', language : 'cpp')
|
||||
endif
|
||||
if get_option('peer_discovery').enabled()
|
||||
opendht_src += 'src/peer_discovery.cpp'
|
||||
add_project_arguments('-DOPENDHT_PEER_DISCOVERY', language: 'cpp')
|
||||
add_project_arguments('-DOPENDHT_PEER_DISCOVERY', language : 'cpp')
|
||||
endif
|
||||
opendht = library(
|
||||
'opendht',
|
||||
opendht = library('opendht',
|
||||
opendht_src,
|
||||
include_directories: opendht_inc,
|
||||
dependencies: deps,
|
||||
cpp_args: ['-DOPENDHT_BUILD', '-Dopendht_EXPORTS'],
|
||||
install: true,
|
||||
)
|
||||
include_directories : opendht_inc,
|
||||
dependencies : deps,
|
||||
cpp_args : ['-DOPENHT_BUILD', '-Dopendht_EXPORTS'],
|
||||
install : true)
|
||||
|
||||
conf_data.set('VERSION', meson.project_version())
|
||||
conf_data.set('prefix', get_option('prefix'))
|
||||
@@ -119,99 +93,74 @@ conf_data.set('exec_prefix', get_option('prefix'))
|
||||
conf_data.set('libdir', join_paths(get_option('prefix'), get_option('libdir')))
|
||||
conf_data.set('includedir', join_paths(get_option('prefix'), get_option('includedir')))
|
||||
conf_data.set('argon2_lib', ', libargon2')
|
||||
conf_data.set('simdutf_lib', ', simdutf')
|
||||
|
||||
configure_file(
|
||||
input: 'opendht.pc.in',
|
||||
output: 'opendht.pc',
|
||||
configuration: conf_data,
|
||||
install: true,
|
||||
install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
|
||||
)
|
||||
configure_file(input : 'opendht.pc.in',
|
||||
output : 'opendht.pc',
|
||||
configuration : conf_data,
|
||||
install: true,
|
||||
install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'))
|
||||
|
||||
readline = meson.get_compiler('c').find_library('readline', required: get_option('tools'))
|
||||
|
||||
if get_option('c').enabled()
|
||||
opendht_c = library(
|
||||
'opendht-c',
|
||||
['c/opendht.cpp', 'c/opendht_c.h'],
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [msgpack, jsoncpp, fmt],
|
||||
cpp_args: ['-DOPENDHT_C_BUILD', '-Dopendht_c_EXPORTS'],
|
||||
install: true,
|
||||
)
|
||||
|
||||
configure_file(
|
||||
input: 'opendht-c.pc.in',
|
||||
output: 'opendht-c.pc',
|
||||
configuration: conf_data,
|
||||
install: true,
|
||||
install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'),
|
||||
)
|
||||
opendht_c = library('opendht-c',
|
||||
['c/opendht.cpp', 'c/opendht_c.h'],
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [msgpack, jsoncpp, fmt],
|
||||
cpp_args : ['-DOPENDHT_C_BUILD', '-Dopendht_c_EXPORTS'],
|
||||
install : true)
|
||||
|
||||
configure_file(input : 'opendht-c.pc.in',
|
||||
output : 'opendht-c.pc',
|
||||
configuration : conf_data,
|
||||
install: true,
|
||||
install_dir: join_paths(get_option('prefix'), get_option('libdir'), 'pkgconfig'))
|
||||
|
||||
if get_option('tools').enabled()
|
||||
dhtcnode = executable(
|
||||
'dhtcnode',
|
||||
'tools/dhtcnode.c',
|
||||
include_directories: ['c', opendht_interface_inc],
|
||||
link_with: opendht_c,
|
||||
dependencies: [readline],
|
||||
install: true,
|
||||
)
|
||||
dhtcnode = executable('dhtcnode', 'tools/dhtcnode.c',
|
||||
include_directories : ['c', opendht_interface_inc],
|
||||
link_with : opendht_c,
|
||||
dependencies : [readline],
|
||||
install : true)
|
||||
endif
|
||||
endif
|
||||
|
||||
if get_option('python').require(
|
||||
get_option('indexation').enabled(),
|
||||
error_message: 'python requires indexation',
|
||||
).allowed()
|
||||
if get_option('python').require(get_option('indexation').enabled(), error_message: 'python requires indexation').allowed()
|
||||
py = import('python').find_installation()
|
||||
dep_py = py.dependency()
|
||||
py.extension_module(
|
||||
'opendht',
|
||||
'python/opendht.pyx',
|
||||
include_directories: opendht_interface_inc,
|
||||
override_options: ['cython_language=cpp'],
|
||||
link_with: [opendht],
|
||||
dependencies: [msgpack, jsoncpp, fmt, dep_py],
|
||||
install: true,
|
||||
include_directories : opendht_interface_inc,
|
||||
override_options : ['cython_language=cpp'],
|
||||
link_with : [opendht],
|
||||
dependencies : [msgpack, jsoncpp, fmt, dep_py],
|
||||
install : true
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('tools').enabled()
|
||||
dhtnode = executable(
|
||||
'dhtnode',
|
||||
'tools/dhtnode.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [readline, jsoncpp, msgpack, fmt, openssl],
|
||||
install: true,
|
||||
)
|
||||
dhtchat = executable(
|
||||
'dhtchat',
|
||||
'tools/dhtchat.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [readline, jsoncpp, msgpack, fmt, openssl],
|
||||
install: true,
|
||||
)
|
||||
dhtscanner = executable(
|
||||
'dhtscanner',
|
||||
'tools/dhtscanner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [readline, jsoncpp, msgpack, fmt, openssl],
|
||||
install: true,
|
||||
)
|
||||
dhtnode = executable('dhtnode', 'tools/dhtnode.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [readline, jsoncpp, msgpack, fmt, openssl],
|
||||
install : true)
|
||||
dhtchat = executable('dhtchat', 'tools/dhtchat.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [readline, jsoncpp, msgpack, fmt, openssl],
|
||||
install : true)
|
||||
dhtscanner = executable('dhtscanner', 'tools/dhtscanner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [readline, jsoncpp, msgpack, fmt, openssl],
|
||||
install : true)
|
||||
if llhttp.found()
|
||||
durl = executable(
|
||||
'durl',
|
||||
'tools/durl.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [msgpack, openssl],
|
||||
)
|
||||
durl = executable('durl', 'tools/durl.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [msgpack, openssl])
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -219,101 +168,74 @@ endif
|
||||
if get_option('tests').enabled()
|
||||
cppunit = dependency('cppunit')
|
||||
|
||||
test_infohash = executable(
|
||||
'test_infohash',
|
||||
'tests/infohashtester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_infohash = executable('test_infohash',
|
||||
'tests/infohashtester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('Infohash', test_infohash)
|
||||
|
||||
test_value = executable(
|
||||
'test_value',
|
||||
'tests/valuetester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_value = executable('test_value',
|
||||
'tests/valuetester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('Value', test_value)
|
||||
|
||||
test_crypto = executable(
|
||||
'test_crypto',
|
||||
'tests/cryptotester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_crypto = executable('test_crypto',
|
||||
'tests/cryptotester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('Crypto', test_crypto)
|
||||
|
||||
test_dhtrunner = executable(
|
||||
'test_dhtrunner',
|
||||
'tests/dhtrunnertester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_dhtrunner = executable('test_dhtrunner',
|
||||
'tests/dhtrunnertester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('DhtRunner', test_dhtrunner)
|
||||
|
||||
test_threadpool = executable(
|
||||
'test_threadpool',
|
||||
'tests/threadpooltester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_threadpool = executable('test_threadpool',
|
||||
'tests/threadpooltester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('ThreadPool', test_threadpool)
|
||||
|
||||
if get_option('proxy_client').enabled() or get_option('proxy_server').enabled()
|
||||
test_http = executable(
|
||||
'test_http',
|
||||
'tests/httptester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_http = executable('test_http',
|
||||
'tests/httptester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('Http', test_http)
|
||||
endif
|
||||
|
||||
if get_option('peer_discovery').enabled()
|
||||
test_peerdiscovery = executable(
|
||||
'test_peerdiscovery',
|
||||
'tests/peerdiscoverytester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_peerdiscovery = executable('test_peerdiscovery',
|
||||
'tests/peerdiscoverytester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('PeerDiscovery', test_peerdiscovery)
|
||||
endif
|
||||
|
||||
if get_option('proxy_server').enabled()
|
||||
test_proxy = executable(
|
||||
'test_dhtproxy',
|
||||
'tests/dhtproxytester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_proxy = executable('test_dhtproxy',
|
||||
'tests/dhtproxytester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('DhtProxy', test_proxy)
|
||||
|
||||
if get_option('long_tests').enabled()
|
||||
test_proxystress = executable(
|
||||
'test_dhtproxystress',
|
||||
'tests/dhtproxy_stress_tester.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_interface_inc,
|
||||
link_with: opendht,
|
||||
dependencies: [cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test_proxystress = executable('test_dhtproxystress',
|
||||
'tests/dhtproxy_stress_tester.cpp', 'tests/tests_runner.cpp',
|
||||
include_directories : opendht_interface_inc,
|
||||
link_with : opendht,
|
||||
dependencies : [cppunit, jsoncpp, fmt, openssl, msgpack])
|
||||
test('DhtProxy Stress', test_proxystress)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
+2
-2
@@ -5,8 +5,8 @@ includedir=@includedir@
|
||||
Name: OpenDHT
|
||||
Description: C++17 Distributed Hash Table library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lopendht -lfmt
|
||||
Libs: -L${libdir} -lopendht
|
||||
Libs.private: @http_lib@ -pthread
|
||||
Requires: gnutls >= 3.3@jsoncpp_lib@@openssl_lib@
|
||||
Requires.private: nettle >= 2.4@argon2_lib@@llhttp_lib@@iouring_lib@@simdutf_lib@
|
||||
Requires.private: nettle >= 2.4@argon2_lib@@iouring_lib@
|
||||
Cflags: -I${includedir}
|
||||
+9
-39
@@ -1,49 +1,19 @@
|
||||
|
||||
set(CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
configure_file(setup.py.in setup.py)
|
||||
configure_file(pyproject.toml pyproject.toml COPYONLY)
|
||||
configure_file(README.md README.md COPYONLY)
|
||||
|
||||
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||
add_custom_target(python ALL
|
||||
COMMAND python3 setup.py build
|
||||
DEPENDS opendht opendht_cpp.pxd opendht.pyx pyproject.toml)
|
||||
|
||||
add_custom_target(python
|
||||
COMMAND ${Python3_EXECUTABLE} -m build "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
DEPENDS opendht opendht_cpp.pxd opendht.pyx pyproject.toml
|
||||
${CURRENT_SOURCE_DIR}/opendht/__init__.py
|
||||
${CURRENT_SOURCE_DIR}/opendht/aio.py)
|
||||
|
||||
install(CODE [[
|
||||
if(NOT Python3_EXECUTABLE)
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
endif()
|
||||
if(NOT Python3_EXECUTABLE)
|
||||
message(WARNING "Skipping Python package install: Python interpreter not found.")
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip --version
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
RESULT_VARIABLE _pip_check)
|
||||
if(NOT _pip_check EQUAL 0)
|
||||
message(WARNING "Skipping Python package install: pip not available for ${Python3_EXECUTABLE}.")
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip install --no-deps --break-system-packages .
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python
|
||||
OUTPUT_VARIABLE _pip_output
|
||||
ERROR_VARIABLE _pip_error
|
||||
RESULT_VARIABLE _pip_result)
|
||||
add_custom_target(dist
|
||||
COMMAND python3 -m build
|
||||
DEPENDS opendht opendht_cpp.pxd opendht.pyx pyproject.toml)
|
||||
|
||||
if(_pip_result EQUAL 0)
|
||||
message(STATUS "Successfully installed Python package")
|
||||
message(STATUS "Output: ${_pip_output}")
|
||||
else()
|
||||
message(WARNING "pip install failed (code: ${_pip_result})\nOutput: ${_pip_output}\nError: ${_pip_error}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
]])
|
||||
install(CODE "execute_process(COMMAND python3 setup.py install --root=\$ENV{DESTDIR}/ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
|
||||
if (OPENDHT_TOOLS)
|
||||
install(PROGRAMS tools/dhtcluster.py DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME dhtcluster)
|
||||
endif()
|
||||
endif()
|
||||
+3
-3
@@ -8,7 +8,7 @@ noinst_HEADERS = \
|
||||
PYTHON_INSTALL_RECORD = $(builddir)/install_record.txt
|
||||
|
||||
pybuild.stamp:
|
||||
LDFLAGS="-L$(top_srcdir)/src/.libs" $(PYTHON) -m build .
|
||||
LDFLAGS="-L$(top_srcdir)/src/.libs" $(PYTHON) setup.py build_ext --inplace
|
||||
echo stamp > pybuild.stamp
|
||||
|
||||
CLEANFILES = pybuild.stamp
|
||||
@@ -18,8 +18,7 @@ clean-local:
|
||||
rm -rf $(builddir)/build $(builddir)/*.so $(PYTHON_INSTALL_RECORD)
|
||||
|
||||
install-exec-local:
|
||||
$(PYTHON) -m pip install --no-deps --no-build-isolation . \
|
||||
--root=$(DESTDIR)/ --prefix=$(prefix)
|
||||
$(PYTHON) setup.py install --root=$(DESTDIR)/ --record $(PYTHON_INSTALL_RECORD)
|
||||
rm -rf $(builddir)/build
|
||||
|
||||
if HAVE_PIP
|
||||
@@ -28,3 +27,4 @@ uninstall-local:
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
# OpenDHT
|
||||
|
||||
OpenDHT is a lightweight Distributed Hash Table implementation providing an easy to use distributed in-memory data store.
|
||||
|
||||
## Key Features
|
||||
|
||||
* Lightweight and scalable, designed for large networks and small devices
|
||||
* High resilience to network disruption
|
||||
* Public key cryptography layer providing optional data signature and encryption
|
||||
* IPv4 and IPv6 support
|
||||
* Python 3 bindings
|
||||
* REST API with optional HTTP client+server with push notification support
|
||||
|
||||
Every node in the network can read and write values to the store. Values are distributed over the network with redundancy.
|
||||
|
||||
## Installation
|
||||
|
||||
Install on Linux, macOS and Windows with:
|
||||
```sh
|
||||
pip install opendht
|
||||
```
|
||||
|
||||
## Quick Example
|
||||
|
||||
Using the simple, blocking API:
|
||||
```python
|
||||
import opendht as dht
|
||||
|
||||
node = dht.DhtRunner()
|
||||
node.run()
|
||||
|
||||
# Join the DHT network through any running node,
|
||||
# here using a known bootstrap node.
|
||||
node.bootstrap("bootstrap.jami.net", "4222")
|
||||
|
||||
# blocking call (provide callback arguments to make the call non-blocking)
|
||||
node.put(dht.InfoHash.get("unique_key"), dht.Value(b'some binary data'))
|
||||
|
||||
results = node.get(dht.InfoHash.get("unique_key"))
|
||||
for value in results:
|
||||
print(value)
|
||||
```
|
||||
|
||||
Or using asyncio:
|
||||
```python
|
||||
import asyncio
|
||||
import opendht.aio as dht
|
||||
|
||||
async def dht_async_demo(key_str: str):
|
||||
# Start a new node using an async context manager.
|
||||
# It is also possible to call run()/await shutdown() manually.
|
||||
async with dht.DhtRunner(
|
||||
bootstrap=(("bootstrap.jami.net", "4222"),)
|
||||
) as node:
|
||||
# compute key hash
|
||||
key = dht.InfoHash.get(key_str)
|
||||
|
||||
# put data, waiting for completion
|
||||
await node.put(key, dht.Value(b'tata data'))
|
||||
|
||||
# get all values at key
|
||||
results = await node.getAll(key)
|
||||
for value in results:
|
||||
print(value)
|
||||
|
||||
# same operation, but stream values as they come from the network
|
||||
with node.get(key) as results:
|
||||
async for value in results:
|
||||
print(value)
|
||||
|
||||
# listen for change of values at key
|
||||
with node.listen(key) as values:
|
||||
async for value, expired in values:
|
||||
print(value)
|
||||
if value.data == b'tata data':
|
||||
break
|
||||
|
||||
asyncio.run(dht_async_demo("unique_key"))
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
For more information, examples and documentation, or to repport issues, visit: https://opendht.net
|
||||
|
||||
## License
|
||||
|
||||
Copyright (C) 2014-2025 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.
|
||||
+116
-250
@@ -5,20 +5,27 @@
|
||||
# distutils: libraries = opendht gnutls
|
||||
# cython: language_level=3
|
||||
#
|
||||
# Copyright (C) 2014-2025 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 Savoir-faire Linux Inc.
|
||||
# Author(s): Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# This wrapper is written for Cython 0.22
|
||||
#
|
||||
# This file is part of OpenDHT Python Wrapper.
|
||||
#
|
||||
# OpenDHT Python Wrapper is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# OpenDHT Python Wrapper is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# along with OpenDHT Python Wrapper. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from libcpp.map cimport map as map
|
||||
from libcpp cimport bool
|
||||
@@ -26,6 +33,7 @@ from libcpp.utility cimport pair
|
||||
from libcpp.string cimport string
|
||||
from libcpp.memory cimport shared_ptr
|
||||
|
||||
from cython.parallel import parallel, prange
|
||||
from cython.operator cimport dereference as deref, preincrement as inc, predecrement as dec
|
||||
from cpython cimport ref
|
||||
from datetime import timedelta
|
||||
@@ -34,23 +42,6 @@ cimport opendht_cpp as cpp
|
||||
|
||||
import threading
|
||||
|
||||
cdef inline void _initialize_gnutls():
|
||||
cdef int err = cpp.gnutls_global_init()
|
||||
if err != 0:
|
||||
print(f"Failed to initialize GnuTLS: {cpp.gnutls_strerror(err).decode()}")
|
||||
else:
|
||||
import atexit
|
||||
atexit.register(_deinitialize_gnutls)
|
||||
|
||||
cdef inline _deinitialize_gnutls():
|
||||
cpp.gnutls_global_deinit()
|
||||
|
||||
# Initialize GnuTLS when this module is imported
|
||||
_initialize_gnutls()
|
||||
|
||||
def version() -> str:
|
||||
return cpp.version().decode()
|
||||
|
||||
cdef inline void lookup_callback(cpp.vector[cpp.shared_ptr[cpp.IndexValue]]* values, cpp.Prefix* p, void *user_data) noexcept with gil:
|
||||
cbs = <object>user_data
|
||||
if 'lookup' in cbs and cbs['lookup']:
|
||||
@@ -107,12 +98,6 @@ cdef class _WithID(object):
|
||||
def __str__(self):
|
||||
return self.getId().toString().decode()
|
||||
|
||||
cdef class _WithPk(object):
|
||||
def __repr__(self):
|
||||
return "<%s '%s'>" % (self.__class__.__name__, str(self))
|
||||
def __str__(self):
|
||||
return self.getLongId().toString().decode()
|
||||
|
||||
cdef class InfoHash(_WithID):
|
||||
cdef cpp.InfoHash _infohash
|
||||
def __cinit__(self, bytes str=b''):
|
||||
@@ -138,57 +123,19 @@ cdef class InfoHash(_WithID):
|
||||
def toFloat(InfoHash self):
|
||||
return self._infohash.toFloat()
|
||||
@staticmethod
|
||||
def commonBits(InfoHash a, InfoHash b) -> int:
|
||||
def commonBits(InfoHash a, InfoHash b):
|
||||
return cpp.InfoHash.commonBits(a._infohash, b._infohash)
|
||||
@staticmethod
|
||||
def get(str key) -> InfoHash:
|
||||
def get(str key):
|
||||
h = InfoHash()
|
||||
h._infohash = cpp.InfoHash.get(key.encode())
|
||||
return h
|
||||
@staticmethod
|
||||
def getRandom() -> InfoHash:
|
||||
def getRandom():
|
||||
h = InfoHash()
|
||||
h._infohash = cpp.InfoHash.getRandom()
|
||||
return h
|
||||
|
||||
cdef class PkId(_WithPk):
|
||||
cdef cpp.PkId _pkid
|
||||
def __cinit__(self, bytes str=b''):
|
||||
self._pkid = cpp.PkId(str) if str else cpp.PkId()
|
||||
def __bool__(PkId self):
|
||||
return <bool>self._pkid
|
||||
def __richcmp__(PkId self, PkId other, int op):
|
||||
if op == 0:
|
||||
return self._pkid < other._pkid
|
||||
if op == 1:
|
||||
return self._pkid < other._pkid or self._pkid == other._pkid
|
||||
if op == 2:
|
||||
return self._pkid == other._pkid
|
||||
return NotImplemented
|
||||
def getBit(PkId self, bit):
|
||||
return self._pkid.getBit(bit)
|
||||
def setBit(PkId self, bit, b):
|
||||
self._pkid.setBit(bit, b)
|
||||
def getLongId(PkId self):
|
||||
return self
|
||||
def toString(PkId self):
|
||||
return self._pkid.toString()
|
||||
def toFloat(PkId self) -> float:
|
||||
return self._pkid.toFloat()
|
||||
@staticmethod
|
||||
def commonBits(PkId a, PkId b) -> int:
|
||||
return cpp.PkId.commonBits(a._pkid, b._pkid)
|
||||
@staticmethod
|
||||
def get(str key) -> PkId:
|
||||
h = PkId()
|
||||
h._pkid = cpp.PkId.get(key.encode())
|
||||
return h
|
||||
@staticmethod
|
||||
def getRandom() -> PkId:
|
||||
h = PkId()
|
||||
h._pkid = cpp.PkId.getRandom()
|
||||
return h
|
||||
|
||||
cdef class SockAddr(object):
|
||||
cdef cpp.SockAddr _addr
|
||||
def toString(SockAddr self):
|
||||
@@ -278,7 +225,7 @@ cdef class Where(object):
|
||||
self._where = cpp.Where()
|
||||
def __str__(self):
|
||||
return self._where.toString().decode()
|
||||
def isSatisfiedBy(self, Where where) -> bool:
|
||||
def isSatisfiedBy(self, Where where):
|
||||
return self._where.isSatisfiedBy(where._where)
|
||||
def id(self, cpp.uint64_t id):
|
||||
self._where.id(id)
|
||||
@@ -300,44 +247,39 @@ cdef class Value(object):
|
||||
cdef shared_ptr[cpp.Value] _value
|
||||
def __init__(self, bytes val=b'', cpp.uint16_t id=0):
|
||||
self._value.reset(new cpp.Value(id, val, len(val)))
|
||||
|
||||
def __str__(self):
|
||||
return self._value.get().toString().decode()
|
||||
@property
|
||||
def owner(self) -> PublicKey:
|
||||
h = PublicKey()
|
||||
h._key = self._value.get().owner
|
||||
return h
|
||||
@property
|
||||
def recipient(self) -> InfoHash:
|
||||
h = InfoHash()
|
||||
h._infohash = self._value.get().recipient
|
||||
return h
|
||||
@recipient.setter
|
||||
def recipient(self, InfoHash h):
|
||||
self._value.get().recipient = h._infohash
|
||||
@property
|
||||
def data(self) -> bytes:
|
||||
cdef char* data_ptr = <char*>self._value.get().data.data()
|
||||
cdef int data_size = self._value.get().data.size()
|
||||
return data_ptr[:data_size]
|
||||
@data.setter
|
||||
def data(self, bytes value):
|
||||
self._value.get().data = value
|
||||
@property
|
||||
def user_type(self) -> str:
|
||||
return self._value.get().user_type.decode()
|
||||
@user_type.setter
|
||||
def user_type(self, str t):
|
||||
self._value.get().user_type = t.encode()
|
||||
@property
|
||||
def id(self):
|
||||
return self._value.get().id
|
||||
@id.setter
|
||||
def id(self, cpp.uint64_t value):
|
||||
self._value.get().id = value
|
||||
@property
|
||||
def size(self) -> int:
|
||||
return self._value.get().size()
|
||||
property owner:
|
||||
def __get__(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._value.get().owner.get().getId()
|
||||
return h
|
||||
property recipient:
|
||||
def __get__(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._value.get().recipient
|
||||
return h
|
||||
def __set__(self, InfoHash h):
|
||||
self._value.get().recipient = h._infohash
|
||||
property data:
|
||||
def __get__(self):
|
||||
return string(<char*>self._value.get().data.data(), self._value.get().data.size())
|
||||
def __set__(self, bytes value):
|
||||
self._value.get().data = value
|
||||
property user_type:
|
||||
def __get__(self):
|
||||
return self._value.get().user_type.decode()
|
||||
def __set__(self, str t):
|
||||
self._value.get().user_type = t.encode()
|
||||
property id:
|
||||
def __get__(self):
|
||||
return self._value.get().id
|
||||
def __set__(self, cpp.uint64_t value):
|
||||
self._value.get().id = value
|
||||
property size:
|
||||
def __get__(self):
|
||||
return self._value.get().size()
|
||||
|
||||
cdef class ValueType(object):
|
||||
cdef cpp.ValueType * _value
|
||||
@@ -392,31 +334,17 @@ cdef class NodeSet(object):
|
||||
def __iter__(self):
|
||||
return NodeSetIter(self)
|
||||
|
||||
cdef class PrivateKey(_WithPk):
|
||||
cdef class PrivateKey(_WithID):
|
||||
cdef shared_ptr[cpp.PrivateKey] _key
|
||||
|
||||
def getId(self) -> InfoHash:
|
||||
if not self._key:
|
||||
raise ValueError("PrivateKey is not initialized")
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._key.get().getSharedPublicKey().get().getId()
|
||||
return h
|
||||
|
||||
def getLongId(self) -> PkId:
|
||||
if not self._key:
|
||||
raise ValueError("PrivateKey is not initialized")
|
||||
id = PkId()
|
||||
id._pkid = self._key.get().getSharedPublicKey().get().getLongId()
|
||||
return id
|
||||
|
||||
def getPublicKey(self) -> PublicKey:
|
||||
if not self._key:
|
||||
raise ValueError("PrivateKey is not initialized")
|
||||
def getPublicKey(self):
|
||||
pk = PublicKey()
|
||||
pk._key = self._key.get().getSharedPublicKey()
|
||||
return pk
|
||||
|
||||
def decrypt(self, bytes dat) -> bytes:
|
||||
def decrypt(self, bytes dat):
|
||||
cdef size_t d_len = len(dat)
|
||||
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
|
||||
cdef cpp.Blob indat
|
||||
@@ -425,49 +353,26 @@ cdef class PrivateKey(_WithPk):
|
||||
cdef char* decrypted_c_str = <char *>decrypted.data()
|
||||
cdef Py_ssize_t length = decrypted.size()
|
||||
return decrypted_c_str[:length]
|
||||
|
||||
def sign(self, bytes dat) -> bytes:
|
||||
if not self._key:
|
||||
raise ValueError("PrivateKey is not initialized")
|
||||
cdef size_t d_len = len(dat)
|
||||
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
|
||||
cdef cpp.Blob indat
|
||||
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
|
||||
cdef cpp.Blob signature = self._key.get().sign(indat)
|
||||
cdef char* signature_c_str = <char *>signature.data()
|
||||
cdef Py_ssize_t length = signature.size()
|
||||
return signature_c_str[:length]
|
||||
|
||||
def __str__(self):
|
||||
return self.getId().toString().decode()
|
||||
@staticmethod
|
||||
def generate() -> PrivateKey:
|
||||
def generate():
|
||||
k = PrivateKey()
|
||||
k._key = cpp.make_shared[cpp.PrivateKey](cpp.PrivateKey.generate())
|
||||
return k
|
||||
@staticmethod
|
||||
def generateEC() -> PrivateKey:
|
||||
def generateEC():
|
||||
k = PrivateKey()
|
||||
k._key = cpp.make_shared[cpp.PrivateKey](cpp.PrivateKey.generateEC())
|
||||
return k
|
||||
|
||||
cdef class PublicKey(_WithPk):
|
||||
cdef class PublicKey(_WithID):
|
||||
cdef cpp.shared_ptr[cpp.PublicKey] _key
|
||||
def getId(self) -> InfoHash:
|
||||
if not self._key:
|
||||
raise ValueError("PublicKey is not initialized")
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._key.get().getId()
|
||||
return h
|
||||
|
||||
def getLongId(self) -> PkId:
|
||||
if not self._key:
|
||||
raise ValueError("PublicKey is not initialized")
|
||||
id = PkId()
|
||||
id._pkid = self._key.get().getLongId()
|
||||
return id
|
||||
|
||||
def encrypt(self, bytes dat) -> bytes:
|
||||
if not self._key:
|
||||
raise ValueError("PublicKey is not initialized")
|
||||
def encrypt(self, bytes dat):
|
||||
cdef size_t d_len = len(dat)
|
||||
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
|
||||
cdef cpp.Blob indat
|
||||
@@ -477,53 +382,29 @@ cdef class PublicKey(_WithPk):
|
||||
cdef Py_ssize_t length = encrypted.size()
|
||||
return encrypted_c_str[:length]
|
||||
|
||||
def checkSignature(self, bytes dat, bytes signature) -> bool:
|
||||
if not self._key:
|
||||
raise ValueError("PublicKey is not initialized")
|
||||
cdef size_t d_len = len(dat)
|
||||
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
|
||||
cdef cpp.Blob indat
|
||||
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
|
||||
cdef size_t s_len = len(signature)
|
||||
cdef cpp.uint8_t* s_ptr = <cpp.uint8_t*>signature
|
||||
cdef cpp.Blob sig
|
||||
sig.assign(s_ptr, <cpp.uint8_t*>(s_ptr + s_len))
|
||||
return self._key.get().checkSignature(indat, sig)
|
||||
|
||||
cdef class Certificate(_WithPk):
|
||||
cdef class Certificate(_WithID):
|
||||
cdef shared_ptr[cpp.Certificate] _cert
|
||||
def __init__(self, bytes dat = None):
|
||||
if dat:
|
||||
self._cert = cpp.make_shared[cpp.Certificate](<cpp.string>dat)
|
||||
def getId(self) -> InfoHash:
|
||||
if not self._cert:
|
||||
raise ValueError("Certificate is not initialized")
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._cert.get().getId()
|
||||
if self._cert:
|
||||
h._infohash = self._cert.get().getId()
|
||||
return h
|
||||
def getLongId(self) -> PkId:
|
||||
if not self._cert:
|
||||
raise ValueError("Certificate is not initialized")
|
||||
id = PkId()
|
||||
id._pkid = self._cert.get().getLongId()
|
||||
return id
|
||||
def toString(self) -> str:
|
||||
if not self._cert:
|
||||
return ""
|
||||
def toString(self):
|
||||
return self._cert.get().toString().decode()
|
||||
def getName(self) -> str:
|
||||
return self._cert.get().getName().decode()
|
||||
def getName(self):
|
||||
return self._cert.get().getName()
|
||||
def revoke(self, PrivateKey k, Certificate c):
|
||||
self._cert.get().revoke(deref(k._key.get()), deref(c._cert.get()));
|
||||
def __bytes__(self):
|
||||
return self._cert.get().toString().encode() if self._cert else b''
|
||||
@property
|
||||
def issuer(self) -> Certificate|None:
|
||||
if self._cert and self._cert.get().issuer:
|
||||
return self._cert.get().toString() if self._cert else b''
|
||||
property issuer:
|
||||
def __get__(self):
|
||||
c = Certificate()
|
||||
c._cert = self._cert.get().issuer
|
||||
return c
|
||||
return None
|
||||
return c;
|
||||
@staticmethod
|
||||
def generate(PrivateKey k, str name, Identity i = Identity(), bool is_ca = False):
|
||||
c = Certificate()
|
||||
@@ -565,27 +446,21 @@ cdef class Identity(object):
|
||||
i = Identity()
|
||||
i._id = cpp.generateIdentity(name.encode(), ca._id, bits)
|
||||
return i
|
||||
@property
|
||||
def publickey(self) -> PublicKey|None:
|
||||
if not self._id.first:
|
||||
return None
|
||||
k = PublicKey()
|
||||
k._key = self._id.first.get().getSharedPublicKey()
|
||||
return k
|
||||
@property
|
||||
def certificate(self) -> Certificate|None:
|
||||
if not self._id.second:
|
||||
return None
|
||||
c = Certificate()
|
||||
c._cert = self._id.second
|
||||
return c
|
||||
@property
|
||||
def key(self) -> PrivateKey|None:
|
||||
if not self._id.first:
|
||||
return None
|
||||
k = PrivateKey()
|
||||
k._key = self._id.first
|
||||
return k
|
||||
property publickey:
|
||||
def __get__(self):
|
||||
k = PublicKey()
|
||||
k._key = self._id.first.get().getSharedPublicKey()
|
||||
return k
|
||||
property certificate:
|
||||
def __get__(self):
|
||||
c = Certificate()
|
||||
c._cert = self._id.second
|
||||
return c
|
||||
property key:
|
||||
def __get__(self):
|
||||
k = PrivateKey()
|
||||
k._key = self._id.first
|
||||
return k
|
||||
|
||||
def aesEncrypt(bytes data, str password) -> bytes :
|
||||
cdef size_t d_len = len(data)
|
||||
@@ -644,22 +519,13 @@ cdef class DhtRunner(_WithID):
|
||||
cdef cpp.shared_ptr[cpp.DhtRunner] thisptr
|
||||
def __cinit__(self):
|
||||
self.thisptr.reset(new cpp.DhtRunner())
|
||||
def getId(self) -> InfoHash:
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
if self.thisptr:
|
||||
h._infohash = self.thisptr.get().getId()
|
||||
return h
|
||||
def getPublicKey(self) -> PublicKey:
|
||||
if not self.thisptr:
|
||||
raise ValueError("DhtRunner is not initialized")
|
||||
pk = PublicKey()
|
||||
pk._key = self.thisptr.get().getPublicKey()
|
||||
return pk
|
||||
def getNodeId(self) -> InfoHash:
|
||||
h = InfoHash()
|
||||
if self.thisptr:
|
||||
h._infohash = self.thisptr.get().getNodeId()
|
||||
return h
|
||||
def getNodeId(self):
|
||||
return self.thisptr.get().getNodeId().toString()
|
||||
def ping(self, SockAddr addr, done_cb=None):
|
||||
if done_cb:
|
||||
cb_obj = {'done':done_cb}
|
||||
@@ -815,33 +681,11 @@ cdef class DhtRunner(_WithID):
|
||||
lock.wait()
|
||||
return ok
|
||||
|
||||
def putEncrypted(self, InfoHash key, Value val, to, done_cb=None, bool permanent=False):
|
||||
if to is None:
|
||||
raise ValueError("'to' must be provided")
|
||||
def putEncrypted(self, InfoHash key, InfoHash to, Value val, done_cb=None, bool permanent=False):
|
||||
if done_cb:
|
||||
cb_obj = {'done':done_cb}
|
||||
ref.Py_INCREF(cb_obj)
|
||||
try:
|
||||
if isinstance(to, PublicKey):
|
||||
self.thisptr.get().putEncrypted(
|
||||
key._infohash, (<PublicKey>to)._key, val._value,
|
||||
cpp.bindDoneCb(done_callback, <void*>cb_obj), permanent
|
||||
)
|
||||
elif isinstance(to, PkId):
|
||||
self.thisptr.get().putEncrypted(
|
||||
key._infohash, (<PkId>to)._pkid, val._value,
|
||||
cpp.bindDoneCb(done_callback, <void*>cb_obj), permanent
|
||||
)
|
||||
elif isinstance(to, InfoHash):
|
||||
self.thisptr.get().putEncrypted(
|
||||
key._infohash, (<InfoHash>to)._infohash, val._value,
|
||||
cpp.bindDoneCb(done_callback, <void*>cb_obj), permanent
|
||||
)
|
||||
else:
|
||||
raise TypeError("'to' must be PublicKey, PkId, or InfoHash")
|
||||
except:
|
||||
ref.Py_DECREF(cb_obj)
|
||||
raise
|
||||
self.thisptr.get().putEncrypted(key._infohash, to._infohash, val._value, cpp.bindDoneCb(done_callback, <void*>cb_obj), permanent)
|
||||
else:
|
||||
lock = threading.Condition()
|
||||
pending = 0
|
||||
@@ -854,7 +698,29 @@ cdef class DhtRunner(_WithID):
|
||||
lock.notify()
|
||||
with lock:
|
||||
pending += 1
|
||||
self.putEncrypted(key, val, to=to, done_cb=tmp_done, permanent=permanent)
|
||||
self.putEncrypted(key, to, val, done_cb=tmp_done, permanent=permanent)
|
||||
while pending > 0:
|
||||
lock.wait()
|
||||
return ok
|
||||
|
||||
def putEncrypted(self, InfoHash key, PublicKey to, Value val, done_cb=None, bool permanent=False):
|
||||
if done_cb:
|
||||
cb_obj = {'done':done_cb}
|
||||
ref.Py_INCREF(cb_obj)
|
||||
self.thisptr.get().putEncrypted(key._infohash, to._key, val._value, cpp.bindDoneCb(done_callback, <void*>cb_obj), permanent)
|
||||
else:
|
||||
lock = threading.Condition()
|
||||
pending = 0
|
||||
ok = False
|
||||
def tmp_done(ok_ret, nodes):
|
||||
nonlocal pending, ok, lock
|
||||
with lock:
|
||||
ok = ok_ret
|
||||
pending -= 1
|
||||
lock.notify()
|
||||
with lock:
|
||||
pending += 1
|
||||
self.putEncrypted(key, to, val, done_cb=tmp_done, permanent=permanent)
|
||||
while pending > 0:
|
||||
lock.wait()
|
||||
return ok
|
||||
@@ -897,9 +763,9 @@ cdef class Pht(object):
|
||||
for kk, size in key_spec.items():
|
||||
cpp_key_spec[bytes(kk, 'utf-8')] = size
|
||||
self.thisptr = new cpp.Pht(name, cpp_key_spec, dht.thisptr)
|
||||
@property
|
||||
def MAX_NODE_ENTRY_COUNT(self):
|
||||
return cpp.PHT_MAX_NODE_ENTRY_COUNT
|
||||
property MAX_NODE_ENTRY_COUNT:
|
||||
def __get__(self):
|
||||
return cpp.PHT_MAX_NODE_ENTRY_COUNT
|
||||
def lookup(self, key, lookup_cb=None, done_cb=None):
|
||||
"""Query the Index with a specified key.
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
"""
|
||||
Python package facade for OpenDHT.
|
||||
|
||||
This package re-exports the Cython-built core bindings from ``opendht._core``
|
||||
to preserve the public API (e.g., ``opendht.DhtRunner``), and also exposes a
|
||||
pure-Python asyncio-friendly wrapper under ``opendht.aio``.
|
||||
"""
|
||||
|
||||
from ._core import * # re-export core Cython bindings
|
||||
|
||||
__version__ = version()
|
||||
__all__ = [name for name in dir() if not name.startswith("_")]
|
||||
@@ -1,293 +0,0 @@
|
||||
# Copyright (C) 2014-2025 Savoir-faire Linux Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from typing import Any, Callable, Iterable, List, Optional, Tuple
|
||||
|
||||
from . import _core as _dht
|
||||
|
||||
# Re-export core types for convenience
|
||||
from ._core import InfoHash, Value, ValueType, Where, SockAddr, PublicKey, PkId, DhtConfig, Identity
|
||||
|
||||
|
||||
class _Listener:
|
||||
"""Async iterator around DHT listen callback.
|
||||
|
||||
Yields tuples (Value, expired: bool).
|
||||
"""
|
||||
|
||||
__slots__ = ("_runner", "_token", "_loop", "_queue", "_closed")
|
||||
|
||||
def __init__(self, runner: DhtRunner, key: InfoHash) -> None:
|
||||
self._runner = runner
|
||||
self._loop = runner._loop
|
||||
self._queue: asyncio.Queue[Tuple[Value, bool]] = asyncio.Queue()
|
||||
self._closed = False
|
||||
|
||||
def _on_value(v: Value, expired: bool) -> bool:
|
||||
if self._closed:
|
||||
return False
|
||||
self._loop.call_soon_threadsafe(self._queue.put_nowait, (v, expired))
|
||||
return True # continue listening
|
||||
|
||||
self._token = self._runner._dht.listen(key, _on_value)
|
||||
|
||||
def __enter__(self) -> _Listener:
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc, tb) -> None:
|
||||
self.cancel()
|
||||
|
||||
def __aiter__(self) -> _Listener:
|
||||
return self
|
||||
|
||||
async def __anext__(self) -> Tuple[Value, bool]:
|
||||
if self._closed:
|
||||
raise StopAsyncIteration
|
||||
item = await self._queue.get()
|
||||
if item is None:
|
||||
self._closed = True
|
||||
raise StopAsyncIteration
|
||||
return item
|
||||
|
||||
def cancel(self) -> None:
|
||||
if self._closed:
|
||||
return
|
||||
self._closed = True
|
||||
try:
|
||||
self._runner._dht.cancelListen(self._token)
|
||||
finally:
|
||||
# Unblock any pending __anext__
|
||||
self._queue.put_nowait(None)
|
||||
|
||||
|
||||
class _GetStream:
|
||||
"""Async iterator around DHT get callback.
|
||||
|
||||
Yields Value instances as they are found, then ends.
|
||||
Raises on failure.
|
||||
"""
|
||||
__slots__ = ("_runner", "_loop", "_queue", "_closed", "_error")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
runner: DhtRunner,
|
||||
key: InfoHash,
|
||||
where: Optional[Where],
|
||||
filter: Optional[Callable[[Value], bool]],
|
||||
) -> None:
|
||||
self._runner = runner
|
||||
self._loop = runner._loop
|
||||
self._queue: asyncio.Queue[Optional[Value]] = asyncio.Queue()
|
||||
self._closed = False
|
||||
self._error: Optional[BaseException] = None
|
||||
|
||||
def _on_value(v: Value) -> bool:
|
||||
# Called on DHT thread
|
||||
if self._closed:
|
||||
return False
|
||||
self._loop.call_soon_threadsafe(self._queue.put_nowait, v)
|
||||
return True
|
||||
|
||||
def _on_done(ok: bool, _nodes: Iterable[Any]) -> None:
|
||||
# Called on DHT thread
|
||||
if self._closed:
|
||||
return
|
||||
if not ok:
|
||||
self._error = RuntimeError("DHT get failed")
|
||||
self._loop.call_soon_threadsafe(self._queue.put_nowait, None)
|
||||
|
||||
self._runner._dht.get(key, _on_value, _on_done, filter, where)
|
||||
|
||||
def __enter__(self) -> _GetStream:
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc, tb) -> None:
|
||||
self.cancel()
|
||||
|
||||
def __aiter__(self) -> _GetStream:
|
||||
return self
|
||||
|
||||
async def __anext__(self) -> Value:
|
||||
if self._closed:
|
||||
raise StopAsyncIteration
|
||||
item = await self._queue.get()
|
||||
if item is None:
|
||||
self._closed = True
|
||||
if self._error is not None:
|
||||
raise self._error
|
||||
raise StopAsyncIteration
|
||||
return item
|
||||
|
||||
def cancel(self) -> None:
|
||||
if self._closed:
|
||||
return
|
||||
self._closed = True
|
||||
# Unblock any pending __anext__
|
||||
self._queue.put_nowait(None)
|
||||
|
||||
|
||||
class DhtRunner:
|
||||
"""Async wrapper around opendht.DhtRunner.
|
||||
"""
|
||||
|
||||
__slots__ = ("_dht", "_loop", "_config", "_bootstrap")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
loop: Optional[asyncio.AbstractEventLoop] = None,
|
||||
core: Optional[_dht.DhtRunner] = None,
|
||||
config: Optional[DhtConfig] = None,
|
||||
bootstrap: Optional[Iterable[Tuple[str, Optional[str]]]] = None,
|
||||
) -> None:
|
||||
try:
|
||||
self._loop = loop or asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
self._loop = asyncio.get_event_loop()
|
||||
self._dht = core or _dht.DhtRunner()
|
||||
self._config = config
|
||||
self._bootstrap = list(bootstrap) if bootstrap is not None else None
|
||||
|
||||
def run(
|
||||
self,
|
||||
id: Optional[Identity] = None,
|
||||
is_bootstrap: bool = False,
|
||||
port: int = 0,
|
||||
ipv4: str = "",
|
||||
ipv6: str = "",
|
||||
config: Optional[DhtConfig] = None,
|
||||
) -> None:
|
||||
cfg = config or self._config or DhtConfig()
|
||||
self._dht.run(id, is_bootstrap, port, ipv4, ipv6, cfg)
|
||||
if self._bootstrap:
|
||||
for host, port_str in self._bootstrap:
|
||||
self._dht.bootstrap(host, port_str)
|
||||
|
||||
def bootstrap(self, host: str, port: Optional[str] = None) -> None:
|
||||
self._dht.bootstrap(host, port)
|
||||
|
||||
async def ping(self, addr: SockAddr) -> bool:
|
||||
fut: asyncio.Future[bool] = self._loop.create_future()
|
||||
self._dht.ping(addr, lambda ok: self._loop.call_soon_threadsafe(fut.set_result, bool(ok)))
|
||||
return await fut
|
||||
|
||||
def get(
|
||||
self,
|
||||
key: InfoHash,
|
||||
*,
|
||||
where: Optional[Where] = None,
|
||||
filter: Optional[Callable[[Value], bool]] = None,
|
||||
):
|
||||
# Return a streaming iterator of values; it ends on completion and raises on failure.
|
||||
return _GetStream(self, key, where, filter)
|
||||
|
||||
async def getAll(
|
||||
self,
|
||||
key: InfoHash,
|
||||
*,
|
||||
where: Optional[Where] = None,
|
||||
filter: Optional[Callable[[Value], bool]] = None,
|
||||
) -> List[Value]:
|
||||
"""Collect all values for a key and return them as a list."""
|
||||
results: List[Value] = []
|
||||
async for v in self.get(key, where=where, filter=filter):
|
||||
results.append(v)
|
||||
return results
|
||||
|
||||
async def getFirst(
|
||||
self,
|
||||
key: InfoHash,
|
||||
*,
|
||||
where: Optional[Where] = None,
|
||||
predicate: Optional[Callable[[Value], Any]] = None,
|
||||
filter: Optional[Callable[[Value], bool]] = None,
|
||||
) -> Optional[Value]:
|
||||
"""Return the first value matching an (optionally async) predicate, or None."""
|
||||
with self.get(key, where=where, filter=filter) as stream:
|
||||
async for value in stream:
|
||||
if predicate is None:
|
||||
return value
|
||||
result = predicate(value)
|
||||
if asyncio.iscoroutine(result):
|
||||
result = await result
|
||||
if result:
|
||||
return value
|
||||
return None
|
||||
|
||||
async def put(self, key: InfoHash, val: Value, *, permanent: bool = False) -> bool:
|
||||
fut: asyncio.Future[bool] = self._loop.create_future()
|
||||
|
||||
def _done(ok: bool, _nodes: Iterable[Any]) -> None:
|
||||
self._loop.call_soon_threadsafe(fut.set_result, bool(ok))
|
||||
|
||||
self._dht.put(key, val, _done, permanent)
|
||||
return await fut
|
||||
|
||||
async def putSigned(self, key: InfoHash, val: Value, *, permanent: bool = False) -> bool:
|
||||
fut: asyncio.Future[bool] = self._loop.create_future()
|
||||
|
||||
def _done(ok: bool, _nodes: Iterable[Any]) -> None:
|
||||
self._loop.call_soon_threadsafe(fut.set_result, bool(ok))
|
||||
|
||||
self._dht.putSigned(key, val, _done, permanent)
|
||||
return await fut
|
||||
|
||||
async def putEncrypted(
|
||||
self,
|
||||
key: InfoHash,
|
||||
to: InfoHash | PublicKey | PkId,
|
||||
val: Value,
|
||||
*,
|
||||
permanent: bool = False,
|
||||
) -> bool:
|
||||
fut: asyncio.Future[bool] = self._loop.create_future()
|
||||
|
||||
def _done(ok: bool, _nodes: Iterable[Any]) -> None:
|
||||
self._loop.call_soon_threadsafe(fut.set_result, bool(ok))
|
||||
|
||||
self._dht.putEncrypted(key, val, to, _done, permanent)
|
||||
return await fut
|
||||
|
||||
def listen(self, key: InfoHash) -> _Listener:
|
||||
return _Listener(self, key)
|
||||
|
||||
async def cancelListen(self, listener: _Listener) -> None:
|
||||
await listener.cancel()
|
||||
|
||||
async def shutdown(self) -> None:
|
||||
fut: asyncio.Future[None] = self._loop.create_future()
|
||||
self._dht.shutdown(lambda: self._loop.call_soon_threadsafe(fut.set_result, None))
|
||||
await fut
|
||||
|
||||
async def join(self) -> None:
|
||||
await asyncio.to_thread(self._dht.join)
|
||||
|
||||
async def __aenter__(self):
|
||||
if not self.isRunning():
|
||||
self.run()
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc, tb):
|
||||
if self.isRunning():
|
||||
try:
|
||||
await self.shutdown()
|
||||
finally:
|
||||
await self.join()
|
||||
return False
|
||||
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
return getattr(self._dht, name)
|
||||
+10
-39
@@ -1,29 +1,31 @@
|
||||
# Copyright (C) 2014-2025 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# along with this program; If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t
|
||||
from libc.stdint cimport *
|
||||
from libcpp cimport bool, nullptr_t, nullptr
|
||||
from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.utility cimport pair
|
||||
from libcpp.map cimport map
|
||||
from libcpp.memory cimport shared_ptr, make_shared
|
||||
from libc.string cimport const_char
|
||||
from libc.string cimport const_char, const_uchar
|
||||
|
||||
ctypedef uint16_t in_port_t
|
||||
ctypedef unsigned short int sa_family_t
|
||||
ctypedef unsigned short int sa_family_t;
|
||||
|
||||
cdef extern from "<chrono>" namespace "std::chrono" nogil:
|
||||
cdef cppclass duration[ulong]:
|
||||
@@ -49,7 +51,6 @@ cdef extern from "<future>" namespace "std" nogil:
|
||||
shared_future[T] share()
|
||||
|
||||
cdef extern from "opendht/utils.h" namespace "dht":
|
||||
const char* version()
|
||||
cdef cppclass time_point:
|
||||
@staticmethod
|
||||
time_point min() const
|
||||
@@ -73,24 +74,6 @@ cdef extern from "opendht/infohash.h" namespace "dht":
|
||||
bool operator==(InfoHash) const
|
||||
bool operator<(InfoHash) const
|
||||
bool operator bool() const
|
||||
|
||||
cdef cppclass PkId:
|
||||
PkId() except +
|
||||
PkId(string s) except +
|
||||
string toString() const
|
||||
bool getBit(unsigned bit) const
|
||||
void setBit(unsigned bit, bool b)
|
||||
double toFloat() const
|
||||
@staticmethod
|
||||
unsigned commonBits(PkId a, PkId b)
|
||||
@staticmethod
|
||||
PkId get(string s)
|
||||
@staticmethod
|
||||
PkId getRandom()
|
||||
bool operator==(PkId) const
|
||||
bool operator<(PkId) const
|
||||
bool operator bool() const
|
||||
|
||||
|
||||
cdef extern from "opendht/sockaddr.h" namespace "dht":
|
||||
cdef cppclass SockAddr:
|
||||
@@ -118,7 +101,6 @@ cdef extern from "opendht/crypto.h" namespace "dht::crypto":
|
||||
PrivateKey()
|
||||
shared_ptr[PublicKey] getSharedPublicKey() const
|
||||
Blob decrypt(Blob data) const
|
||||
Blob sign(Blob data) const
|
||||
@staticmethod
|
||||
PrivateKey generate()
|
||||
@staticmethod
|
||||
@@ -127,16 +109,12 @@ cdef extern from "opendht/crypto.h" namespace "dht::crypto":
|
||||
cdef cppclass PublicKey:
|
||||
PublicKey()
|
||||
InfoHash getId() const
|
||||
PkId getLongId() const
|
||||
Blob encrypt(Blob data) const
|
||||
bool checkSignature(Blob data, Blob signature) const
|
||||
bool operator==(PublicKey) const
|
||||
|
||||
cdef cppclass Certificate:
|
||||
Certificate()
|
||||
Certificate(string pem)
|
||||
InfoHash getId() const
|
||||
PkId getLongId() const
|
||||
string toString() const
|
||||
string getName() const
|
||||
void revoke(PrivateKey key, Certificate cert)
|
||||
@@ -277,7 +255,6 @@ cdef extern from "opendht/dhtrunner.h" namespace "dht":
|
||||
SockAddr bind6
|
||||
|
||||
InfoHash getId() const
|
||||
shared_ptr[PublicKey] getPublicKey() const
|
||||
InfoHash getNodeId() const
|
||||
void bootstrap(const_char*, const_char*)
|
||||
void bootstrap(const SockAddr&, DoneCallbackSimple done_cb)
|
||||
@@ -295,7 +272,6 @@ cdef extern from "opendht/dhtrunner.h" namespace "dht":
|
||||
void put(InfoHash key, shared_ptr[Value] val, DoneCallback done_cb, time_point created, bool permanent)
|
||||
void putSigned(InfoHash key, shared_ptr[Value] val, DoneCallback done_cb, bool permanent)
|
||||
void putEncrypted(InfoHash key, InfoHash to, shared_ptr[Value] val, DoneCallback done_cb, bool permanent)
|
||||
void putEncrypted(InfoHash key, PkId to, shared_ptr[Value] val, DoneCallback done_cb, bool permanent)
|
||||
void putEncrypted(InfoHash key, shared_ptr[PublicKey] to, shared_ptr[Value] val, DoneCallback done_cb, bool permanent)
|
||||
void cancelPut(InfoHash key, shared_ptr[Value] val)
|
||||
ListenToken listen(InfoHash key, ValueCallback get_cb)
|
||||
@@ -327,8 +303,3 @@ cdef extern from "opendht/indexation/pht.h" namespace "dht::indexation":
|
||||
void insert(IndexKey k, IndexValue v, DoneCallbackSimple cb)
|
||||
@staticmethod
|
||||
LookupCallback bindLookupCb(LookupCallbackRaw cb, void *user_data)
|
||||
|
||||
cdef extern from "gnutls/gnutls.h" nogil:
|
||||
int gnutls_global_init()
|
||||
void gnutls_global_deinit()
|
||||
const char* gnutls_strerror(int error)
|
||||
@@ -1,48 +1,3 @@
|
||||
[build-system]
|
||||
requires = ["setuptools", "wheel", "Cython"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.cibuildwheel]
|
||||
build = [
|
||||
'cp3{9,10,11,12,13}-manylinux_x86_64',
|
||||
'cp3{10,11,12,13}-manylinux_aarch64',
|
||||
'cp3{11,12,13}-macosx_x86_64',
|
||||
'cp3{11,12,13}-macosx_arm64',
|
||||
'cp3{11,12,13}-win_amd64',
|
||||
]
|
||||
|
||||
[tool.cibuildwheel.linux]
|
||||
manylinux-x86_64-image = 'manylinux_2_34'
|
||||
manylinux-aarch64-image = 'manylinux_2_34'
|
||||
before-all = [
|
||||
'dnf install -y epel-release',
|
||||
'dnf install -y gnutls-devel msgpack-devel readline-devel libargon2-devel asio-devel fmt-devel',
|
||||
]
|
||||
before-build = [
|
||||
'pip install cython',
|
||||
'cmake -DOPENDHT_PYTHON=ON -DOPENDHT_TOOLS=OFF -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release .',
|
||||
'cmake --build .',
|
||||
]
|
||||
# Point auditwheel to libopendht.so.* in the current dir when repairing
|
||||
repair-wheel-command = 'LD_LIBRARY_PATH=$PWD auditwheel repair -w {dest_dir} {wheel}'
|
||||
|
||||
[tool.cibuildwheel.macos]
|
||||
environment = { MACOSX_DEPLOYMENT_TARGET = "15.0" }
|
||||
before-all = [
|
||||
'brew update',
|
||||
'brew install gnutls msgpack-cxx readline argon2 asio fmt',
|
||||
]
|
||||
before-build = [
|
||||
'pip install cython delocate',
|
||||
'cmake -DOPENDHT_PYTHON=ON -DOPENDHT_TOOLS=OFF -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release .',
|
||||
'cmake --build .',
|
||||
]
|
||||
# Bundle dependent dylibs into the wheel; ensure local libopendht.dylib is found
|
||||
repair-wheel-command = 'DYLD_LIBRARY_PATH=$PWD delocate-wheel -w {dest_dir} {wheel}'
|
||||
|
||||
[tool.cibuildwheel.windows]
|
||||
# Configure first, then from 'build' directory run: with pipx run cibuildwheel python
|
||||
before-build = [
|
||||
'cmake --build . --config Release',
|
||||
]
|
||||
repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel} --add-path ./Release --add-path ./vcpkg_installed/x64-windows-release/bin"
|
||||
+37
-59
@@ -1,77 +1,55 @@
|
||||
# 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>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# A Python3 wrapper to access to OpenDHT API
|
||||
# This wrapper is written for Cython 0.22
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# This file is part of OpenDHT Python Wrapper.
|
||||
#
|
||||
# OpenDHT Python Wrapper 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.
|
||||
#
|
||||
# OpenDHT Python Wrapper is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OpenDHT Python Wrapper. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from setuptools import setup, Extension, find_packages
|
||||
from setuptools.command.build_ext import build_ext as _build_ext
|
||||
import os
|
||||
|
||||
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'README.md'), 'r', encoding='utf-8') as f:
|
||||
long_description = f.read()
|
||||
|
||||
extra_compile_args = {
|
||||
'msvc': ['/std:c++17', '/EHsc', '/utf-8'],
|
||||
'unix': ['-std=c++17'],
|
||||
}
|
||||
|
||||
extra_link_args = {
|
||||
'msvc': ['wsock32.lib', 'ws2_32.lib'],
|
||||
'unix': ['-std=c++17']
|
||||
}
|
||||
extra_libraries = {
|
||||
'msvc': ['opendht_import', 'gnutls'],
|
||||
'unix': ['opendht']
|
||||
}
|
||||
|
||||
class build_ext(_build_ext):
|
||||
def build_extensions(self):
|
||||
compile_args = extra_compile_args.get(self.compiler.compiler_type, [])
|
||||
link_args = extra_link_args.get(self.compiler.compiler_type, [])
|
||||
libraries = extra_libraries.get(self.compiler.compiler_type, ['opendht'])
|
||||
for ext in self.extensions:
|
||||
ext.extra_compile_args.extend(compile_args)
|
||||
ext.extra_link_args.extend(link_args)
|
||||
ext.libraries = libraries
|
||||
super().build_extensions()
|
||||
from setuptools import setup, Extension
|
||||
from Cython.Build import cythonize
|
||||
from Cython.Distutils import build_ext
|
||||
|
||||
setup(name="opendht",
|
||||
version="@PACKAGE_VERSION@",
|
||||
description="OpenDHT: A lightweight Distributed Hash Table",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
description="Python wrapper for OpenDHT",
|
||||
url='https://github.com/savoirfairelinux/opendht',
|
||||
author="Adrien Beraud <adrien.beraud@savoirfairelinux.com>",
|
||||
license="GPL-3.0-or-later",
|
||||
author="Adrien Béraud, Guillaume Roguez, Simon Désaulniers",
|
||||
license="GPLv3",
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: System :: Distributed Computing',
|
||||
'Topic :: System :: Networking',
|
||||
'Topic :: System :: Networking'
|
||||
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
],
|
||||
cmdclass=dict(build_ext=build_ext),
|
||||
packages=find_packages(where='@CURRENT_SOURCE_DIR@'),
|
||||
package_dir={"": "@CURRENT_SOURCE_DIR@"},
|
||||
ext_modules=[Extension(
|
||||
"opendht._core",
|
||||
cmdclass = { 'build_ext' : build_ext },
|
||||
ext_modules = cythonize(Extension(
|
||||
"opendht",
|
||||
["@CURRENT_SOURCE_DIR@/opendht.pyx"],
|
||||
include_dirs = ['@PROJECT_SOURCE_DIR@/include'],
|
||||
language="c++",
|
||||
extra_compile_args=["-DMSGPACK_NO_BOOST", "-DMSGPACK_DISABLE_LEGACY_NIL", "-DMSGPACK_DISABLE_LEGACY_CONVERT", "-DOPENDHT_INDEXATION", "-Dopendht_EXPORTS"],
|
||||
libraries=["opendht", "gnutls"],
|
||||
include_dirs = ['@PROJECT_SOURCE_DIR@/include'@OPENDHT_PYTHON_INCLUDE_DIRS@],
|
||||
library_dirs = ['@CURRENT_BINARY_DIR@', '@PROJECT_BINARY_DIR@'@OPENDHT_PYTHON_LIBRARY_DIRS@]
|
||||
)]
|
||||
extra_compile_args=["-std=c++17"],
|
||||
extra_link_args=["-std=c++17"],
|
||||
libraries=["opendht"],
|
||||
library_dirs = ['@CURRENT_BINARY_DIR@', '@PROJECT_BINARY_DIR@']
|
||||
))
|
||||
)
|
||||
@@ -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,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
|
||||
|
||||
+48
-46
@@ -15,62 +15,64 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import asyncio
|
||||
import opendht as dht
|
||||
import time
|
||||
import asyncio
|
||||
|
||||
from opendht import aio as dht
|
||||
config = dht.DhtConfig()
|
||||
config.setRateLimit(-1, -1)
|
||||
|
||||
ping_node = dht.DhtRunner()
|
||||
ping_node.run(config=config)
|
||||
#ping_node.enableLogging()
|
||||
#ping_node.bootstrap("bootstrap.jami.net", "4222")
|
||||
pong_node = dht.DhtRunner()
|
||||
pong_node.run(config=config)
|
||||
#pong_node.enableLogging()
|
||||
pong_node.ping(ping_node.getBound())
|
||||
|
||||
async def main():
|
||||
config = dht.DhtConfig()
|
||||
config.setRateLimit(-1, -1)
|
||||
loc_ping = dht.InfoHash.get("toto99")
|
||||
loc_pong = dht.InfoHash.get(str(loc_ping))
|
||||
|
||||
ping_node = dht.DhtRunner()
|
||||
pong_node = dht.DhtRunner()
|
||||
# ping_node.enableLogging()
|
||||
# pong_node.enableLogging()
|
||||
# ping_node.bootstrap("bootstrap.jami.net", "4222")
|
||||
ping_node.run(config=config)
|
||||
pong_node.run(config=config)
|
||||
await pong_node.ping(ping_node.getBound())
|
||||
net = []
|
||||
for i in range(1,10):
|
||||
node = dht.DhtRunner()
|
||||
node.run(config=config)
|
||||
node.ping(ping_node.getBound())
|
||||
net.append(node)
|
||||
|
||||
net = [dht.DhtRunner() for _ in range(1, 10)]
|
||||
for n in net:
|
||||
n.run(config=config)
|
||||
n.ping(ping_node.getBound())
|
||||
i = 0
|
||||
MAX = 2048
|
||||
|
||||
MAX = 2048
|
||||
counter = 0
|
||||
loc_ping = dht.InfoHash.get(f"ping-{ping_node.getNodeId()}")
|
||||
loc_pong = dht.InfoHash.get(str(loc_ping))
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
async def ponger(listener_node: dht.DhtRunner, listen_key, responder_node: dht.DhtRunner, respond_key):
|
||||
nonlocal counter
|
||||
with listener_node.listen(listen_key) as listener:
|
||||
async for value, expired in listener:
|
||||
if not expired:
|
||||
await responder_node.put(respond_key, dht.Value(b"hey"))
|
||||
counter += 1
|
||||
if counter >= MAX:
|
||||
break
|
||||
def done(h, ok):
|
||||
pass
|
||||
#print(h, "over", ok)
|
||||
|
||||
start = time.time()
|
||||
await asyncio.gather(
|
||||
ponger(ping_node, loc_ping, pong_node, loc_pong),
|
||||
ponger(pong_node, loc_pong, ping_node, loc_ping),
|
||||
pong_node.put(loc_ping, dht.Value(b"hey"))
|
||||
)
|
||||
duration = time.time() - start
|
||||
def ping(node, h):
|
||||
global i
|
||||
i += 1
|
||||
if i < MAX:
|
||||
node.put(h, dht.Value(b"hey"), lambda ok, nodes: done(node.getNodeId().decode(), ok))
|
||||
else:
|
||||
loop.stop()
|
||||
|
||||
await asyncio.gather(
|
||||
ping_node.shutdown(),
|
||||
pong_node.shutdown(),
|
||||
*(n.shutdown() for n in net),
|
||||
)
|
||||
def pong(node, h):
|
||||
#print(node.getNodeId().decode(), "got ping", h, i)
|
||||
loop.call_soon_threadsafe(ping, node, h)
|
||||
return True
|
||||
|
||||
print(MAX, "ping-pong done, took", duration, "s")
|
||||
print(1000 * duration / MAX, "ms per rt", MAX / duration, "rt per s")
|
||||
t1 = time.time()
|
||||
|
||||
ping_node.listen(loc_ping, lambda v, e: pong(pong_node, loc_pong) if not e else True)
|
||||
pong_node.listen(loc_pong, lambda v, e: pong(ping_node, loc_ping) if not e else True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
ping(pong_node, loc_ping)
|
||||
|
||||
loop.run_forever()
|
||||
|
||||
t2 = time.time()
|
||||
|
||||
print(MAX, "ping-pong done, took", t2 - t1, "s")
|
||||
print(1000 * (t2 - t1)/MAX, "ms per rt", MAX/(t2 - t1), "rt per s")
|
||||
@@ -1,18 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (C) 2014-2025 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2023 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
# along with this program; If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import time, sys, os
|
||||
from pprint import pprint
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 84 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 451 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB |
@@ -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
@@ -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
@@ -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,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
@@ -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,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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
lib_LTLIBRARIES = libopendht.la
|
||||
|
||||
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@ @OpenSSL_CFLAGS@ @Fmt_CFLAGS@ @Llhttp_CFLAGS@ @Liburing_CFLAGS@ @simdutf_CFLAGS@
|
||||
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@ @OpenSSL_LIBS@ @Fmt_LIBS@ @Llhttp_LIBS@ @Liburing_LIBS@ @simdutf_LIBS@
|
||||
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@ @OpenSSL_CFLAGS@ @Fmt_CFLAGS@
|
||||
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@ @OpenSSL_LIBS@ @Fmt_LIBS@
|
||||
libopendht_la_LDFLAGS = @LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
|
||||
libopendht_la_SOURCES = \
|
||||
dht.cpp \
|
||||
|
||||
+113
-16
@@ -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
|
||||
@@ -17,30 +17,127 @@
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#include <simdutf.h>
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
/* Mainly based on the following stackoverflow question:
|
||||
* http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
|
||||
*/
|
||||
static const char encoding_table[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
|
||||
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
||||
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
|
||||
's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2',
|
||||
'3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
static const size_t mod_table[] = { 0, 2, 1 };
|
||||
|
||||
char *base64_encode(const uint8_t *input, size_t input_length,
|
||||
char *output, size_t *output_length)
|
||||
{
|
||||
size_t i, j;
|
||||
size_t out_sz = *output_length;
|
||||
*output_length = 4 * ((input_length + 2) / 3);
|
||||
if (out_sz < *output_length || output == nullptr)
|
||||
return nullptr;
|
||||
|
||||
for (i = 0, j = 0; i < input_length; ) {
|
||||
uint8_t octet_a = i < input_length ? input[i++] : 0;
|
||||
uint8_t octet_b = i < input_length ? input[i++] : 0;
|
||||
uint8_t octet_c = i < input_length ? input[i++] : 0;
|
||||
|
||||
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||
|
||||
output[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
|
||||
output[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
|
||||
output[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
|
||||
output[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
|
||||
}
|
||||
|
||||
for (i = 0; i < mod_table[input_length % 3]; i++)
|
||||
output[*output_length - 1 - i] = '=';
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
uint8_t *base64_decode(const char *input, size_t input_length,
|
||||
uint8_t *output, size_t *output_length)
|
||||
{
|
||||
size_t i, j;
|
||||
uint8_t decoding_table[256];
|
||||
|
||||
uint8_t c;
|
||||
for (c = 0; c < 64; c++)
|
||||
decoding_table[static_cast<int>(encoding_table[c])] = c;
|
||||
|
||||
if (input_length % 4 != 0 || input_length < 2)
|
||||
return nullptr;
|
||||
|
||||
size_t out_sz = *output_length;
|
||||
*output_length = input_length / 4 * 3;
|
||||
if (input[input_length - 1] == '=')
|
||||
(*output_length)--;
|
||||
if (input[input_length - 2] == '=')
|
||||
(*output_length)--;
|
||||
|
||||
if (out_sz < *output_length || output == nullptr)
|
||||
return nullptr;
|
||||
|
||||
for (i = 0, j = 0; i < input_length;) {
|
||||
uint8_t sextet_a = input[i] == '=' ? 0 & i++
|
||||
: decoding_table[static_cast<int>(input[i++])];
|
||||
uint8_t sextet_b = input[i] == '=' ? 0 & i++
|
||||
: decoding_table[static_cast<int>(input[i++])];
|
||||
uint8_t sextet_c = input[i] == '=' ? 0 & i++
|
||||
: decoding_table[static_cast<int>(input[i++])];
|
||||
uint8_t sextet_d = input[i] == '=' ? 0 & i++
|
||||
: decoding_table[static_cast<int>(input[i++])];
|
||||
|
||||
uint32_t triple = (sextet_a << 3 * 6) +
|
||||
(sextet_b << 2 * 6) +
|
||||
(sextet_c << 1 * 6) +
|
||||
(sextet_d << 0 * 6);
|
||||
|
||||
if (j < *output_length)
|
||||
output[j++] = (triple >> 2 * 8) & 0xFF;
|
||||
if (j < *output_length)
|
||||
output[j++] = (triple >> 1 * 8) & 0xFF;
|
||||
if (j < *output_length)
|
||||
output[j++] = (triple >> 0 * 8) & 0xFF;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string
|
||||
base64_encode(const std::vector<uint8_t>::const_iterator begin,
|
||||
const std::vector<uint8_t>::const_iterator end)
|
||||
{
|
||||
size_t output_length = 4 * ((std::distance(begin, end) + 2) / 3);
|
||||
std::string out;
|
||||
out.resize(output_length);
|
||||
base64_encode(&(*begin), std::distance(begin, end),
|
||||
&(*out.begin()), &output_length);
|
||||
out.resize(output_length);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
base64_encode(const std::vector<unsigned char>& str)
|
||||
{
|
||||
std::string buffer(simdutf::base64_length_from_binary(str.size()), '\0');
|
||||
simdutf::binary_to_base64((const char*)str.data(), str.size(), buffer.data());
|
||||
return buffer;
|
||||
return base64_encode(str.cbegin(), str.cend());
|
||||
}
|
||||
|
||||
std::vector<unsigned char>
|
||||
base64_decode(const std::string& str)
|
||||
{
|
||||
std::vector<unsigned char> buffer(simdutf::maximal_binary_length_from_base64(str.data(), str.size()));
|
||||
simdutf::result r = simdutf::base64_to_binary(str.data(), str.size(), (char *)buffer.data());
|
||||
if(r.error) {
|
||||
// Decoding error, return an empty vector
|
||||
return std::vector<unsigned char>();
|
||||
} else {
|
||||
buffer.resize(r.count); // resize the buffer according to actual number of bytes
|
||||
}
|
||||
return buffer;
|
||||
size_t output_length = str.length() / 4 * 3 + 2;
|
||||
std::vector<uint8_t> output;
|
||||
output.resize(output_length);
|
||||
base64_decode(str.data(), str.size(), output.data(), &output_length);
|
||||
output.resize(output_length);
|
||||
return output;
|
||||
}
|
||||
+1
-1
@@ -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
@@ -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,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>
|
||||
*
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <process.h>
|
||||
#include <direct.h>
|
||||
#include <fcntl.h>
|
||||
#include <synchapi.h>
|
||||
|
||||
#define R_OK 4
|
||||
#define W_OK 2
|
||||
|
||||
Loaded 100 of 163 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user