mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-09 04:49:14 +00:00
Compare commits
48
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f5bec3af6 | ||
|
|
d07a9e6583 | ||
|
|
fd43a329e7 | ||
|
|
93b2e8d5b9 | ||
|
|
d66713d97e | ||
|
|
7af9868c47 | ||
|
|
05a524b038 | ||
|
|
57ed00579e | ||
|
|
9ffccb3956 | ||
|
|
d99324ebd4 | ||
|
|
933f6cbca1 | ||
|
|
d5d7d6483f | ||
|
|
cc09a39ade | ||
|
|
621b44c8e8 | ||
|
|
e1c088f2e4 | ||
|
|
a6e0e441ac | ||
|
|
dcc2ba3492 | ||
|
|
ccf00d6b09 | ||
|
|
d8250574fc | ||
|
|
0d698c76e8 | ||
|
|
e4e3b4e73b | ||
|
|
b26d622f5d | ||
|
|
78694751bd | ||
|
|
f9b90c5c1c | ||
|
|
56b848bf47 | ||
|
|
dd875230c3 | ||
|
|
de1d428e63 | ||
|
|
55e3a6514f | ||
|
|
f4bbef210c | ||
|
|
2c1470cef6 | ||
|
|
adb6aa57e6 | ||
|
|
acd0abdb70 | ||
|
|
b9c8f5e0fd | ||
|
|
18fedf431f | ||
|
|
fc6edb4d20 | ||
|
|
d1093c77a3 | ||
|
|
b543f1e3cb | ||
|
|
be210e27da | ||
|
|
f7243fca37 | ||
|
|
1f6efd5736 | ||
|
|
54fbad3a7e | ||
|
|
1315489a7b | ||
|
|
c189fa0e82 | ||
|
|
3eae03289e | ||
|
|
e5e5a45b91 | ||
|
|
7a71beb892 | ||
|
|
74a894229f | ||
|
|
c81c1f70c8 |
No files matched your search
@@ -2,12 +2,12 @@ name: C/C++ CI
|
||||
|
||||
env:
|
||||
LLHTTP_VERSION: "v9.2.1"
|
||||
RESTINIO_VERSION: "0.7.8.1"
|
||||
RESTINIO_VERSION: "0.7.10"
|
||||
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 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"
|
||||
DEBIAN13_DEPS: "git libtool 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"
|
||||
DEBIAN13_DEPS: "git libtool 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-cxx-dev libargon2-dev"
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
|
||||
@@ -23,11 +23,13 @@ jobs:
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
- name: restinio
|
||||
env:
|
||||
RESTINIO_VERSION: "0.7.10"
|
||||
run: |
|
||||
mkdir restinio && cd restinio
|
||||
wget https://github.com/Stiffstream/restinio/releases/download/v0.7.8.1/restinio-0.7.8.1.tar.bz2
|
||||
ls -l && tar -xjf restinio-0.7.8.1.tar.bz2
|
||||
cd restinio-0.7.8.1/dev
|
||||
wget "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2"
|
||||
ls -l && tar -xjf "restinio-${RESTINIO_VERSION}.tar.bz2"
|
||||
cd "restinio-${RESTINIO_VERSION}/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 .
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
|
||||
# Run locally with: pipx run cibuildwheel --platform linux python
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v4.1.1
|
||||
uses: pypa/cibuildwheel@v4.3.4
|
||||
with:
|
||||
package-dir: python
|
||||
|
||||
@@ -36,36 +36,28 @@ jobs:
|
||||
name: Build wheels on Windows
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCPKG_VERSION: "2026.06.01"
|
||||
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
|
||||
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg-binary-cache,readwrite
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Cache vcpkg installed packages
|
||||
id: cache-vcpkg
|
||||
- name: Set up vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgJsonGlob: vcpkg.json
|
||||
vcpkgConfigurationJsonGlob: vcpkg-configuration.json
|
||||
|
||||
- name: Cache vcpkg binary packages
|
||||
uses: actions/cache@v6
|
||||
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
|
||||
path: ${{ github.workspace }}/vcpkg-binary-cache
|
||||
key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-
|
||||
|
||||
- name: Build wheels
|
||||
run: |
|
||||
@@ -73,7 +65,7 @@ jobs:
|
||||
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 `
|
||||
"-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DBUILD_TESTING=OFF `
|
||||
-DOPENDHT_C=OFF `
|
||||
|
||||
@@ -309,12 +309,10 @@ jobs:
|
||||
name: Build Windows MSI Installer
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCPKG_VERSION: "2026.06.01"
|
||||
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
|
||||
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg-binary-cache,readwrite
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
@@ -323,6 +321,12 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgJsonGlob: vcpkg.json
|
||||
vcpkgConfigurationJsonGlob: vcpkg-configuration.json
|
||||
|
||||
- name: Set up MSVC developer environment
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
@@ -332,27 +336,14 @@ jobs:
|
||||
wix extension add --global WixToolset.UI.wixext/6.0.1
|
||||
shell: pwsh
|
||||
|
||||
- name: Cache vcpkg installed packages
|
||||
id: cache-vcpkg
|
||||
- name: Cache vcpkg binary packages
|
||||
uses: actions/cache@v6
|
||||
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
|
||||
path: ${{ github.workspace }}/vcpkg-binary-cache
|
||||
key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-
|
||||
|
||||
- name: Configure CMake for MSI
|
||||
shell: pwsh
|
||||
@@ -360,7 +351,7 @@ jobs:
|
||||
mkdir build -ErrorAction SilentlyContinue
|
||||
cmake -B build `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
"-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
|
||||
-DVCPKG_TARGET_TRIPLET=x64-windows `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
@@ -413,12 +404,10 @@ jobs:
|
||||
name: Build Windows dhtnode
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCPKG_VERSION: "2026.06.01"
|
||||
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
|
||||
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg-binary-cache,readwrite
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
@@ -427,33 +416,23 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgJsonGlob: vcpkg.json
|
||||
vcpkgConfigurationJsonGlob: vcpkg-configuration.json
|
||||
|
||||
- name: Set up MSVC developer environment
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Cache vcpkg static installed packages
|
||||
id: cache-vcpkg-static
|
||||
- name: Cache vcpkg binary packages
|
||||
uses: actions/cache@v6
|
||||
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') }}
|
||||
path: ${{ github.workspace }}/vcpkg-binary-cache
|
||||
key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
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
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-
|
||||
|
||||
- name: Configure CMake for Static Build
|
||||
shell: pwsh
|
||||
@@ -461,7 +440,7 @@ jobs:
|
||||
mkdir build_static -ErrorAction SilentlyContinue
|
||||
cmake -B build_static `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
"-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
|
||||
-DVCPKG_TARGET_TRIPLET=x64-windows-static-release `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
|
||||
@@ -9,18 +9,16 @@ on:
|
||||
branches: [ main, master ]
|
||||
|
||||
env:
|
||||
VCPKG_VERSION: "2026.06.01"
|
||||
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
|
||||
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg-binary-cache,readwrite
|
||||
|
||||
jobs:
|
||||
prepare-dependencies:
|
||||
name: Prepare Windows Dependencies
|
||||
runs-on: windows-latest
|
||||
outputs:
|
||||
vcpkg_cache_key: ${{ steps.generate_cache_key.outputs.key }}
|
||||
env:
|
||||
VCPKG_DEFAULT_TRIPLET: ${{ matrix.arch }}-windows
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x64]
|
||||
@@ -32,43 +30,31 @@ jobs:
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- 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
|
||||
- name: Cache vcpkg binary packages
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ steps.generate_cache_key.outputs.key }}
|
||||
path: ${{ github.workspace }}/vcpkg-binary-cache
|
||||
key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
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-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-
|
||||
|
||||
- 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
|
||||
- name: Set up vcpkg and install dependencies
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgJsonGlob: vcpkg.json
|
||||
vcpkgConfigurationJsonGlob: vcpkg-configuration.json
|
||||
runVcpkgInstall: true
|
||||
runVcpkgFormatString: >-
|
||||
[`install`, `--clean-after-build`, `--x-feature=test`,
|
||||
`--triplet`, `$[env.VCPKG_DEFAULT_TRIPLET]`,
|
||||
`--x-install-root`, `$[env.VCPKG_INSTALLED_DIR]`]
|
||||
|
||||
prepare-static-dependencies:
|
||||
name: Prepare Windows Static Dependencies
|
||||
runs-on: windows-latest
|
||||
outputs:
|
||||
vcpkg_static_cache_key: ${{ steps.generate_static_cache_key.outputs.key }}
|
||||
env:
|
||||
VCPKG_DEFAULT_TRIPLET: ${{ matrix.arch }}-windows-static-release
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x64]
|
||||
@@ -80,42 +66,32 @@ jobs:
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- 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
|
||||
- name: Cache vcpkg binary packages
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ steps.generate_static_cache_key.outputs.key }}
|
||||
path: ${{ github.workspace }}/vcpkg-binary-cache
|
||||
key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
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-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-
|
||||
|
||||
- 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
|
||||
- name: Set up vcpkg and install dependencies
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgJsonGlob: vcpkg.json
|
||||
vcpkgConfigurationJsonGlob: vcpkg-configuration.json
|
||||
runVcpkgInstall: true
|
||||
runVcpkgFormatString: >-
|
||||
[`install`, `--clean-after-build`, `--x-feature=test`,
|
||||
`--triplet`, `$[env.VCPKG_DEFAULT_TRIPLET]`,
|
||||
`--x-install-root`, `$[env.VCPKG_INSTALLED_DIR]`]
|
||||
|
||||
build-windows:
|
||||
name: Windows MSVC Build
|
||||
runs-on: windows-latest
|
||||
needs: prepare-dependencies
|
||||
env:
|
||||
VCPKG_DEFAULT_TRIPLET: ${{ matrix.arch }}-windows
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -127,20 +103,23 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Set up vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgJsonGlob: vcpkg.json
|
||||
vcpkgConfigurationJsonGlob: vcpkg-configuration.json
|
||||
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Restore vcpkg installed packages
|
||||
id: cache-vcpkg-restore
|
||||
- name: Restore vcpkg binary packages
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ needs.prepare-dependencies.outputs.vcpkg_cache_key }}
|
||||
path: ${{ github.workspace }}/vcpkg-binary-cache
|
||||
key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
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-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-
|
||||
|
||||
- name: Configure CMake
|
||||
shell: pwsh
|
||||
@@ -148,7 +127,7 @@ jobs:
|
||||
mkdir build -ErrorAction SilentlyContinue
|
||||
cmake -B build `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
"-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
|
||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
@@ -194,6 +173,8 @@ jobs:
|
||||
name: Windows Static MSVC Build
|
||||
runs-on: windows-latest
|
||||
needs: prepare-static-dependencies
|
||||
env:
|
||||
VCPKG_DEFAULT_TRIPLET: ${{ matrix.arch }}-windows-static-release
|
||||
strategy:
|
||||
matrix:
|
||||
build_type: [Release]
|
||||
@@ -204,20 +185,23 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Set up vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgJsonGlob: vcpkg.json
|
||||
vcpkgConfigurationJsonGlob: vcpkg-configuration.json
|
||||
|
||||
- name: Set up MSVC
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Restore vcpkg static installed packages
|
||||
id: cache-vcpkg-static-restore
|
||||
- name: Restore vcpkg binary packages
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: |
|
||||
${{ env.VCPKG_INSTALLED_DIR }}
|
||||
${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: ${{ needs.prepare-static-dependencies.outputs.vcpkg_static_cache_key }}
|
||||
path: ${{ github.workspace }}/vcpkg-binary-cache
|
||||
key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
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-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-
|
||||
${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-
|
||||
|
||||
- name: Configure CMake for Static Build
|
||||
shell: pwsh
|
||||
@@ -225,7 +209,7 @@ jobs:
|
||||
mkdir build -ErrorAction SilentlyContinue
|
||||
cmake -B build `
|
||||
-S . `
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_INSTALLATION_ROOT }}/scripts/buildsystems/vcpkg.cmake `
|
||||
"-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
|
||||
-DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static-release `
|
||||
-DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} `
|
||||
-DVCPKG_MANIFEST_FEATURES=test `
|
||||
@@ -304,7 +288,7 @@ jobs:
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
LLHTTP_VERSION: "v9.2.1"
|
||||
RESTINIO_VERSION: "0.7.6"
|
||||
RESTINIO_VERSION: "0.7.10"
|
||||
EXPECTED_LITE_URL: "https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp"
|
||||
run: |
|
||||
MSYS2_SYSROOT=$(cygpath -u "$MSYSTEM_PREFIX")
|
||||
|
||||
@@ -121,10 +121,12 @@ 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:
|
||||
1. Install [VCPKG](https://github.com/microsoft/vcpkg) 2026.10.16 and required dependencies:
|
||||
```ps1
|
||||
git clone https://github.com/microsoft/vcpkg.git
|
||||
cd vcpkg; .\bootstrap-vcpkg.bat
|
||||
cd vcpkg
|
||||
git checkout 9eec002df1cd109f8f104cd966a763daf9751489
|
||||
.\bootstrap-vcpkg.bat
|
||||
```
|
||||
|
||||
2. Use CMake preset for vcpkg:
|
||||
@@ -133,3 +135,19 @@ cd opendht
|
||||
cmake --preset=vcpkg_manifest .
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
### CI
|
||||
|
||||
Windows CI uses [lukka/run-vcpkg](https://github.com/lukka/run-vcpkg) to acquire
|
||||
and bootstrap the revision pinned by `default-registry.baseline` in
|
||||
`vcpkg-configuration.json`. CMake uses the action's `VCPKG_ROOT` and installs
|
||||
manifest dependencies on every run. Dependency-preparation jobs warm the binary
|
||||
cache before the Windows build matrix starts.
|
||||
|
||||
Only ABI-keyed binary package archives are cached, not installed trees. The
|
||||
supported [files provider](https://learn.microsoft.com/en-us/vcpkg/reference/binarycaching#files-provider)
|
||||
is persisted with `actions/cache`; it does not use the removed `x-gha` provider
|
||||
or require package-feed credentials. Cache keys include the target triplet,
|
||||
manifests, overlay ports, run ID, and attempt, with restore prefixes for reuse.
|
||||
Each run can save newly built archives without overwriting an immutable cache;
|
||||
vcpkg validates package ABIs before reuse.
|
||||
+7
-1
@@ -10,7 +10,7 @@ if(POLICY CMP0167)
|
||||
endif()
|
||||
|
||||
set (opendht_VERSION_MAJOR 4)
|
||||
set (opendht_VERSION_MINOR 3.0)
|
||||
set (opendht_VERSION_MINOR 4.2)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
@@ -875,6 +875,12 @@ if (BUILD_TESTING)
|
||||
tests/test_valuecache.h
|
||||
tests/test_valuecache.cpp
|
||||
)
|
||||
if (OPENDHT_INDEX)
|
||||
list (APPEND test_FILES
|
||||
tests/test_pht.h
|
||||
tests/test_pht.cpp
|
||||
)
|
||||
endif()
|
||||
if (OPENDHT_PROXY_CLIENT)
|
||||
list (APPEND test_FILES
|
||||
tests/test_dhtproxy_client.h
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:24.04
|
||||
FROM ubuntu:26.04
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
|
||||
@@ -20,11 +20,12 @@ RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
ARG RESTINIO_VERSION=0.7.10
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/Stiffstream/restinio/releases/download/v0.7.8.1/restinio-0.7.8.1.tar.bz2 \
|
||||
&& ls -l && tar -xjf restinio-0.7.8.1.tar.bz2 \
|
||||
&& cd restinio-0.7.8.1/dev \
|
||||
&& wget "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& ls -l && tar -xjf "restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& cd "restinio-${RESTINIO_VERSION}/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,4 +1,4 @@
|
||||
FROM alpine:3.23
|
||||
FROM alpine:3.24
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source=https://github.com/savoirfairelinux/opendht
|
||||
|
||||
@@ -15,11 +15,12 @@ RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
ARG RESTINIO_VERSION=0.7.10
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/Stiffstream/restinio/releases/download/v0.7.8.1/restinio-0.7.8.1.tar.bz2 \
|
||||
&& ls -l && tar -xjf restinio-0.7.8.1.tar.bz2 \
|
||||
&& cd restinio-0.7.8.1/dev \
|
||||
&& wget "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& ls -l && tar -xjf "restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& cd "restinio-${RESTINIO_VERSION}/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 . \
|
||||
|
||||
@@ -15,11 +15,12 @@ RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
ARG RESTINIO_VERSION=0.7.10
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/Stiffstream/restinio/releases/download/v0.7.8.1/restinio-0.7.8.1.tar.bz2 \
|
||||
&& ls -l && tar -xjf restinio-0.7.8.1.tar.bz2 \
|
||||
&& cd restinio-0.7.8.1/dev \
|
||||
&& wget "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& ls -l && tar -xjf "restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& cd "restinio-${RESTINIO_VERSION}/dev" \
|
||||
&& cmake -GNinja -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 . \
|
||||
|
||||
@@ -22,11 +22,12 @@ RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
ARG RESTINIO_VERSION=0.7.10
|
||||
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${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& ls -l && tar -xjf "restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& cd "restinio-${RESTINIO_VERSION}/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 . \
|
||||
|
||||
@@ -26,11 +26,12 @@ RUN mkdir /usr/include/nonstd \
|
||||
&& wget https://raw.githubusercontent.com/martinmoene/expected-lite/master/include/nonstd/expected.hpp \
|
||||
-O /usr/include/nonstd/expected.hpp
|
||||
|
||||
ARG RESTINIO_VERSION=0.7.10
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/Stiffstream/restinio/releases/download/v0.7.8.1/restinio-0.7.8.1.tar.bz2 \
|
||||
&& ls -l && tar -xjf restinio-0.7.8.1.tar.bz2 \
|
||||
&& cd restinio-0.7.8.1/dev \
|
||||
&& wget "https://github.com/Stiffstream/restinio/releases/download/v${RESTINIO_VERSION}/restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& ls -l && tar -xjf "restinio-${RESTINIO_VERSION}.tar.bz2" \
|
||||
&& cd "restinio-${RESTINIO_VERSION}/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 . \
|
||||
|
||||
@@ -532,6 +532,8 @@ public:
|
||||
|
||||
/**
|
||||
* Insert a push notification to process for OpenDHT
|
||||
* Returns an immediately ready future with IgnoredStopped if the runner is idle,
|
||||
* or IgnoredDisabled if push notification support is disabled at build time.
|
||||
*/
|
||||
std::future<PushNotificationResult> pushNotificationReceived(const std::map<std::string, std::string>& data);
|
||||
|
||||
|
||||
@@ -123,28 +123,19 @@ ee *
|
||||
*/
|
||||
static inline unsigned commonBits(const Prefix& p1, const Prefix& p2)
|
||||
{
|
||||
unsigned i, j;
|
||||
uint8_t x;
|
||||
/* size_ counts bits, so the comparison walks bits: reading it as a
|
||||
byte count would run past the end of the shorter content. */
|
||||
auto longest_prefix_size = std::min(p1.size_, p2.size_);
|
||||
|
||||
for (i = 0; i < longest_prefix_size; i++) {
|
||||
if (p1.content_.data()[i] != p2.content_.data()[i] or not p1.isFlagActive(i) or not p2.isFlagActive(i)) {
|
||||
unsigned common = 0;
|
||||
while (common < longest_prefix_size) {
|
||||
if (not p1.isFlagActive(common) or not p2.isFlagActive(common)
|
||||
or p1.isContentBitActive(common) != p2.isContentBitActive(common))
|
||||
break;
|
||||
}
|
||||
common++;
|
||||
}
|
||||
|
||||
if (i == longest_prefix_size)
|
||||
return 8 * longest_prefix_size;
|
||||
|
||||
x = p1.content_.data()[i] ^ p2.content_.data()[i];
|
||||
|
||||
j = 0;
|
||||
while ((x & 0x80) == 0) {
|
||||
x <<= 1;
|
||||
j++;
|
||||
}
|
||||
|
||||
return 8 * i + j;
|
||||
return common;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,7 +196,7 @@ private:
|
||||
for (auto i = copy.size(); i < size; i++)
|
||||
copy.push_back(0);
|
||||
|
||||
swapBit(copy, size_ + 1);
|
||||
swapBit(copy, size_);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -242,8 +233,9 @@ private:
|
||||
if (bit >= b.size() * 8)
|
||||
throw std::out_of_range("bit larger than prefix size.");
|
||||
|
||||
size_t offset_bit = (8 - bit) % 8;
|
||||
b[bit / 8] ^= (1 << offset_bit);
|
||||
/* Bit 0 is the most significant one of the first byte, as
|
||||
isActiveBit reads it. */
|
||||
b[bit / 8] ^= (1 << (7 - (bit % 8)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+19
-1
@@ -5,7 +5,7 @@ project(
|
||||
'cython',
|
||||
license: 'MIT',
|
||||
license_files: 'LICENSE',
|
||||
version: '4.3.0',
|
||||
version: '4.4.2',
|
||||
meson_version: '>=1.1.0',
|
||||
default_options: ['cpp_std=c++20', 'warning_level=3'],
|
||||
)
|
||||
@@ -292,6 +292,24 @@ if get_option('tests').enabled()
|
||||
)
|
||||
test('NetworkEngine', test_networkengine)
|
||||
|
||||
test_opcache = executable(
|
||||
'test_opcache',
|
||||
'tests/test_opcache.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_inc,
|
||||
dependencies: [opendht_dep, cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test('OpCache', test_opcache)
|
||||
|
||||
test_valuecache = executable(
|
||||
'test_valuecache',
|
||||
'tests/test_valuecache.cpp',
|
||||
'tests/tests_runner.cpp',
|
||||
include_directories: opendht_inc,
|
||||
dependencies: [opendht_dep, cppunit, jsoncpp, fmt, openssl, msgpack],
|
||||
)
|
||||
test('ValueCache', test_valuecache)
|
||||
|
||||
test_crypto = executable(
|
||||
'test_crypto',
|
||||
'tests/test_crypto.cpp',
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
diff --git a/SMP/libgnutls.vcxproj.filters b/SMP/libgnutls.vcxproj.filters
|
||||
index b182189..91ee160 100644
|
||||
--- a/SMP/libgnutls.vcxproj.filters
|
||||
+++ b/SMP/libgnutls.vcxproj.filters
|
||||
@@ -103,9 +103,6 @@
|
||||
<Filter Include="Header Files\lib\inih">
|
||||
<UniqueIdentifier>{ae0c3eeb-53df-4c72-a85a-6b46de35e7ba}</UniqueIdentifier>
|
||||
</Filter>
|
||||
- <Filter Include="Source Files\libtasn1">
|
||||
- <UniqueIdentifier>{32be60b7-8c65-486e-9df5-7e529443cf07}</UniqueIdentifier>
|
||||
- </Filter>
|
||||
<Filter Include="Source Files\lib\nettle\gost">
|
||||
<UniqueIdentifier>{1f3549a8-3c3d-475f-8fd6-20451d336464}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -1553,30 +1550,6 @@
|
||||
<ClCompile Include="..\lib\nettle\sysrng-bcrypt.c">
|
||||
<Filter>Source Files\lib\nettle</Filter>
|
||||
</ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\coding.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\decoding.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\element.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\errors.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\gstr.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\parser_aux.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\structure.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\version.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
<ClCompile Include="..\lib\nettle\gost\acpkm.c">
|
||||
<Filter>Source Files\lib\nettle\gost</Filter>
|
||||
</ClCompile>
|
||||
diff --git a/SMP/libgnutls_files.props b/SMP/libgnutls_files.props
|
||||
index adcb074..2317c2a 100644
|
||||
--- a/SMP/libgnutls_files.props
|
||||
+++ b/SMP/libgnutls_files.props
|
||||
@@ -179,13 +179,6 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="lib\gnutls_asn1_tab.c" />
|
||||
<ClCompile Include="lib\pkix_asn1_tab.c" />
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\coding.c" />
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\decoding.c" />
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\element.c" />
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\gstr.c" />
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\parser_aux.c" />
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\structure.c" />
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\version.c" />
|
||||
<ClCompile Include="..\gnulib\lib\c-strcasecmp.c" />
|
||||
<ClCompile Include="..\gnulib\lib\c-strncasecmp.c" />
|
||||
<ClCompile Include="..\gnulib\lib\cloexec.c" />
|
||||
@@ -572,9 +565,6 @@
|
||||
<ClCompile Include="..\gnulib\lib\readdir.c">
|
||||
<ForcedIncludeFiles>dirent-private.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\errors.c">
|
||||
- <ObjectFileName>$(IntDir)\tasn1_$(filename).obj</ObjectFileName>
|
||||
- </ClCompile>
|
||||
<ClCompile Include="..\lib\algorithms\ecc.c">
|
||||
<ObjectFileName>$(IntDir)\alg_%(Filename).obj</ObjectFileName>
|
||||
</ClCompile>
|
||||
diff --git a/SMP/libgnutls_winrt.vcxproj.filters b/SMP/libgnutls_winrt.vcxproj.filters
|
||||
index 014a408..ae5ecff 100644
|
||||
--- a/SMP/libgnutls_winrt.vcxproj.filters
|
||||
+++ b/SMP/libgnutls_winrt.vcxproj.filters
|
||||
@@ -103,9 +103,6 @@
|
||||
<Filter Include="Header Files\lib\inih">
|
||||
<UniqueIdentifier>{ae0c3eeb-53df-4c72-a85a-6b46de35e7ba}</UniqueIdentifier>
|
||||
</Filter>
|
||||
- <Filter Include="Source Files\libtasn1">
|
||||
- <UniqueIdentifier>{32be60b7-8c65-486e-9df5-7e529443cf07}</UniqueIdentifier>
|
||||
- </Filter>
|
||||
<Filter Include="Header Files\lib\nettle\gost">
|
||||
<UniqueIdentifier>{4fada990-3138-4089-a6c7-ae722a0e7fe9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -1553,30 +1550,6 @@
|
||||
<ClCompile Include="..\lib\nettle\sysrng-bcrypt.c">
|
||||
<Filter>Source Files\lib\nettle</Filter>
|
||||
</ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\coding.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\decoding.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\element.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\errors.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\gstr.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\parser_aux.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\structure.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
- <ClCompile Include="..\devel\libtasn1\lib\version.c">
|
||||
- <Filter>Source Files\libtasn1</Filter>
|
||||
- </ClCompile>
|
||||
<ClCompile Include="..\lib\accelerated\afalg.c">
|
||||
<Filter>Source Files\lib\accelerated</Filter>
|
||||
</ClCompile>
|
||||
@@ -0,0 +1,12 @@
|
||||
--- a/lib/gnutls.pc.in
|
||||
+++ b/lib/gnutls.pc.in
|
||||
@@ -18,7 +18,7 @@
|
||||
Name: GnuTLS
|
||||
Description: Transport Security Layer implementation for the GNU system
|
||||
URL: https://www.gnutls.org/
|
||||
Version: @VERSION@
|
||||
-Libs: -L${libdir} -lgnutls
|
||||
+Libs: -L${libdir} @GNUTLS_LIBS@
|
||||
Libs.private: @LIBINTL@ @LIBSOCKET@ @INET_PTON_LIB@ @LIBPTHREAD@ @LIB_SELECT@ @TSS_LIBS@ @GMP_LIBS@ @LIBUNISTRING@ @LIBATOMIC_LIBS@ @GNUTLS_LIBS_PRIVATE@
|
||||
@GNUTLS_REQUIRES_PRIVATE@
|
||||
Cflags: -I${includedir}
|
||||
@@ -0,0 +1,187 @@
|
||||
set(GNULIB_REF "1cc0125a28cba4e8503d853bf99b854fe4dd454c")
|
||||
|
||||
vcpkg_from_github(
|
||||
OUT_SOURCE_PATH SOURCE_PATH
|
||||
REPO savoirfairelinux/gnutls
|
||||
REF 300b0c721fc1809f3d191b7f9e289c0267eabd01
|
||||
SHA512 8a74fbf0343e658f6321da0f28bcc05c580fb7b950f6edfb6a8fdaad6d814456ed2dbf94e8dd330c7740c836f01e04552e649d529ee29424c3641861c41344bf
|
||||
HEAD_REF fix/ci-msvc
|
||||
PATCHES
|
||||
external-libtasn1.patch
|
||||
pkgconfig.patch
|
||||
)
|
||||
|
||||
file(REMOVE_RECURSE "${SOURCE_PATH}/devel/perlasm")
|
||||
|
||||
vcpkg_download_distfile(
|
||||
GNULIB_SNAPSHOT
|
||||
URLS "https://gitlab.com/libidn/gnulib-mirror/-/archive/${GNULIB_REF}/gnulib-mirror-${GNULIB_REF}.tar.gz"
|
||||
FILENAME "gnulib-mirror-${GNULIB_REF}.tar.gz"
|
||||
SHA512 340539bd7b8e30b1e0f81a15fb207960e9ae3c4ef515f39f1d1bdb43ed52ad94a29c6a6ce8bbca3484ba5392e1dae7447c2f6b58124209614e884345e13914f5
|
||||
)
|
||||
|
||||
vcpkg_extract_source_archive(
|
||||
GNULIB_SOURCE_PATH
|
||||
ARCHIVE "${GNULIB_SNAPSHOT}"
|
||||
SOURCE_BASE ${GNULIB_REF}
|
||||
)
|
||||
|
||||
file(REMOVE_RECURSE "${SOURCE_PATH}/gnulib")
|
||||
file(RENAME "${GNULIB_SOURCE_PATH}" "${SOURCE_PATH}/gnulib")
|
||||
|
||||
include("${CURRENT_HOST_INSTALLED_DIR}/share/yasm-tool-helper/yasm-tool-helper.cmake")
|
||||
yasm_tool_helper(OUT_VAR YASM)
|
||||
file(TO_NATIVE_PATH "${YASM}" YASM)
|
||||
|
||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
|
||||
set(CONFIGURATION_RELEASE ReleaseDLL)
|
||||
set(CONFIGURATION_DEBUG DebugDLL)
|
||||
else()
|
||||
set(CONFIGURATION_RELEASE Release)
|
||||
set(CONFIGURATION_DEBUG Debug)
|
||||
endif()
|
||||
|
||||
if(VCPKG_TARGET_IS_UWP)
|
||||
string(APPEND CONFIGURATION_RELEASE WinRT)
|
||||
string(APPEND CONFIGURATION_DEBUG WinRT)
|
||||
endif()
|
||||
|
||||
set(_gnutlsproject "${SOURCE_PATH}/SMP/libgnutls.vcxproj")
|
||||
file(READ "${_gnutlsproject}" _contents)
|
||||
string(REPLACE [[<Import Project="$(VCTargetsPath)\BuildCustomizations\yasm.props" />]]
|
||||
"<Import Project=\"${CURRENT_HOST_INSTALLED_DIR}/share/vs-yasm/yasm.props\" />"
|
||||
_contents "${_contents}")
|
||||
string(REPLACE [[<Import Project="$(VCTargetsPath)\BuildCustomizations\yasm.targets" />]]
|
||||
"<Import Project=\"${CURRENT_HOST_INSTALLED_DIR}/share/vs-yasm/yasm.targets\" />"
|
||||
_contents "${_contents}")
|
||||
string(REGEX REPLACE "${VCPKG_ROOT_DIR}/installed/[^/]+/share" "${CURRENT_HOST_INSTALLED_DIR}/share" _contents "${_contents}") # Above already
|
||||
file(WRITE "${_gnutlsproject}" "${_contents}")
|
||||
|
||||
if(VCPKG_CRT_LINKAGE STREQUAL "static")
|
||||
set(RuntimeLibraryExt "")
|
||||
else()
|
||||
set(RuntimeLibraryExt "DLL")
|
||||
endif()
|
||||
|
||||
# patch output library file path and name
|
||||
foreach(PROPS IN ITEMS
|
||||
"${SOURCE_PATH}/SMP/smp_deps.props"
|
||||
"${SOURCE_PATH}/SMP/smp_winrt_deps.props")
|
||||
vcpkg_replace_string(
|
||||
"${PROPS}"
|
||||
[=[_winrt</TargetName>]=]
|
||||
[=[</TargetName>]=]
|
||||
IGNORE_UNCHANGED
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${PROPS}"
|
||||
[=[<TargetName>lib$(RootNamespace)]=]
|
||||
[=[<TargetName>$(RootNamespace)]=]
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# patch hogweed, gmp, nettle, zlib libraries file names; inject RuntimeLibrary property to control CRT linkage
|
||||
foreach(VCXPROJ IN ITEMS
|
||||
"${SOURCE_PATH}/SMP/libgnutls.vcxproj"
|
||||
"${SOURCE_PATH}/SMP/libgnutls_winrt.vcxproj")
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"_winrt.lib"
|
||||
".lib"
|
||||
IGNORE_UNCHANGED
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"libhogweed"
|
||||
"hogweed"
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"hogweedd"
|
||||
"hogweed"
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"libgmp"
|
||||
"gmp"
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"gmpd"
|
||||
"gmp"
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"libnettle"
|
||||
"nettle"
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"nettled"
|
||||
"nettle"
|
||||
)
|
||||
set(zlib_basename "zlib")
|
||||
if(EXISTS "${CURRENT_INSTALLED_DIR}/lib/zs.lib")
|
||||
set(zlib_basename "zs")
|
||||
elseif(EXISTS "${CURRENT_INSTALLED_DIR}/lib/z.lib")
|
||||
set(zlib_basename "z")
|
||||
endif()
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"libzlib"
|
||||
"${zlib_basename}"
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
"zlib"
|
||||
"${zlib_basename}"
|
||||
)
|
||||
vcpkg_replace_string(
|
||||
"${VCXPROJ}"
|
||||
[=[</DisableSpecificWarnings>]=]
|
||||
[=[</DisableSpecificWarnings><ForcedIncludeFiles>gnutls_msvc_fixes.h;%(ForcedIncludeFiles)</ForcedIncludeFiles><RuntimeLibrary>$(RuntimeLibrary)</RuntimeLibrary>]=]
|
||||
)
|
||||
endforeach()
|
||||
|
||||
vcpkg_install_msbuild(
|
||||
USE_VCPKG_INTEGRATION
|
||||
SOURCE_PATH "${SOURCE_PATH}"
|
||||
PROJECT_SUBPATH SMP/libgnutls.sln
|
||||
PLATFORM ${TRIPLET_SYSTEM_ARCH}
|
||||
LICENSE_SUBPATH LICENSE
|
||||
RELEASE_CONFIGURATION ${CONFIGURATION_RELEASE}
|
||||
DEBUG_CONFIGURATION ${CONFIGURATION_DEBUG}
|
||||
SKIP_CLEAN
|
||||
OPTIONS /p:YasmPath="${YASM}" /p:OutDir=..\\msvc
|
||||
OPTIONS_DEBUG /p:RuntimeLibrary=MultiThreadedDebug${RuntimeLibraryExt}
|
||||
OPTIONS_RELEASE /p:RuntimeLibrary=MultiThreaded${RuntimeLibraryExt}
|
||||
)
|
||||
|
||||
get_filename_component(SOURCE_PATH_SUFFIX "${SOURCE_PATH}" NAME)
|
||||
if(VCPKG_TARGET_IS_UWP)
|
||||
set(WINRT_SUBFOLDER libgnutls_winrt)
|
||||
endif()
|
||||
file(INSTALL "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/${SOURCE_PATH_SUFFIX}/msvc/${WINRT_SUBFOLDER}/include" DESTINATION "${CURRENT_PACKAGES_DIR}")
|
||||
|
||||
set(GNUTLS_REQUIRES_PRIVATE "Requires.private: gmp, nettle, hogweed, libtasn1, zlib")
|
||||
set(GNUTLS_LIBS_PRIVATE "-lcrypt32 -lws2_32 -lkernel32 -lncrypt")
|
||||
|
||||
set(prefix "${CURRENT_INSTALLED_DIR}")
|
||||
set(exec_prefix "\${prefix}")
|
||||
set(libdir "\${prefix}/lib")
|
||||
set(includedir "\${prefix}/include")
|
||||
set(GNUTLS_LIBS "-lgnutls")
|
||||
configure_file("${SOURCE_PATH}/lib/gnutls.pc.in" "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/gnutls.pc" @ONLY)
|
||||
|
||||
if(NOT VCPKG_BUILD_TYPE)
|
||||
set(prefix "${CURRENT_INSTALLED_DIR}/debug")
|
||||
set(exec_prefix "\${prefix}")
|
||||
set(libdir "\${prefix}/lib")
|
||||
set(includedir "\${prefix}/../include")
|
||||
set(GNUTLS_LIBS "-lgnutlsd")
|
||||
configure_file("${SOURCE_PATH}/lib/gnutls.pc.in" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/gnutls.pc" @ONLY)
|
||||
endif()
|
||||
|
||||
vcpkg_fixup_pkgconfig()
|
||||
vcpkg_copy_pdbs()
|
||||
file(COPY "${CURRENT_PORT_DIR}/vcpkg-cmake-wrapper.cmake" DESTINATION "${CURRENT_PACKAGES_DIR}/share/gnutls")
|
||||
@@ -0,0 +1,2 @@
|
||||
find_library(GNUTLS_LIBRARY NAMES gnutls gnutlsd NAMES_PER_DIR)
|
||||
_find_package(${ARGS})
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "shiftmedia-libgnutls",
|
||||
"version": "3.8.13",
|
||||
"port-version": 0,
|
||||
"description": "GnuTLS fork maintained by Savoir-faire Linux with native Visual Studio project build tools.",
|
||||
"homepage": "https://github.com/savoirfairelinux/gnutls",
|
||||
"license": "LGPL-2.1-only",
|
||||
"supports": "windows & !arm & !mingw & !xbox",
|
||||
"dependencies": [
|
||||
"gmp",
|
||||
"libtasn1",
|
||||
"nettle",
|
||||
{
|
||||
"name": "vs-yasm",
|
||||
"host": true
|
||||
},
|
||||
{
|
||||
"name": "yasm-tool-helper",
|
||||
"host": true
|
||||
},
|
||||
"zlib"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import runpy
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import netifaces
|
||||
|
||||
|
||||
class NodeClusterTester(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
script = Path(__file__).resolve().parents[1] / 'tools' / 'dhtcluster.py'
|
||||
with patch.dict('sys.modules', {'opendht': Mock()}):
|
||||
cls.NodeCluster = runpy.run_path(str(script))['NodeCluster']
|
||||
|
||||
def test_find_ip_interface(self):
|
||||
addresses = {
|
||||
netifaces.AF_INET: [{'addr': '127.0.0.1'}],
|
||||
netifaces.AF_INET6: [{'addr': '::1'}],
|
||||
}
|
||||
with patch('netifaces.ifaddresses', return_value=addresses) as ifaddresses:
|
||||
self.assertEqual(self.NodeCluster.find_ip('lo'), ('127.0.0.1', '::1'))
|
||||
self.assertTrue(ifaddresses.called)
|
||||
self.assertTrue(all(call.args == ('lo',) for call in ifaddresses.call_args_list))
|
||||
|
||||
def test_find_ip_any(self):
|
||||
with patch('netifaces.ifaddresses') as ifaddresses:
|
||||
for iface in (None, '', 'any'):
|
||||
with self.subTest(iface=iface):
|
||||
self.assertEqual(self.NodeCluster.find_ip(iface), ('0.0.0.0', '::0'))
|
||||
ifaddresses.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -9,6 +9,7 @@ import argparse
|
||||
import logging
|
||||
import logging.handlers
|
||||
|
||||
import netifaces
|
||||
import opendht as dht
|
||||
|
||||
logger = logging.getLogger('dhtcluster')
|
||||
|
||||
+1
-32
@@ -1659,24 +1659,8 @@ OcspResponse::toString(const bool compact) const
|
||||
gnutls_ocsp_cert_status_t
|
||||
OcspResponse::getCertificateStatus() const
|
||||
{
|
||||
int ret;
|
||||
unsigned int status;
|
||||
// MSVC/vcpkg GnuTLS cast workaround
|
||||
#if _WIN32 && (GNUTLS_VERSION_NUMBER == 0x030807)
|
||||
ret = gnutls_ocsp_resp_get_single(response,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
reinterpret_cast<gnutls_ocsp_cert_status_t*>(&status),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
#else
|
||||
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status, NULL, NULL, NULL, NULL);
|
||||
#endif
|
||||
int ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status, NULL, NULL, NULL, NULL);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
return (gnutls_ocsp_cert_status_t) status;
|
||||
@@ -1735,22 +1719,7 @@ OcspResponse::verifyDirect(const Certificate& crt, const Blob& nonce)
|
||||
|
||||
// Check certificate revocation status
|
||||
unsigned int status_ocsp;
|
||||
// MSVC/vcpkg GnuTLS cast workaround
|
||||
#if _WIN32 && (GNUTLS_VERSION_NUMBER == 0x030807)
|
||||
ret = gnutls_ocsp_resp_get_single(response,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
reinterpret_cast<gnutls_ocsp_cert_status_t*>(&status_ocsp),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
#else
|
||||
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status_ocsp, NULL, NULL, NULL, NULL);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
return (gnutls_ocsp_cert_status_t) status_ocsp;
|
||||
|
||||
@@ -1239,6 +1239,10 @@ DhtRunner::pushNotificationReceived([[maybe_unused]] const std::map<std::string,
|
||||
auto ret_token = std::make_shared<std::promise<PushNotificationResult>>();
|
||||
auto future = ret_token->get_future();
|
||||
std::lock_guard lck(storage_mtx);
|
||||
if (running == State::Idle) {
|
||||
ret_token->set_value(PushNotificationResult::IgnoredStopped);
|
||||
return future;
|
||||
}
|
||||
pending_ops_prio.emplace([ret_token, this, data](SecureDht&) {
|
||||
if (dht_)
|
||||
ret_token->set_value(dht_->pushNotificationReceived(data));
|
||||
|
||||
+4
-2
@@ -39,8 +39,10 @@ OpValueCache::onValuesExpired(const std::vector<Sp<Value>>& vals, const system_c
|
||||
if (vit != values.end()) {
|
||||
if (vit->second.updated > t)
|
||||
continue;
|
||||
if (v->seq < vit->second.data->seq)
|
||||
continue; // source held an older version, not counted
|
||||
// Mirror onValuesAdded: a version that was never counted (different
|
||||
// content, not a newer seq) must not decrement the refcount
|
||||
if (*v != *vit->second.data and v->seq <= vit->second.data->seq)
|
||||
continue;
|
||||
|
||||
vit->second.updated = t;
|
||||
vit->second.refCount--;
|
||||
|
||||
+1
-1
@@ -189,7 +189,7 @@ private:
|
||||
v->second.created = now;
|
||||
v->second.expiration = now + te;
|
||||
v->second.typeExpiration = te;
|
||||
if (value->seq > v->second.data->seq) {
|
||||
if (*value != *v->second.data and value->seq > v->second.data->seq) {
|
||||
// edited value (same rule as OpValueCache): emit as add
|
||||
v->second.data = value;
|
||||
nvals.emplace_back(value);
|
||||
|
||||
+61
-47
@@ -16,6 +16,21 @@ using namespace std::chrono_literals;
|
||||
namespace test {
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(DhtProxyTester);
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
namespace {
|
||||
// The result is produced on the DHT thread, which may be blocked in a listen
|
||||
// callback waiting for the same mutex: never hold it while waiting.
|
||||
dht::PushNotificationResult
|
||||
sendPush(dht::DhtRunner& node, const std::map<std::string, std::string>& data, std::unique_lock<std::mutex>& lk)
|
||||
{
|
||||
lk.unlock();
|
||||
auto ret = node.pushNotificationReceived(data).get();
|
||||
lk.lock();
|
||||
return ret;
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
void
|
||||
DhtProxyTester::setUp()
|
||||
{
|
||||
@@ -332,7 +347,7 @@ DhtProxyTester::testPushListenValueEdit()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
|
||||
// Wait for first add callback
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] {
|
||||
@@ -357,7 +372,7 @@ DhtProxyTester::testPushListenValueEdit()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
|
||||
// Wait for the second add
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] {
|
||||
@@ -389,7 +404,7 @@ DhtProxyTester::testPushListenValueEdit()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
CPPUNIT_ASSERT(nodeClient.pushNotificationReceived(push_data).get() == dht::PushNotificationResult::ValuesExpired);
|
||||
CPPUNIT_ASSERT(sendPush(nodeClient, push_data, lk) == dht::PushNotificationResult::ValuesExpired);
|
||||
|
||||
// Wait for the expire callback
|
||||
CPPUNIT_ASSERT_MESSAGE("Should receive expire callback via push", cv.wait_for(lk, 10s, [&] {
|
||||
@@ -541,7 +556,7 @@ DhtProxyTester::testPushNotification()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
CPPUNIT_ASSERT(nodeClient.pushNotificationReceived(push_data).get() == dht::PushNotificationResult::Values);
|
||||
CPPUNIT_ASSERT(sendPush(nodeClient, push_data, lk) == dht::PushNotificationResult::Values);
|
||||
|
||||
// Wait for client to receive the value
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] { return gotValues; }));
|
||||
@@ -570,7 +585,7 @@ DhtProxyTester::testPushNotification()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
CPPUNIT_ASSERT(nodeClient.pushNotificationReceived(push_data).get() == dht::PushNotificationResult::Values);
|
||||
CPPUNIT_ASSERT(sendPush(nodeClient, push_data, lk) == dht::PushNotificationResult::Values);
|
||||
|
||||
// Wait for client to receive the edited value
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] { return gotValues; }));
|
||||
@@ -587,7 +602,7 @@ DhtProxyTester::testPushNotification()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
CPPUNIT_ASSERT(nodeClient.pushNotificationReceived(push_data).get() == dht::PushNotificationResult::ValuesExpired);
|
||||
CPPUNIT_ASSERT(sendPush(nodeClient, push_data, lk) == dht::PushNotificationResult::ValuesExpired);
|
||||
|
||||
cv.wait_for(lk, 500ms, [&] { return gotExpiredValues; });
|
||||
|
||||
@@ -1118,7 +1133,8 @@ DhtProxyTester::testPushMultiValueEditExpire()
|
||||
auto key = dht::InfoHash::get("pushMultiEditExpire");
|
||||
auto identity = dht::crypto::generateIdentity("MultiEditAuthor");
|
||||
|
||||
struct Event {
|
||||
struct Event
|
||||
{
|
||||
dht::Value::Id id;
|
||||
uint16_t seq;
|
||||
bool expired;
|
||||
@@ -1176,7 +1192,7 @@ DhtProxyTester::testPushMultiValueEditExpire()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
|
||||
// Wait for both values to arrive
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] {
|
||||
@@ -1209,7 +1225,7 @@ DhtProxyTester::testPushMultiValueEditExpire()
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
push_data.erase("exp");
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
|
||||
// Wait for the edited value (id=100, seq=2) to arrive
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] {
|
||||
@@ -1232,13 +1248,11 @@ DhtProxyTester::testPushMultiValueEditExpire()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
CPPUNIT_ASSERT(nodeClient.pushNotificationReceived(push_data).get() == dht::PushNotificationResult::ValuesExpired);
|
||||
CPPUNIT_ASSERT(sendPush(nodeClient, push_data, lk) == dht::PushNotificationResult::ValuesExpired);
|
||||
|
||||
// Wait for expire callback for value B
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] {
|
||||
return std::any_of(events.begin(), events.end(), [](const Event& e) {
|
||||
return e.id == 200 && e.expired;
|
||||
});
|
||||
return std::any_of(events.begin(), events.end(), [](const Event& e) { return e.id == 200 && e.expired; });
|
||||
}));
|
||||
|
||||
// Verify: value A (edited) should NOT have been expired
|
||||
@@ -1288,7 +1302,8 @@ DhtProxyTester::testPushRefreshNoSpuriousExpire()
|
||||
auto key = dht::InfoHash::get("pushRefreshNoExpire");
|
||||
auto identity = dht::crypto::generateIdentity("RefreshAuthor");
|
||||
|
||||
struct Event {
|
||||
struct Event
|
||||
{
|
||||
dht::Value::Id id;
|
||||
bool expired;
|
||||
};
|
||||
@@ -1328,7 +1343,7 @@ DhtProxyTester::testPushRefreshNoSpuriousExpire()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
|
||||
// Wait for all 3 values to arrive
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] {
|
||||
@@ -1354,7 +1369,7 @@ DhtProxyTester::testPushRefreshNoSpuriousExpire()
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
push_data.erase("exp");
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
|
||||
// Wait a bit for any callbacks
|
||||
cv.wait_for(lk, 1s);
|
||||
@@ -1375,13 +1390,11 @@ DhtProxyTester::testPushRefreshNoSpuriousExpire()
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
|
||||
// Wait for expire callback
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] {
|
||||
return std::any_of(events.begin(), events.end(), [](const Event& e) {
|
||||
return e.id == 20 && e.expired;
|
||||
});
|
||||
return std::any_of(events.begin(), events.end(), [](const Event& e) { return e.id == 20 && e.expired; });
|
||||
}));
|
||||
|
||||
// Verify only value 20 expired, not 10 or 30
|
||||
@@ -1426,7 +1439,12 @@ DhtProxyTester::testProxyListenEditChain()
|
||||
auto key = dht::InfoHash::get("proxyEditChain");
|
||||
auto identity = dht::crypto::generateIdentity("ProxyChainEditTester");
|
||||
|
||||
struct Event { dht::Value::Id id; uint16_t seq; bool expired; };
|
||||
struct Event
|
||||
{
|
||||
dht::Value::Id id;
|
||||
uint16_t seq;
|
||||
bool expired;
|
||||
};
|
||||
std::vector<Event> events;
|
||||
|
||||
auto ftoken = nodeClient.listen(key, [&](const std::vector<std::shared_ptr<dht::Value>>& vals, bool expired) {
|
||||
@@ -1493,8 +1511,7 @@ DhtProxyTester::testProxyListenEditChain()
|
||||
for (const auto& e : events)
|
||||
if (!e.expired && e.seq > maxSeq)
|
||||
maxSeq = e.seq;
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Latest add should be the final version",
|
||||
(uint16_t) NUM_EDITS, maxSeq);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Latest add should be the final version", (uint16_t) NUM_EDITS, maxSeq);
|
||||
}
|
||||
|
||||
// Wait for natural expiration
|
||||
@@ -1518,8 +1535,7 @@ DhtProxyTester::testProxyListenEditChain()
|
||||
}
|
||||
}
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Should have exactly 1 expire via proxy", 1, expireCount);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Expired value should be the latest",
|
||||
(uint16_t) NUM_EDITS, expiredSeq);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Expired value should be the latest", (uint16_t) NUM_EDITS, expiredSeq);
|
||||
}
|
||||
|
||||
nodeClient.cancelListen(key, ftoken.get());
|
||||
@@ -1557,7 +1573,12 @@ DhtProxyTester::testPushRapidEditsNoPhantom()
|
||||
auto key = dht::InfoHash::get("pushRapidEdits");
|
||||
auto identity = dht::crypto::generateIdentity("RapidEditAuthor");
|
||||
|
||||
struct Event { dht::Value::Id id; uint16_t seq; bool expired; };
|
||||
struct Event
|
||||
{
|
||||
dht::Value::Id id;
|
||||
uint16_t seq;
|
||||
bool expired;
|
||||
};
|
||||
std::vector<Event> events;
|
||||
|
||||
auto ftoken = nodeClient.listen(key, [&](const std::vector<std::shared_ptr<dht::Value>>& vals, bool expired) {
|
||||
@@ -1593,12 +1614,9 @@ DhtProxyTester::testPushRapidEditsNoPhantom()
|
||||
std::map<std::string, std::string> push_data;
|
||||
push_data["key"] = key.toString();
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
lk.unlock();
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
lk.lock();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
}
|
||||
|
||||
// Wait for edits to arrive (at least 2: initial + latest)
|
||||
@@ -1669,7 +1687,12 @@ DhtProxyTester::testPushRefreshAfterEditKeepsLatest()
|
||||
auto key = dht::InfoHash::get("pushRefreshAfterEdit");
|
||||
auto identity = dht::crypto::generateIdentity("RefreshEditAuthor");
|
||||
|
||||
struct Event { dht::Value::Id id; uint16_t seq; bool expired; };
|
||||
struct Event
|
||||
{
|
||||
dht::Value::Id id;
|
||||
uint16_t seq;
|
||||
bool expired;
|
||||
};
|
||||
std::vector<Event> events;
|
||||
|
||||
auto ftoken = nodeClient.listen(key, [&](const std::vector<std::shared_ptr<dht::Value>>& vals, bool expired) {
|
||||
@@ -1705,12 +1728,9 @@ DhtProxyTester::testPushRefreshAfterEditKeepsLatest()
|
||||
std::map<std::string, std::string> push_data;
|
||||
push_data["key"] = key.toString();
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
lk.unlock();
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
lk.lock();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
}
|
||||
|
||||
// Wait for initial add
|
||||
@@ -1742,12 +1762,9 @@ DhtProxyTester::testPushRefreshAfterEditKeepsLatest()
|
||||
std::map<std::string, std::string> push_data;
|
||||
push_data["key"] = key.toString();
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
lk.unlock();
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
lk.lock();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
}
|
||||
|
||||
// Wait for the edit add (seq=3)
|
||||
@@ -1765,12 +1782,9 @@ DhtProxyTester::testPushRefreshAfterEditKeepsLatest()
|
||||
std::map<std::string, std::string> push_data;
|
||||
push_data["key"] = key.toString();
|
||||
push_data["t"] = std::to_string(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
lk.unlock();
|
||||
nodeClient.pushNotificationReceived(push_data).get();
|
||||
lk.lock();
|
||||
sendPush(nodeClient, push_data, lk);
|
||||
}
|
||||
|
||||
// Wait a bit for any callbacks
|
||||
|
||||
@@ -16,6 +16,58 @@ using namespace std::literals;
|
||||
|
||||
namespace test {
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(DhtRunnerTester);
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(DhtRunnerPushTester);
|
||||
|
||||
namespace {
|
||||
#if defined(OPENDHT_PROXY_CLIENT) && defined(OPENDHT_PUSH_NOTIFICATIONS)
|
||||
constexpr auto stoppedPushResult = dht::PushNotificationResult::IgnoredStopped;
|
||||
#else
|
||||
constexpr auto stoppedPushResult = dht::PushNotificationResult::IgnoredDisabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunnerPushTester::testPushBeforeRun()
|
||||
{
|
||||
dht::DhtRunner node;
|
||||
auto result = node.pushNotificationReceived({});
|
||||
CPPUNIT_ASSERT(result.wait_for(0s) == std::future_status::ready);
|
||||
CPPUNIT_ASSERT(result.get() == stoppedPushResult);
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunnerPushTester::testPushAfterJoin()
|
||||
{
|
||||
dht::DhtRunner node;
|
||||
node.run(0);
|
||||
node.join();
|
||||
auto result = node.pushNotificationReceived({});
|
||||
CPPUNIT_ASSERT(result.wait_for(0s) == std::future_status::ready);
|
||||
CPPUNIT_ASSERT(result.get() == stoppedPushResult);
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunnerPushTester::testPushBurstAfterJoin()
|
||||
{
|
||||
dht::DhtRunner node;
|
||||
node.run(0);
|
||||
node.join();
|
||||
for (unsigned i = 0; i < 32; ++i) {
|
||||
auto result = node.pushNotificationReceived({});
|
||||
CPPUNIT_ASSERT(result.wait_for(0s) == std::future_status::ready);
|
||||
CPPUNIT_ASSERT(result.get() == stoppedPushResult);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunnerPushTester::testPushWhileRunning()
|
||||
{
|
||||
dht::DhtRunner node;
|
||||
node.run(0);
|
||||
auto result = node.pushNotificationReceived({});
|
||||
CPPUNIT_ASSERT(result.wait_for(5s) == std::future_status::ready);
|
||||
CPPUNIT_ASSERT(result.get() != dht::PushNotificationResult::IgnoredStopped);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T
|
||||
|
||||
@@ -10,6 +10,22 @@
|
||||
|
||||
namespace test {
|
||||
|
||||
class DhtRunnerPushTester : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(DhtRunnerPushTester);
|
||||
CPPUNIT_TEST(testPushBeforeRun);
|
||||
CPPUNIT_TEST(testPushAfterJoin);
|
||||
CPPUNIT_TEST(testPushBurstAfterJoin);
|
||||
CPPUNIT_TEST(testPushWhileRunning);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
void testPushBeforeRun();
|
||||
void testPushAfterJoin();
|
||||
void testPushBurstAfterJoin();
|
||||
void testPushWhileRunning();
|
||||
};
|
||||
|
||||
class DhtRunnerTester : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(DhtRunnerTester);
|
||||
|
||||
@@ -210,6 +210,32 @@ OpCacheTester::testStaleExpireIgnored()
|
||||
CPPUNIT_ASSERT_EQUAL((uint16_t) 2, events.back().seq);
|
||||
}
|
||||
|
||||
void
|
||||
OpCacheTester::testSameSeqConflictExpireIgnored()
|
||||
{
|
||||
// A different payload with the same seq (e.g. the same signed content
|
||||
// re-signed with a randomized signature) is ignored on add and not
|
||||
// counted: its expiration must be ignored too.
|
||||
std::vector<Event> events;
|
||||
dht::OpValueCache cache(recordEvents(events));
|
||||
|
||||
auto x = makeValue(60, 0, "x");
|
||||
auto y = makeValue(60, 0, "y");
|
||||
|
||||
cache.onValuesAdded({x}); // A
|
||||
cache.onValuesAdded({y}); // B: same seq, different content
|
||||
CPPUNIT_ASSERT_EQUAL(1u, count(events, false));
|
||||
CPPUNIT_ASSERT(cache.get(60)->data == x->data);
|
||||
|
||||
cache.onValuesExpired({y}); // B
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("An uncounted version must not expire the value", (size_t) 1, cache.size());
|
||||
CPPUNIT_ASSERT_EQUAL(0u, count(events, true));
|
||||
|
||||
cache.onValuesExpired({x}); // A
|
||||
CPPUNIT_ASSERT_EQUAL((size_t) 0, cache.size());
|
||||
CPPUNIT_ASSERT_EQUAL(1u, count(events, true));
|
||||
}
|
||||
|
||||
void
|
||||
OpCacheTester::testCallbacks()
|
||||
{
|
||||
@@ -543,6 +569,29 @@ OpCacheTester::testSourceDropKeepsValue()
|
||||
CPPUNIT_ASSERT_EQUAL((size_t) 0, searchCache.get(dht::Value::Filter {}).size());
|
||||
}
|
||||
|
||||
void
|
||||
OpCacheTester::testSeqOnlyRefreshNotCounted()
|
||||
{
|
||||
// A node re-announcing the same content with a bumped seq must not be
|
||||
// counted as an additional source by the OpValueCache above it, or the
|
||||
// value would survive the node's departure.
|
||||
std::vector<Event> events;
|
||||
dht::OpValueCache parent(recordEvents(events));
|
||||
dht::TypeStore types;
|
||||
auto now = dht::clock::now();
|
||||
|
||||
auto v = makeValue(42, 0, "same");
|
||||
auto vBumped = makeValue(42, 1, "same");
|
||||
{
|
||||
dht::ValueCache node([&](const Values& vals, bool expired) { parent.onValue(vals, expired); });
|
||||
node.onValues({v}, {}, {}, types, now);
|
||||
node.onValues({vBumped}, {}, {}, types, now);
|
||||
CPPUNIT_ASSERT_EQUAL(1u, count(events, false));
|
||||
}
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Node gone: its value must be expired once", 1u, count(events, true));
|
||||
CPPUNIT_ASSERT_EQUAL((size_t) 0, parent.size());
|
||||
}
|
||||
|
||||
void
|
||||
OpCacheTester::testHighChurnRefCountConsistency()
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ class OpCacheTester : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testEditChainMultiSource);
|
||||
CPPUNIT_TEST(testStaleAddIgnored);
|
||||
CPPUNIT_TEST(testStaleExpireIgnored);
|
||||
CPPUNIT_TEST(testSameSeqConflictExpireIgnored);
|
||||
CPPUNIT_TEST(testCallbacks);
|
||||
CPPUNIT_TEST(testFilters);
|
||||
CPPUNIT_TEST(testSyncStatus);
|
||||
@@ -26,6 +27,7 @@ class OpCacheTester : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testGetCallbackReturnsFalse);
|
||||
CPPUNIT_TEST(testTimestampOrdering);
|
||||
CPPUNIT_TEST(testSourceDropKeepsValue);
|
||||
CPPUNIT_TEST(testSeqOnlyRefreshNotCounted);
|
||||
CPPUNIT_TEST(testHighChurnRefCountConsistency);
|
||||
CPPUNIT_TEST(testValueUpdateSingleSourcePhantom);
|
||||
CPPUNIT_TEST(testExpireAfterUpdate);
|
||||
@@ -43,6 +45,7 @@ public:
|
||||
void testEditChainMultiSource();
|
||||
void testStaleAddIgnored();
|
||||
void testStaleExpireIgnored();
|
||||
void testSameSeqConflictExpireIgnored();
|
||||
void testCallbacks();
|
||||
void testFilters();
|
||||
void testSyncStatus();
|
||||
@@ -53,6 +56,7 @@ public:
|
||||
void testGetCallbackReturnsFalse();
|
||||
void testTimestampOrdering();
|
||||
void testSourceDropKeepsValue();
|
||||
void testSeqOnlyRefreshNotCounted();
|
||||
void testHighChurnRefCountConsistency();
|
||||
void testValueUpdateSingleSourcePhantom();
|
||||
void testExpireAfterUpdate();
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2014-2026 Savoir-faire Linux Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "test_pht.h"
|
||||
|
||||
// opendht
|
||||
#include "opendht/indexation/pht.h"
|
||||
|
||||
namespace test {
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(PhtTester);
|
||||
|
||||
using dht::indexation::Prefix;
|
||||
|
||||
void
|
||||
PhtTester::testCommonBits()
|
||||
{
|
||||
// Prefix::size_ counts bits, so two prefixes that agree everywhere have
|
||||
// as many bits in common as they are long, and no more.
|
||||
const Prefix same {dht::Blob(20, 0xAB)};
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned) 160, Prefix::commonBits(same, Prefix {dht::Blob(20, 0xAB)}));
|
||||
|
||||
// A difference in the very last bit leaves every other bit in common.
|
||||
dht::Blob other(20, 0xAB);
|
||||
other[19] = 0xAA;
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned) 159, Prefix::commonBits(same, Prefix {other}));
|
||||
|
||||
// A difference in the very first bit leaves nothing in common.
|
||||
dht::Blob first(20, 0xAB);
|
||||
first[0] = 0x2B;
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned) 0, Prefix::commonBits(same, Prefix {first}));
|
||||
|
||||
// Bits beyond the shorter prefix are not compared, whatever the content
|
||||
// they are cut from holds.
|
||||
const Prefix shorter = same.getPrefix(3);
|
||||
CPPUNIT_ASSERT_EQUAL((size_t) 3, shorter.size_);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned) 3, Prefix::commonBits(shorter, same));
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned) 3, Prefix::commonBits(same, shorter));
|
||||
}
|
||||
|
||||
void
|
||||
PhtTester::testSibling()
|
||||
{
|
||||
// The sibling of a node in the trie is the prefix that differs from it in
|
||||
// its last bit, and in that bit only.
|
||||
for (size_t length : {1, 7, 8, 9, 15, 16, 159}) {
|
||||
const Prefix prefix = Prefix {dht::Blob(20, 0xAB)}.getPrefix(length);
|
||||
const Prefix sibling = prefix.getSibling();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(prefix.size_, sibling.size_);
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned) (length - 1), Prefix::commonBits(prefix, sibling));
|
||||
CPPUNIT_ASSERT(prefix.isContentBitActive(length - 1) != sibling.isContentBitActive(length - 1));
|
||||
|
||||
// Being siblings is symmetric.
|
||||
CPPUNIT_ASSERT(sibling.getSibling().content_ == prefix.content_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PhtTester::testPadding()
|
||||
{
|
||||
for (size_t keySize : {0, 1, 2, 20}) {
|
||||
for (size_t paddingSize : {1, 4}) {
|
||||
dht::Blob expected(keySize, 0xAB);
|
||||
Prefix prefix {expected};
|
||||
expected.resize(keySize + paddingSize, 0);
|
||||
expected[keySize] = 0x80;
|
||||
|
||||
prefix.addPaddingContent(expected.size());
|
||||
|
||||
CPPUNIT_ASSERT(prefix.content_ == expected);
|
||||
CPPUNIT_ASSERT_EQUAL(keySize * 8, prefix.size_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2014-2026 Savoir-faire Linux Inc.
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
// cppunit
|
||||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
namespace test {
|
||||
|
||||
class PhtTester : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(PhtTester);
|
||||
CPPUNIT_TEST(testCommonBits);
|
||||
CPPUNIT_TEST(testSibling);
|
||||
CPPUNIT_TEST(testPadding);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Test how many bits two prefixes have in common
|
||||
*/
|
||||
void testCommonBits();
|
||||
/**
|
||||
* Test the prefix of the sibling node in the trie
|
||||
*/
|
||||
void testSibling();
|
||||
void testPadding();
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
@@ -353,6 +353,47 @@ ValueCacheTester::testSameSeqEditIgnored()
|
||||
CPPUNIT_ASSERT_EQUAL(2, addCount);
|
||||
}
|
||||
|
||||
void
|
||||
ValueCacheTester::testSameContentHigherSeqIsRefresh()
|
||||
{
|
||||
// Value::operator== ignores seq: identical content with a bumped seq is
|
||||
// the same value re-announced, not an edition. Re-emitting it would make
|
||||
// a source-counting OpValueCache count this node twice.
|
||||
int addCount = 0;
|
||||
dht::ValueCache cache([&](const std::vector<std::shared_ptr<dht::Value>>& vals, bool expired) {
|
||||
if (!expired)
|
||||
addCount += vals.size();
|
||||
});
|
||||
dht::TypeStore types;
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
auto v1 = std::make_shared<dht::Value>();
|
||||
v1->id = 1;
|
||||
v1->seq = 0;
|
||||
v1->data = {'A'};
|
||||
cache.onValues({v1}, {}, {}, types, now);
|
||||
CPPUNIT_ASSERT_EQUAL(1, addCount);
|
||||
|
||||
auto sameContent = std::make_shared<dht::Value>();
|
||||
sameContent->id = 1;
|
||||
sameContent->seq = 1;
|
||||
sameContent->data = {'A'};
|
||||
auto later = now + std::chrono::minutes(5);
|
||||
cache.onValues({sameContent}, {}, {}, types, later);
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Same content with a higher seq is a refresh, not an edit", 1, addCount);
|
||||
|
||||
// The refresh still extends the expiration (default type: 10 minutes)
|
||||
cache.expireValues(now + std::chrono::minutes(11));
|
||||
CPPUNIT_ASSERT_EQUAL((size_t) 1, cache.size());
|
||||
|
||||
auto edited = std::make_shared<dht::Value>();
|
||||
edited->id = 1;
|
||||
edited->seq = 2;
|
||||
edited->data = {'B'};
|
||||
cache.onValues({edited}, {}, {}, types, later);
|
||||
CPPUNIT_ASSERT_EQUAL(2, addCount);
|
||||
}
|
||||
|
||||
void
|
||||
ValueCacheTester::testShortExpirationRefreshLost()
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@ class ValueCacheTester : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testMaxValues);
|
||||
CPPUNIT_TEST(testUpdateTypeExpiration);
|
||||
CPPUNIT_TEST(testSameSeqEditIgnored);
|
||||
CPPUNIT_TEST(testSameContentHigherSeqIsRefresh);
|
||||
CPPUNIT_TEST(testShortExpirationRefreshLost);
|
||||
CPPUNIT_TEST(testShortExpirationHighChurn);
|
||||
CPPUNIT_TEST(testGracePeriodWhileSynced);
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
void testMaxValues();
|
||||
void testUpdateTypeExpiration();
|
||||
void testSameSeqEditIgnored();
|
||||
void testSameContentHigherSeqIsRefresh();
|
||||
void testShortExpirationRefreshLost();
|
||||
void testShortExpirationHighChurn();
|
||||
void testGracePeriodWhileSynced();
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
{
|
||||
"default-registry": {
|
||||
"kind": "git",
|
||||
"baseline": "f3e10653cc27d62a37a3763cd84b38bca07c6075",
|
||||
"baseline": "9eec002df1cd109f8f104cd966a763daf9751489",
|
||||
"repository": "https://github.com/microsoft/vcpkg"
|
||||
},
|
||||
"overlay-ports": [
|
||||
"ports"
|
||||
],
|
||||
"registries": [
|
||||
{
|
||||
"kind": "artifact",
|
||||
|
||||
+9
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "opendht",
|
||||
"version-string": "4.3.0",
|
||||
"version-string": "4.4.2",
|
||||
"port-version": 1,
|
||||
"description": "OpenDHT: A lightweight C++17 Distributed Hash Table library.",
|
||||
"homepage": "https://opendht.net",
|
||||
@@ -16,7 +16,14 @@
|
||||
},
|
||||
"fmt",
|
||||
"nettle",
|
||||
"shiftmedia-libgnutls",
|
||||
{
|
||||
"name": "shiftmedia-libgnutls",
|
||||
"platform": "windows & !mingw"
|
||||
},
|
||||
{
|
||||
"name": "libgnutls",
|
||||
"platform": "!windows | mingw"
|
||||
},
|
||||
"msgpack",
|
||||
"jsoncpp",
|
||||
"asio",
|
||||
|
||||
Reference in new issue
Block a user