mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-09 12:57:03 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7987229145 | ||
|
|
966e6205ce | ||
|
|
7915b987ec | ||
|
|
29bdc1a46f | ||
|
|
e0d32e80fb | ||
|
|
e753d200c6 | ||
|
|
85fd395c52 | ||
|
|
0f146a354b | ||
|
|
9fcaca9232 | ||
|
|
1bc65bc5f5 | ||
|
|
478d28a326 | ||
|
|
4d544d53a8 | ||
|
|
694c44bbec | ||
|
|
16915ff424 | ||
|
|
a22566599c | ||
|
|
f9b2285593 | ||
|
|
9c2268fa41 | ||
|
|
d4e6fd545a | ||
|
|
dfd0a09361 | ||
|
|
0afa40820a | ||
|
|
f984a6a69a | ||
|
|
b4bbc6ae38 | ||
|
|
bc98d974cb | ||
|
|
785e54838b |
No files matched your search
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "C++",
|
||||
"build": {
|
||||
"dockerfile": "../docker/DockerfileDepsLlvm",
|
||||
},
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
|
||||
"settings": {},
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools"
|
||||
],
|
||||
"forwardPorts": [4222],
|
||||
}
|
||||
@@ -3,12 +3,11 @@ name: C/C++ CI
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
build-ubuntu:
|
||||
name: Ubuntu/GCC build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
- name: deps
|
||||
run: |
|
||||
sudo apt install libncurses5-dev libreadline-dev nettle-dev \
|
||||
@@ -29,3 +28,41 @@ jobs:
|
||||
run: make
|
||||
- name: make check
|
||||
run: make check
|
||||
|
||||
build-macos:
|
||||
name: macOS/Clang build
|
||||
runs-on: macos-11
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: deps
|
||||
run: |
|
||||
brew install msgpack-cxx asio gnutls nettle readline fmt jsoncpp argon2 openssl http-parser cppunit
|
||||
|
||||
- name: restinio
|
||||
run: |
|
||||
mkdir restinio && cd restinio
|
||||
wget https://github.com/aberaud/restinio/archive/e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz
|
||||
ls -l && tar -xzf e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz
|
||||
cd restinio-e0a261dd8488246a3cb8bbb3ea781ea5139c3c94/dev
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
|
||||
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
|
||||
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none .
|
||||
make -j8 && sudo make install
|
||||
cd ../../.. && rm -rf restinio
|
||||
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"
|
||||
export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
|
||||
export CPPFLAGS="-I/usr/local/opt/openssl@3/include"
|
||||
export PKG_CONFIG_PATH="/usr/local/opt/openssl@3/lib/pkgconfig"
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Debug \
|
||||
-DOPENDHT_C=On -DOPENDHT_TESTS=On -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off \
|
||||
-DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On
|
||||
|
||||
- name: make
|
||||
run: cd build && make
|
||||
|
||||
- name: make check
|
||||
run: cd build && ./opendht_unit_tests
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Clang Static Analysis
|
||||
on:
|
||||
push
|
||||
jobs:
|
||||
clang-analyzer:
|
||||
name: Clang Static Analysis
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: deps
|
||||
run: |
|
||||
sudo apt install libncurses5-dev libreadline-dev nettle-dev \
|
||||
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
|
||||
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev libargon2-0-dev libasio-dev \
|
||||
llvm llvm-dev clang clang-tools && \
|
||||
sudo apt remove gcc g++
|
||||
|
||||
- name: restinio
|
||||
run: |
|
||||
mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/aberaud/restinio/archive/e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
|
||||
&& ls -l && tar -xzf e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
|
||||
&& cd restinio-e0a261dd8488246a3cb8bbb3ea781ea5139c3c94/dev \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
|
||||
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
|
||||
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none . \
|
||||
&& make -j8 && sudo make install \
|
||||
&& cd ../../.. && rm -rf restinio
|
||||
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build && \
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DOPENDHT_C=On -DOPENDHT_PEER_DISCOVERY=On -DOPENDHT_PYTHON=Off -DOPENDHT_TOOLS=On -DOPENDHT_PROXY_SERVER=On -DOPENDHT_PROXY_CLIENT=On
|
||||
- name: scan-build
|
||||
run: cd build && scan-build --status-bugs make
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
dist: xenial
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- OPENDHT_TEST_JOB="opendht.classic"
|
||||
- OPENDHT_TEST_JOB="opendht.llvm"
|
||||
- OPENDHT_TEST_JOB="opendht.proxyserver"
|
||||
- OPENDHT_TEST_JOB="opendht.proxyclient"
|
||||
- OPENDHT_TEST_JOB="opendht.push"
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.classic"* ]]; then
|
||||
docker pull aberaud/opendht-deps-bionic;
|
||||
fi
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyclient"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyserver"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.push"* ]]; then
|
||||
docker pull aberaud/opendht-deps;
|
||||
fi
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.llvm"* ]]; then
|
||||
docker pull aberaud/opendht-deps-llvm
|
||||
fi
|
||||
|
||||
script:
|
||||
- |
|
||||
# classic build
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.classic"* ]]; then
|
||||
docker build -t opendht -f docker/DockerfileTravis .;
|
||||
fi
|
||||
|
||||
- |
|
||||
# proxy builds
|
||||
if [[ "$OPENDHT_TEST_JOB" != *"opendht.llvm"* ]] && [[ "$OPENDHT_TEST_JOB" != *"opendht.classic"* ]]; then
|
||||
docker build -t opendht-proxy -f docker/DockerfileTravisProxy .;
|
||||
options='-DOPENDHT_SANITIZE=On ';
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyserver"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.push"* ]]; then
|
||||
options+='-DOPENDHT_PROXY_SERVER=ON ';
|
||||
else
|
||||
options+='-DOPENDHT_PROXY_SERVER=OFF ';
|
||||
fi
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.proxyclient"* ]] || [[ "$OPENDHT_TEST_JOB" == *"opendht.push"* ]]; then
|
||||
options+='-DOPENDHT_PROXY_CLIENT=ON ';
|
||||
else
|
||||
options+='-DOPENDHT_PROXY_CLIENT=OFF ';
|
||||
fi
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.push"* ]]; then
|
||||
options+='-DOPENDHT_PUSH_NOTIFICATIONS=ON ';
|
||||
else
|
||||
options+='-DOPENDHT_PUSH_NOTIFICATIONS=OFF ';
|
||||
fi
|
||||
docker run opendht-proxy /bin/sh -c "cd /root/opendht && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=ON -DOPENDHT_LTO=ON -DOPENDHT_TESTS=ON $options .. && make -j8 && ./opendht_unit_tests && make install";
|
||||
fi
|
||||
|
||||
- |
|
||||
# llvm build
|
||||
if [[ "$OPENDHT_TEST_JOB" == *"opendht.llvm"* ]]; then
|
||||
docker build -f docker/DockerfileTravisLlvm .
|
||||
fi
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- adrien.beraud@savoirfairelinux.com
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "dhtnode",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/tools/dhtnode",
|
||||
"args": ["-v", "-p", "4222"],
|
||||
"cwd": "${workspaceFolder}/build",
|
||||
"environment": [],
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "build",
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"externalConsole": false,
|
||||
},
|
||||
"osx": {
|
||||
"MIMode": "lldb",
|
||||
"externalConsole": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/opendht_unit_tests",
|
||||
"cwd": "${workspaceFolder}/build",
|
||||
"environment": [],
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "build",
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"externalConsole": false,
|
||||
},
|
||||
"osx": {
|
||||
"MIMode": "lldb",
|
||||
"externalConsole": true,
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+44
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/build"
|
||||
},
|
||||
"command": "make",
|
||||
"args": ["-j4"],
|
||||
"dependsOn": "cmake"
|
||||
},
|
||||
{
|
||||
"label": "cmake",
|
||||
"type": "shell",
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/build"
|
||||
},
|
||||
"command": "cmake",
|
||||
"args": [
|
||||
"${workspaceRoot}",
|
||||
"-DCMAKE_BUILD_TYPE=Debug",
|
||||
"-DOPENDHT_PROXY_CLIENT=On",
|
||||
"-DOPENDHT_PROXY_SERVER=On",
|
||||
"-DOPENDHT_TESTS=On",
|
||||
"-DOPENDHT_C=On"
|
||||
],
|
||||
"dependsOn": "builddir"
|
||||
},
|
||||
{
|
||||
"label": "builddir",
|
||||
"type": "shell",
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
"command": "mkdir",
|
||||
"args": [
|
||||
"-p",
|
||||
"${workspaceRoot}/build"
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -99,7 +99,7 @@ for r in results:
|
||||
- (optional) restinio used for the REST API.
|
||||
- (optional) jsoncpp 1.7.4-3+, used for the REST API.
|
||||
- Build tested with GCC 7+ (GNU/Linux, Windows with MinGW), Clang/LLVM (GNU/Linux, Android, macOS, iOS).
|
||||
- Build tested with Microsoft Visual Studio 2017, 2019, 2021
|
||||
- Build tested with Microsoft Visual Studio 2017, 2019, 2022
|
||||
|
||||
## Contact
|
||||
|
||||
|
||||
+13
-19
@@ -12,8 +12,12 @@ function(check_working_cxx_atomics varname)
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <atomic>
|
||||
std::atomic<int> x;
|
||||
std::atomic<short> y;
|
||||
std::atomic<char> z;
|
||||
int main() {
|
||||
return x;
|
||||
++z;
|
||||
++y;
|
||||
return ++x;
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
@@ -42,15 +46,10 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
|
||||
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
|
||||
if( HAVE_LIBATOMIC )
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
message(FATAL_ERROR "Host compiler must support std::atomic!")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
message(FATAL_ERROR "Host compiler must support std::atomic!")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -64,15 +63,10 @@ endif()
|
||||
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
|
||||
if(HAVE_CXX_LIBATOMICS64)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ RUN echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
|
||||
RUN apt-get update && apt-get install -y \
|
||||
apt-transport-https build-essential pkg-config git wget libncurses5-dev libreadline-dev nettle-dev \
|
||||
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
|
||||
libargon2-0-dev \
|
||||
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev libssl-dev python3-pip \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
||||
|
||||
@@ -21,9 +22,9 @@ RUN echo "** Building a recent version of asio ***" \
|
||||
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/aberaud/restinio/archive/e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
|
||||
&& ls -l && tar -xzf e0a261dd8488246a3cb8bbb3ea781ea5139c3c94.tar.gz \
|
||||
&& cd restinio-e0a261dd8488246a3cb8bbb3ea781ea5139c3c94/dev \
|
||||
&& wget https://github.com/aberaud/restinio/archive/8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59.tar.gz \
|
||||
&& ls -l && tar -xzf 8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59.tar.gz \
|
||||
&& cd restinio-8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59/dev \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
|
||||
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
|
||||
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none . \
|
||||
|
||||
@@ -8,7 +8,7 @@ RUN apt-get update && apt-get install -y \
|
||||
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y llvm llvm-dev clang make cmake pkg-config git wget libncurses5-dev libreadline-dev \
|
||||
&& apt-get install -y llvm llvm-dev lldb clang gdb make cmake pkg-config git wget libncurses5-dev libreadline-dev \
|
||||
nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libjsoncpp-dev cython3 python3-dev \
|
||||
python3-setuptools libcppunit-dev python3-pip \
|
||||
autotools-dev autoconf libssl-dev libargon2-dev \
|
||||
|
||||
@@ -178,8 +178,8 @@ msgpack::object* findMapValue(const msgpack::object& map, const char* key, size_
|
||||
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, const std::string& key) {
|
||||
return findMapValue(map, key.c_str(), key.size());
|
||||
inline msgpack::object* findMapValue(const msgpack::object& map, std::string_view key) {
|
||||
return findMapValue(map, key.data(), key.size());
|
||||
}
|
||||
|
||||
} // namespace dht
|
||||
+10
-9
@@ -43,8 +43,9 @@
|
||||
#endif
|
||||
|
||||
namespace dht {
|
||||
using namespace std::literals;
|
||||
|
||||
static const std::string VALUE_KEY_ID("id");
|
||||
static constexpr auto VALUE_KEY_ID("id");
|
||||
static const std::string VALUE_KEY_DAT("dat");
|
||||
static const std::string VALUE_KEY_PRIO("p");
|
||||
static const std::string VALUE_KEY_SIGNATURE("sig");
|
||||
@@ -270,8 +271,8 @@ struct OPENDHT_PUBLIC Value
|
||||
};
|
||||
}
|
||||
|
||||
static Filter UserTypeFilter(const std::string& ut) {
|
||||
return [ut](const Value& v) {
|
||||
static Filter UserTypeFilter(std::string ut) {
|
||||
return [ut = std::move(ut)](const Value& v) {
|
||||
return v.user_type == ut;
|
||||
};
|
||||
}
|
||||
@@ -660,7 +661,7 @@ struct OPENDHT_PUBLIC FieldValue
|
||||
FieldValue() {}
|
||||
FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
|
||||
FieldValue(Value::Field f, InfoHash hash_value) : field(f), hashValue(hash_value) {}
|
||||
FieldValue(Value::Field f, Blob blob_value) : field(f), blobValue(blob_value) {}
|
||||
FieldValue(Value::Field f, Blob blob_value) : field(f), blobValue(std::move(blob_value)) {}
|
||||
|
||||
bool operator==(const FieldValue& fd) const;
|
||||
|
||||
@@ -673,9 +674,9 @@ struct OPENDHT_PUBLIC FieldValue
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const {
|
||||
p.pack_map(2);
|
||||
p.pack(std::string("f")); p.pack(static_cast<uint8_t>(field));
|
||||
p.pack("f"sv); p.pack(static_cast<uint8_t>(field));
|
||||
|
||||
p.pack(std::string("v"));
|
||||
p.pack("v"sv);
|
||||
switch (field) {
|
||||
case Value::Field::Id:
|
||||
case Value::Field::ValueType:
|
||||
@@ -697,12 +698,12 @@ struct OPENDHT_PUBLIC FieldValue
|
||||
hashValue = {};
|
||||
blobValue.clear();
|
||||
|
||||
if (auto f = findMapValue(msg, "f"))
|
||||
if (auto f = findMapValue(msg, "f"sv))
|
||||
field = (Value::Field)f->as<unsigned>();
|
||||
else
|
||||
throw msgpack::type_error();
|
||||
|
||||
auto v = findMapValue(msg, "v");
|
||||
auto v = findMapValue(msg, "v"sv);
|
||||
if (not v)
|
||||
throw msgpack::type_error();
|
||||
else
|
||||
@@ -864,7 +865,7 @@ struct OPENDHT_PUBLIC Where
|
||||
*
|
||||
* @return the resulting Where instance.
|
||||
*/
|
||||
Where& userType(std::string user_type) {
|
||||
Where& userType(std::string_view user_type) {
|
||||
FieldValue fv {Value::Field::UserType, Blob {user_type.begin(), user_type.end()}};
|
||||
if (std::find(filters_.begin(), filters_.end(), fv) == filters_.end())
|
||||
filters_.emplace_back(std::move(fv));
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the specified
|
||||
# version of the C++ standard. If necessary, add switches to CXX and
|
||||
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
|
||||
# or '14' (for the C++14 standard).
|
||||
# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for
|
||||
# the respective C++ standard version.
|
||||
#
|
||||
# The second argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
# preference for no added switch, and then for an extended mode.
|
||||
#
|
||||
# The third argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline support for the specified C++ standard is
|
||||
@@ -35,13 +35,15 @@
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
|
||||
# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
|
||||
# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
|
||||
# Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 11
|
||||
#serial 14
|
||||
|
||||
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
|
||||
dnl (serial version number 13).
|
||||
@@ -50,6 +52,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
|
||||
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
|
||||
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
|
||||
[$1], [20], [ax_cxx_compile_alternatives="20"],
|
||||
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$2], [], [],
|
||||
[$2], [ext], [],
|
||||
@@ -62,6 +65,16 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
|
||||
m4_if([$2], [], [dnl
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
|
||||
ax_cv_cxx_compile_cxx$1,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[ax_cv_cxx_compile_cxx$1=yes],
|
||||
[ax_cv_cxx_compile_cxx$1=no])])
|
||||
if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
|
||||
ac_success=yes
|
||||
fi])
|
||||
|
||||
m4_if([$2], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
@@ -140,7 +153,6 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
)
|
||||
|
||||
|
||||
dnl Test body for checking C++14 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
|
||||
@@ -148,12 +160,24 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
)
|
||||
|
||||
dnl Test body for checking C++17 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
|
||||
)
|
||||
|
||||
dnl Test body for checking C++20 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_20
|
||||
)
|
||||
|
||||
|
||||
dnl Tests for new features in C++11
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
|
||||
@@ -949,3 +973,33 @@ namespace cxx17
|
||||
#endif // __cplusplus < 201703L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++20
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 202002L
|
||||
|
||||
#error "This is not a C++20 compiler"
|
||||
|
||||
#else
|
||||
|
||||
#include <version>
|
||||
|
||||
namespace cxx20
|
||||
{
|
||||
|
||||
// As C++20 supports feature test macros in the standard, there is no
|
||||
// immediate need to actually test for feature availability on the
|
||||
// Autoconf side.
|
||||
|
||||
} // namespace cxx20
|
||||
|
||||
#endif // __cplusplus < 202002L
|
||||
|
||||
]])
|
||||
+3
-1
@@ -1057,6 +1057,8 @@ Certificate::generateOcspRequest(gnutls_x509_crt_t& issuer)
|
||||
Blob noncebuf(32);
|
||||
gnutls_datum_t nonce = { noncebuf.data(), (unsigned)noncebuf.size() };
|
||||
err = gnutls_rnd(GNUTLS_RND_NONCE, nonce.data, nonce.size);
|
||||
if (err < 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
err = gnutls_ocsp_req_set_nonce(req.get(), 0, &nonce);
|
||||
if (err < 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
@@ -1473,7 +1475,7 @@ RevocationList::RevocationList(const Blob& b)
|
||||
} catch (const std::exception& e) {
|
||||
gnutls_x509_crl_deinit(crl);
|
||||
crl = nullptr;
|
||||
throw e;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,15 +41,15 @@ struct DhtProxyClient::OperationState {
|
||||
struct DhtProxyClient::Listener
|
||||
{
|
||||
Listener(OpValueCache&& c):
|
||||
cache(std::move(c))
|
||||
{}
|
||||
cache(std::move(c)) {}
|
||||
|
||||
unsigned callbackId;
|
||||
OpValueCache cache;
|
||||
CacheValueCallback cb;
|
||||
Sp<OperationState> opstate;
|
||||
std::shared_ptr<http::Request> request;
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
std::unique_ptr<asio::steady_timer> refreshSubscriberTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PermanentPut {
|
||||
@@ -814,6 +814,7 @@ DhtProxyClient::listen(const InfoHash& key, ValueCallback cb, Value::Filter filt
|
||||
}
|
||||
return false;
|
||||
};
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
if (not deviceKey_.empty()) {
|
||||
/*
|
||||
* Relaunch push listeners even if a timeout is not received
|
||||
@@ -826,6 +827,7 @@ DhtProxyClient::listen(const InfoHash& key, ValueCallback cb, Value::Filter filt
|
||||
l->second.refreshSubscriberTimer->async_wait(std::bind(&DhtProxyClient::handleResubscribe, this,
|
||||
std::placeholders::_1, key, token, opstate));
|
||||
}
|
||||
#endif
|
||||
ListenMethod method;
|
||||
restinio::http_request_header_t header;
|
||||
if (deviceKey_.empty()){ // listen
|
||||
@@ -1229,7 +1231,7 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
|
||||
ids.emplace_back(std::stoull(substr));
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lockCallbacks_);
|
||||
std::lock_guard<std::mutex> lockCb(lockCallbacks_);
|
||||
callbacks_.emplace_back([this, key, token, opstate, ids, sendTime]() {
|
||||
if (opstate->stop)
|
||||
return;
|
||||
|
||||
+15
-14
@@ -38,6 +38,7 @@
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace dht {
|
||||
constexpr char RESP_MSG_JSON_INCORRECT[] = "{\"err:\":\"Incorrect JSON\"}";
|
||||
@@ -99,7 +100,7 @@ class DhtProxyServer::ConnectionListener
|
||||
{
|
||||
public:
|
||||
ConnectionListener() {};
|
||||
ConnectionListener(std::function<void(restinio::connection_id_t)> onClosed) : onClosed_(std::move(onClosed)) {};
|
||||
explicit ConnectionListener(std::function<void(restinio::connection_id_t)> onClosed) : onClosed_(std::move(onClosed)) {};
|
||||
~ConnectionListener() {};
|
||||
|
||||
/**
|
||||
@@ -151,25 +152,25 @@ struct DhtProxyServer::RestRouterTraits : public restinio::default_traits_t
|
||||
void
|
||||
DhtProxyServer::PermanentPut::msgpack_unpack(const msgpack::object& o)
|
||||
{
|
||||
if (auto cid = findMapValue(o, "cid")) {
|
||||
if (auto cid = findMapValue(o, "cid"sv)) {
|
||||
clientId = cid->as<std::string>();
|
||||
}
|
||||
if (auto exp = findMapValue(o, "exp")) {
|
||||
if (auto exp = findMapValue(o, "exp"sv)) {
|
||||
expiration = from_time_t(exp->as<time_t>());
|
||||
}
|
||||
if (auto token = findMapValue(o, "token")) {
|
||||
if (auto token = findMapValue(o, "token"sv)) {
|
||||
pushToken = token->as<std::string>();
|
||||
}
|
||||
if (auto sid = findMapValue(o, "sid")) {
|
||||
if (auto sid = findMapValue(o, "sid"sv)) {
|
||||
if (not sessionCtx)
|
||||
sessionCtx = std::make_shared<PushSessionContext>(sid->as<std::string>());
|
||||
else
|
||||
sessionCtx->sessionId = sid->as<std::string>();
|
||||
}
|
||||
if (auto t = findMapValue(o, "t")) {
|
||||
if (auto t = findMapValue(o, "t"sv)) {
|
||||
type = t->as<PushType>();
|
||||
}
|
||||
if (auto val = findMapValue(o, "value")) {
|
||||
if (auto val = findMapValue(o, "value"sv)) {
|
||||
value = std::make_shared<dht::Value>(*val);
|
||||
}
|
||||
}
|
||||
@@ -178,19 +179,19 @@ DhtProxyServer::PermanentPut::msgpack_unpack(const msgpack::object& o)
|
||||
void
|
||||
DhtProxyServer::Listener::msgpack_unpack(const msgpack::object& o)
|
||||
{
|
||||
if (auto cid = findMapValue(o, "cid")) {
|
||||
if (auto cid = findMapValue(o, "cid"sv)) {
|
||||
clientId = cid->as<std::string>();
|
||||
}
|
||||
if (auto exp = findMapValue(o, "exp")) {
|
||||
if (auto exp = findMapValue(o, "exp"sv)) {
|
||||
expiration = from_time_t(exp->as<time_t>());
|
||||
}
|
||||
if (auto sid = findMapValue(o, "sid")) {
|
||||
if (auto sid = findMapValue(o, "sid"sv)) {
|
||||
if (not sessionCtx)
|
||||
sessionCtx = std::make_shared<PushSessionContext>(sid->as<std::string>());
|
||||
else
|
||||
sessionCtx->sessionId = sid->as<std::string>();
|
||||
}
|
||||
if (auto t = findMapValue(o, "t")) {
|
||||
if (auto t = findMapValue(o, "t"sv)) {
|
||||
type = t->as<PushType>();
|
||||
}
|
||||
}
|
||||
@@ -345,7 +346,7 @@ DhtProxyServer::loadState(Is& is, size_t size) {
|
||||
while (pac.next(oh)) {
|
||||
if (oh.get().type != msgpack::type::MAP)
|
||||
continue;
|
||||
if (auto puts = findMapValue(oh.get(), "puts")) {
|
||||
if (auto puts = findMapValue(oh.get(), "puts"sv)) {
|
||||
std::lock_guard<std::mutex> lock(lockSearchPuts_);
|
||||
puts_ = puts->as<decltype(puts_)>();
|
||||
if (logger_)
|
||||
@@ -382,9 +383,9 @@ DhtProxyServer::loadState(Is& is, size_t size) {
|
||||
logger_->d("No persistent puts in state");
|
||||
}
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
if (auto listeners = findMapValue(oh.get(), "pushListeners")) {
|
||||
if (auto pushListeners = findMapValue(oh.get(), "pushListeners"sv)) {
|
||||
std::lock_guard<std::mutex> lock(lockListener_);
|
||||
pushListeners_ = listeners->as<decltype(pushListeners_)>();
|
||||
pushListeners_ = pushListeners->as<decltype(pushListeners_)>();
|
||||
if (logger_)
|
||||
logger_->d("Loading %zu push listeners", pushListeners_.size());
|
||||
for (auto& pushListener : pushListeners_) {
|
||||
|
||||
+2
-2
@@ -181,8 +181,8 @@ DhtRunner::run(const Config& config, Context&& context)
|
||||
config_ = config;
|
||||
identityAnnouncedCb_ = context.identityAnnouncedCb;
|
||||
#endif
|
||||
auto dht = std::unique_ptr<DhtInterface>(new Dht(std::move(context.sock), SecureDht::getConfig(config.dht_config), context.logger));
|
||||
dht_ = std::unique_ptr<SecureDht>(new SecureDht(std::move(dht), config.dht_config, std::move(context.identityAnnouncedCb), context.logger));
|
||||
auto dht = std::make_unique<Dht>(std::move(context.sock), SecureDht::getConfig(config.dht_config), context.logger);
|
||||
dht_ = std::make_unique<SecureDht>(std::move(dht), config.dht_config, std::move(context.identityAnnouncedCb), context.logger);
|
||||
enableProxy(not config.proxy_server.empty());
|
||||
} catch(const std::exception& e) {
|
||||
config_ = {};
|
||||
|
||||
+4
-2
@@ -22,6 +22,8 @@
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace dht {
|
||||
|
||||
const HexMap hex_map = {};
|
||||
@@ -33,9 +35,9 @@ NodeExport::msgpack_unpack(msgpack::object o)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.size < 2)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.ptr[0].key.as<std::string>() != "id")
|
||||
if (o.via.map.ptr[0].key.as<std::string_view>() != "id"sv)
|
||||
throw msgpack::type_error();
|
||||
if (o.via.map.ptr[1].key.as<std::string>() != "addr")
|
||||
if (o.via.map.ptr[1].key.as<std::string_view>() != "addr"sv)
|
||||
throw msgpack::type_error();
|
||||
const auto& addr = o.via.map.ptr[1].val;
|
||||
if (addr.type != msgpack::type::BIN)
|
||||
|
||||
+2
-2
@@ -38,7 +38,7 @@ printLog(std::ostream& s, char const *m, va_list args) {
|
||||
// print log to buffer
|
||||
std::array<char, 8192> buffer;
|
||||
int ret = vsnprintf(buffer.data(), buffer.size(), m, args);
|
||||
if (ret < 0)
|
||||
if (ret <= 0)
|
||||
return;
|
||||
|
||||
// write timestamp
|
||||
@@ -89,7 +89,7 @@ std::shared_ptr<Logger>
|
||||
getSyslogLogger(const char* name) {
|
||||
#ifndef _WIN32
|
||||
struct Syslog {
|
||||
Syslog(const char* n) {
|
||||
explicit Syslog(const char* n) {
|
||||
openlog(n, LOG_NDELAY, LOG_USER);
|
||||
}
|
||||
~Syslog() {
|
||||
|
||||
+10
-10
@@ -219,7 +219,7 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c
|
||||
Tid tid (n->getNewTid());
|
||||
|
||||
pk.pack(KEY_Q); pk.pack(QUERY_UPDATE);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::UpdateValue, tid, n,
|
||||
Blob(buffer.data(), buffer.data() + buffer.size()),
|
||||
@@ -460,9 +460,9 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, SockAddr f)
|
||||
// process the full message
|
||||
process(std::move(pmsg_it->second.msg), from);
|
||||
partial_messages.erase(pmsg_it);
|
||||
} catch (...) {
|
||||
} catch (...) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else
|
||||
scheduler.add(now + RX_TIMEOUT, std::bind(&NetworkEngine::maintainRxBuffer, this, msg->tid));
|
||||
}
|
||||
@@ -485,11 +485,11 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, SockAddr f)
|
||||
}
|
||||
|
||||
if (msg->value_parts.empty()) {
|
||||
try {
|
||||
try {
|
||||
process(std::move(msg), from);
|
||||
} catch(...) {
|
||||
} catch(...) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// starting partial message session
|
||||
auto k = msg->tid;
|
||||
@@ -955,8 +955,8 @@ NetworkEngine::sendValueParts(Tid tid, const std::vector<Blob>& svals, const Soc
|
||||
pk.pack(KEY_TID); pk.pack(tid);
|
||||
pk.pack(KEY_V); pk.pack_map(1);
|
||||
pk.pack(i); pk.pack_map(2);
|
||||
pk.pack(std::string("o")); pk.pack(start);
|
||||
pk.pack(std::string("d")); pk.pack_bin(end-start);
|
||||
pk.pack("o"sv); pk.pack(start);
|
||||
pk.pack("d"sv); pk.pack_bin(end-start);
|
||||
pk.pack_bin_body((const char*)v.data()+start, end-start);
|
||||
send(addr, buffer.data(), buffer.size());
|
||||
start = end;
|
||||
@@ -998,8 +998,8 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
|
||||
auto fields = query.select.getSelection();
|
||||
pk.pack(KEY_REQ_FIELDS);
|
||||
pk.pack_map(2);
|
||||
pk.pack(std::string("f")); pk.pack(fields);
|
||||
pk.pack(std::string("v")); pk.pack_array(st.size()*fields.size());
|
||||
pk.pack("f"sv); pk.pack(fields);
|
||||
pk.pack("v"sv); pk.pack_array(st.size()*fields.size());
|
||||
for (const auto& v : st)
|
||||
v->msgpack_pack_fields(fields, pk);
|
||||
//DHT_LOG_DBG("sending closest nodes (%d+%d nodes.), %u value headers containing %u fields",
|
||||
|
||||
+1
-4
@@ -137,10 +137,7 @@ Node::openSocket(SocketCb&& cb)
|
||||
if (++transaction_id == 0)
|
||||
transaction_id = 1;
|
||||
|
||||
auto sock = std::make_shared<Socket>(std::move(cb));
|
||||
auto s = sockets_.emplace(transaction_id, std::move(sock));
|
||||
if (not s.second)
|
||||
s.first->second = std::move(sock);
|
||||
sockets_[transaction_id] = std::make_shared<Socket>(std::move(cb));
|
||||
return transaction_id;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ SearchCache::listen(const ValueCallback& get_cb, const Sp<Query>& q, const Value
|
||||
auto op = getOp(q);
|
||||
if (op == ops.end()) {
|
||||
// New query
|
||||
op = ops.emplace(q, std::unique_ptr<OpCache>(new OpCache)).first;
|
||||
op = ops.emplace(q, std::make_unique<OpCache>()).first;
|
||||
auto& cache = *op->second;
|
||||
cache.searchToken = onListen(q, [&](const std::vector<Sp<Value>>& values, bool expired){
|
||||
return cache.onValue(values, expired);
|
||||
|
||||
+3
-3
@@ -28,13 +28,13 @@ struct OpCacheValueStorage
|
||||
Sp<Value> data {};
|
||||
unsigned refCount {1};
|
||||
system_clock::time_point updated {system_clock::time_point::min()};
|
||||
OpCacheValueStorage(Sp<Value> val) : data(val) {}
|
||||
explicit OpCacheValueStorage(Sp<Value> val) : data(val) {}
|
||||
};
|
||||
|
||||
class OpValueCache {
|
||||
public:
|
||||
OpValueCache(ValueCallback&& cb) noexcept : callback(std::forward<ValueCallback>(cb)) {}
|
||||
OpValueCache(OpValueCache&& o) noexcept : values(std::move(o.values)), callback(std::move(o.callback)) {
|
||||
explicit OpValueCache(OpValueCache&& o) noexcept : values(std::move(o.values)), callback(std::move(o.callback)) {
|
||||
o.callback = {};
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
return cache.size();
|
||||
}
|
||||
|
||||
size_t searchToken;
|
||||
size_t searchToken {0};
|
||||
private:
|
||||
constexpr static const std::chrono::seconds EXPIRATION {60};
|
||||
OpCache(const OpCache&) = delete;
|
||||
|
||||
+47
-44
@@ -22,47 +22,50 @@
|
||||
#include "net.h"
|
||||
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
static const std::string KEY_Y {"y"};
|
||||
static const std::string KEY_R {"r"};
|
||||
static const std::string KEY_U {"u"};
|
||||
static const std::string KEY_E {"e"};
|
||||
static const std::string KEY_V {"p"};
|
||||
static const std::string KEY_TID {"t"};
|
||||
static const std::string KEY_UA {"v"};
|
||||
static const std::string KEY_NETID {"n"};
|
||||
static const std::string KEY_ISCLIENT {"s"};
|
||||
static const std::string KEY_Q {"q"};
|
||||
static const std::string KEY_A {"a"};
|
||||
static constexpr auto KEY_Y = "y"sv;
|
||||
static constexpr auto KEY_R = "r"sv;
|
||||
static constexpr auto KEY_U = "u"sv;
|
||||
static constexpr auto KEY_E = "e"sv;
|
||||
static constexpr auto KEY_V = "p"sv;
|
||||
static constexpr auto KEY_TID = "t"sv;
|
||||
static constexpr auto KEY_UA = "v"sv;
|
||||
static constexpr auto KEY_NETID = "n"sv;
|
||||
static constexpr auto KEY_ISCLIENT = "s"sv;
|
||||
static constexpr auto KEY_Q = "q"sv;
|
||||
static constexpr auto KEY_A = "a"sv;
|
||||
|
||||
static const std::string KEY_REQ_SID {"sid"};
|
||||
static const std::string KEY_REQ_ID {"id"};
|
||||
static const std::string KEY_REQ_H {"h"};
|
||||
static const std::string KEY_REQ_TARGET {"target"};
|
||||
static const std::string KEY_REQ_QUERY {"q"};
|
||||
static const std::string KEY_REQ_TOKEN {"token"};
|
||||
static const std::string KEY_REQ_VALUE_ID {"vid"};
|
||||
static const std::string KEY_REQ_NODES4 {"n4"};
|
||||
static const std::string KEY_REQ_NODES6 {"n6"};
|
||||
static const std::string KEY_REQ_CREATION {"c"};
|
||||
static const std::string KEY_REQ_ADDRESS {"sa"};
|
||||
static const std::string KEY_REQ_VALUES {"values"};
|
||||
static const std::string KEY_REQ_EXPIRED {"exp"};
|
||||
static const std::string KEY_REQ_REFRESHED {"re"};
|
||||
static const std::string KEY_REQ_FIELDS {"fileds"};
|
||||
static const std::string KEY_REQ_WANT {"w"};
|
||||
static const std::string KEY_VERSION {"ve"};
|
||||
static constexpr auto KEY_REQ_SID = "sid"sv;
|
||||
static constexpr auto KEY_REQ_ID = "id"sv;
|
||||
static constexpr auto KEY_REQ_H = "h"sv;
|
||||
static constexpr auto KEY_REQ_TARGET = "target"sv;
|
||||
static constexpr auto KEY_REQ_QUERY = "q"sv;
|
||||
static constexpr auto KEY_REQ_TOKEN = "token"sv;
|
||||
static constexpr auto KEY_REQ_VALUE_ID = "vid"sv;
|
||||
static constexpr auto KEY_REQ_NODES4 = "n4"sv;
|
||||
static constexpr auto KEY_REQ_NODES6 = "n6"sv;
|
||||
static constexpr auto KEY_REQ_CREATION = "c"sv;
|
||||
static constexpr auto KEY_REQ_ADDRESS = "sa"sv;
|
||||
static constexpr auto KEY_REQ_VALUES = "values"sv;
|
||||
static constexpr auto KEY_REQ_EXPIRED = "exp"sv;
|
||||
static constexpr auto KEY_REQ_REFRESHED = "re"sv;
|
||||
static constexpr auto KEY_REQ_FIELDS = "fileds"sv;
|
||||
static constexpr auto KEY_REQ_WANT = "w"sv;
|
||||
static constexpr auto KEY_VERSION = "ve"sv;
|
||||
|
||||
static const std::string QUERY_PING {"ping"};
|
||||
static const std::string QUERY_FIND {"find"};
|
||||
static const std::string QUERY_GET {"get"};
|
||||
static const std::string QUERY_UPDATE {"update"};
|
||||
static const std::string QUERY_PUT {"put"};
|
||||
static const std::string QUERY_LISTEN {"listen"};
|
||||
static const std::string QUERY_REFRESH {"refresh"};
|
||||
static constexpr auto QUERY_PING = "ping"sv;
|
||||
static constexpr auto QUERY_FIND = "find"sv;
|
||||
static constexpr auto QUERY_GET = "get"sv;
|
||||
static constexpr auto QUERY_UPDATE = "update"sv;
|
||||
static constexpr auto QUERY_PUT = "put"sv;
|
||||
static constexpr auto QUERY_LISTEN = "listen"sv;
|
||||
static constexpr auto QUERY_REFRESH = "refresh"sv;
|
||||
|
||||
Tid unpackTid(const msgpack::object& o) {
|
||||
switch (o.type) {
|
||||
@@ -173,14 +176,14 @@ ParsedMessage::msgpack_unpack(const msgpack::object& msg)
|
||||
msgpack::object* e;
|
||||
msgpack::object* v;
|
||||
msgpack::object* a;
|
||||
std::string q;
|
||||
std::string_view q;
|
||||
} parsed {};
|
||||
|
||||
for (unsigned i = 0; i < msg.via.map.size; i++) {
|
||||
auto& o = msg.via.map.ptr[i];
|
||||
if (o.key.type != msgpack::type::STR)
|
||||
continue;
|
||||
auto key = o.key.as<std::string>();
|
||||
auto key = o.key.as<std::string_view>();
|
||||
if (key == KEY_Y)
|
||||
parsed.y = &o.val;
|
||||
else if (key == KEY_R)
|
||||
@@ -200,7 +203,7 @@ ParsedMessage::msgpack_unpack(const msgpack::object& msg)
|
||||
else if (key == KEY_ISCLIENT)
|
||||
is_client = o.val.as<bool>();
|
||||
else if (key == KEY_Q)
|
||||
parsed.q = o.val.as<std::string>();
|
||||
parsed.q = o.val.as<std::string_view>();
|
||||
else if (key == KEY_A)
|
||||
parsed.a = &o.val;
|
||||
}
|
||||
@@ -213,7 +216,7 @@ ParsedMessage::msgpack_unpack(const msgpack::object& msg)
|
||||
type = MessageType::ValueData;
|
||||
else if (parsed.u)
|
||||
type = MessageType::ValueUpdate;
|
||||
else if (parsed.y and parsed.y->as<std::string>() != "q")
|
||||
else if (parsed.y and parsed.y->as<std::string_view>() != "q"sv)
|
||||
throw msgpack::type_error();
|
||||
else if (parsed.q == QUERY_PING)
|
||||
type = MessageType::Ping;
|
||||
@@ -237,8 +240,8 @@ ParsedMessage::msgpack_unpack(const msgpack::object& msg)
|
||||
throw msgpack::type_error();
|
||||
for (size_t i = 0; i < parsed.v->via.map.size; ++i) {
|
||||
auto& vdat = parsed.v->via.map.ptr[i];
|
||||
auto o = findMapValue(vdat.val, "o");
|
||||
auto d = findMapValue(vdat.val, "d");
|
||||
auto o = findMapValue(vdat.val, "o"sv);
|
||||
auto d = findMapValue(vdat.val, "d"sv);
|
||||
if (not o or not d)
|
||||
continue;
|
||||
value_parts.emplace(vdat.key.as<unsigned>(), std::pair<size_t, Blob>(o->as<size_t>(), unpackBlob(*d)));
|
||||
@@ -267,7 +270,7 @@ ParsedMessage::msgpack_unpack(const msgpack::object& msg)
|
||||
auto& o = req.via.map.ptr[i];
|
||||
if (o.key.type != msgpack::type::STR)
|
||||
continue;
|
||||
auto key = o.key.as<std::string>();
|
||||
auto key = o.key.as<std::string_view>();
|
||||
if (key == KEY_REQ_SID)
|
||||
socket_id = unpackTid(o.val);
|
||||
else if (key == KEY_REQ_ID)
|
||||
@@ -341,9 +344,9 @@ ParsedMessage::msgpack_unpack(const msgpack::object& msg)
|
||||
}
|
||||
}
|
||||
} else if (parsedReq.fields) {
|
||||
if (auto rfields = findMapValue(*parsedReq.fields, "f")) {
|
||||
if (auto rfields = findMapValue(*parsedReq.fields, "f"sv)) {
|
||||
auto vfields = rfields->as<std::set<Value::Field>>();
|
||||
if (auto rvalues = findMapValue(*parsedReq.fields, "v")) {
|
||||
if (auto rvalues = findMapValue(*parsedReq.fields, "v"sv)) {
|
||||
if (rvalues->type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
size_t val_num = rvalues->via.array.size / vfields.size();
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <asio.hpp>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace dht {
|
||||
|
||||
// Organization-local Scope multicast
|
||||
@@ -61,7 +63,7 @@ private:
|
||||
|
||||
msgpack::sbuffer sbuf_;
|
||||
std::map<std::string, msgpack::sbuffer> messages_;
|
||||
std::map<std::string, ServiceDiscoveredCallback> callbackmap_;
|
||||
std::map<std::string, ServiceDiscoveredCallback, std::less<>> callbackmap_;
|
||||
bool lrunning_ {false};
|
||||
bool drunning_ {false};
|
||||
|
||||
@@ -133,19 +135,18 @@ PeerDiscovery::DomainPeerDiscovery::loopListener()
|
||||
msgpack::object obj = rcv.get();
|
||||
|
||||
if (obj.type == msgpack::type::STR) {
|
||||
if (lrunning_ and obj.as<std::string>() == "q")
|
||||
if (lrunning_ and obj.as<std::string_view>() == "q"sv)
|
||||
publish(receiveFrom_);
|
||||
} else if (obj.type == msgpack::type::MAP) {
|
||||
for (unsigned i = 0; i < obj.via.map.size; i++) {
|
||||
auto& o = obj.via.map.ptr[i];
|
||||
if (o.key.type != msgpack::type::STR)
|
||||
continue;
|
||||
auto key = o.key.as<std::string>();
|
||||
ServiceDiscoveredCallback cb;
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(dmtx_);
|
||||
if (drunning_) {
|
||||
auto callback = callbackmap_.find(key);
|
||||
auto callback = callbackmap_.find(o.key.as<std::string_view>());
|
||||
if (callback != callbackmap_.end())
|
||||
cb = callback->second;
|
||||
} else
|
||||
|
||||
+14
-15
@@ -164,12 +164,12 @@ struct Dht::SearchNode {
|
||||
if (node->isExpired())
|
||||
return false;
|
||||
|
||||
bool pending {false},
|
||||
bool is_pending {false},
|
||||
completed_sq_status {false},
|
||||
pending_sq_status {false};
|
||||
for (const auto& s : getStatus) {
|
||||
if (s.second and s.second->pending())
|
||||
pending = true;
|
||||
is_pending = true;
|
||||
if (s.first and q and q->isSatisfiedBy(*s.first) and s.second) {
|
||||
if (s.second->pending())
|
||||
pending_sq_status = true;
|
||||
@@ -180,7 +180,7 @@ struct Dht::SearchNode {
|
||||
}
|
||||
}
|
||||
|
||||
return (not pending and now > last_get_reply + Node::NODE_EXPIRE_TIME) or
|
||||
return (not is_pending and now > last_get_reply + Node::NODE_EXPIRE_TIME) or
|
||||
not (completed_sq_status or pending_sq_status or hasStartedPagination(q));
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ struct Dht::SearchNode {
|
||||
return std::find_if(status.cbegin(), status.cend(),
|
||||
[](const SyncStatus::value_type& r){
|
||||
return r.second and r.second->pending();
|
||||
}) != status.end();
|
||||
}) != status.cend();
|
||||
}
|
||||
static bool pending(const NodeListenerStatus& status) {
|
||||
return std::find_if(status.begin(), status.end(),
|
||||
@@ -437,13 +437,13 @@ struct Dht::Search {
|
||||
~Search() {
|
||||
if (opExpirationJob)
|
||||
opExpirationJob->cancel();
|
||||
for (auto& get : callbacks) {
|
||||
get.second.done_cb(false, {});
|
||||
get.second.done_cb = {};
|
||||
for (auto& g : callbacks) {
|
||||
g.second.done_cb(false, {});
|
||||
g.second.done_cb = {};
|
||||
}
|
||||
for (auto& put : announce) {
|
||||
put.callback(false, {});
|
||||
put.callback = {};
|
||||
for (auto& a : announce) {
|
||||
a.callback(false, {});
|
||||
a.callback = {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ struct Dht::Search {
|
||||
bool insertNode(const Sp<Node>& n, time_point now, const Blob& token={});
|
||||
|
||||
SearchNode* getNode(const Sp<Node>& n) {
|
||||
auto srn = std::find_if(nodes.begin(), nodes.end(), [&](std::unique_ptr<SearchNode>& sn) {
|
||||
auto srn = std::find_if(nodes.begin(), nodes.end(), [&](const std::unique_ptr<SearchNode>& sn) {
|
||||
return n == sn->node;
|
||||
});
|
||||
return (srn == nodes.end()) ? nullptr : (*srn).get();
|
||||
@@ -665,12 +665,11 @@ struct Dht::Search {
|
||||
}
|
||||
unsigned getNumberOfConsecutiveBadNodes() const {
|
||||
unsigned count = 0;
|
||||
std::find_if(nodes.begin(), nodes.end(), [&count](const std::unique_ptr<SearchNode>& sn) {
|
||||
for (const auto& sn : nodes) {
|
||||
if (not sn->node->isExpired())
|
||||
return true;
|
||||
break;
|
||||
++count;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -482,13 +482,13 @@ Query::msgpack_unpack(const msgpack::object& o)
|
||||
if (o.type != msgpack::type::MAP)
|
||||
throw msgpack::type_error();
|
||||
|
||||
auto rfilters = findMapValue(o, "w"); /* unpacking filters */
|
||||
auto rfilters = findMapValue(o, "w"sv); /* unpacking filters */
|
||||
if (rfilters)
|
||||
where.msgpack_unpack(*rfilters);
|
||||
else
|
||||
throw msgpack::type_error();
|
||||
|
||||
auto rfield_selector = findMapValue(o, "s"); /* unpacking field selectors */
|
||||
auto rfield_selector = findMapValue(o, "s"sv); /* unpacking field selectors */
|
||||
if (rfield_selector)
|
||||
select.msgpack_unpack(*rfield_selector);
|
||||
else
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ using CallbackQueue = std::list<std::function<void()>>;
|
||||
|
||||
class ValueCache {
|
||||
public:
|
||||
ValueCache(ValueStateCallback&& cb, SyncCallback&& scb = {})
|
||||
explicit ValueCache(ValueStateCallback&& cb, SyncCallback&& scb = {})
|
||||
: callback(std::forward<ValueStateCallback>(cb)), syncCallback(std::move(scb))
|
||||
{
|
||||
if (syncCallback)
|
||||
|
||||
@@ -147,6 +147,7 @@ DhtRunnerTester::testListen() {
|
||||
if (ok) putOkCount++;
|
||||
cv.notify_all();
|
||||
});
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
+13
-6
@@ -327,15 +327,17 @@ void cmd_loop(std::shared_ptr<DhtRunner>& node, dht_params& params
|
||||
if (op == "g") {
|
||||
std::string rem;
|
||||
std::getline(iss, rem);
|
||||
node->get(id, [start](const std::vector<std::shared_ptr<Value>>& values) {
|
||||
auto total = std::make_shared<size_t>();
|
||||
node->get(id, [start, total](const std::vector<std::shared_ptr<Value>>& values) {
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
std::cout << "Get: found " << values.size() << " value(s) after " << print_duration(now-start) << std::endl;
|
||||
(*total) += values.size();
|
||||
std::cout << "Get: found " << values.size() << " value(s) after " << print_duration(now-start) << " (total " << *total << ')' << std::endl;
|
||||
for (const auto& value : values)
|
||||
std::cout << "\t" << *value << std::endl;
|
||||
return true;
|
||||
}, [start](bool ok) {
|
||||
}, [start, total](bool ok) {
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::cout << "Get: " << (ok ? "completed" : "failure") << ", took " << print_duration(end-start) << std::endl;
|
||||
std::cout << "Get: " << (ok ? "completed" : "failure") << ", took " << print_duration(end-start) << " (total " << *total << ')' << std::endl;
|
||||
}, {}, dht::Where {rem});
|
||||
}
|
||||
else if (op == "q") {
|
||||
@@ -356,8 +358,13 @@ void cmd_loop(std::shared_ptr<DhtRunner>& node, dht_params& params
|
||||
else if (op == "l") {
|
||||
std::string rem;
|
||||
std::getline(iss, rem);
|
||||
auto token = node->listen(id, [](const std::vector<std::shared_ptr<Value>>& values, bool expired) {
|
||||
std::cout << "Listen: found " << values.size() << " values" << (expired ? " expired" : "") << std::endl;
|
||||
auto total = std::make_shared<size_t>();
|
||||
auto token = node->listen(id, [total](const std::vector<std::shared_ptr<Value>>& values, bool expired) {
|
||||
if (expired)
|
||||
(*total) -= values.size();
|
||||
else
|
||||
(*total) += values.size();
|
||||
std::cout << "Listen: found " << values.size() << " values" << (expired ? " expired" : "") << " (total " << *total << ')' << std::endl;
|
||||
for (const auto& value : values)
|
||||
std::cout << "\t" << *value << std::endl;
|
||||
return true;
|
||||
|
||||
Reference in new issue
Block a user