mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 12:28:42 +00:00
Compare commits
286
Commits
dht_bootstrap
..
pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebf2362b00 | ||
|
|
fe6676f2e6 | ||
|
|
619a2d89e2 | ||
|
|
7915b987ec | ||
|
|
29bdc1a46f | ||
|
|
e0d32e80fb | ||
|
|
e753d200c6 | ||
|
|
85fd395c52 | ||
|
|
0f146a354b | ||
|
|
9fcaca9232 | ||
|
|
1bc65bc5f5 | ||
|
|
478d28a326 | ||
|
|
4d544d53a8 | ||
|
|
694c44bbec | ||
|
|
16915ff424 | ||
|
|
a22566599c | ||
|
|
f9b2285593 | ||
|
|
9c2268fa41 | ||
|
|
d4e6fd545a | ||
|
|
dfd0a09361 | ||
|
|
0afa40820a | ||
|
|
f984a6a69a | ||
|
|
b4bbc6ae38 | ||
|
|
bc98d974cb | ||
|
|
785e54838b | ||
|
|
bb7611fc3d | ||
|
|
f675a6bdd3 | ||
|
|
21a71b1559 | ||
|
|
ca5455302d | ||
|
|
f206a8ac9e | ||
|
|
0c4cec66ff | ||
|
|
a03124d889 | ||
|
|
9691746fde | ||
|
|
d7c9311014 | ||
|
|
290e8594b6 | ||
|
|
c59f951e5a | ||
|
|
6919a34f88 | ||
|
|
3480bb1098 | ||
|
|
27b8c870f3 | ||
|
|
be43212a73 | ||
|
|
f0b9bc56a6 | ||
|
|
5654816f5a | ||
|
|
b0fb476d97 | ||
|
|
fada8d067d | ||
|
|
90022ee3e8 | ||
|
|
de68a47a16 | ||
|
|
714af68292 | ||
|
|
e6768edaf0 | ||
|
|
6145e54543 | ||
|
|
ac51c2300e | ||
|
|
f590980c3e | ||
|
|
5dbade3d0b | ||
|
|
2028d4b13e | ||
|
|
a6f7b49b92 | ||
|
|
c2415f38fa | ||
|
|
9cf717ab43 | ||
|
|
d4589bb6f6 | ||
|
|
484878aec3 | ||
|
|
ace3a94e08 | ||
|
|
5d771e119c | ||
|
|
8dcc695947 | ||
|
|
1ae28e07b6 | ||
|
|
2de0737443 | ||
|
|
bc32f848cb | ||
|
|
edee6d63d6 | ||
|
|
af3f6f40bb | ||
|
|
32f72c245d | ||
|
|
043ef8da72 | ||
|
|
6812b733bb | ||
|
|
2ec28dcb83 | ||
|
|
db000a2f88 | ||
|
|
59880df60e | ||
|
|
75f1b07e7a | ||
|
|
f191c4f636 | ||
|
|
1b2bc7b1e3 | ||
|
|
a89e4d626e | ||
|
|
dbbfdaab0f | ||
|
|
536f30ec84 | ||
|
|
b7aec1310c | ||
|
|
31d76b1080 | ||
|
|
2fbafc3591 | ||
|
|
19fe34415a | ||
|
|
2a50f85a30 | ||
|
|
26b71ab993 | ||
|
|
04a78445c6 | ||
|
|
fa19897016 | ||
|
|
3806355509 | ||
|
|
3f6738185b | ||
|
|
e58d09e5da | ||
|
|
71cd9d22c6 | ||
|
|
6c58d4f2e9 | ||
|
|
4070eecea7 | ||
|
|
ffb53ceb1d | ||
|
|
0c00544798 | ||
|
|
471d443e4a | ||
|
|
ba9a445263 | ||
|
|
056bc2850b | ||
|
|
b668d6ad68 | ||
|
|
29fab5560f | ||
|
|
8aef63ce4a | ||
|
|
1ea7a2994e | ||
|
|
208b3fa6fe | ||
|
|
d9ff95da49 | ||
|
|
c8a0b443f3 | ||
|
|
00e595d737 | ||
|
|
a178a8f820 | ||
|
|
ec359d50fb | ||
|
|
3c5aeccd53 | ||
|
|
f99fe16a46 | ||
|
|
43dc7cf222 | ||
|
|
ad549098f8 | ||
|
|
6795ba3838 | ||
|
|
efb5f8e36a | ||
|
|
8aa24f1289 | ||
|
|
14d882d220 | ||
|
|
f4c6c54a08 | ||
|
|
4dc7a5ca0a | ||
|
|
40fdd04cb3 | ||
|
|
a24dedd225 | ||
|
|
ae2445fd07 | ||
|
|
7ba53cb4b3 | ||
|
|
fbff8389c5 | ||
|
|
827fdacc4b | ||
|
|
3efc27e9f3 | ||
|
|
f7104199e3 | ||
|
|
5c0fbf7e68 | ||
|
|
55c595330a | ||
|
|
d3fc75589f | ||
|
|
f8605f45f7 | ||
|
|
d541b17fe1 | ||
|
|
29eb1d97f8 | ||
|
|
623b1c4585 | ||
|
|
74f7d7811e | ||
|
|
7774331a20 | ||
|
|
aae30c5891 | ||
|
|
41760e4b65 | ||
|
|
9ca0de250b | ||
|
|
d0156b4637 | ||
|
|
f6cca88593 | ||
|
|
c6da80573e | ||
|
|
5527869d13 | ||
|
|
5c599b2feb | ||
|
|
122d814a33 | ||
|
|
a1a8adbe4b | ||
|
|
5a370cabb5 | ||
|
|
639ae26ac1 | ||
|
|
896b6de60c | ||
|
|
d025f9d1b5 | ||
|
|
0b029bc0bf | ||
|
|
2256434ec7 | ||
|
|
0b4caeda73 | ||
|
|
18a1a1c47f | ||
|
|
6702956521 | ||
|
|
c996220685 | ||
|
|
df85abfabe | ||
|
|
e6c760ec6b | ||
|
|
a77dc855f0 | ||
|
|
2524e167d9 | ||
|
|
638d1c91f1 | ||
|
|
ba4058dfd9 | ||
|
|
ab90a170af | ||
|
|
f780499241 | ||
|
|
91709bc999 | ||
|
|
72725dc5c1 | ||
|
|
3098439db2 | ||
|
|
6441a09e09 | ||
|
|
57e7699723 | ||
|
|
17e1cfbbbe | ||
|
|
bfe1311ca8 | ||
|
|
537a1650f2 | ||
|
|
8c852c20e7 | ||
|
|
1da46382d3 | ||
|
|
4953888af3 | ||
|
|
22de868c6c | ||
|
|
0998707e03 | ||
|
|
b5fcd49b7b | ||
|
|
81cdd9650b | ||
|
|
e028cea687 | ||
|
|
17ed4a9e26 | ||
|
|
3ff318b9e4 | ||
|
|
0c11c25c66 | ||
|
|
0d31139402 | ||
|
|
e970cac4d7 | ||
|
|
7c8eecd745 | ||
|
|
4d87c2267b | ||
|
|
88b2439deb | ||
|
|
766a06c69a | ||
|
|
aa502553bb | ||
|
|
05ff4205d2 | ||
|
|
9d937bb277 | ||
|
|
1621515b3c | ||
|
|
30261e70ad | ||
|
|
c2a4f667a7 | ||
|
|
05b95331d8 | ||
|
|
c986f44704 | ||
|
|
7f62073d93 | ||
|
|
1a562962ba | ||
|
|
065be0621d | ||
|
|
6c085ed975 | ||
|
|
4c5776f9d2 | ||
|
|
c84fac6823 | ||
|
|
1778f64048 | ||
|
|
d1000635dd | ||
|
|
1273b062e1 | ||
|
|
961b96ca3d | ||
|
|
bcb29c3588 | ||
|
|
5d9395b16f | ||
|
|
23a75a3f50 | ||
|
|
7b87d32c0a | ||
|
|
d5f4f81566 | ||
|
|
a69863da4e | ||
|
|
4d70c214b0 | ||
|
|
11afc2b468 | ||
|
|
879e4f4e02 | ||
|
|
b5b4eea253 | ||
|
|
67adc09d52 | ||
|
|
e2b39dd3a0 | ||
|
|
9dc0ce7392 | ||
|
|
1a025c5cea | ||
|
|
732e9af439 | ||
|
|
4e5666fc3a | ||
|
|
b41f5b04f5 | ||
|
|
cfa21df8b3 | ||
|
|
6ac451a5de | ||
|
|
9efb8bb662 | ||
|
|
f0aee6f909 | ||
|
|
f72bfc9df2 | ||
|
|
c9ebfd1119 | ||
|
|
cf1874baaa | ||
|
|
c221cfdafe | ||
|
|
31b84e6d92 | ||
|
|
ae05bc8ea5 | ||
|
|
acbf7cfcf0 | ||
|
|
8250116946 | ||
|
|
45e9458373 | ||
|
|
2623b86274 | ||
|
|
2e1dda8189 | ||
|
|
e26256b819 | ||
|
|
18e59ad7c8 | ||
|
|
a7a3d23f50 | ||
|
|
323a2b5093 | ||
|
|
563811ebf8 | ||
|
|
190c7f2063 | ||
|
|
6158751a32 | ||
|
|
4c7d126782 | ||
|
|
3e24ea1212 | ||
|
|
a7ac979da6 | ||
|
|
87f48f0a28 | ||
|
|
15586a3cb1 | ||
|
|
2195c0ed3e | ||
|
|
af1e904895 | ||
|
|
a4fbf7ced0 | ||
|
|
1b7e0679d5 | ||
|
|
9292c1116c | ||
|
|
a2afb5bb31 | ||
|
|
15fbfdebcc | ||
|
|
15eb221cd1 | ||
|
|
7d3781acc8 | ||
|
|
f3100a6752 | ||
|
|
e3cd2a9d02 | ||
|
|
19ccc3a327 | ||
|
|
4587c0925f | ||
|
|
fc96245891 | ||
|
|
a27815b4a9 | ||
|
|
5daaf372b4 | ||
|
|
cc51d2684c | ||
|
|
28b5893239 | ||
|
|
c754b5cfce | ||
|
|
b0c1249710 | ||
|
|
c41ee417fb | ||
|
|
47ba0415ca | ||
|
|
99857e25cc | ||
|
|
7f832ba9d5 | ||
|
|
8c4a894f93 | ||
|
|
dd3de412fb | ||
|
|
4ad5e6c9ba | ||
|
|
b445818521 | ||
|
|
7c14ea1730 | ||
|
|
7bf9f861a5 | ||
|
|
4cf5c87761 | ||
|
|
e1c6fec581 | ||
|
|
31da5b91fa | ||
|
|
01bcb1a750 | ||
|
|
35348bf77f | ||
|
|
ae58ea8312 | ||
|
|
f30d21e96f |
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],
|
||||
}
|
||||
@@ -1,24 +1,20 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on: [push]
|
||||
on: [push, pull_request]
|
||||
|
||||
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 \
|
||||
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
|
||||
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev
|
||||
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev libargon2-0-dev
|
||||
- name: autogen
|
||||
run: ./autogen.sh
|
||||
- name: argon2
|
||||
run: |
|
||||
cd argon2 && make && sudo make install && cd ..
|
||||
- name: asio
|
||||
run: |
|
||||
wget https://github.com/aberaud/asio/archive/b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz \
|
||||
@@ -32,3 +28,39 @@ 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
|
||||
|
||||
@@ -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
|
||||
@@ -19,6 +19,9 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
**/dhtnode
|
||||
**/dhtchat
|
||||
**/dhtscanner
|
||||
|
||||
# Autotools
|
||||
/ac
|
||||
@@ -73,3 +76,4 @@ doc/Doxyfile
|
||||
|
||||
# build dir
|
||||
build
|
||||
.DS_Store
|
||||
@@ -1,4 +0,0 @@
|
||||
[submodule "argon2"]
|
||||
path = argon2
|
||||
url = https://github.com/P-H-C/phc-winner-argon2
|
||||
ignore = dirty
|
||||
-68
@@ -1,68 +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:
|
||||
- |
|
||||
# non llvm builds
|
||||
if [[ "$OPENDHT_TEST_JOB" != *"opendht.llvm"* ]]; then
|
||||
docker pull aberaud/opendht-deps;
|
||||
fi
|
||||
|
||||
- |
|
||||
# classic build
|
||||
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"
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
+203
-126
@@ -1,10 +1,25 @@
|
||||
cmake_minimum_required (VERSION 3.1)
|
||||
cmake_minimum_required (VERSION 3.10)
|
||||
if(POLICY CMP0065)
|
||||
cmake_policy(SET CMP0065 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0069)
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0073)
|
||||
cmake_policy(SET CMP0073 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0074)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
endif()
|
||||
project (opendht)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
include(FindPkgConfig)
|
||||
include(cmake/CheckAtomic.cmake)
|
||||
|
||||
project (opendht)
|
||||
set (opendht_VERSION_MAJOR 2)
|
||||
set (opendht_VERSION_MINOR 0.0)
|
||||
set (opendht_VERSION_MINOR 4.0)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
@@ -16,94 +31,122 @@ option (OPENDHT_LOG "Build with logs" ON)
|
||||
option (OPENDHT_PYTHON "Build Python bindings" OFF)
|
||||
option (OPENDHT_TOOLS "Build DHT tools" ON)
|
||||
option (OPENDHT_SYSTEMD "Install systemd module" OFF)
|
||||
option (OPENDHT_ARGON2 "Use included argon2 sources" OFF)
|
||||
option (OPENDHT_LTO "Build with LTO" OFF)
|
||||
option (OPENDHT_SYSTEMD_UNIT_FILE_LOCATION "Where to install systemd unit file")
|
||||
option (OPENDHT_SANITIZE "Build with address sanitizer and stack protector" OFF)
|
||||
option (OPENDHT_PROXY_SERVER "Enable DHT proxy server, use Restinio and jsoncpp" OFF)
|
||||
option (OPENDHT_PUSH_NOTIFICATIONS "Enable push notifications support" OFF)
|
||||
option (OPENDHT_PROXY_SERVER_IDENTITY "Allow clients to use the node identity" OFF)
|
||||
option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restinio and jsoncpp" OFF)
|
||||
option (OPENDHT_PROXY_OPENSSL "Build DHT proxy with OpenSSL" ON)
|
||||
option (OPENDHT_PROXY_HTTP_PARSER_FORK "Build DHT proxy with custom http_parser to support old API" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(OPENDHT_HTTP "Build embedded http(s) client" OFF "NOT OPENDHT_PROXY_SERVER;NOT OPENDHT_PROXY_CLIENT" ON)
|
||||
option (OPENDHT_PEER_DISCOVERY "Enable multicast peer discovery" ON)
|
||||
option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
|
||||
option (OPENDHT_TESTS "Add unit tests executable" OFF)
|
||||
option (OPENDHT_TESTS_NETWORK "Enable unit tests that require network access" ON)
|
||||
option (OPENDHT_C "Build C bindings" OFF)
|
||||
|
||||
find_package(Doxygen)
|
||||
option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
|
||||
|
||||
# Dependencies
|
||||
if (NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
link_libraries (atomic)
|
||||
endif ()
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
find_package (Threads)
|
||||
find_package (PkgConfig)
|
||||
find_package (GnuTLS 3.3 REQUIRED)
|
||||
pkg_search_module (Nettle nettle)
|
||||
find_package (Msgpack 1.2 REQUIRED)
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
if (NOT OPENDHT_ARGON2)
|
||||
find_package(PkgConfig)
|
||||
pkg_search_module(argon2 libargon2)
|
||||
if (argon2_FOUND)
|
||||
message("-- Found Argon2: " ${argon2_LIBRARY_DIRS} " (found version \"" ${argon2_VERSION} "\")")
|
||||
link_directories (${argon2_LIBRARY_DIRS})
|
||||
else ()
|
||||
message("Argon2 not found, using included version.")
|
||||
set(OPENDHT_ARGON2 ON)
|
||||
if (NOT MSVC)
|
||||
set (THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package (Threads)
|
||||
find_package (PkgConfig REQUIRED)
|
||||
find_package (GnuTLS 3.3 REQUIRED)
|
||||
pkg_search_module (Nettle REQUIRED nettle)
|
||||
find_package (msgpack REQUIRED)
|
||||
if (OPENDHT_TOOLS)
|
||||
find_package (Readline 6 REQUIRED)
|
||||
endif ()
|
||||
pkg_search_module(argon2 REQUIRED libargon2)
|
||||
pkg_search_module(Jsoncpp jsoncpp)
|
||||
if (Jsoncpp_FOUND)
|
||||
add_definitions(-DOPENDHT_JSONCPP)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/base64.h
|
||||
src/base64.cpp
|
||||
)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
pkg_search_module(Jsoncpp jsoncpp)
|
||||
if (Jsoncpp_FOUND)
|
||||
add_definitions(-DOPENDHT_JSONCPP)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/base64.h
|
||||
src/base64.cpp
|
||||
)
|
||||
endif()
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_HTTP)
|
||||
find_package(Restinio REQUIRED)
|
||||
if (Restinio_FOUND)
|
||||
if (OPENDHT_HTTP)
|
||||
find_package(Restinio REQUIRED)
|
||||
find_library(FMT_LIBRARY fmt)
|
||||
add_library(fmt SHARED IMPORTED)
|
||||
find_library(HTTP_PARSER_LIBRARY http_parser)
|
||||
add_library(http_parser SHARED IMPORTED)
|
||||
endif()
|
||||
if (NOT Jsoncpp_FOUND)
|
||||
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
# https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
|
||||
pkg_search_module(OPENSSL REQUIRED openssl)
|
||||
if (OPENSSL_FOUND)
|
||||
message(STATUS "Found OpenSSL ${OPENSSL_VERSION}")
|
||||
include_directories(${OPENSSL_INCLUDE_DIRS})
|
||||
else ()
|
||||
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
|
||||
if (NOT Jsoncpp_FOUND)
|
||||
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
|
||||
endif()
|
||||
endif()
|
||||
if (OPENDHT_PROXY_HTTP_PARSER_FORK)
|
||||
add_definitions(-DOPENDHT_PROXY_HTTP_PARSER_FORK)
|
||||
endif()
|
||||
else()
|
||||
set(OPENDHT_PROXY_OPENSSL OFF)
|
||||
endif()
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
# https://cmake.org/cmake/help/latest/module/FindOpenSSL.html
|
||||
pkg_search_module(OPENSSL REQUIRED openssl)
|
||||
if (OPENSSL_FOUND)
|
||||
message(STATUS "Found OpenSSL ${OPENSSL_VERSION} ${OPENSSL_INCLUDE_DIRS}")
|
||||
include_directories(SYSTEM ${OPENSSL_INCLUDE_DIRS})
|
||||
link_directories (${OPENSSL_LIBRARY_DIRS})
|
||||
else ()
|
||||
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
|
||||
endif()
|
||||
endif()
|
||||
else ()
|
||||
set(OPENDHT_PROXY_OPENSSL OFF)
|
||||
endif ()
|
||||
else ()
|
||||
set (WIN32_DEP_DIR ${PROJECT_SOURCE_DIR}/../)
|
||||
include_directories(${WIN32_DEP_DIR}/../msvc/include) # SMP gnutls
|
||||
include_directories(${WIN32_DEP_DIR}/argon2/include)
|
||||
include_directories(${WIN32_DEP_DIR}/jsoncpp/include)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/base64.h
|
||||
src/base64.cpp
|
||||
)
|
||||
add_definitions(-DOPENDHT_JSONCPP)
|
||||
include_directories(${WIN32_DEP_DIR}/msgpack-c/include)
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
include_directories(
|
||||
${WIN32_DEP_DIR}/asio/asio/include
|
||||
${WIN32_DEP_DIR}/openssl/include
|
||||
${WIN32_DEP_DIR}/restinio/dev
|
||||
${WIN32_DEP_DIR}/fmt/include
|
||||
${WIN32_DEP_DIR}/http_parser
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
|
||||
add_definitions(-DASIO_STANDALONE)
|
||||
endif()
|
||||
|
||||
# Build flags
|
||||
set (CMAKE_CXX_STANDARD 14)
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED on)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
|
||||
if (OPENDHT_SANITIZE)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-protector-strong")
|
||||
|
||||
if (NOT MSVC)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
|
||||
if (OPENDHT_SANITIZE)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-protector-strong")
|
||||
endif ()
|
||||
else ()
|
||||
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-DWIN32_LEAN_AND_MEAN
|
||||
-DSTATIC_GETOPT
|
||||
-DGNUTLS_INTERNAL_BUILD)
|
||||
set(DISABLE_MSC_WARNINGS "/wd4101 /wd4244 /wd4267 /wd4273 /wd4804 /wd4834 /wd4996")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DISABLE_MSC_WARNINGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
endif ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
@@ -114,15 +157,6 @@ if (OPENDHT_LOG)
|
||||
else ()
|
||||
add_definitions(-DOPENDHT_LOG=false)
|
||||
endif()
|
||||
if (OPENDHT_LTO)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-linker-plugin")
|
||||
set (CMAKE_AR "gcc-ar")
|
||||
set (CMAKE_NM "gcc-nm")
|
||||
set (CMAKE_RANLIB "gcc-ranlib")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (MSGPACK_INCLUDE_DIRS)
|
||||
include_directories (SYSTEM "${MSGPACK_INCLUDE_DIRS}")
|
||||
@@ -133,17 +167,18 @@ endif ()
|
||||
if (Nettle_INCLUDE_DIRS)
|
||||
include_directories (SYSTEM "${Nettle_INCLUDE_DIRS}")
|
||||
endif ()
|
||||
if (ASIO_INCLUDE_DIR)
|
||||
include_directories (SYSTEM "${ASIO_INCLUDE_DIR}")
|
||||
endif ()
|
||||
if (Restinio_INCLUDE_DIR)
|
||||
include_directories (SYSTEM "${Restinio_INCLUDE_DIR}")
|
||||
endif ()
|
||||
if (Jsoncpp_INCLUDE_DIRS)
|
||||
include_directories (SYSTEM "${Jsoncpp_INCLUDE_DIRS}")
|
||||
endif ()
|
||||
if (OpenSSL_INCLUDE_DIR)
|
||||
include_directories (SYSTEM "${OpenSSL_INCLUDE_DIR}")
|
||||
endif ()
|
||||
link_directories (${Nettle_LIBRARY_DIRS})
|
||||
link_directories (${Jsoncpp_LIBRARY_DIRS})
|
||||
link_directories (${argon2_LIBRARY_DIRS})
|
||||
include_directories (
|
||||
./
|
||||
include/
|
||||
@@ -263,46 +298,80 @@ if (OPENDHT_HTTP)
|
||||
list (APPEND opendht_HEADERS
|
||||
include/opendht/proxy.h
|
||||
include/opendht/http.h
|
||||
src/compat/os_cert.h
|
||||
)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/http.cpp
|
||||
src/compat/os_cert.cpp
|
||||
)
|
||||
endif ()
|
||||
|
||||
if(OPENDHT_ARGON2)
|
||||
# make sure argon2 submodule is up to date and initialized
|
||||
message("Initializing Argon2 submodule")
|
||||
execute_process(COMMAND git submodule update --init)
|
||||
|
||||
# add local argon2 files to build
|
||||
list (APPEND opendht_SOURCES
|
||||
argon2/src/argon2.c
|
||||
argon2/src/core.c
|
||||
argon2/src/blake2/blake2b.c
|
||||
argon2/src/thread.c
|
||||
argon2/src/ref.c
|
||||
argon2/src/encoding.c
|
||||
)
|
||||
include_directories(argon2/include/)
|
||||
endif()
|
||||
if (MSVC)
|
||||
list (APPEND opendht_HEADERS src/compat/msvc/unistd.h)
|
||||
endif ()
|
||||
|
||||
# Targets
|
||||
if (OPENDHT_STATIC)
|
||||
add_library (opendht-static STATIC
|
||||
${opendht_SOURCES}
|
||||
${opendht_HEADERS}
|
||||
)
|
||||
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "opendht")
|
||||
if (OPENDHT_ARGON2)
|
||||
target_include_directories(opendht-static SYSTEM PRIVATE argon2)
|
||||
else ()
|
||||
if (NOT MSVC)
|
||||
add_library (opendht-static STATIC
|
||||
${opendht_SOURCES}
|
||||
${opendht_HEADERS}
|
||||
)
|
||||
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "opendht")
|
||||
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
|
||||
endif ()
|
||||
target_link_libraries(opendht-static
|
||||
PRIVATE ${argon2_LIBRARIES}
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
|
||||
${Jsoncpp_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
|
||||
${OPENSSL_LIBRARIES})
|
||||
target_link_libraries(opendht-static
|
||||
PRIVATE ${argon2_LIBRARIES}
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_STATIC_LIBRARIES}
|
||||
${Jsoncpp_STATIC_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
|
||||
${OPENSSL_STATIC_LIBRARIES})
|
||||
else ()
|
||||
if (OPENDHT_TOOLS)
|
||||
function (add_obj_lib name libfile)
|
||||
add_library(${name} OBJECT IMPORTED)
|
||||
set_property(TARGET ${name} PROPERTY IMPORTED_OBJECTS ${libfile})
|
||||
endfunction ()
|
||||
add_obj_lib (win32_json ${WIN32_DEP_DIR}/../msvc/lib/x64/lib_json.lib)
|
||||
add_obj_lib (win32_gnutls ${WIN32_DEP_DIR}/../msvc/lib/x64/libgnutls.lib)
|
||||
add_obj_lib (win32_argon2 ${WIN32_DEP_DIR}/argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib)
|
||||
list (APPEND obj_libs
|
||||
$<TARGET_OBJECTS:win32_json>
|
||||
$<TARGET_OBJECTS:win32_gnutls>
|
||||
$<TARGET_OBJECTS:win32_argon2>
|
||||
)
|
||||
if (OPENDHT_HTTP)
|
||||
add_obj_lib (win32_fmt ${WIN32_DEP_DIR}/fmt/msvc/Release/fmt.lib)
|
||||
add_obj_lib (win32_http_parser ${WIN32_DEP_DIR}/http_parser/x64/Release/http-parser.lib)
|
||||
add_obj_lib (win32_ssl ${WIN32_DEP_DIR}/openssl/libssl_static.lib)
|
||||
add_obj_lib (win32_crypto ${WIN32_DEP_DIR}/openssl/libcrypto_static.lib)
|
||||
list (APPEND obj_libs
|
||||
$<TARGET_OBJECTS:win32_fmt>
|
||||
$<TARGET_OBJECTS:win32_http_parser>
|
||||
$<TARGET_OBJECTS:win32_ssl>
|
||||
$<TARGET_OBJECTS:win32_crypto>
|
||||
)
|
||||
endif ()
|
||||
else ()
|
||||
list (APPEND win32_Libs
|
||||
${PROJECT_SOURCE_DIR}/../../msvc/lib/x64/libgnutls.lib
|
||||
${PROJECT_SOURCE_DIR}/../../msvc/lib/x64/lib_json.lib
|
||||
${PROJECT_SOURCE_DIR}/../argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib
|
||||
)
|
||||
list (APPEND win32_Libs
|
||||
${PROJECT_SOURCE_DIR}/../fmt/msvc/Release/fmt.lib
|
||||
${PROJECT_SOURCE_DIR}/../http_parser/x64/Release/http-parser.lib
|
||||
${PROJECT_SOURCE_DIR}/../openssl/libssl.lib
|
||||
${PROJECT_SOURCE_DIR}/../openssl/libcrypto.lib
|
||||
)
|
||||
endif ()
|
||||
add_library (opendht-static STATIC
|
||||
${opendht_SOURCES}
|
||||
${opendht_HEADERS}
|
||||
${obj_libs}
|
||||
)
|
||||
target_link_libraries(opendht-static PUBLIC ${Win32_STATIC_LIBRARIES} ${Win32_IMPORT_LIBRARIES})
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4006")
|
||||
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "libopendht")
|
||||
endif()
|
||||
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
endif ()
|
||||
|
||||
@@ -314,17 +383,21 @@ if (OPENDHT_SHARED)
|
||||
set_target_properties (opendht PROPERTIES IMPORT_SUFFIX "_import.lib")
|
||||
set_target_properties (opendht PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
|
||||
target_compile_definitions(opendht PRIVATE OPENDHT_BUILD)
|
||||
if (OPENDHT_ARGON2)
|
||||
target_include_directories(opendht SYSTEM PRIVATE argon2)
|
||||
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
|
||||
if (APPLE)
|
||||
target_link_libraries(opendht
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
|
||||
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
|
||||
${Jsoncpp_LIBRARIES}
|
||||
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${argon2_LIBRARIES}
|
||||
SYSTEM "-framework CoreFoundation" "-framework Security")
|
||||
else ()
|
||||
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
|
||||
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
|
||||
target_link_libraries(opendht
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
|
||||
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
|
||||
${Jsoncpp_LIBRARIES}
|
||||
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${argon2_LIBRARIES})
|
||||
endif ()
|
||||
target_link_libraries(opendht
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
|
||||
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
|
||||
${Jsoncpp_LIBRARIES}
|
||||
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
|
||||
|
||||
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
endif ()
|
||||
@@ -349,6 +422,7 @@ if (OPENDHT_C)
|
||||
)
|
||||
install (TARGETS opendht-c DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht-c)
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendht-c.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
install (FILES c/opendht_c.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/opendht)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_TOOLS)
|
||||
@@ -380,7 +454,7 @@ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATIO
|
||||
|
||||
# Unit tests
|
||||
if (OPENDHT_TESTS)
|
||||
FIND_PACKAGE(Cppunit REQUIRED)
|
||||
pkg_search_module(Cppunit REQUIRED cppunit)
|
||||
# unit testing
|
||||
list (APPEND test_FILES
|
||||
tests/infohashtester.h
|
||||
@@ -394,25 +468,28 @@ if (OPENDHT_TESTS)
|
||||
tests/threadpooltester.h
|
||||
tests/threadpooltester.cpp
|
||||
)
|
||||
if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT)
|
||||
list (APPEND test_FILES
|
||||
tests/httptester.h
|
||||
tests/httptester.cpp
|
||||
tests/dhtproxytester.h
|
||||
tests/dhtproxytester.cpp
|
||||
)
|
||||
endif()
|
||||
if (OPENDHT_PEER_DISCOVERY)
|
||||
list (APPEND test_FILES
|
||||
tests/peerdiscoverytester.h
|
||||
tests/peerdiscoverytester.cpp
|
||||
)
|
||||
if (OPENDHT_TESTS_NETWORK)
|
||||
if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT)
|
||||
list (APPEND test_FILES
|
||||
tests/httptester.h
|
||||
tests/httptester.cpp
|
||||
tests/dhtproxytester.h
|
||||
tests/dhtproxytester.cpp
|
||||
)
|
||||
endif()
|
||||
if (OPENDHT_PEER_DISCOVERY)
|
||||
list (APPEND test_FILES
|
||||
tests/peerdiscoverytester.h
|
||||
tests/peerdiscoverytester.cpp
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
add_executable(opendht_unit_tests
|
||||
tests/tests_runner.cpp
|
||||
${test_FILES}
|
||||
)
|
||||
target_include_directories(opendht_unit_tests SYSTEM PRIVATE ${CPPUNIT_INCLUDE_DIRS})
|
||||
target_include_directories(opendht_unit_tests SYSTEM PRIVATE ${Cppunit_INCLUDE_DIR})
|
||||
target_link_directories(opendht_unit_tests PRIVATE ${Cppunit_LIBRARY_DIRS})
|
||||
if (OPENDHT_SHARED)
|
||||
target_link_libraries(opendht_unit_tests opendht)
|
||||
else ()
|
||||
@@ -420,7 +497,7 @@ if (OPENDHT_TESTS)
|
||||
endif ()
|
||||
target_link_libraries(opendht_unit_tests
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${CPPUNIT_LIBRARIES}
|
||||
${Cppunit_LIBRARIES}
|
||||
${GNUTLS_LIBRARIES}
|
||||
${Jsoncpp_LIBRARIES}
|
||||
)
|
||||
|
||||
-248
@@ -1,248 +0,0 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
#output directories
|
||||
DebugLib/
|
||||
Debug/
|
||||
ReleaseLib/
|
||||
Release/
|
||||
.config/
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.VC.VC.opendb
|
||||
*.VC.db
|
||||
*.db
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
!config.h
|
||||
contrib/build/
|
||||
@@ -1,168 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}</ProjectGuid>
|
||||
<RootNamespace>dhtchat</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(ProjectDir)..\..\bin\x64</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tools\dhtchat.cpp" />
|
||||
<ClCompile Include="wingetopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tools\tools_common.h" />
|
||||
<ClInclude Include="wingetopt.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,168 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}</ProjectGuid>
|
||||
<RootNamespace>dhtnode</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(ProjectDir)..\..\bin\x64</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tools\dhtnode.cpp" />
|
||||
<ClCompile Include="wingetopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tools\tools_common.h" />
|
||||
<ClInclude Include="wingetopt.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,168 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{78443BCD-4689-4007-A246-F8F34B27F561}</ProjectGuid>
|
||||
<RootNamespace>dhtscanner</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(ProjectDir)..\..\bin\x64</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\restbed\source;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4267;4244;4800;4273;4101;</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>restbed.lib;libeay32.lib;ssleay32.lib;crypt32.lib;Argon2Ref.lib;lib_json.lib;libgnutls.lib;libopendht.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\msvc\lib\$(PlatformTarget);$(ProjectDir)..\..\restbed\build\Release;$(ProjectDir)..\..\restbed\dependency\openssl\out32dll;$(ProjectDir)..\..\argon2\vs2015\Argon2Ref\vs2015\build</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/ignore:4049 %(AdditionalOptions)</AdditionalOptions>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\tools\dhtscanner.cpp" />
|
||||
<ClCompile Include="wingetopt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tools\tools_common.h" />
|
||||
<ClInclude Include="wingetopt.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,257 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opendht", "opendht.vcxproj", "{711397CE-E5D5-467D-9457-8716C047E50C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
DebugDLL|x64 = DebugDLL|x64
|
||||
DebugDLL|x86 = DebugDLL|x86
|
||||
DebugDLLStaticDeps|x64 = DebugDLLStaticDeps|x64
|
||||
DebugDLLStaticDeps|x86 = DebugDLLStaticDeps|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
ReleaseDLL|x64 = ReleaseDLL|x64
|
||||
ReleaseDLL|x86 = ReleaseDLL|x86
|
||||
ReleaseDLLStaticDeps|x64 = ReleaseDLLStaticDeps|x64
|
||||
ReleaseDLLStaticDeps|x86 = ReleaseDLLStaticDeps|x86
|
||||
ReleaseLTO|x64 = ReleaseLTO|x64
|
||||
ReleaseLTO|x86 = ReleaseLTO|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x64.Build.0 = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.ActiveCfg = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x64.Build.0 = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.Release|x86.Build.0 = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x64.Build.0 = Debug|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.ActiveCfg = Release|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x64.Build.0 = Release|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.Release|x86.Build.0 = Release|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x64.Build.0 = Debug|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.ActiveCfg = Release|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x64.Build.0 = Release|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.Release|x86.Build.0 = Release|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x64.Build.0 = Debug|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.ActiveCfg = Release|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x64.Build.0 = Release|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.Release|x86.Build.0 = Release|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x64.Build.0 = Debug|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x64.Build.0 = DebugDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.DebugDLLStaticDeps|x86.Build.0 = DebugDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.ActiveCfg = Release|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x64.Build.0 = Release|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.Release|x86.Build.0 = Release|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLLStaticDeps|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLLStaticDeps|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x64.Build.0 = Debug|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Debug|x86.Build.0 = Debug|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.ActiveCfg = Release|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x64.Build.0 = Release|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.ActiveCfg = Release|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.Release|x86.Build.0 = Release|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x64.Build.0 = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLL|x86.Build.0 = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.ActiveCfg = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x64.Build.0 = DebugDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.ActiveCfg = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.DebugDLLStaticDeps|x86.Build.0 = DebugDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x64.Build.0 = Release|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.Release|x86.Build.0 = Release|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.ActiveCfg = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x64.Build.0 = ReleaseDLL|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.ActiveCfg = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseDLLStaticDeps|x86.Build.0 = ReleaseDLL|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x64.Build.0 = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseLTO|x86.Build.0 = ReleaseLTO|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x64.Build.0 = Debug|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.ActiveCfg = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLL|x86.Build.0 = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.Release|x86.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLL|x86.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseLTO|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,271 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\dht_proxy_client.cpp" />
|
||||
<ClCompile Include="..\src\http.cpp" />
|
||||
<ClCompile Include="..\src\network_utils.cpp" />
|
||||
<ClCompile Include="..\src\op_cache.cpp" />
|
||||
<ClCompile Include="..\src\peer_discovery.cpp" />
|
||||
<ClCompile Include="..\src\rng.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thread_pool.cpp" />
|
||||
<ClCompile Include="wingetopt.c" />
|
||||
<ClCompile Include="..\src\base64.cpp" />
|
||||
<ClCompile Include="..\src\callbacks.cpp" />
|
||||
<ClCompile Include="..\src\crypto.cpp" />
|
||||
<ClCompile Include="..\src\default_types.cpp" />
|
||||
<ClCompile Include="..\src\dht.cpp" />
|
||||
<ClCompile Include="..\src\dhtrunner.cpp" />
|
||||
<ClCompile Include="..\src\dht_proxy_server.cpp" />
|
||||
<ClCompile Include="..\src\indexation\pht.cpp" />
|
||||
<ClCompile Include="..\src\infohash.cpp" />
|
||||
<ClCompile Include="..\src\log.cpp" />
|
||||
<ClCompile Include="..\src\network_engine.cpp" />
|
||||
<ClCompile Include="..\src\node.cpp" />
|
||||
<ClCompile Include="..\src\node_cache.cpp" />
|
||||
<ClCompile Include="..\src\routing_table.cpp" />
|
||||
<ClCompile Include="..\src\securedht.cpp" />
|
||||
<ClCompile Include="..\src\utils.cpp" />
|
||||
<ClCompile Include="..\src\value.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\opendht\http.h" />
|
||||
<ClInclude Include="..\src\network_utils.h" />
|
||||
<ClInclude Include="..\src\thread_pool.h" />
|
||||
<ClInclude Include="unistd.h" />
|
||||
<ClInclude Include="wingetopt.h" />
|
||||
<ClInclude Include="..\include\opendht.h" />
|
||||
<ClInclude Include="..\include\opendht\callbacks.h" />
|
||||
<ClInclude Include="..\include\opendht\crypto.h" />
|
||||
<ClInclude Include="..\include\opendht\def.h" />
|
||||
<ClInclude Include="..\include\opendht\default_types.h" />
|
||||
<ClInclude Include="..\include\opendht\dht.h" />
|
||||
<ClInclude Include="..\include\opendht\dhtrunner.h" />
|
||||
<ClInclude Include="..\include\opendht\dht_proxy_server.h" />
|
||||
<ClInclude Include="..\include\opendht\indexation\pht.h" />
|
||||
<ClInclude Include="..\include\opendht\infohash.h" />
|
||||
<ClInclude Include="..\include\opendht\log.h" />
|
||||
<ClInclude Include="..\include\opendht\log_enable.h" />
|
||||
<ClInclude Include="..\include\opendht\network_engine.h" />
|
||||
<ClInclude Include="..\include\opendht\node.h" />
|
||||
<ClInclude Include="..\include\opendht\node_cache.h" />
|
||||
<ClInclude Include="..\include\opendht\rate_limiter.h" />
|
||||
<ClInclude Include="..\include\opendht\rng.h" />
|
||||
<ClInclude Include="..\include\opendht\routing_table.h" />
|
||||
<ClInclude Include="..\include\opendht\scheduler.h" />
|
||||
<ClInclude Include="..\include\opendht\securedht.h" />
|
||||
<ClInclude Include="..\include\opendht\sockaddr.h" />
|
||||
<ClInclude Include="..\include\opendht\utils.h" />
|
||||
<ClInclude Include="..\include\opendht\value.h" />
|
||||
<ClInclude Include="..\src\base64.h" />
|
||||
<ClInclude Include="..\src\listener.h" />
|
||||
<ClInclude Include="..\src\net.h" />
|
||||
<ClInclude Include="..\src\parsed_message.h" />
|
||||
<ClInclude Include="..\src\request.h" />
|
||||
<ClInclude Include="..\src\search.h" />
|
||||
<ClInclude Include="..\src\storage.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{711397CE-E5D5-467D-9457-8716C047E50C}</ProjectGuid>
|
||||
<RootNamespace>opendht</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>libopendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>libopendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
<TargetName>libopendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
<TargetName>libopendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
mkdir $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
|
||||
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
mkdir $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
|
||||
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
mkdir $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)..\..\..\msvc\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include;$(ProjectDir)..\..\msgpack-c\include;$(ProjectDir)..\..\jsoncpp\include;$(ProjectDir)..\..\openssl\inc32;$(ProjectDir)..\..\asio\asio\include;$(ProjectDir)..\..\restinio\dev;$(ProjectDir)..\..\fmt\include;$(ProjectDir)..\..\http_parser</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>OPENDHT_JSONCPP;OPENDHT_PROXY_CLIENT;OPENDHT_PROXY_SERVER;OPENDHT_PUSH_NOTIFICATIONS;_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;ASIO_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;4273;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
|
||||
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>mkdir $(OutDir)\include
|
||||
mkdir $(OutDir)\include\opendht
|
||||
mkdir $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\indexation\*.h $(OutDir)\include\opendht\indexation
|
||||
copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,198 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\callbacks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\crypto.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\default_types.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\dht.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\dhtrunner.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\infohash.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\log.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\network_engine.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\node.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\node_cache.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\routing_table.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\securedht.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\value.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\base64.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\dht_proxy_server.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\indexation\pht.cpp">
|
||||
<Filter>Source Files\indexation</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="wingetopt.c" />
|
||||
<ClCompile Include="..\src\rng.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\op_cache.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\dht_proxy_client.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\peer_discovery.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\network_utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thread_pool.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\http.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\opendht.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\callbacks.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\crypto.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\default_types.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\dht.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\dht_proxy_server.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\dhtrunner.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\infohash.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\log.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\log_enable.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\network_engine.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\node.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\node_cache.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\rate_limiter.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\rng.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\routing_table.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\scheduler.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\securedht.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\utils.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\value.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\indexation\pht.h">
|
||||
<Filter>Header Files\opendht\indexation</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="unistd.h" />
|
||||
<ClInclude Include="wingetopt.h" />
|
||||
<ClInclude Include="..\include\opendht\def.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\net.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\parsed_message.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\sockaddr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\network_utils.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thread_pool.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\listener.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\base64.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\search.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\request.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\storage.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht\http.h">
|
||||
<Filter>Header Files\opendht</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{be73d179-6cf2-4c05-8d91-53c8499a7134}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{d1ab5bfe-3ab1-45ee-9324-b4b071887668}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\indexation">
|
||||
<UniqueIdentifier>{939134d3-d5a2-4458-bca8-a10ea9042ea2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\opendht">
|
||||
<UniqueIdentifier>{0b46e2d0-4874-404c-bae3-fae8d49b85b8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\opendht\indexation">
|
||||
<UniqueIdentifier>{03bd5139-2ae5-41b0-a77b-944814e1b2b6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -4,7 +4,7 @@
|
||||
<a id="user-content-opendht-" class="anchor" href="/savoirfairelinux/opendht/blob/master/README.md#opendht-" aria-hidden="true"></a>OpenDHT
|
||||
</h1>
|
||||
|
||||
A lightweight C++14 Distributed Hash Table implementation.
|
||||
A lightweight C++17 Distributed Hash Table implementation.
|
||||
|
||||
OpenDHT provides an easy to use distributed in-memory data store.
|
||||
Every node in the network can read and write values to the store.
|
||||
@@ -14,7 +14,7 @@ Values are distributed over the network, with redundancy.
|
||||
* High resilience to network disruption
|
||||
* Public key cryptography layer providing optional data signature and encryption (using GnuTLS)
|
||||
* IPv4 and IPv6 support
|
||||
* Clean and powerful **C++14** map API
|
||||
* Clean and powerful **C++17** map API
|
||||
* Bindings for **C, Rust & Python 3**
|
||||
* REST API with optional HTTP client+server with push notification support
|
||||
|
||||
@@ -27,7 +27,7 @@ Build instructions: <https://github.com/savoirfairelinux/opendht/wiki/Build-the-
|
||||
|
||||
#### How-to build a simple client app
|
||||
```bash
|
||||
g++ main.cpp -std=c++14 -lopendht
|
||||
g++ main.cpp -std=c++17 -lopendht
|
||||
```
|
||||
|
||||
## Examples
|
||||
@@ -98,15 +98,15 @@ for r in results:
|
||||
- Nettle 2.4+, a GnuTLS dependency for crypto.
|
||||
- (optional) restinio used for the REST API.
|
||||
- (optional) jsoncpp 1.7.4-3+, used for the REST API.
|
||||
- Build tested with GCC 5.2+ (GNU/Linux, Windows with MinGW), Clang/LLVM (GNU/Linux, Android, macOS, iOS).
|
||||
- Build tested with Microsoft Visual Studio 2015, 2017, 2019
|
||||
- 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, 2022
|
||||
|
||||
## Contact
|
||||
|
||||
IRC: join us on Freenode at [`#opendht`](https://webchat.freenode.net/?channels=%23opendht).
|
||||
IRC: join us on Libera.chat at [`#opendht`](https://web.libera.chat/#opendht).
|
||||
|
||||
## License
|
||||
Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
|
||||
OpenDHT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
-1
Submodule argon2 deleted from 62358ba212.
@@ -1,2 +1 @@
|
||||
git submodule update --init
|
||||
autoreconf --install --verbose -Wall
|
||||
+108
-33
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "opendht_c.h"
|
||||
#include "opendht.h"
|
||||
|
||||
@@ -10,6 +28,8 @@ using CertSp = std::shared_ptr<dht::crypto::Certificate>;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
// dht::InfoHash
|
||||
|
||||
inline dht_infohash dht_infohash_to_c(const dht::InfoHash& h) {
|
||||
@@ -97,10 +117,20 @@ const char* dht_value_get_user_type(const dht_value* data) {
|
||||
return vsp->user_type.c_str();
|
||||
}
|
||||
|
||||
void dht_value_set_user_type(dht_value* data, const char* user_type) {
|
||||
(*reinterpret_cast<ValueSp*>(data))->user_type = user_type;
|
||||
}
|
||||
|
||||
dht_value* dht_value_new(const uint8_t* data, size_t size) {
|
||||
return reinterpret_cast<dht_value*>(new ValueSp(std::make_shared<dht::Value>(data, size)));
|
||||
}
|
||||
|
||||
dht_value* dht_value_new_from_string(const char* str) {
|
||||
ValueSp value = std::make_shared<dht::Value>((const uint8_t*)str, strlen(str));
|
||||
value->user_type = "text/plain";
|
||||
return reinterpret_cast<dht_value*>(new ValueSp(std::move(value)));
|
||||
}
|
||||
|
||||
dht_value* dht_value_ref(const dht_value* v) {
|
||||
return reinterpret_cast<dht_value*>(new ValueSp(*reinterpret_cast<const ValueSp*>(v)));
|
||||
}
|
||||
@@ -144,9 +174,13 @@ bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, si
|
||||
|
||||
dht_blob* dht_publickey_encrypt(const dht_publickey* pk, const char* data, size_t data_size) {
|
||||
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
|
||||
auto rdata = new dht::Blob;
|
||||
*rdata = pkey->encrypt((const uint8_t*)data, data_size);
|
||||
return (dht_blob*)rdata;
|
||||
try {
|
||||
auto rdata = std::make_unique<dht::Blob>();
|
||||
*rdata = pkey->encrypt((const uint8_t*)data, data_size);
|
||||
return (dht_blob*)rdata.release();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// dht::crypto::PrivateKey
|
||||
@@ -173,7 +207,18 @@ int dht_privatekey_export(const dht_privatekey* k, char* out, size_t* out_size,
|
||||
|
||||
dht_publickey* dht_privatekey_get_publickey(const dht_privatekey* k) {
|
||||
const auto& key = *reinterpret_cast<const PrivkeySp*>(k);
|
||||
return reinterpret_cast<dht_publickey*>(new PubkeySp(std::make_shared<dht::crypto::PublicKey>(key->getPublicKey())));
|
||||
return reinterpret_cast<dht_publickey*>(new PubkeySp(key->getSharedPublicKey()));
|
||||
}
|
||||
|
||||
dht_blob* dht_privatekey_decrypt(const dht_privatekey* k, const char* data, size_t data_size) {
|
||||
const auto& key = *reinterpret_cast<const PrivkeySp*>(k);
|
||||
try {
|
||||
auto rdata = std::make_unique<dht::Blob>();
|
||||
*rdata = key->decrypt((const uint8_t*)data, data_size);
|
||||
return (dht_blob*)rdata.release();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void dht_privatekey_delete(dht_privatekey* pk) {
|
||||
@@ -247,7 +292,7 @@ void dht_runner_config_default(dht_runner_config* config) {
|
||||
}
|
||||
|
||||
// dht::DhtRunner
|
||||
dht_runner* dht_runner_new() {
|
||||
dht_runner* dht_runner_new(void) {
|
||||
return reinterpret_cast<dht_runner*>(new dht::DhtRunner);
|
||||
}
|
||||
|
||||
@@ -255,39 +300,55 @@ void dht_runner_delete(dht_runner* runner) {
|
||||
delete reinterpret_cast<dht::DhtRunner*>(runner);
|
||||
}
|
||||
|
||||
void dht_runner_run(dht_runner* r, in_port_t port) {
|
||||
int dht_runner_run(dht_runner* r, in_port_t port) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
runner->run(port, {}, true);
|
||||
try {
|
||||
runner->run(port, {}, true);
|
||||
} catch(...) {
|
||||
return ENOTCONN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dht_runner_run_config(dht_runner* r, in_port_t port, const dht_runner_config* conf) {
|
||||
int dht_runner_run_config(dht_runner* r, in_port_t port, const dht_runner_config* conf) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
dht::DhtRunner::Config config;
|
||||
config.dht_config.node_config.is_bootstrap = conf->dht_config.node_config.is_bootstrap;
|
||||
config.dht_config.node_config.maintain_storage = conf->dht_config.node_config.maintain_storage;
|
||||
config.dht_config.node_config.node_id = *reinterpret_cast<const dht::InfoHash*>(&conf->dht_config.node_config.node_id);
|
||||
config.dht_config.node_config.network = conf->dht_config.node_config.network;
|
||||
config.dht_config.node_config.persist_path = conf->dht_config.node_config.persist_path
|
||||
? std::string(conf->dht_config.node_config.persist_path) : std::string{};
|
||||
try {
|
||||
dht::DhtRunner::Config config;
|
||||
config.dht_config.node_config.is_bootstrap = conf->dht_config.node_config.is_bootstrap;
|
||||
config.dht_config.node_config.maintain_storage = conf->dht_config.node_config.maintain_storage;
|
||||
config.dht_config.node_config.node_id = *reinterpret_cast<const dht::InfoHash*>(&conf->dht_config.node_config.node_id);
|
||||
config.dht_config.node_config.network = conf->dht_config.node_config.network;
|
||||
config.dht_config.node_config.persist_path = conf->dht_config.node_config.persist_path
|
||||
? std::string(conf->dht_config.node_config.persist_path) : std::string{};
|
||||
|
||||
if (conf->dht_config.id.privatekey)
|
||||
config.dht_config.id.first = *reinterpret_cast<const PrivkeySp*>(conf->dht_config.id.privatekey);
|
||||
if (conf->dht_config.id.privatekey)
|
||||
config.dht_config.id.first = *reinterpret_cast<const PrivkeySp*>(conf->dht_config.id.privatekey);
|
||||
|
||||
if (conf->dht_config.id.certificate)
|
||||
config.dht_config.id.second = *reinterpret_cast<const CertSp*>(conf->dht_config.id.certificate);
|
||||
if (conf->dht_config.id.certificate)
|
||||
config.dht_config.id.second = *reinterpret_cast<const CertSp*>(conf->dht_config.id.certificate);
|
||||
|
||||
config.threaded = conf->threaded;
|
||||
config.proxy_server = conf->proxy_server ? std::string(conf->proxy_server) : std::string{};
|
||||
config.push_node_id = conf->push_node_id ? std::string(conf->push_node_id) : std::string{};
|
||||
config.push_token = conf->push_token ? std::string(conf->push_token) : std::string{};
|
||||
config.peer_discovery = conf->peer_discovery;
|
||||
config.peer_publish = conf->peer_publish;
|
||||
runner->run(port, config);
|
||||
config.threaded = conf->threaded;
|
||||
config.proxy_server = conf->proxy_server ? std::string(conf->proxy_server) : std::string{};
|
||||
config.push_node_id = conf->push_node_id ? std::string(conf->push_node_id) : std::string{};
|
||||
config.push_token = conf->push_token ? std::string(conf->push_token) : std::string{};
|
||||
config.peer_discovery = conf->peer_discovery;
|
||||
config.peer_publish = conf->peer_publish;
|
||||
runner->run(port, config);
|
||||
} catch(...) {
|
||||
return ENOTCONN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dht_runner_ping(dht_runner* r, struct sockaddr* addr, socklen_t addr_len) {
|
||||
void dht_runner_ping(dht_runner* r, struct sockaddr* addr, socklen_t addr_len, dht_done_cb done_cb, void* cb_user_data) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
runner->bootstrap(dht::SockAddr(addr, addr_len));
|
||||
if (done_cb) {
|
||||
runner->bootstrap(dht::SockAddr(addr, addr_len), [done_cb, cb_user_data](bool ok){
|
||||
done_cb(ok, cb_user_data);
|
||||
});
|
||||
} else {
|
||||
runner->bootstrap(dht::SockAddr(addr, addr_len));
|
||||
}
|
||||
}
|
||||
|
||||
void dht_runner_bootstrap(dht_runner* r, const char* host, const char* service) {
|
||||
@@ -326,8 +387,11 @@ dht_op_token* dht_runner_listen(dht_runner* r, const dht_infohash* h, dht_value_
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
|
||||
auto fret = new std::future<size_t>;
|
||||
auto guard = done_cb ? std::make_shared<ScopeGuardCb>(done_cb, cb_user_data) : std::shared_ptr<ScopeGuardCb>{};
|
||||
*fret = runner->listen(*hash, [cb,cb_user_data, guard](const std::vector<std::shared_ptr<dht::Value>>& values, bool expired) {
|
||||
*fret = runner->listen(*hash, [
|
||||
cb,
|
||||
cb_user_data,
|
||||
guard = done_cb ? std::make_shared<ScopeGuardCb>(done_cb, cb_user_data) : std::shared_ptr<ScopeGuardCb>{}
|
||||
](const std::vector<std::shared_ptr<dht::Value>>& values, bool expired) {
|
||||
for (const auto& value : values) {
|
||||
if (not cb(reinterpret_cast<const dht_value*>(&value), expired, cb_user_data))
|
||||
return false;
|
||||
@@ -393,6 +457,17 @@ void dht_runner_shutdown(dht_runner* r, dht_shutdown_cb done_cb, void* cb_user_d
|
||||
});
|
||||
}
|
||||
|
||||
bool dht_runner_is_running(const dht_runner* r) {
|
||||
if (not r) return false;
|
||||
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
|
||||
return runner->isRunning();
|
||||
}
|
||||
|
||||
in_port_t dht_runner_get_bound_port(const dht_runner* r, sa_family_t af) {
|
||||
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
|
||||
return runner->getBoundPort(af);
|
||||
}
|
||||
|
||||
dht_infohash dht_runner_get_node_id(const dht_runner* r) {
|
||||
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
|
||||
dht_infohash ret;
|
||||
@@ -414,9 +489,9 @@ struct sockaddr** dht_runner_get_public_address(const dht_runner* r) {
|
||||
return nullptr;
|
||||
auto ret = (struct sockaddr**)malloc(sizeof(struct sockaddr*) * (addrs.size() + 1));
|
||||
for (size_t i=0; i<addrs.size(); i++) {
|
||||
if (auto len = addrs[i].getLength()) {
|
||||
ret[i] = (struct sockaddr*)malloc(len);
|
||||
memcpy((struct sockaddr*)ret[i], addrs[i].get(), len);
|
||||
if (const auto& addr = addrs[i]) {
|
||||
ret[i] = (struct sockaddr*)malloc(addr.getLength());
|
||||
memcpy((struct sockaddr*)ret[i], addr.get(), addr.getLength());
|
||||
} else {
|
||||
ret[i] = nullptr;
|
||||
}
|
||||
|
||||
+30
-4
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -58,6 +76,7 @@ OPENDHT_C_PUBLIC dht_privatekey* dht_privatekey_generate(unsigned key_length_bit
|
||||
OPENDHT_C_PUBLIC dht_privatekey* dht_privatekey_import(const uint8_t* dat, size_t dat_size, const char* password);
|
||||
OPENDHT_C_PUBLIC int dht_privatekey_export(const dht_privatekey*, char* out, size_t* out_size, const char* password);
|
||||
OPENDHT_C_PUBLIC dht_publickey* dht_privatekey_get_publickey(const dht_privatekey*);
|
||||
OPENDHT_C_PUBLIC dht_blob* dht_privatekey_decrypt(const dht_privatekey*, const char* data, size_t data_size);
|
||||
OPENDHT_C_PUBLIC void dht_privatekey_delete(dht_privatekey*);
|
||||
|
||||
// dht::crypto::Certificate
|
||||
@@ -82,6 +101,7 @@ struct OPENDHT_C_PUBLIC dht_value;
|
||||
typedef struct dht_value dht_value;
|
||||
typedef uint64_t dht_value_id;
|
||||
OPENDHT_C_PUBLIC dht_value* dht_value_new(const uint8_t* data, size_t size);
|
||||
OPENDHT_C_PUBLIC dht_value* dht_value_new_from_string(const char* str);
|
||||
OPENDHT_C_PUBLIC dht_value* dht_value_ref(const dht_value*);
|
||||
OPENDHT_C_PUBLIC void dht_value_unref(dht_value*);
|
||||
OPENDHT_C_PUBLIC dht_data_view dht_value_get_data(const dht_value* data);
|
||||
@@ -89,6 +109,7 @@ OPENDHT_C_PUBLIC dht_value_id dht_value_get_id(const dht_value* data);
|
||||
OPENDHT_C_PUBLIC dht_publickey* dht_value_get_owner(const dht_value* data);
|
||||
OPENDHT_C_PUBLIC dht_infohash dht_value_get_recipient(const dht_value* data);
|
||||
OPENDHT_C_PUBLIC const char* dht_value_get_user_type(const dht_value* data);
|
||||
OPENDHT_C_PUBLIC void dht_value_set_user_type(dht_value* data, const char* user_type);
|
||||
|
||||
// callbacks
|
||||
typedef bool (*dht_get_cb)(const dht_value* value, void* user_data);
|
||||
@@ -133,11 +154,13 @@ OPENDHT_C_PUBLIC void dht_runner_config_default(dht_runner_config* config);
|
||||
// dht::DhtRunner
|
||||
struct OPENDHT_C_PUBLIC dht_runner;
|
||||
typedef struct dht_runner dht_runner;
|
||||
OPENDHT_C_PUBLIC dht_runner* dht_runner_new();
|
||||
OPENDHT_C_PUBLIC dht_runner* dht_runner_new(void);
|
||||
OPENDHT_C_PUBLIC void dht_runner_delete(dht_runner* runner);
|
||||
OPENDHT_C_PUBLIC void dht_runner_run(dht_runner* runner, in_port_t port);
|
||||
OPENDHT_C_PUBLIC void dht_runner_run_config(dht_runner* runner, in_port_t port, const dht_runner_config* config);
|
||||
OPENDHT_C_PUBLIC void dht_runner_ping(dht_runner* runner, struct sockaddr* addr, socklen_t addr_len);
|
||||
/* Returns 0 on success, standard error code on failure */
|
||||
OPENDHT_C_PUBLIC int dht_runner_run(dht_runner* runner, in_port_t port);
|
||||
/* Returns 0 on success, standard error code on failure */
|
||||
OPENDHT_C_PUBLIC int dht_runner_run_config(dht_runner* runner, in_port_t port, const dht_runner_config* config);
|
||||
OPENDHT_C_PUBLIC void dht_runner_ping(dht_runner* runner, struct sockaddr* addr, socklen_t addr_len, dht_done_cb done_cb, void* cb_user_data);
|
||||
OPENDHT_C_PUBLIC void dht_runner_bootstrap(dht_runner* runner, const char* host, const char* service);
|
||||
OPENDHT_C_PUBLIC void dht_runner_get(dht_runner* runner, const dht_infohash* hash, dht_get_cb cb, dht_done_cb done_cb, void* cb_user_data);
|
||||
OPENDHT_C_PUBLIC dht_op_token* dht_runner_listen(dht_runner* runner, const dht_infohash* hash, dht_value_cb cb, dht_shutdown_cb done_cb, void* cb_user_data);
|
||||
@@ -149,6 +172,9 @@ OPENDHT_C_PUBLIC void dht_runner_cancel_put(dht_runner* runner, const dht_infoha
|
||||
OPENDHT_C_PUBLIC void dht_runner_shutdown(dht_runner* runner, dht_shutdown_cb done_cb, void* cb_user_data);
|
||||
OPENDHT_C_PUBLIC dht_infohash dht_runner_get_node_id(const dht_runner* runner);
|
||||
OPENDHT_C_PUBLIC dht_infohash dht_runner_get_id(const dht_runner* runner);
|
||||
OPENDHT_C_PUBLIC bool dht_runner_is_running(const dht_runner* runner);
|
||||
OPENDHT_C_PUBLIC in_port_t dht_runner_get_bound_port(const dht_runner* runner, sa_family_t af);
|
||||
/** Returns null-terminated array that must be freed after use as well as each element */
|
||||
OPENDHT_C_PUBLIC struct sockaddr** dht_runner_get_public_address(const dht_runner* runner);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
# atomic builtins are required for threading support.
|
||||
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/DetermineGCCCompatible.cmake")
|
||||
|
||||
# Sometimes linking against libatomic is required for atomic ops, if
|
||||
# the platform doesn't support lock-free atomics.
|
||||
|
||||
function(check_working_cxx_atomics varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <atomic>
|
||||
std::atomic<int> x;
|
||||
std::atomic<short> y;
|
||||
std::atomic<char> z;
|
||||
int main() {
|
||||
++z;
|
||||
++y;
|
||||
return ++x;
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
endfunction(check_working_cxx_atomics)
|
||||
|
||||
function(check_working_cxx_atomics64 varname)
|
||||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
std::atomic<uint64_t> x (0);
|
||||
int main() {
|
||||
uint64_t i = x.load(std::memory_order_relaxed);
|
||||
(void)i;
|
||||
return 0;
|
||||
}
|
||||
" ${varname})
|
||||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||
endfunction(check_working_cxx_atomics64)
|
||||
|
||||
|
||||
# Check for (non-64-bit) atomic operations.
|
||||
if(MSVC)
|
||||
set(HAVE_CXX_ATOMICS_WITHOUT_LIB True)
|
||||
elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
|
||||
# First check if atomics work without the library.
|
||||
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)
|
||||
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()
|
||||
|
||||
# Check for 64 bit atomic operations.
|
||||
if(MSVC)
|
||||
set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
|
||||
elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
|
||||
# First check if atomics work without the library.
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
# If not, check if the library exists, and atomics work with it.
|
||||
if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
|
||||
check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
|
||||
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
## TODO: This define is only used for the legacy atomic operations in
|
||||
## llvm's Atomic.h, which should be replaced. Other code simply
|
||||
## assumes C++11 <atomic> works.
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#endif
|
||||
int main() {
|
||||
#ifdef _MSC_VER
|
||||
volatile LONG val = 1;
|
||||
MemoryBarrier();
|
||||
InterlockedCompareExchange(&val, 0, 1);
|
||||
InterlockedIncrement(&val);
|
||||
InterlockedDecrement(&val);
|
||||
#else
|
||||
volatile unsigned long val = 1;
|
||||
__sync_synchronize();
|
||||
__sync_val_compare_and_swap(&val, 1, 0);
|
||||
__sync_add_and_fetch(&val, 1);
|
||||
__sync_sub_and_fetch(&val, 1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
" LLVM_HAS_ATOMICS)
|
||||
|
||||
if( NOT LLVM_HAS_ATOMICS )
|
||||
message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
|
||||
endif()
|
||||
@@ -0,0 +1,13 @@
|
||||
# Determine if the compiler has GCC-compatible command-line syntax.
|
||||
|
||||
if(NOT DEFINED LLVM_COMPILER_IS_GCC_COMPATIBLE)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
elseif( MSVC )
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE OFF)
|
||||
elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" )
|
||||
set(LLVM_COMPILER_IS_GCC_COMPATIBLE ON)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,28 +0,0 @@
|
||||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_CPPUNIT "cppunit")
|
||||
|
||||
FIND_PATH(CPPUNIT_INCLUDE_DIRS
|
||||
NAMES cppunit/TestCase.h
|
||||
HINTS ${PC_CPPUNIT_INCLUDE_DIR}
|
||||
${CMAKE_INSTALL_PREFIX}/include
|
||||
PATHS
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(CPPUNIT_LIBRARIES
|
||||
NAMES cppunit
|
||||
HINTS ${PC_CPPUNIT_LIBDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
PATHS
|
||||
${CPPUNIT_INCLUDE_DIRS}/../lib
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS)
|
||||
@@ -1,64 +0,0 @@
|
||||
# - Try to find msgpack
|
||||
# Once done this will define
|
||||
# MSGPACK_FOUND - System has msgpack
|
||||
# MSGPACK_INCLUDE_DIRS - The msgpack include directories
|
||||
# MSGPACK_LIBRARIES - The libraries needed to use msgpack
|
||||
|
||||
if(NOT MSGPACK_USE_BUNDLED)
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_search_module(PC_MSGPACK QUIET
|
||||
msgpackc>=${Msgpack_FIND_VERSION}
|
||||
msgpack>=${Msgpack_FIND_VERSION})
|
||||
endif()
|
||||
else()
|
||||
set(PC_MSGPACK_INCLUDEDIR)
|
||||
set(PC_MSGPACK_INCLUDE_DIRS)
|
||||
set(PC_MSGPACK_LIBDIR)
|
||||
set(PC_MSGPACK_LIBRARY_DIRS)
|
||||
set(LIMIT_SEARCH NO_DEFAULT_PATH)
|
||||
endif()
|
||||
|
||||
set(MSGPACK_DEFINITIONS ${PC_MSGPACK_CFLAGS_OTHER})
|
||||
|
||||
find_path(MSGPACK_INCLUDE_DIR msgpack/version_master.h
|
||||
HINTS ${PC_MSGPACK_INCLUDEDIR} ${PC_MSGPACK_INCLUDE_DIRS}
|
||||
${LIMIT_SEARCH})
|
||||
|
||||
if(MSGPACK_INCLUDE_DIR)
|
||||
file(READ ${MSGPACK_INCLUDE_DIR}/msgpack/version_master.h msgpack_version_h)
|
||||
string(REGEX REPLACE ".*MSGPACK_VERSION_MAJOR +([0-9]+).*" "\\1" MSGPACK_VERSION_MAJOR "${msgpack_version_h}")
|
||||
string(REGEX REPLACE ".*MSGPACK_VERSION_MINOR +([0-9]+).*" "\\1" MSGPACK_VERSION_MINOR "${msgpack_version_h}")
|
||||
string(REGEX REPLACE ".*MSGPACK_VERSION_REVISION +([0-9]+).*" "\\1" MSGPACK_VERSION_REVISION "${msgpack_version_h}")
|
||||
set(MSGPACK_VERSION_STRING "${MSGPACK_VERSION_MAJOR}.${MSGPACK_VERSION_MINOR}.${MSGPACK_VERSION_REVISION}")
|
||||
else()
|
||||
set(MSGPACK_VERSION_STRING)
|
||||
endif()
|
||||
|
||||
# If we're asked to use static linkage, add libmsgpack{,c}.a as a preferred library name.
|
||||
if(MSGPACK_USE_STATIC)
|
||||
list(APPEND MSGPACK_NAMES
|
||||
"${CMAKE_STATIC_LIBRARY_PREFIX}msgpackc${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
"${CMAKE_STATIC_LIBRARY_PREFIX}msgpack${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
endif()
|
||||
|
||||
list(APPEND MSGPACK_NAMES msgpackc msgpack)
|
||||
|
||||
find_library(MSGPACK_LIBRARY NAMES ${MSGPACK_NAMES}
|
||||
# Check each directory for all names to avoid using headers/libraries from
|
||||
# different places.
|
||||
NAMES_PER_DIR
|
||||
HINTS ${PC_MSGPACK_LIBDIR} ${PC_MSGPACK_LIBRARY_DIRS}
|
||||
${LIMIT_SEARCH})
|
||||
|
||||
mark_as_advanced(MSGPACK_INCLUDE_DIR MSGPACK_LIBRARY)
|
||||
|
||||
set(MSGPACK_LIBRARIES ${MSGPACK_LIBRARY})
|
||||
set(MSGPACK_INCLUDE_DIRS ${MSGPACK_INCLUDE_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set MSGPACK_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(Msgpack
|
||||
REQUIRED_VARS MSGPACK_LIBRARY MSGPACK_INCLUDE_DIR
|
||||
VERSION_VAR MSGPACK_VERSION_STRING)
|
||||
+5
-32
@@ -1,6 +1,6 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 2)
|
||||
m4_define([opendht_minor_version], 0)
|
||||
m4_define([opendht_minor_version], 4)
|
||||
m4_define([opendht_patch_version], 0)
|
||||
m4_define([opendht_version],
|
||||
[opendht_major_version.opendht_minor_version.opendht_patch_version])
|
||||
@@ -102,7 +102,7 @@ AS_IF([test "x$SYS" = "xandroid"],
|
||||
LT_INIT()
|
||||
LT_LANG(C++)
|
||||
|
||||
AX_CXX_COMPILE_STDCXX(14,[noext],[mandatory])
|
||||
AX_CXX_COMPILE_STDCXX(17,[noext],[mandatory])
|
||||
|
||||
PKG_PROG_PKG_CONFIG()
|
||||
|
||||
@@ -132,6 +132,8 @@ 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])
|
||||
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
|
||||
PKG_CHECK_MODULES([Argon2], [libargon2])
|
||||
AC_SUBST(argon2_lib, [", libargon2"])
|
||||
|
||||
AC_ARG_WITH([jsoncpp], AS_HELP_STRING([--without-jsoncpp], [Build without JsonCpp support]))
|
||||
AS_IF([test "x$with_jsoncpp" != "xno"],
|
||||
@@ -157,14 +159,6 @@ AS_IF([test "x$have_openssl" = "xyes"], [
|
||||
AC_MSG_NOTICE([Not using OpenSSL])
|
||||
])
|
||||
|
||||
AC_ARG_WITH([http_parser_fork], AS_HELP_STRING([--with-http-parser-fork], [Build with http_parser fork to support old API]))
|
||||
AS_IF([test "x$with_http_parser_fork" = "xyes"],[
|
||||
AC_MSG_NOTICE([Using http_parser fork])
|
||||
AC_DEFINE([OPENDHT_PROXY_HTTP_PARSER_FORK], [], [Define if using http parser fork])
|
||||
], [
|
||||
AC_MSG_NOTICE([Not using http_parser fork])
|
||||
])
|
||||
|
||||
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
|
||||
AC_CHECK_HEADERS([asio.hpp], exit,, AC_MSG_ERROR([Missing Asio headers files]))
|
||||
CXXFLAGS="${CXXFLAGS} -DASIO_STANDALONE"
|
||||
@@ -181,28 +175,7 @@ AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
|
||||
AS_IF([test "x$http_parser_headers" != "xyes"], AC_MSG_ERROR([Missing HttpParser headers files]))
|
||||
])
|
||||
|
||||
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
|
||||
|
||||
dnl Check for Argon2
|
||||
AC_ARG_WITH([argon2], AS_HELP_STRING([--without-argon2], [Use included Argon2]))
|
||||
AS_IF([test "x$with_argon2" != "xno"],
|
||||
[PKG_CHECK_MODULES([Argon2], [libargon2], [have_argon2=yes], [have_argon2=no])],
|
||||
[have_argon2=no])
|
||||
AS_IF([test "x$have_argon2" = "xyes"], [
|
||||
AC_MSG_NOTICE([Using system Argon2])
|
||||
AC_SUBST(argon2_lib, [", libargon2"])
|
||||
], [
|
||||
AS_IF([test "x$with_argon2" = "xyes"], [
|
||||
AC_MSG_ERROR([Argon2 requested but not found])
|
||||
],[
|
||||
AC_MSG_NOTICE([Using included Argon2])
|
||||
AC_SUBST(Argon2_CFLAGS, "-I\${top_srcdir}/argon2/src -I\${top_srcdir}/argon2/include")
|
||||
AC_SUBST(Argon2_LIBS, "libargon2.la")
|
||||
AC_SUBST(Argon2_LDFLAGS, "-L\${abs_top_srcdir}/argon2/src/.libs")
|
||||
])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([WITH_INCLUDED_ARGON2], [test "x$have_argon2" = "xno"])
|
||||
CXXFLAGS="${CXXFLAGS} -DMSGPACK_NO_BOOST -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
|
||||
|
||||
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
|
||||
AM_CONDITIONAL(ENABLE_TOOLS, test x$build_tools == xyes)
|
||||
|
||||
+13
-3
@@ -1,6 +1,16 @@
|
||||
FROM aberaud/opendht-deps
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps:latest
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On && make -j8 && make install \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
-DOPENDHT_PEER_DISCOVERY=On \
|
||||
-DOPENDHT_PYTHON=On \
|
||||
-DOPENDHT_TOOLS=On \
|
||||
-DOPENDHT_PROXY_SERVER=On \
|
||||
-DOPENDHT_PROXY_CLIENT=On \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
+11
-8
@@ -1,13 +1,16 @@
|
||||
FROM docker.pkg.github.com/savoirfairelinux/opendht/opendht-deps-bionic:2.0.0
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-bionic:latest
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DOPENDHT_PROXY_CLIENT=On \
|
||||
-DOPENDHT_PROXY_SERVER=On \
|
||||
-DOPENDHT_C=On \
|
||||
-DOPENDHT_PYTHON=On \
|
||||
-DOPENDHT_LTO=On \
|
||||
&& make -j8 && make install \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
-DOPENDHT_PEER_DISCOVERY=On \
|
||||
-DOPENDHT_PYTHON=On \
|
||||
-DOPENDHT_TOOLS=On \
|
||||
-DOPENDHT_PROXY_SERVER=On \
|
||||
-DOPENDHT_PROXY_CLIENT=On \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
+19
-47
@@ -1,56 +1,28 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
FROM ubuntu:20.04
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev \
|
||||
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
|
||||
autotools-dev autoconf libssl-dev \
|
||||
&& apt-get clean
|
||||
dialog apt-utils \
|
||||
&& apt-get clean \
|
||||
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
|
||||
|
||||
RUN echo "*** Installing libfmt ***" \
|
||||
&& wget https://github.com/fmtlib/fmt/archive/5.3.0.tar.gz \
|
||||
&& tar -xzf 5.3.0.tar.gz && cd fmt-5.3.0/ \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=On -DFMT_TEST=Off -DFMT_DOC=Off . \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../ && rm -rf fmt*
|
||||
|
||||
# libhttp-parser-dev is 2.1-2 which is too old
|
||||
RUN echo "*** Building nodejs/http_parser dependency ***" \
|
||||
&& wget https://github.com/nodejs/http-parser/archive/v2.9.2.tar.gz \
|
||||
&& tar xvf v2.9.2.tar.gz && cd http-parser-2.9.2/ \
|
||||
&& PREFIX=/usr make -j8 install \
|
||||
&& cd ../ && rm -rf http-parser*
|
||||
|
||||
# libasio-dev (1.10.6-3) is too old
|
||||
RUN echo "** Building a recent version of asio ***" \
|
||||
&& wget https://github.com/aberaud/asio/archive/a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz \
|
||||
&& tar -xvf a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz && cd asio-a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571/asio \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
|
||||
&& make install \
|
||||
&& cd ../../ && rm -rf asio*
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential pkg-config cmake git wget \
|
||||
autotools-dev autoconf \
|
||||
cython3 python3-dev python3-setuptools \
|
||||
libncurses5-dev libreadline-dev nettle-dev libcppunit-dev \
|
||||
libgnutls28-dev libuv1-dev libjsoncpp-dev libargon2-dev \
|
||||
libssl-dev libfmt-dev libhttp-parser-dev libasio-dev libmsgpack-dev \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
||||
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/aberaud/restinio/archive/a7a10e419d9089c5b8ee63f5e3098c892f22fae4.tar.gz \
|
||||
&& ls -l && tar -xzf a7a10e419d9089c5b8ee63f5e3098c892f22fae4.tar.gz \
|
||||
&& cd restinio-a7a10e419d9089c5b8ee63f5e3098c892f22fae4/dev \
|
||||
&& 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 && make install \
|
||||
&& cd ../../ && rm -rf restinio*
|
||||
|
||||
|
||||
# build restbed from sources
|
||||
RUN git clone --recursive https://github.com/corvusoft/restbed.git \
|
||||
&& cd restbed && mkdir build && cd build \
|
||||
&& cmake -DBUILD_TESTS=NO -DBUILD_EXAMPLES=NO -DBUILD_SSL=NO -DBUILD_SHARED=YES -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib .. \
|
||||
&& make -j8 install \
|
||||
&& cd .. && rm -rf restbed
|
||||
|
||||
#build msgpack from source
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.1.5/msgpack-2.1.5.tar.gz \
|
||||
&& tar -xzf msgpack-2.1.5.tar.gz \
|
||||
&& cd msgpack-2.1.5 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-2.1.5 msgpack-2.1.5.tar.gz
|
||||
&& cd ../../.. && rm -rf restinio
|
||||
@@ -1,12 +1,16 @@
|
||||
FROM ubuntu:18.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
|
||||
RUN apt-get update && apt-get install -y \
|
||||
apt-transport-https build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev \
|
||||
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 \
|
||||
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev libssl-dev \
|
||||
&& apt-get clean
|
||||
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/*
|
||||
|
||||
RUN pip3 install --upgrade cmake
|
||||
|
||||
# libasio-dev (1.10) is too old
|
||||
RUN echo "** Building a recent version of asio ***" \
|
||||
|
||||
+17
-48
@@ -1,62 +1,31 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
FROM ubuntu:20.04
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
dialog apt-utils \
|
||||
&& apt-get clean \
|
||||
&& echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y llvm llvm-dev clang make cmake 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 \
|
||||
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
|
||||
autotools-dev autoconf libssl-dev libargon2-dev \
|
||||
libfmt-dev libhttp-parser-dev libasio-dev \
|
||||
&& apt-get remove -y gcc g++ && apt-get autoremove -y \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
||||
|
||||
ENV CC cc
|
||||
ENV CXX c++
|
||||
|
||||
RUN echo "*** Installing libfmt ***" \
|
||||
&& wget https://github.com/fmtlib/fmt/archive/5.3.0.tar.gz \
|
||||
&& tar -xzf 5.3.0.tar.gz && cd fmt-5.3.0/ \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=On -DFMT_TEST=Off -DFMT_DOC=Off . \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../ && rm -rf fmt*
|
||||
|
||||
# libhttp-parser-dev is 2.1-2 which is too old
|
||||
RUN echo "*** Building nodejs/http_parser dependency ***" \
|
||||
&& wget https://github.com/nodejs/http-parser/archive/v2.9.2.tar.gz \
|
||||
&& tar xvf v2.9.2.tar.gz && cd http-parser-2.9.2/ \
|
||||
&& PREFIX=/usr make -j8 install \
|
||||
&& cd ../ && rm -rf http-parser*
|
||||
|
||||
# libasio-dev (1.10.6-3) is too old
|
||||
RUN echo "** Building a recent version of asio ***" \
|
||||
&& wget https://github.com/aberaud/asio/archive/a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz \
|
||||
&& tar -xvf a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571.tar.gz && cd asio-a7d66ef4017d8f1b7f2cef1bb4ba8e23b0961571/asio \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
|
||||
&& make install \
|
||||
&& cd ../../ && rm -rf asio*
|
||||
|
||||
#patch for https://github.com/Stiffstream/restinio-conan-example/issues/2
|
||||
RUN apt-get update && apt-get install -y python3-pip && pip3 install --upgrade cmake
|
||||
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/aberaud/restinio/archive/a7a10e419d9089c5b8ee63f5e3098c892f22fae4.tar.gz \
|
||||
&& ls -l && tar -xzf a7a10e419d9089c5b8ee63f5e3098c892f22fae4.tar.gz \
|
||||
&& cd restinio-a7a10e419d9089c5b8ee63f5e3098c892f22fae4/dev \
|
||||
&& 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 && make install \
|
||||
&& cd ../../ && rm -rf restinio*
|
||||
|
||||
# build restbed from sources
|
||||
RUN git clone --recursive https://github.com/corvusoft/restbed.git \
|
||||
&& cd restbed && mkdir build && cd build \
|
||||
&& cmake -DBUILD_TESTS=NO -DBUILD_EXAMPLES=NO -DBUILD_SSL=NO -DBUILD_SHARED=YES -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib .. \
|
||||
&& make -j8 install \
|
||||
&& cd .. && rm -rf restbed
|
||||
|
||||
#build msgpack from source
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.1.5/msgpack-2.1.5.tar.gz \
|
||||
&& tar -xzf msgpack-2.1.5.tar.gz \
|
||||
&& cd msgpack-2.1.5 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-2.1.5 msgpack-2.1.5.tar.gz
|
||||
@@ -0,0 +1,16 @@
|
||||
FROM ghcr.io/savoirfairelinux/opendht/opendht-deps-llvm:latest
|
||||
LABEL maintainer="Adrien Béraud <adrien.beraud@savoirfairelinux.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/savoirfairelinux/opendht
|
||||
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On \
|
||||
-DOPENDHT_C=On \
|
||||
-DOPENDHT_PEER_DISCOVERY=On \
|
||||
-DOPENDHT_PYTHON=On \
|
||||
-DOPENDHT_TOOLS=On \
|
||||
-DOPENDHT_PROXY_SERVER=On \
|
||||
-DOPENDHT_PROXY_CLIENT=On \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -1,7 +0,0 @@
|
||||
FROM aberaud/opendht-deps
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
|
||||
COPY . /root/opendht
|
||||
RUN cd /root/opendht && mkdir build && cd build \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_C=On -DOPENDHT_LTO=On -DOPENDHT_TESTS=ON .. \
|
||||
&& make -j8 && ./opendht_unit_tests && make install
|
||||
@@ -1,7 +0,0 @@
|
||||
FROM aberaud/opendht-deps-llvm
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
|
||||
COPY . /root/opendht
|
||||
RUN cd /root/opendht && mkdir build && cd build \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_C=On -DOPENDHT_TESTS=ON .. \
|
||||
&& make -j8 && ./opendht_unit_tests && make install
|
||||
@@ -1,4 +0,0 @@
|
||||
FROM aberaud/opendht-deps
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
|
||||
COPY . /root/opendht
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+13
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -82,6 +82,8 @@ struct OPENDHT_PUBLIC NodeInfo {
|
||||
NodeStats ipv4 {};
|
||||
NodeStats ipv6 {};
|
||||
size_t ongoing_ops {0};
|
||||
in_port_t bound4 {0};
|
||||
in_port_t bound6 {0};
|
||||
|
||||
#ifdef OPENDHT_JSONCPP
|
||||
/**
|
||||
@@ -130,7 +132,7 @@ struct OPENDHT_PUBLIC Config {
|
||||
/* If non-0, overrides the default maximum store size. -1 means no limit. */
|
||||
ssize_t max_store_size {0};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Use appropriate bahavior for a public IP, stable node:
|
||||
* - No connectivity change triggered when a search fails
|
||||
* - Larger listen refresh time
|
||||
@@ -146,7 +148,7 @@ struct OPENDHT_PUBLIC SecureDhtConfig
|
||||
Config node_config {};
|
||||
crypto::Identity id {};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Cache all encountered public keys and certificates,
|
||||
* for use by the certificate store, putEncrypted and putSigned
|
||||
*/
|
||||
@@ -162,6 +164,7 @@ using GetCallback = std::function<bool(const std::vector<std::shared_ptr<Value>>
|
||||
using ValueCallback = std::function<bool(const std::vector<std::shared_ptr<Value>>& values, bool expired)>;
|
||||
using GetCallbackSimple = std::function<bool(std::shared_ptr<Value> value)>;
|
||||
using ShutdownCallback = std::function<void()>;
|
||||
using IdentityAnnouncedCb = std::function<void(bool)>;
|
||||
|
||||
using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::Certificate>>(const InfoHash& pk_id)>;
|
||||
|
||||
@@ -176,13 +179,13 @@ typedef bool (*FilterRaw)(const Value&, void *user_data);
|
||||
|
||||
using DoneCallbackSimple = std::function<void(bool success)>;
|
||||
|
||||
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(const GetCallbackRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC GetCallback bindGetCb(const GetCallbackSimple& cb);
|
||||
OPENDHT_PUBLIC ValueCallback bindValueCb(const ValueCallbackRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(const ShutdownCallbackRaw& shutdown_cb_raw, void* user_data);
|
||||
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC GetCallback bindGetCb(GetCallbackSimple cb);
|
||||
OPENDHT_PUBLIC ValueCallback bindValueCb(ValueCallbackRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC ShutdownCallback bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackSimple donecb);
|
||||
OPENDHT_PUBLIC DoneCallback bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallbackSimple bindDoneCbSimple(const DoneCallbackSimpleRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC Value::Filter bindFilterRaw(const FilterRaw& raw_filter, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallback bindDoneCb(DoneCallbackRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC Value::Filter bindFilterRaw(FilterRaw raw_filter, void* user_data);
|
||||
|
||||
}
|
||||
+88
-12
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -26,6 +27,7 @@ extern "C" {
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/abstract.h>
|
||||
#include <gnutls/x509.h>
|
||||
#include <gnutls/ocsp.h>
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
@@ -78,6 +80,8 @@ struct OPENDHT_PUBLIC PublicKey
|
||||
* Takes ownership of an existing gnutls_pubkey.
|
||||
*/
|
||||
PublicKey(gnutls_pubkey_t k) : pk(k) {}
|
||||
|
||||
/** Import public key from serialized data */
|
||||
PublicKey(const uint8_t* dat, size_t dat_size);
|
||||
PublicKey(const Blob& pk) : PublicKey(pk.data(), pk.size()) {}
|
||||
PublicKey(PublicKey&& o) noexcept : pk(o.pk) { o.pk = nullptr; };
|
||||
@@ -104,12 +108,12 @@ struct OPENDHT_PUBLIC PublicKey
|
||||
PkId getLongId() const;
|
||||
|
||||
bool checkSignature(const uint8_t* data, size_t data_len, const uint8_t* signature, size_t signature_len) const;
|
||||
bool checkSignature(const Blob& data, const Blob& signature) const {
|
||||
inline bool checkSignature(const Blob& data, const Blob& signature) const {
|
||||
return checkSignature(data.data(), data.size(), signature.data(), signature.size());
|
||||
}
|
||||
|
||||
Blob encrypt(const uint8_t* data, size_t data_len) const;
|
||||
Blob encrypt(const Blob& data) const {
|
||||
inline Blob encrypt(const Blob& data) const {
|
||||
return encrypt(data.data(), data.size());
|
||||
}
|
||||
|
||||
@@ -160,7 +164,9 @@ struct OPENDHT_PUBLIC PrivateKey
|
||||
~PrivateKey();
|
||||
explicit operator bool() const { return key; }
|
||||
|
||||
PublicKey getPublicKey() const;
|
||||
const PublicKey& getPublicKey() const;
|
||||
const std::shared_ptr<PublicKey>& getSharedPublicKey() const;
|
||||
|
||||
int serialize(uint8_t* out, size_t* out_len, const std::string& password = {}) const;
|
||||
Blob serialize(const std::string& password = {}) const;
|
||||
|
||||
@@ -168,14 +174,16 @@ struct OPENDHT_PUBLIC PrivateKey
|
||||
* Sign the provided binary object.
|
||||
* @returns the signature data.
|
||||
*/
|
||||
Blob sign(const Blob&) const;
|
||||
Blob sign(const uint8_t* data, size_t data_len) const;
|
||||
inline Blob sign(const Blob& dat) const { return sign(dat.data(), dat.size()); }
|
||||
|
||||
/**
|
||||
* Try to decrypt the provided cypher text.
|
||||
* In case of failure a CryptoException is thrown.
|
||||
* @returns the decrypted data.
|
||||
*/
|
||||
Blob decrypt(const Blob& cypher) const;
|
||||
Blob decrypt(const uint8_t* cypher, size_t cypher_len) const;
|
||||
Blob decrypt(const Blob& cypher) const { return decrypt(cypher.data(), cypher.size()); }
|
||||
|
||||
/**
|
||||
* Generate a new RSA key pair
|
||||
@@ -193,10 +201,9 @@ private:
|
||||
PrivateKey& operator=(const PrivateKey&) = delete;
|
||||
Blob decryptBloc(const uint8_t* src, size_t src_size) const;
|
||||
|
||||
//friend dht::crypto::Identity dht::crypto::generateIdentity(const std::string&, dht::crypto::Identity, unsigned key_length);
|
||||
mutable std::shared_ptr<PublicKey> publicKey_ {};
|
||||
};
|
||||
|
||||
|
||||
class OPENDHT_PUBLIC RevocationList
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
@@ -309,6 +316,55 @@ private:
|
||||
gnutls_x509_crq_t request {nullptr};
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC OcspRequest
|
||||
{
|
||||
public:
|
||||
OcspRequest(gnutls_ocsp_req_t r) : request(r) {};
|
||||
OcspRequest(const uint8_t* dat_ptr, size_t dat_size);
|
||||
~OcspRequest();
|
||||
|
||||
/*
|
||||
* Get OCSP Request in readable format.
|
||||
*/
|
||||
std::string toString(const bool compact = true) const;
|
||||
|
||||
Blob pack() const;
|
||||
Blob getNonce() const;
|
||||
private:
|
||||
gnutls_ocsp_req_t request;
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC OcspResponse
|
||||
{
|
||||
public:
|
||||
OcspResponse(const uint8_t* dat_ptr, size_t dat_size);
|
||||
OcspResponse(const std::string& response) : OcspResponse((const uint8_t*)response.data(), response.size()) {};
|
||||
~OcspResponse();
|
||||
|
||||
Blob pack() const;
|
||||
/*
|
||||
* Get OCSP Response in readable format.
|
||||
*/
|
||||
std::string toString(const bool compact = true) const;
|
||||
|
||||
/*
|
||||
* Get OCSP response certificate status.
|
||||
* Return certificate status.
|
||||
* http://www.gnu.org/software/gnutls/reference/gnutls-ocsp.html#gnutls-ocsp-cert-status-t
|
||||
*/
|
||||
gnutls_ocsp_cert_status_t getCertificateStatus() const;
|
||||
|
||||
/*
|
||||
* Verify OCSP response and return OCSP status.
|
||||
* Throws CryptoException in case of error in the response.
|
||||
* http://www.gnu.org/software/gnutls/reference/gnutls-ocsp.html#gnutls-ocsp-verify-reason-t
|
||||
*/
|
||||
gnutls_ocsp_cert_status_t verifyDirect(const Certificate& crt, const Blob& nonce);
|
||||
|
||||
private:
|
||||
gnutls_ocsp_resp_t response;
|
||||
};
|
||||
|
||||
struct OPENDHT_PUBLIC Certificate {
|
||||
Certificate() noexcept {}
|
||||
|
||||
@@ -434,6 +490,8 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
/** Same as getPublicKey().getLongId() */
|
||||
PkId getLongId() const;
|
||||
|
||||
Blob getSerialNumber() const;
|
||||
|
||||
/** Read certificate Common Name (CN) */
|
||||
std::string getName() const;
|
||||
|
||||
@@ -483,8 +541,8 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
void addRevocationList(RevocationList&&);
|
||||
void addRevocationList(std::shared_ptr<RevocationList>);
|
||||
|
||||
static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", const Identity& ca = {}, bool is_ca = false);
|
||||
static Certificate generate(const CertificateRequest& request, const Identity& ca);
|
||||
static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", const Identity& ca = {}, bool is_ca = false, int64_t validity = 0);
|
||||
static Certificate generate(const CertificateRequest& request, const Identity& ca, int64_t validity = 0);
|
||||
|
||||
gnutls_x509_crt_t getCopy() const {
|
||||
if (not cert)
|
||||
@@ -527,11 +585,27 @@ struct OPENDHT_PUBLIC Certificate {
|
||||
|
||||
gnutls_digest_algorithm_t getPreferredDigest() const;
|
||||
|
||||
/*
|
||||
* Generate OCSP request.
|
||||
* Return GnuTLS error code.
|
||||
* https://www.gnutls.org/manual/html_node/Error-codes.html
|
||||
*/
|
||||
std::pair<std::string, Blob> generateOcspRequest(gnutls_x509_crt_t& issuer);
|
||||
|
||||
/**
|
||||
* Change certificate's expiration
|
||||
*/
|
||||
void setValidity(const Identity& ca, int64_t validity);
|
||||
void setValidity(const PrivateKey& key, int64_t validity);
|
||||
|
||||
gnutls_x509_crt_t cert {nullptr};
|
||||
std::shared_ptr<Certificate> issuer {};
|
||||
std::shared_ptr<OcspResponse> ocspResponse;
|
||||
private:
|
||||
Certificate(const Certificate&) = delete;
|
||||
Certificate& operator=(const Certificate&) = delete;
|
||||
mutable InfoHash cachedId_ {};
|
||||
mutable PkId cachedLongId_ {};
|
||||
|
||||
struct crlNumberCmp {
|
||||
bool operator() (const std::shared_ptr<RevocationList>& lhs, const std::shared_ptr<RevocationList>& rhs) const {
|
||||
@@ -707,8 +781,10 @@ OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
|
||||
/**
|
||||
* AES-GCM decryption.
|
||||
*/
|
||||
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const Blob& key);
|
||||
OPENDHT_PUBLIC Blob aesDecrypt(const Blob& data, const std::string& password);
|
||||
OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key);
|
||||
OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const Blob& key) { return aesDecrypt(data.data(), data.size(), key); }
|
||||
OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const std::string& password);
|
||||
OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const std::string& password) { return aesDecrypt(data.data(), data.size(), password); }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -66,8 +66,10 @@ private:
|
||||
|
||||
public:
|
||||
virtual void unpackValue(const Value& v) override {
|
||||
if (v.owner)
|
||||
if (v.owner) {
|
||||
owner = v.owner;
|
||||
from = v.owner->getId();
|
||||
}
|
||||
BaseClass::unpackValue(v);
|
||||
}
|
||||
|
||||
@@ -75,6 +77,7 @@ public:
|
||||
return [](const Value& v){ return v.isSigned(); };
|
||||
}
|
||||
|
||||
Sp<crypto::PublicKey> owner;
|
||||
dht::InfoHash from;
|
||||
};
|
||||
|
||||
@@ -144,17 +147,18 @@ public:
|
||||
static const ValueType TYPE;
|
||||
|
||||
TrustRequest() {}
|
||||
TrustRequest(std::string s) : service(s) {}
|
||||
TrustRequest(std::string s, const Blob& d) : service(s), payload(d) {}
|
||||
TrustRequest(std::string s, std::string ci = {}) : service(s), conversationId(ci) {}
|
||||
TrustRequest(std::string s, std::string ci, const Blob& d) : service(s), conversationId(ci), payload(d) {}
|
||||
|
||||
static Value::Filter getFilter() {
|
||||
return EncryptedValue::getFilter();
|
||||
}
|
||||
|
||||
std::string service;
|
||||
std::string conversationId;
|
||||
Blob payload;
|
||||
bool confirm {false};
|
||||
MSGPACK_DEFINE_MAP(service, payload, confirm)
|
||||
MSGPACK_DEFINE_MAP(service, conversationId, payload, confirm)
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC IceCandidates : public EncryptedValue<IceCandidates>
|
||||
|
||||
+18
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -61,9 +61,6 @@ struct LocalListener;
|
||||
*/
|
||||
class OPENDHT_PUBLIC Dht final : public DhtInterface {
|
||||
public:
|
||||
|
||||
Dht();
|
||||
|
||||
/**
|
||||
* Initialise the Dht with two open sockets (for IPv4 and IP6)
|
||||
* and an ID for the node.
|
||||
@@ -98,7 +95,7 @@ public:
|
||||
/**
|
||||
* Performs final operations before quitting.
|
||||
*/
|
||||
void shutdown(ShutdownCallback cb) override;
|
||||
void shutdown(ShutdownCallback cb, bool stop = false) override;
|
||||
|
||||
/**
|
||||
* Returns true if the node is running (have access to an open socket).
|
||||
@@ -117,7 +114,7 @@ public:
|
||||
|
||||
void addBootstrap(const std::string& host, const std::string& service) override {
|
||||
bootstrap_nodes.emplace_back(host, service);
|
||||
onDisconnected();
|
||||
startBootstrap();
|
||||
}
|
||||
|
||||
void clearBootstrap() override {
|
||||
@@ -359,6 +356,8 @@ private:
|
||||
|
||||
static constexpr duration REANNOUNCE_MARGIN {std::chrono::seconds(10)};
|
||||
|
||||
static constexpr std::chrono::seconds BOOTSTRAP_PERIOD {10};
|
||||
|
||||
static constexpr size_t TOKEN_SIZE {32};
|
||||
|
||||
// internal structures
|
||||
@@ -371,6 +370,8 @@ private:
|
||||
Dht(const Dht&) = delete;
|
||||
Dht& operator=(const Dht&) = delete;
|
||||
|
||||
std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
|
||||
|
||||
InfoHash myid {};
|
||||
|
||||
uint64_t secret {};
|
||||
@@ -394,7 +395,7 @@ private:
|
||||
Kad dht6 {};
|
||||
|
||||
std::vector<std::pair<std::string,std::string>> bootstrap_nodes {};
|
||||
std::chrono::steady_clock::duration bootstrap_period {std::chrono::seconds(10)};
|
||||
std::chrono::steady_clock::duration bootstrap_period {BOOTSTRAP_PERIOD};
|
||||
Sp<Scheduler::Job> bootstrapJob {};
|
||||
|
||||
std::map<InfoHash, Storage> store;
|
||||
@@ -412,7 +413,6 @@ private:
|
||||
std::map<size_t, std::tuple<size_t, size_t, size_t>> listeners {};
|
||||
size_t listener_token {1};
|
||||
|
||||
std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
|
||||
|
||||
// timing
|
||||
Scheduler scheduler;
|
||||
@@ -445,7 +445,7 @@ private:
|
||||
void reportedAddr(const SockAddr&);
|
||||
|
||||
// Storage
|
||||
void storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t tid, Query&& = {});
|
||||
void storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t tid, Query&& = {}, int version = 0);
|
||||
bool storageStore(const InfoHash& id, const Sp<Value>& value, time_point created, const SockAddr& sa = {}, bool permanent = false);
|
||||
bool storageErase(const InfoHash& id, Value::Id vid);
|
||||
bool storageRefresh(const InfoHash& id, Value::Id vid);
|
||||
@@ -482,6 +482,9 @@ private:
|
||||
void sendCachedPing(Bucket& b);
|
||||
bool bucketMaintenance(RoutingTable&);
|
||||
void dumpBucket(const Bucket& b, std::ostream& out) const;
|
||||
void bootstrap();
|
||||
void startBootstrap();
|
||||
void stopBootstrap();
|
||||
|
||||
// Nodes
|
||||
void onNewNode(const Sp<Node>& node, int confirm);
|
||||
@@ -489,7 +492,6 @@ private:
|
||||
bool trySearchInsert(const Sp<Node>& node);
|
||||
|
||||
// Searches
|
||||
|
||||
inline SearchMap& searches(sa_family_t af) { return dht(af).searches; }
|
||||
inline const SearchMap& searches(sa_family_t af) const { return dht(af).searches; }
|
||||
|
||||
@@ -514,6 +516,8 @@ private:
|
||||
|
||||
void confirmNodes();
|
||||
void expire();
|
||||
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
|
||||
/**
|
||||
@@ -569,7 +573,8 @@ private:
|
||||
*
|
||||
* @param sr The search to execute its operations.
|
||||
*/
|
||||
void searchStep(Sp<Search>);
|
||||
void searchStep(std::weak_ptr<Search> ws);
|
||||
|
||||
void searchSynchedNodeListen(const Sp<Search>&, SearchNode&);
|
||||
|
||||
void dumpSearch(const Search& sr, std::ostream& out) const;
|
||||
@@ -600,7 +605,8 @@ private:
|
||||
const InfoHash& hash,
|
||||
const Blob& token,
|
||||
size_t socket_id,
|
||||
const Query& query);
|
||||
const Query& query,
|
||||
int version = 0);
|
||||
void onListenDone(const Sp<Node>& status,
|
||||
net::RequestAnswer& a,
|
||||
Sp<Search>& sr);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "infohash.h"
|
||||
#include "log_enable.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
namespace dht {
|
||||
|
||||
namespace net {
|
||||
@@ -46,6 +48,10 @@ public:
|
||||
virtual NodeStatus getStatus(sa_family_t af) const = 0;
|
||||
virtual NodeStatus getStatus() const = 0;
|
||||
|
||||
void addOnConnectedCallback(std::function<void()> cb) {
|
||||
onConnectCallbacks_.emplace(std::move(cb));
|
||||
}
|
||||
|
||||
virtual net::DatagramSocket* getSocket() const { return {}; };
|
||||
|
||||
/**
|
||||
@@ -55,8 +61,10 @@ public:
|
||||
|
||||
/**
|
||||
* Performs final operations before quitting.
|
||||
* stop: if true, cancel ongoing operations and call their 'done'
|
||||
* callbacks synchronously.
|
||||
*/
|
||||
virtual void shutdown(ShutdownCallback cb) = 0;
|
||||
virtual void shutdown(ShutdownCallback cb, bool stop = false) = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the node is running (have access to an open socket).
|
||||
@@ -264,6 +272,7 @@ public:
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Logger> logger_ {};
|
||||
std::queue<std::function<void()>> onConnectCallbacks_ {};
|
||||
};
|
||||
|
||||
} // namespace dht
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
/**
|
||||
* Performs final operations before quitting.
|
||||
*/
|
||||
void shutdown(ShutdownCallback cb) override;
|
||||
void shutdown(ShutdownCallback cb, bool) override;
|
||||
|
||||
/**
|
||||
* Returns true if the node is running (have access to an open socket).
|
||||
@@ -107,13 +107,13 @@ public:
|
||||
*/
|
||||
virtual void get(const InfoHash& key, GetCallback cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {}) override;
|
||||
virtual void get(const InfoHash& key, GetCallback cb, DoneCallbackSimple donecb={}, Value::Filter&& f={}, Where&& w = {}) override {
|
||||
get(key, cb, bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
get(key, cb, bindDoneCb(std::move(donecb)), std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
}
|
||||
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {}) override {
|
||||
get(key, bindGetCb(cb), donecb, std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
get(key, bindGetCb(cb), std::move(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
}
|
||||
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallbackSimple donecb, Value::Filter&& f={}, Where&& w = {}) override {
|
||||
get(key, bindGetCb(cb), bindDoneCb(donecb), std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
get(key, bindGetCb(cb), bindDoneCb(std::move(donecb)), std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, v, bindDoneCb(cb), created, permanent);
|
||||
put(key, v, bindDoneCb(std::move(cb)), created, permanent);
|
||||
}
|
||||
|
||||
void put(const InfoHash& key,
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, std::make_shared<Value>(std::move(v)), cb, created, permanent);
|
||||
put(key, std::make_shared<Value>(std::move(v)), std::move(cb), created, permanent);
|
||||
}
|
||||
void put(const InfoHash& key,
|
||||
Value&& v,
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, std::forward<Value>(v), bindDoneCb(cb), created, permanent);
|
||||
put(key, std::forward<Value>(v), bindDoneCb(std::move(cb)), created, permanent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,14 +176,14 @@ public:
|
||||
virtual size_t listen(const InfoHash&, ValueCallback, Value::Filter={}, Where={}) override;
|
||||
|
||||
virtual size_t listen(const InfoHash& key, GetCallback cb, Value::Filter f={}, Where w={}) override {
|
||||
return listen(key, [cb](const std::vector<Sp<Value>>& vals, bool expired){
|
||||
return listen(key, [cb=std::move(cb)](const std::vector<Sp<Value>>& vals, bool expired){
|
||||
if (not expired)
|
||||
return cb(vals);
|
||||
return true;
|
||||
}, std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
}
|
||||
virtual size_t listen(const InfoHash& key, GetCallbackSimple cb, Value::Filter f={}, Where w={}) override {
|
||||
return listen(key, bindGetCb(cb), std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
return listen(key, bindGetCb(std::move(cb)), std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
}
|
||||
/*
|
||||
* This function relies on the cache implementation.
|
||||
@@ -214,7 +214,7 @@ public:
|
||||
*/
|
||||
virtual void query(const InfoHash& /*key*/, QueryCallback /*cb*/, DoneCallback /*done_cb*/ = {}, Query&& /*q*/ = {}) override { }
|
||||
virtual void query(const InfoHash& key, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query&& q = {}) override {
|
||||
query(key, cb, bindDoneCb(done_cb), std::forward<Query>(q));
|
||||
query(key, cb, bindDoneCb(std::move(done_cb)), std::forward<Query>(q));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,11 +264,10 @@ public:
|
||||
std::vector<unsigned> getNodeMessageStats(bool) override { return {}; }
|
||||
void setStorageLimit(size_t) override {}
|
||||
void connectivityChanged(sa_family_t) override {
|
||||
restartListeners();
|
||||
getProxyInfos();
|
||||
}
|
||||
void connectivityChanged() override {
|
||||
getProxyInfos();
|
||||
restartListeners();
|
||||
loopSignal_();
|
||||
}
|
||||
|
||||
@@ -338,6 +337,7 @@ private:
|
||||
NodeStats stats6_ {};
|
||||
SockAddr publicAddressV4_;
|
||||
SockAddr publicAddressV6_;
|
||||
std::atomic_bool launchConnectedCbs_ {false};
|
||||
|
||||
InfoHash myid {};
|
||||
|
||||
@@ -379,13 +379,13 @@ private:
|
||||
* Retrieve if we can connect to the proxy (update statusIpvX_)
|
||||
*/
|
||||
void handleProxyConfirm(const asio::error_code &ec);
|
||||
Sp<asio::steady_timer> nextProxyConfirmationTimer_;
|
||||
Sp<asio::steady_timer> listenerRestartTimer_;
|
||||
std::unique_ptr<asio::steady_timer> nextProxyConfirmationTimer_;
|
||||
std::unique_ptr<asio::steady_timer> listenerRestartTimer_;
|
||||
|
||||
/**
|
||||
* Relaunch LISTEN requests if the client disconnect/reconnect.
|
||||
*/
|
||||
void restartListeners();
|
||||
void restartListeners(const asio::error_code &ec);
|
||||
|
||||
/**
|
||||
* Refresh a listen via a token
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
@@ -36,6 +36,15 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace dht {
|
||||
enum class PushType {
|
||||
None = 0,
|
||||
Android,
|
||||
iOS
|
||||
};
|
||||
}
|
||||
MSGPACK_ADD_ENUM(dht::PushType)
|
||||
|
||||
namespace http {
|
||||
class Request;
|
||||
struct ListenerSession;
|
||||
@@ -52,6 +61,13 @@ class DhtRunner;
|
||||
using RestRouter = restinio::router::express_router_t<>;
|
||||
using RequestStatus = restinio::request_handling_status_t;
|
||||
|
||||
struct ProxyServerConfig {
|
||||
in_port_t port {8000};
|
||||
std::string pushServer {};
|
||||
std::string persistStatePath {};
|
||||
dht::crypto::Identity identity {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the REST API
|
||||
*/
|
||||
@@ -66,10 +82,9 @@ public:
|
||||
* @note if the server fails to start (if port is already used or reserved),
|
||||
* it will fails silently
|
||||
*/
|
||||
DhtProxyServer(
|
||||
dht::crypto::Identity identity,
|
||||
std::shared_ptr<DhtRunner> dht, in_port_t port = 8000, const std::string& pushServer = "",
|
||||
std::shared_ptr<dht::Logger> logger = {});
|
||||
DhtProxyServer(const std::shared_ptr<DhtRunner>& dht,
|
||||
const ProxyServerConfig& config = {},
|
||||
const std::shared_ptr<dht::Logger>& logger = {});
|
||||
|
||||
virtual ~DhtProxyServer();
|
||||
|
||||
@@ -83,8 +98,10 @@ public:
|
||||
struct ServerStats {
|
||||
/** Current number of listen operations */
|
||||
size_t listenCount {0};
|
||||
/** Current number of permanent put operations */
|
||||
/** Current number of permanent put operations (hash used) */
|
||||
size_t putCount {0};
|
||||
/** Current number of permanent put values */
|
||||
size_t totalPermanentPuts {0};
|
||||
/** Current number of push tokens with at least one listen operation */
|
||||
size_t pushListenersCount {0};
|
||||
/** Average requests per second */
|
||||
@@ -114,6 +131,7 @@ public:
|
||||
Json::Value result;
|
||||
result["listenCount"] = static_cast<Json::UInt64>(listenCount);
|
||||
result["putCount"] = static_cast<Json::UInt64>(putCount);
|
||||
result["totalPermanentPuts"] = static_cast<Json::UInt64>(totalPermanentPuts);
|
||||
result["pushListenersCount"] = static_cast<Json::UInt64>(pushListenersCount);
|
||||
result["requestRate"] = requestRate;
|
||||
if (nodeInfo)
|
||||
@@ -282,17 +300,17 @@ private:
|
||||
* @param key of the device
|
||||
* @param json, the content to send
|
||||
*/
|
||||
void sendPushNotification(const std::string& key, Json::Value&& json, bool isAndroid, bool highPriority);
|
||||
void sendPushNotification(const std::string& key, Json::Value&& json, PushType type, bool highPriority);
|
||||
|
||||
/**
|
||||
* Send push notification with an expire timeout.
|
||||
* @param ec
|
||||
* @param pushToken
|
||||
* @param json
|
||||
* @param isAndroid
|
||||
* @param type
|
||||
*/
|
||||
void handleNotifyPushListenExpire(const asio::error_code &ec, const std::string pushToken,
|
||||
std::function<Json::Value()> json, const bool isAndroid);
|
||||
std::function<Json::Value()> json, PushType type);
|
||||
|
||||
/**
|
||||
* Remove a push listener between a client and a hash
|
||||
@@ -309,6 +327,12 @@ private:
|
||||
void handlePrintStats(const asio::error_code &ec);
|
||||
void updateStats();
|
||||
|
||||
template <typename Os>
|
||||
void saveState(Os& stream);
|
||||
|
||||
template <typename Is>
|
||||
void loadState(Is& is, size_t size);
|
||||
|
||||
using clock = std::chrono::steady_clock;
|
||||
using time_point = clock::time_point;
|
||||
|
||||
@@ -316,6 +340,9 @@ private:
|
||||
std::shared_ptr<DhtRunner> dht_;
|
||||
Json::StreamWriterBuilder jsonBuilder_;
|
||||
Json::CharReaderBuilder jsonReaderBuilder_;
|
||||
std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
|
||||
|
||||
std::string persistPath_;
|
||||
|
||||
// http server
|
||||
std::thread serverThread_;
|
||||
@@ -344,6 +371,7 @@ private:
|
||||
struct PushSessionContext {
|
||||
std::mutex lock;
|
||||
std::string sessionId;
|
||||
PushSessionContext(const std::string& id) : sessionId(id) {}
|
||||
};
|
||||
struct PermanentPut {
|
||||
time_point expiration;
|
||||
@@ -353,9 +381,32 @@ private:
|
||||
std::unique_ptr<asio::steady_timer> expireTimer;
|
||||
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
|
||||
Sp<Value> value;
|
||||
PushType type;
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const
|
||||
{
|
||||
p.pack_map(2 + (sessionCtx ? 1 : 0) + (clientId.empty() ? 0 : 1) + (type == PushType::None ? 0 : 2));
|
||||
p.pack("value"); p.pack(value);
|
||||
p.pack("exp"); p.pack(to_time_t(expiration));
|
||||
if (not clientId.empty()) {
|
||||
p.pack("cid"); p.pack(clientId);
|
||||
}
|
||||
if (sessionCtx) {
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
p.pack("sid"); p.pack(sessionCtx->sessionId);
|
||||
}
|
||||
if (type != PushType::None) {
|
||||
p.pack("t"); p.pack(type);
|
||||
p.pack("token"); p.pack(pushToken);
|
||||
}
|
||||
}
|
||||
|
||||
void msgpack_unpack(const msgpack::object& o);
|
||||
};
|
||||
struct SearchPuts {
|
||||
std::map<dht::Value::Id, PermanentPut> puts;
|
||||
MSGPACK_DEFINE_ARRAY(puts)
|
||||
};
|
||||
std::mutex lockSearchPuts_;
|
||||
std::map<InfoHash, SearchPuts> puts_;
|
||||
@@ -367,16 +418,33 @@ private:
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
struct Listener {
|
||||
time_point expiration;
|
||||
std::string clientId;
|
||||
std::shared_ptr<PushSessionContext> sessionCtx;
|
||||
std::future<size_t> internalToken;
|
||||
std::unique_ptr<asio::steady_timer> expireTimer;
|
||||
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
|
||||
PushType type;
|
||||
|
||||
template <typename Packer>
|
||||
void msgpack_pack(Packer& p) const
|
||||
{
|
||||
p.pack_map(sessionCtx ? 4 : 3);
|
||||
p.pack("cid"); p.pack(clientId);
|
||||
p.pack("exp"); p.pack(to_time_t(expiration));
|
||||
if (sessionCtx) {
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
p.pack("sid"); p.pack(sessionCtx->sessionId);
|
||||
}
|
||||
p.pack("t"); p.pack(type);
|
||||
}
|
||||
|
||||
void msgpack_unpack(const msgpack::object& o);
|
||||
};
|
||||
struct PushListener {
|
||||
std::map<InfoHash, std::vector<Listener>> listeners;
|
||||
MSGPACK_DEFINE_ARRAY(listeners)
|
||||
};
|
||||
std::mutex lockPushListeners_;
|
||||
std::map<std::string, PushListener> pushListeners_;
|
||||
proxy::ListenToken tokenPushNotif_ {0};
|
||||
#endif //OPENDHT_PUSH_NOTIFICATIONS
|
||||
|
||||
+29
-25
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
bool peer_publish {false};
|
||||
std::shared_ptr<dht::crypto::Certificate> server_ca;
|
||||
dht::crypto::Identity client_identity;
|
||||
SockAddr bind4 {}, bind6 {};
|
||||
};
|
||||
|
||||
struct Context {
|
||||
@@ -73,6 +74,7 @@ public:
|
||||
std::shared_ptr<PeerDiscovery> peerDiscovery {};
|
||||
StatusCallback statusChangedCallback {};
|
||||
CertificateStoreQuery certificateStore {};
|
||||
IdentityAnnouncedCb identityAnnouncedCb {};
|
||||
Context() {}
|
||||
};
|
||||
|
||||
@@ -97,7 +99,7 @@ public:
|
||||
template <class T>
|
||||
void get(InfoHash hash, std::function<bool(std::vector<T>&&)> cb, DoneCallbackSimple dcb={})
|
||||
{
|
||||
get(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
get(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
return cb(unpackVector<T>(vals));
|
||||
},
|
||||
dcb,
|
||||
@@ -106,7 +108,7 @@ public:
|
||||
template <class T>
|
||||
void get(InfoHash hash, std::function<bool(T&&)> cb, DoneCallbackSimple dcb={})
|
||||
{
|
||||
get(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
get(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
for (const auto& v : vals) {
|
||||
try {
|
||||
if (not cb(Value::unpack<T>(*v)))
|
||||
@@ -155,7 +157,7 @@ public:
|
||||
std::future<size_t> listen(InfoHash key, ValueCallback vcb, Value::Filter f = {}, Where w = {});
|
||||
|
||||
std::future<size_t> listen(InfoHash key, GetCallback cb, Value::Filter f={}, Where w={}) {
|
||||
return listen(key, [cb](const std::vector<Sp<Value>>& vals, bool expired){
|
||||
return listen(key, [cb=std::move(cb)](const std::vector<Sp<Value>>& vals, bool expired){
|
||||
if (not expired)
|
||||
return cb(vals);
|
||||
return true;
|
||||
@@ -169,7 +171,7 @@ public:
|
||||
template <class T>
|
||||
std::future<size_t> listen(InfoHash hash, std::function<bool(std::vector<T>&&)> cb)
|
||||
{
|
||||
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
return cb(unpackVector<T>(vals));
|
||||
},
|
||||
getFilterSet<T>());
|
||||
@@ -177,7 +179,7 @@ public:
|
||||
template <class T>
|
||||
std::future<size_t> listen(InfoHash hash, std::function<bool(std::vector<T>&&, bool)> cb)
|
||||
{
|
||||
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
|
||||
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
|
||||
return cb(unpackVector<T>(vals), expired);
|
||||
},
|
||||
getFilterSet<T>());
|
||||
@@ -186,7 +188,7 @@ public:
|
||||
template <typename T>
|
||||
std::future<size_t> listen(InfoHash hash, std::function<bool(T&&)> cb, Value::Filter f = {}, Where w = {})
|
||||
{
|
||||
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals) {
|
||||
for (const auto& v : vals) {
|
||||
try {
|
||||
if (not cb(Value::unpack<T>(*v)))
|
||||
@@ -202,7 +204,7 @@ public:
|
||||
template <typename T>
|
||||
std::future<size_t> listen(InfoHash hash, std::function<bool(T&&, bool)> cb, Value::Filter f = {}, Where w = {})
|
||||
{
|
||||
return listen(hash, [=](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
|
||||
return listen(hash, [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& vals, bool expired) {
|
||||
for (const auto& v : vals) {
|
||||
try {
|
||||
if (not cb(Value::unpack<T>(*v), expired))
|
||||
@@ -255,12 +257,23 @@ public:
|
||||
}
|
||||
void putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb={}, bool permanent = false);
|
||||
|
||||
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
|
||||
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
|
||||
}
|
||||
|
||||
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb={}, bool permanent = false);
|
||||
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert known nodes to the routing table, without necessarly ping them.
|
||||
* Usefull to restart a node and get things running fast without putting load on the network.
|
||||
*/
|
||||
void bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple&& cb={});
|
||||
void bootstrap(const SockAddr& addr, DoneCallbackSimple&& cb={});
|
||||
void bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple cb={});
|
||||
void bootstrap(const SockAddr& addr, DoneCallbackSimple cb={});
|
||||
|
||||
/**
|
||||
* Insert known nodes to the routing table, without necessarly ping them.
|
||||
@@ -301,6 +314,7 @@ public:
|
||||
* Get the public key fingerprint if an identity is used with this node, 0 otherwise.
|
||||
*/
|
||||
InfoHash getId() const;
|
||||
std::shared_ptr<crypto::PublicKey> getPublicKey() const;
|
||||
|
||||
/**
|
||||
* Get the ID of the DHT node.
|
||||
@@ -359,6 +373,7 @@ public:
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t af = AF_UNSPEC);
|
||||
std::vector<std::string> getPublicAddressStr(sa_family_t af = AF_UNSPEC);
|
||||
void getPublicAddress(std::function<void(std::vector<SockAddr>&&)>, sa_family_t af = AF_UNSPEC);
|
||||
|
||||
// securedht methods
|
||||
|
||||
@@ -379,22 +394,12 @@ public:
|
||||
config.threaded = threaded;
|
||||
run(port, config);
|
||||
}
|
||||
void run(in_port_t port, const Config& config, Context&& context = {});
|
||||
|
||||
/**
|
||||
* @param local4: Local IPv4 address and port to bind. Can be null.
|
||||
* @param local6: Local IPv6 address and port to bind. Can be null.
|
||||
* You should allways bind to a global IPv6 address.
|
||||
* @param identity: RSA key pair to use for cryptographic operations.
|
||||
* @param threaded: If false, loop() must be called periodically. Otherwise a thread is launched.
|
||||
* @param cb: Optional callback to receive general state information.
|
||||
*/
|
||||
void run(const SockAddr& local4, const SockAddr& local6, const Config& config, Context&& context = {});
|
||||
void run(in_port_t port, Config& config, Context&& context = {});
|
||||
|
||||
/**
|
||||
* Same as @run(sockaddr_in, sockaddr_in6, Identity, bool, StatusCallback), but with string IP addresses and service (port).
|
||||
*/
|
||||
void run(const char* ip4, const char* ip6, const char* service, const Config& config, Context&& context = {});
|
||||
void run(const char* ip4, const char* ip6, const char* service, Config& config, Context&& context = {});
|
||||
|
||||
void run(const Config& config, Context&& context);
|
||||
|
||||
@@ -415,7 +420,7 @@ public:
|
||||
/**
|
||||
* Gracefuly disconnect from network.
|
||||
*/
|
||||
void shutdown(ShutdownCallback cb = {});
|
||||
void shutdown(ShutdownCallback cb = {}, bool stop = false);
|
||||
|
||||
/**
|
||||
* Quit and wait for all threads to terminate.
|
||||
@@ -451,8 +456,6 @@ public:
|
||||
void forwardAllMessages(bool forward);
|
||||
|
||||
private:
|
||||
static constexpr std::chrono::seconds BOOTSTRAP_PERIOD {10};
|
||||
|
||||
enum class State {
|
||||
Idle,
|
||||
Running,
|
||||
@@ -481,6 +484,7 @@ private:
|
||||
|
||||
/** Current configuration */
|
||||
Config config_;
|
||||
IdentityAnnouncedCb identityAnnouncedCb_;
|
||||
|
||||
/**
|
||||
* reset dht clients
|
||||
|
||||
+19
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -72,15 +72,17 @@ using socket_t = asio::ip::tcp::socket;
|
||||
class OPENDHT_PUBLIC Url
|
||||
{
|
||||
public:
|
||||
Url(){};
|
||||
Url() = default;
|
||||
Url(const std::string& url);
|
||||
std::string url;
|
||||
std::string protocol {"http"};
|
||||
std::string host;
|
||||
std::string service {"80"};
|
||||
std::string target {"/"};
|
||||
std::string service;
|
||||
std::string target;
|
||||
std::string query;
|
||||
std::string fragment;
|
||||
|
||||
std::string toString() const;
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC Connection : public std::enable_shared_from_this<Connection>
|
||||
@@ -94,8 +96,9 @@ public:
|
||||
inline unsigned int id() const { return id_; };
|
||||
bool is_open() const;
|
||||
bool is_ssl() const;
|
||||
void checkOcsp(bool check = true) { checkOcsp_ = check; }
|
||||
|
||||
void set_ssl_verification(const asio::ip::tcp::endpoint& endpoint, const asio::ssl::verify_mode verify_mode);
|
||||
void set_ssl_verification(const std::string& hostname, const asio::ssl::verify_mode verify_mode);
|
||||
|
||||
asio::streambuf& input();
|
||||
std::istream& data() { return istream_; }
|
||||
@@ -141,6 +144,7 @@ private:
|
||||
|
||||
std::unique_ptr<asio::steady_timer> timeout_timer_;
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
bool checkOcsp_ {false};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -226,12 +230,15 @@ public:
|
||||
using OnStatusCb = std::function<void(unsigned status_code)>;
|
||||
using OnDataCb = std::function<void(const char* at, size_t length)>;
|
||||
using OnStateChangeCb = std::function<void(State state, const Response& response)>;
|
||||
using OnJsonCb = std::function<void(Json::Value value, unsigned status_code)>;
|
||||
using OnJsonCb = std::function<void(Json::Value value, const Response& response)>;
|
||||
using OnDoneCb = std::function<void(const Response& response)>;
|
||||
|
||||
// resolves implicitly
|
||||
Request(asio::io_context& ctx, const std::string& url, const Json::Value& json, OnJsonCb jsoncb,
|
||||
std::shared_ptr<dht::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, const std::string& url, OnJsonCb jsoncb,
|
||||
std::shared_ptr<dht::Logger> logger = {});
|
||||
|
||||
Request(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger = {});
|
||||
Request(asio::io_context& ctx, const std::string& host, const std::string& service,
|
||||
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
|
||||
@@ -285,10 +292,14 @@ public:
|
||||
|
||||
void send();
|
||||
|
||||
/** Send and block for response */
|
||||
const Response& await();
|
||||
|
||||
/**
|
||||
* User action to cancel the Request and call the completion callbacks.
|
||||
*/
|
||||
void cancel();
|
||||
void terminate(const asio::error_code& ec);
|
||||
|
||||
private:
|
||||
using OnCompleteCb = std::function<void()>;
|
||||
@@ -301,6 +312,8 @@ private:
|
||||
OnStateChangeCb on_state_change;
|
||||
};
|
||||
|
||||
static std::string getRelativePath(const Url& origin, const std::string& path);
|
||||
|
||||
void notify_state_change(State state);
|
||||
|
||||
void build();
|
||||
@@ -313,8 +326,6 @@ private:
|
||||
|
||||
void connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb = {});
|
||||
|
||||
void terminate(const asio::error_code& ec);
|
||||
|
||||
void post();
|
||||
|
||||
void handle_request(const asio::error_code& ec);
|
||||
@@ -364,15 +375,3 @@ private:
|
||||
} // namespace http
|
||||
} // namespace dht
|
||||
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
namespace restinio
|
||||
{
|
||||
/* Custom HTTP-methods for RESTinio > 0.5.0.
|
||||
* https://github.com/Stiffstream/restinio/issues/26
|
||||
*/
|
||||
constexpr const restinio::http_method_id_t method_listen {HTTP_LISTEN, "LISTEN"};
|
||||
constexpr const restinio::http_method_id_t method_stats {HTTP_STATS, "STATS"};
|
||||
constexpr const restinio::http_method_id_t method_sign {HTTP_SIGN, "SIGN"};
|
||||
constexpr const restinio::http_method_id_t method_encrypt {HTTP_ENCRYPT, "ENCRYPT"};
|
||||
} // namespace restinio
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Nicolas Reynaud <nicolas.reynaud@savoirfairelinux.com>
|
||||
@@ -335,7 +335,7 @@ public:
|
||||
void lookup(Key k, LookupCallback cb = {}, DoneCallbackSimple done_cb = {}, bool exact_match = true);
|
||||
void lookup(Key k, LookupCallbackSimple cb = {}, DoneCallbackSimple done_cb = {}, bool exact_match = true)
|
||||
{
|
||||
lookup(k, [=](std::vector<std::shared_ptr<Value>>& values, Prefix) { cb(values); }, done_cb, exact_match);
|
||||
lookup(k, [cb=std::move(cb)](std::vector<std::shared_ptr<Value>>& values, Prefix) { cb(values); }, done_cb, exact_match);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+63
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -40,10 +40,12 @@ typedef uint16_t in_port_t;
|
||||
#include <iomanip>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
|
||||
namespace dht {
|
||||
|
||||
@@ -54,9 +56,9 @@ namespace crypto {
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an InfoHash.
|
||||
* An InfoHash is a byte array of HASH_LEN bytes.
|
||||
* InfoHashes identify nodes and values in the Dht.
|
||||
* Represents an Hash,
|
||||
* a byte array of N bytes.
|
||||
* Hashes identify nodes and values in the Dht.
|
||||
*/
|
||||
template <size_t N>
|
||||
class OPENDHT_PUBLIC Hash {
|
||||
@@ -65,10 +67,10 @@ public:
|
||||
typedef typename T::iterator iterator;
|
||||
typedef typename T::const_iterator const_iterator;
|
||||
|
||||
Hash () noexcept {
|
||||
Hash() noexcept {
|
||||
data_.fill(0);
|
||||
}
|
||||
Hash (const uint8_t* h, size_t data_len) {
|
||||
Hash(const uint8_t* h, size_t data_len) {
|
||||
if (data_len < N)
|
||||
data_.fill(0);
|
||||
else
|
||||
@@ -79,7 +81,12 @@ public:
|
||||
* hex must be at least 2.HASH_LEN characters long.
|
||||
* If too long, only the first 2.HASH_LEN characters are read.
|
||||
*/
|
||||
explicit Hash(const std::string& hex);
|
||||
explicit Hash(std::string_view hex) {
|
||||
if (hex.size() < 2*N)
|
||||
data_.fill(0);
|
||||
else
|
||||
fromString(hex.data());
|
||||
}
|
||||
|
||||
Hash(const msgpack::object& o) {
|
||||
msgpack_unpack(o);
|
||||
@@ -93,6 +100,8 @@ public:
|
||||
iterator end() { return data_.end(); }
|
||||
const_iterator cend() const { return data_.cend(); }
|
||||
|
||||
static constexpr inline Hash zero() noexcept { return Hash{}; }
|
||||
|
||||
bool operator==(const Hash& h) const {
|
||||
auto a = reinterpret_cast<const uint32_t*>(data_.data());
|
||||
auto b = reinterpret_cast<const uint32_t*>(h.data_.data());
|
||||
@@ -112,6 +121,14 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
Hash operator^(const Hash& o) const {
|
||||
Hash result;
|
||||
for(auto i = 0u; i < N; i++) {
|
||||
result[i] = data_[i] ^ o.data_[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
auto a = reinterpret_cast<const uint32_t*>(data_.data());
|
||||
auto b = reinterpret_cast<const uint32_t*>(data_.data() + N);
|
||||
@@ -142,10 +159,6 @@ public:
|
||||
return 8 * i + j;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget about the ``XOR-metric''. An id is just a path from the
|
||||
* root of the tree, so bits are numbered from the start.
|
||||
*/
|
||||
static inline int cmp(const Hash& id1, const Hash& id2) {
|
||||
return std::memcmp(id1.data_.data(), id2.data_.data(), N);
|
||||
}
|
||||
@@ -179,16 +192,12 @@ public:
|
||||
int
|
||||
xorCmp(const Hash& id1, const Hash& id2) const
|
||||
{
|
||||
for(unsigned i = 0; i < N; i++) {
|
||||
uint8_t xor1, xor2;
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
if(id1.data_[i] == id2.data_[i])
|
||||
continue;
|
||||
xor1 = id1.data_[i] ^ data_[i];
|
||||
xor2 = id2.data_[i] ^ data_[i];
|
||||
if(xor1 < xor2)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
uint8_t xor1 = id1.data_[i] ^ data_[i];
|
||||
uint8_t xor2 = id2.data_[i] ^ data_[i];
|
||||
return (xor1 < xor2) ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -217,7 +226,7 @@ public:
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline Hash get(const std::string& data) {
|
||||
static inline Hash get(std::string_view data) {
|
||||
return get((const uint8_t*)data.data(), data.size());
|
||||
}
|
||||
|
||||
@@ -237,6 +246,9 @@ public:
|
||||
|
||||
static Hash getRandom();
|
||||
|
||||
template <typename Rd>
|
||||
static Hash getRandom(Rd&);
|
||||
|
||||
template <size_t M>
|
||||
OPENDHT_PUBLIC friend std::ostream& operator<< (std::ostream& s, const Hash<M>& h);
|
||||
|
||||
@@ -286,14 +298,6 @@ std::istream& operator>> (std::istream& s, Hash<N>& h)
|
||||
return s;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
Hash<N>::Hash(const std::string& hex) {
|
||||
if (hex.size() < 2*N)
|
||||
data_.fill(0);
|
||||
else
|
||||
fromString(hex.c_str());
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void
|
||||
Hash<N>::fromString(const char* in) {
|
||||
@@ -324,7 +328,20 @@ Hash<N>::getRandom()
|
||||
return h;
|
||||
}
|
||||
|
||||
struct HexMap : public std::array<std::array<char, 2>, 256> {
|
||||
template <size_t N>
|
||||
template <typename Rd>
|
||||
Hash<N>
|
||||
Hash<N>::getRandom(Rd& rdev)
|
||||
{
|
||||
Hash h;
|
||||
std::uniform_int_distribution<uint32_t> rand_int;
|
||||
auto a = reinterpret_cast<uint32_t*>(h.data());
|
||||
auto b = reinterpret_cast<uint32_t*>(h.data() + h.size());
|
||||
std::generate(a, b, std::bind(rand_int, std::ref(rdev)));
|
||||
return h;
|
||||
}
|
||||
|
||||
struct alignas(std::max_align_t) HexMap : public std::array<std::array<char, 2>, 256> {
|
||||
HexMap() {
|
||||
for (size_t i=0; i<size(); i++) {
|
||||
auto& e = (*this)[i];
|
||||
@@ -338,11 +355,27 @@ private:
|
||||
|
||||
OPENDHT_PUBLIC extern const HexMap hex_map;
|
||||
|
||||
inline std::string
|
||||
toHex(const uint8_t* data, size_t size) {
|
||||
std::string ret(size * 2, '\0');
|
||||
for (size_t i=0; i<size; i++) {
|
||||
auto b = ret.data()+i*2;
|
||||
const auto& m = hex_map[data[i]];
|
||||
*((uint16_t*)b) = *((uint16_t*)&m);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
toHex(const std::vector<uint8_t>& data) {
|
||||
return toHex(data.data(), data.size());
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
const char*
|
||||
Hash<N>::to_c_str() const
|
||||
{
|
||||
thread_local std::array<char, N*2+1> buf;
|
||||
alignas(std::max_align_t) thread_local std::array<char, N*2+1> buf;
|
||||
for (size_t i=0; i<N; i++) {
|
||||
auto b = buf.data()+i*2;
|
||||
const auto& m = hex_map[data_[i]];
|
||||
@@ -358,8 +391,6 @@ Hash<N>::toString() const
|
||||
return std::string(to_c_str(), N*2);
|
||||
}
|
||||
|
||||
const InfoHash zeroes {};
|
||||
|
||||
struct OPENDHT_PUBLIC NodeExport {
|
||||
InfoHash id;
|
||||
sockaddr_storage ss;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -82,13 +82,13 @@ private:
|
||||
};
|
||||
|
||||
struct Logger {
|
||||
LogMethod DBG = {};
|
||||
LogMethod WARN = {};
|
||||
LogMethod ERR = {};
|
||||
LogMethod WARN = {};
|
||||
LogMethod DBG = {};
|
||||
|
||||
Logger() = default;
|
||||
Logger(LogMethod&& err, LogMethod&& warn, LogMethod&& dbg)
|
||||
: DBG(std::move(dbg)), WARN(std::move(warn)), ERR(std::move(err)) {}
|
||||
: ERR(std::move(err)), WARN(std::move(warn)), DBG(std::move(dbg)) {}
|
||||
void setFilter(const InfoHash& f) {
|
||||
filter_ = f;
|
||||
filterEnable_ = static_cast<bool>(filter_);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -180,7 +180,8 @@ private:
|
||||
const InfoHash&,
|
||||
const Blob&,
|
||||
Tid,
|
||||
const Query&)> onListen {};
|
||||
const Query&,
|
||||
int)> onListen {};
|
||||
/**
|
||||
* Called on announce request.
|
||||
*
|
||||
@@ -210,9 +211,9 @@ private:
|
||||
|
||||
public:
|
||||
using RequestCb = std::function<void(const Request&, RequestAnswer&&)>;
|
||||
using RequestErrorCb = std::function<bool(const Request&, DhtProtocolException&&)>;
|
||||
using RequestExpiredCb = std::function<void(const Request&, bool)>;
|
||||
|
||||
NetworkEngine(const Sp<Logger>& log, std::mt19937_64& rd, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock);
|
||||
NetworkEngine(
|
||||
InfoHash& myid,
|
||||
NetworkConfig config,
|
||||
@@ -237,9 +238,10 @@ public:
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Sends values (with closest nodes) to a listenner.
|
||||
* Sends values (with closest nodes) to a listener.
|
||||
*
|
||||
* @param sa The address of the listenner.
|
||||
* @deprecated
|
||||
* @param sa The address of the listener.
|
||||
* @param sslen The length of the sockaddr structure.
|
||||
* @param socket_id The tid to use to write to the request socket.
|
||||
* @param hash The hash key of the value.
|
||||
@@ -248,13 +250,14 @@ public:
|
||||
* @param nodes The ipv4 closest nodes.
|
||||
* @param nodes6 The ipv6 closest nodes.
|
||||
* @param values The values to send.
|
||||
* @param version If version = 1, a request will be used to answer to the listener
|
||||
*/
|
||||
void tellListener(Sp<Node> n, Tid socket_id, const InfoHash& hash, want_t want, const Blob& ntoken,
|
||||
std::vector<Sp<Node>>&& nodes, std::vector<Sp<Node>>&& nodes6,
|
||||
std::vector<Sp<Value>>&& values, const Query& q);
|
||||
std::vector<Sp<Value>>&& values, const Query& q, int version);
|
||||
|
||||
void tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values);
|
||||
void tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values);
|
||||
void tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
|
||||
void tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values, int version);
|
||||
|
||||
bool isRunning(sa_family_t af) const;
|
||||
inline want_t want () const { return dht_socket->hasIPv4() and dht_socket->hasIPv6() ? (WANT4 | WANT6) : -1; }
|
||||
@@ -289,7 +292,7 @@ public:
|
||||
*/
|
||||
Sp<Request>
|
||||
sendPing(SockAddr&& sa, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
|
||||
return sendPing(std::make_shared<Node>(zeroes, std::move(sa), rd),
|
||||
return sendPing(std::make_shared<Node>(InfoHash::zero(), std::move(sa), rd),
|
||||
std::forward<RequestCb>(on_done),
|
||||
std::forward<RequestExpiredCb>(on_expired));
|
||||
}
|
||||
@@ -358,10 +361,9 @@ public:
|
||||
const InfoHash& hash,
|
||||
const Query& query,
|
||||
const Blob& token,
|
||||
Sp<Request> previous,
|
||||
Tid socketId,
|
||||
RequestCb&& on_done,
|
||||
RequestExpiredCb&& on_expired,
|
||||
SocketCb&& socket_cb);
|
||||
RequestExpiredCb&& on_expired);
|
||||
/**
|
||||
* Send a "announce" request to a given node.
|
||||
*
|
||||
@@ -400,7 +402,26 @@ public:
|
||||
const Value::Id& vid,
|
||||
const Blob& token,
|
||||
RequestCb&& on_done,
|
||||
RequestErrorCb&& on_error,
|
||||
RequestExpiredCb&& on_expired);
|
||||
/**
|
||||
* Send a "update" request to a given node. Used for Listen operations
|
||||
*
|
||||
* @param n The node.
|
||||
* @param hash The target hash.
|
||||
* @param values The values.
|
||||
* @param created Time id.
|
||||
* @param token A security token.
|
||||
* @param sid The socket id.
|
||||
*
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request> sendUpdateValues(Sp<Node> n,
|
||||
const InfoHash& infohash,
|
||||
const std::vector<Sp<Value>>& values,
|
||||
time_point created,
|
||||
const Blob& token,
|
||||
const size_t& sid);
|
||||
|
||||
/**
|
||||
* Parses a message and calls appropriate callbacks.
|
||||
@@ -413,8 +434,8 @@ public:
|
||||
*/
|
||||
void processMessage(const uint8_t *buf, size_t buflen, SockAddr addr);
|
||||
|
||||
Sp<Node> insertNode(const InfoHash& myid, const SockAddr& addr) {
|
||||
auto n = cache.getNode(myid, addr, scheduler.time(), 0);
|
||||
Sp<Node> insertNode(const InfoHash& id, const SockAddr& addr) {
|
||||
auto n = cache.getNode(id, addr, scheduler.time(), 0);
|
||||
onNewNode(n, 0);
|
||||
return n;
|
||||
}
|
||||
@@ -490,19 +511,20 @@ private:
|
||||
void sendRequest(const Sp<Request>& request);
|
||||
|
||||
struct MessageStats {
|
||||
unsigned ping {0};
|
||||
unsigned find {0};
|
||||
unsigned get {0};
|
||||
unsigned put {0};
|
||||
unsigned listen {0};
|
||||
unsigned refresh {0};
|
||||
unsigned ping {0};
|
||||
unsigned find {0};
|
||||
unsigned get {0};
|
||||
unsigned put {0};
|
||||
unsigned listen {0};
|
||||
unsigned refresh {0};
|
||||
unsigned updateValue {0};
|
||||
};
|
||||
|
||||
|
||||
// basic wrapper for socket sendto function
|
||||
int send(const SockAddr& addr, const char *buf, size_t len, bool confirmed = false);
|
||||
|
||||
void sendValueParts(const TransId& tid, const std::vector<Blob>& svals, const SockAddr& addr);
|
||||
void sendValueParts(Tid tid, const std::vector<Blob>& svals, const SockAddr& addr);
|
||||
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<Sp<Value>>&);
|
||||
void maintainRxBuffer(Tid tid);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+15
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace dht {
|
||||
namespace crypto {
|
||||
@@ -111,11 +113,18 @@ using random_device = std::random_device;
|
||||
template<class T = std::mt19937, std::size_t N = T::state_size>
|
||||
auto getSeededRandomEngine () -> typename std::enable_if<!!N, T>::type {
|
||||
typename T::result_type random_data[N];
|
||||
random_device source;
|
||||
std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
|
||||
std::seed_seq seeds(std::begin(random_data), std::end(random_data));
|
||||
T seededEngine (seeds);
|
||||
return seededEngine;
|
||||
for (unsigned i=0; i<256; i++) {
|
||||
try {
|
||||
random_device source;
|
||||
std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
|
||||
std::seed_seq seeds(std::begin(random_data), std::end(random_data));
|
||||
T seededEngine (seeds);
|
||||
return seededEngine;
|
||||
} catch (...) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Can't seed random engine");
|
||||
}
|
||||
|
||||
}} // dht::crypto
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
|
||||
+20
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -36,8 +36,9 @@ namespace dht {
|
||||
class Scheduler {
|
||||
public:
|
||||
struct Job {
|
||||
Job(std::function<void()>&& f) : do_(std::move(f)) {}
|
||||
Job(std::function<void()>&& f, time_point t) : do_(std::move(f)), t_(t) {}
|
||||
std::function<void()> do_;
|
||||
const time_point t_;
|
||||
void cancel() { do_ = {}; }
|
||||
};
|
||||
|
||||
@@ -50,17 +51,12 @@ public:
|
||||
* @return pointer to the newly scheduled job.
|
||||
*/
|
||||
Sp<Scheduler::Job> add(time_point t, std::function<void()>&& job_func) {
|
||||
auto job = std::make_shared<Job>(std::move(job_func));
|
||||
auto job = std::make_shared<Job>(std::move(job_func), t);
|
||||
if (t != time_point::max())
|
||||
timers.emplace(std::move(t), job);
|
||||
return job;
|
||||
}
|
||||
|
||||
void add(const Sp<Scheduler::Job>& job, time_point t) {
|
||||
if (t != time_point::max())
|
||||
timers.emplace(std::move(t), job);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reschedules a job.
|
||||
*
|
||||
@@ -68,16 +64,29 @@ public:
|
||||
* @param t The time at which the job shall be rescheduled.
|
||||
*/
|
||||
void edit(Sp<Scheduler::Job>& job, time_point t) {
|
||||
if (not job) {
|
||||
if (not job)
|
||||
return;
|
||||
}
|
||||
// std::function move doesn't garantee to leave the object empty.
|
||||
// Force clearing old value.
|
||||
auto task = std::move(job->do_);
|
||||
job->do_ = {};
|
||||
cancel(job);
|
||||
job = add(t, std::move(task));
|
||||
}
|
||||
|
||||
bool cancel(Sp<Scheduler::Job>& job) {
|
||||
if (job) {
|
||||
job->cancel();
|
||||
for (auto r = timers.equal_range(job->t_); r.first != r.second; ++r.first) {
|
||||
if (r.first->second == job) {
|
||||
timers.erase(r.first);
|
||||
job.reset();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the jobs to do up to now.
|
||||
*
|
||||
|
||||
+16
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
* Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
@@ -45,15 +45,13 @@ public:
|
||||
return c;
|
||||
}
|
||||
|
||||
SecureDht() {}
|
||||
|
||||
/**
|
||||
* s, s6: bound socket descriptors for IPv4 and IPv6, respectively.
|
||||
* For the Dht to be initialised, at least one of them must be >= 0.
|
||||
* id: the identity to use for the crypto layer and to compute
|
||||
* our own hash on the Dht.
|
||||
*/
|
||||
SecureDht(std::unique_ptr<DhtInterface> dht, Config config);
|
||||
SecureDht(std::unique_ptr<DhtInterface> dht, Config config, IdentityAnnouncedCb iacb = {}, const std::shared_ptr<Logger>& l = {});
|
||||
|
||||
virtual ~SecureDht();
|
||||
|
||||
@@ -63,6 +61,9 @@ public:
|
||||
PkId getLongId() const {
|
||||
return key_ ? key_->getPublicKey().getLongId() : PkId();
|
||||
}
|
||||
Sp<crypto::PublicKey> getPublicKey() const {
|
||||
return key_ ? key_->getSharedPublicKey() : Sp<crypto::PublicKey>{};
|
||||
}
|
||||
|
||||
ValueType secureType(ValueType&& type);
|
||||
|
||||
@@ -117,6 +118,10 @@ public:
|
||||
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
|
||||
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
|
||||
}
|
||||
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
|
||||
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Value&& v, DoneCallback callback, bool permanent = false) {
|
||||
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take ownership of the value and sign it using our private key.
|
||||
@@ -128,13 +133,13 @@ public:
|
||||
Value decrypt(const Value& v);
|
||||
|
||||
void findCertificate(const InfoHash& node, const std::function<void(const Sp<crypto::Certificate>)>& cb);
|
||||
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<const crypto::PublicKey>)>& cb);
|
||||
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<crypto::PublicKey>)>& cb);
|
||||
|
||||
const Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
|
||||
Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
|
||||
void registerCertificate(Sp<crypto::Certificate>& cert);
|
||||
|
||||
const Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
|
||||
const Sp<const crypto::PublicKey> getPublicKey(const InfoHash& node) const;
|
||||
Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
|
||||
Sp<crypto::PublicKey> getPublicKey(const InfoHash& node) const;
|
||||
|
||||
/**
|
||||
* Allows to set a custom callback called by the library to find a locally-stored certificate.
|
||||
@@ -148,8 +153,8 @@ public:
|
||||
/**
|
||||
* SecureDht to Dht proxy
|
||||
*/
|
||||
void shutdown(ShutdownCallback cb) override {
|
||||
dht_->shutdown(cb);
|
||||
void shutdown(ShutdownCallback cb, bool stop = false) override {
|
||||
dht_->shutdown(cb, stop);
|
||||
}
|
||||
void dumpTables() const override {
|
||||
dht_->dumpTables();
|
||||
@@ -356,7 +361,7 @@ private:
|
||||
|
||||
// our certificate cache
|
||||
std::map<InfoHash, Sp<crypto::Certificate>> nodesCertificates_ {};
|
||||
std::map<InfoHash, Sp<const crypto::PublicKey>> nodesPubKeys_ {};
|
||||
std::map<InfoHash, Sp<crypto::PublicKey>> nodesPubKeys_ {};
|
||||
|
||||
std::atomic_bool forward_all_ {false};
|
||||
bool enableCache_ {false};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
* Build from existing address.
|
||||
*/
|
||||
SockAddr(const sockaddr* sa, socklen_t length) {
|
||||
if (length > sizeof(sockaddr_storage))
|
||||
if (length > static_cast<socklen_t>(sizeof(sockaddr_storage)))
|
||||
throw std::runtime_error("Socket address length is too large");
|
||||
set(sa, length);
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public:
|
||||
if (len) addr.reset((sockaddr*)::calloc(len, 1));
|
||||
else addr.reset();
|
||||
}
|
||||
if (len > sizeof(sa_family_t))
|
||||
if (len)
|
||||
addr->sa_family = af;
|
||||
}
|
||||
|
||||
@@ -223,16 +223,16 @@ public:
|
||||
*/
|
||||
sockaddr* get() { return addr.get(); }
|
||||
|
||||
const sockaddr_in& getIPv4() const {
|
||||
inline const sockaddr_in& getIPv4() const {
|
||||
return *reinterpret_cast<const sockaddr_in*>(get());
|
||||
}
|
||||
const sockaddr_in6& getIPv6() const {
|
||||
inline const sockaddr_in6& getIPv6() const {
|
||||
return *reinterpret_cast<const sockaddr_in6*>(get());
|
||||
}
|
||||
sockaddr_in& getIPv4() {
|
||||
inline sockaddr_in& getIPv4() {
|
||||
return *reinterpret_cast<sockaddr_in*>(get());
|
||||
}
|
||||
sockaddr_in6& getIPv6() {
|
||||
inline sockaddr_in6& getIPv6() {
|
||||
return *reinterpret_cast<sockaddr_in6*>(get());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <future>
|
||||
#include <functional>
|
||||
|
||||
#include <ciso646> // fix windows compiler bug
|
||||
|
||||
namespace dht {
|
||||
|
||||
class OPENDHT_PUBLIC ThreadPool {
|
||||
@@ -63,15 +65,14 @@ public:
|
||||
void join();
|
||||
|
||||
private:
|
||||
struct ThreadState;
|
||||
std::queue<std::function<void()>> tasks_ {};
|
||||
std::vector<std::unique_ptr<ThreadState>> threads_;
|
||||
unsigned readyThreads_ {0};
|
||||
std::mutex lock_ {};
|
||||
std::condition_variable cv_ {};
|
||||
std::queue<std::function<void()>> tasks_ {};
|
||||
std::vector<std::unique_ptr<std::thread>> threads_;
|
||||
unsigned readyThreads_ {0};
|
||||
bool running_ {true};
|
||||
|
||||
const unsigned maxThreads_;
|
||||
bool running_ {true};
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC Executor : public std::enable_shared_from_this<Executor> {
|
||||
@@ -93,4 +94,71 @@ private:
|
||||
void schedule();
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC ExecutionContext {
|
||||
public:
|
||||
ExecutionContext(ThreadPool& pool)
|
||||
: threadPool_(pool), state_(std::make_shared<SharedState>())
|
||||
{}
|
||||
|
||||
~ExecutionContext() {
|
||||
state_->destroy();
|
||||
}
|
||||
|
||||
/** Wait for ongoing tasks to complete execution and drop other pending tasks */
|
||||
void stop() {
|
||||
state_->destroy(false);
|
||||
}
|
||||
|
||||
void run(std::function<void()>&& task) {
|
||||
std::lock_guard<std::mutex> lock(state_->mtx);
|
||||
if (state_->shutdown_) return;
|
||||
state_->pendingTasks++;
|
||||
threadPool_.get().run([task = std::move(task), state = state_] {
|
||||
state->run(task);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
struct SharedState {
|
||||
std::mutex mtx {};
|
||||
std::condition_variable cv {};
|
||||
unsigned pendingTasks {0};
|
||||
unsigned ongoingTasks {0};
|
||||
/** When true, prevents new tasks to be scheduled */
|
||||
bool shutdown_ {false};
|
||||
/** When true, prevents scheduled tasks to be executed */
|
||||
std::atomic_bool destroyed {false};
|
||||
|
||||
void destroy(bool wait = true) {
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
if (destroyed) return;
|
||||
if (wait) {
|
||||
cv.wait(lock, [this] { return pendingTasks == 0 && ongoingTasks == 0; });
|
||||
}
|
||||
shutdown_ = true;
|
||||
if (not wait) {
|
||||
cv.wait(lock, [this] { return ongoingTasks == 0; });
|
||||
}
|
||||
destroyed = true;
|
||||
}
|
||||
|
||||
void run(const std::function<void()>& task) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
pendingTasks--;
|
||||
ongoingTasks++;
|
||||
}
|
||||
if (destroyed) return;
|
||||
task();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
ongoingTasks--;
|
||||
cv.notify_all();
|
||||
}
|
||||
}
|
||||
};
|
||||
std::reference_wrapper<ThreadPool> threadPool_;
|
||||
std::shared_ptr<SharedState> state_;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -173,7 +173,13 @@ unpackMsg(Blob b) {
|
||||
|
||||
msgpack::unpacked unpackMsg(Blob b);
|
||||
|
||||
msgpack::object* findMapValue(const msgpack::object& map, const char* key);
|
||||
msgpack::object* findMapValue(const msgpack::object& map, const std::string& key);
|
||||
msgpack::object* findMapValue(const msgpack::object& map, const char* key, size_t length);
|
||||
|
||||
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) {
|
||||
return findMapValue(map, key.data(), key.size());
|
||||
}
|
||||
|
||||
} // namespace dht
|
||||
+24
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <msgpack.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <sstream>
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
@@ -42,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");
|
||||
@@ -117,7 +119,7 @@ struct OPENDHT_PUBLIC ValueType {
|
||||
|
||||
Id id {0};
|
||||
std::string name {};
|
||||
duration expiration {60 * 10};
|
||||
duration expiration {std::chrono::minutes(10)};
|
||||
StorePolicy storePolicy {DEFAULT_STORE_POLICY};
|
||||
EditPolicy editPolicy {DEFAULT_EDIT_POLICY};
|
||||
};
|
||||
@@ -205,7 +207,7 @@ struct OPENDHT_PUBLIC Value
|
||||
}
|
||||
static Filter chainOr(Filter&& f1, Filter&& f2) {
|
||||
if (not f1 or not f2) return {};
|
||||
return [f1,f2](const Value& v) {
|
||||
return [f1=std::move(f1),f2=std::move(f2)](const Value& v) {
|
||||
return f1(v) or f2(v);
|
||||
};
|
||||
}
|
||||
@@ -231,8 +233,7 @@ struct OPENDHT_PUBLIC Value
|
||||
}
|
||||
|
||||
static Filter TypeFilter(const ValueType& t) {
|
||||
const auto tid = t.id;
|
||||
return [tid](const Value& v) {
|
||||
return [tid = t.id](const Value& v) {
|
||||
return v.type == tid;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -357,7 +358,7 @@ struct OPENDHT_PUBLIC Value
|
||||
void sign(const crypto::PrivateKey& key) {
|
||||
if (isEncrypted())
|
||||
throw DhtException("Can't sign encrypted data.");
|
||||
owner = std::make_shared<const crypto::PublicKey>(key.getPublicKey());
|
||||
owner = key.getSharedPublicKey();
|
||||
signature = key.sign(getToSign());
|
||||
}
|
||||
|
||||
@@ -369,8 +370,8 @@ struct OPENDHT_PUBLIC Value
|
||||
return isSigned() and owner->checkSignature(getToSign(), signature);
|
||||
}
|
||||
|
||||
std::shared_ptr<const crypto::PublicKey> getOwner() const {
|
||||
return std::static_pointer_cast<const crypto::PublicKey>(owner);
|
||||
std::shared_ptr<crypto::PublicKey> getOwner() const {
|
||||
return std::static_pointer_cast<crypto::PublicKey>(owner);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -595,7 +596,7 @@ struct OPENDHT_PUBLIC Value
|
||||
/**
|
||||
* Public key of the signer.
|
||||
*/
|
||||
std::shared_ptr<const crypto::PublicKey> owner {};
|
||||
std::shared_ptr<crypto::PublicKey> owner {};
|
||||
|
||||
/**
|
||||
* Hash of the recipient (optional).
|
||||
@@ -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
|
||||
@@ -742,7 +743,7 @@ private:
|
||||
struct OPENDHT_PUBLIC Select
|
||||
{
|
||||
Select() { }
|
||||
Select(const std::string& q_str);
|
||||
Select(std::string_view q_str);
|
||||
|
||||
bool isSatisfiedBy(const Select& os) const;
|
||||
|
||||
@@ -797,7 +798,7 @@ private:
|
||||
struct OPENDHT_PUBLIC Where
|
||||
{
|
||||
Where() { }
|
||||
Where(const std::string& q_str);
|
||||
Where(std::string_view q_str);
|
||||
|
||||
bool isSatisfiedBy(const Where& where) const;
|
||||
|
||||
@@ -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));
|
||||
@@ -937,11 +938,11 @@ struct OPENDHT_PUBLIC Query
|
||||
* - $string$: a simple string WITHOUT SPACES.
|
||||
* - $integer$: a simple integer.
|
||||
*/
|
||||
Query(std::string q_str) {
|
||||
Query(std::string_view q_str) {
|
||||
auto pos_W = q_str.find("WHERE");
|
||||
auto pos_w = q_str.find("where");
|
||||
auto pos = std::min(pos_W != std::string::npos ? pos_W : q_str.size(),
|
||||
pos_w != std::string::npos ? pos_w : q_str.size());
|
||||
auto pos = std::min(pos_W != std::string_view::npos ? pos_W : q_str.size(),
|
||||
pos_w != std::string_view::npos ? pos_w : q_str.size());
|
||||
select = q_str.substr(0, pos);
|
||||
where = q_str.substr(pos, q_str.size()-pos);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
]])
|
||||
+22
-10
@@ -1,11 +1,11 @@
|
||||
# distutils: language = c++
|
||||
# distutils: extra_compile_args = -std=c++14
|
||||
# distutils: extra_compile_args = -std=c++17
|
||||
# distutils: include_dirs = ../../include
|
||||
# distutils: library_dirs = ../../src
|
||||
# distutils: libraries = opendht gnutls
|
||||
# cython: language_level=3
|
||||
#
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Author(s): Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
@@ -36,6 +36,7 @@ from libcpp.memory cimport shared_ptr
|
||||
from cython.parallel import parallel, prange
|
||||
from cython.operator cimport dereference as deref, preincrement as inc, predecrement as dec
|
||||
from cpython cimport ref
|
||||
from datetime import timedelta
|
||||
|
||||
cimport opendht_cpp as cpp
|
||||
|
||||
@@ -235,8 +236,9 @@ cdef class Where(object):
|
||||
|
||||
cdef class Value(object):
|
||||
cdef shared_ptr[cpp.Value] _value
|
||||
def __init__(self, bytes val=b''):
|
||||
self._value.reset(new cpp.Value(val, len(val)))
|
||||
def __init__(self, bytes val=b'', cpp.uint16_t id=0):
|
||||
self._value.reset(new cpp.Value(id, val, len(val)))
|
||||
|
||||
def __str__(self):
|
||||
return self._value.get().toString().decode()
|
||||
property owner:
|
||||
@@ -270,6 +272,14 @@ cdef class Value(object):
|
||||
def __get__(self):
|
||||
return self._value.get().size()
|
||||
|
||||
cdef class ValueType(object):
|
||||
cdef cpp.ValueType * _value
|
||||
def __init__(self, cpp.uint16_t id, str name, expiration: timedelta):
|
||||
if not isinstance(expiration, timedelta):
|
||||
raise TypeError("expiration argument must be of type timedelta")
|
||||
cdef cpp.seconds duration = cpp.seconds(int(expiration.total_seconds()))
|
||||
self._value = new cpp.ValueType(id, name.encode(), duration)
|
||||
|
||||
cdef class NodeSetIter(object):
|
||||
cdef map[cpp.InfoHash, shared_ptr[cpp.Node]]* _nodes
|
||||
cdef map[cpp.InfoHash, shared_ptr[cpp.Node]].iterator _curIter
|
||||
@@ -319,11 +329,11 @@ cdef class PrivateKey(_WithID):
|
||||
cdef shared_ptr[cpp.PrivateKey] _key
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._key.get().getPublicKey().getId()
|
||||
h._infohash = self._key.get().getSharedPublicKey().get().getId()
|
||||
return h
|
||||
def getPublicKey(self):
|
||||
pk = PublicKey()
|
||||
pk._key = self._key.get().getPublicKey()
|
||||
pk._key = self._key.get().getSharedPublicKey()
|
||||
return pk
|
||||
def decrypt(self, bytes dat):
|
||||
cdef size_t d_len = len(dat)
|
||||
@@ -348,17 +358,17 @@ cdef class PrivateKey(_WithID):
|
||||
return k
|
||||
|
||||
cdef class PublicKey(_WithID):
|
||||
cdef cpp.PublicKey _key
|
||||
cdef cpp.shared_ptr[cpp.PublicKey] _key
|
||||
def getId(self):
|
||||
h = InfoHash()
|
||||
h._infohash = self._key.getId()
|
||||
h._infohash = self._key.get().getId()
|
||||
return h
|
||||
def encrypt(self, bytes dat):
|
||||
cdef size_t d_len = len(dat)
|
||||
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
|
||||
cdef cpp.Blob indat
|
||||
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
|
||||
cdef cpp.Blob encrypted = self._key.encrypt(indat)
|
||||
cdef cpp.Blob encrypted = self._key.get().encrypt(indat)
|
||||
cdef char* encrypted_c_str = <char *>encrypted.data()
|
||||
cdef Py_ssize_t length = encrypted.size()
|
||||
return encrypted_c_str[:length]
|
||||
@@ -430,7 +440,7 @@ cdef class Identity(object):
|
||||
property publickey:
|
||||
def __get__(self):
|
||||
k = PublicKey()
|
||||
k._key = self._id.first.get().getPublicKey()
|
||||
k._key = self._id.first.get().getSharedPublicKey()
|
||||
return k
|
||||
property certificate:
|
||||
def __get__(self):
|
||||
@@ -513,6 +523,8 @@ cdef class DhtRunner(_WithID):
|
||||
cb_obj = {'shutdown':shutdown_cb}
|
||||
ref.Py_INCREF(cb_obj)
|
||||
self.thisptr.get().shutdown(cpp.bindShutdownCb(shutdown_callback, <void*>cb_obj))
|
||||
def registerType(self, ValueType type):
|
||||
self.thisptr.get().registerType(deref(type._value))
|
||||
def enableLogging(self):
|
||||
cpp.enableLogging(self.thisptr.get()[0])
|
||||
def disableLogging(self):
|
||||
|
||||
+18
-4
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
@@ -26,6 +26,14 @@ from libc.string cimport const_char, const_uchar
|
||||
ctypedef uint16_t in_port_t
|
||||
ctypedef unsigned short int sa_family_t;
|
||||
|
||||
cdef extern from "<iostream>" namespace "std::chrono" nogil:
|
||||
cdef cppclass duration[ulong]:
|
||||
duration() except +
|
||||
|
||||
cdef cppclass seconds:
|
||||
duration seconds(uint64_t) except +
|
||||
duration seconds()
|
||||
|
||||
cdef extern from "<memory>" namespace "std" nogil:
|
||||
cdef cppclass shared_ptr[T]:
|
||||
shared_ptr() except +
|
||||
@@ -89,7 +97,7 @@ cdef extern from "opendht/crypto.h" namespace "dht::crypto":
|
||||
|
||||
cdef cppclass PrivateKey:
|
||||
PrivateKey()
|
||||
PublicKey getPublicKey() const
|
||||
shared_ptr[PublicKey] getSharedPublicKey() const
|
||||
Blob decrypt(Blob data) const
|
||||
@staticmethod
|
||||
PrivateKey generate()
|
||||
@@ -131,7 +139,6 @@ cdef extern from "opendht/value.h" namespace "dht::Value":
|
||||
cdef extern from "opendht/value.h" namespace "dht::Value::Field":
|
||||
cdef Field None
|
||||
cdef Field Id
|
||||
cdef Field ValueType
|
||||
cdef Field OwnerPk
|
||||
cdef Field SeqNum
|
||||
cdef Field UserType
|
||||
@@ -141,7 +148,7 @@ cdef extern from "opendht/value.h" namespace "dht":
|
||||
cdef cppclass Value:
|
||||
Value() except +
|
||||
Value(vector[uint8_t]) except +
|
||||
Value(const uint8_t* dat_ptr, size_t dat_len) except +
|
||||
Value(const uint16_t t, const uint8_t* dat_ptr, size_t dat_len) except +
|
||||
string toString() const
|
||||
size_t size() const
|
||||
uint64_t id
|
||||
@@ -150,6 +157,12 @@ cdef extern from "opendht/value.h" namespace "dht":
|
||||
vector[uint8_t] data
|
||||
string user_type
|
||||
|
||||
cdef cppclass ValueType:
|
||||
ValueType(uint16_t id, string name, seconds expiration) except +
|
||||
uint16_t id
|
||||
string name
|
||||
seconds expiration
|
||||
|
||||
cdef cppclass Query:
|
||||
Query() except +
|
||||
Query(Select s, Where w) except +
|
||||
@@ -234,6 +247,7 @@ cdef extern from "opendht/dhtrunner.h" namespace "dht":
|
||||
void run(const_char*, const_char*, const_char*, Config config)
|
||||
void join()
|
||||
void shutdown(ShutdownCallback)
|
||||
void registerType(ValueType& value);
|
||||
bool isRunning()
|
||||
SockAddr getBound(sa_family_t af) const
|
||||
string getStorageLog() const
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
@@ -50,8 +50,8 @@ setup(name="opendht",
|
||||
["@CURRENT_SOURCE_DIR@/opendht.pyx"],
|
||||
include_dirs = ['@PROJECT_SOURCE_DIR@/include'],
|
||||
language="c++",
|
||||
extra_compile_args=["-std=c++14"],
|
||||
extra_link_args=["-std=c++14"],
|
||||
extra_compile_args=["-std=c++17"],
|
||||
extra_link_args=["-std=c++17"],
|
||||
libraries=["opendht"],
|
||||
library_dirs = ['@CURRENT_BINARY_DIR@', '@PROJECT_BINARY_DIR@']
|
||||
))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015-2019 Savoir-Faire Linux Inc.
|
||||
# Copyright (C) 2015-2022 Savoir-Faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
# Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
# Author(s): Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2016-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2016-2022 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+12
-27
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2019 Savoir-faire Linux Inc.
|
||||
# Copyright (c) 2015-2022 Savoir-faire Linux Inc.
|
||||
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,6 +21,7 @@ from math import cos, sin, pi
|
||||
import urllib3
|
||||
import gzip
|
||||
import queue
|
||||
from geoip import geolite2
|
||||
|
||||
sys.path.append('..')
|
||||
from opendht import *
|
||||
@@ -55,7 +56,7 @@ plt.ion()
|
||||
plt.figaspect(2.)
|
||||
|
||||
fig, axes = plt.subplots(2, 1)
|
||||
fig.set_size_inches(8,16,forward=True)
|
||||
#fig.set_size_inches(8,16,forward=True)
|
||||
fig.tight_layout()
|
||||
fig.canvas.set_window_title('OpenDHT scanner')
|
||||
|
||||
@@ -90,27 +91,12 @@ def exitcb(arg):
|
||||
run = False
|
||||
exitbtn.on_clicked(exitcb)
|
||||
|
||||
def check_dl(fname, url):
|
||||
if os.path.isfile(fname):
|
||||
return
|
||||
print('downloading', url)
|
||||
ghandle = gzip.GzipFile(fileobj=http.request('GET', url, headers={'User-Agent': 'Mozilla/5.0'}, preload_content=False))
|
||||
with open(fname, 'wb') as out:
|
||||
for line in ghandle:
|
||||
out.write(line)
|
||||
|
||||
check_dl("GeoLiteCity.dat", "http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz")
|
||||
check_dl("GeoLiteCityv6.dat", "http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz")
|
||||
|
||||
gi = GeoIP.open("GeoLiteCity.dat", GeoIP.GEOIP_INDEX_CACHE | GeoIP.GEOIP_CHECK_CACHE)
|
||||
gi6 = GeoIP.open("GeoLiteCityv6.dat", GeoIP.GEOIP_INDEX_CACHE | GeoIP.GEOIP_CHECK_CACHE)
|
||||
|
||||
def gcb(v):
|
||||
return True
|
||||
|
||||
r = DhtRunner()
|
||||
r.run(port=4112)
|
||||
r.bootstrap("bootstrap.ring.cx", "4222")
|
||||
r.bootstrap("bootstrap.jami.net", "4222")
|
||||
|
||||
plt.pause(1)
|
||||
|
||||
@@ -143,9 +129,9 @@ def nextstep(cur_h, cur_depth, ok, nodes):
|
||||
depth = min(8, commonBits+6)
|
||||
if cur_depth < depth:
|
||||
for b in range(cur_depth, depth):
|
||||
new_h = InfoHash(cur_h.toString());
|
||||
new_h.setBit(b, 1);
|
||||
step(new_h, b+1);
|
||||
new_h = InfoHash(cur_h.toString())
|
||||
new_h.setBit(b, 1)
|
||||
step(new_h, b+1)
|
||||
else:
|
||||
print("step done with no nodes", ok, cur_h.toString().decode())
|
||||
done -= 1
|
||||
@@ -186,23 +172,22 @@ def appendNewNode(n):
|
||||
if addr in nodes_ip6s:
|
||||
nodes_ip6s[addr][1] += 1
|
||||
else:
|
||||
georecord = gi6.record_by_name_v6(addr)
|
||||
georecord = geolite2.lookup(addr)
|
||||
nodes_ip6s[addr] = [n, 1, georecord]
|
||||
else:
|
||||
if addr in nodes_ip4s:
|
||||
nodes_ip4s[addr][1] += 1
|
||||
else:
|
||||
georecord = gi.record_by_name(addr)
|
||||
georecord = geolite2.lookup(addr)
|
||||
nodes_ip4s[addr] = [n, 1, georecord]
|
||||
if georecord:
|
||||
appendMapPoint(georecord)
|
||||
|
||||
def appendMapPoint(res):
|
||||
global lons, lats, cities
|
||||
lons.append(res['longitude'])
|
||||
lats.append(res['latitude'])
|
||||
cities.append(res['city'] if res['city'] else (str(int(res['latitude']))+'-'+str(int(res['longitude']))))
|
||||
|
||||
lons.append(res.location[1])
|
||||
lats.append(res.location[0])
|
||||
cities.append(res.city if res.city else (str(int(res.location[0]))+'-'+str(int(res.location[1]))))
|
||||
|
||||
def restart(arg):
|
||||
global collection, all_lines, all_nodes, points, done, nodes_ip4s, nodes_ip6s, lats, lons, cities, xys, colors
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+3
-30
@@ -2,7 +2,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_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
|
||||
libopendht_la_LDFLAGS = @LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
|
||||
libopendht_la_SOURCES = \
|
||||
dht.cpp \
|
||||
storage.h \
|
||||
@@ -71,8 +71,8 @@ endif
|
||||
|
||||
libopendht_la_SOURCES += base64.h base64.cpp
|
||||
if PROXY_CLIENT_OR_SERVER
|
||||
libopendht_la_SOURCES += http.cpp
|
||||
nobase_include_HEADERS += ../include/opendht/proxy.h ../include/opendht/http.h
|
||||
libopendht_la_SOURCES += http.cpp compat/os_cert.cpp
|
||||
nobase_include_HEADERS += ../include/opendht/proxy.h ../include/opendht/http.h compat/os_cert.h
|
||||
endif
|
||||
|
||||
if ENABLE_PEER_DISCOVERY
|
||||
@@ -87,30 +87,3 @@ endif
|
||||
|
||||
clean-local:
|
||||
rm -rf libargon2.la
|
||||
|
||||
######################
|
||||
# ARGON2 submodule #
|
||||
######################
|
||||
|
||||
if WITH_INCLUDED_ARGON2
|
||||
noinst_LTLIBRARIES = libargon2.la
|
||||
libopendht_la_DEPENDENCIES = libargon2.la
|
||||
|
||||
libargon2_la_CFLAGS = -std=c89 -fPIC -pthread -O3 -Wall -I@top_builddir@/argon2/include -I@top_builddir@/argon2/src
|
||||
libargon2_la_SOURCES = \
|
||||
@top_builddir@/argon2/src/argon2.c \
|
||||
@top_builddir@/argon2/src/core.c \
|
||||
@top_builddir@/argon2/src/blake2/blake2b.c \
|
||||
@top_builddir@/argon2/src/thread.c \
|
||||
@top_builddir@/argon2/src/ref.c \
|
||||
@top_builddir@/argon2/src/encoding.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
@top_builddir@/argon2/include/argon2.h \
|
||||
@top_builddir@/argon2/src/blake2/blake2.h \
|
||||
@top_builddir@/argon2/src/blake2/blake2-impl.h \
|
||||
@top_builddir@/argon2/src/blake2/blamka-round-ref.h \
|
||||
@top_builddir@/argon2/src/core.h \
|
||||
@top_builddir@/argon2/src/encoding.h \
|
||||
@top_builddir@/argon2/src/thread.h
|
||||
endif
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -26,7 +26,7 @@ namespace dht {
|
||||
|
||||
|
||||
GetCallbackSimple
|
||||
bindGetCb(const GetCallbackRaw& raw_cb, void* user_data)
|
||||
bindGetCb(GetCallbackRaw raw_cb, void* user_data)
|
||||
{
|
||||
if (not raw_cb) return {};
|
||||
return [=](const std::shared_ptr<Value>& value) {
|
||||
@@ -35,10 +35,10 @@ bindGetCb(const GetCallbackRaw& raw_cb, void* user_data)
|
||||
}
|
||||
|
||||
GetCallback
|
||||
bindGetCb(const GetCallbackSimple& cb)
|
||||
bindGetCb(GetCallbackSimple cb)
|
||||
{
|
||||
if (not cb) return {};
|
||||
return [=](const std::vector<std::shared_ptr<Value>>& values) {
|
||||
return [cb=std::move(cb)](const std::vector<std::shared_ptr<Value>>& values) {
|
||||
for (const auto& v : values)
|
||||
if (not cb(v))
|
||||
return false;
|
||||
@@ -47,7 +47,7 @@ bindGetCb(const GetCallbackSimple& cb)
|
||||
}
|
||||
|
||||
ValueCallback
|
||||
bindValueCb(const ValueCallbackRaw& raw_cb, void* user_data)
|
||||
bindValueCb(ValueCallbackRaw raw_cb, void* user_data)
|
||||
{
|
||||
if (not raw_cb) return {};
|
||||
return [=](const std::vector<std::shared_ptr<Value>>& values, bool expired) {
|
||||
@@ -59,7 +59,7 @@ bindValueCb(const ValueCallbackRaw& raw_cb, void* user_data)
|
||||
}
|
||||
|
||||
ShutdownCallback
|
||||
bindShutdownCb(const ShutdownCallbackRaw& shutdown_cb_raw, void* user_data)
|
||||
bindShutdownCb(ShutdownCallbackRaw shutdown_cb_raw, void* user_data)
|
||||
{
|
||||
return [=]() { shutdown_cb_raw(user_data); };
|
||||
}
|
||||
@@ -69,11 +69,11 @@ bindDoneCb(DoneCallbackSimple donecb)
|
||||
{
|
||||
if (not donecb) return {};
|
||||
using namespace std::placeholders;
|
||||
return std::bind(donecb, _1);
|
||||
return std::bind(std::move(donecb), _1);
|
||||
}
|
||||
|
||||
DoneCallback
|
||||
bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data)
|
||||
bindDoneCb(DoneCallbackRaw raw_cb, void* user_data)
|
||||
{
|
||||
if (not raw_cb) return {};
|
||||
return [=](bool success, const std::vector<std::shared_ptr<Node>>& nodes) {
|
||||
@@ -82,7 +82,7 @@ bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data)
|
||||
}
|
||||
|
||||
DoneCallbackSimple
|
||||
bindDoneCbSimple(const DoneCallbackSimpleRaw& raw_cb, void* user_data) {
|
||||
bindDoneCbSimple(DoneCallbackSimpleRaw raw_cb, void* user_data) {
|
||||
if (not raw_cb) return {};
|
||||
return [=](bool success) {
|
||||
raw_cb(success, user_data);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os_cert.h"
|
||||
|
||||
#include "log_enable.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#pragma comment(lib, "crypt32.lib")
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifdef TARGET_OS_OSX
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Security/Security.h>
|
||||
#endif /*TARGET_OS_OSX*/
|
||||
|
||||
#if EMBEDDED_ASN1_TIME_PARSE
|
||||
#undef X509_NAME
|
||||
#undef OCSP_REQUEST
|
||||
#undef OCSP_RESPONSE
|
||||
#define GENTIME_LENGTH 15
|
||||
#define UTCTIME_LENGTH 13
|
||||
#define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0'))
|
||||
extern "C" {
|
||||
// Taken from libressl/src/crypto/asn1/a_time_tm.c
|
||||
int
|
||||
ASN1_time_parse(const char* bytes, size_t len, struct tm* tm, int mode)
|
||||
{
|
||||
size_t i;
|
||||
int type = 0;
|
||||
struct tm ltm;
|
||||
struct tm* lt;
|
||||
const char* p;
|
||||
|
||||
if (bytes == NULL)
|
||||
return (-1);
|
||||
|
||||
/* Constrain to valid lengths. */
|
||||
if (len != UTCTIME_LENGTH && len != GENTIME_LENGTH)
|
||||
return (-1);
|
||||
|
||||
lt = tm;
|
||||
if (lt == NULL) {
|
||||
memset(<m, 0, sizeof(ltm));
|
||||
lt = <m;
|
||||
}
|
||||
|
||||
/* Timezone is required and must be GMT (Zulu). */
|
||||
if (bytes[len - 1] != 'Z')
|
||||
return (-1);
|
||||
|
||||
/* Make sure everything else is digits. */
|
||||
for (i = 0; i < len - 1; i++) {
|
||||
if (isdigit((unsigned char) bytes[i]))
|
||||
continue;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate and convert the time
|
||||
*/
|
||||
p = bytes;
|
||||
switch (len) {
|
||||
case GENTIME_LENGTH:
|
||||
if (mode == V_ASN1_UTCTIME)
|
||||
return (-1);
|
||||
lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */
|
||||
type = V_ASN1_GENERALIZEDTIME;
|
||||
/* FALLTHROUGH */
|
||||
case UTCTIME_LENGTH:
|
||||
if (type == 0) {
|
||||
if (mode == V_ASN1_GENERALIZEDTIME)
|
||||
return (-1);
|
||||
type = V_ASN1_UTCTIME;
|
||||
}
|
||||
lt->tm_year += ATOI2(p); /* yy */
|
||||
if (type == V_ASN1_UTCTIME) {
|
||||
if (lt->tm_year < 50)
|
||||
lt->tm_year += 100;
|
||||
}
|
||||
lt->tm_mon = ATOI2(p) - 1; /* mm */
|
||||
if (lt->tm_mon < 0 || lt->tm_mon > 11)
|
||||
return (-1);
|
||||
lt->tm_mday = ATOI2(p); /* dd */
|
||||
if (lt->tm_mday < 1 || lt->tm_mday > 31)
|
||||
return (-1);
|
||||
lt->tm_hour = ATOI2(p); /* HH */
|
||||
if (lt->tm_hour < 0 || lt->tm_hour > 23)
|
||||
return (-1);
|
||||
lt->tm_min = ATOI2(p); /* MM */
|
||||
if (lt->tm_min < 0 || lt->tm_min > 59)
|
||||
return (-1);
|
||||
lt->tm_sec = ATOI2(p); /* SS */
|
||||
/* Leap second 60 is not accepted. Reconsider later? */
|
||||
if (lt->tm_sec < 0 || lt->tm_sec > 59)
|
||||
return (-1);
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
#endif /* EMBEDDED_ASN1_TIME_PARSE */
|
||||
|
||||
namespace dht {
|
||||
namespace http {
|
||||
|
||||
PEMCache::PEMCache(const std::shared_ptr<Logger>& l)
|
||||
: logger(l)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
PCCERT_CONTEXT pContext = NULL;
|
||||
HCERTSTORE hSystemStore;
|
||||
hSystemStore = CertOpenSystemStore(NULL, "ROOT");
|
||||
if (!hSystemStore) {
|
||||
if (logger)
|
||||
logger->e("couldn't open the system cert store");
|
||||
return;
|
||||
}
|
||||
while (pContext = CertEnumCertificatesInStore(hSystemStore, pContext)) {
|
||||
const uint8_t* encoded_cert = pContext->pbCertEncoded;
|
||||
X509Ptr x509cert(d2i_X509(nullptr, &encoded_cert, pContext->cbCertEncoded), &X509_free);
|
||||
if (x509cert)
|
||||
pems_.emplace_back(std::move(x509cert));
|
||||
}
|
||||
CertCloseStore(hSystemStore, 0);
|
||||
#elif TARGET_OS_OSX
|
||||
CFArrayRef result = NULL;
|
||||
OSStatus osStatus;
|
||||
|
||||
if ((osStatus = SecTrustCopyAnchorCertificates(&result)) != 0) {
|
||||
if (logger) {
|
||||
CFStringRef statusString = SecCopyErrorMessageString(osStatus, NULL);
|
||||
logger->d("Error enumerating certificates: %s",
|
||||
CFStringGetCStringPtr(statusString, kCFStringEncodingASCII));
|
||||
CFRelease(statusString);
|
||||
}
|
||||
if (result != NULL) {
|
||||
CFRelease(result);
|
||||
}
|
||||
return;
|
||||
}
|
||||
CFDataRef rawData = NULL;
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(result); i++) {
|
||||
SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(result, i);
|
||||
rawData = SecCertificateCopyData(cert);
|
||||
if (!rawData) {
|
||||
if (logger)
|
||||
logger->e("couldn't copy raw certificate data");
|
||||
break;
|
||||
}
|
||||
const uint8_t* rawDataPtr = CFDataGetBytePtr(rawData);
|
||||
X509Ptr x509cert(d2i_X509(nullptr, &rawDataPtr, CFDataGetLength(rawData)), &X509_free);
|
||||
if (x509cert)
|
||||
pems_.emplace_back(std::move(x509cert));
|
||||
CFRelease(rawData);
|
||||
rawData = NULL;
|
||||
}
|
||||
if (result != NULL) {
|
||||
CFRelease(result);
|
||||
}
|
||||
if (rawData != NULL) {
|
||||
CFRelease(rawData);
|
||||
}
|
||||
#endif /*TARGET_OS_OSX, _WIN32*/
|
||||
}
|
||||
|
||||
void
|
||||
PEMCache::fillX509Store(SSL_CTX* ctx)
|
||||
{
|
||||
if (logger)
|
||||
logger->d("adding %d decoded certs to X509 store", pems_.size());
|
||||
if (X509_STORE* store = SSL_CTX_get_cert_store(ctx)) {
|
||||
for (const auto& pem : pems_) {
|
||||
if (X509_STORE_add_cert(store, pem.get()) != 1)
|
||||
if (logger)
|
||||
logger->w("couldn't add local certificate");
|
||||
}
|
||||
} else if (logger)
|
||||
logger->e("couldn't get the context cert store");
|
||||
}
|
||||
|
||||
} /*namespace http*/
|
||||
} /*namespace dht*/
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "log_enable.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER > 0x20501000L))
|
||||
#define EMBEDDED_ASN1_TIME_PARSE 0
|
||||
#else
|
||||
#define EMBEDDED_ASN1_TIME_PARSE 1
|
||||
#endif
|
||||
|
||||
#if EMBEDDED_ASN1_TIME_PARSE
|
||||
#define V_ASN1_UTCTIME 23
|
||||
#define V_ASN1_GENERALIZEDTIME 24
|
||||
|
||||
extern "C" {
|
||||
/*
|
||||
* Parse an RFC 5280 format ASN.1 time string.
|
||||
*
|
||||
* mode must be:
|
||||
* 0 if we expect to parse a time as specified in RFC 5280 for an X509 object.
|
||||
* V_ASN1_UTCTIME if we wish to parse an RFC5280 format UTC time.
|
||||
* V_ASN1_GENERALIZEDTIME if we wish to parse an RFC5280 format Generalized time.
|
||||
*
|
||||
* Returns:
|
||||
* -1 if the string was invalid.
|
||||
* V_ASN1_UTCTIME if the string validated as a UTC time string.
|
||||
* V_ASN1_GENERALIZEDTIME if the string validated as a Generalized time string.
|
||||
*
|
||||
* Fills in *tm with the corresponding time if tm is non NULL.
|
||||
*/
|
||||
int ASN1_time_parse(const char* bytes, size_t len, struct tm* tm, int mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace dht {
|
||||
namespace http {
|
||||
|
||||
// A singleton class used to cache the decoded certificates
|
||||
// loaded from local cert stores that need to be added to the
|
||||
// ssl context prior to each request.
|
||||
class PEMCache
|
||||
{
|
||||
PEMCache(const std::shared_ptr<Logger>& l);
|
||||
|
||||
using X509Ptr = std::unique_ptr<X509, void(*)(X509*)>;
|
||||
std::vector<X509Ptr> pems_;
|
||||
std::shared_ptr<Logger> logger;
|
||||
|
||||
public:
|
||||
static PEMCache& instance(const std::shared_ptr<Logger>& l)
|
||||
{
|
||||
static PEMCache instance_(l);
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void fillX509Store(SSL_CTX* ctx);
|
||||
};
|
||||
}
|
||||
} // namespace dht
|
||||
+315
-61
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,6 +26,7 @@ extern "C" {
|
||||
#include <gnutls/x509.h>
|
||||
#include <nettle/gcm.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <gnutls/crypto.h>
|
||||
|
||||
#include <argon2.h>
|
||||
}
|
||||
@@ -52,7 +54,7 @@ static std::uniform_int_distribution<uint8_t> rand_byte;
|
||||
#define GNUTLS_PKCS_PBES2_AES_256 GNUTLS_PKCS_USE_PBES2_AES_256
|
||||
#endif
|
||||
|
||||
#define DHT_AES_LEGACY_ENCRYPT 1
|
||||
#define DHT_AES_LEGACY_ENCRYPT 0
|
||||
#define DHT_AES_LEGACY_DECRYPT 1
|
||||
|
||||
namespace dht {
|
||||
@@ -67,7 +69,7 @@ constexpr gnutls_digest_algorithm_t gnutlsHashAlgo(size_t min_res) {
|
||||
GNUTLS_DIG_SHA1));
|
||||
}
|
||||
|
||||
constexpr size_t gnutlsHashSize(int algo) {
|
||||
constexpr size_t gnutlsHashSize(gnutls_digest_algorithm_t algo) {
|
||||
return (algo == GNUTLS_DIG_SHA512) ? 512/8 : (
|
||||
(algo == GNUTLS_DIG_SHA256) ? 256/8 : (
|
||||
(algo == GNUTLS_DIG_SHA1) ? 160/8 : 0 ));
|
||||
@@ -126,37 +128,37 @@ Blob aesEncrypt(const Blob& data, const std::string& password)
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
Blob aesDecrypt(const Blob& data, const Blob& key)
|
||||
Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key)
|
||||
{
|
||||
if (not aesKeySizeGood(key.size()))
|
||||
throw DecryptError("Wrong key size");
|
||||
|
||||
if (data.size() <= GCM_IV_SIZE + GCM_DIGEST_SIZE)
|
||||
if (data_length <= GCM_IV_SIZE + GCM_DIGEST_SIZE)
|
||||
throw DecryptError("Wrong data size");
|
||||
|
||||
std::array<uint8_t, GCM_DIGEST_SIZE> digest;
|
||||
|
||||
struct gcm_aes_ctx aes;
|
||||
gcm_aes_set_key(&aes, key.size(), key.data());
|
||||
gcm_aes_set_iv(&aes, GCM_IV_SIZE, data.data());
|
||||
gcm_aes_set_iv(&aes, GCM_IV_SIZE, data);
|
||||
|
||||
size_t data_sz = data.size() - GCM_IV_SIZE - GCM_DIGEST_SIZE;
|
||||
size_t data_sz = data_length - GCM_IV_SIZE - GCM_DIGEST_SIZE;
|
||||
Blob ret(data_sz);
|
||||
gcm_aes_decrypt(&aes, data_sz, ret.data(), data.data() + GCM_IV_SIZE);
|
||||
gcm_aes_decrypt(&aes, data_sz, ret.data(), data + GCM_IV_SIZE);
|
||||
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, digest.data());
|
||||
|
||||
if (not std::equal(digest.begin(), digest.end(), data.end() - GCM_DIGEST_SIZE)) {
|
||||
if (not std::equal(digest.begin(), digest.end(), data + data_length - GCM_DIGEST_SIZE)) {
|
||||
#if DHT_AES_LEGACY_DECRYPT
|
||||
//gcm_aes_decrypt(&aes, data_sz, ret.data(), data.data() + GCM_IV_SIZE);
|
||||
//gcm_aes_decrypt(&aes, data_sz, ret.data(), data + GCM_IV_SIZE);
|
||||
Blob ret_tmp(data_sz);
|
||||
struct gcm_aes_ctx aes_d;
|
||||
gcm_aes_set_key(&aes_d, key.size(), key.data());
|
||||
gcm_aes_set_iv(&aes_d, GCM_IV_SIZE, data.data());
|
||||
gcm_aes_set_iv(&aes_d, GCM_IV_SIZE, data);
|
||||
gcm_aes_update(&aes_d, ret.size(), ret.data());
|
||||
gcm_aes_encrypt(&aes_d, ret.size(), ret_tmp.data(), ret.data());
|
||||
gcm_aes_digest(&aes_d, GCM_DIGEST_SIZE, digest.data());
|
||||
|
||||
if (not std::equal(digest.begin(), digest.end(), data.end() - GCM_DIGEST_SIZE))
|
||||
if (not std::equal(digest.begin(), digest.end(), data + data_length - GCM_DIGEST_SIZE))
|
||||
throw DecryptError("Can't decrypt data");
|
||||
#else
|
||||
throw DecryptError("Can't decrypt data");
|
||||
@@ -166,14 +168,13 @@ Blob aesDecrypt(const Blob& data, const Blob& key)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Blob aesDecrypt(const Blob& data, const std::string& password)
|
||||
Blob aesDecrypt(const uint8_t* data, size_t data_len, const std::string& password)
|
||||
{
|
||||
if (data.size() <= PASSWORD_SALT_LENGTH)
|
||||
if (data_len <= PASSWORD_SALT_LENGTH)
|
||||
throw DecryptError("Wrong data size");
|
||||
Blob salt {data.begin(), data.begin()+PASSWORD_SALT_LENGTH};
|
||||
Blob salt {data, data+PASSWORD_SALT_LENGTH};
|
||||
Blob key = stretchKey(password, salt, 256/8);
|
||||
Blob encrypted {data.begin()+PASSWORD_SALT_LENGTH, data.end()};
|
||||
return aesDecrypt(encrypted, key);
|
||||
return aesDecrypt(data+PASSWORD_SALT_LENGTH, data_len - PASSWORD_SALT_LENGTH, key);
|
||||
}
|
||||
|
||||
Blob stretchKey(const std::string& password, Blob& salt, size_t key_length)
|
||||
@@ -290,14 +291,14 @@ PrivateKey::operator=(PrivateKey&& o) noexcept
|
||||
}
|
||||
|
||||
Blob
|
||||
PrivateKey::sign(const Blob& data) const
|
||||
PrivateKey::sign(const uint8_t* data, size_t data_length) const
|
||||
{
|
||||
if (!key)
|
||||
throw CryptoException("Can't sign data: no private key set !");
|
||||
if (std::numeric_limits<unsigned>::max() < data.size())
|
||||
if (std::numeric_limits<unsigned>::max() < data_length)
|
||||
throw CryptoException("Can't sign data: too large !");
|
||||
gnutls_datum_t sig;
|
||||
const gnutls_datum_t dat {(unsigned char*)data.data(), (unsigned)data.size()};
|
||||
const gnutls_datum_t dat {(unsigned char*)data, (unsigned)data_length};
|
||||
if (gnutls_privkey_sign_data(key, GNUTLS_DIG_SHA512, 0, &dat, &sig) != GNUTLS_E_SUCCESS)
|
||||
throw CryptoException("Can't sign data !");
|
||||
Blob ret(sig.data, sig.data+sig.size);
|
||||
@@ -319,7 +320,7 @@ PrivateKey::decryptBloc(const uint8_t* src, size_t src_size) const
|
||||
}
|
||||
|
||||
Blob
|
||||
PrivateKey::decrypt(const Blob& cipher) const
|
||||
PrivateKey::decrypt(const uint8_t* cypher, size_t cypher_len) const
|
||||
{
|
||||
if (!key)
|
||||
throw CryptoException("Can't decrypt data without private key !");
|
||||
@@ -332,12 +333,12 @@ PrivateKey::decrypt(const Blob& cipher) const
|
||||
throw CryptoException("Must be an RSA key");
|
||||
|
||||
unsigned cypher_block_sz = key_len / 8;
|
||||
if (cipher.size() < cypher_block_sz)
|
||||
if (cypher_len < cypher_block_sz)
|
||||
throw DecryptError("Unexpected cipher length");
|
||||
else if (cipher.size() == cypher_block_sz)
|
||||
return decryptBloc(cipher.data(), cypher_block_sz);
|
||||
else if (cypher_len == cypher_block_sz)
|
||||
return decryptBloc(cypher, cypher_block_sz);
|
||||
|
||||
return aesDecrypt(Blob {cipher.begin() + cypher_block_sz, cipher.end()}, decryptBloc(cipher.data(), cypher_block_sz));
|
||||
return aesDecrypt(cypher + cypher_block_sz, cypher_len - cypher_block_sz, decryptBloc(cypher, cypher_block_sz));
|
||||
}
|
||||
|
||||
Blob
|
||||
@@ -367,13 +368,22 @@ PrivateKey::serialize(uint8_t* out, size_t* out_len, const std::string& password
|
||||
: gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, out, out_len);
|
||||
}
|
||||
|
||||
PublicKey
|
||||
const PublicKey&
|
||||
PrivateKey::getPublicKey() const
|
||||
{
|
||||
PublicKey pk;
|
||||
if (auto err = gnutls_pubkey_import_privkey(pk.pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))
|
||||
return *getSharedPublicKey();
|
||||
}
|
||||
|
||||
const std::shared_ptr<PublicKey>&
|
||||
PrivateKey::getSharedPublicKey() const
|
||||
{
|
||||
if (publicKey_)
|
||||
return publicKey_;
|
||||
auto pk = std::make_shared<PublicKey>();
|
||||
if (auto err = gnutls_pubkey_import_privkey(pk->pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))
|
||||
throw CryptoException(std::string("Can't retreive public key: ") + gnutls_strerror(err));
|
||||
return pk;
|
||||
publicKey_ = pk;
|
||||
return publicKey_;
|
||||
}
|
||||
|
||||
PublicKey::PublicKey()
|
||||
@@ -539,12 +549,7 @@ PublicKey::getId() const
|
||||
return {};
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030401
|
||||
const int flags = 0;
|
||||
#else
|
||||
const int flags = (id.size() == 32) ? GNUTLS_KEYID_USE_SHA256 : 0;
|
||||
#endif
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, flags, id.data(), &sz))
|
||||
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get public key ID: wrong output length.");
|
||||
@@ -709,13 +714,13 @@ CertificateRequest::sign(const PrivateKey& key, const std::string& password)
|
||||
}
|
||||
|
||||
bool
|
||||
CertificateRequest::verify() const
|
||||
CertificateRequest::verify() const
|
||||
{
|
||||
return gnutls_x509_crq_verify(request, 0) >= 0;
|
||||
}
|
||||
|
||||
Blob
|
||||
CertificateRequest::pack() const
|
||||
Blob
|
||||
CertificateRequest::pack() const
|
||||
{
|
||||
gnutls_datum_t dat {nullptr, 0};
|
||||
if (auto err = gnutls_x509_crq_export2(request, GNUTLS_X509_FMT_PEM, &dat))
|
||||
@@ -726,7 +731,7 @@ CertificateRequest::pack() const
|
||||
}
|
||||
|
||||
std::string
|
||||
CertificateRequest::toString() const
|
||||
CertificateRequest::toString() const
|
||||
{
|
||||
gnutls_datum_t dat {nullptr, 0};
|
||||
if (auto err = gnutls_x509_crq_export2(request, GNUTLS_X509_FMT_PEM, &dat))
|
||||
@@ -848,12 +853,15 @@ Certificate::getId() const
|
||||
{
|
||||
if (not cert)
|
||||
return {};
|
||||
if (cachedId_)
|
||||
return cachedId_;
|
||||
InfoHash id;
|
||||
size_t sz = id.size();
|
||||
if (auto err = gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz))
|
||||
throw CryptoException(std::string("Can't get certificate public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate public key ID: wrong output length.");
|
||||
cachedId_ = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -862,6 +870,8 @@ Certificate::getLongId() const
|
||||
{
|
||||
if (not cert)
|
||||
return {};
|
||||
if (cachedLongId_)
|
||||
return cachedLongId_;
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030401
|
||||
throw CryptoException("Can't get certificate 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
|
||||
#else
|
||||
@@ -871,10 +881,23 @@ Certificate::getLongId() const
|
||||
throw CryptoException(std::string("Can't get certificate 256 bits public key ID: ") + gnutls_strerror(err));
|
||||
if (sz != id.size())
|
||||
throw CryptoException("Can't get certificate 256 bits public key ID: wrong output length.");
|
||||
cachedLongId_ = id;
|
||||
return id;
|
||||
#endif
|
||||
}
|
||||
|
||||
Blob
|
||||
Certificate::getSerialNumber() const
|
||||
{
|
||||
if (not cert)
|
||||
return {};
|
||||
// extract from certificate
|
||||
unsigned char serial[64];
|
||||
auto size = sizeof(serial);
|
||||
gnutls_x509_crt_get_serial(cert, &serial, &size);
|
||||
return {serial, serial + size};
|
||||
}
|
||||
|
||||
std::string
|
||||
Certificate::getName() const
|
||||
{
|
||||
@@ -1020,6 +1043,34 @@ Certificate::getPreferredDigest() const
|
||||
return getPublicKey().getPreferredDigest();
|
||||
}
|
||||
|
||||
std::pair<std::string, Blob>
|
||||
Certificate::generateOcspRequest(gnutls_x509_crt_t& issuer)
|
||||
{
|
||||
gnutls_ocsp_req_t rreq;
|
||||
int err = gnutls_ocsp_req_init(&rreq);
|
||||
if (err < 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
std::unique_ptr<struct gnutls_ocsp_req_int, decltype(&gnutls_ocsp_req_deinit)> req(rreq, &gnutls_ocsp_req_deinit);
|
||||
err = gnutls_ocsp_req_add_cert(req.get(), GNUTLS_DIG_SHA1, issuer, cert);
|
||||
if (err < 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
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));
|
||||
gnutls_datum_t rdata;
|
||||
err = gnutls_ocsp_req_export(req.get(), &rdata);
|
||||
if (err != 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
std::string ret((char*)rdata.data, (char*)rdata.data + rdata.size);
|
||||
gnutls_free(rdata.data);
|
||||
return std::make_pair<std::string, Blob>(std::move(ret), std::move(noncebuf));
|
||||
}
|
||||
|
||||
// PrivateKey
|
||||
|
||||
PrivateKey
|
||||
@@ -1108,31 +1159,29 @@ void
|
||||
setRandomSerial(gnutls_x509_crt_t cert)
|
||||
{
|
||||
random_device rdev;
|
||||
std::uniform_int_distribution<uint64_t> dist{};
|
||||
uint64_t cert_serial = dist(rdev);
|
||||
std::uniform_int_distribution<int64_t> dist{1};
|
||||
int64_t cert_serial = dist(rdev);
|
||||
gnutls_x509_crt_set_serial(cert, &cert_serial, sizeof(cert_serial));
|
||||
}
|
||||
|
||||
Certificate
|
||||
Certificate::generate(const PrivateKey& key, const std::string& name, const Identity& ca, bool is_ca)
|
||||
Certificate::generate(const PrivateKey& key, const std::string& name, const Identity& ca, bool is_ca, int64_t validity)
|
||||
{
|
||||
gnutls_x509_crt_t cert;
|
||||
if (not key.x509_key or gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS)
|
||||
return {};
|
||||
Certificate ret {cert};
|
||||
|
||||
setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60);
|
||||
if (gnutls_x509_crt_set_key(cert, key.x509_key) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when setting certificate key" << std::endl;
|
||||
return {};
|
||||
setValidityPeriod(cert, validity <= 0 ? 10 * 365 * 24 * 60 * 60 : validity);
|
||||
if (int err = gnutls_x509_crt_set_key(cert, key.x509_key)) {
|
||||
throw CryptoException(std::string("Error when setting certificate key ") + gnutls_strerror(err));
|
||||
}
|
||||
if (gnutls_x509_crt_set_version(cert, 3) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when setting certificate version" << std::endl;
|
||||
return {};
|
||||
if (int err = gnutls_x509_crt_set_version(cert, 3)) {
|
||||
throw CryptoException(std::string("Error when setting certificate version ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
// TODO: compute the subject key using the recommended RFC method
|
||||
auto pk = key.getPublicKey();
|
||||
const auto& pk = key.getPublicKey();
|
||||
auto pk_id = pk.getId();
|
||||
const std::string uid_str = pk_id.toString();
|
||||
|
||||
@@ -1153,18 +1202,15 @@ Certificate::generate(const PrivateKey& key, const std::string& name, const Iden
|
||||
|
||||
if (ca.first && ca.second) {
|
||||
if (not ca.second->isCA()) {
|
||||
// Signing certificate must be CA.
|
||||
return {};
|
||||
throw CryptoException("Signing certificate must be CA");
|
||||
}
|
||||
if (gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, pk.getPreferredDigest(), 0) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when signing certificate" << std::endl;
|
||||
return {};
|
||||
if (int err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, pk.getPreferredDigest(), 0)) {
|
||||
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
|
||||
}
|
||||
ret.issuer = ca.second;
|
||||
} else {
|
||||
if (gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0) != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Error when signing certificate" << std::endl;
|
||||
return {};
|
||||
if (int err = gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0)) {
|
||||
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1172,7 +1218,7 @@ Certificate::generate(const PrivateKey& key, const std::string& name, const Iden
|
||||
}
|
||||
|
||||
Certificate
|
||||
Certificate::generate(const CertificateRequest& request, const Identity& ca)
|
||||
Certificate::generate(const CertificateRequest& request, const Identity& ca, int64_t validity)
|
||||
{
|
||||
gnutls_x509_crt_t cert;
|
||||
if (auto err = gnutls_x509_crt_init(&cert))
|
||||
@@ -1185,7 +1231,7 @@ Certificate::generate(const CertificateRequest& request, const Identity& ca)
|
||||
throw CryptoException(std::string("Can't set certificate version: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60);
|
||||
setValidityPeriod(cert, validity <= 0 ? 10 * 365 * 24 * 60 * 60 : validity);
|
||||
setRandomSerial(cert);
|
||||
|
||||
if (auto err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, ca.second->getPreferredDigest(), 0)) {
|
||||
@@ -1196,6 +1242,32 @@ Certificate::generate(const CertificateRequest& request, const Identity& ca)
|
||||
return ret.getPacked();
|
||||
}
|
||||
|
||||
void
|
||||
Certificate::setValidity(const Identity& ca, int64_t validity)
|
||||
{
|
||||
setValidityPeriod(cert, validity);
|
||||
setRandomSerial(cert);
|
||||
if (ca.first && ca.second) {
|
||||
if (not ca.second->isCA()) {
|
||||
throw CryptoException("Signing certificate must be CA");
|
||||
}
|
||||
if (int err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, ca.second->getPreferredDigest(), 0)) {
|
||||
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Certificate::setValidity(const PrivateKey& key, int64_t validity)
|
||||
{
|
||||
setValidityPeriod(cert, validity);
|
||||
setRandomSerial(cert);
|
||||
const auto& pk = key.getPublicKey();
|
||||
if (int err = gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0)) {
|
||||
throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<RevocationList>>
|
||||
Certificate::getRevocationLists() const
|
||||
{
|
||||
@@ -1206,6 +1278,188 @@ Certificate::getRevocationLists() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
// OcspRequest
|
||||
|
||||
OcspRequest::OcspRequest(const uint8_t* dat_ptr, size_t dat_size)
|
||||
{
|
||||
int ret = gnutls_ocsp_req_init(&request);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
gnutls_datum_t dat = {(unsigned char*)dat_ptr,(unsigned int)dat_size};
|
||||
ret = gnutls_ocsp_req_import(request, &dat);
|
||||
if (ret < 0){
|
||||
gnutls_ocsp_req_deinit(request);
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
}
|
||||
}
|
||||
|
||||
OcspRequest::~OcspRequest()
|
||||
{
|
||||
if (request) {
|
||||
gnutls_ocsp_req_deinit(request);
|
||||
request = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
OcspRequest::toString(const bool compact) const
|
||||
{
|
||||
int ret;
|
||||
gnutls_datum_t dat;
|
||||
ret = gnutls_ocsp_req_print(request, compact ? GNUTLS_OCSP_PRINT_COMPACT : GNUTLS_OCSP_PRINT_FULL, &dat);
|
||||
|
||||
std::string str;
|
||||
if (ret == 0) {
|
||||
str = std::string((const char*)dat.data, (size_t)dat.size);
|
||||
gnutls_free(dat.data);
|
||||
} else
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
return str;
|
||||
}
|
||||
|
||||
Blob
|
||||
OcspRequest::pack() const
|
||||
{
|
||||
gnutls_datum_t dat;
|
||||
int err = gnutls_ocsp_req_export(request, &dat);
|
||||
if (err < 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
Blob ret {dat.data, dat.data + dat.size};
|
||||
gnutls_free(dat.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Blob
|
||||
OcspRequest::getNonce() const
|
||||
{
|
||||
gnutls_datum_t dat;
|
||||
unsigned critical;
|
||||
int err = gnutls_ocsp_req_get_nonce(request, &critical, &dat);
|
||||
if (err < 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
Blob ret {dat.data, dat.data + dat.size};
|
||||
gnutls_free(dat.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// OcspResponse
|
||||
|
||||
OcspResponse::OcspResponse(const uint8_t* dat_ptr, size_t dat_size)
|
||||
{
|
||||
int ret = gnutls_ocsp_resp_init(&response);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
gnutls_datum_t dat = {(unsigned char*)dat_ptr,(unsigned int)dat_size};
|
||||
ret = gnutls_ocsp_resp_import(response, &dat);
|
||||
if (ret < 0){
|
||||
gnutls_ocsp_resp_deinit(response);
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
}
|
||||
}
|
||||
|
||||
OcspResponse::~OcspResponse()
|
||||
{
|
||||
gnutls_ocsp_resp_deinit(response);
|
||||
}
|
||||
|
||||
Blob
|
||||
OcspResponse::pack() const
|
||||
{
|
||||
gnutls_datum_t dat;
|
||||
int err = gnutls_ocsp_resp_export(response, &dat);
|
||||
if (err < 0)
|
||||
throw CryptoException(gnutls_strerror(err));
|
||||
Blob ret {dat.data, dat.data + dat.size};
|
||||
gnutls_free(dat.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string
|
||||
OcspResponse::toString(const bool compact) const
|
||||
{
|
||||
int ret;
|
||||
std::string str;
|
||||
gnutls_datum_t dat;
|
||||
ret = gnutls_ocsp_resp_print(response, compact ? GNUTLS_OCSP_PRINT_COMPACT : GNUTLS_OCSP_PRINT_FULL, &dat);
|
||||
if (ret == 0)
|
||||
str = std::string((const char*)dat.data, (size_t)dat.size);
|
||||
gnutls_free(dat.data);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
gnutls_ocsp_cert_status_t
|
||||
OcspResponse::getCertificateStatus() const
|
||||
{
|
||||
int ret;
|
||||
unsigned int status;
|
||||
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status, NULL, NULL, NULL, NULL);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
return (gnutls_ocsp_cert_status_t) status;
|
||||
}
|
||||
|
||||
gnutls_ocsp_cert_status_t
|
||||
OcspResponse::verifyDirect(const Certificate& crt, const Blob& nonce)
|
||||
{
|
||||
// Check OCSP response
|
||||
int ret = gnutls_ocsp_resp_get_status(response);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
gnutls_ocsp_resp_status_t status = (gnutls_ocsp_resp_status_t)ret;
|
||||
if (status != GNUTLS_OCSP_RESP_SUCCESSFUL)
|
||||
throw CryptoException("OCSP request unsuccessful: " + std::to_string(ret));
|
||||
|
||||
if (not nonce.empty()) {
|
||||
// Ensure no replay attack has been done
|
||||
gnutls_datum_t rnonce;
|
||||
ret = gnutls_ocsp_resp_get_nonce(response, NULL, &rnonce);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
if (rnonce.size != nonce.size() || memcmp(nonce.data(), rnonce.data, nonce.size()) != 0){
|
||||
gnutls_free(rnonce.data);
|
||||
throw CryptoException(gnutls_strerror(GNUTLS_E_OCSP_RESPONSE_ERROR));
|
||||
}
|
||||
gnutls_free(rnonce.data);
|
||||
}
|
||||
|
||||
// Verify signature of the Basic OCSP response against the public key in the issuer certificate.
|
||||
unsigned int verify = 0;
|
||||
ret = gnutls_ocsp_resp_verify_direct(response, crt.issuer->cert, &verify, 0);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
if (verify) {
|
||||
if (verify & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
|
||||
throw CryptoException("Signer cert not found");
|
||||
if (verify & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
|
||||
throw CryptoException("Signer cert keyusage error");
|
||||
if (verify & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
|
||||
throw CryptoException("Signer cert is not trusted");
|
||||
if (verify & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
|
||||
throw CryptoException("Insecure algorithm");
|
||||
if (verify & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
|
||||
throw CryptoException("Signature failure");
|
||||
if (verify & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
|
||||
throw CryptoException("Signer cert not yet activated");
|
||||
if (verify & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
|
||||
throw CryptoException("Signer cert expired");
|
||||
throw CryptoException(gnutls_strerror(GNUTLS_E_OCSP_RESPONSE_ERROR));
|
||||
}
|
||||
|
||||
// Check whether the OCSP response is about the provided certificate.
|
||||
if ((ret = gnutls_ocsp_resp_check_crt(response, 0, crt.cert)) < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
|
||||
// Check certificate revocation status
|
||||
unsigned status_ocsp;
|
||||
ret = gnutls_ocsp_resp_get_single(response, 0, NULL, NULL, NULL, NULL, &status_ocsp, NULL, NULL, NULL, NULL);
|
||||
if (ret < 0)
|
||||
throw CryptoException(gnutls_strerror(ret));
|
||||
return (gnutls_ocsp_cert_status_t)status_ocsp;
|
||||
}
|
||||
|
||||
// RevocationList
|
||||
|
||||
RevocationList::RevocationList()
|
||||
@@ -1221,7 +1475,7 @@ RevocationList::RevocationList(const Blob& b)
|
||||
} catch (const std::exception& e) {
|
||||
gnutls_x509_crl_deinit(crl);
|
||||
crl = nullptr;
|
||||
throw e;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
+205
-114
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
|
||||
*
|
||||
@@ -30,16 +30,20 @@
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
namespace dht {
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
constexpr std::chrono::minutes Dht::MAX_STORAGE_MAINTENANCE_EXPIRE_TIME;
|
||||
constexpr std::chrono::minutes Dht::SEARCH_EXPIRE_TIME;
|
||||
constexpr std::chrono::seconds Dht::BOOTSTRAP_PERIOD;
|
||||
constexpr duration Dht::LISTEN_EXPIRE_TIME;
|
||||
constexpr duration Dht::LISTEN_EXPIRE_TIME_PUBLIC;
|
||||
constexpr duration Dht::REANNOUNCE_MARGIN;
|
||||
static constexpr size_t MAX_REQUESTS_PER_SEC {8 * 1024};
|
||||
static constexpr duration BOOTSTRAP_PERIOD_MAX {std::chrono::hours(24)};
|
||||
|
||||
NodeStatus
|
||||
Dht::updateStatus(sa_family_t af)
|
||||
@@ -49,15 +53,10 @@ Dht::updateStatus(sa_family_t af)
|
||||
d.status = d.getStatus(scheduler.time());
|
||||
if (d.status != old) {
|
||||
auto& other = dht(af == AF_INET ? AF_INET6 : AF_INET);
|
||||
if (other.status == NodeStatus::Disconnected && d.status == NodeStatus::Disconnected)
|
||||
if (other.status == NodeStatus::Disconnected && d.status == NodeStatus::Disconnected) {
|
||||
onDisconnected();
|
||||
else if (other.status == NodeStatus::Connected || d.status == NodeStatus::Connected) {
|
||||
// On connected
|
||||
if (bootstrapJob) {
|
||||
bootstrapJob->cancel();
|
||||
bootstrapJob.reset();
|
||||
}
|
||||
bootstrap_period = std::chrono::seconds(10);
|
||||
} else if (other.status == NodeStatus::Connected || d.status == NodeStatus::Connected) {
|
||||
onConnected();
|
||||
}
|
||||
}
|
||||
return d.status;
|
||||
@@ -82,11 +81,27 @@ Dht::Kad::getStatus(time_point now) const
|
||||
}
|
||||
|
||||
void
|
||||
Dht::shutdown(ShutdownCallback cb)
|
||||
Dht::shutdown(ShutdownCallback cb, bool stop)
|
||||
{
|
||||
if (not persistPath.empty())
|
||||
saveState(persistPath);
|
||||
|
||||
if (stop) {
|
||||
for (auto dht : {&dht4, &dht6}) {
|
||||
for (auto& sr : dht->searches) {
|
||||
for (const auto& r : sr.second->callbacks)
|
||||
r.second.done_cb(false, {});
|
||||
sr.second->callbacks.clear();
|
||||
for (const auto& a : sr.second->announce) {
|
||||
if (a.callback) a.callback(false, {});
|
||||
}
|
||||
sr.second->announce.clear();
|
||||
sr.second->listeners.clear();
|
||||
}
|
||||
}
|
||||
network_engine.clear();
|
||||
}
|
||||
|
||||
if (not maintain_storage) {
|
||||
if (cb) cb();
|
||||
return;
|
||||
@@ -273,7 +288,7 @@ Dht::searchNodeGetDone(const net::Request& req,
|
||||
if (srn->syncJob)
|
||||
scheduler.edit(srn->syncJob, syncTime);
|
||||
else
|
||||
srn->syncJob = scheduler.add(syncTime, std::bind(&Dht::searchStep, this, sr));
|
||||
srn->syncJob = scheduler.add(syncTime, std::bind(&Dht::searchStep, this, ws));
|
||||
}
|
||||
onGetValuesDone(req.node, answer, sr, query);
|
||||
}
|
||||
@@ -432,7 +447,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr) {
|
||||
{ /* when put done */
|
||||
if (auto sr = ws.lock()) {
|
||||
onAnnounceDone(req.node, answer, sr);
|
||||
searchStep(sr);
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -475,41 +490,61 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr) {
|
||||
} catch (std::out_of_range&) { }
|
||||
|
||||
auto next_refresh_time = now + getType(a.value->type).expiration;
|
||||
auto& acked = sn->acked[a.value->id];
|
||||
scheduler.cancel(acked.refresh);
|
||||
/* only put the value if the node doesn't already have it */
|
||||
if (not hasValue or seq_no < a.value->seq) {
|
||||
if (logger_)
|
||||
logger_->d(sr->id, sn->node->id, "[search %s] [node %s] sending 'put' (vid: %d)",
|
||||
logger_->d(sr->id, sn->node->id, "[search %s] [node %s] sending 'put' (vid: %016" PRIx64 ")",
|
||||
sr->id.toString().c_str(), sn->node->toString().c_str(), a.value->id);
|
||||
auto created = a.permanent ? time_point::max() : a.created;
|
||||
sn->acked[a.value->id] = {
|
||||
acked = {
|
||||
network_engine.sendAnnounceValue(sn->node, sr->id, a.value, created, sn->token, onDone, onExpired),
|
||||
next_refresh_time
|
||||
};
|
||||
} else if (hasValue and a.permanent) {
|
||||
if (logger_)
|
||||
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] sending 'refresh' (vid: %d)",
|
||||
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] sending 'refresh' (vid: %016" PRIx64 ")",
|
||||
sr->id.toString().c_str(), sn->node->toString().c_str(), a.value->id);
|
||||
sn->acked[a.value->id] = {
|
||||
network_engine.sendRefreshValue(sn->node, sr->id, a.value->id, sn->token, onDone, onExpired),
|
||||
acked = {
|
||||
network_engine.sendRefreshValue(sn->node, sr->id, a.value->id, sn->token, onDone,
|
||||
[this, ws, node=sn->node, v=a.value,
|
||||
onDone,
|
||||
onExpired,
|
||||
created = a.permanent ? time_point::max() : a.created,
|
||||
next_refresh_time
|
||||
](const net::Request& /*req*/, net::DhtProtocolException&& e){
|
||||
if (e.getCode() == net::DhtProtocolException::NOT_FOUND) {
|
||||
if (logger_)
|
||||
logger_->e(node->id, "[node %s] returned error 404: storage not found", node->toString().c_str());
|
||||
if (auto sr = ws.lock()) {
|
||||
if (auto sn = sr->getNode(node)) {
|
||||
sn->acked[v->id] = {
|
||||
network_engine.sendAnnounceValue(sn->node, sr->id, v, created, sn->token, onDone, onExpired),
|
||||
next_refresh_time
|
||||
};
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, onExpired),
|
||||
next_refresh_time
|
||||
};
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] already has value (vid: %d). Aborting.",
|
||||
logger_->w(sr->id, sn->node->id, "[search %s] [node %s] already has value (vid: %016" PRIx64 "). Aborting.",
|
||||
sr->id.toString().c_str(), sn->node->toString().c_str(), a.value->id);
|
||||
auto ack_req = std::make_shared<net::Request>(net::Request::State::COMPLETED);
|
||||
ack_req->reply_time = now;
|
||||
sn->acked[a.value->id] = std::make_pair(std::move(ack_req), next_refresh_time);
|
||||
acked = {std::move(ack_req), next_refresh_time};
|
||||
|
||||
/* step to clear announces */
|
||||
scheduler.edit(sr->nextSearchStep, now);
|
||||
}
|
||||
if (a.permanent) {
|
||||
scheduler.add(next_refresh_time - REANNOUNCE_MARGIN, [this,ws] {
|
||||
if (auto sr = ws.lock()) {
|
||||
searchStep(sr);
|
||||
}
|
||||
});
|
||||
acked.refresh = scheduler.add(next_refresh_time - REANNOUNCE_MARGIN, std::bind(&Dht::searchStep, this, ws));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -534,7 +569,7 @@ void Dht::searchSendAnnounceValue(const Sp<Search>& sr) {
|
||||
sendQuery = true;
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->w(sr->id, n.node->id, "[search %s] [node %s] sending 'put' (vid: %d)",
|
||||
logger_->w(sr->id, n.node->id, "[search %s] [node %s] sending 'put' (vid: %016" PRIx64 ")",
|
||||
sr->id.toString().c_str(), n.node->toString().c_str(), a.value->id);
|
||||
n.acked[a.value->id] = {
|
||||
network_engine.sendAnnounceValue(n.node, sr->id, a.value, a.created, n.token, onDone, onExpired),
|
||||
@@ -569,33 +604,30 @@ Dht::searchSynchedNodeListen(const Sp<Search>& sr, SearchNode& n)
|
||||
std::weak_ptr<Search> ws = sr;
|
||||
for (const auto& l : sr->listeners) {
|
||||
const auto& query = l.second.query;
|
||||
auto list_token = l.first;
|
||||
if (n.getListenTime(query, listenExp) > scheduler.time())
|
||||
|
||||
auto r = n.listenStatus.find(query);
|
||||
if (n.getListenTime(r, listenExp) > scheduler.time())
|
||||
continue;
|
||||
// if (logger_)
|
||||
// logger_->d(sr->id, n.node->id, "[search %s] [node %s] sending 'listen'",
|
||||
// sr->id.toString().c_str(), n.node->toString().c_str());
|
||||
|
||||
auto r = n.listenStatus.find(query);
|
||||
if (r == n.listenStatus.end()) {
|
||||
r = n.listenStatus.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(query),
|
||||
std::forward_as_tuple(
|
||||
[ws,list_token](const std::vector<Sp<Value>>& values, bool expired){
|
||||
if (auto sr = ws.lock()) {
|
||||
auto l = sr->listeners.find(list_token);
|
||||
if (l != sr->listeners.end()) {
|
||||
l->second.get_cb(values, expired);
|
||||
l.second.get_cb,
|
||||
l.second.sync_cb,
|
||||
n.node->openSocket([this,ws,query](const Sp<Node>& node, net::RequestAnswer&& answer) mutable {
|
||||
/* on new values */
|
||||
if (auto sr = ws.lock()) {
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
sr->insertNode(node, scheduler.time(), answer.ntoken);
|
||||
if (auto sn = sr->getNode(node)) {
|
||||
sn->onValues(query, std::move(answer), types, scheduler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [ws,list_token] (ListenSyncStatus status) {
|
||||
if (auto sr = ws.lock()) {
|
||||
auto l = sr->listeners.find(list_token);
|
||||
if (l != sr->listeners.end()) {
|
||||
l->second.sync_cb(status);
|
||||
}
|
||||
}
|
||||
})).first;
|
||||
}))).first;
|
||||
r->second.cacheExpirationJob = scheduler.add(time_point::max(), [this,ws,query,node=n.node]{
|
||||
if (auto sr = ws.lock()) {
|
||||
if (auto sn = sr->getNode(node)) {
|
||||
@@ -604,15 +636,14 @@ Dht::searchSynchedNodeListen(const Sp<Search>& sr, SearchNode& n)
|
||||
}
|
||||
});
|
||||
}
|
||||
auto prev_req = r != n.listenStatus.end() ? r->second.req : nullptr;
|
||||
auto new_req = network_engine.sendListen(n.node, sr->id, *query, n.token, prev_req,
|
||||
auto new_req = network_engine.sendListen(n.node, sr->id, *query, n.token, r->second.socketId,
|
||||
[this,ws,query](const net::Request& req, net::RequestAnswer&& answer) mutable
|
||||
{ /* on done */
|
||||
if (auto sr = ws.lock()) {
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
if (auto sn = sr->getNode(req.node)) {
|
||||
scheduler.add(sn->getListenTime(query, getListenExpiration()), std::bind(&Dht::searchStep, this, sr));
|
||||
sn->onListenSynced(query);
|
||||
auto job = scheduler.add(sn->getListenTime(query, getListenExpiration()), std::bind(&Dht::searchStep, this, ws));
|
||||
sn->onListenSynced(query, true, std::move(job));
|
||||
}
|
||||
onListenDone(req.node, answer, sr);
|
||||
}
|
||||
@@ -625,16 +656,6 @@ Dht::searchSynchedNodeListen(const Sp<Search>& sr, SearchNode& n)
|
||||
if (auto sn = sr->getNode(req.node))
|
||||
sn->listenStatus.erase(query);
|
||||
}
|
||||
},
|
||||
[this,ws,query](const Sp<Node>& node, net::RequestAnswer&& answer) mutable
|
||||
{ /* on new values */
|
||||
if (auto sr = ws.lock()) {
|
||||
scheduler.edit(sr->nextSearchStep, scheduler.time());
|
||||
sr->insertNode(node, scheduler.time(), answer.ntoken);
|
||||
if (auto sn = sr->getNode(node)) {
|
||||
sn->onValues(query, std::move(answer), types, scheduler);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
// Here the request may have failed and the CachedListenStatus removed
|
||||
@@ -648,8 +669,9 @@ Dht::searchSynchedNodeListen(const Sp<Search>& sr, SearchNode& n)
|
||||
/* When a search is in progress, we periodically call search_step to send
|
||||
further requests. */
|
||||
void
|
||||
Dht::searchStep(Sp<Search> sr)
|
||||
Dht::searchStep(std::weak_ptr<Search> ws)
|
||||
{
|
||||
auto sr = ws.lock();
|
||||
if (not sr or sr->expired or sr->done) return;
|
||||
|
||||
const auto& now = scheduler.time();
|
||||
@@ -717,7 +739,7 @@ Dht::searchStep(Sp<Search> sr)
|
||||
|
||||
while (sr->currentlySolicitedNodeCount() < MAX_REQUESTED_SEARCH_NODES and searchSendGetValues(sr));
|
||||
|
||||
|
||||
|
||||
if (sr->getNumberOfConsecutiveBadNodes() >= std::min<size_t>(sr->nodes.size(), SEARCH_MAX_BAD_NODES))
|
||||
{
|
||||
if (logger_)
|
||||
@@ -802,7 +824,7 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback gcb, QueryCallback q
|
||||
sr->expired = false;
|
||||
sr->nodes.clear();
|
||||
sr->nodes.reserve(SEARCH_NODES+1);
|
||||
sr->nextSearchStep = scheduler.add(time_point::max(), std::bind(&Dht::searchStep, this, sr));
|
||||
sr->nextSearchStep = scheduler.add(time_point::max(), std::bind(&Dht::searchStep, this, std::weak_ptr<Search>(sr)));
|
||||
if (logger_)
|
||||
logger_->w(id, "[search %s IPv%c] new search", id.toString().c_str(), (af == AF_INET) ? '4' : '6');
|
||||
if (search_id == 0)
|
||||
@@ -854,6 +876,11 @@ Dht::listenTo(const InfoHash& id, sa_family_t af, ValueCallback cb, Value::Filte
|
||||
size_t
|
||||
Dht::listen(const InfoHash& id, ValueCallback cb, Value::Filter f, Where where)
|
||||
{
|
||||
if (not id) {
|
||||
if (logger_)
|
||||
logger_->w(id, "Listen called with invalid key");
|
||||
return 0;
|
||||
}
|
||||
scheduler.syncTime();
|
||||
|
||||
auto token = ++listener_token;
|
||||
@@ -936,7 +963,9 @@ struct GetStatus : public OpStatus {
|
||||
void
|
||||
Dht::put(const InfoHash& id, Sp<Value> val, DoneCallback callback, time_point created, bool permanent)
|
||||
{
|
||||
if (not val) {
|
||||
if (not id or not val) {
|
||||
if (logger_)
|
||||
logger_->w(id, "Put called with invalid key or value");
|
||||
if (callback)
|
||||
callback(false, {});
|
||||
return;
|
||||
@@ -1006,6 +1035,13 @@ bool callbackWrapper(Cb get_cb, DoneCallback done_cb, const std::vector<Sp<T>>&
|
||||
void
|
||||
Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filter&& filter, Where&& where)
|
||||
{
|
||||
if (not id) {
|
||||
if (logger_)
|
||||
logger_->w(id, "Get called with invalid key");
|
||||
if (donecb)
|
||||
donecb(false, {});
|
||||
return;
|
||||
}
|
||||
scheduler.syncTime();
|
||||
|
||||
auto op = std::make_shared<GetStatus<std::map<Value::Id, Sp<Value>>>>();
|
||||
@@ -1046,6 +1082,13 @@ Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filt
|
||||
|
||||
void Dht::query(const InfoHash& id, QueryCallback cb, DoneCallback done_cb, Query&& q)
|
||||
{
|
||||
if (not id) {
|
||||
if (logger_)
|
||||
logger_->w(id, "Query called with invalid key");
|
||||
if (done_cb)
|
||||
done_cb(false, {});
|
||||
return;
|
||||
}
|
||||
scheduler.syncTime();
|
||||
auto op = std::make_shared<GetStatus<std::vector<Sp<FieldValueIndex>>>>();
|
||||
auto f = q.where.getFilter();
|
||||
@@ -1201,7 +1244,7 @@ Dht::storageChanged(const InfoHash& id, Storage& st, ValueStorage& v, bool newVa
|
||||
vals.push_back(v.data);
|
||||
Blob ntoken = makeToken(node_listeners.first->getAddr(), false);
|
||||
network_engine.tellListener(node_listeners.first, l.first, id, 0, ntoken, {}, {},
|
||||
std::move(vals), l.second.query);
|
||||
std::move(vals), l.second.query, l.second.version);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1234,8 +1277,9 @@ Dht::storageStore(const InfoHash& id, const Sp<Value>& value, time_point created
|
||||
if (auto vs = store.first) {
|
||||
total_store_size += store.second.size_diff;
|
||||
total_values += store.second.values_diff;
|
||||
scheduler.cancel(vs->expiration_job);
|
||||
if (not permanent) {
|
||||
scheduler.add(expiration, std::bind(&Dht::expireStorage, this, id));
|
||||
vs->expiration_job = scheduler.add(expiration, std::bind(&Dht::expireStorage, this, id));
|
||||
}
|
||||
if (total_store_size > max_store_size) {
|
||||
expireStore();
|
||||
@@ -1259,7 +1303,7 @@ Dht::storageErase(const InfoHash& id, Value::Id vid)
|
||||
}
|
||||
|
||||
void
|
||||
Dht::storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t socket_id, Query&& query)
|
||||
Dht::storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t socket_id, Query&& query, int version)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
auto st = store.find(id);
|
||||
@@ -1275,9 +1319,9 @@ Dht::storageAddListener(const InfoHash& id, const Sp<Node>& node, size_t socket_
|
||||
if (not vals.empty()) {
|
||||
network_engine.tellListener(node, socket_id, id, WANT4 | WANT6, makeToken(node->getAddr(), false),
|
||||
dht4.buckets.findClosestNodes(id, now, TARGET_NODES), dht6.buckets.findClosestNodes(id, now, TARGET_NODES),
|
||||
std::move(vals), query);
|
||||
std::move(vals), query, version);
|
||||
}
|
||||
node_listeners.emplace(socket_id, Listener {now, std::forward<Query>(query)});
|
||||
node_listeners.emplace(socket_id, Listener {now, std::forward<Query>(query), version});
|
||||
}
|
||||
else
|
||||
l->second.refresh(now, std::forward<Query>(query));
|
||||
@@ -1312,7 +1356,7 @@ Dht::expireStore(decltype(store)::iterator i)
|
||||
id.toString().c_str(),
|
||||
node_listeners.first->toString().c_str());
|
||||
Blob ntoken = makeToken(node_listeners.first->getAddr(), false);
|
||||
network_engine.tellListenerExpired(node_listeners.first, l.first, id, ntoken, ids);
|
||||
network_engine.tellListenerExpired(node_listeners.first, l.first, id, ntoken, ids, l.second.version);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1395,6 +1439,7 @@ Dht::connectivityChanged(sa_family_t af)
|
||||
reported_addr.erase(std::remove_if(reported_addr.begin(), reported_addr.end(), [&](const ReportedAddr& addr){
|
||||
return addr.second.getFamily() == af;
|
||||
}), reported_addr.end());
|
||||
startBootstrap(); // will only happen if disconnected
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1576,10 +1621,10 @@ Dht::dumpSearch(const Search& sr, std::ostream& out) const
|
||||
out << "[";
|
||||
for (const auto& a : sr.announce) {
|
||||
auto ack = n.acked.find(a.value->id);
|
||||
if (ack == n.acked.end() or not ack->second.first) {
|
||||
if (ack == n.acked.end() or not ack->second.req) {
|
||||
out << ' ';
|
||||
} else {
|
||||
out << ack->second.first->getStateChar();
|
||||
out << ack->second.req->getStateChar();
|
||||
}
|
||||
}
|
||||
out << "] ";
|
||||
@@ -1739,11 +1784,9 @@ fromDhtConfig(const Config& config)
|
||||
return netConf;
|
||||
}
|
||||
|
||||
Dht::Dht() : store(), network_engine(logger_, rd, scheduler, {}) {}
|
||||
|
||||
Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Sp<Logger>& l)
|
||||
: DhtInterface(l),
|
||||
myid(config.node_id ? config.node_id : InfoHash::getRandom()),
|
||||
myid(config.node_id ? config.node_id : InfoHash::getRandom(rd)),
|
||||
store(),
|
||||
store_quota(),
|
||||
max_store_keys(config.max_store_size ? (int)config.max_store_size : MAX_HASHES),
|
||||
@@ -1755,7 +1798,7 @@ Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, cons
|
||||
std::bind(&Dht::onPing, this, _1),
|
||||
std::bind(&Dht::onFindNode, this, _1, _2, _3),
|
||||
std::bind(&Dht::onGetValues, this, _1, _2, _3, _4),
|
||||
std::bind(&Dht::onListen, this, _1, _2, _3, _4, _5),
|
||||
std::bind(&Dht::onListen, this, _1, _2, _3, _4, _5, _6),
|
||||
std::bind(&Dht::onAnnounce, this, _1, _2, _3, _4, _5),
|
||||
std::bind(&Dht::onRefresh, this, _1, _2, _3, _4)),
|
||||
persistPath(config.persist_path),
|
||||
@@ -1785,13 +1828,13 @@ Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, cons
|
||||
secret = std::uniform_int_distribution<uint64_t>{}(rd);
|
||||
rotateSecrets();
|
||||
|
||||
if (not persistPath.empty())
|
||||
loadState(persistPath);
|
||||
|
||||
expire();
|
||||
|
||||
if (logger_)
|
||||
logger_->d("DHT node initialised with ID %s", myid.toString().c_str());
|
||||
|
||||
if (not persistPath.empty())
|
||||
loadState(persistPath);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1975,25 +2018,61 @@ Dht::expire()
|
||||
scheduler.add(expire_stuff_time, std::bind(&Dht::expire, this));
|
||||
}
|
||||
|
||||
void
|
||||
Dht::onConnected()
|
||||
{
|
||||
stopBootstrap();
|
||||
auto callbacks = std::move(onConnectCallbacks_);
|
||||
while (not callbacks.empty()) {
|
||||
callbacks.front()();
|
||||
callbacks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dht::onDisconnected()
|
||||
{
|
||||
if (not bootstrapJob)
|
||||
bootstrap();
|
||||
}
|
||||
|
||||
void
|
||||
Dht::bootstrap()
|
||||
{
|
||||
if (dht4.status != NodeStatus::Disconnected || dht6.status != NodeStatus::Disconnected)
|
||||
return;
|
||||
if (logger_)
|
||||
logger_->d(myid, "Bootstraping");
|
||||
for (const auto& boootstrap : bootstrap_nodes)
|
||||
for (const auto& boootstrap : bootstrap_nodes) {
|
||||
try {
|
||||
for (const auto& ip : network_engine.getSocket()->resolve(boootstrap.first, boootstrap.second))
|
||||
auto ips = network_engine.getSocket()->resolve(boootstrap.first, boootstrap.second);
|
||||
for (auto& ip : ips) {
|
||||
if (ip.getPort() == 0)
|
||||
ip.setPort(net::DHT_DEFAULT_PORT);
|
||||
pingNode(ip);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
if (logger_)
|
||||
logger_->e(myid, "Can't resolve %s:%s: %s", boootstrap.first.c_str(), boootstrap.second.c_str(), e.what());
|
||||
}
|
||||
if (bootstrapJob)
|
||||
bootstrapJob->cancel();
|
||||
bootstrapJob = scheduler.add(scheduler.time() + bootstrap_period, std::bind(&Dht::onDisconnected, this));
|
||||
bootstrap_period *= 2;
|
||||
}
|
||||
scheduler.cancel(bootstrapJob);
|
||||
bootstrapJob = scheduler.add(scheduler.time() + bootstrap_period, std::bind(&Dht::bootstrap, this));
|
||||
bootstrap_period = std::min(bootstrap_period * 2, BOOTSTRAP_PERIOD_MAX);
|
||||
}
|
||||
|
||||
void
|
||||
Dht::startBootstrap()
|
||||
{
|
||||
stopBootstrap();
|
||||
bootstrapJob = scheduler.add(scheduler.time(), std::bind(&Dht::bootstrap, this));
|
||||
}
|
||||
|
||||
void
|
||||
Dht::stopBootstrap()
|
||||
{
|
||||
scheduler.cancel(bootstrapJob);
|
||||
bootstrap_period = BOOTSTRAP_PERIOD;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2065,13 +2144,13 @@ Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
|
||||
for (const auto& node : import) {
|
||||
if (node.second.empty())
|
||||
for (const auto& value : import) {
|
||||
if (value.second.empty())
|
||||
continue;
|
||||
|
||||
try {
|
||||
msgpack::unpacked msg;
|
||||
msgpack::unpack(msg, (const char*)node.second.data(), node.second.size());
|
||||
msgpack::unpack(msg, (const char*)value.second.data(), value.second.size());
|
||||
auto valarr = msg.get();
|
||||
if (valarr.type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
@@ -2086,15 +2165,15 @@ Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
tmp_val.msgpack_unpack(valel.via.array.ptr[1]);
|
||||
} catch (const std::exception&) {
|
||||
if (logger_)
|
||||
logger_->e(node.first, "Error reading value at %s", node.first.toString().c_str());
|
||||
logger_->e(value.first, "Error reading value at %s", value.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
val_time = std::min(val_time, now);
|
||||
storageStore(node.first, std::make_shared<Value>(std::move(tmp_val)), val_time);
|
||||
storageStore(value.first, std::make_shared<Value>(std::move(tmp_val)), val_time);
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
if (logger_)
|
||||
logger_->e(node.first, "Error reading values at %s", node.first.toString().c_str());
|
||||
logger_->e(value.first, "Error reading values at %s", value.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2110,25 +2189,25 @@ Dht::exportNodes() const
|
||||
if (b4 != dht4.buckets.end()) {
|
||||
for (auto& n : b4->nodes)
|
||||
if (n->isGood(now))
|
||||
nodes.push_back(n->exportNode());
|
||||
nodes.emplace_back(n->exportNode());
|
||||
}
|
||||
const auto b6 = dht6.buckets.findBucket(myid);
|
||||
if (b6 != dht6.buckets.end()) {
|
||||
for (auto& n : b6->nodes)
|
||||
if (n->isGood(now))
|
||||
nodes.push_back(n->exportNode());
|
||||
nodes.emplace_back(n->exportNode());
|
||||
}
|
||||
for (auto b = dht4.buckets.begin(); b != dht4.buckets.end(); ++b) {
|
||||
if (b == b4) continue;
|
||||
for (auto& n : b->nodes)
|
||||
if (n->isGood(now))
|
||||
nodes.push_back(n->exportNode());
|
||||
nodes.emplace_back(n->exportNode());
|
||||
}
|
||||
for (auto b = dht6.buckets.begin(); b != dht6.buckets.end(); ++b) {
|
||||
if (b == b6) continue;
|
||||
for (auto& n : b->nodes)
|
||||
if (n->isGood(now))
|
||||
nodes.push_back(n->exportNode());
|
||||
nodes.emplace_back(n->exportNode());
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
@@ -2170,7 +2249,6 @@ Dht::onError(Sp<net::Request> req, net::DhtProtocolException e) {
|
||||
if (logger_)
|
||||
logger_->e(node->id, "[node %s] token flush", node->toString().c_str());
|
||||
node->authError();
|
||||
node->cancelRequest(req);
|
||||
for (auto& srp : searches(node->getFamily())) {
|
||||
auto& sr = srp.second;
|
||||
for (auto& n : sr->nodes) {
|
||||
@@ -2320,7 +2398,7 @@ void Dht::onGetValuesDone(const Sp<Node>& node,
|
||||
}
|
||||
|
||||
net::RequestAnswer
|
||||
Dht::onListen(Sp<Node> node, const InfoHash& hash, const Blob& token, size_t socket_id, const Query& query)
|
||||
Dht::onListen(Sp<Node> node, const InfoHash& hash, const Blob& token, size_t socket_id, const Query& query, int version)
|
||||
{
|
||||
if (not hash) {
|
||||
if (logger_)
|
||||
@@ -2336,7 +2414,7 @@ Dht::onListen(Sp<Node> node, const InfoHash& hash, const Blob& token, size_t soc
|
||||
throw net::DhtProtocolException {net::DhtProtocolException::UNAUTHORIZED, net::DhtProtocolException::LISTEN_WRONG_TOKEN};
|
||||
}
|
||||
Query q = query;
|
||||
storageAddListener(hash, node, socket_id, std::move(q));
|
||||
storageAddListener(hash, node, socket_id, std::move(q), version);
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -2402,7 +2480,7 @@ Dht::onAnnounce(Sp<Node> n,
|
||||
if (*lv == *vc) {
|
||||
storageRefresh(hash, v->id);
|
||||
if (logger_)
|
||||
logger_->d(hash, node.id, "[store %s] [node %s] refreshed value %s", hash.toString().c_str(), node.toString().c_str(), std::to_string(v->id).c_str());
|
||||
logger_->d(hash, node.id, "[store %s] [node %s] refreshed value %016" PRIx64, hash.toString().c_str(), node.toString().c_str(), v->id);
|
||||
} else {
|
||||
const auto& type = getType(lv->type);
|
||||
if (type.editPolicy(hash, lv, vc, node.id, node.getAddr())) {
|
||||
@@ -2445,7 +2523,7 @@ Dht::onRefresh(Sp<Node> node, const InfoHash& hash, const Blob& token, const Val
|
||||
}
|
||||
if (storageRefresh(hash, vid)) {
|
||||
if (logger_)
|
||||
logger_->d(hash, node->id, "[store %s] [node %s] refreshed value %s", hash.toString().c_str(), node->toString().c_str(), std::to_string(vid).c_str());
|
||||
logger_->d(hash, node->id, "[store %s] [node %s] refreshed value %016" PRIx64, hash.toString().c_str(), node->toString().c_str(), vid);
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->d(hash, node->id, "[store %s] [node %s] got refresh for unknown value",
|
||||
@@ -2475,14 +2553,18 @@ Dht::storageRefresh(const InfoHash& id, Value::Id vid)
|
||||
id.toString().c_str(),
|
||||
node_listeners.first->toString().c_str());
|
||||
Blob ntoken = makeToken(node_listeners.first->getAddr(), false);
|
||||
network_engine.tellListenerRefreshed(node_listeners.first, l.first, id, ntoken, ids);
|
||||
network_engine.tellListenerRefreshed(node_listeners.first, l.first, id, ntoken, ids, l.second.version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto expiration = s->second.refresh(now, vid, types);
|
||||
if (expiration != time_point::max())
|
||||
scheduler.add(expiration, std::bind(&Dht::expireStorage, this, id));
|
||||
if (expiration.first) {
|
||||
scheduler.cancel(expiration.first->expiration_job);
|
||||
if (expiration.second != time_point::max()) {
|
||||
expiration.first->expiration_job = scheduler.add(expiration.second, std::bind(&Dht::expireStorage, this, id));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -2499,12 +2581,24 @@ Dht::onAnnounceDone(const Sp<Node>& node, net::RequestAnswer& answer, Sp<Search>
|
||||
}
|
||||
|
||||
|
||||
struct DhtState {
|
||||
unsigned v {1};
|
||||
InfoHash id;
|
||||
std::vector<NodeExport> nodes;
|
||||
std::vector<ValuesExport> values;
|
||||
|
||||
MSGPACK_DEFINE_MAP(v, id, nodes, values)
|
||||
};
|
||||
|
||||
void
|
||||
Dht::saveState(const std::string& path) const
|
||||
{
|
||||
DhtState state;
|
||||
state.id = myid;
|
||||
state.nodes = exportNodes();
|
||||
state.values = exportValues();
|
||||
std::ofstream file(path);
|
||||
msgpack::pack(file, exportNodes());
|
||||
msgpack::pack(file, exportValues());
|
||||
msgpack::pack(file, state);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2530,19 +2624,16 @@ Dht::loadState(const std::string& path)
|
||||
// Import nodes
|
||||
msgpack::object_handle oh;
|
||||
if (pac.next(oh)) {
|
||||
{
|
||||
auto imported_nodes = oh.get().as<std::vector<NodeExport>>();
|
||||
if (logger_)
|
||||
logger_->d("Importing %zu nodes", imported_nodes.size());
|
||||
for (const auto& node : imported_nodes)
|
||||
insertNode(node);
|
||||
}
|
||||
if (pac.next(oh)) {
|
||||
auto imported_values = oh.get().as<std::vector<ValuesExport>>();
|
||||
if (logger_)
|
||||
logger_->d("Importing %zu values", imported_values.size());
|
||||
importValues(imported_values);
|
||||
}
|
||||
auto state = oh.get().as<DhtState>();
|
||||
if (logger_)
|
||||
logger_->d("Importing %zu nodes", state.nodes.size());
|
||||
if (state.id)
|
||||
myid = state.id;
|
||||
std::vector<Sp<Node>> tmpNodes;
|
||||
tmpNodes.reserve(state.nodes.size());
|
||||
for (const auto& node : state.nodes)
|
||||
tmpNodes.emplace_back(network_engine.insertNode(node.id, SockAddr(node.ss, node.sslen)));
|
||||
importValues(state.values);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
if (logger_)
|
||||
|
||||
+44
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
@@ -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 {
|
||||
@@ -98,7 +98,7 @@ getRandomSessionId(size_t length = 8) {
|
||||
static constexpr const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~";
|
||||
std::string str(length, 0);
|
||||
crypto::random_device rdev;
|
||||
std::uniform_int_distribution<> dist(0, (sizeof(chars)/sizeof(char)) - 1);
|
||||
std::uniform_int_distribution<> dist(0, (sizeof(chars)/sizeof(char)) - 2);
|
||||
std::generate_n( str.begin(), length, [&]{ return chars[dist(rdev)]; } );
|
||||
return str;
|
||||
}
|
||||
@@ -155,10 +155,10 @@ DhtProxyClient::startProxy()
|
||||
if (logger_)
|
||||
logger_->d("[proxy:client] start proxy with %s", proxyUrl_.c_str());
|
||||
|
||||
nextProxyConfirmationTimer_ = std::make_shared<asio::steady_timer>(httpContext_, std::chrono::steady_clock::now());
|
||||
nextProxyConfirmationTimer_ = std::make_unique<asio::steady_timer>(httpContext_, std::chrono::steady_clock::now());
|
||||
nextProxyConfirmationTimer_->async_wait(std::bind(&DhtProxyClient::handleProxyConfirm, this, std::placeholders::_1));
|
||||
|
||||
listenerRestartTimer_ = std::make_shared<asio::steady_timer>(httpContext_);
|
||||
listenerRestartTimer_ = std::make_unique<asio::steady_timer>(httpContext_);
|
||||
|
||||
loopSignal_();
|
||||
}
|
||||
@@ -242,7 +242,7 @@ DhtProxyClient::cancelAllListeners()
|
||||
}
|
||||
|
||||
void
|
||||
DhtProxyClient::shutdown(ShutdownCallback cb)
|
||||
DhtProxyClient::shutdown(ShutdownCallback cb, bool)
|
||||
{
|
||||
stop();
|
||||
if (cb)
|
||||
@@ -636,6 +636,8 @@ DhtProxyClient::queryProxyInfo(const Sp<InfoState>& infoState, const Sp<http::Re
|
||||
logger_->d("[proxy:client] [status] query ipv%i info", family == AF_INET ? 4 : 6);
|
||||
try {
|
||||
auto request = std::make_shared<http::Request>(httpContext_, resolver, family);
|
||||
if (serverCertificate_)
|
||||
request->set_certificate_authority(serverCertificate_);
|
||||
auto reqid = request->id();
|
||||
request->set_method(restinio::http_method_get());
|
||||
setHeaderFields(*request);
|
||||
@@ -683,7 +685,7 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t fa
|
||||
{
|
||||
if (isDestroying_)
|
||||
return;
|
||||
std::lock_guard<std::mutex> l(lockCurrentProxyInfos_);
|
||||
std::unique_lock<std::mutex> l(lockCurrentProxyInfos_);
|
||||
auto oldStatus = std::max(statusIpv4_, statusIpv6_);
|
||||
auto& status = family == AF_INET ? statusIpv4_ : statusIpv6_;
|
||||
if (not proxyInfos.isMember("node_id")) {
|
||||
@@ -718,9 +720,19 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t fa
|
||||
}
|
||||
auto newStatus = std::max(statusIpv4_, statusIpv6_);
|
||||
if (newStatus == NodeStatus::Connected) {
|
||||
if (oldStatus == NodeStatus::Disconnected || oldStatus == NodeStatus::Connecting) {
|
||||
if (oldStatus == NodeStatus::Disconnected || oldStatus == NodeStatus::Connecting || launchConnectedCbs_) {
|
||||
launchConnectedCbs_ = false;
|
||||
listenerRestartTimer_->expires_at(std::chrono::steady_clock::now());
|
||||
listenerRestartTimer_->async_wait(std::bind(&DhtProxyClient::restartListeners, this));
|
||||
listenerRestartTimer_->async_wait(std::bind(&DhtProxyClient::restartListeners, this, std::placeholders::_1));
|
||||
if (not onConnectCallbacks_.empty()) {
|
||||
std::lock_guard<std::mutex> lock(lockCallbacks_);
|
||||
callbacks_.emplace_back([cbs = std::move(onConnectCallbacks_)]() mutable {
|
||||
while (not cbs.empty()) {
|
||||
cbs.front()();
|
||||
cbs.pop();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
nextProxyConfirmationTimer_->expires_at(std::chrono::steady_clock::now() + std::chrono::minutes(15));
|
||||
nextProxyConfirmationTimer_->async_wait(std::bind(&DhtProxyClient::handleProxyConfirm, this, std::placeholders::_1));
|
||||
@@ -729,6 +741,7 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t fa
|
||||
nextProxyConfirmationTimer_->expires_at(std::chrono::steady_clock::now() + std::chrono::minutes(1));
|
||||
nextProxyConfirmationTimer_->async_wait(std::bind(&DhtProxyClient::handleProxyConfirm, this, std::placeholders::_1));
|
||||
}
|
||||
l.unlock();
|
||||
loopSignal_();
|
||||
}
|
||||
|
||||
@@ -801,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
|
||||
@@ -813,17 +827,13 @@ 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
|
||||
method = ListenMethod::LISTEN;
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
header.method(restinio::method_listen);
|
||||
header.request_target("/" + key.toString());
|
||||
#else
|
||||
header.method(restinio::http_method_get());
|
||||
header.request_target("/key/" + key.toString() + "/listen");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
method = ListenMethod::SUBSCRIBE;
|
||||
@@ -1078,8 +1088,16 @@ DhtProxyClient::getConnectivityStatus()
|
||||
}
|
||||
|
||||
void
|
||||
DhtProxyClient::restartListeners()
|
||||
DhtProxyClient::restartListeners(const asio::error_code &ec)
|
||||
{
|
||||
if (ec == asio::error::operation_aborted)
|
||||
return;
|
||||
else if (ec){
|
||||
if (logger_)
|
||||
logger_->e("[proxy:client] restart error: %s", ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDestroying_)
|
||||
return;
|
||||
if (logger_)
|
||||
@@ -1131,13 +1149,8 @@ DhtProxyClient::restartListeners()
|
||||
auto cb = listener.cb;
|
||||
// define header
|
||||
restinio::http_request_header_t header;
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
header.method(restinio::method_listen);
|
||||
header.request_target("/" + search.first.toString());
|
||||
#else
|
||||
header.method(restinio::http_method_get());
|
||||
header.request_target("/key/" + search.first.toString() + "/listen");
|
||||
#endif
|
||||
sendListen(header, cb, opstate, listener, ListenMethod::LISTEN);
|
||||
}
|
||||
}
|
||||
@@ -1150,9 +1163,13 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
|
||||
{
|
||||
// If a push notification is received, the proxy is up and running
|
||||
std::lock_guard<std::mutex> l(lockCurrentProxyInfos_);
|
||||
auto oldStatus = std::max(statusIpv4_, statusIpv6_);
|
||||
if (oldStatus != NodeStatus::Connected)
|
||||
launchConnectedCbs_ = true;
|
||||
statusIpv4_ = NodeStatus::Connected;
|
||||
statusIpv6_ = NodeStatus::Connected;
|
||||
}
|
||||
auto launchLoop = false;
|
||||
try {
|
||||
auto sessionId = notification.find("s");
|
||||
if (sessionId != notification.end() and sessionId->second != pushSessionId_) {
|
||||
@@ -1214,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;
|
||||
@@ -1229,7 +1246,7 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
|
||||
opstate->stop = true;
|
||||
});
|
||||
}
|
||||
loopSignal_();
|
||||
launchLoop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1237,6 +1254,8 @@ DhtProxyClient::pushNotificationReceived(const std::map<std::string, std::string
|
||||
if (logger_)
|
||||
logger_->e("[proxy:client] [push] receive error: %s", e.what());
|
||||
}
|
||||
if (launchLoop)
|
||||
loopSignal_();
|
||||
#else
|
||||
(void) notification;
|
||||
#endif
|
||||
@@ -1252,11 +1271,7 @@ DhtProxyClient::resubscribe(const InfoHash& key, const size_t token, Listener& l
|
||||
logger_->d("[proxy:client] [resubscribe] [search %s]", key.to_c_str());
|
||||
|
||||
auto opstate = listener.opstate;
|
||||
opstate->stop = true;
|
||||
if (listener.request){
|
||||
listener.request.reset();
|
||||
}
|
||||
opstate->stop = false;
|
||||
listener.request.reset(); // This will update ok to false
|
||||
opstate->ok = true;
|
||||
|
||||
restinio::http_request_header_t header;
|
||||
|
||||
+364
-187
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
|
||||
* Copyright (C) 2014-2022 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
* Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com>
|
||||
@@ -34,29 +34,11 @@
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
namespace restinio {
|
||||
struct custom_http_methods_t
|
||||
{
|
||||
static constexpr restinio::http_method_id_t from_nodejs(int m) noexcept {
|
||||
if(m == method_listen.raw_id())
|
||||
return method_listen;
|
||||
else if(m == method_stats.raw_id())
|
||||
return method_stats;
|
||||
else if(m == method_sign.raw_id())
|
||||
return method_sign;
|
||||
else if(m == method_encrypt.raw_id())
|
||||
return method_encrypt;
|
||||
else
|
||||
return restinio::default_http_methods_t::from_nodejs(m);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
using namespace std::literals;
|
||||
|
||||
namespace dht {
|
||||
constexpr char RESP_MSG_JSON_INCORRECT[] = "{\"err:\":\"Incorrect JSON\"}";
|
||||
@@ -118,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() {};
|
||||
|
||||
/**
|
||||
@@ -155,9 +137,6 @@ DhtProxyServer::onConnectionClosed(restinio::connection_id_t id)
|
||||
struct DhtProxyServer::RestRouterTraitsTls : public restinio::default_tls_traits_t
|
||||
{
|
||||
using timer_manager_t = restinio::asio_timer_manager_t;
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
using http_methods_mapper_t = restinio::custom_http_methods_t;
|
||||
#endif
|
||||
using logger_t = opendht_logger_t;
|
||||
using request_handler_t = RestRouter;
|
||||
using connection_state_listener_t = ConnectionListener;
|
||||
@@ -165,34 +144,78 @@ struct DhtProxyServer::RestRouterTraitsTls : public restinio::default_tls_traits
|
||||
struct DhtProxyServer::RestRouterTraits : public restinio::default_traits_t
|
||||
{
|
||||
using timer_manager_t = restinio::asio_timer_manager_t;
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
using http_methods_mapper_t = restinio::custom_http_methods_t;
|
||||
#endif
|
||||
using logger_t = opendht_logger_t;
|
||||
using request_handler_t = RestRouter;
|
||||
using connection_state_listener_t = ConnectionListener;
|
||||
};
|
||||
|
||||
DhtProxyServer::DhtProxyServer(
|
||||
crypto::Identity identity,
|
||||
std::shared_ptr<DhtRunner> dht, in_port_t port, const std::string& pushServer,
|
||||
std::shared_ptr<Logger> logger
|
||||
void
|
||||
DhtProxyServer::PermanentPut::msgpack_unpack(const msgpack::object& o)
|
||||
{
|
||||
if (auto cid = findMapValue(o, "cid"sv)) {
|
||||
clientId = cid->as<std::string>();
|
||||
}
|
||||
if (auto exp = findMapValue(o, "exp"sv)) {
|
||||
expiration = from_time_t(exp->as<time_t>());
|
||||
}
|
||||
if (auto token = findMapValue(o, "token"sv)) {
|
||||
pushToken = token->as<std::string>();
|
||||
}
|
||||
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"sv)) {
|
||||
type = t->as<PushType>();
|
||||
}
|
||||
if (auto val = findMapValue(o, "value"sv)) {
|
||||
value = std::make_shared<dht::Value>(*val);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
void
|
||||
DhtProxyServer::Listener::msgpack_unpack(const msgpack::object& o)
|
||||
{
|
||||
if (auto cid = findMapValue(o, "cid"sv)) {
|
||||
clientId = cid->as<std::string>();
|
||||
}
|
||||
if (auto exp = findMapValue(o, "exp"sv)) {
|
||||
expiration = from_time_t(exp->as<time_t>());
|
||||
}
|
||||
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"sv)) {
|
||||
type = t->as<PushType>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
DhtProxyServer::DhtProxyServer(const std::shared_ptr<DhtRunner>& dht,
|
||||
const ProxyServerConfig& config,
|
||||
const std::shared_ptr<dht::Logger>& logger
|
||||
)
|
||||
: ioContext_(std::make_shared<asio::io_context>()),
|
||||
dht_(dht), logger_(logger),
|
||||
dht_(dht), persistPath_(config.persistStatePath), logger_(logger),
|
||||
printStatsTimer_(std::make_unique<asio::steady_timer>(*ioContext_, 3s)),
|
||||
connListener_(std::make_shared<ConnectionListener>(std::bind(&DhtProxyServer::onConnectionClosed, this, std::placeholders::_1))),
|
||||
pushServer_(pushServer)
|
||||
pushServer_(config.pushServer)
|
||||
{
|
||||
if (not dht_)
|
||||
throw std::invalid_argument("A DHT instance must be provided");
|
||||
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [init] running on %i", port);
|
||||
if (not pushServer.empty()){
|
||||
logger_->d("[proxy:server] [init] running on %i", config.port);
|
||||
if (not pushServer_.empty()){
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [init] using push server %s", pushServer.c_str());
|
||||
logger_->d("[proxy:server] [init] using push server %s", pushServer_.c_str());
|
||||
#else
|
||||
if (logger_)
|
||||
logger_->e("[proxy:server] [init] opendht built without push notification support");
|
||||
@@ -202,9 +225,9 @@ DhtProxyServer::DhtProxyServer(
|
||||
jsonBuilder_["commentStyle"] = "None";
|
||||
jsonBuilder_["indentation"] = "";
|
||||
|
||||
if (!pushServer.empty()){
|
||||
if (!pushServer_.empty()){
|
||||
// no host delim, assume port only
|
||||
if (pushServer.find(":") == std::string::npos)
|
||||
if (pushServer_.find(":") == std::string::npos)
|
||||
pushServer_ = "localhost:" + pushServer_;
|
||||
// define http request destination for push notifications
|
||||
pushHostPort_ = splitPort(pushServer_);
|
||||
@@ -212,7 +235,7 @@ DhtProxyServer::DhtProxyServer(
|
||||
logger_->d("Using push server for notifications: %s:%s", pushHostPort_.first.c_str(),
|
||||
pushHostPort_.second.c_str());
|
||||
}
|
||||
if (identity.first and identity.second) {
|
||||
if (config.identity.first and config.identity.second) {
|
||||
asio::error_code ec;
|
||||
// define tls context
|
||||
asio::ssl::context tls_context { asio::ssl::context::sslv23 };
|
||||
@@ -226,13 +249,13 @@ DhtProxyServer::DhtProxyServer(
|
||||
SSL_CTX_set_options(tls_context.native_handle(), SSL_OP_NO_RENEGOTIATION); // CVE-2009-3555
|
||||
#endif
|
||||
// node private key
|
||||
auto key = identity.first->serialize();
|
||||
auto key = config.identity.first->serialize();
|
||||
tls_context.use_private_key(asio::const_buffer{key.data(), key.size()},
|
||||
asio::ssl::context::file_format::pem, ec);
|
||||
if (ec)
|
||||
throw std::runtime_error("Error setting node's private key: " + ec.message());
|
||||
// certificate chain
|
||||
auto certchain = identity.second->toString(true/*chain*/);
|
||||
auto certchain = config.identity.second->toString(true/*chain*/);
|
||||
tls_context.use_certificate_chain(asio::const_buffer{certchain.data(), certchain.size()}, ec);
|
||||
if (ec)
|
||||
throw std::runtime_error("Error setting certificate chain: " + ec.message());
|
||||
@@ -241,7 +264,7 @@ DhtProxyServer::DhtProxyServer(
|
||||
// build http server
|
||||
auto settings = restinio::run_on_this_thread_settings_t<RestRouterTraitsTls>();
|
||||
addServerSettings(settings);
|
||||
settings.port(port);
|
||||
settings.port(config.port);
|
||||
settings.tls_context(std::move(tls_context));
|
||||
httpsServer_ = std::make_unique<restinio::http_server_t<RestRouterTraitsTls>>(
|
||||
ioContext_,
|
||||
@@ -258,7 +281,7 @@ DhtProxyServer::DhtProxyServer(
|
||||
else {
|
||||
auto settings = restinio::run_on_this_thread_settings_t<RestRouterTraits>();
|
||||
addServerSettings(settings);
|
||||
settings.port(port);
|
||||
settings.port(config.port);
|
||||
httpServer_ = std::make_unique<restinio::http_server_t<RestRouterTraits>>(
|
||||
ioContext_,
|
||||
std::forward<restinio::run_on_this_thread_settings_t<RestRouterTraits>>(std::move(settings))
|
||||
@@ -274,8 +297,158 @@ DhtProxyServer::DhtProxyServer(
|
||||
dht->forwardAllMessages(true);
|
||||
updateStats();
|
||||
printStatsTimer_->async_wait(std::bind(&DhtProxyServer::handlePrintStats, this, std::placeholders::_1));
|
||||
|
||||
if (not persistPath_.empty()) {
|
||||
try {
|
||||
std::ifstream stateFile(persistPath_, std::ios::binary | std::ios::ate);
|
||||
if (stateFile) {
|
||||
std::streamsize size = stateFile.tellg();
|
||||
stateFile.seekg(0, std::ios::beg);
|
||||
if (logger_)
|
||||
logger_->d("Loading proxy state from %.*s (%td bytes)", (int)persistPath_.size(), persistPath_.c_str(), size);
|
||||
loadState(stateFile, size);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
if (logger_)
|
||||
logger_->e("Error loading state from file: %s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Os>
|
||||
void
|
||||
DhtProxyServer::saveState(Os& stream) {
|
||||
msgpack::packer<Os> pk(&stream);
|
||||
pk.pack_map(2);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lockSearchPuts_);
|
||||
pk.pack("puts");
|
||||
pk.pack(puts_);
|
||||
}
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(lockListener_);
|
||||
pk.pack("pushListeners");
|
||||
pk.pack(pushListeners_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Is>
|
||||
void
|
||||
DhtProxyServer::loadState(Is& is, size_t size) {
|
||||
msgpack::unpacker pac;
|
||||
pac.reserve_buffer(size);
|
||||
if (is.read(pac.buffer(), size)) {
|
||||
pac.buffer_consumed(size);
|
||||
|
||||
msgpack::object_handle oh;
|
||||
while (pac.next(oh)) {
|
||||
if (oh.get().type != msgpack::type::MAP)
|
||||
continue;
|
||||
if (auto puts = findMapValue(oh.get(), "puts"sv)) {
|
||||
std::lock_guard<std::mutex> lock(lockSearchPuts_);
|
||||
puts_ = puts->as<decltype(puts_)>();
|
||||
if (logger_)
|
||||
logger_->d("Loading %zu persistent puts", puts_.size());
|
||||
for (auto& put : puts_) {
|
||||
for (auto& pput : put.second.puts) {
|
||||
pput.second.expireTimer = std::make_unique<asio::steady_timer>(io_context(), pput.second.expiration);
|
||||
pput.second.expireTimer->async_wait(std::bind(&DhtProxyServer::handleCancelPermamentPut, this,
|
||||
std::placeholders::_1, put.first, pput.first));
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
if (not pput.second.pushToken.empty()) {
|
||||
auto jsonProvider = [infoHash=put.first.toString(), clientId=pput.second.clientId, vid = pput.first, sessionCtx = pput.second.sessionCtx](){
|
||||
Json::Value json;
|
||||
json["timeout"] = infoHash;
|
||||
json["to"] = clientId;
|
||||
json["vid"] = std::to_string(vid);
|
||||
if (sessionCtx) {
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
json["s"] = sessionCtx->sessionId;
|
||||
}
|
||||
return json;
|
||||
};
|
||||
pput.second.expireNotifyTimer = std::make_unique<asio::steady_timer>(io_context(), pput.second.expiration - proxy::OP_MARGIN);
|
||||
pput.second.expireNotifyTimer->async_wait(std::bind(
|
||||
&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pput.second.pushToken, std::move(jsonProvider), pput.second.type));
|
||||
}
|
||||
#endif
|
||||
dht_->put(put.first, pput.second.value, DoneCallbackSimple{}, time_point::max(), true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->d("No persistent puts in state");
|
||||
}
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
if (auto pushListeners = findMapValue(oh.get(), "pushListeners"sv)) {
|
||||
std::lock_guard<std::mutex> lock(lockListener_);
|
||||
pushListeners_ = pushListeners->as<decltype(pushListeners_)>();
|
||||
if (logger_)
|
||||
logger_->d("Loading %zu push listeners", pushListeners_.size());
|
||||
for (auto& pushListener : pushListeners_) {
|
||||
for (auto& listeners : pushListener.second.listeners) {
|
||||
for (auto& listener : listeners.second) {
|
||||
listener.internalToken = dht_->listen(listeners.first,
|
||||
[this, infoHash=listeners.first, pushToken=pushListener.first, type=listener.type, clientId=listener.clientId, sessionCtx = listener.sessionCtx]
|
||||
(const std::vector<std::shared_ptr<Value>>& values, bool expired) {
|
||||
// Build message content
|
||||
Json::Value json;
|
||||
json["key"] = infoHash.toString();
|
||||
json["to"] = clientId;
|
||||
json["t"] = Json::Value::Int64(std::chrono::duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count());
|
||||
{
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
json["s"] = sessionCtx->sessionId;
|
||||
}
|
||||
if (expired and values.size() < 2){
|
||||
std::stringstream ss;
|
||||
for(size_t i = 0; i < values.size(); ++i){
|
||||
if(i != 0) ss << ",";
|
||||
ss << values[i]->id;
|
||||
}
|
||||
json["exp"] = ss.str();
|
||||
}
|
||||
auto maxPrio = 1000u;
|
||||
for (const auto& v : values)
|
||||
maxPrio = std::min(maxPrio, v->priority);
|
||||
sendPushNotification(pushToken, std::move(json), type, !expired and maxPrio == 0);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// expire notify
|
||||
listener.expireNotifyTimer = std::make_unique<asio::steady_timer>(io_context(), listener.expiration - proxy::OP_MARGIN);
|
||||
auto jsonProvider = [infoHash = listeners.first.toString(), clientId = listener.clientId, sessionCtx = listener.sessionCtx](){
|
||||
Json::Value json;
|
||||
json["timeout"] = infoHash;
|
||||
json["to"] = clientId;
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
json["s"] = sessionCtx->sessionId;
|
||||
return json;
|
||||
};
|
||||
listener.expireNotifyTimer->async_wait(std::bind(&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pushListener.first, std::move(jsonProvider), listener.type));
|
||||
// cancel push listen
|
||||
listener.expireTimer = std::make_unique<asio::steady_timer>(io_context(), listener.expiration);
|
||||
listener.expireTimer->async_wait(std::bind(&DhtProxyServer::handleCancelPushListen, this,
|
||||
std::placeholders::_1, pushListener.first, listeners.first, listener.clientId));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (logger_)
|
||||
logger_->d("No push listeners in state");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (logger_)
|
||||
logger_->d("loading ended");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
asio::io_context&
|
||||
DhtProxyServer::io_context() const
|
||||
{
|
||||
@@ -284,6 +457,12 @@ DhtProxyServer::io_context() const
|
||||
|
||||
DhtProxyServer::~DhtProxyServer()
|
||||
{
|
||||
if (not persistPath_.empty()) {
|
||||
if (logger_)
|
||||
logger_->d("Saving proxy state to %.*s", (int)persistPath_.size(), persistPath_.c_str());
|
||||
std::ofstream stateFile(persistPath_, std::ios::binary);
|
||||
saveState(stateFile);
|
||||
}
|
||||
if (dht_) {
|
||||
std::lock_guard<std::mutex> lock(lockListener_);
|
||||
for (auto& l : listeners_) {
|
||||
@@ -359,6 +538,10 @@ DhtProxyServer::updateStats(std::shared_ptr<NodeInfo> info) const
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
stats.pushListenersCount = pushListeners_.size();
|
||||
#endif
|
||||
stats.totalPermanentPuts = 0;
|
||||
std::for_each(puts_.begin(), puts_.end(), [&stats](const auto& put) {
|
||||
stats.totalPermanentPuts += put.second.puts.size();
|
||||
});
|
||||
stats.putCount = puts_.size();
|
||||
stats.listenCount = listeners_.size();
|
||||
stats.nodeInfo = std::move(info);
|
||||
@@ -405,11 +588,6 @@ DhtProxyServer::createRestRouter()
|
||||
// **************************** LEGACY ROUTES ****************************
|
||||
// node.info
|
||||
router->http_get("/", std::bind(&DhtProxyServer::getNodeInfo, this, _1, _2));
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
// node.stats
|
||||
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_stats.raw_id()),
|
||||
"/", std::bind(&DhtProxyServer::getStats, this, _1, _2));
|
||||
#endif
|
||||
// key.options
|
||||
router->add_handler(restinio::http_method_options(),
|
||||
"/:hash", std::bind(&DhtProxyServer::options, this, _1, _2));
|
||||
@@ -417,11 +595,6 @@ DhtProxyServer::createRestRouter()
|
||||
router->http_get("/:hash", std::bind(&DhtProxyServer::get, this, _1, _2));
|
||||
// key.post
|
||||
router->http_post("/:hash", std::bind(&DhtProxyServer::put, this, _1, _2));
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
// key.listen
|
||||
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_listen.raw_id()),
|
||||
"/:hash", std::bind(&DhtProxyServer::listen, this, _1, _2));
|
||||
#endif
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
// key.subscribe
|
||||
router->add_handler(restinio::http_method_subscribe(),
|
||||
@@ -431,14 +604,6 @@ DhtProxyServer::createRestRouter()
|
||||
"/:hash", std::bind(&DhtProxyServer::unsubscribe, this, _1, _2));
|
||||
#endif //OPENDHT_PUSH_NOTIFICATIONS
|
||||
#ifdef OPENDHT_PROXY_SERVER_IDENTITY
|
||||
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
|
||||
// key.sign
|
||||
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_sign.raw_id()),
|
||||
"/:hash", std::bind(&DhtProxyServer::putSigned, this, _1, _2));
|
||||
// key.encrypt
|
||||
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_encrypt.raw_id()),
|
||||
"/:hash", std::bind(&DhtProxyServer::putEncrypted, this, _1, _2));
|
||||
#endif
|
||||
#endif // OPENDHT_PROXY_SERVER_IDENTITY
|
||||
|
||||
// **************************** NEW ROUTES ****************************
|
||||
@@ -519,9 +684,9 @@ DhtProxyServer::get(restinio::request_handle_t request,
|
||||
{
|
||||
requestNum_++;
|
||||
try {
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
auto response = std::make_shared<ResponseByPartsBuilder>(
|
||||
initHttpResponse(request->create_response<ResponseByParts>()));
|
||||
response->flush();
|
||||
@@ -550,9 +715,9 @@ DhtProxyServer::listen(restinio::request_handle_t request,
|
||||
requestNum_++;
|
||||
|
||||
try {
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
auto response = std::make_shared<ResponseByPartsBuilder>(
|
||||
initHttpResponse(request->create_response<ResponseByParts>()));
|
||||
response->flush();
|
||||
@@ -585,12 +750,11 @@ DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params)
|
||||
{
|
||||
requestNum_++;
|
||||
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
|
||||
try {
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
|
||||
std::string err;
|
||||
Json::Value r;
|
||||
auto* char_data = reinterpret_cast<const char*>(request->body().data());
|
||||
@@ -607,117 +771,115 @@ DhtProxyServer::subscribe(restinio::request_handle_t request,
|
||||
response.set_body(RESP_MSG_NO_TOKEN);
|
||||
return response.done();
|
||||
}
|
||||
auto isAndroid = root["platform"].asString() == "android";
|
||||
auto type = root["platform"].asString() == "android" ? PushType::Android : PushType::iOS;
|
||||
auto clientId = root["client_id"].asString();
|
||||
auto sessionId = root["session_id"].asString();
|
||||
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [subscribe %s] [client %s] [session %s]", infoHash.toString().c_str(), clientId.c_str(), sessionId.c_str());
|
||||
// ================ Search for existing listener ===================
|
||||
// start the timer
|
||||
auto timeout = std::chrono::steady_clock::now() + proxy::OP_TIMEOUT;
|
||||
std::lock_guard<std::mutex> lock(lockPushListeners_);
|
||||
|
||||
// Insert new or return existing push listeners of a token
|
||||
std::lock_guard<std::mutex> lock(lockListener_);
|
||||
auto& pushListener = pushListeners_[pushToken];
|
||||
auto& pushListeners = pushListener.listeners[infoHash];
|
||||
|
||||
for (auto &listener: pushListeners) {
|
||||
// Found -> Resubscribe
|
||||
if (listener.clientId == clientId) {
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [subscribe] found [client %s]", listener.clientId.c_str());
|
||||
// Reset timers
|
||||
listener.expireTimer->expires_at(timeout);
|
||||
listener.expireNotifyTimer->expires_at(timeout - proxy::OP_MARGIN);
|
||||
{
|
||||
std::lock_guard<std::mutex> l(listener.sessionCtx->lock);
|
||||
listener.sessionCtx->sessionId = sessionId;
|
||||
}
|
||||
// Send response header
|
||||
auto response = std::make_shared<ResponseByPartsBuilder>(
|
||||
initHttpResponse(request->create_response<ResponseByParts>()));
|
||||
response->flush();
|
||||
if (!root["refresh"].asBool()) {
|
||||
// No Refresh
|
||||
dht_->get(infoHash, [this, response](const Sp<Value>& value){
|
||||
auto output = Json::writeString(jsonBuilder_, value->toJson()) + "\n";
|
||||
response->append_chunk(output);
|
||||
response->flush();
|
||||
return true;
|
||||
},
|
||||
[response] (bool){
|
||||
response->done();
|
||||
});
|
||||
} else {
|
||||
// Refresh
|
||||
response->append_chunk("{}\n");
|
||||
response->done();
|
||||
}
|
||||
return restinio::request_handling_status_t::accepted;
|
||||
}
|
||||
auto listIt = std::find_if(pushListeners.begin(), pushListeners.end(), [&](const Listener& l) {
|
||||
return l.clientId == clientId;
|
||||
});
|
||||
bool newListener = listIt == pushListeners.end();
|
||||
if (newListener) {
|
||||
pushListeners.emplace_back(Listener{});
|
||||
listIt = std::prev(pushListeners.end());
|
||||
listIt->clientId = clientId;
|
||||
listIt->sessionCtx = std::make_shared<PushSessionContext>(sessionId);
|
||||
} else {
|
||||
std::lock_guard<std::mutex> l(listIt->sessionCtx->lock);
|
||||
listIt->sessionCtx->sessionId = sessionId;
|
||||
}
|
||||
// =========== No existing listener for an infoHash ============
|
||||
// Add new listener to list of listeners
|
||||
pushListeners.emplace_back(Listener{});
|
||||
auto &listener = pushListeners.back();
|
||||
listener.clientId = clientId;
|
||||
listener.sessionCtx = std::make_shared<PushSessionContext>();
|
||||
listener.sessionCtx->sessionId = sessionId;
|
||||
auto& listener = *listIt;
|
||||
|
||||
// Add listen on dht
|
||||
listener.internalToken = dht_->listen(infoHash,
|
||||
[this, infoHash, pushToken, isAndroid, clientId, sessionCtx = listener.sessionCtx]
|
||||
(const std::vector<std::shared_ptr<Value>>& values, bool expired){
|
||||
// Build message content
|
||||
Json::Value json;
|
||||
json["key"] = infoHash.toString();
|
||||
json["to"] = clientId;
|
||||
json["t"] = Json::Value::Int64(std::chrono::duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count());
|
||||
{
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
json["s"] = sessionCtx->sessionId;
|
||||
}
|
||||
if (expired and values.size() < 2){
|
||||
std::stringstream ss;
|
||||
for(size_t i = 0; i < values.size(); ++i){
|
||||
if(i != 0) ss << ",";
|
||||
ss << values[i]->id;
|
||||
}
|
||||
json["exp"] = ss.str();
|
||||
}
|
||||
auto maxPrio = 1000u;
|
||||
for (const auto& v : values)
|
||||
maxPrio = std::min(maxPrio, v->priority);
|
||||
sendPushNotification(pushToken, std::move(json), isAndroid, !expired and maxPrio == 0);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// expire notify
|
||||
if (!listener.expireNotifyTimer)
|
||||
listener.expireNotifyTimer = std::make_unique<asio::steady_timer>(io_context(), timeout - proxy::OP_MARGIN);
|
||||
else
|
||||
// Expiration
|
||||
auto timeout = std::chrono::steady_clock::now() + proxy::OP_TIMEOUT;
|
||||
listener.expiration = timeout;
|
||||
listener.type = type;
|
||||
if (listener.expireNotifyTimer)
|
||||
listener.expireNotifyTimer->expires_at(timeout - proxy::OP_MARGIN);
|
||||
auto jsonProvider = [infoHash, clientId, sessionCtx = listener.sessionCtx](){
|
||||
else
|
||||
listener.expireNotifyTimer = std::make_unique<asio::steady_timer>(io_context(), timeout - proxy::OP_MARGIN);
|
||||
auto jsonProvider = [h=infoHash.toString(), clientId, sessionCtx = listener.sessionCtx](){
|
||||
Json::Value json;
|
||||
json["timeout"] = infoHash.toString();
|
||||
json["timeout"] = h;
|
||||
json["to"] = clientId;
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
json["s"] = sessionCtx->sessionId;
|
||||
return json;
|
||||
};
|
||||
listener.expireNotifyTimer->async_wait(std::bind(&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), isAndroid));
|
||||
// cancel push listen
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), listener.type));
|
||||
if (!listener.expireTimer)
|
||||
listener.expireTimer = std::make_unique<asio::steady_timer>(io_context(), timeout);
|
||||
else
|
||||
listener.expireTimer->expires_at(timeout);
|
||||
listener.expireTimer->async_wait(std::bind(&DhtProxyServer::handleCancelPushListen, this,
|
||||
std::placeholders::_1, pushToken, infoHash, clientId));
|
||||
auto response = initHttpResponse(request->create_response());
|
||||
response.set_body("{}\n");
|
||||
return response.done();
|
||||
std::placeholders::_1, pushToken, infoHash, clientId));
|
||||
|
||||
// Send response
|
||||
if (not newListener) {
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [subscribe] found [client %s]", listener.clientId.c_str());
|
||||
// Send response header
|
||||
auto response = std::make_shared<ResponseByPartsBuilder>(initHttpResponse(request->create_response<ResponseByParts>()));
|
||||
response->flush();
|
||||
if (!root["refresh"].asBool()) {
|
||||
// No Refresh
|
||||
dht_->get(infoHash, [this, response](const Sp<Value>& value){
|
||||
auto output = Json::writeString(jsonBuilder_, value->toJson()) + "\n";
|
||||
response->append_chunk(output);
|
||||
response->flush();
|
||||
return true;
|
||||
},
|
||||
[response] (bool){
|
||||
response->done();
|
||||
});
|
||||
} else {
|
||||
// Refresh
|
||||
response->append_chunk("{}\n");
|
||||
return response->done();
|
||||
}
|
||||
} else {
|
||||
// =========== No existing listener for an infoHash ============
|
||||
// Add listen on dht
|
||||
listener.internalToken = dht_->listen(infoHash,
|
||||
[this, infoHash, pushToken, type, clientId, sessionCtx = listener.sessionCtx]
|
||||
(const std::vector<std::shared_ptr<Value>>& values, bool expired){
|
||||
// Build message content
|
||||
Json::Value json;
|
||||
json["key"] = infoHash.toString();
|
||||
json["to"] = clientId;
|
||||
json["t"] = Json::Value::Int64(std::chrono::duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count());
|
||||
{
|
||||
std::lock_guard<std::mutex> l(sessionCtx->lock);
|
||||
json["s"] = sessionCtx->sessionId;
|
||||
}
|
||||
if (expired and values.size() < 2){
|
||||
std::stringstream ss;
|
||||
for(size_t i = 0; i < values.size(); ++i){
|
||||
if(i != 0) ss << ",";
|
||||
ss << values[i]->id;
|
||||
}
|
||||
json["exp"] = ss.str();
|
||||
}
|
||||
auto maxPrio = 1000u;
|
||||
for (const auto& v : values)
|
||||
maxPrio = std::min(maxPrio, v->priority);
|
||||
sendPushNotification(pushToken, std::move(json), type, !expired and maxPrio == 0);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
auto response = initHttpResponse(request->create_response());
|
||||
response.set_body("{}\n");
|
||||
return response.done();
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return serverError(*request);
|
||||
@@ -731,9 +893,9 @@ DhtProxyServer::unsubscribe(restinio::request_handle_t request,
|
||||
{
|
||||
requestNum_++;
|
||||
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [unsubscribe %s]", infoHash.toString().c_str());
|
||||
@@ -766,7 +928,7 @@ DhtProxyServer::unsubscribe(restinio::request_handle_t request,
|
||||
|
||||
void
|
||||
DhtProxyServer::handleNotifyPushListenExpire(const asio::error_code &ec, const std::string pushToken,
|
||||
std::function<Json::Value()> jsonProvider, const bool isAndroid)
|
||||
std::function<Json::Value()> jsonProvider, PushType type)
|
||||
{
|
||||
if (ec == asio::error::operation_aborted)
|
||||
return;
|
||||
@@ -776,7 +938,7 @@ DhtProxyServer::handleNotifyPushListenExpire(const asio::error_code &ec, const s
|
||||
}
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [subscribe] sending put refresh to %s token", pushToken.c_str());
|
||||
sendPushNotification(pushToken, jsonProvider(), isAndroid, false);
|
||||
sendPushNotification(pushToken, jsonProvider(), type, false);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -818,7 +980,7 @@ DhtProxyServer::handleCancelPushListen(const asio::error_code &ec, const std::st
|
||||
}
|
||||
|
||||
void
|
||||
DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& json, bool isAndroid, bool highPriority)
|
||||
DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& json, PushType type, bool highPriority)
|
||||
{
|
||||
if (pushServer_.empty())
|
||||
return;
|
||||
@@ -840,10 +1002,16 @@ DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& jso
|
||||
Json::Value tokens(Json::arrayValue);
|
||||
tokens[0] = token;
|
||||
notification["tokens"] = std::move(tokens);
|
||||
notification["platform"] = isAndroid ? 2 : 1;
|
||||
notification["platform"] = type == PushType::Android ? 2 : 1;
|
||||
notification["data"] = std::move(json);
|
||||
notification["priority"] = highPriority ? "high" : "normal";
|
||||
notification["time_to_live"] = 600;
|
||||
if (type == PushType::Android)
|
||||
notification["time_to_live"] = 3600 * 24; // 24 hours
|
||||
else {
|
||||
const auto expiration = std::chrono::system_clock::now() + std::chrono::hours(24);
|
||||
uint32_t exp = std::chrono::duration_cast<std::chrono::seconds>(expiration.time_since_epoch()).count();
|
||||
notification["expiration"] = exp;
|
||||
}
|
||||
|
||||
Json::Value notifications(Json::arrayValue);
|
||||
notifications[0] = notification;
|
||||
@@ -889,6 +1057,7 @@ DhtProxyServer::handleCancelPermamentPut(const asio::error_code &ec, const InfoH
|
||||
}
|
||||
if (logger_)
|
||||
logger_->d("[proxy:server] [put %s] cancel permament put %i", key.toString().c_str(), vid);
|
||||
std::lock_guard<std::mutex> lock(lockSearchPuts_);
|
||||
auto sPuts = puts_.find(key);
|
||||
if (sPuts == puts_.end())
|
||||
return;
|
||||
@@ -898,6 +1067,8 @@ DhtProxyServer::handleCancelPermamentPut(const asio::error_code &ec, const InfoH
|
||||
return;
|
||||
if (dht_)
|
||||
dht_->cancelPut(key, vid);
|
||||
if (put->second.expireTimer)
|
||||
put->second.expireTimer->cancel();
|
||||
if (put->second.expireNotifyTimer)
|
||||
put->second.expireNotifyTimer->cancel();
|
||||
sPutsMap.erase(put);
|
||||
@@ -910,9 +1081,9 @@ DhtProxyServer::put(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params)
|
||||
{
|
||||
requestNum_++;
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
|
||||
if (request->body().empty()){
|
||||
auto response = initHttpResponse(request->create_response(restinio::status_bad_request()));
|
||||
@@ -941,13 +1112,13 @@ DhtProxyServer::put(restinio::request_handle_t request,
|
||||
platform = pVal["platform"].asString();
|
||||
sessionId = pVal["session_id"].asString();
|
||||
}
|
||||
std::unique_lock<std::mutex> lock(lockSearchPuts_);
|
||||
std::lock_guard<std::mutex> lock(lockSearchPuts_);
|
||||
auto timeout = std::chrono::steady_clock::now() + proxy::OP_TIMEOUT;
|
||||
auto& sPuts = puts_[infoHash];
|
||||
if (value->id == Value::INVALID_ID) {
|
||||
for (auto& pp : sPuts.puts) {
|
||||
if (pp.second.pushToken == pushToken
|
||||
and pp.second.clientId == clientId
|
||||
if (pp.second.pushToken == pushToken
|
||||
and pp.second.clientId == clientId
|
||||
and pp.second.value->contentEquals(*value))
|
||||
{
|
||||
pp.second.expireTimer->expires_at(timeout);
|
||||
@@ -955,32 +1126,36 @@ DhtProxyServer::put(restinio::request_handle_t request,
|
||||
std::placeholders::_1, infoHash, pp.second.value->id));
|
||||
if (not sessionId.empty()) {
|
||||
if (not pp.second.sessionCtx)
|
||||
pp.second.sessionCtx = std::make_shared<PushSessionContext>();
|
||||
std::lock_guard<std::mutex> l(pp.second.sessionCtx->lock);
|
||||
pp.second.sessionCtx->sessionId = sessionId;
|
||||
pp.second.sessionCtx = std::make_shared<PushSessionContext>(sessionId);
|
||||
else {
|
||||
std::lock_guard<std::mutex> l(pp.second.sessionCtx->lock);
|
||||
pp.second.sessionCtx->sessionId = sessionId;
|
||||
}
|
||||
}
|
||||
auto response = initHttpResponse(request->create_response());
|
||||
response.append_body(Json::writeString(jsonBuilder_, value->toJson()) + "\n");
|
||||
return response.done();
|
||||
}
|
||||
}
|
||||
value->id = std::uniform_int_distribution<Value::Id>{1}(rd);
|
||||
}
|
||||
|
||||
auto vid = value->id;
|
||||
auto& pput = sPuts.puts[vid];
|
||||
pput.value = value;
|
||||
pput.expiration = timeout;
|
||||
if (not pput.expireTimer) {
|
||||
auto &ctx = io_context();
|
||||
// cancel permanent put
|
||||
pput.expireTimer = std::make_unique<asio::steady_timer>(ctx, timeout);
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
if (not pushToken.empty()){
|
||||
bool isAndroid = platform == "android";
|
||||
pput.pushToken = pushToken;
|
||||
pput.clientId = clientId;
|
||||
pput.sessionCtx = std::make_shared<PushSessionContext>();
|
||||
pput.sessionCtx->sessionId = sessionId;
|
||||
pput.type = isAndroid ? PushType::Android : PushType::iOS;
|
||||
pput.sessionCtx = std::make_shared<PushSessionContext>(sessionId);
|
||||
// notify push listen expire
|
||||
bool isAndroid = platform == "android";
|
||||
auto jsonProvider = [infoHash, clientId, vid, sessionCtx = pput.sessionCtx](){
|
||||
Json::Value json;
|
||||
json["timeout"] = infoHash.toString();
|
||||
@@ -997,15 +1172,17 @@ DhtProxyServer::put(restinio::request_handle_t request,
|
||||
pput.expireNotifyTimer->expires_at(timeout - proxy::OP_MARGIN);
|
||||
pput.expireNotifyTimer->async_wait(std::bind(
|
||||
&DhtProxyServer::handleNotifyPushListenExpire, this,
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), isAndroid));
|
||||
std::placeholders::_1, pushToken, std::move(jsonProvider), pput.type));
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (not sessionId.empty()) {
|
||||
if (not pput.sessionCtx)
|
||||
pput.sessionCtx = std::make_shared<PushSessionContext>();
|
||||
std::lock_guard<std::mutex> l(pput.sessionCtx->lock);
|
||||
pput.sessionCtx->sessionId = sessionId;
|
||||
pput.sessionCtx = std::make_shared<PushSessionContext>(sessionId);
|
||||
else {
|
||||
std::lock_guard<std::mutex> l(pput.sessionCtx->lock);
|
||||
pput.sessionCtx->sessionId = sessionId;
|
||||
}
|
||||
}
|
||||
pput.expireTimer->expires_at(timeout);
|
||||
if (pput.expireNotifyTimer)
|
||||
@@ -1045,9 +1222,9 @@ DhtProxyServer::putSigned(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params) const
|
||||
{
|
||||
requestNum_++;
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
|
||||
if (request->body().empty()){
|
||||
auto response = initHttpResponse(request->create_response(restinio::status_bad_request()));
|
||||
@@ -1095,9 +1272,9 @@ DhtProxyServer::putEncrypted(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params)
|
||||
{
|
||||
requestNum_++;
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
|
||||
if (request->body().empty()){
|
||||
auto response = initHttpResponse(request->create_response(restinio::status_bad_request()));
|
||||
@@ -1167,10 +1344,10 @@ DhtProxyServer::getFiltered(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params)
|
||||
{
|
||||
requestNum_++;
|
||||
auto value = params["value"].to_string();
|
||||
InfoHash infoHash(params["hash"].to_string());
|
||||
auto query = params["value"];
|
||||
InfoHash infoHash(params["hash"]);
|
||||
if (!infoHash)
|
||||
infoHash = InfoHash::get(params["hash"].to_string());
|
||||
infoHash = InfoHash::get(params["hash"]);
|
||||
|
||||
try {
|
||||
auto response = std::make_shared<ResponseByPartsBuilder>(
|
||||
@@ -1185,7 +1362,7 @@ DhtProxyServer::getFiltered(restinio::request_handle_t request,
|
||||
[response] (bool /*ok*/){
|
||||
response->done();
|
||||
},
|
||||
{}, value);
|
||||
{}, query);
|
||||
return restinio::request_handling_status_t::accepted;
|
||||
} catch (const std::exception& e){
|
||||
return serverError(*request);
|
||||
|
||||
Loaded 100 of 154 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user