Compare commits

...
34 Commits
Author SHA1 Message Date
Adrien Beraud cf73feb056 dht: use max date for permanent puts 2025-11-28 13:41:29 -05:00
Adrien Béraud e028c1be8c update version to 3.6.0 2025-11-26 14:03:56 -05:00
Adrien Béraud 3e8d9835d4 utils: various fixes to build with c++23 2025-11-26 14:03:56 -05:00
Adrien Béraud 18df23bd50 build/cmake: support c++ other than 17 2025-11-26 14:03:56 -05:00
Adrien Béraud 6b8c3ea581 base64: use simdutf 2025-11-26 14:01:45 -05:00
dependabot[bot] 7645f284e4 build(deps): bump pypa/cibuildwheel from 3.2.1 to 3.3.0
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.2.1 to 3.3.0.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.2.1...v3.3.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-25 10:54:55 -05:00
dependabot[bot] 2cec478dfc build(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-25 10:54:00 -05:00
Adrien Béraud 54f07e449c pkgconfig: link with fmt 2025-11-19 11:20:40 -05:00
Adrien Béraud 09308321f8 network_utils: cleanup 2025-11-19 11:20:02 -05:00
Adrien Béraud e4b333b672 add clang-format 2025-11-19 11:20:02 -05:00
Adrien Béraud 69f382449d add .vscode settings 2025-11-19 11:19:55 -05:00
Adrien Beraud 47d2f41930 proxy client: check for null resolver 2025-11-17 12:56:36 -05:00
ovari d6b124eec0 Update BUILD.md 2025-11-16 17:35:19 -05:00
ovari 0330ee6683 Update BUILD.md 2025-11-16 17:35:19 -05:00
Jean-Charles de Longueville 1b854b8a09 Update BUILD.md from reviewer's comments 2025-11-16 16:50:04 -05:00
Jean-Charles de Longueville 4f6c561540 Update BUILD.md: typo 2025-11-16 16:50:04 -05:00
Jean-Charles de Longueville 79ffe663f6 Update BUILD.md: add debian 13 trixie instructions 2025-11-16 16:50:04 -05:00
dependabot[bot] a14a97e3a2 build(deps): bump actions/download-artifact from 5 to 6
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-28 10:20:24 -04:00
dependabot[bot] bddc34d47b build(deps): bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-28 10:19:46 -04:00
kestrel de6ea1d632 Add support for io_uring for Autotools builds.
* configure.ac (liburing): Add --with-liburing option, tests for liburing.
* src/Makefile.am (libopendht_la_CPPFLAGS, libopendht_la_LIBS): Add relevant compiler and linker flags.
2025-10-15 15:13:19 -04:00
kestrel 1d2fd80fad Use pkg-config to test for llhttp for Autotools builds.
* configure.ac (llhttp_lib): Replaces existing tests with PKG_CHECK_MODULES.
* src/Makefile.am (libopendht_la_CPPFLAGS, libopendht_la_LIBS): Add relevant compiler and linker flags.
2025-10-15 15:13:19 -04:00
SASANO Takayoshi f7df3413e1 CMakeLists.txt: revise libreadline check on OpenBSD 2025-10-15 15:12:17 -04:00
SASANO Takayoshi 4cb67002e3 CMakeLists.txt: fix -lreadline not found error 2025-10-15 15:12:17 -04:00
SASANO Takayoshi 197a9a6bcd CMakeLists.txt: fix 'install TARGETS RUNTIME_DEPENDENCY_SET is not supported' 2025-10-15 15:12:17 -04:00
SASANO Takayoshi 8641de139d CMakeLists.txt: avoid libreadline check on OpenBSD 2025-10-15 15:12:17 -04:00
dependabot[bot] adcb61bbf9 build(deps): bump pypa/cibuildwheel from 3.2.0 to 3.2.1
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.2.0...v3.2.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-15 15:11:09 -04:00
dependabot[bot] 70709c9a68 build(deps): bump github/codeql-action from 3 to 4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-15 15:10:42 -04:00
kestrel bf930de9e4 configure.ac: Fix llhttplib substituion.
* configure.ac (@http_lib@): Rename to llhttp_lib, replace the substituted value for a pkg-config module name.
2025-10-13 14:35:28 -04:00
Adrien Beraud bb4e716fc7 README: add pypi badge 2025-10-10 13:59:44 -04:00
Adrien Beraud 54fd6cf64f securedht: avoid calling identity announced callback multiple times 2025-10-10 13:59:44 -04:00
dependabot[bot] d905a02b32 build(deps): bump pypa/cibuildwheel from 3.1.4 to 3.2.0
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.1.4 to 3.2.0.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.1.4...v3.2.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-10 11:11:56 -04:00
Adrien Béraud d12f9271b8 pht: use const reference for IndexEntry::TYPE
Prevents static initialization order issue
2025-09-22 14:41:22 -04:00
Adrien Béraud 3639d651a2 docker: add alpine edge container 2025-09-22 14:41:22 -04:00
Adrien Béraud 07824391a2 update version to 3.5.5 2025-09-22 14:41:22 -04:00
28 changed files with 1698 additions and 1084 deletions

No files matched your search

+99
View File
@@ -0,0 +1,99 @@
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
+25 -10
View File
@@ -7,7 +7,7 @@ env:
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: "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"
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]
@@ -16,7 +16,7 @@ jobs:
name: Ubuntu/GCC Autotools build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Dependencies
run: |
@@ -39,6 +39,15 @@ jobs:
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: |
@@ -66,7 +75,7 @@ jobs:
name: Ubuntu/GCC Meson build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Dependencies
run: |
@@ -87,7 +96,7 @@ jobs:
name: Ubuntu/GCC minimal build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Minimal Dependencies
run: |
@@ -123,7 +132,7 @@ jobs:
DEBIAN_FRONTEND: noninteractive
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Dependencies
run: |
@@ -157,17 +166,23 @@ jobs:
make install
cd ../../ && rm -rf restinio*
- name: Build
- name: Configure project with CMake
run: |
./autogen.sh
./configure --enable-proxy-client
make
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
build-macos:
name: macOS/Clang build
runs-on: macos-15
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Homebrew Dependencies
run: brew install msgpack-cxx asio gnutls nettle readline fmt jsoncpp argon2 openssl cppunit
+1 -1
View File
@@ -6,7 +6,7 @@ jobs:
name: Clang Static Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: deps
run: |
sudo apt update && \
+3 -3
View File
@@ -27,15 +27,15 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
+6 -6
View File
@@ -19,15 +19,15 @@ jobs:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
# Run locally with: pipx run cibuildwheel --platform linux python
- name: Build wheels
uses: pypa/cibuildwheel@v3.1.4
uses: pypa/cibuildwheel@v3.3.0
with:
package-dir: python
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v5
with:
name: opendht-wheels-${{ matrix.os }}
path: ./wheelhouse/*.whl
@@ -44,7 +44,7 @@ jobs:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}\vcpkg_binary_cache
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Cache vcpkg installed packages
id: cache-vcpkg
@@ -86,7 +86,7 @@ jobs:
pipx run cibuildwheel python
shell: pwsh
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v5
with:
name: opendht-wheels-win_amd64
path: ./build/wheelhouse/*.whl
@@ -95,7 +95,7 @@ jobs:
runs-on: ubuntu-latest
needs: [build_wheels, build_wheels_windows]
steps:
- uses: actions/download-artifact@v5
- uses: actions/download-artifact@v6
with:
pattern: opendht-wheels-*
path: dist
+14 -14
View File
@@ -25,7 +25,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -58,7 +58,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -92,7 +92,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -125,7 +125,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -159,7 +159,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -193,7 +193,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -227,7 +227,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -266,7 +266,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
submodules: recursive
@@ -350,7 +350,7 @@ jobs:
}
- name: Upload MSI Artifact
uses: actions/upload-artifact@v4
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
@@ -370,7 +370,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
submodules: recursive
@@ -430,7 +430,7 @@ jobs:
cmake --build build_static --config Release --parallel $([System.Environment]::ProcessorCount)
- name: Upload Static dhtnode Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: opendht-windows-dhtnode
path: |
@@ -446,16 +446,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Download Windows MSI artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: opendht-windows-msi
path: downloaded_artifacts/windows_msi
- name: Download Static dhtnode artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: opendht-windows-dhtnode
path: downloaded_artifacts/static_dhtnode
+8 -8
View File
@@ -27,7 +27,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Set up MSVC
uses: microsoft/setup-msbuild@v2
@@ -75,7 +75,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Set up MSVC
uses: microsoft/setup-msbuild@v2
@@ -124,7 +124,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Set up MSVC
uses: microsoft/setup-msbuild@v2
@@ -178,7 +178,7 @@ jobs:
- name: Upload build artifacts
if: matrix.build_type == 'Release'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: opendht-windows-${{ matrix.arch }}-${{ matrix.build_type }}
path: |
@@ -198,7 +198,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Set up MSVC
uses: microsoft/setup-msbuild@v2
@@ -250,7 +250,7 @@ jobs:
ctest --build-config ${{ matrix.build_type }} --output-on-failure --parallel 4
- name: Upload static build artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: opendht-windows-static-${{ matrix.arch }}-${{ matrix.build_type }}
path: |
@@ -269,7 +269,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Setup MinGW
uses: msys2/setup-msys2@v2
@@ -369,7 +369,7 @@ jobs:
- name: Upload MinGW artifacts
if: matrix.build_type == 'Release'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: opendht-windows-mingw-${{ matrix.build_type }}
path: |
+10
View File
@@ -0,0 +1,10 @@
{
"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",
}
+36 -6
View File
@@ -1,21 +1,49 @@
# Build the library
Build is currently tested on GNU/Linux, macOS and Windows.
The build is currently tested on GNU/Linux, macOS, and Windows.
## Unix-like systems (Linux, macOS, MSYS2/MinGW etc.)
## 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
# Install Python binding dependencies
sudo apt-get install cython3 python3-dev python3-setuptools python3-build
```
Optionally, install Restinio to enable OpenDHT proxy client and server:
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
@@ -37,18 +65,20 @@ 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
# Build and install
cd opendht
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
@@ -63,7 +93,7 @@ Minimal build (libraries only):
cmake -DOPENDHT_TOOLS=OFF ..
```
Full-featured build with proxy support, Python and C bindings:
Full-featured build with proxy support, Python, and C bindings:
```sh
cmake -DOPENDHT_PYTHON=ON \
-DOPENDHT_C=ON \
+70 -19
View File
@@ -1,16 +1,16 @@
cmake_minimum_required (VERSION 3.21..3.31)
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0091 NEW)
endif()
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
cmake_policy(SET CMP0135 NEW)
endif()
if(NOT CMAKE_VERSION VERSION_LESS 3.30 AND NOT POLICY CMP0167)
cmake_policy(SET CMP0167 OLD)
if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
endif()
set (opendht_VERSION_MAJOR 3)
set (opendht_VERSION_MINOR 5.4)
set (opendht_VERSION_MINOR 6.0)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
set (VERSION "${opendht_VERSION}")
@@ -59,7 +59,9 @@ if (DOXYGEN_FOUND)
option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
endif ()
# Build flags
set (CMAKE_CXX_STANDARD 17)
if(NOT DEFINED CMAKE_CXX_STANDARD)
set (CMAKE_CXX_STANDARD 17)
endif()
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>")
@@ -126,18 +128,51 @@ if (NOT MSVC)
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)
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")
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()
set(READLINE_LIBRARIES ${readline_LIBRARIES})
endif ()
# ASIO
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
@@ -302,6 +337,9 @@ else () # MSVC
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})
@@ -552,13 +590,16 @@ if (MSVC)
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)
endif()
target_link_libraries(opendht PUBLIC msgpack-cxx JsonCpp::JsonCpp fmt::fmt)
if (OPENDHT_HTTP)
target_link_libraries(opendht
PUBLIC restinio::restinio
@@ -579,6 +620,7 @@ else()
PRIVATE
PkgConfig::argon2
PkgConfig::Nettle
${SIMDUTF_LIBRARIES}
PUBLIC
${CMAKE_THREAD_LIBS_INIT}
PkgConfig::GnuTLS
@@ -653,12 +695,21 @@ if (BUILD_SHARED_LIBS)
target_compile_definitions(opendht PUBLIC opendht_EXPORTS)
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()
install (TARGETS opendht
DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME_DEPENDENCY_SET opendht_rdeps
EXPORT opendht
)
if (WIN32)
install(RUNTIME_DEPENDENCY_SET opendht_rdeps
PRE_EXCLUDE_REGEXES
+2
View File
@@ -4,6 +4,8 @@
<a id="user-content-opendht-" class="anchor" href="/savoirfairelinux/opendht/blob/master/README.md#opendht-" aria-hidden="true"></a>OpenDHT
</h1>
![PyPI - Version](https://img.shields.io/pypi/v/opendht?style=flat)
A lightweight C++17 Distributed Hash Table implementation.
OpenDHT provides an easy to use distributed in-memory data store.
+19 -9
View File
@@ -1,11 +1,12 @@
dnl define macros
m4_define([opendht_major_version], 3)
m4_define([opendht_minor_version], 5)
m4_define([opendht_patch_version], 4)
m4_define([opendht_minor_version], 6)
m4_define([opendht_patch_version], 0)
m4_define([opendht_version],
[opendht_major_version.opendht_minor_version.opendht_patch_version])
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])
@@ -141,19 +142,21 @@ 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 >= 1.2])
PKG_CHECK_MODULES([MsgPack], [msgpack-cxx >= 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([JsonCpp], [jsoncpp >= 1.7.2], [have_jsoncpp=yes], [have_jsoncpp=no])
PKG_CHECK_MODULES([simdutf], [simdutf >= 6], [have_simdutf=yes], [have_simdutf=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"]))
@@ -180,12 +183,18 @@ 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"
# 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]))
PKG_CHECK_MODULES([Llhttp], [libllhttp])
llhttp_lib=", libllhttp"
])
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"
@@ -218,4 +227,5 @@ 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
+41
View File
@@ -0,0 +1,41 @@
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"]
+27
View File
@@ -0,0 +1,27 @@
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*
+1 -1
View File
@@ -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);
+59 -41
View File
@@ -30,89 +30,107 @@
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 S, typename... Args>
inline void debug(S&& format, Args&&... args) const {
logger(LogLevel::debug, fmt::format(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 warn(S&& format, Args&&... args) const {
logger(LogLevel::warning, 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 error(S&& format, Args&&... args) const {
logger(LogLevel::error, 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... 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
+67 -40
View File
@@ -20,6 +20,7 @@
#include "def.h"
#include <type_traits>
#include <msgpack.hpp>
#include <fmt/format.h>
@@ -48,32 +49,38 @@ 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(std::string_view 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
@@ -86,47 +93,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>
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 fmt::format("{:.3g} us",
std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count());
} 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 fmt::format("{:.3g} ms",
std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count());
} else if (d < std::chrono::minutes(1)) {
return fmt::format("{:.3g} s", std::chrono::duration_cast<std::chrono::duration<double>>(d).count());
} 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());
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 fmt::format("{:.3g} h",
std::chrono::duration_cast<std::chrono::duration<double, std::ratio<3600>>>(d).count());
} else {
return fmt::format("{:.3g} days", std::chrono::duration_cast<std::chrono::duration<double, std::ratio<86400>>>(d).count());
return fmt::format("{:.3g} days",
std::chrono::duration_cast<std::chrono::duration<double, std::ratio<86400>>>(d).count());
}
}
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));
}
};
@@ -143,19 +164,21 @@ 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>();
}
@@ -163,10 +186,14 @@ 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());
}
+195 -118
View File
@@ -1,30 +1,53 @@
project('opendht', 'c', 'cpp', 'cython',
version: '3.5.4',
project(
'opendht',
'c',
'cpp',
'cython',
version: '3.6.0',
meson_version: '>=1.1.0',
default_options: [
'cpp_std=c++17',
'warning_level=3'
])
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()
deps = [fmt, gnutls, nettle, msgpack, argon2, openssl, jsoncpp, llhttp, io_uring]
deps = [
fmt,
gnutls,
nettle,
msgpack,
argon2,
openssl,
jsoncpp,
simdutf,
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)
@@ -49,17 +72,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
@@ -68,25 +91,27 @@ 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: ['-DOPENDHT_BUILD', '-Dopendht_EXPORTS'],
install: true,
)
conf_data.set('VERSION', meson.project_version())
conf_data.set('prefix', get_option('prefix'))
@@ -94,74 +119,99 @@ 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
@@ -169,74 +219,101 @@ 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
View File
@@ -5,8 +5,8 @@ includedir=@includedir@
Name: OpenDHT
Description: C++17 Distributed Hash Table library
Version: @VERSION@
Libs: -L${libdir} -lopendht
Libs: -L${libdir} -lopendht -lfmt
Libs.private: @http_lib@ -pthread
Requires: gnutls >= 3.3@jsoncpp_lib@@openssl_lib@
Requires.private: nettle >= 2.4@argon2_lib@@llhttp_lib@@iouring_lib@
Requires.private: nettle >= 2.4@argon2_lib@@llhttp_lib@@iouring_lib@@simdutf_lib@
Cflags: -I${includedir}
+2 -2
View File
@@ -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@
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@ @OpenSSL_LIBS@ @Fmt_LIBS@
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_LDFLAGS = @LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
libopendht_la_SOURCES = \
dht.cpp \
+15 -112
View File
@@ -17,127 +17,30 @@
#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)
{
return base64_encode(str.cbegin(), str.cend());
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;
}
std::vector<unsigned char>
base64_decode(const std::string& str)
{
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;
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;
}
+763 -512
View File
File diff suppressed because it is too large. Load diff
+2 -1
View File
@@ -208,7 +208,8 @@ DhtProxyClient::stop()
std::lock_guard<std::mutex> l(resolverLock_);
resolver = std::move(resolver_);
}
resolver->cancel();
if (resolver)
resolver->cancel();
cancelAllListeners();
if (infoState_)
infoState_->cancel = true;
+1 -1
View File
@@ -145,7 +145,7 @@ int Pht::Cache::lookup(const Prefix& p) {
return pos;
}
const ValueType IndexEntry::TYPE = ValueType::USER_DATA;
const ValueType& IndexEntry::TYPE = ValueType::USER_DATA;
constexpr std::chrono::minutes Pht::Cache::NODE_EXPIRE_TIME;
void Pht::lookupStep(Prefix p, std::shared_ptr<int> lo, std::shared_ptr<int> hi,
+42 -30
View File
@@ -23,8 +23,8 @@
#include <io.h>
#include <string>
#include <cstring>
#define close(x) closesocket(x)
#define write(s, b, f) send(s, b, (int)strlen(b), 0)
#define close(x) closesocket(x)
#define write(s, b, f) send(s, b, (int) strlen(b), 0)
#define _poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
#else
#include <fcntl.h>
@@ -49,10 +49,10 @@ bindSocket(const SockAddr& addr, SockAddr& bound)
throw DhtException(std::string("Can't open socket: ") + strerror(sock));
int set = 1;
#ifdef SO_NOSIGPIPE
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&set, sizeof(set));
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (const char*) &set, sizeof(set));
#endif
if (is_ipv6)
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&set, sizeof(set));
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*) &set, sizeof(set));
net::setNonblocking(sock);
int rc = bind(sock, addr.get(), addr.getLength());
if (rc < 0) {
@@ -62,7 +62,7 @@ bindSocket(const SockAddr& addr, SockAddr& bound)
}
sockaddr_storage ss;
socklen_t ss_len = sizeof(ss);
getsockname(sock, (sockaddr*)&ss, &ss_len);
getsockname(sock, (sockaddr*) &ss, &ss_len);
bound = {ss, ss_len};
return sock;
}
@@ -84,7 +84,8 @@ setNonblocking(int fd, bool nonblocking)
}
#ifdef _WIN32
void udpPipe(int fds[2])
void
udpPipe(int fds[2])
{
int lst = socket(AF_INET, SOCK_DGRAM, 0);
if (lst < 0)
@@ -97,11 +98,12 @@ void udpPipe(int fds[2])
inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
inaddr.sin_port = 0;
int yes = 1;
setsockopt(lst, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes));
int rc = bind(lst, (sockaddr*)&inaddr, sizeof(inaddr));
setsockopt(lst, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, sizeof(yes));
int rc = bind(lst, (sockaddr*) &inaddr, sizeof(inaddr));
if (rc < 0) {
close(lst);
throw DhtException("Can't bind socket on " + print_addr((sockaddr*)&inaddr, sizeof(inaddr)) + " " + strerror(rc));
throw DhtException("Can't bind socket on " + print_addr((sockaddr*) &inaddr, sizeof(inaddr)) + " "
+ strerror(rc));
}
socklen_t len = sizeof(addr);
getsockname(lst, &addr, &len);
@@ -111,7 +113,9 @@ void udpPipe(int fds[2])
}
#endif
UdpSocket::UdpSocket(in_port_t port, const std::shared_ptr<Logger>& l) : logger(l) {
UdpSocket::UdpSocket(in_port_t port, const std::shared_ptr<Logger>& l)
: logger(l)
{
SockAddr bind4;
bind4.setFamily(AF_INET);
bind4.setPort(port);
@@ -122,28 +126,37 @@ UdpSocket::UdpSocket(in_port_t port, const std::shared_ptr<Logger>& l) : logger(
openSockets(bind4, bind6);
}
UdpSocket::UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const std::shared_ptr<Logger>& l) : logger(l)
UdpSocket::UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const std::shared_ptr<Logger>& l)
: logger(l)
{
std::lock_guard<std::mutex> lk(lock);
openSockets(bind4, bind6);
}
UdpSocket::~UdpSocket() {
UdpSocket::~UdpSocket()
{
stop();
if (rcv_thread.joinable())
rcv_thread.join();
}
int
UdpSocket::sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) {
UdpSocket::sendTo(const SockAddr& dest, const uint8_t* data, size_t size, [[maybe_unused]] bool replied)
{
if (not dest)
return EFAULT;
int s;
switch (dest.getFamily()) {
case AF_INET: s = s4; break;
case AF_INET6: s = s6; break;
default: s = -1; break;
case AF_INET:
s = s4;
break;
case AF_INET6:
s = s6;
break;
default:
s = -1;
break;
}
if (s < 0)
@@ -153,14 +166,12 @@ UdpSocket::sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool r
#ifdef MSG_CONFIRM
if (replied)
flags |= MSG_CONFIRM;
#else
(void) replied;
#endif
#ifdef MSG_NOSIGNAL
flags |= MSG_NOSIGNAL;
#endif
if (sendto(s, (const char*)data, size, flags, dest.get(), dest.getLength()) == -1) {
if (sendto(s, (const char*) data, size, flags, dest.get(), dest.getLength()) == -1) {
int err = errno;
if (logger)
logger->d("Can't send message to %s: %s", dest.toString().c_str(), strerror(err));
@@ -239,7 +250,7 @@ UdpSocket::openSockets(const SockAddr& bind4, const SockAddr& bind6)
}
running = true;
rcv_thread = std::thread([this, stop_readfd, ls4=s4, ls6=s6]() mutable {
rcv_thread = std::thread([this, stop_readfd, ls4 = s4, ls6 = s6]() mutable {
struct pollfd fds[NUM_FDS];
for (int i = 0; i < NUM_FDS; i++)
fds[i].events = POLLIN;
@@ -270,23 +281,22 @@ UdpSocket::openSockets(const SockAddr& bind4, const SockAddr& bind6)
socklen_t from_len = sizeof(from);
if (fds[stop_readfd_index].revents & POLLIN) {
if (recv(stop_readfd, (char*)buf.data(), buf.size(), 0) < 0) {
if (recv(stop_readfd, (char*) buf.data(), buf.size(), 0) < 0) {
if (logger)
logger->e("Got stop packet error: %s", strerror(errno));
break;
}
}
else if (fds[ls4_index].revents & POLLIN)
rc = recvfrom(ls4, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
} else if (fds[ls4_index].revents & POLLIN)
rc = recvfrom(ls4, (char*) buf.data(), buf.size(), 0, (sockaddr*) &from, &from_len);
else if (fds[ls6_index].revents & POLLIN)
rc = recvfrom(ls6, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
rc = recvfrom(ls6, (char*) buf.data(), buf.size(), 0, (sockaddr*) &from, &from_len);
else
continue;
if (rc > 0) {
auto pkts = getNewPacket();
auto& pkt = pkts.front();
pkt.data.insert(pkt.data.end(), buf.begin(), buf.begin()+rc);
pkt.data.insert(pkt.data.end(), buf.begin(), buf.begin() + rc);
pkt.from = {from, from_len};
pkt.received = clock::now();
onReceived(std::move(pkts));
@@ -295,10 +305,12 @@ UdpSocket::openSockets(const SockAddr& bind4, const SockAddr& bind6)
logger->e("Error receiving packet: %s", strerror(errno));
int err = errno;
if (err == EPIPE || err == ENOTCONN || err == ECONNRESET) {
if (not running) break;
if (not running)
break;
std::unique_lock<std::mutex> lk(lock, std::try_to_lock);
if (lk.owns_lock()) {
if (not running) break;
if (not running)
break;
if (ls4 >= 0) {
close(ls4);
try {
@@ -363,5 +375,5 @@ UdpSocket::stop()
}
}
}
}
} // namespace net
} // namespace dht
+129 -108
View File
@@ -36,10 +36,18 @@ extern "C" {
namespace dht {
SecureDht::SecureDht(std::unique_ptr<DhtInterface> dht, SecureDht::Config conf, IdentityAnnouncedCb iacb, const std::shared_ptr<Logger>& l)
: DhtInterface(l), dht_(std::move(dht)), key_(conf.id.first), certificate_(conf.id.second), enableCache_(conf.cert_cache_all)
SecureDht::SecureDht(std::unique_ptr<DhtInterface> dht,
SecureDht::Config conf,
IdentityAnnouncedCb iacb,
const std::shared_ptr<Logger>& l)
: DhtInterface(l)
, dht_(std::move(dht))
, key_(conf.id.first)
, certificate_(conf.id.second)
, enableCache_(conf.cert_cache_all)
{
if (!dht_) return;
if (!dht_)
return;
for (const auto& type : DEFAULT_TYPES)
registerType(type);
@@ -53,30 +61,28 @@ SecureDht::SecureDht(std::unique_ptr<DhtInterface> dht, SecureDht::Config conf,
auto certLongId = certificate_->getLongId();
if (key_ and (certId != key_->getPublicKey().getId() or certLongId != key_->getPublicKey().getLongId()))
throw DhtException("SecureDht: provided certificate doesn't match private key.");
dht_->addOnConnectedCallback([this, certId, certLongId, cb=std::move(iacb)]{
dht_->put(certId, Value {
CERTIFICATE_TYPE,
*certificate_,
1
}, [this, certId, cb=std::move(cb)](bool ok) {
if (cb) cb(ok);
if (logger_)
logger_->d(certId, "SecureDht: certificate announcement %s", ok ? "succeeded" : "failed");
}, {}, true);
dht_->put(InfoHash::get(certLongId), Value {
CERTIFICATE_TYPE,
*certificate_,
1
}, [this, cb=std::move(cb)](bool ok) {
if (cb) cb(ok);
if (logger_)
logger_->debug("SecureDht: certificate announcement {}", ok ? "succeeded" : "failed");
}, {}, true);
auto cb = iacb ? [
this,
completedState = std::make_shared<std::pair<unsigned,bool>>(2, true),
iacb = std::move(iacb)
](bool ok) {
if (logger_)
logger_->d("SecureDht: certificate announcement %s", ok ? "succeeded" : "failed");
completedState->second = completedState->second and ok;
if (--completedState->first == 0)
iacb(completedState->second);
} : iacb;
dht_->addOnConnectedCallback([this, certId, certLongId, cb = std::move(cb)] {
dht_->put(certId, Value {CERTIFICATE_TYPE, *certificate_, 1}, cb, time_point::max(), true);
dht_->put(InfoHash::get(certLongId), Value {CERTIFICATE_TYPE, *certificate_, 1}, cb, time_point::max(), true);
});
}
}
SecureDht::~SecureDht(){
SecureDht::~SecureDht()
{
dht_.reset();
}
@@ -88,7 +94,8 @@ SecureDht::secureType(ValueType&& type)
return v->checkSignature();
return type.storePolicy(id, v, nid, a);
};
type.editPolicy = [this,type](InfoHash id, const Sp<Value>& o, Sp<Value>& n, const InfoHash& nid, const SockAddr& a) {
type.editPolicy = [this,
type](InfoHash id, const Sp<Value>& o, Sp<Value>& n, const InfoHash& nid, const SockAddr& a) {
if (not o->isSigned())
return type.editPolicy(id, o, n, nid, a);
if (*o->owner != *n->owner or not n->isSigned()) {
@@ -109,8 +116,7 @@ SecureDht::secureType(ValueType&& type)
logger_->w("Edition forbidden: sequence number must be increasing.");
return false;
}
}
else if (n->seq < o->seq)
} else if (n->seq < o->seq)
return false;
return true;
};
@@ -242,22 +248,26 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
}
auto found = std::make_shared<bool>(false);
dht_->get(node, [cb,node,found,this](const std::vector<Sp<Value>>& vals) {
for (const auto& v : vals) {
if (auto cert = registerCertificate(node, v->data)) {
*found = true;
if (logger_)
logger_->d(node, "Found certificate for %s", node.to_c_str());
if (cb)
cb(cert);
return false;
dht_->get(
node,
[cb, node, found, this](const std::vector<Sp<Value>>& vals) {
for (const auto& v : vals) {
if (auto cert = registerCertificate(node, v->data)) {
*found = true;
if (logger_)
logger_->d(node, "Found certificate for %s", node.to_c_str());
if (cb)
cb(cert);
return false;
}
}
}
return !*found;
}, [cb,found](bool) {
if (!*found and cb)
cb(nullptr);
}, Value::TypeFilter(CERTIFICATE_TYPE));
return !*found;
},
[cb, found](bool) {
if (!*found and cb)
cb(nullptr);
},
Value::TypeFilter(CERTIFICATE_TYPE));
}
void
@@ -277,11 +287,13 @@ SecureDht::findPublicKey(const InfoHash& node, const std::function<void(const Sp
if (*pk) {
nodesPubKeys_[pk->getId()] = pk;
nodesPubKeysLong_[pk->getLongId()] = pk;
if (cb) cb(pk);
if (cb)
cb(pk);
return;
}
}
if (cb) cb(nullptr);
if (cb)
cb(nullptr);
});
}
@@ -311,22 +323,26 @@ SecureDht::findCertificate(const PkId& node, const std::function<void(const Sp<c
}
auto found = std::make_shared<bool>(false);
dht_->get(InfoHash::get(node), [cb,node,found,this](const std::vector<Sp<Value>>& vals) {
for (const auto& v : vals) {
if (auto cert = registerCertificate(node, v->data)) {
*found = true;
if (logger_)
logger_->debug("Found certificate for {}", node.to_c_str());
if (cb)
cb(cert);
return false;
dht_->get(
InfoHash::get(node),
[cb, node, found, this](const std::vector<Sp<Value>>& vals) {
for (const auto& v : vals) {
if (auto cert = registerCertificate(node, v->data)) {
*found = true;
if (logger_)
logger_->debug("Found certificate for {}", node.to_c_str());
if (cb)
cb(cert);
return false;
}
}
}
return !*found;
}, [cb,found](bool) {
if (!*found and cb)
cb(nullptr);
}, Value::TypeFilter(CERTIFICATE_TYPE));
return !*found;
},
[cb, found](bool) {
if (!*found and cb)
cb(nullptr);
},
Value::TypeFilter(CERTIFICATE_TYPE));
}
void
@@ -346,11 +362,13 @@ SecureDht::findPublicKey(const PkId& node, const std::function<void(const Sp<cry
if (*pk) {
nodesPubKeys_[pk->getId()] = pk;
nodesPubKeysLong_[pk->getLongId()] = pk;
if (cb) cb(pk);
if (cb)
cb(pk);
return;
}
}
if (cb) cb(nullptr);
if (cb)
cb(nullptr);
});
}
@@ -418,7 +436,6 @@ SecureDht::getCallbackFilter(const ValueCallback& cb, Value::Filter&& filter)
};
}
GetCallback
SecureDht::getCallbackFilter(const GetCallback& cb, Value::Filter&& filter)
{
@@ -449,7 +466,6 @@ SecureDht::listen(const InfoHash& id, ValueCallback cb, Value::Filter f, Where w
return dht_->listen(id, getCallbackFilter(cb, std::forward<Value::Filter>(f)), {}, std::forward<Where>(w));
}
size_t
SecureDht::listen(const InfoHash& id, GetCallback cb, Value::Filter f, Where w)
{
@@ -459,7 +475,7 @@ SecureDht::listen(const InfoHash& id, GetCallback cb, Value::Filter f, Where w)
void
SecureDht::putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback, bool permanent)
{
if (not key_ or not hash or not val) {
if (not key_ or not hash or not val) {
if (callback)
callback(false, {});
return;
@@ -477,8 +493,9 @@ SecureDht::putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback,
}
// Check if data already exists on the dht
get(hash,
[val,this] (const std::vector<Sp<Value>>& vals) {
get(
hash,
[val, this](const std::vector<Sp<Value>>& vals) {
if (logger_)
logger_->d("Found online previous value being announced.");
for (const auto& v : vals) {
@@ -493,73 +510,77 @@ SecureDht::putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback,
}
return true;
},
[hash,val,this,callback,permanent] (bool /* ok */) {
[hash, val, this, callback, permanent](bool /* ok */) {
sign(*val);
dht_->put(hash, val, callback, time_point::max(), permanent);
},
Value::IdFilter(val->id),
Where().id(val->id)
);
Where().id(val->id));
}
void
SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val, DoneCallback callback, bool permanent)
{
if (not key_) {
if (not key_) {
if (callback)
callback(false, {});
return;
}
findPublicKey(to, [this, hash, val = std::move(val), callback = std::move(callback), permanent](const Sp<crypto::PublicKey>& pk) {
if(!pk || !*pk) {
if (callback)
callback(false, {});
return;
}
if (logger_)
logger_->w("Encrypting data for PK: %s", pk->getId().toString().c_str());
try {
dht_->put(hash, encrypt(*val, *pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
if (logger_)
logger_->e("Error putting encrypted data: %s", e.what());
if (callback)
callback(false, {});
}
});
findPublicKey(to,
[this, hash, val = std::move(val), callback = std::move(callback), permanent](
const Sp<crypto::PublicKey>& pk) {
if (!pk || !*pk) {
if (callback)
callback(false, {});
return;
}
if (logger_)
logger_->w("Encrypting data for PK: %s", pk->getId().toString().c_str());
try {
dht_->put(hash, encrypt(*val, *pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
if (logger_)
logger_->e("Error putting encrypted data: %s", e.what());
if (callback)
callback(false, {});
}
});
}
void
SecureDht::putEncrypted(const InfoHash& hash, const PkId& to, Sp<Value> val, DoneCallback callback, bool permanent)
{
if (not key_) {
if (not key_) {
if (callback)
callback(false, {});
return;
}
findPublicKey(to, [this, hash, val = std::move(val), callback = std::move(callback), permanent](const Sp<crypto::PublicKey>& pk) {
if(!pk || !*pk) {
if (callback)
callback(false, {});
return;
}
if (logger_)
logger_->warn("Encrypting data for PK: {}", pk->getLongId());
try {
dht_->put(hash, encrypt(*val, *pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
if (logger_)
logger_->e("Error putting encrypted data: %s", e.what());
if (callback)
callback(false, {});
}
});
findPublicKey(to,
[this, hash, val = std::move(val), callback = std::move(callback), permanent](
const Sp<crypto::PublicKey>& pk) {
if (!pk || !*pk) {
if (callback)
callback(false, {});
return;
}
if (logger_)
logger_->warn("Encrypting data for PK: {}", pk->getLongId());
try {
dht_->put(hash, encrypt(*val, *pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
if (logger_)
logger_->e("Error putting encrypted data: %s", e.what());
if (callback)
callback(false, {});
}
});
}
void
SecureDht::putEncrypted(const InfoHash& hash, const crypto::PublicKey& pk, Sp<Value> val, DoneCallback callback, bool permanent)
SecureDht::putEncrypted(
const InfoHash& hash, const crypto::PublicKey& pk, Sp<Value> val, DoneCallback callback, bool permanent)
{
if (not key_) {
if (not key_) {
if (callback)
callback(false, {});
return;
@@ -597,7 +618,7 @@ SecureDht::decrypt(const Value& v)
auto decrypted = key_->decrypt(v.cypher);
Value ret {v.id};
auto msg = msgpack::unpack((const char*)decrypted.data(), decrypted.size());
auto msg = msgpack::unpack((const char*) decrypted.data(), decrypted.size());
ret.msgpack_unpack_body(msg.get());
if (ret.recipient != getId())
@@ -608,4 +629,4 @@ SecureDht::decrypt(const Value& v)
return ret;
}
}
} // namespace dht
+47 -32
View File
@@ -52,13 +52,13 @@ DhtRunnerTester::tearDown() {
std::condition_variable cv;
std::mutex cv_m;
auto shutdown = [&]{
std::lock_guard<std::mutex> lk(cv_m);
std::lock_guard lk(cv_m);
done++;
cv.notify_all();
};
node1.shutdown(shutdown);
node2.shutdown(shutdown);
std::unique_lock<std::mutex> lk(cv_m);
std::unique_lock lk(cv_m);
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]{ return done == 2u; }));
node1.join();
node2.join();
@@ -207,13 +207,13 @@ DhtRunnerTester::testListen() {
for (unsigned i=0; i<N; i++) {
node2.put(a, dht::Value("v1"), [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
std::lock_guard lock(mutex);
putCount++;
if (ok) putOkCount1++;
cv.notify_all();
});
node2.put(b, dht::Value("v2"), [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
std::lock_guard lock(mutex);
putCount++;
if (ok) putOkCount2++;
cv.notify_all();
@@ -221,7 +221,7 @@ DhtRunnerTester::testListen() {
auto bigVal = std::make_shared<dht::Value>();
bigVal->data = mtu;
node2.put(c, std::move(bigVal), [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
std::lock_guard lock(mutex);
putCount++;
if (ok) putOkCount3++;
cv.notify_all();
@@ -229,7 +229,7 @@ DhtRunnerTester::testListen() {
}
{
std::unique_lock<std::mutex> lk(mutex);
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]{ return putCount == N * 3u; }));
CPPUNIT_ASSERT_EQUAL(N, putOkCount1);
CPPUNIT_ASSERT_EQUAL(N, putOkCount2);
@@ -264,6 +264,7 @@ void
DhtRunnerTester::testIdOps() {
std::mutex mutex;
std::condition_variable cv;
unsigned identityCount(0);
unsigned valueCount(0);
unsigned valueCountEdit(0);
@@ -275,8 +276,8 @@ DhtRunnerTester::testIdOps() {
dht::DhtRunner::Context context2;
context2.identityAnnouncedCb = [&](bool ok) {
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(mutex);
valueCount++;
std::lock_guard lk(mutex);
identityCount++;
cv.notify_all();
};
@@ -288,27 +289,28 @@ DhtRunnerTester::testIdOps() {
node2.bootstrap(bound);
{
std::unique_lock<std::mutex> lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 1; }));
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return identityCount == 1; }));
}
node1.findCertificate(node2.getId(), [&](const std::shared_ptr<dht::crypto::Certificate>& crt){
CPPUNIT_ASSERT(crt);
std::lock_guard<std::mutex> lk(mutex);
std::lock_guard lk(mutex);
valueCount++;
cv.notify_all();
});
{
std::unique_lock<std::mutex> lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 2; }));
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 1u; }));
CPPUNIT_ASSERT_EQUAL(1u, identityCount);
}
dht::DhtRunner::Context context1;
context1.identityAnnouncedCb = [&](bool ok) {
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(mutex);
valueCount++;
std::lock_guard lk(mutex);
identityCount++;
cv.notify_all();
};
@@ -323,21 +325,21 @@ DhtRunnerTester::testIdOps() {
auto key = dht::InfoHash::get("key");
node1.putEncrypted(key, node2.getId(), dht::Value("yo"), [&](bool ok){
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(mutex);
std::lock_guard lk(mutex);
valueCount++;
cv.notify_all();
});
node1.putEncrypted(key, node2.getPublicKey(), std::make_shared<dht::Value>("yo"), [&](bool ok){
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(mutex);
std::lock_guard lk(mutex);
valueCount++;
cv.notify_all();
});
node2.listen<std::string>(key, [&](std::string&& value){
CPPUNIT_ASSERT_EQUAL("yo"s, value);
std::lock_guard<std::mutex> lk(mutex);
std::lock_guard lk(mutex);
valueCount++;
cv.notify_all();
return true;
@@ -347,7 +349,7 @@ DhtRunnerTester::testIdOps() {
auto editValue = std::make_shared<dht::Value>("v1");
node1.putSigned(key2, editValue, [&](bool ok){
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(mutex);
std::lock_guard lk(mutex);
valueCountEdit++;
cv.notify_all();
});
@@ -359,16 +361,29 @@ DhtRunnerTester::testIdOps() {
CPPUNIT_ASSERT_EQUAL("v2"s, dht::unpackMsg<std::string>(v->data));
CPPUNIT_ASSERT_EQUAL(v->owner->getLongId(), node1.getPublicKey()->getLongId());
}
std::lock_guard<std::mutex> lk(mutex);
std::lock_guard lk(mutex);
valueCountEdit += values.size();
cv.notify_all();
return true;
});
{
std::unique_lock<std::mutex> lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 7; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCountEdit == 2; }));
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return identityCount == 2u; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 5u; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCountEdit == 2u; }));
}
node2.findCertificate(node1.getPublicKey()->getLongId(), [&](const std::shared_ptr<dht::crypto::Certificate>& crt){
CPPUNIT_ASSERT(crt);
std::lock_guard lk(mutex);
valueCount++;
cv.notify_all();
});
{
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCount == 6u; }));
}
// editValue->data = dht::packMsg("v2");
@@ -376,12 +391,12 @@ DhtRunnerTester::testIdOps() {
editValue->data = dht::packMsg("v2");
node1.putSigned(key2, editValue, [&](bool ok){
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(mutex);
std::lock_guard lk(mutex);
valueCountEdit++;
cv.notify_all();
});
std::unique_lock<std::mutex> lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCountEdit == 4; }));
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]{ return valueCountEdit == 4u; }));
}
void
@@ -399,14 +414,14 @@ DhtRunnerTester::testListenLotOfBytes() {
for (unsigned i=0; i<N; i++) {
node2.put(foo, data, [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
std::lock_guard lock(mutex);
putCount++;
if (ok) putOkCount++;
cv.notify_all();
});
}
{
std::unique_lock<std::mutex> lk(mutex);
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]{ return putCount == N; }));
}
@@ -427,7 +442,7 @@ DhtRunnerTester::testListenLotOfBytes() {
});
{
std::unique_lock<std::mutex> lk(mutex);
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]{ return valueCount == N; }));
}
@@ -447,7 +462,7 @@ DhtRunnerTester::testMultithread() {
for (unsigned i=0; i<N; i++) {
dht::ThreadPool::computation().run([&]{
node2.put(dht::InfoHash::get("123" + std::to_string(i)), "hehe", [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
std::lock_guard lock(mutex);
putCount++;
if (ok) putOkCount++;
cv.notify_all();
@@ -455,14 +470,14 @@ DhtRunnerTester::testMultithread() {
node2.get(dht::InfoHash::get("123" + std::to_string(N-i-1)), [](const std::shared_ptr<dht::Value>&){
return true;
}, [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
std::lock_guard lock(mutex);
putCount++;
if (ok) putOkCount++;
cv.notify_all();
});
});
}
std::unique_lock<std::mutex> lk(mutex);
std::unique_lock lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]{ return putCount == 2*N; }));
CPPUNIT_ASSERT_EQUAL(2*N, putOkCount);
+12 -8
View File
@@ -1,18 +1,18 @@
{
"name": "opendht",
"version-string": "3.5.4",
"version-string": "3.6.0",
"port-version": 1,
"description": "OpenDHT: A lightweight C++17 Distributed Hash Table library.",
"homepage": "https://opendht.net",
"license": "GPL-3.0-or-later",
"dependencies": [
{
"name" : "vcpkg-cmake",
"host" : true
"name": "vcpkg-cmake",
"host": true
},
{
"name" : "vcpkg-cmake-config",
"host" : true
"name": "vcpkg-cmake-config",
"host": true
},
"fmt",
"nettle",
@@ -20,9 +20,13 @@
"msgpack",
"jsoncpp",
"asio",
"argon2"
"argon2",
"simdutf"
],
"default-features": [
"proxy",
"tools"
],
"default-features": ["proxy", "tools"],
"features": {
"proxy": {
"description": "DHT Proxy",
@@ -45,4 +49,4 @@
]
}
}
}
}