mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 12:28:42 +00:00
Compare commits
591
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c29848ba1 | ||
|
|
c1e2a368a8 | ||
|
|
c62f27c929 | ||
|
|
ec0c3d4d25 | ||
|
|
17a1178054 | ||
|
|
6256c576c9 | ||
|
|
9565adf693 | ||
|
|
c10aa32596 | ||
|
|
21c294f352 | ||
|
|
4654f78e08 | ||
|
|
38644fc934 | ||
|
|
fa8dc4c835 | ||
|
|
6dab10cac2 | ||
|
|
77a1c27f2b | ||
|
|
e8577bfd05 | ||
|
|
c0327a9881 | ||
|
|
2a1eacc949 | ||
|
|
e705bebc25 | ||
|
|
a330762f40 | ||
|
|
e7972ae897 | ||
|
|
8d2d40cb7f | ||
|
|
aceb548c26 | ||
|
|
afce4639e1 | ||
|
|
e5d248bcd0 | ||
|
|
0fbebf8e03 | ||
|
|
24efa37846 | ||
|
|
c0f14ca59d | ||
|
|
05a66cc1f1 | ||
|
|
ed6df8869c | ||
|
|
b7d410e1aa | ||
|
|
77a377a406 | ||
|
|
e0b6f152f1 | ||
|
|
dd3c789916 | ||
|
|
333087bcba | ||
|
|
5b87090cab | ||
|
|
fffee634f1 | ||
|
|
c4aa272dbb | ||
|
|
4ce78bdb4d | ||
|
|
f331f39c77 | ||
|
|
17fb92654e | ||
|
|
294034f00f | ||
|
|
36857c1f3d | ||
|
|
7e9f5303bd | ||
|
|
c2780b1ca9 | ||
|
|
16b798324d | ||
|
|
bc850bf00c | ||
|
|
0d8d302128 | ||
|
|
97013badfa | ||
|
|
31185c24f0 | ||
|
|
2f6f8e2ac1 | ||
|
|
8f141951ce | ||
|
|
43d111b7dc | ||
|
|
620ba2a89b | ||
|
|
d1598380db | ||
|
|
69fe399db0 | ||
|
|
a60dde2e13 | ||
|
|
201982b1a9 | ||
|
|
83f2b272a7 | ||
|
|
7e47d0458a | ||
|
|
f6d26757fa | ||
|
|
476d0bca4f | ||
|
|
259986e786 | ||
|
|
8ff0c979d4 | ||
|
|
913cb543c8 | ||
|
|
b380c9ffba | ||
|
|
8c717085b4 | ||
|
|
48742a1058 | ||
|
|
fe11285a03 | ||
|
|
fb34770a54 | ||
|
|
4a909419e9 | ||
|
|
dab7099369 | ||
|
|
9c84e59bbf | ||
|
|
eae383b3ed | ||
|
|
28bf78408d | ||
|
|
7ed6f74e6b | ||
|
|
cf6d9fd8c2 | ||
|
|
5df34bb752 | ||
|
|
bebb66490d | ||
|
|
5f361748eb | ||
|
|
984745624c | ||
|
|
f9e860fdc8 | ||
|
|
06ea3d23e5 | ||
|
|
f0857a5925 | ||
|
|
5a993fb902 | ||
|
|
8a18c591e9 | ||
|
|
9daa7ec283 | ||
|
|
01f2ad9ea4 | ||
|
|
2dd4cde035 | ||
|
|
cb0005d0eb | ||
|
|
eca340b785 | ||
|
|
cdd035b801 | ||
|
|
cb7d7f6614 | ||
|
|
f5a6801ab9 | ||
|
|
0049ba92e6 | ||
|
|
7838e7de0b | ||
|
|
e2d7dbc293 | ||
|
|
090da49fed | ||
|
|
22594396d2 | ||
|
|
0c8d0e2e0d | ||
|
|
18793cee3b | ||
|
|
0bde82a218 | ||
|
|
bc84655f42 | ||
|
|
ed642b0337 | ||
|
|
f710df9675 | ||
|
|
42398a541d | ||
|
|
429a5ad1d4 | ||
|
|
01bc43af35 | ||
|
|
555487012b | ||
|
|
697d554edb | ||
|
|
8edd67834c | ||
|
|
80f04430c3 | ||
|
|
e4853bd29c | ||
|
|
6863800cfb | ||
|
|
1f387a0e95 | ||
|
|
142aee12a7 | ||
|
|
95a65ce565 | ||
|
|
144fa7ddc8 | ||
|
|
b77fd2336f | ||
|
|
c0e117871e | ||
|
|
3c88eaa602 | ||
|
|
8d131449a8 | ||
|
|
fee7e5dd30 | ||
|
|
4c2a974433 | ||
|
|
a483205976 | ||
|
|
96df1d4339 | ||
|
|
432f387423 | ||
|
|
3abb9114ba | ||
|
|
727c5f0e8c | ||
|
|
f86abfaf22 | ||
|
|
f84131c820 | ||
|
|
28de983166 | ||
|
|
4b28278cb1 | ||
|
|
653a4309bd | ||
|
|
48b763f11b | ||
|
|
cbfa12a921 | ||
|
|
3e0d4cd703 | ||
|
|
4bff6d392a | ||
|
|
712b7218a9 | ||
|
|
5a8e252e32 | ||
|
|
b5be4549dc | ||
|
|
bf8fb6f321 | ||
|
|
08cf212c53 | ||
|
|
fc2a597bb2 | ||
|
|
7212b7a28b | ||
|
|
5c610895fe | ||
|
|
a567ca1dc1 | ||
|
|
97b20705a1 | ||
|
|
431da16ba6 | ||
|
|
09818d779e | ||
|
|
934e36ba13 | ||
|
|
2e47b9bab5 | ||
|
|
f938d486d5 | ||
|
|
76b4da089e | ||
|
|
2a72277194 | ||
|
|
e8d96d3b42 | ||
|
|
c92d236c1b | ||
|
|
b680407e9a | ||
|
|
6caf4b0d0b | ||
|
|
7f65fdc7f9 | ||
|
|
b00dfdf572 | ||
|
|
2b1d2fc3f6 | ||
|
|
a0566cf695 | ||
|
|
a3f2b055a1 | ||
|
|
01bf8f9303 | ||
|
|
22741436e3 | ||
|
|
d958b0ea5f | ||
|
|
6c96a47f13 | ||
|
|
15403c0f6e | ||
|
|
0eee567c4e | ||
|
|
e8843076d9 | ||
|
|
3a6ce2f499 | ||
|
|
299e632795 | ||
|
|
12aee01ffe | ||
|
|
83c5014a36 | ||
|
|
e9377f2eb6 | ||
|
|
083a28f5d8 | ||
|
|
ab7f36ff85 | ||
|
|
8856a70af5 | ||
|
|
f24b6ca3e3 | ||
|
|
ccfb76d9b4 | ||
|
|
104a9e3b28 | ||
|
|
d77c868c55 | ||
|
|
347f404a92 | ||
|
|
ed1b0220e5 | ||
|
|
739f4d0c0d | ||
|
|
8ec0ab0ae4 | ||
|
|
55c56a5203 | ||
|
|
7558444ae0 | ||
|
|
9bc2ceca68 | ||
|
|
ac10afac44 | ||
|
|
128af52ea2 | ||
|
|
8ed2bf50b3 | ||
|
|
dcdfeb0415 | ||
|
|
833dc7f5a7 | ||
|
|
d0510dcb72 | ||
|
|
6f87e9dbc3 | ||
|
|
223260bc7d | ||
|
|
c564810b8c | ||
|
|
f9ffb8650a | ||
|
|
e58fc4ef31 | ||
|
|
7fde8f63a8 | ||
|
|
166b5e352c | ||
|
|
77356b0539 | ||
|
|
c7d633e609 | ||
|
|
2576d95aa0 | ||
|
|
b31a29ea26 | ||
|
|
833bd069f4 | ||
|
|
39a186c47d | ||
|
|
c03af5f5a8 | ||
|
|
b03a7732e3 | ||
|
|
87f6f3df8b | ||
|
|
7270c353df | ||
|
|
63afc8c29a | ||
|
|
6a760a629c | ||
|
|
5068de7bc0 | ||
|
|
2a5f786f8b | ||
|
|
c690d060f9 | ||
|
|
bcf8ab5404 | ||
|
|
f7c8168f99 | ||
|
|
c37f0083d3 | ||
|
|
29e7768c9d | ||
|
|
72a06b1425 | ||
|
|
e4dacc64b5 | ||
|
|
20df5fe845 | ||
|
|
5b4f40229d | ||
|
|
6c4af9bfea | ||
|
|
ef26155b19 | ||
|
|
eb2269625f | ||
|
|
70c92d6cea | ||
|
|
fd7f644531 | ||
|
|
562bf7124c | ||
|
|
5b344cada7 | ||
|
|
7c4450fdb1 | ||
|
|
9b8358cdf1 | ||
|
|
7ae3b3af5b | ||
|
|
06d1865446 | ||
|
|
83495a94db | ||
|
|
8ee5485767 | ||
|
|
e7742489ca | ||
|
|
99fc97f3cf | ||
|
|
82d5db81e0 | ||
|
|
fbb90a71b7 | ||
|
|
316f3ccfa0 | ||
|
|
185158f460 | ||
|
|
baa9fcf820 | ||
|
|
04a383c4fb | ||
|
|
b7b6fb802d | ||
|
|
9575f84081 | ||
|
|
0b0442bd02 | ||
|
|
251fe8bf2f | ||
|
|
c211055bf9 | ||
|
|
fafe97194a | ||
|
|
d214bfebf5 | ||
|
|
d551b8a54c | ||
|
|
4a8397d71b | ||
|
|
366f76986f | ||
|
|
8072092b67 | ||
|
|
624f36467e | ||
|
|
561a660693 | ||
|
|
414e0a2e60 | ||
|
|
e0393ff8ad | ||
|
|
d26bfc58d8 | ||
|
|
d50aae0751 | ||
|
|
1a79ae45e4 | ||
|
|
c6f830f54d | ||
|
|
f018610ec9 | ||
|
|
119c162f49 | ||
|
|
144e254c40 | ||
|
|
6cc84312aa | ||
|
|
b3a7bdd880 | ||
|
|
a797ea9171 | ||
|
|
023b4aff61 | ||
|
|
86429aa360 | ||
|
|
fbea6afe5d | ||
|
|
18bcad33bd | ||
|
|
8bc43b4e47 | ||
|
|
25f3000a78 | ||
|
|
96992b803c | ||
|
|
500ae6ef54 | ||
|
|
b01d3cfca5 | ||
|
|
49f6dd3c9c | ||
|
|
4054ec6af0 | ||
|
|
3345c1b048 | ||
|
|
4b061d0886 | ||
|
|
c1f805e6e2 | ||
|
|
25c9375d95 | ||
|
|
84a9d899d5 | ||
|
|
7ea40c292b | ||
|
|
2954158bba | ||
|
|
3382195760 | ||
|
|
b67149c98c | ||
|
|
f34cb6440f | ||
|
|
9cf37eb865 | ||
|
|
c8bed06641 | ||
|
|
51aef18885 | ||
|
|
49a132a54b | ||
|
|
235c48c400 | ||
|
|
5465b08d76 | ||
|
|
a8e24e505d | ||
|
|
5c0a8986a7 | ||
|
|
460205eb78 | ||
|
|
208758ede3 | ||
|
|
de9e0906de | ||
|
|
692304c2e3 | ||
|
|
f837c13e31 | ||
|
|
5812b24d56 | ||
|
|
a72ddfdb03 | ||
|
|
e7b03e4d53 | ||
|
|
baf43d96ff | ||
|
|
0f9df9a62b | ||
|
|
630112601c | ||
|
|
b0500af062 | ||
|
|
6c985e8fda | ||
|
|
9c1e55279c | ||
|
|
593d024f51 | ||
|
|
a6e57d95d6 | ||
|
|
846f495202 | ||
|
|
6f603bfc0a | ||
|
|
9c106f9efe | ||
|
|
ff288fb4a3 | ||
|
|
17ff4c0224 | ||
|
|
45a2c6dadb | ||
|
|
477ff59e91 | ||
|
|
a001e0cafd | ||
|
|
ac63527e0b | ||
|
|
4b3d8d1231 | ||
|
|
d04a741d5e | ||
|
|
ac2b7deda8 | ||
|
|
c8b08b5ed1 | ||
|
|
f556987e47 | ||
|
|
2daf36c97e | ||
|
|
2a2555f0c2 | ||
|
|
bdfb0148e4 | ||
|
|
01be4d2eb8 | ||
|
|
93f7251805 | ||
|
|
a8718242cd | ||
|
|
297a23fb1f | ||
|
|
0d641161e8 | ||
|
|
27b3c0d47e | ||
|
|
149b33ef57 | ||
|
|
150e62de0b | ||
|
|
89bdfce840 | ||
|
|
bce41ecd69 | ||
|
|
4374d206ab | ||
|
|
b64820af59 | ||
|
|
0e509318bb | ||
|
|
bcc2baa94a | ||
|
|
bbed9d530d | ||
|
|
5a3612be98 | ||
|
|
8202c1f7d7 | ||
|
|
a200b0e14c | ||
|
|
bd32edc6c5 | ||
|
|
d0d3ef7394 | ||
|
|
712da15ae2 | ||
|
|
fcdc997d29 | ||
|
|
cf18effebb | ||
|
|
b8c2ff8a11 | ||
|
|
1fad1b9ce3 | ||
|
|
117fedb641 | ||
|
|
422f5a6c45 | ||
|
|
51a42aa2c8 | ||
|
|
be0baefee8 | ||
|
|
2ac5157ab8 | ||
|
|
fbe8834e04 | ||
|
|
89ff131750 | ||
|
|
feb498305f | ||
|
|
b00f56c94a | ||
|
|
2067cb052f | ||
|
|
51aeaeaeab | ||
|
|
c0bb8f065c | ||
|
|
126318956a | ||
|
|
9014c0a7bb | ||
|
|
728782921c | ||
|
|
d438d4ef1b | ||
|
|
2959709462 | ||
|
|
4a26168248 | ||
|
|
9c348b1df4 | ||
|
|
7e7654d1ae | ||
|
|
69ee1d212a | ||
|
|
21ec9129c3 | ||
|
|
b7185fa87c | ||
|
|
54acd67a1f | ||
|
|
045de8602c | ||
|
|
390fa48700 | ||
|
|
0d08f0d356 | ||
|
|
738424b1ae | ||
|
|
d123d8f768 | ||
|
|
a20a48506d | ||
|
|
063a2b4860 | ||
|
|
829d365475 | ||
|
|
11e6671e60 | ||
|
|
6fe473d3cc | ||
|
|
9f493b9572 | ||
|
|
2164c5ddc7 | ||
|
|
a57a4d55e8 | ||
|
|
b98cc78b42 | ||
|
|
789d41ff07 | ||
|
|
632403875c | ||
|
|
bc2737cdc9 | ||
|
|
0c6bfde1c5 | ||
|
|
cfeeaf7950 | ||
|
|
e31ebfea32 | ||
|
|
07efe8c76e | ||
|
|
5c78bf386d | ||
|
|
86088b043b | ||
|
|
fad8bb1631 | ||
|
|
9a56c099a1 | ||
|
|
8298c0c868 | ||
|
|
971f590941 | ||
|
|
1813d83273 | ||
|
|
e87d164f0b | ||
|
|
b9604807ea | ||
|
|
9f12b44179 | ||
|
|
0772d5435c | ||
|
|
368ee9e22e | ||
|
|
dd56bdd8e2 | ||
|
|
71b36e0643 | ||
|
|
61b43759df | ||
|
|
96e12e88c3 | ||
|
|
8da933c01a | ||
|
|
20c0069867 | ||
|
|
8942e0d00e | ||
|
|
bc760f9348 | ||
|
|
59702190a7 | ||
|
|
cb3e94d0be | ||
|
|
ab7b8f6027 | ||
|
|
6e5231047b | ||
|
|
777505434c | ||
|
|
18c3161261 | ||
|
|
1060038bdf | ||
|
|
9d427a6a80 | ||
|
|
f1dbac2aff | ||
|
|
a63c5d172b | ||
|
|
9c6de8cc16 | ||
|
|
fe9de44867 | ||
|
|
4bfd6bb545 | ||
|
|
120c017399 | ||
|
|
7fc7597564 | ||
|
|
f8d62dc6a7 | ||
|
|
fc3686d817 | ||
|
|
a692f7fbe2 | ||
|
|
cb349d9cf6 | ||
|
|
6266f88cd5 | ||
|
|
0a3320e2c8 | ||
|
|
d6ad67d8e2 | ||
|
|
19d0aa55f7 | ||
|
|
941e53425f | ||
|
|
10971f700f | ||
|
|
2e7767d192 | ||
|
|
baf811bfe9 | ||
|
|
76f0672e63 | ||
|
|
330ad8ed12 | ||
|
|
3252e6daa3 | ||
|
|
07599239a6 | ||
|
|
eac61678f4 | ||
|
|
078c1198b0 | ||
|
|
3d525030b9 | ||
|
|
3733fc2890 | ||
|
|
c40f35fa06 | ||
|
|
13661929d1 | ||
|
|
4e934f8902 | ||
|
|
125a05a5fc | ||
|
|
868c114bcb | ||
|
|
f0acc3e735 | ||
|
|
171e2b130b | ||
|
|
cb5a261b82 | ||
|
|
feb8bd0d4f | ||
|
|
3955368c01 | ||
|
|
b841ff1b83 | ||
|
|
7a04c0eb66 | ||
|
|
fe1659bd2f | ||
|
|
b90e14edd6 | ||
|
|
9e3e9e65e6 | ||
|
|
1c3132e0ef | ||
|
|
f3e304e661 | ||
|
|
2545282624 | ||
|
|
52c413f056 | ||
|
|
ab082543ea | ||
|
|
ff6be81929 | ||
|
|
bd994384f0 | ||
|
|
598e38dbf4 | ||
|
|
b1a35b82a2 | ||
|
|
e4516772ee | ||
|
|
c7844fc320 | ||
|
|
c7e2483160 | ||
|
|
37b12c114d | ||
|
|
77bd34ad9c | ||
|
|
44490bd9ca | ||
|
|
ca01568824 | ||
|
|
2b259639d2 | ||
|
|
84d322e428 | ||
|
|
6d5e3d8cd2 | ||
|
|
b56518f258 | ||
|
|
d807af3951 | ||
|
|
5f393490a5 | ||
|
|
efe869fe42 | ||
|
|
a31cecdeac | ||
|
|
4a4becdbec | ||
|
|
eef2838a12 | ||
|
|
a520657fac | ||
|
|
29003700db | ||
|
|
b143bc459d | ||
|
|
4d6e5ab877 | ||
|
|
248d2e3f73 | ||
|
|
0692bd9bc9 | ||
|
|
7f48c4808b | ||
|
|
32a443a1d8 | ||
|
|
6d0fcba3b5 | ||
|
|
76e2efb19b | ||
|
|
bbe1b9233f | ||
|
|
7558ca0dca | ||
|
|
38141322f1 | ||
|
|
6c5ea125ca | ||
|
|
d0362e58e0 | ||
|
|
1b3a40f345 | ||
|
|
38d854e6f4 | ||
|
|
e0241ccfbd | ||
|
|
d4311925b4 | ||
|
|
9aa56dd464 | ||
|
|
ec3b259ead | ||
|
|
332cab10ef | ||
|
|
85f2b618c7 | ||
|
|
bcf18fda53 | ||
|
|
6b78a4cad6 | ||
|
|
66d3a8aeaa | ||
|
|
958cb250a3 | ||
|
|
6a5724a868 | ||
|
|
11ac84de54 | ||
|
|
f65e8c1a1f | ||
|
|
c2fdf6ae92 | ||
|
|
91a81f64ac | ||
|
|
17b772e6cc | ||
|
|
75738ac28b | ||
|
|
84a2d771c1 | ||
|
|
f6273f9efc | ||
|
|
5881c91510 | ||
|
|
e09c55ca42 | ||
|
|
c737e4690e | ||
|
|
35a9d1f612 | ||
|
|
0f3396cd66 | ||
|
|
98cd6cc61e | ||
|
|
092cb9551e | ||
|
|
a2bbca792c | ||
|
|
5ec72e213e | ||
|
|
0f51115f44 | ||
|
|
683a111726 | ||
|
|
0fd4fed537 | ||
|
|
18aa6ddb7b | ||
|
|
0a436e17b0 | ||
|
|
763ffddf51 | ||
|
|
ef82652a1e | ||
|
|
4f03a5c64e | ||
|
|
5257ac314f | ||
|
|
0580a4e7dd | ||
|
|
fd1f2cd0e4 | ||
|
|
af940c63b1 | ||
|
|
15da502354 | ||
|
|
b7a9a52f97 | ||
|
|
6e10756e28 | ||
|
|
aad4ad03cf | ||
|
|
3d1e055c7b | ||
|
|
b02e9cfff7 | ||
|
|
453db29058 | ||
|
|
a8ba536d44 | ||
|
|
a238183031 | ||
|
|
73827cd34d | ||
|
|
876190a392 | ||
|
|
7fe321e4fc | ||
|
|
7f7075ca9a | ||
|
|
9b9f12d87e | ||
|
|
26ad6de3a4 | ||
|
|
ae91f8bd55 | ||
|
|
28eeee24ba | ||
|
|
671c55a01d | ||
|
|
a4f2e6efdd | ||
|
|
60831ee898 | ||
|
|
98dbe1cba7 | ||
|
|
6c705e525f | ||
|
|
96347d83e1 | ||
|
|
01d8e513a1 | ||
|
|
b5921b0d9d | ||
|
|
8ee7883c53 | ||
|
|
4240820463 | ||
|
|
7ebbf17f37 | ||
|
|
6821e5bd96 | ||
|
|
c4ec1e78e0 | ||
|
|
e86d717e81 | ||
|
|
db2b48d2af | ||
|
|
2b938110fd | ||
|
|
c647b19e91 | ||
|
|
8cd14646a6 |
No files matched your search
@@ -0,0 +1,34 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- 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
|
||||
- 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 \
|
||||
&& tar -xvf b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz && cd asio-b2b7a1c166390459e1c169c8ae9ef3234b361e3f/asio \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
|
||||
&& sudo make install \
|
||||
&& cd ../../ && rm -rf asio*
|
||||
- name: configure
|
||||
run: ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: make check
|
||||
run: make check
|
||||
@@ -46,6 +46,15 @@ Makefile.in
|
||||
.kdev4/
|
||||
*.kdev4
|
||||
|
||||
# VSCode
|
||||
.vscode/*
|
||||
|
||||
# Eclipse CDT
|
||||
.cproject
|
||||
.project
|
||||
.autotools
|
||||
language.settings.xml
|
||||
|
||||
# Python
|
||||
*.pyc
|
||||
*.stamp
|
||||
|
||||
+189
-66
@@ -1,80 +1,127 @@
|
||||
cmake_minimum_required (VERSION 3.1)
|
||||
project (opendht)
|
||||
set (opendht_VERSION_MAJOR 1)
|
||||
set (opendht_VERSION_MINOR 8.2)
|
||||
set (opendht_VERSION_MAJOR 2)
|
||||
set (opendht_VERSION_MINOR 0.0)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
|
||||
# Options
|
||||
option (OPENDHT_LIGHT "Build minimal version of the library" OFF)
|
||||
|
||||
option (OPENDHT_STATIC "Build static library" ON)
|
||||
|
||||
option (OPENDHT_SHARED "Build shared library" ON)
|
||||
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_SANITIZE "Build with address sanitizer and stack protector" OFF)
|
||||
option (OPENDHT_PROXY_SERVER "Enable DHT proxy server, use Restbed and jsoncpp" 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 Restbed and jsoncpp" 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)
|
||||
option (OPENDHT_PEER_DISCOVERY "Enable multicast peer discovery" ON)
|
||||
option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
|
||||
option (OPENDHT_C "Build C bindings" OFF)
|
||||
option (OPENDHT_TESTS "Add unit tests executable" OFF)
|
||||
|
||||
if (OPENDHT_LIGHT)
|
||||
set(OPENDHT_SHARED OFF)
|
||||
set(OPENDHT_TOOLS OFF)
|
||||
set(OPENDHT_PROXY_SERVER OFF)
|
||||
set(OPENDHT_PROXY_CLIENT OFF)
|
||||
set(OPENDHT_PEER_DISCOVERY OFF)
|
||||
set(OPENDHT_INDEX OFF)
|
||||
set(OPENDHT_PYTHON OFF)
|
||||
add_definitions(-DOPENDHT_LIGHT)
|
||||
endif()
|
||||
|
||||
option (OPENDHT_LOG "Build with logs" ON)
|
||||
option (OPENDHT_LTO "Build with LTO" OFF)
|
||||
option (OPENDHT_SANITIZE "Build with address sanitizer and stack protector" OFF)
|
||||
|
||||
find_package(Doxygen)
|
||||
option (OPENDHT_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND})
|
||||
|
||||
# Dependencies
|
||||
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("Argon2 found " ${argon2_req})
|
||||
set(argon2_lib ", libargon2")
|
||||
else ()
|
||||
message("Argon2 not found, using included version.")
|
||||
set(OPENDHT_ARGON2 ON)
|
||||
if (NOT OPENDHT_LIGHT)
|
||||
find_package (Threads)
|
||||
find_package (GnuTLS 3.3 REQUIRED)
|
||||
pkg_search_module (Nettle nettle)
|
||||
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)
|
||||
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()
|
||||
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_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
|
||||
find_package(Restbed REQUIRED)
|
||||
if (NOT Jsoncpp_FOUND)
|
||||
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
|
||||
if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
|
||||
find_package(Restinio REQUIRED)
|
||||
if (Restinio_FOUND)
|
||||
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")
|
||||
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_SERVER OR OPENDHT_PROXY_CLIENT OR OPENDHT_PEER_DISCOVERY)
|
||||
add_definitions(-DASIO_STANDALONE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Build flags
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
set (CMAKE_CXX_STANDARD 14)
|
||||
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")
|
||||
endif ()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT")
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif ()
|
||||
add_definitions(-DPACKAGE_VERSION="${opendht_VERSION}")
|
||||
if (OPENDHT_LOG)
|
||||
add_definitions(-DOPENDHT_LOG=true)
|
||||
else ()
|
||||
@@ -99,12 +146,15 @@ endif ()
|
||||
if (Nettle_INCLUDE_DIRS)
|
||||
include_directories (SYSTEM "${Nettle_INCLUDE_DIRS}")
|
||||
endif ()
|
||||
if (Restbed_INCLUDE_DIR)
|
||||
include_directories (SYSTEM "${Restbed_INCLUDE_DIR}")
|
||||
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})
|
||||
include_directories (
|
||||
@@ -128,7 +178,6 @@ set (top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
list (APPEND opendht_SOURCES
|
||||
src/utils.cpp
|
||||
src/infohash.cpp
|
||||
src/crypto.cpp
|
||||
src/default_types.cpp
|
||||
src/node.cpp
|
||||
src/value.cpp
|
||||
@@ -146,8 +195,6 @@ list (APPEND opendht_SOURCES
|
||||
src/routing_table.cpp
|
||||
src/node_cache.cpp
|
||||
src/network_engine.cpp
|
||||
src/securedht.cpp
|
||||
src/dhtrunner.cpp
|
||||
src/log.cpp
|
||||
)
|
||||
|
||||
@@ -156,7 +203,6 @@ list (APPEND opendht_HEADERS
|
||||
include/opendht/utils.h
|
||||
include/opendht/sockaddr.h
|
||||
include/opendht/rng.h
|
||||
include/opendht/crypto.h
|
||||
include/opendht/infohash.h
|
||||
include/opendht/default_types.h
|
||||
include/opendht/node.h
|
||||
@@ -175,6 +221,34 @@ list (APPEND opendht_HEADERS
|
||||
include/opendht.h
|
||||
)
|
||||
|
||||
if (NOT OPENDHT_LIGHT)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/crypto.cpp
|
||||
src/securedht.cpp
|
||||
src/dhtrunner.cpp
|
||||
src/network_utils.cpp
|
||||
src/thread_pool.cpp
|
||||
)
|
||||
|
||||
list (APPEND opendht_HEADERS
|
||||
include/opendht/crypto.h
|
||||
include/opendht/securedht.h
|
||||
include/opendht/dhtrunner.h
|
||||
include/opendht/thread_pool.h
|
||||
include/opendht/network_utils.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if (OPENDHT_PEER_DISCOVERY)
|
||||
list (APPEND opendht_SOURCES src/peer_discovery.cpp)
|
||||
list (APPEND opendht_HEADERS include/opendht/peer_discovery.h)
|
||||
add_definitions(-DOPENDHT_PEER_DISCOVERY)
|
||||
endif()
|
||||
|
||||
if (OPENDHT_PYTHON)
|
||||
message("Indexation enabled since it is required for Python support")
|
||||
set(OPENDHT_INDEX ON)
|
||||
endif()
|
||||
if (OPENDHT_INDEX)
|
||||
list (APPEND opendht_SOURCES src/indexation/pht.cpp)
|
||||
list (APPEND opendht_HEADERS include/opendht/indexation/pht.h)
|
||||
@@ -190,8 +264,6 @@ if (OPENDHT_PROXY_SERVER)
|
||||
include/opendht/dht_proxy_server.h
|
||||
)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/thread_pool.h
|
||||
src/thread_pool.cpp
|
||||
src/dht_proxy_server.cpp
|
||||
)
|
||||
endif ()
|
||||
@@ -213,6 +285,10 @@ if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
|
||||
endif ()
|
||||
list (APPEND opendht_HEADERS
|
||||
include/opendht/proxy.h
|
||||
include/opendht/http.h
|
||||
)
|
||||
list (APPEND opendht_SOURCES
|
||||
src/http.cpp
|
||||
)
|
||||
endif ()
|
||||
|
||||
@@ -246,8 +322,10 @@ if (OPENDHT_STATIC)
|
||||
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
|
||||
endif ()
|
||||
target_link_libraries(opendht-static
|
||||
PRIVATE ${Restbed_LIBRARY} ${argon2_LIBRARIES}
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES} ${Jsoncpp_LIBRARIES})
|
||||
PRIVATE ${argon2_LIBRARIES}
|
||||
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
|
||||
${Jsoncpp_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
|
||||
${OPENSSL_LIBRARIES})
|
||||
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
|
||||
endif ()
|
||||
|
||||
@@ -265,10 +343,37 @@ if (OPENDHT_SHARED)
|
||||
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
|
||||
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
|
||||
endif ()
|
||||
target_link_libraries(opendht PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES} ${Restbed_LIBRARY} ${Jsoncpp_LIBRARIES})
|
||||
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 ()
|
||||
|
||||
if (OPENDHT_C)
|
||||
add_library (opendht-c SHARED
|
||||
c/opendht.cpp
|
||||
c/opendht_c.h
|
||||
)
|
||||
target_compile_definitions(opendht-c PRIVATE OPENDHT_C_BUILD)
|
||||
if (OPENDHT_SHARED)
|
||||
target_link_libraries(opendht-c opendht)
|
||||
else ()
|
||||
target_link_libraries(opendht-c opendht-static)
|
||||
endif ()
|
||||
|
||||
# PkgConfig module
|
||||
configure_file (
|
||||
opendht-c.pc.in
|
||||
opendht-c.pc
|
||||
@ONLY
|
||||
)
|
||||
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)
|
||||
endif ()
|
||||
|
||||
if (OPENDHT_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif ()
|
||||
@@ -299,39 +404,57 @@ install (FILES ${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake DESTINATIO
|
||||
|
||||
# Unit tests
|
||||
if (OPENDHT_TESTS)
|
||||
FIND_PACKAGE(Cppunit REQUIRED)
|
||||
# unit testing
|
||||
FIND_PACKAGE(Cppunit REQUIRED)
|
||||
# unit testing
|
||||
list (APPEND test_FILES
|
||||
tests/infohashtester.h
|
||||
tests/infohashtester.cpp
|
||||
tests/valuetester.h
|
||||
tests/valuetester.cpp
|
||||
tests/cryptotester.h
|
||||
tests/cryptotester.cpp
|
||||
tests/dhtrunnertester.h
|
||||
tests/dhtrunnertester.cpp
|
||||
tests/infohashtester.h
|
||||
tests/infohashtester.cpp
|
||||
tests/valuetester.h
|
||||
tests/valuetester.cpp
|
||||
)
|
||||
if (NOT OPENDHT_LIGHT)
|
||||
list (APPEND test_FILES
|
||||
tests/cryptotester.h
|
||||
tests/cryptotester.cpp
|
||||
tests/dhtrunnertester.h
|
||||
tests/dhtrunnertester.cpp
|
||||
tests/threadpooltester.h
|
||||
tests/threadpooltester.cpp
|
||||
)
|
||||
endif()
|
||||
if (OPENDHT_PROXY_SERVER AND OPENDHT_PROXY_CLIENT)
|
||||
list (APPEND test_FILES
|
||||
tests/dhtproxytester.h
|
||||
tests/dhtproxytester.cpp
|
||||
)
|
||||
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()
|
||||
add_executable(opendht_unit_tests
|
||||
tests/tests_runner.cpp
|
||||
${test_FILES}
|
||||
tests/tests_runner.cpp
|
||||
${test_FILES}
|
||||
)
|
||||
target_include_directories(opendht_unit_tests SYSTEM PRIVATE ${CPPUNIT_INCLUDE_DIRS})
|
||||
if (OPENDHT_SHARED)
|
||||
target_link_libraries(opendht_unit_tests opendht)
|
||||
target_link_libraries(opendht_unit_tests opendht)
|
||||
else ()
|
||||
target_link_libraries(opendht_unit_tests opendht-static)
|
||||
target_link_libraries(opendht_unit_tests opendht-static)
|
||||
endif ()
|
||||
target_link_libraries(opendht_unit_tests
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${CPPUNIT_LIBRARIES}
|
||||
${GNUTLS_LIBRARIES}
|
||||
${Jsoncpp_LIBRARIES}
|
||||
)
|
||||
if (OPENDHT_PROXY_OPENSSL)
|
||||
target_link_libraries(opendht_unit_tests ${OPENSSL_LIBRARIES})
|
||||
endif()
|
||||
enable_testing()
|
||||
add_test(TEST opendht_unit_tests)
|
||||
endif()
|
||||
@@ -1,35 +0,0 @@
|
||||
@echo on
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
set SRC=%~dp0
|
||||
|
||||
set PATH=%PATH%;%ProgramFiles(x86)%\MSBuild\14.0\Bin\
|
||||
|
||||
set MSBUILD_ARGS=/nologo /p:Configuration=Release /p:Platform=x64 /verbosity:normal /maxcpucount:%NUMBER_OF_PROCESSORS%
|
||||
|
||||
set TOBUILD=( ^
|
||||
contrib\build\argon2\vs2015\Argon2Ref\Argon2Ref.vcxproj, ^
|
||||
contrib\build\gmp\SMP\libgmp.vcxproj, ^
|
||||
contrib\build\nettle\SMP\libnettle.vcxproj, ^
|
||||
contrib\build\nettle\SMP\libhogweed.vcxproj, ^
|
||||
contrib\build\libiconv\SMP\libiconv.vcxproj, ^
|
||||
contrib\build\nettle\SMP\libiconv.vcxproj, ^
|
||||
contrib\build\zlib\SMP\libzlib.vcxproj, ^
|
||||
contrib\build\gnutls\SMP\libgnutls.vcxproj, ^
|
||||
contrib\build\msgpack-c\msgpack_vc8.vcxproj, ^
|
||||
opendht.vcxproj, ^
|
||||
dhtchat.vcxproj, ^
|
||||
dhtscanner.vcxproj, ^
|
||||
dhtnode.vcxproj ^
|
||||
)
|
||||
|
||||
for %%I in %TOBUILD% do (
|
||||
call :build "%SRC%%%I"
|
||||
)
|
||||
|
||||
exit /B %ERRORLEVEL%
|
||||
|
||||
:build
|
||||
echo "Building project: " %*
|
||||
msbuild %* %MSBUILD_ARGS%
|
||||
exit /B 0
|
||||
@@ -1,39 +0,0 @@
|
||||
--- a/vs2015/Argon2Ref/Argon2Ref.vcxproj
|
||||
+++ b/vs2015/Argon2Ref/Argon2Ref.vcxproj
|
||||
@@ -59,7 +59,7 @@
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
- <ConfigurationType>Application</ConfigurationType>
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
@@ -117,8 +117,8 @@
|
||||
<IncludePath>$(SolutionDir)include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <OutDir>$(SolutionDir)vs2015\build\</OutDir>
|
||||
- <IntDir>$(SolutionDir)vs2015\build\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\..\lib\x64</OutDir>
|
||||
+ <IntDir>$(ProjectDir)vs2015\build\$(ProjectName)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'">
|
||||
@@ -179,6 +179,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <AdditionalIncludeDirectories>$(ProjectDir)..\..\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
@@ -223,4 +224,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
-</Project>
|
||||
+</Project>
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.10.2.windows.1
|
||||
@@ -1,22 +0,0 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set ARGON2_VERSION=1eea0104e7cb2a38c617cf90ffa46ce5db6aceda
|
||||
set ARGON2_URL=https://github.com/P-H-C/phc-winner-argon2/archive/%ARGON2_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%ARGON2_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %ARGON2_URL%
|
||||
)
|
||||
|
||||
7z -y x %ARGON2_VERSION%.tar.gz && 7z -y x %ARGON2_VERSION%.tar -o%BUILD%
|
||||
del %ARGON2_VERSION%.tar && del %ARGON2_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\phc-winner-argon2-%ARGON2_VERSION% argon2
|
||||
|
||||
cd %BUILD%\argon2
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\argon2\argon2-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -1,23 +0,0 @@
|
||||
@echo OFF
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
set SRC=%~dp0
|
||||
|
||||
if "%USE_CACHE%"=="" (
|
||||
set USE_CACHE=0
|
||||
)
|
||||
|
||||
set DEPENDENCIES=( ^
|
||||
argon2, ^
|
||||
gmp, ^
|
||||
gnutls, ^
|
||||
iconv, ^
|
||||
msgpack, ^
|
||||
nettle, ^
|
||||
opendht, ^
|
||||
zlib ^
|
||||
)
|
||||
|
||||
for %%I in %DEPENDENCIES% do (
|
||||
call %SRC%\%%I\fetch_and_patch.bat
|
||||
)
|
||||
@@ -1,22 +0,0 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set GMP_VERSION=3c8f5a0ae0c2ac9ff0ea31b27f71b152979b556d
|
||||
set GMP_URL=https://github.com/ShiftMediaProject/gmp/archive/%GMP_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%GMP_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %GMP_URL%
|
||||
)
|
||||
|
||||
7z -y x %GMP_VERSION%.tar.gz && 7z -y x %GMP_VERSION%.tar -o%BUILD%
|
||||
del %GMP_VERSION%.tar && del %GMP_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\gmp-%GMP_VERSION% gmp
|
||||
|
||||
cd %BUILD%\gmp
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\gmp\gmp-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -1,110 +0,0 @@
|
||||
--- a/SMP/libgmp.vcxproj
|
||||
+++ b/SMP/libgmp.vcxproj
|
||||
@@ -1248,6 +1248,7 @@
|
||||
<ProjectGuid>{02B94302-23D6-43EF-8865-95CDE99D5DC2}</ProjectGuid>
|
||||
<RootNamespace>libgmp</RootNamespace>
|
||||
<ProjectName>libgmp</ProjectName>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -1368,65 +1369,65 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmpd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmpd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmpd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmpd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgmp</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmp</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gmp</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--- a/SMP/config.h
|
||||
+++ b/SMP/config.h
|
||||
@@ -202,7 +202,7 @@
|
||||
/* #undef HAVE_NATIVE_mpn_add_n_sub_n */
|
||||
#define HAVE_NATIVE_mpn_add_nc 1
|
||||
#if defined(__x86_64) || defined(_M_X64)
|
||||
-#define HAVE_NATIVE_mpn_addaddmul_1msb0 1
|
||||
+#define HAVE_NATIVE_mpn_addaddmul_1msb0 0
|
||||
#define HAVE_NATIVE_mpn_addlsh1_n 1
|
||||
#define HAVE_NATIVE_mpn_addlsh2_n 1
|
||||
#define HAVE_NATIVE_mpn_addlsh_n 1
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set GNUTLS_VERSION=f2d0ade53ff644da55244aed79d05eca78d11a2f
|
||||
set GNUTLS_URL=https://github.com/ShiftMediaProject/gnutls/archive/%GNUTLS_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%GNUTLS_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %GNUTLS_URL%
|
||||
)
|
||||
|
||||
7z -y x %GNUTLS_VERSION%.tar.gz && 7z -y x %GNUTLS_VERSION%.tar -o%BUILD%
|
||||
del %GNUTLS_VERSION%.tar && del %GNUTLS_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\gnutls-%GNUTLS_VERSION% gnutls
|
||||
|
||||
cd %BUILD%\gnutls
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\gnutls\gnutls-no-egd.patch
|
||||
git apply --reject --whitespace=fix %SRC%\gnutls\read-file-limits.h.patch
|
||||
git apply --reject --whitespace=fix %SRC%\gnutls\gnutls-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -1,107 +0,0 @@
|
||||
{a => b}/lib/nettle/Makefile.am | 2 +-
|
||||
{a => b}/lib/nettle/Makefile.in | 11 +++++------
|
||||
{a => b}/lib/nettle/rnd-common.c | 7 +++++--
|
||||
3 files changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/lib/nettle/Makefile.am b/lib/nettle/Makefile.am
|
||||
index e84ed1f..4767663 100644
|
||||
--- a/lib/nettle/Makefile.am
|
||||
+++ b/lib/nettle/Makefile.am
|
||||
@@ -38,7 +38,7 @@ endif
|
||||
|
||||
noinst_LTLIBRARIES = libcrypto.la
|
||||
|
||||
-libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c egd.c egd.h \
|
||||
+libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c \
|
||||
gnettle.h rnd-common.h rnd-common.c \
|
||||
rnd.c
|
||||
|
||||
diff --git a/lib/nettle/Makefile.in b/lib/nettle/Makefile.in
|
||||
index 88ae7cf..6ddd536 100644
|
||||
--- a/lib/nettle/Makefile.in
|
||||
+++ b/lib/nettle/Makefile.in
|
||||
@@ -221,8 +221,8 @@ CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||
libcrypto_la_LIBADD =
|
||||
-am__libcrypto_la_SOURCES_DIST = pk.c mpi.c mac.c cipher.c init.c egd.c \
|
||||
- egd.h gnettle.h rnd-common.h rnd-common.c rnd.c rnd-fips.c \
|
||||
+am__libcrypto_la_SOURCES_DIST = pk.c mpi.c mac.c cipher.c init.c \
|
||||
+ gnettle.h rnd-common.h rnd-common.c rnd.c rnd-fips.c \
|
||||
int/drbg-aes-self-test.c int/dsa-fips.h \
|
||||
int/dsa-keygen-fips186.c int/dsa-validate.c \
|
||||
int/provable-prime.c int/drbg-aes.c int/drbg-aes.h \
|
||||
@@ -233,7 +233,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
|
||||
@ENABLE_FIPS140_TRUE@ int/dsa-keygen-fips186.lo \
|
||||
@ENABLE_FIPS140_TRUE@ int/dsa-validate.lo int/provable-prime.lo \
|
||||
@ENABLE_FIPS140_TRUE@ int/drbg-aes.lo int/rsa-keygen-fips186.lo
|
||||
-am_libcrypto_la_OBJECTS = pk.lo mpi.lo mac.lo cipher.lo init.lo egd.lo \
|
||||
+am_libcrypto_la_OBJECTS = pk.lo mpi.lo mac.lo cipher.lo init.lo \
|
||||
rnd-common.lo rnd.lo $(am__objects_1)
|
||||
libcrypto_la_OBJECTS = $(am_libcrypto_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
@@ -1279,8 +1279,8 @@ AM_CPPFLAGS = -I$(srcdir)/int -I$(srcdir)/../../gl \
|
||||
-I$(builddir)/../includes -I$(builddir)/../../gl \
|
||||
-I$(srcdir)/.. $(am__append_1)
|
||||
noinst_LTLIBRARIES = libcrypto.la
|
||||
-libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c egd.c egd.h \
|
||||
- gnettle.h rnd-common.h rnd-common.c rnd.c $(am__append_2)
|
||||
+libcrypto_la_SOURCES = pk.c mpi.c mac.c cipher.c init.c gnettle.h \
|
||||
+ rnd-common.h rnd-common.c rnd.c $(am__append_2)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
@@ -1355,7 +1355,6 @@ distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Plo@am__quote@
|
||||
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egd.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi.Plo@am__quote@
|
||||
diff --git a/lib/nettle/rnd-common.c b/lib/nettle/rnd-common.c
|
||||
index c69ff3b..80b5f32 100644
|
||||
--- a/lib/nettle/rnd-common.c
|
||||
+++ b/lib/nettle/rnd-common.c
|
||||
@@ -139,7 +139,7 @@ void _rnd_system_entropy_deinit(void)
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <locks.h>
|
||||
-#include "egd.h"
|
||||
+//#include "egd.h"
|
||||
|
||||
static int _gnutls_urandom_fd = -1;
|
||||
static mode_t _gnutls_urandom_fd_mode = 0;
|
||||
@@ -208,6 +208,7 @@ static int _rnd_get_system_entropy_urandom(void* _rnd, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#if 0
|
||||
static
|
||||
int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
|
||||
{
|
||||
@@ -232,6 +233,7 @@ int _rnd_get_system_entropy_egd(void* _rnd, size_t size)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+#endif
|
||||
|
||||
int _rnd_system_entropy_check(void)
|
||||
{
|
||||
@@ -268,6 +270,7 @@ int _rnd_system_entropy_init(void)
|
||||
|
||||
return 0;
|
||||
fallback:
|
||||
+#if 0
|
||||
_gnutls_urandom_fd = _rndegd_connect_socket();
|
||||
if (_gnutls_urandom_fd < 0) {
|
||||
_gnutls_debug_log("Cannot open egd socket!\n");
|
||||
@@ -281,7 +284,7 @@ fallback:
|
||||
}
|
||||
|
||||
_rnd_get_system_entropy = _rnd_get_system_entropy_egd;
|
||||
-
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,445 +0,0 @@
|
||||
--- a/SMP/libgnutls.vcxproj
|
||||
+++ b/SMP/libgnutls.vcxproj
|
||||
@@ -743,91 +744,91 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutlsd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutlsd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutlsd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libgnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>gnutls</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@@ -1834,7 +1834,7 @@ del /f /q $(OutDir)\licenses\gnutls.txt
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FloatingPointExceptions>false</FloatingPointExceptions>
|
||||
- <PreprocessorDefinitions>HAVE_CONFIG_H;inline=__inline;ASN1_BUILDING;ASN1_STATIC;LOCALEDIR=".";__func__=__FUNCTION__;ASM_X86;ASM_X86_64;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <PreprocessorDefinitions>RING_UWP;HAVE_WIN32_LOCKS;HAVE_CONFIG_H;inline=__inline;ASN1_BUILDING;ASN1_STATIC;LOCALEDIR=".";__func__=__FUNCTION__;ASM_X86_64;_WIN32_WINNT=0x0600;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\;.\lib;..\lib;..\lib\accelerated;..\lib\auth;..\lib\ext;..\lib\extras;..\lib\minitasn1;..\lib\nettle;..\lib\nettle\int;..\lib\openpgp;..\lib\opencdk;..\lib\x509;..\lib\includes;..\gl;$(OutDir)\include;..\lib\accelerated\x86;$(ProjectDir)\..\..\prebuilt\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<DisableSpecificWarnings>4996;4244;4018;4146;4267;4028;4101;4020;4047;4024;4005;4311;4312;4334;4116;4090;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
@@ -1850,7 +1850,7 @@ del /f /q $(OutDir)\licenses\gnutls.txt
|
||||
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
- <AdditionalDependencies>Crypt32.lib;Ws2_32.lib;libzlib.lib;libiconv.lib;libhogweed.lib;libgmp.lib;libnettle.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
+ <AdditionalDependencies>bcrypt.lib;Ws2_32.lib;libzlib.lib;libiconv.lib;libhogweed.lib;libgmp.lib;libnettle.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir)\lib\x64\;$(ProjectDir)\..\..\prebuilt\lib\x64\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>/IGNORE:4006,4221,4042 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
--- a/lib/nettle/rnd-common.c
|
||||
+++ b/lib/nettle/rnd-common.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
+#include <bcrypt.h>
|
||||
|
||||
/* gnulib wants to claim strerror even if it cannot provide it. WTF */
|
||||
#undef strerror
|
||||
@@ -88,16 +89,25 @@ void _rnd_get_event(struct event_st *e)
|
||||
#include <wincrypt.h>
|
||||
|
||||
static HCRYPTPROV device_fd = 0;
|
||||
+static BCRYPT_ALG_HANDLE bdevice_fd = 0;
|
||||
|
||||
static
|
||||
int _rnd_get_system_entropy_win32(void* rnd, size_t size)
|
||||
{
|
||||
+#ifndef RING_UWP
|
||||
if (!CryptGenRandom(device_fd, (DWORD) size, rnd)) {
|
||||
_gnutls_debug_log("Error in CryptGenRandom: %d\n",
|
||||
(int)GetLastError());
|
||||
return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
}
|
||||
-
|
||||
+#else
|
||||
+ NTSTATUS ret = BCryptGenRandom(bdevice_fd, rnd, (ULONG) size, 0);
|
||||
+ if (!(BCRYPT_SUCCESS(ret))) {
|
||||
+ _gnutls_debug_log("Error in BCryptGenRandom: %d\n",
|
||||
+ (int)GetLastError());
|
||||
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
+ }
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,7 +121,7 @@ int _rnd_system_entropy_check(void)
|
||||
int _rnd_system_entropy_init(void)
|
||||
{
|
||||
int old;
|
||||
-
|
||||
+#ifndef RING_UWP
|
||||
if (!CryptAcquireContext
|
||||
(&device_fd, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
|
||||
@@ -119,13 +129,26 @@ int _rnd_system_entropy_init(void)
|
||||
("error in CryptAcquireContext!\n");
|
||||
return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
}
|
||||
-
|
||||
+#else
|
||||
+ NTSTATUS ret = BCryptOpenAlgorithmProvider(&bdevice_fd,
|
||||
+ BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER,
|
||||
+ 0);
|
||||
+ if (!(BCRYPT_SUCCESS(ret))) {
|
||||
+ _gnutls_debug_log
|
||||
+ ("error in BCryptOpenAlgorithmProvider!\n");
|
||||
+ return GNUTLS_E_RANDOM_DEVICE_ERROR;
|
||||
+ }
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _rnd_system_entropy_deinit(void)
|
||||
{
|
||||
+#ifndef RING_UWP
|
||||
CryptReleaseContext(device_fd, 0);
|
||||
+#else
|
||||
+ BCryptCloseAlgorithmProvider(bdevice_fd, 0);
|
||||
+#endif
|
||||
}
|
||||
|
||||
#else /* POSIX */
|
||||
--- a/lib/opencdk/misc.c
|
||||
+++ b/lib/opencdk/misc.c
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <gnutls_int.h>
|
||||
#include <gnutls_str.h>
|
||||
|
||||
-
|
||||
u32 _cdk_buftou32(const byte * buf)
|
||||
{
|
||||
u32 u;
|
||||
@@ -149,6 +148,13 @@ int _cdk_check_args(int overwrite, const char *in, const char *out)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
+#if (_WIN32_WINNT >= 0x0600)
|
||||
+FILE *_cdk_tmpfile(void)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+#else
|
||||
+
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -183,6 +189,7 @@ FILE *_cdk_tmpfile(void)
|
||||
_close(fd);
|
||||
return NULL;
|
||||
}
|
||||
+#endif /*_WIN32*/
|
||||
#else
|
||||
FILE *_cdk_tmpfile(void)
|
||||
{
|
||||
--- a/lib/system-keys-win.c
|
||||
+++ b/lib/system-keys-win.c
|
||||
@@ -20,9 +20,10 @@
|
||||
|
||||
// Before including any Windows header we need to set _WIN32_WINNT to Vista
|
||||
// (or higher) so that the NCRYPT stuff can be used.
|
||||
-#if _WIN32_WINNT < 0x600
|
||||
+#define _WIN32_WINNT 0x0A00
|
||||
+#if _WIN32_WINNT < 0x0600
|
||||
#undef _WIN32_WINNT
|
||||
-#define _WIN32_WINNT 0x600
|
||||
+#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1075,7 +1076,11 @@ int _gnutls_system_key_init(void)
|
||||
int ret;
|
||||
|
||||
#ifdef DYN_NCRYPT
|
||||
- ncrypt_lib = LoadLibraryA("ncrypt.dll");
|
||||
+#if (_WIN32_WINNT < 0x0A00)
|
||||
+ ncrypt_lib = LoadLibrary("ncrypt.dll");
|
||||
+#else
|
||||
+ ncrypt_lib = LoadPackagedLibrary("ncrypt.dll", 0);
|
||||
+#endif
|
||||
if (ncrypt_lib == NULL) {
|
||||
return gnutls_assert_val(GNUTLS_E_CRYPTO_INIT_FAILED);
|
||||
}
|
||||
--- a/lib/system-keys-win.c
|
||||
+++ b/lib/system-keys-win.c
|
||||
@@ -396,7 +396,11 @@ _gnutls_privkey_import_system_url(gnutls_privkey_t pkey,
|
||||
blob.cbData = id_size;
|
||||
blob.pbData = id;
|
||||
|
||||
- store = CertOpenSystemStore(0, "MY");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if (store == NULL) {
|
||||
gnutls_assert();
|
||||
ret = GNUTLS_E_FILE_ERROR;
|
||||
@@ -535,7 +539,11 @@ _gnutls_x509_crt_import_system_url(gnutls_x509_crt_t crt, const char *url)
|
||||
blob.cbData = id_size;
|
||||
blob.pbData = id;
|
||||
|
||||
- store = CertOpenSystemStore(0, "MY");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if (store == NULL) {
|
||||
gnutls_assert();
|
||||
ret = GNUTLS_E_FILE_ERROR;
|
||||
@@ -776,7 +784,11 @@ gnutls_system_key_iter_get_info(gnutls_system_key_iter_t *iter,
|
||||
if (*iter == NULL)
|
||||
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
||||
|
||||
- (*iter)->store = CertOpenSystemStore(0, "MY");
|
||||
+ (*iter)->store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if ((*iter)->store == NULL) {
|
||||
gnutls_free(*iter);
|
||||
*iter = NULL;
|
||||
@@ -841,7 +853,11 @@ int gnutls_system_key_delete(const char *cert_url, const char *key_url)
|
||||
blob.cbData = id_size;
|
||||
blob.pbData = id;
|
||||
|
||||
- store = CertOpenSystemStore(0, "MY");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"MY");
|
||||
if (store != NULL) {
|
||||
do {
|
||||
cert = CertFindCertificateInStore(store,
|
||||
--- a/lib/system.c
|
||||
+++ b/lib/system.c
|
||||
@@ -446,9 +446,17 @@ int add_system_trust(gnutls_x509_trust_list_t list, unsigned int tl_flags,
|
||||
gnutls_datum_t data;
|
||||
|
||||
if (i == 0)
|
||||
- store = CertOpenSystemStore(0, "ROOT");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"ROOT");
|
||||
else
|
||||
- store = CertOpenSystemStore(0, "CA");
|
||||
+ store = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||||
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
+ 0,
|
||||
+ CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
+ (const void*)"CA");
|
||||
|
||||
if (store == NULL)
|
||||
return GNUTLS_E_FILE_ERROR;
|
||||
--- a/lib/accelerated/x86/x86-common.c
|
||||
+++ b/lib/accelerated/x86/x86-common.c
|
||||
@@ -652,6 +652,7 @@ void register_x86_intel_crypto(unsigned capabilities)
|
||||
|
||||
void register_x86_crypto(void)
|
||||
{
|
||||
+#ifndef RING_UWP
|
||||
unsigned capabilities = 0;
|
||||
char *p;
|
||||
p = secure_getenv("GNUTLS_CPUID_OVERRIDE");
|
||||
@@ -663,5 +664,7 @@ void register_x86_crypto(void)
|
||||
#ifdef ENABLE_PADLOCK
|
||||
register_x86_padlock_crypto(capabilities);
|
||||
#endif
|
||||
+#endif
|
||||
+ register_x86_intel_crypto(0);
|
||||
}
|
||||
|
||||
--- a/lib/gnutls_global.c
|
||||
+++ b/lib/gnutls_global.c
|
||||
@@ -240,7 +240,9 @@ int gnutls_global_init(void)
|
||||
|
||||
_gnutls_switch_lib_state(LIB_STATE_INIT);
|
||||
|
||||
+#ifndef RING_UWP
|
||||
e = secure_getenv("GNUTLS_DEBUG_LEVEL");
|
||||
+#endif
|
||||
if (e != NULL) {
|
||||
level = atoi(e);
|
||||
gnutls_global_set_log_level(level);
|
||||
@@ -473,8 +475,10 @@ const char *e;
|
||||
if (_gnutls_global_init_skip() != 0)
|
||||
return;
|
||||
|
||||
+#ifndef RING_UWP
|
||||
e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
|
||||
- if (e != NULL) {
|
||||
+#endif
|
||||
+ if (e != NULL) {
|
||||
ret = atoi(e);
|
||||
if (ret == 1)
|
||||
return;
|
||||
@@ -494,7 +498,9 @@ static void _DESTRUCTOR lib_deinit(void)
|
||||
if (_gnutls_global_init_skip() != 0)
|
||||
return;
|
||||
|
||||
+#ifndef RING_UWP
|
||||
e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
|
||||
+#endif
|
||||
if (e != NULL) {
|
||||
int ret = atoi(e);
|
||||
if (ret == 1)
|
||||
--- a/lib/gnutls_kx.c
|
||||
+++ b/lib/gnutls_kx.c
|
||||
@@ -105,7 +105,9 @@ static void write_nss_key_log(gnutls_session_t session, const gnutls_datum_t *pr
|
||||
|
||||
if (!checked_env) {
|
||||
checked_env = 1;
|
||||
+#ifndef RING_UWP
|
||||
keylogfile = secure_getenv("SSLKEYLOGFILE");
|
||||
+#endif
|
||||
}
|
||||
|
||||
if (keylogfile == NULL)
|
||||
--- a/lib/system.c
|
||||
+++ b/lib/system.c
|
||||
@@ -340,7 +340,11 @@ void gnutls_system_global_deinit(void)
|
||||
*/
|
||||
int _gnutls_find_config_path(char *path, size_t max_size)
|
||||
{
|
||||
- const char *home_dir = secure_getenv("HOME");
|
||||
+#ifndef RING_UWP
|
||||
+ const char *home_dir = secure_getenv("HOME");
|
||||
+#else
|
||||
+ const char *home_dir = NULL;
|
||||
+#endif
|
||||
|
||||
if (home_dir != NULL && home_dir[0] != 0) {
|
||||
snprintf(path, max_size, "%s/" CONFIG_PATH, home_dir);
|
||||
@@ -349,8 +353,13 @@ int _gnutls_find_config_path(char *path, size_t max_size)
|
||||
|
||||
#ifdef _WIN32
|
||||
if (home_dir == NULL || home_dir[0] == '\0') {
|
||||
+#ifndef RING_UWP
|
||||
const char *home_drive = getenv("HOMEDRIVE");
|
||||
const char *home_path = getenv("HOMEPATH");
|
||||
+#else
|
||||
+ const char *home_drive = NULL;
|
||||
+ const char *home_path = NULL;
|
||||
+#endif
|
||||
|
||||
if (home_drive != NULL && home_path != NULL) {
|
||||
snprintf(path, max_size, "%s%s\\" CONFIG_PATH, home_drive, home_path);
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
--- gnutls/gl/read-file.c.orig 2012-03-06 20:59:29.600593329 -0500
|
||||
+++ gnutls/gl/read-file.c 2012-03-06 20:59:44.568593328 -0500
|
||||
@@ -35,6 +35,9 @@
|
||||
/* Get errno. */
|
||||
#include <errno.h>
|
||||
|
||||
+/* Get SIZE_MAX */
|
||||
+#include <limits.h>
|
||||
+
|
||||
/* Read a STREAM and return a newly allocated string with the content,
|
||||
and set *LENGTH to the length of the string. The string is
|
||||
zero-terminated, but the terminating zero byte is not counted in
|
||||
@@ -1,22 +0,0 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set ICONV_VERSION=65ab92f7a1699ecc39e37fb81f66e5a42aaa35c4
|
||||
set ICONV_URL=https://github.com/ShiftMediaProject/libiconv/archive/%ICONV_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%ICONV_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %ICONV_URL%
|
||||
)
|
||||
|
||||
7z -y x %ICONV_VERSION%.tar.gz && 7z -y x %ICONV_VERSION%.tar -o%BUILD%
|
||||
del %ICONV_VERSION%.tar && del %ICONV_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\libiconv-%ICONV_VERSION% libiconv
|
||||
|
||||
cd %BUILD%\libiconv
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\iconv\libiconv-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -1,99 +0,0 @@
|
||||
--- a/SMP/libiconv.vcxproj
|
||||
+++ b/SMP/libiconv.vcxproj
|
||||
@@ -45,6 +45,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}</ProjectGuid>
|
||||
<RootNamespace>libiconv</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -164,65 +165,65 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconvd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconvd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconvd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconvd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libiconv</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconv</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>iconv</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set MSGPACK_VERSION=1df97bc37b363a340c5ad06c5cbcc53310aaff80
|
||||
set MSGPACK_URL=https://github.com/msgpack/msgpack-c/archive/%MSGPACK_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%MSGPACK_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %MSGPACK_URL%
|
||||
)
|
||||
|
||||
7z -y x %MSGPACK_VERSION%.tar.gz && 7z -y x %MSGPACK_VERSION%.tar -o%BUILD%
|
||||
del %MSGPACK_VERSION%.tar && del %MSGPACK_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\msgpack-c-%MSGPACK_VERSION% msgpack-c
|
||||
|
||||
cd %BUILD%\msgpack-c
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\msgpack\msgpack-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -1,221 +0,0 @@
|
||||
--- /dev/null
|
||||
+++ b/msgpack_vc8.vcxproj
|
||||
@@ -0,0 +1,214 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<Project DefaultTargets="Build" ToolsVersion="14.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="Debug|x64">
|
||||
+ <Configuration>Debug</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release|Win32">
|
||||
+ <Configuration>Release</Configuration>
|
||||
+ <Platform>Win32</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release|x64">
|
||||
+ <Configuration>Release</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
+ </ItemGroup>
|
||||
+ <PropertyGroup Label="Globals">
|
||||
+ <ProjectName>MessagePack</ProjectName>
|
||||
+ <ProjectGuid>{122A2EA4-B283-4241-9655-786DE78283B2}</ProjectGuid>
|
||||
+ <RootNamespace>MessagePack</RootNamespace>
|
||||
+ <Keyword>Win32Proj</Keyword>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
+ </PropertyGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ <WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ <WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>v140</PlatformToolset>
|
||||
+ <CharacterSet>Unicode</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
+ <ImportGroup Label="ExtensionSettings">
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
+ <PropertyGroup Label="UserMacros" />
|
||||
+ <PropertyGroup>
|
||||
+ <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ <TargetName>msgpackd</TargetName>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
+ <TargetName>msgpackd</TargetName>
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ <TargetName>msgpack</TargetName>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
+ <TargetName>msgpack</TargetName>
|
||||
+ <OutDir>$(ProjectDir)..\</OutDir>
|
||||
+ <IntDir>$(Configuration)\</IntDir>
|
||||
+ </PropertyGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <MinimalRebuild>true</MinimalRebuild>
|
||||
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader />
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <BasicRuntimeChecks>StackFrameRuntimeCheck</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader />
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ <LinkTimeCodeGeneration />
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>MSGPACK_USE_CPP03;WIN32_NATIVE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
+ </ClCompile>
|
||||
+ <Lib>
|
||||
+ <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
+ <LinkTimeCodeGeneration />
|
||||
+ </Lib>
|
||||
+ <PostBuildEvent>
|
||||
+ <Command>mkdir $(OutDir)\include
|
||||
+
|
||||
+mkdir $(OutDir)\include\msgpack
|
||||
+
|
||||
+copy include\*.h $(OutDir)\include\
|
||||
+
|
||||
+copy include\*.hpp $(OutDir)\include\
|
||||
+xcopy /S /Y include\msgpack\*.h $(OutDir)\include\msgpack
|
||||
+xcopy /S /Y include\msgpack\*.hpp $(OutDir)\include\msgpack
|
||||
+</Command>
|
||||
+ </PostBuildEvent>
|
||||
+ </ItemDefinitionGroup>
|
||||
+ <ItemGroup>
|
||||
+ <ClCompile Include="src\objectc.c" />
|
||||
+ <ClCompile Include="src\unpack.c" />
|
||||
+ <ClCompile Include="src\version.c" />
|
||||
+ <ClCompile Include="src\vrefbuffer.c" />
|
||||
+ <ClCompile Include="src\zone.c" />
|
||||
+ </ItemGroup>
|
||||
+ <ItemGroup>
|
||||
+ <ClInclude Include="include\msgpack.hpp" />
|
||||
+ </ItemGroup>
|
||||
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
+ <ImportGroup Label="ExtensionTargets">
|
||||
+ </ImportGroup>
|
||||
+</Project>
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set NETTLE_VERSION=4e0b2723b76d4163fa37b2b456d41534154ec97c
|
||||
set NETTLE_URL=https://github.com/ShiftMediaProject/nettle/archive/%NETTLE_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%NETTLE_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %NETTLE_URL%
|
||||
)
|
||||
|
||||
7z -y x %NETTLE_VERSION%.tar.gz && 7z -y x %NETTLE_VERSION%.tar -o%BUILD%
|
||||
del %NETTLE_VERSION%.tar && del %NETTLE_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\nettle-%NETTLE_VERSION% nettle
|
||||
|
||||
cd %BUILD%\nettle
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\nettle\nettle-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -1,228 +0,0 @@
|
||||
--- a/SMP/libhogweed.vcxproj
|
||||
+++ b/SMP/libhogweed.vcxproj
|
||||
@@ -242,6 +242,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}</ProjectGuid>
|
||||
<RootNamespace>libhogweed</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -405,91 +406,91 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweedd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweedd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweedd</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libhogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLLStaticDeps|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>hogweed</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--- a/SMP/libnettle.vcxproj
|
||||
+++ b/SMP/libnettle.vcxproj
|
||||
@@ -278,6 +278,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}</ProjectGuid>
|
||||
<RootNamespace>libnettle</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -397,65 +398,65 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettled</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettled</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettled</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettled</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libnettle</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettle</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>nettle</TargetName>
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
--
|
||||
2.8.1.windows.1
|
||||
@@ -1,22 +0,0 @@
|
||||
set BUILD=%SRC%..\build
|
||||
|
||||
set ZLIB_VERSION=3a062eb61d0c3d4aa30851cd1a6597b977b56597
|
||||
set ZLIB_URL=https://github.com/ShiftMediaProject/zlib/archive/%ZLIB_VERSION%.tar.gz
|
||||
|
||||
mkdir %BUILD%
|
||||
|
||||
if %USE_CACHE%==1 (
|
||||
copy %CACHE_DIR%\%ZLIB_VERSION%.tar.gz %cd%
|
||||
) else (
|
||||
wget %ZLIB_URL%
|
||||
)
|
||||
|
||||
7z -y x %ZLIB_VERSION%.tar.gz && 7z -y x %ZLIB_VERSION%.tar -o%BUILD%
|
||||
del %ZLIB_VERSION%.tar && del %ZLIB_VERSION%.tar.gz && del %BUILD%\pax_global_header
|
||||
rename %BUILD%\zlib-%ZLIB_VERSION% zlib
|
||||
|
||||
cd %BUILD%\zlib
|
||||
|
||||
git apply --reject --whitespace=fix %SRC%\zlib\zlib-uwp.patch
|
||||
|
||||
cd %SRC%
|
||||
@@ -1,97 +0,0 @@
|
||||
--- a/SMP/libzlib.vcxproj
|
||||
+++ b/SMP/libzlib.vcxproj
|
||||
@@ -45,6 +45,7 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}</ProjectGuid>
|
||||
<RootNamespace>libzlib</RootNamespace>
|
||||
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -165,63 +166,63 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlibd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlibd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlibd</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>libzlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlib</TargetName>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
|
||||
- <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
- <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
+ <OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
+ <IntDir>$(ProjectDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
|
||||
<TargetName>zlibd</TargetName>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
|
||||
--
|
||||
2.8.1.windows.1
|
||||
|
||||
+22
-22
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -21,32 +21,32 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}</ProjectGuid>
|
||||
<RootNamespace>dhtchat</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -86,14 +86,14 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -102,14 +102,14 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -120,16 +120,16 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -140,16 +140,16 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.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)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64;$(ProjectDir)vs2015\build</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
|
||||
+22
-22
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -21,32 +21,32 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}</ProjectGuid>
|
||||
<RootNamespace>dhtnode</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -86,14 +86,14 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -102,14 +102,14 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -120,16 +120,16 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -140,16 +140,16 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.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)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64;$(ProjectDir)vs2015\build</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
|
||||
+22
-22
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -21,32 +21,32 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{78443BCD-4689-4007-A246-F8F34B27F561}</ProjectGuid>
|
||||
<RootNamespace>dhtscanner</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -86,14 +86,14 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -102,14 +102,14 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -120,16 +120,16 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\..\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;blake.lib;argon.lib;libgnutls.lib;opendht.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)..\..\lib\x64</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
@@ -140,16 +140,16 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;$(ProjectDir)contrib\build\include;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_NATIVE;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>crypt32.lib;Argon2Ref.lib;libgnutls.lib;opendht.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)contrib\build\lib\x64;$(ProjectDir)..\..\lib\x64;$(ProjectDir)vs2015\build</AdditionalLibraryDirectories>
|
||||
<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>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
@echo on
|
||||
call contrib\src\fetch_and_patch.bat
|
||||
+53
-35
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -19,6 +19,18 @@
|
||||
</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" />
|
||||
@@ -39,6 +51,9 @@
|
||||
<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" />
|
||||
@@ -75,32 +90,32 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{711397CE-E5D5-467D-9457-8716C047E50C}</ProjectGuid>
|
||||
<RootNamespace>opendht</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<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>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -123,33 +138,34 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>opendhtd</TargetName>
|
||||
<TargetName>libopendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>opendht</TargetName>
|
||||
<TargetName>libopendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<TargetName>opendhtd</TargetName>
|
||||
<OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
|
||||
<TargetName>libopendht</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)..\..\</OutDir>
|
||||
<TargetName>opendht</TargetName>
|
||||
<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>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
|
||||
<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
|
||||
@@ -160,7 +176,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -168,10 +184,11 @@ copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
|
||||
<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
|
||||
@@ -182,7 +199,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@@ -192,11 +209,11 @@ copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\include;..\include;..\include\opendht;..\..\msgpack-c\include;</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DisableSpecificWarnings>4804;4800;4101;4267;4244;4503;</DisableSpecificWarnings>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions)</AdditionalOptions>
|
||||
<ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<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>
|
||||
@@ -211,7 +228,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -222,11 +239,12 @@ copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)contrib\build\include;$(ProjectDir)..\include;$(ProjectDir)..\include\opendht;$(ProjectDir)contrib\build\msgpack-c\include;$(ProjectDir)contrib\build\argon2\include;$(ProjectDir)..\..\include;$(ProjectDir)..\..\argon2\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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_WARNINGS %(AdditionalOptions)</AdditionalOptions>
|
||||
<ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<AdditionalOptions>-D_SCL_SECURE_NO_WARNING;%(AdditionalOptions)</AdditionalOptions>
|
||||
<ProgramDataBaseFileName>$(OutDir)lib\$(PlatformTarget)\$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
@@ -241,7 +259,7 @@ copy ..\include\opendht\*.h $(OutDir)\include\opendht
|
||||
copy ..\include\opendht.h $(OutDir)\include\</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<OutputFile>$(OutDir)lib\$(PlatformTarget)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
|
||||
@@ -53,27 +53,29 @@
|
||||
<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\def.h" />
|
||||
<ClInclude Include="..\include\opendht\sockaddr.h" />
|
||||
<ClInclude Include="..\src\net.h" />
|
||||
<ClInclude Include="..\src\parsed_message.h" />
|
||||
<ClInclude Include="..\src\base64.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\listener.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\request.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\search.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\storage.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\opendht.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -139,6 +141,42 @@
|
||||
</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">
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opendht", "opendht.vcxproj", "{711397CE-E5D5-467D-9457-8716C047E50C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {070FEF2B-0C3F-4F33-9D3C-53C7330BF518}
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2} = {122A2EA4-B283-4241-9655-786DE78283B2}
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2} = {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02} = {6F610EE8-7F59-4191-AB88-F63843267C02}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{71A1A9EC-1104-4335-A87E-AF8749FD5B34}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgmp", "contrib\build\gmp\SMP\libgmp.vcxproj", "{02B94302-23D6-43EF-8865-95CDE99D5DC2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgnutls", "contrib\build\gnutls\SMP\libgnutls.vcxproj", "{6F610EE8-7F59-4191-AB88-F63843267C02}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {02B94302-23D6-43EF-8865-95CDE99D5DC2}
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {070FEF2B-0C3F-4F33-9D3C-53C7330BF518}
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} = {CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C} = {200F3D3C-8B84-46D8-953A-6C0EBD283B5C}
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libiconv", "contrib\build\libiconv\SMP\libiconv.vcxproj", "{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhogweed", "contrib\build\nettle\SMP\libhogweed.vcxproj", "{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {02B94302-23D6-43EF-8865-95CDE99D5DC2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnettle", "contrib\build\nettle\SMP\libnettle.vcxproj", "{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzlib", "contrib\build\zlib\SMP\libzlib.vcxproj", "{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "contrib\build\msgpack-c\msgpack_vc8.vcxproj", "{122A2EA4-B283-4241-9655-786DE78283B2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{296E2989-CF09-43AC-BBD2-BCF1A4B56D07}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dhtnode", "dhtnode.vcxproj", "{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C} = {711397CE-E5D5-467D-9457-8716C047E50C}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dhtscanner", "dhtscanner.vcxproj", "{78443BCD-4689-4007-A246-F8F34B27F561}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C} = {711397CE-E5D5-467D-9457-8716C047E50C}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dhtchat", "dhtchat.vcxproj", "{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C} = {711397CE-E5D5-467D-9457-8716C047E50C}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2Ref", "contrib\build\argon2\vs2015\Argon2Ref\Argon2Ref.vcxproj", "{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
ReleaseStatic|x64 = ReleaseStatic|x64
|
||||
ReleaseStatic|x86 = ReleaseStatic|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}.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}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{711397CE-E5D5-467D-9457-8716C047E50C}.ReleaseStatic|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}.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}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2}.ReleaseStatic|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}.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}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02}.ReleaseStatic|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}.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}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B}.ReleaseStatic|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}.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}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C}.ReleaseStatic|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}.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}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518}.ReleaseStatic|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}.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}.ReleaseStatic|x64.ActiveCfg = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x64.Build.0 = ReleaseLTO|x64
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|x86.ActiveCfg = ReleaseLTO|Win32
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}.ReleaseStatic|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}.Release|x64.ActiveCfg = Release|Win32
|
||||
{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}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x64.Build.0 = Debug|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x64.ActiveCfg = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x64.Build.0 = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.Release|x86.Build.0 = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x64.Build.0 = Debug|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Debug|x86.Build.0 = Debug|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x64.ActiveCfg = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x64.Build.0 = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x86.ActiveCfg = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.Release|x86.Build.0 = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x64.Build.0 = Debug|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Debug|x86.Build.0 = Debug|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x64.ActiveCfg = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x64.Build.0 = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.Release|x86.Build.0 = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x64.ActiveCfg = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x64.Build.0 = Release|x64
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x86.ActiveCfg = Release|Win32
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA}.ReleaseStatic|x86.Build.0 = Release|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.Build.0 = Debug|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.ActiveCfg = Release|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.Build.0 = Release|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.Build.0 = Release|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{02B94302-23D6-43EF-8865-95CDE99D5DC2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{6F610EE8-7F59-4191-AB88-F63843267C02} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{CB8BB76F-D3FF-434E-A85E-7FFC0893EC9B} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{200F3D3C-8B84-46D8-953A-6C0EBD283B5C} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{070FEF2B-0C3F-4F33-9D3C-53C7330BF518} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{122A2EA4-B283-4241-9655-786DE78283B2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
{BF92AECF-AA1D-4B05-9D00-0247E92A24B5} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
|
||||
{78443BCD-4689-4007-A246-F8F34B27F561} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
|
||||
{8BE7F14D-B227-4D54-9105-7E5473F2D0BA} = {296E2989-CF09-43AC-BBD2-BCF1A4B56D07}
|
||||
{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2} = {71A1A9EC-1104-4335-A87E-AF8749FD5B34}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -16,9 +16,7 @@ if ENABLE_TESTS
|
||||
SUBDIRS += tests
|
||||
endif
|
||||
|
||||
if HAVE_DOXYGEN
|
||||
SUBDIRS += doc
|
||||
endif
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
|
||||
@@ -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++11 Distributed Hash Table implementation.
|
||||
A lightweight C++14 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++11 map API
|
||||
* Clean and powerful C++14 map API
|
||||
* Python 3 bindings
|
||||
* REST API
|
||||
|
||||
@@ -27,13 +27,13 @@ Build instructions: <https://github.com/savoirfairelinux/opendht/wiki/Build-the-
|
||||
|
||||
#### How-to build a simple client app
|
||||
```bash
|
||||
g++ main.cpp -std=c++11 -lopendht -lgnutls
|
||||
g++ main.cpp -std=c++14 -lopendht -lgnutls
|
||||
```
|
||||
|
||||
## Examples
|
||||
### C++ example
|
||||
The `tools` directory includes simple example programs :
|
||||
* `dhtnode`, a command line tool, mostly used for debuging, allowing to perform operations supported by the library (get, put etc.) with text values.
|
||||
* `dhtnode`, a command line tool, allowing to run a DHT node and perform operations supported by the library (get, put etc.) with text values.
|
||||
* `dhtchat`, a very simple IM client working over the dht.
|
||||
|
||||
Example program launching a DHT node, connecting to the network and performing some basic operations:
|
||||
@@ -96,10 +96,10 @@ for r in results:
|
||||
- msgpack-c 1.2+, used for data serialization.
|
||||
- GnuTLS 3.3+, used for cryptographic operations.
|
||||
- Nettle 2.4+, a GnuTLS dependency for crypto.
|
||||
- (optional) restbed used for the REST API. commit fb84213e170bc171fecd825a8e47ed9f881a12cd (https://github.com/AmarOk1412/restbed/tree/async_read_until)
|
||||
- (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
|
||||
- Build tested with Microsoft Visual Studio 2015, 2017, 2019
|
||||
|
||||
## Contact
|
||||
|
||||
|
||||
+1
-1
Submodule argon2 updated: 670229c849...62358ba212.
+430
@@ -0,0 +1,430 @@
|
||||
#include "opendht_c.h"
|
||||
#include "opendht.h"
|
||||
|
||||
using ValueSp = std::shared_ptr<dht::Value>;
|
||||
using PrivkeySp = std::shared_ptr<dht::crypto::PrivateKey>;
|
||||
using PubkeySp = std::shared_ptr<const dht::crypto::PublicKey>;
|
||||
using CertSp = std::shared_ptr<dht::crypto::Certificate>;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// dht::InfoHash
|
||||
|
||||
inline dht_infohash dht_infohash_to_c(const dht::InfoHash& h) {
|
||||
dht_infohash ret;
|
||||
*reinterpret_cast<dht::InfoHash*>(&ret) = h;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline dht_pkid dht_pkid_to_c(const dht::PkId& h) {
|
||||
dht_pkid ret;
|
||||
*reinterpret_cast<dht::PkId*>(&ret) = h;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* dht_infohash_print(const dht_infohash* h) {
|
||||
return reinterpret_cast<const dht::InfoHash*>(h)->to_c_str();
|
||||
}
|
||||
|
||||
void dht_infohash_zero(dht_infohash* h) {
|
||||
*reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash{};
|
||||
}
|
||||
|
||||
void dht_infohash_random(dht_infohash* h) {
|
||||
*reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::getRandom();
|
||||
}
|
||||
|
||||
void dht_infohash_get(dht_infohash* h, const uint8_t* dat, size_t dat_size) {
|
||||
*reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::get(dat, dat_size);
|
||||
}
|
||||
|
||||
void dht_infohash_get_from_string(dht_infohash* h, const char* dat) {
|
||||
*reinterpret_cast<dht::InfoHash*>(h) = dht::InfoHash::get((const uint8_t*)dat, (size_t)strlen(dat));
|
||||
}
|
||||
|
||||
bool dht_infohash_is_zero(const dht_infohash* h) {
|
||||
return !static_cast<bool>(*reinterpret_cast<const dht::InfoHash*>(h));
|
||||
}
|
||||
|
||||
void dht_infohash_from_hex(dht_infohash* h, const char* dat) {
|
||||
*h = dht_infohash_to_c(dht::InfoHash(std::string(dat, HASH_LEN*2)));
|
||||
}
|
||||
|
||||
const char* dht_pkid_print(const dht_pkid* h) {
|
||||
return reinterpret_cast<const dht::PkId*>(h)->to_c_str();
|
||||
}
|
||||
|
||||
// dht::Blob
|
||||
void dht_blob_delete(dht_blob* data) {
|
||||
delete reinterpret_cast<dht::Blob*>(data);
|
||||
}
|
||||
|
||||
dht_data_view dht_blob_get_data(const dht_blob* data) {
|
||||
dht_data_view view;
|
||||
view.data = reinterpret_cast<const dht::Blob*>(data)->data();
|
||||
view.size = reinterpret_cast<const dht::Blob*>(data)->size();
|
||||
return view;
|
||||
}
|
||||
|
||||
// dht::Value
|
||||
dht_data_view dht_value_get_data(const dht_value* data) {
|
||||
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
|
||||
dht_data_view view;
|
||||
view.data = vsp->data.data();
|
||||
view.size = vsp->data.size();
|
||||
return view;
|
||||
}
|
||||
|
||||
dht_value_id dht_value_get_id(const dht_value* data) {
|
||||
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
|
||||
return vsp->id;
|
||||
}
|
||||
|
||||
dht_publickey* dht_value_get_owner(const dht_value* data) {
|
||||
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
|
||||
return vsp->owner ? reinterpret_cast<dht_publickey*>(new PubkeySp(vsp->owner)) : nullptr;
|
||||
}
|
||||
|
||||
dht_infohash dht_value_get_recipient(const dht_value* data) {
|
||||
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
|
||||
return dht_infohash_to_c(vsp->recipient);
|
||||
}
|
||||
|
||||
const char* dht_value_get_user_type(const dht_value* data) {
|
||||
const ValueSp& vsp(*reinterpret_cast<const ValueSp*>(data));
|
||||
return vsp->user_type.c_str();
|
||||
}
|
||||
|
||||
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_ref(const dht_value* v) {
|
||||
return reinterpret_cast<dht_value*>(new ValueSp(*reinterpret_cast<const ValueSp*>(v)));
|
||||
}
|
||||
|
||||
void dht_value_unref(dht_value* v) {
|
||||
delete reinterpret_cast<ValueSp*>(v);
|
||||
}
|
||||
|
||||
// dht::crypto::PublicKey
|
||||
dht_publickey* dht_publickey_import(const uint8_t* dat, size_t dat_size) {
|
||||
try {
|
||||
return reinterpret_cast<dht_publickey*>(new PubkeySp(std::make_shared<const dht::crypto::PublicKey>(dat, dat_size)));
|
||||
} catch (const dht::crypto::CryptoException& e) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void dht_publickey_delete(dht_publickey* pk) {
|
||||
delete reinterpret_cast<PubkeySp*>(pk);
|
||||
}
|
||||
|
||||
int dht_publickey_export(const dht_publickey* pk, char* out, size_t* outlen) {
|
||||
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
|
||||
return gnutls_pubkey_export(pkey->pk, GNUTLS_X509_FMT_DER, out, outlen);
|
||||
}
|
||||
|
||||
dht_infohash dht_publickey_get_id(const dht_publickey* pk) {
|
||||
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
|
||||
return dht_infohash_to_c(pkey->getId());
|
||||
}
|
||||
|
||||
dht_pkid dht_publickey_get_long_id(const dht_publickey* pk) {
|
||||
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
|
||||
return dht_pkid_to_c(pkey->getLongId());
|
||||
}
|
||||
|
||||
bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, size_t data_size, const char* signature, size_t signature_size) {
|
||||
const auto& pkey = *reinterpret_cast<const PubkeySp*>(pk);
|
||||
return pkey->checkSignature((const uint8_t*)data, data_size, (const uint8_t*)signature, signature_size);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// dht::crypto::PrivateKey
|
||||
dht_privatekey* dht_privatekey_generate(unsigned key_length_bits) {
|
||||
if (key_length_bits == 0)
|
||||
key_length_bits = 4096;
|
||||
return reinterpret_cast<dht_privatekey*>(new PrivkeySp(std::make_shared<dht::crypto::PrivateKey>(dht::crypto::PrivateKey::generate(key_length_bits))));
|
||||
}
|
||||
|
||||
dht_privatekey* dht_privatekey_import(const uint8_t* dat, size_t dat_size, const char* password) {
|
||||
try {
|
||||
return reinterpret_cast<dht_privatekey*>(new PrivkeySp(std::make_shared<dht::crypto::PrivateKey>(dat, dat_size, password)));
|
||||
} catch (const dht::crypto::CryptoException& e) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int dht_privatekey_export(const dht_privatekey* k, char* out, size_t* out_size, const char* password) {
|
||||
if (!out or !out_size or !*out_size)
|
||||
return -1;
|
||||
const auto& key = *reinterpret_cast<const PrivkeySp*>(k);
|
||||
return key->serialize((uint8_t*)out, out_size, password);
|
||||
}
|
||||
|
||||
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())));
|
||||
}
|
||||
|
||||
void dht_privatekey_delete(dht_privatekey* pk) {
|
||||
delete reinterpret_cast<PrivkeySp*>(pk);
|
||||
}
|
||||
|
||||
// dht::crypto::Certificate
|
||||
dht_certificate* dht_certificate_import(const uint8_t* dat, size_t dat_size) {
|
||||
try {
|
||||
return reinterpret_cast<dht_certificate*>(new CertSp(std::make_shared<dht::crypto::Certificate>(dat, dat_size)));
|
||||
} catch (const dht::crypto::CryptoException& e) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void dht_certificate_delete(dht_certificate* c) {
|
||||
delete reinterpret_cast<CertSp*>(c);
|
||||
}
|
||||
|
||||
dht_infohash dht_certificate_get_id(const dht_certificate* c) {
|
||||
const auto& cert = *reinterpret_cast<const CertSp*>(c);
|
||||
return dht_infohash_to_c(cert->getId());
|
||||
}
|
||||
|
||||
dht_pkid dht_certificate_get_long_id(const dht_certificate* c) {
|
||||
const auto& cert = *reinterpret_cast<const CertSp*>(c);
|
||||
return dht_pkid_to_c(cert->getLongId());
|
||||
}
|
||||
|
||||
dht_publickey* dht_certificate_get_publickey(const dht_certificate* c) {
|
||||
const auto& cert = *reinterpret_cast<const CertSp*>(c);
|
||||
return reinterpret_cast<dht_publickey*>(new PubkeySp(std::make_shared<dht::crypto::PublicKey>(cert->getPublicKey())));
|
||||
}
|
||||
|
||||
// dht::crypto::Identity
|
||||
inline dht::crypto::Identity dht_identity_from_c(const dht_identity* cid) {
|
||||
dht::crypto::Identity id {};
|
||||
if (cid and cid->privatekey)
|
||||
id.first = *reinterpret_cast<const PrivkeySp*>(cid->privatekey);
|
||||
if (cid and cid->certificate)
|
||||
id.second = *reinterpret_cast<const CertSp*>(cid->certificate);
|
||||
return id;
|
||||
}
|
||||
|
||||
inline dht_identity dht_identity_to_c(const dht::crypto::Identity& id) {
|
||||
dht_identity cid {};
|
||||
cid.privatekey = id.first ? reinterpret_cast<dht_privatekey*>(new PrivkeySp(id.first)) : NULL;
|
||||
cid.certificate = id.second ? reinterpret_cast<dht_certificate*>(new CertSp(id.second)) : NULL;
|
||||
return cid;
|
||||
}
|
||||
|
||||
OPENDHT_C_PUBLIC dht_identity dht_identity_generate(const char* common_name, const dht_identity* ca) {
|
||||
return dht_identity_to_c(dht::crypto::generateIdentity(common_name, dht_identity_from_c(ca)));
|
||||
}
|
||||
|
||||
OPENDHT_C_PUBLIC void dht_identity_delete(dht_identity* id) {
|
||||
if (id->certificate) {
|
||||
dht_certificate_delete(id->certificate);
|
||||
id->certificate = NULL;
|
||||
}
|
||||
if (id->privatekey) {
|
||||
dht_privatekey_delete(id->privatekey);
|
||||
id->privatekey = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// config
|
||||
void dht_runner_config_default(dht_runner_config* config) {
|
||||
bzero(config, sizeof(dht_runner_config));
|
||||
config->threaded = true;
|
||||
}
|
||||
|
||||
// dht::DhtRunner
|
||||
dht_runner* dht_runner_new() {
|
||||
return reinterpret_cast<dht_runner*>(new dht::DhtRunner);
|
||||
}
|
||||
|
||||
void dht_runner_delete(dht_runner* runner) {
|
||||
delete reinterpret_cast<dht::DhtRunner*>(runner);
|
||||
}
|
||||
|
||||
void dht_runner_run(dht_runner* r, in_port_t port) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
runner->run(port, {}, true);
|
||||
}
|
||||
|
||||
void 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{};
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void dht_runner_ping(dht_runner* r, struct sockaddr* addr, socklen_t addr_len) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
runner->bootstrap(dht::SockAddr(addr, addr_len));
|
||||
}
|
||||
|
||||
void dht_runner_bootstrap(dht_runner* r, const char* host, const char* service) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
if (service)
|
||||
runner->bootstrap(host, service);
|
||||
else
|
||||
runner->bootstrap(host);
|
||||
}
|
||||
|
||||
void dht_runner_get(dht_runner* r, const dht_infohash* h, dht_get_cb cb, dht_done_cb done_cb, void* cb_user_data) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
|
||||
runner->get(*hash, [cb,cb_user_data](std::shared_ptr<dht::Value> value){
|
||||
return cb(reinterpret_cast<const dht_value*>(&value), cb_user_data);
|
||||
}, [done_cb, cb_user_data](bool ok){
|
||||
if (done_cb)
|
||||
done_cb(ok, cb_user_data);
|
||||
});
|
||||
}
|
||||
|
||||
struct ScopeGuardCb {
|
||||
ScopeGuardCb(dht_shutdown_cb cb, void* data)
|
||||
: onDestroy(cb), userData(data) {}
|
||||
|
||||
~ScopeGuardCb() {
|
||||
if (onDestroy)
|
||||
onDestroy((void*)userData);
|
||||
}
|
||||
private:
|
||||
const dht_shutdown_cb onDestroy;
|
||||
void const* userData;
|
||||
};
|
||||
|
||||
dht_op_token* dht_runner_listen(dht_runner* r, const dht_infohash* h, dht_value_cb cb, dht_shutdown_cb done_cb, void* cb_user_data) {
|
||||
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) {
|
||||
for (const auto& value : values) {
|
||||
if (not cb(reinterpret_cast<const dht_value*>(&value), expired, cb_user_data))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return (dht_op_token*)fret;
|
||||
}
|
||||
|
||||
void dht_runner_cancel_listen(dht_runner* r, const dht_infohash* h, dht_op_token* t) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
|
||||
auto token = reinterpret_cast<std::future<size_t>*>(t);
|
||||
runner->cancelListen(*hash, std::move(*token));
|
||||
}
|
||||
|
||||
void dht_op_token_delete(dht_op_token* token) {
|
||||
delete reinterpret_cast<std::future<size_t>*>(token);
|
||||
}
|
||||
|
||||
void dht_runner_put(dht_runner* r, const dht_infohash* h, const dht_value* v, dht_done_cb done_cb, void* cb_user_data, bool permanent) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
|
||||
auto value = reinterpret_cast<const ValueSp*>(v);
|
||||
runner->put(*hash, *value, [done_cb, cb_user_data](bool ok){
|
||||
if (done_cb)
|
||||
done_cb(ok, cb_user_data);
|
||||
}, dht::time_point::max(), permanent);
|
||||
}
|
||||
|
||||
void dht_runner_put_signed(dht_runner* r, const dht_infohash* h, const dht_value* v, dht_done_cb done_cb, void* cb_user_data, bool permanent) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
|
||||
auto value = reinterpret_cast<const ValueSp*>(v);
|
||||
runner->putSigned(*hash, *value, [done_cb, cb_user_data](bool ok){
|
||||
if (done_cb)
|
||||
done_cb(ok, cb_user_data);
|
||||
}, permanent);
|
||||
}
|
||||
|
||||
void dht_runner_put_encrypted(dht_runner* r, const dht_infohash* h, const dht_infohash* to, const dht_value* v, dht_done_cb done_cb, void* cb_user_data, bool permanent) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
|
||||
auto toHash = reinterpret_cast<const dht::InfoHash*>(to);
|
||||
auto value = reinterpret_cast<const ValueSp*>(v);
|
||||
runner->putEncrypted(*hash, *toHash, *value, [done_cb, cb_user_data](bool ok){
|
||||
if (done_cb)
|
||||
done_cb(ok, cb_user_data);
|
||||
}, permanent);
|
||||
}
|
||||
|
||||
void dht_runner_cancel_put(dht_runner* r, const dht_infohash* h, dht_value_id value_id) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
auto hash = reinterpret_cast<const dht::InfoHash*>(h);
|
||||
runner->cancelPut(*hash, value_id);
|
||||
}
|
||||
|
||||
void dht_runner_shutdown(dht_runner* r, dht_shutdown_cb done_cb, void* cb_user_data) {
|
||||
auto runner = reinterpret_cast<dht::DhtRunner*>(r);
|
||||
runner->shutdown([done_cb, cb_user_data](){
|
||||
if (done_cb)
|
||||
done_cb(cb_user_data);
|
||||
});
|
||||
}
|
||||
|
||||
dht_infohash dht_runner_get_node_id(const dht_runner* r) {
|
||||
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
|
||||
dht_infohash ret;
|
||||
*reinterpret_cast<dht::InfoHash*>(&ret) = runner->getNodeId();
|
||||
return ret;
|
||||
}
|
||||
|
||||
dht_infohash dht_runner_get_id(const dht_runner* r) {
|
||||
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
|
||||
dht_infohash ret;
|
||||
*reinterpret_cast<dht::InfoHash*>(&ret) = runner->getId();
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct sockaddr** dht_runner_get_public_address(const dht_runner* r) {
|
||||
auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
|
||||
auto addrs = const_cast<dht::DhtRunner*>(runner)->getPublicAddress();
|
||||
if (addrs.empty())
|
||||
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);
|
||||
} else {
|
||||
ret[i] = nullptr;
|
||||
}
|
||||
}
|
||||
ret[addrs.size()] = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "def.h"
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Non-owning data view
|
||||
struct OPENDHT_C_PUBLIC dht_data_view {
|
||||
const uint8_t* data;
|
||||
size_t size;
|
||||
};
|
||||
typedef struct dht_data_view dht_data_view;
|
||||
|
||||
// dht::Blob
|
||||
struct OPENDHT_C_PUBLIC dht_blob;
|
||||
typedef struct dht_blob dht_blob;
|
||||
OPENDHT_C_PUBLIC dht_data_view dht_blob_get_data(const dht_blob* data);
|
||||
OPENDHT_C_PUBLIC void dht_blob_delete(dht_blob* data);
|
||||
|
||||
// dht::InfoHash
|
||||
struct OPENDHT_C_PUBLIC dht_infohash { uint8_t d[HASH_LEN]; };
|
||||
typedef struct dht_infohash dht_infohash;
|
||||
OPENDHT_C_PUBLIC void dht_infohash_zero(dht_infohash* h);
|
||||
OPENDHT_C_PUBLIC void dht_infohash_random(dht_infohash* h);
|
||||
OPENDHT_C_PUBLIC void dht_infohash_from_hex(dht_infohash* h, const char* dat);
|
||||
OPENDHT_C_PUBLIC void dht_infohash_get(dht_infohash* h, const uint8_t* dat, size_t dat_size);
|
||||
OPENDHT_C_PUBLIC void dht_infohash_get_from_string(dht_infohash* h, const char* str);
|
||||
OPENDHT_C_PUBLIC const char* dht_infohash_print(const dht_infohash* h);
|
||||
OPENDHT_C_PUBLIC bool dht_infohash_is_zero(const dht_infohash* h);
|
||||
|
||||
// dht::PkId
|
||||
struct OPENDHT_C_PUBLIC dht_pkid { uint8_t d[32]; };
|
||||
typedef struct dht_pkid dht_pkid;
|
||||
OPENDHT_C_PUBLIC const char* dht_pkid_print(const dht_pkid* h);
|
||||
|
||||
// dht::crypto::PublicKey
|
||||
struct OPENDHT_C_PUBLIC dht_publickey;
|
||||
typedef struct dht_publickey dht_publickey;
|
||||
OPENDHT_C_PUBLIC dht_publickey* dht_publickey_import(const uint8_t* dat, size_t dat_size);
|
||||
OPENDHT_C_PUBLIC void dht_publickey_delete(dht_publickey* pk);
|
||||
OPENDHT_C_PUBLIC int dht_publickey_export(const dht_publickey* pk, char* out, size_t* out_size);
|
||||
OPENDHT_C_PUBLIC dht_infohash dht_publickey_get_id(const dht_publickey* pk);
|
||||
OPENDHT_C_PUBLIC dht_pkid dht_publickey_get_long_id(const dht_publickey* pk);
|
||||
OPENDHT_C_PUBLIC bool dht_publickey_check_signature(const dht_publickey* pk, const char* data, size_t data_size, const char* signature, size_t signature_size);
|
||||
OPENDHT_C_PUBLIC dht_blob* dht_publickey_encrypt(const dht_publickey* pk, const char* data, size_t data_size);
|
||||
|
||||
// dht::crypto::PrivateKey
|
||||
struct OPENDHT_C_PUBLIC dht_privatekey;
|
||||
typedef struct dht_privatekey dht_privatekey;
|
||||
OPENDHT_C_PUBLIC dht_privatekey* dht_privatekey_generate(unsigned key_length_bits);
|
||||
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 void dht_privatekey_delete(dht_privatekey*);
|
||||
|
||||
// dht::crypto::Certificate
|
||||
struct OPENDHT_C_PUBLIC dht_certificate;
|
||||
typedef struct dht_certificate dht_certificate;
|
||||
OPENDHT_C_PUBLIC dht_certificate* dht_certificate_import(const uint8_t* dat, size_t dat_size);
|
||||
OPENDHT_C_PUBLIC dht_infohash dht_certificate_get_id(const dht_certificate*);
|
||||
OPENDHT_C_PUBLIC dht_pkid dht_certificate_get_long_id(const dht_certificate*);
|
||||
OPENDHT_C_PUBLIC dht_publickey* dht_certificate_get_publickey(const dht_certificate*);
|
||||
OPENDHT_C_PUBLIC void dht_certificate_delete(dht_certificate*);
|
||||
|
||||
struct OPENDHT_PUBLIC dht_identity {
|
||||
dht_privatekey* privatekey;
|
||||
dht_certificate* certificate;
|
||||
};
|
||||
typedef struct dht_identity dht_identity;
|
||||
OPENDHT_C_PUBLIC dht_identity dht_identity_generate(const char* common_name, const dht_identity* ca);
|
||||
OPENDHT_C_PUBLIC void dht_identity_delete(dht_identity*);
|
||||
|
||||
// dht::Value
|
||||
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_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);
|
||||
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);
|
||||
|
||||
// callbacks
|
||||
typedef bool (*dht_get_cb)(const dht_value* value, void* user_data);
|
||||
typedef bool (*dht_value_cb)(const dht_value* value, bool expired, void* user_data);
|
||||
typedef void (*dht_done_cb)(bool ok, void* user_data);
|
||||
typedef void (*dht_shutdown_cb)(void* user_data);
|
||||
|
||||
struct OPENDHT_C_PUBLIC dht_op_token;
|
||||
typedef struct dht_op_token dht_op_token;
|
||||
OPENDHT_C_PUBLIC void dht_op_token_delete(dht_op_token* token);
|
||||
|
||||
// config
|
||||
struct OPENDHT_PUBLIC dht_node_config {
|
||||
dht_infohash node_id;
|
||||
uint32_t network;
|
||||
bool is_bootstrap;
|
||||
bool maintain_storage;
|
||||
const char* persist_path;
|
||||
};
|
||||
typedef struct dht_node_config dht_node_config;
|
||||
|
||||
struct OPENDHT_PUBLIC dht_secure_config {
|
||||
dht_node_config node_config;
|
||||
dht_identity id;
|
||||
};
|
||||
typedef struct dht_secure_config dht_secure_config;
|
||||
|
||||
struct OPENDHT_PUBLIC dht_runner_config {
|
||||
dht_secure_config dht_config;
|
||||
bool threaded;
|
||||
const char* proxy_server;
|
||||
const char* push_node_id;
|
||||
const char* push_token;
|
||||
bool peer_discovery;
|
||||
bool peer_publish;
|
||||
dht_certificate* server_ca;
|
||||
dht_identity client_identity;
|
||||
};
|
||||
typedef struct dht_runner_config dht_runner_config;
|
||||
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 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);
|
||||
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);
|
||||
OPENDHT_C_PUBLIC void dht_runner_cancel_listen(dht_runner* runner, const dht_infohash* hash, dht_op_token* token);
|
||||
OPENDHT_C_PUBLIC void dht_runner_put(dht_runner* runner, const dht_infohash* hash, const dht_value* value, dht_done_cb done_cb, void* cb_user_data, bool permanent);
|
||||
OPENDHT_C_PUBLIC void dht_runner_put_signed(dht_runner* runner, const dht_infohash* hash, const dht_value* value, dht_done_cb done_cb, void* cb_user_data, bool permanent);
|
||||
OPENDHT_C_PUBLIC void dht_runner_put_encrypted(dht_runner* runner, const dht_infohash* hash, const dht_infohash* to, const dht_value* value, dht_done_cb done_cb, void* cb_user_data, bool permanent);
|
||||
OPENDHT_C_PUBLIC void dht_runner_cancel_put(dht_runner* runner, const dht_infohash* hash, dht_value_id value_id);
|
||||
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 struct sockaddr** dht_runner_get_public_address(const dht_runner* runner);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
if(NOT Restbed_FOUND)
|
||||
find_path (Restbed_INCLUDE_DIR restbed
|
||||
HINTS
|
||||
"/usr/include"
|
||||
"/usr/local/include"
|
||||
"/opt/local/include")
|
||||
find_library(Restbed_LIBRARY restbed
|
||||
HINTS ${Restbed_ROOT_DIR} PATH_SUFFIXES lib)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Restbed DEFAULT_MSG Restbed_LIBRARY Restbed_INCLUDE_DIR)
|
||||
if (Restbed_INCLUDE_DIR)
|
||||
set(Restbed_FOUND TRUE)
|
||||
set(Restbed_LIBRARIES ${Restbed_LIBRARY})
|
||||
set(Restbed_INCLUDE_DIRS ${Restbed_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,14 @@
|
||||
# header-only does not produce a library
|
||||
if(NOT Restinio_FOUND)
|
||||
find_path (Restinio_INCLUDE_DIR restinio
|
||||
HINTS
|
||||
"/usr/include"
|
||||
"/usr/local/include"
|
||||
"/opt/local/include")
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Restinio DEFAULT_MSG Restinio_INCLUDE_DIR)
|
||||
if (Restinio_INCLUDE_DIR)
|
||||
set(Restinio_FOUND TRUE)
|
||||
set(Restinio_INCLUDE_DIRS ${Restinio_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
+52
-23
@@ -1,7 +1,7 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 1)
|
||||
m4_define([opendht_minor_version], 8)
|
||||
m4_define([opendht_patch_version], 2)
|
||||
m4_define([opendht_major_version], 2)
|
||||
m4_define([opendht_minor_version], 0)
|
||||
m4_define([opendht_patch_version], 0)
|
||||
m4_define([opendht_version],
|
||||
[opendht_major_version.opendht_minor_version.opendht_patch_version])
|
||||
|
||||
@@ -35,10 +35,14 @@ AS_IF([test "x$enable_logs" != "xno"], [
|
||||
dnl Check for indexation
|
||||
AC_ARG_ENABLE([indexation], [AS_HELP_STRING([--disable-indexation], [Disable DHT indexation])])
|
||||
AM_CONDITIONAL(ENABLE_INDEXATION, test x$enable_indexation != "xno")
|
||||
AS_IF([test "x$enable_indexation" != "xno"], [
|
||||
AC_DEFINE([OPENDHT_INDEXATION], [1], [Define if DHT indexation is enabled])
|
||||
AM_COND_IF(ENABLE_INDEXATION, [
|
||||
AC_DEFINE([OPENDHT_INDEXATION], [], [Define if DHT indexation is enabled])
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE([peer-discovery], [AS_HELP_STRING([--disable-peer-discovery], [Disable peer-discovery])])
|
||||
AM_CONDITIONAL(ENABLE_PEER_DISCOVERY, test x$enable_peer_discovery != "xno")
|
||||
AM_COND_IF(ENABLE_PEER_DISCOVERY, [AC_DEFINE([OPENDHT_PEER_DISCOVERY], [], [Define if peer discovery is enabled])])
|
||||
|
||||
dnl Check for Doxygen
|
||||
AC_ARG_ENABLE([doc], AS_HELP_STRING([--enable-doc], [Enable documentation generation (doxygen)]))
|
||||
AS_IF([test "x$enable_doc" = "xyes"], [
|
||||
@@ -98,7 +102,7 @@ AS_IF([test "x$SYS" = "xandroid"],
|
||||
LT_INIT()
|
||||
LT_LANG(C++)
|
||||
|
||||
AX_CXX_COMPILE_STDCXX(11,[noext],[mandatory])
|
||||
AX_CXX_COMPILE_STDCXX(14,[noext],[mandatory])
|
||||
|
||||
PKG_PROG_PKG_CONFIG()
|
||||
|
||||
@@ -123,7 +127,7 @@ AM_COND_IF([ENABLE_TESTS], [
|
||||
PKG_CHECK_MODULES([CppUnit], [cppunit >= 1.12])
|
||||
])
|
||||
|
||||
AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes | test x$proxy_server == xyes)
|
||||
AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes || test x$proxy_server == xyes)
|
||||
|
||||
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
|
||||
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
|
||||
@@ -135,15 +139,43 @@ AS_IF([test "x$with_jsoncpp" != "xno"],
|
||||
[have_jsoncpp=no])
|
||||
AS_IF([test "x$have_jsoncpp" = "xyes"], [
|
||||
AC_MSG_NOTICE([Using JsonCpp])
|
||||
CPPFLAGS+=" -DOPENDHT_JSONCPP=1"
|
||||
CPPFLAGS+=" -DOPENDHT_JSONCPP"
|
||||
], [
|
||||
AC_MSG_NOTICE([Not using JsonCpp])
|
||||
AM_COND_IF(PROXY_CLIENT_OR_SERVER, AC_MSG_ERROR(["JsonCpp is required for proxy/push notification support"]))
|
||||
])
|
||||
|
||||
AC_ARG_WITH([openssl], AS_HELP_STRING([--without-openssl], [Build with OpenSSL support]))
|
||||
AS_IF([test "x$with_openssl" != "xno"],
|
||||
[PKG_CHECK_MODULES([OpenSSL], [openssl >= 1.1], [have_openssl=yes], [have_openssl=no])],
|
||||
[have_openssl=no])
|
||||
AS_IF([test "x$have_openssl" = "xyes"], [
|
||||
AC_MSG_NOTICE([Using OpenSSL])
|
||||
], [
|
||||
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_LIB(restbed, exit,, AC_MSG_ERROR([Missing restbed files]))
|
||||
LDFLAGS="${LDFLAGS} -lrestbed"
|
||||
AC_CHECK_HEADERS([asio.hpp], exit,, AC_MSG_ERROR([Missing Asio headers files]))
|
||||
CXXFLAGS="${CXXFLAGS} -DASIO_STANDALONE"
|
||||
PKG_CHECK_MODULES([Fmt], [fmt >= 5.3.0], [have_fmt=yes], [have_fmt=no])
|
||||
AS_IF([test "x$have_fmt" = "xyes"], [
|
||||
AC_MSG_NOTICE([Using libfmt])
|
||||
], [
|
||||
AC_MSG_NOTICE([Missing libfmt files])
|
||||
])
|
||||
# http_parser has no pkgconfig, instead we check with:
|
||||
AC_CHECK_LIB(http_parser, exit,, AC_MSG_ERROR([Missing HttpParser library files]))
|
||||
AC_CHECK_HEADERS([http_parser.h], [http_parser_headers=yes; break;])
|
||||
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"
|
||||
@@ -177,27 +209,24 @@ AM_COND_IF([ENABLE_TOOLS], [
|
||||
])
|
||||
])
|
||||
|
||||
AM_COND_IF(ENABLE_PROXY_SERVER, [CPPFLAGS+=" -DOPENDHT_PROXY_SERVER"], [])
|
||||
AM_COND_IF(ENABLE_PROXY_CLIENT, [CPPFLAGS+=" -DOPENDHT_PROXY_CLIENT"], [])
|
||||
AM_COND_IF(ENABLE_PROXY_SERVER, AC_DEFINE([OPENDHT_PROXY_SERVER], [], [Building with proxy server]))
|
||||
AM_COND_IF(ENABLE_PROXY_CLIENT, AC_DEFINE([OPENDHT_PROXY_CLIENT], [], [Building with proxy client]))
|
||||
AM_COND_IF(ENABLE_PUSH_NOTIFICATIONS, [CPPFLAGS+=" -DOPENDHT_PUSH_NOTIFICATIONS"], [])
|
||||
AM_COND_IF(ENABLE_PROXY_SERVER_IDENTITY, [CPPFLAGS+=" -DOPENDHT_PROXY_SERVER_IDENTITY"], [])
|
||||
|
||||
AM_COND_IF([HAVE_DOXYGEN], [
|
||||
AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])
|
||||
])
|
||||
|
||||
dnl Configure setup.py if we build the python module
|
||||
AM_COND_IF([USE_CYTHON], [
|
||||
AC_SUBST(CURRENT_SOURCE_DIR, ".")
|
||||
AC_SUBST(CURRENT_BINARY_DIR, ".")
|
||||
AC_SUBST(PROJECT_SOURCE_DIR, "..")
|
||||
AC_SUBST(PROJECT_BINARY_DIR, "../src/.libs")
|
||||
AC_CONFIG_FILES([python/Makefile python/setup.py])
|
||||
])
|
||||
AC_SUBST(CURRENT_SOURCE_DIR, ".")
|
||||
AC_SUBST(CURRENT_BINARY_DIR, ".")
|
||||
AC_SUBST(PROJECT_SOURCE_DIR, "..")
|
||||
AC_SUBST(PROJECT_BINARY_DIR, "../src/.libs")
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/Makefile
|
||||
tools/Makefile
|
||||
python/Makefile
|
||||
python/setup.py
|
||||
tests/Makefile
|
||||
doc/Makefile
|
||||
doc/Doxyfile
|
||||
opendht.pc])
|
||||
AC_OUTPUT
|
||||
+4
-1
@@ -1,7 +1,10 @@
|
||||
dist_man1_MANS = dhtnode.1
|
||||
|
||||
noinst_HEADERS = \
|
||||
Doxyfile
|
||||
|
||||
if HAVE_DOXYGEN
|
||||
doxyfile.stamp:
|
||||
doxyfile.stamp: Doxyfile
|
||||
$(DOXYGEN) Doxyfile
|
||||
echo stamp > doxyfile.stamp
|
||||
|
||||
|
||||
+57
-35
@@ -1,22 +1,24 @@
|
||||
.TH DHTNODE 1 2016-07-29
|
||||
|
||||
.TH DHTNODE 1 2019-06-08
|
||||
.SH NAME
|
||||
.B dhtnode
|
||||
- a simple OpenDHT command line node runner.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B dhtnode [-h]
|
||||
|
||||
.B dhtnode [-v [-l \fIlogfile\fP]] [-i] [-d] [-n \fInetwork_id\fP] [-p \fIlocal_port\fP] [-b \fIbootstrap_host\fP[:\fIport\fP]]
|
||||
|
||||
.B dhtnode
|
||||
[\fB\-h\fR]
|
||||
[\fB\-v\fR [\fB\-l\fR \fIlogfile\fR] [\fB\-L\fR]]
|
||||
[\fB\-i\fR [\fB\-\-save\-identity\fR \fIfile\fR]]
|
||||
[\fB\-d\fR] [\fB\-s\fR]
|
||||
[\fB\-n\fR \fInetwork_id\fR]
|
||||
[\fB\-p\fR \fIlocal_port\fR]
|
||||
[\fB\-b\fR \fIbootstrap_host\fR[:\fIport\fR]]
|
||||
[\fB\-\-certificate\fR \fIfile\fR]
|
||||
[\fB\-\-privkey\fR \fIfile\fR]
|
||||
[\fB\-\-privkey\-password\fR \fIpassword\fR]
|
||||
[\fB\-\-proxyserver\fR \fIport\fR]
|
||||
[\fB\-\-proxyclient\fR \fIserver\fR]
|
||||
.SH DESCRIPTION
|
||||
|
||||
This program runs a simple OpenDHT node in an interactive way. If you rather
|
||||
want to run the node in daemon mode, option \fB'-d'\fP is provided. When running
|
||||
in the interactive shell, you benefit from the readline capabilities for writing
|
||||
your commands such as command history. Here are the available commands in the
|
||||
interactive shell:
|
||||
|
||||
Runs an OpenDHT node, with a CLI (default) or as a daemon (with \fB'-d'\fP or \fB'-s'\fP).
|
||||
Commands available in the interactive shell are:
|
||||
.EE
|
||||
h, help Print this help message.
|
||||
q, quit Quit the program.
|
||||
@@ -37,43 +39,63 @@ interactive shell:
|
||||
private key.
|
||||
e [key] [dest] [str] Put string value at [key], encrypted for [dest] with
|
||||
its public key (if found).
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
\fB-h\fP
|
||||
\fB\-h\fP
|
||||
Prints some help.
|
||||
|
||||
.TP
|
||||
\fB-v\fP
|
||||
Enable the verbose mode (log to stdout by default)
|
||||
|
||||
\fB\-v\fP
|
||||
Enable the verbose mode (log to stdout/stderr by default)
|
||||
.TP
|
||||
\fB-l\fP \fIlog_file\fP
|
||||
Write log to file instead of stdout
|
||||
|
||||
\fB\-l\fP \fIlog_file\fP
|
||||
Write log to file instead of stdout/stderr
|
||||
.TP
|
||||
\fB-i\fP
|
||||
\fB\-L\fP
|
||||
Write log to syslog instead of stdout/stderr
|
||||
.TP
|
||||
\fB\-i\fP
|
||||
Generate cryptographic identity for the node.
|
||||
|
||||
.TP
|
||||
\fB-d\fP
|
||||
\fB\-\-save\-identity\fP \fIfile\fP
|
||||
Save generated identity (certificate and private key) to given file prefix.
|
||||
.TP
|
||||
\fB\-\-certificate\fP \fIfile\fP
|
||||
Load identity certificate from given file.
|
||||
.TP
|
||||
\fB\-\-privkey\fP \fIfile\fP
|
||||
Load identity private key from given file.
|
||||
.TP
|
||||
\fB\-\-privkey\-password\fP \fIpassword\fP
|
||||
Password to use for private key encryption or decryption (optional).
|
||||
.TP
|
||||
\fB\-d\fP
|
||||
Run the program in daemon mode (will fork in the background).
|
||||
|
||||
.TP
|
||||
\fB-n\fP \fInetwork_id\fP
|
||||
\fB\-s\fP
|
||||
Run the program in service mode (non\-forking daemon).
|
||||
.TP
|
||||
\fB\-D\fP
|
||||
Enables multicast automatic local peer discovery.
|
||||
.TP
|
||||
\fB\-f\fP \fIfile\fP
|
||||
Specify a file path to persist/load the node state.
|
||||
.TP
|
||||
\fB\-n\fP \fInetwork_id\fP
|
||||
Specify the network id. This let you connect to distinct networks and prevents
|
||||
the merge of two different networks (available since OpenDHT v0.6.1).
|
||||
|
||||
.TP
|
||||
\fB-p\fP \fIlocal_port\fP
|
||||
Use port \fIlocal_port\fP for the program to bind to.
|
||||
|
||||
\fB\-p\fP \fIlocal_port\fP
|
||||
Use UDP port \fIlocal_port\fP for the program to bind to.
|
||||
.TP
|
||||
\fB-b\fP \fIbootstrap_host\fP[:\fIport\fP]
|
||||
\fB\-b\fP \fIbootstrap_host\fP[:\fIport\fP]
|
||||
The program needs to be given a node to connect to the network. You use this
|
||||
option to provide the ip address of that node.
|
||||
|
||||
.TP
|
||||
\fB\-\-proxyserver\fP \fIlocal_port\fP
|
||||
Run a proxy server bound to this DHT node on HTTP port \fIlocal_port\fP
|
||||
.TP
|
||||
\fB\-\-proxyclient\fP \fIserver\fP
|
||||
Run this DHT node in proxy client mode, and connect to \fIserver\fP
|
||||
.SH AUTHORS
|
||||
.TP
|
||||
Program written by
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
FROM docker.pkg.github.com/savoirfairelinux/opendht/opendht-deps-bionic:2.0.0
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
|
||||
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 \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
+44
-6
@@ -1,6 +1,44 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
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 libcppunit-dev libjsoncpp-dev libasio-dev libssl-dev python3-setuptools && apt-get clean
|
||||
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
|
||||
|
||||
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/b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz \
|
||||
&& tar -xvf b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz && cd asio-b2b7a1c166390459e1c169c8ae9ef3234b361e3f/asio \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
|
||||
&& make install \
|
||||
&& cd ../../ && rm -rf asio*
|
||||
|
||||
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 \
|
||||
&& 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 \
|
||||
@@ -11,8 +49,8 @@ RUN git clone --recursive https://github.com/corvusoft/restbed.git \
|
||||
|
||||
#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
|
||||
&& 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,28 @@
|
||||
FROM ubuntu:18.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
|
||||
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 \
|
||||
libgnutls28-dev libuv1-dev cython3 python3-dev python3-setuptools libcppunit-dev libjsoncpp-dev \
|
||||
autotools-dev autoconf libfmt-dev libhttp-parser-dev libmsgpack-dev \
|
||||
&& apt-get clean
|
||||
|
||||
# libasio-dev (1.10) is too old
|
||||
RUN echo "** Building a recent version of asio ***" \
|
||||
&& wget https://github.com/aberaud/asio/archive/b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz \
|
||||
&& tar -xvf b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz && cd asio-b2b7a1c166390459e1c169c8ae9ef3234b361e3f/asio \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr --without-boost --disable-examples --disable-tests \
|
||||
&& make install \
|
||||
&& cd ../../ && rm -rf asio*
|
||||
|
||||
RUN echo "*** Downloading RESTinio ***" \
|
||||
&& mkdir restinio && cd restinio \
|
||||
&& wget https://github.com/aberaud/restinio/archive/8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59.tar.gz \
|
||||
&& ls -l && tar -xzf 8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59.tar.gz \
|
||||
&& cd restinio-8d5d3e8237e0947adb9ba1ffc8281f4ad7cb2a59/dev \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF \
|
||||
-DRESTINIO_INSTALL_SAMPLES=OFF -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF \
|
||||
-DRESTINIO_FIND_DEPS=ON -DRESTINIO_ALLOW_SOBJECTIZER=Off -DRESTINIO_USE_BOOST_ASIO=none . \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../../ && rm -rf restinio*
|
||||
@@ -1,12 +1,51 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y llvm llvm-dev clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls28-dev libuv1-dev libmsgpack-dev libjsoncpp-dev libasio-dev cython3 python3-dev python3-setuptools libcppunit-dev \
|
||||
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
|
||||
&& apt-get install -y llvm llvm-dev clang make cmake 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
|
||||
|
||||
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/b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz \
|
||||
&& tar -xvf b2b7a1c166390459e1c169c8ae9ef3234b361e3f.tar.gz && cd asio-b2b7a1c166390459e1c169c8ae9ef3234b361e3f/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 \
|
||||
&& 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 \
|
||||
@@ -16,8 +55,8 @@ RUN git clone --recursive https://github.com/corvusoft/restbed.git \
|
||||
|
||||
#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
|
||||
&& 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
|
||||
@@ -19,11 +19,4 @@
|
||||
#pragma once
|
||||
|
||||
#include "opendht/dhtrunner.h"
|
||||
#ifdef OPENDHT_PROXY_SERVER
|
||||
#include "opendht/dht_proxy_server.h"
|
||||
#endif
|
||||
#include "opendht/log.h"
|
||||
#include "opendht/default_types.h"
|
||||
#ifdef OPENDHT_INDEXATION
|
||||
#include "opendht/indexation/pht.h"
|
||||
#endif
|
||||
+29
-12
@@ -44,6 +44,13 @@ enum class NodeStatus {
|
||||
Connected // 1+ good nodes
|
||||
};
|
||||
|
||||
inline constexpr const char*
|
||||
statusToStr(NodeStatus status) {
|
||||
return status == NodeStatus::Connected ? "connected" : (
|
||||
status == NodeStatus::Connecting ? "connecting" :
|
||||
"disconnected");
|
||||
}
|
||||
|
||||
struct OPENDHT_PUBLIC NodeStats {
|
||||
unsigned good_nodes {0},
|
||||
dubious_nodes {0},
|
||||
@@ -69,8 +76,9 @@ struct OPENDHT_PUBLIC NodeStats {
|
||||
struct OPENDHT_PUBLIC NodeInfo {
|
||||
InfoHash id;
|
||||
InfoHash node_id;
|
||||
NodeStats ipv4;
|
||||
NodeStats ipv6;
|
||||
NodeStats ipv4 {};
|
||||
NodeStats ipv6 {};
|
||||
size_t ongoing_ops {0};
|
||||
|
||||
#ifdef OPENDHT_JSONCPP
|
||||
/**
|
||||
@@ -89,33 +97,41 @@ struct OPENDHT_PUBLIC NodeInfo {
|
||||
*/
|
||||
struct OPENDHT_PUBLIC Config {
|
||||
/** DHT node ID */
|
||||
InfoHash node_id;
|
||||
InfoHash node_id {};
|
||||
|
||||
/**
|
||||
* DHT network ID. A node will only talk with other nodes having
|
||||
* the same network ID.
|
||||
* Network ID 0 (default) represents the main public network.
|
||||
*/
|
||||
NetId network;
|
||||
NetId network {0};
|
||||
|
||||
/** For testing purposes only, enables bootstrap mode */
|
||||
bool is_bootstrap;
|
||||
bool is_bootstrap {false};
|
||||
|
||||
/** Makes the DHT responsible to maintain its stored values. Consumes more ressources. */
|
||||
bool maintain_storage;
|
||||
bool maintain_storage {false};
|
||||
|
||||
/** If set, the dht will load its state from this file on start and save its state in this file on shutdown */
|
||||
std::string persist_path;
|
||||
std::string persist_path {};
|
||||
|
||||
/** If non-0, overrides the default global rate-limit.-1 means no limit. */
|
||||
ssize_t max_req_per_sec {0};
|
||||
|
||||
/** If non-0, overrides the default per-IP address rate-limit. -1 means no limit. */
|
||||
ssize_t max_peer_req_per_sec {0};
|
||||
};
|
||||
|
||||
#ifndef OPENDHT_LIGHT
|
||||
/**
|
||||
* SecureDht configuration.
|
||||
*/
|
||||
struct OPENDHT_PUBLIC SecureDhtConfig
|
||||
{
|
||||
Config node_config;
|
||||
crypto::Identity id;
|
||||
Config node_config {};
|
||||
crypto::Identity id {};
|
||||
};
|
||||
#endif
|
||||
|
||||
static constexpr size_t DEFAULT_STORAGE_LIMIT {1024 * 1024 * 64};
|
||||
|
||||
@@ -130,9 +146,7 @@ using ShutdownCallback = std::function<void()>;
|
||||
using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::Certificate>>(const InfoHash& pk_id)>;
|
||||
|
||||
typedef bool (*GetCallbackRaw)(std::shared_ptr<Value>, void *user_data);
|
||||
|
||||
OPENDHT_PUBLIC GetCallbackSimple bindGetCb(const GetCallbackRaw& raw_cb, void* user_data);
|
||||
OPENDHT_PUBLIC GetCallback bindGetCb(const GetCallbackSimple& cb);
|
||||
typedef bool (*ValueCallbackRaw)(std::shared_ptr<Value>, bool expired, void *user_data);
|
||||
|
||||
using DoneCallback = std::function<void(bool success, const std::vector<std::shared_ptr<Node>>& nodes)>;
|
||||
typedef void (*DoneCallbackRaw)(bool, std::vector<std::shared_ptr<Node>>*, void *user_data);
|
||||
@@ -142,6 +156,9 @@ 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 DoneCallback bindDoneCb(DoneCallbackSimple donecb);
|
||||
OPENDHT_PUBLIC DoneCallback bindDoneCb(const DoneCallbackRaw& raw_cb, void* user_data);
|
||||
|
||||
@@ -43,16 +43,22 @@ namespace dht {
|
||||
namespace crypto {
|
||||
|
||||
class OPENDHT_PUBLIC CryptoException : public std::runtime_error {
|
||||
public:
|
||||
CryptoException(const std::string& str) : std::runtime_error(str) {};
|
||||
public:
|
||||
explicit CryptoException(const std::string& str) : std::runtime_error(str) {};
|
||||
explicit CryptoException(const char* str) : std::runtime_error(str) {};
|
||||
CryptoException(const CryptoException& e) noexcept = default;
|
||||
CryptoException& operator=(const CryptoException&) noexcept = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown when a decryption error happened.
|
||||
*/
|
||||
class OPENDHT_PUBLIC DecryptError : public CryptoException {
|
||||
public:
|
||||
DecryptError(const std::string& str = "") : CryptoException(str) {};
|
||||
public:
|
||||
explicit DecryptError(const std::string& str) : CryptoException(str) {};
|
||||
explicit DecryptError(const char* str) : CryptoException(str) {};
|
||||
DecryptError(const DecryptError& e) noexcept = default;
|
||||
DecryptError& operator=(const DecryptError&) noexcept = default;
|
||||
};
|
||||
|
||||
struct PrivateKey;
|
||||
@@ -72,7 +78,8 @@ struct OPENDHT_PUBLIC PublicKey
|
||||
* Takes ownership of an existing gnutls_pubkey.
|
||||
*/
|
||||
PublicKey(gnutls_pubkey_t k) : pk(k) {}
|
||||
PublicKey(const Blob& pk);
|
||||
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; };
|
||||
|
||||
~PublicKey();
|
||||
@@ -96,8 +103,15 @@ struct OPENDHT_PUBLIC PublicKey
|
||||
*/
|
||||
PkId getLongId() const;
|
||||
|
||||
bool checkSignature(const Blob& data, const Blob& signature) const;
|
||||
Blob encrypt(const Blob&) 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 {
|
||||
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 {
|
||||
return encrypt(data.data(), data.size());
|
||||
}
|
||||
|
||||
void pack(Blob& b) const;
|
||||
void unpack(const uint8_t* dat, size_t dat_size);
|
||||
@@ -140,11 +154,13 @@ struct OPENDHT_PUBLIC PrivateKey
|
||||
PrivateKey(PrivateKey&& o) noexcept;
|
||||
PrivateKey& operator=(PrivateKey&& o) noexcept;
|
||||
|
||||
PrivateKey(const Blob& import, const std::string& password = {});
|
||||
PrivateKey(const uint8_t* src, size_t src_size, const char* password = nullptr);
|
||||
PrivateKey(const Blob& src, const std::string& password = {}) : PrivateKey(src.data(), src.size(), password.data()) {}
|
||||
~PrivateKey();
|
||||
explicit operator bool() const { return key; }
|
||||
|
||||
PublicKey getPublicKey() const;
|
||||
int serialize(uint8_t* out, size_t* out_len, const std::string& password = {}) const;
|
||||
Blob serialize(const std::string& password = {}) const;
|
||||
|
||||
/**
|
||||
@@ -283,6 +299,7 @@ public:
|
||||
bool verify() const;
|
||||
|
||||
Blob pack() const;
|
||||
std::string toString() const;
|
||||
|
||||
gnutls_x509_crq_t get() const { return request; }
|
||||
private:
|
||||
@@ -654,6 +671,7 @@ OPENDHT_PUBLIC Identity generateIdentity(const std::string& name = "dhtnode", co
|
||||
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name, const Identity& ca, bool is_ca);
|
||||
OPENDHT_PUBLIC Identity generateEcIdentity(const std::string& name = "dhtnode", const Identity& ca = {});
|
||||
|
||||
OPENDHT_PUBLIC void saveIdentity(const Identity& id, const std::string& path, const std::string& privkey_password = {});
|
||||
|
||||
/**
|
||||
* Performs SHA512, SHA256 or SHA1, depending on hash_length.
|
||||
@@ -679,7 +697,10 @@ OPENDHT_PUBLIC Blob stretchKey(const std::string& password, Blob& salt, size_t k
|
||||
/**
|
||||
* AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes).
|
||||
*/
|
||||
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const Blob& key);
|
||||
OPENDHT_PUBLIC Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key);
|
||||
OPENDHT_PUBLIC inline Blob aesEncrypt(const Blob& data, const Blob& key) {
|
||||
return aesEncrypt(data.data(), data.size(), key);
|
||||
}
|
||||
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,3 +26,19 @@
|
||||
#define OPENDHT_PUBLIC
|
||||
#define OPENDHT_LOCAL
|
||||
#endif // opendht_EXPORTS
|
||||
|
||||
|
||||
#ifdef opendht_c_EXPORTS // defined if OpenDHT is compiled as a shared library
|
||||
#ifdef OPENDHT_C_BUILD // defined if we are building the OpenDHT shared library (instead of using it)
|
||||
#define OPENDHT_C_PUBLIC OPENDHT_EXPORT
|
||||
#else
|
||||
#define OPENDHT_C_PUBLIC OPENDHT_IMPORT
|
||||
#endif // OPENDHT_BUILD
|
||||
#define OPENDHT_C_LOCAL OPENDHT_HIDDEN
|
||||
#else // opendht_EXPORTS is not defined: this means OpenDHT is a static lib.
|
||||
#define OPENDHT_C_PUBLIC
|
||||
#define OPENDHT_C_LOCAL
|
||||
#endif // opendht_EXPORTS
|
||||
|
||||
// bytes
|
||||
#define HASH_LEN 20u
|
||||
@@ -58,6 +58,7 @@ public:
|
||||
MSGPACK_DEFINE(service, data)
|
||||
};
|
||||
|
||||
#ifndef OPENDHT_LIGHT
|
||||
template <typename T>
|
||||
class OPENDHT_PUBLIC SignedValue : public Value::Serializable<T>
|
||||
{
|
||||
@@ -102,7 +103,6 @@ public:
|
||||
|
||||
|
||||
|
||||
|
||||
class OPENDHT_PUBLIC ImMessage : public SignedValue<ImMessage>
|
||||
{
|
||||
private:
|
||||
@@ -114,8 +114,10 @@ public:
|
||||
ImMessage() {}
|
||||
ImMessage(dht::Value::Id id, std::string&& m, long d = 0)
|
||||
: id(id), msg(std::move(m)), date(d) {}
|
||||
ImMessage(dht::Value::Id id, std::string&& dt, std::string&& m, long d = 0)
|
||||
ImMessage(dht::Value::Id id, std::string &&dt, std::string &&m, long d = 0)
|
||||
: id(id), msg(std::move(m)), datatype(std::move(dt)), date(d) {}
|
||||
ImMessage(dht::Value::Id id, std::string &&dt, std::string &&m, std::map<std::string, std::string> &&md, long d = 0)
|
||||
: id(id), msg(std::move(m)), datatype(std::move(dt)), metadatas(std::move(md)), date(d) {}
|
||||
|
||||
virtual void unpackValue(const Value& v) override {
|
||||
to = v.recipient;
|
||||
@@ -126,10 +128,11 @@ public:
|
||||
dht::Value::Id id {0};
|
||||
std::string msg;
|
||||
std::string datatype;
|
||||
std::map<std::string, std::string> metadatas;
|
||||
long date {0};
|
||||
ImStatus status {ImStatus::NONE};
|
||||
|
||||
MSGPACK_DEFINE_MAP(id, msg, date, status, datatype)
|
||||
MSGPACK_DEFINE_MAP(id, msg, date, status, datatype, metadatas)
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC TrustRequest : public EncryptedValue<TrustRequest>
|
||||
@@ -174,16 +177,8 @@ public:
|
||||
{
|
||||
pk.pack_array(2);
|
||||
pk.pack(id);
|
||||
#if 1
|
||||
pk.pack_bin(ice_data.size());
|
||||
pk.pack_bin_body((const char*)ice_data.data(), ice_data.size());
|
||||
#else
|
||||
// hack for backward compatibility with old opendht compiled with msgpack 1.0
|
||||
// remove when enough people have moved to new versions
|
||||
pk.pack_array(ice_data.size());
|
||||
for (uint8_t b : ice_data)
|
||||
pk.pack(b);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void msgpack_unpack(msgpack::object o)
|
||||
@@ -197,6 +192,7 @@ public:
|
||||
Value::Id id {0};
|
||||
Blob ice_data;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* "Peer" announcement
|
||||
*/
|
||||
@@ -258,8 +254,11 @@ private:
|
||||
SockAddr addr;
|
||||
};
|
||||
|
||||
|
||||
#ifndef OPENDHT_LIGHT
|
||||
OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 5> DEFAULT_TYPES;
|
||||
#else
|
||||
OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_TYPES;
|
||||
#endif
|
||||
|
||||
OPENDHT_PUBLIC extern const std::array<std::reference_wrapper<const ValueType>, 1> DEFAULT_INSECURE_TYPES;
|
||||
|
||||
|
||||
+54
-63
@@ -68,27 +68,29 @@ public:
|
||||
* Initialise the Dht with two open sockets (for IPv4 and IP6)
|
||||
* and an ID for the node.
|
||||
*/
|
||||
Dht(const int& s, const int& s6, const Config& config);
|
||||
Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Logger& l = {});
|
||||
virtual ~Dht();
|
||||
|
||||
/**
|
||||
* Get the ID of the node.
|
||||
*/
|
||||
inline const InfoHash& getNodeId() const { return myid; }
|
||||
inline const InfoHash& getNodeId() const override { return myid; }
|
||||
|
||||
/**
|
||||
* Get the current status of the node for the given family.
|
||||
*/
|
||||
NodeStatus getStatus(sa_family_t af) const;
|
||||
NodeStatus getStatus(sa_family_t af) const override;
|
||||
|
||||
NodeStatus getStatus() const {
|
||||
NodeStatus getStatus() const override {
|
||||
return std::max(getStatus(AF_INET), getStatus(AF_INET6));
|
||||
}
|
||||
|
||||
net::DatagramSocket* getSocket() const override { return network_engine.getSocket(); };
|
||||
|
||||
/**
|
||||
* Performs final operations before quitting.
|
||||
*/
|
||||
void shutdown(ShutdownCallback cb);
|
||||
void shutdown(ShutdownCallback cb) override;
|
||||
|
||||
/**
|
||||
* Returns true if the node is running (have access to an open socket).
|
||||
@@ -96,12 +98,12 @@ public:
|
||||
* af: address family. If non-zero, will return true if the node
|
||||
* is running for the provided family.
|
||||
*/
|
||||
bool isRunning(sa_family_t af = 0) const;
|
||||
bool isRunning(sa_family_t af = 0) const override;
|
||||
|
||||
virtual void registerType(const ValueType& type) {
|
||||
virtual void registerType(const ValueType& type) override {
|
||||
types.registerType(type);
|
||||
}
|
||||
const ValueType& getType(ValueType::Id type_id) const {
|
||||
const ValueType& getType(ValueType::Id type_id) const override {
|
||||
return types.getType(type_id);
|
||||
}
|
||||
|
||||
@@ -110,18 +112,15 @@ public:
|
||||
* The node is not pinged, so this should be
|
||||
* used to bootstrap efficiently from previously known nodes.
|
||||
*/
|
||||
void insertNode(const InfoHash& id, const SockAddr&);
|
||||
void insertNode(const InfoHash& id, const sockaddr* sa, socklen_t salen) {
|
||||
insertNode(id, SockAddr(sa, salen));
|
||||
}
|
||||
void insertNode(const NodeExport& n) {
|
||||
void insertNode(const InfoHash& id, const SockAddr&) override;
|
||||
void insertNode(const NodeExport& n) override {
|
||||
insertNode(n.id, SockAddr(n.ss, n.sslen));
|
||||
}
|
||||
|
||||
void pingNode(const sockaddr*, socklen_t, DoneCallbackSimple&& cb={});
|
||||
void pingNode(SockAddr, DoneCallbackSimple&& cb={}) override;
|
||||
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, const SockAddr&);
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) {
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr) override;
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
|
||||
return periodic(buf, buflen, SockAddr(from, fromlen));
|
||||
}
|
||||
|
||||
@@ -135,14 +134,14 @@ public:
|
||||
cb and donecb won't be called again afterward.
|
||||
* @param f a filter function used to prefilter values.
|
||||
*/
|
||||
virtual void get(const InfoHash& key, GetCallback cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {});
|
||||
virtual void get(const InfoHash& key, GetCallback cb, DoneCallbackSimple donecb={}, Value::Filter&& f={}, Where&& w = {}) {
|
||||
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));
|
||||
}
|
||||
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallback donecb={}, Value::Filter&& f={}, 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));
|
||||
}
|
||||
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallbackSimple donecb, Value::Filter&& f={}, 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));
|
||||
}
|
||||
/**
|
||||
@@ -155,20 +154,20 @@ public:
|
||||
* @param q a query used to filter values on the remotes before they send a
|
||||
* response.
|
||||
*/
|
||||
virtual void query(const InfoHash& key, QueryCallback cb, DoneCallback done_cb = {}, Query&& q = {});
|
||||
virtual void query(const InfoHash& key, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query&& q = {}) {
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get locally stored data for the given hash.
|
||||
*/
|
||||
std::vector<Sp<Value>> getLocal(const InfoHash& key, Value::Filter f = {}) const;
|
||||
std::vector<Sp<Value>> getLocal(const InfoHash& key, const Value::Filter& f = {}) const override;
|
||||
|
||||
/**
|
||||
* Get locally stored data for the given key and value id.
|
||||
*/
|
||||
Sp<Value> getLocalById(const InfoHash& key, Value::Id vid) const;
|
||||
Sp<Value> getLocalById(const InfoHash& key, Value::Id vid) const override;
|
||||
|
||||
/**
|
||||
* Announce a value on all available protocols (IPv4, IPv6).
|
||||
@@ -180,12 +179,12 @@ public:
|
||||
Sp<Value>,
|
||||
DoneCallback cb=nullptr,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false);
|
||||
bool permanent = false) override;
|
||||
void put(const InfoHash& key,
|
||||
const Sp<Value>& v,
|
||||
DoneCallbackSimple cb,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, v, bindDoneCb(cb), created, permanent);
|
||||
}
|
||||
@@ -194,7 +193,7 @@ public:
|
||||
Value&& v,
|
||||
DoneCallback cb=nullptr,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, std::make_shared<Value>(std::move(v)), cb, created, permanent);
|
||||
}
|
||||
@@ -202,7 +201,7 @@ public:
|
||||
Value&& v,
|
||||
DoneCallbackSimple cb,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, std::forward<Value>(v), bindDoneCb(cb), created, permanent);
|
||||
}
|
||||
@@ -210,18 +209,18 @@ public:
|
||||
/**
|
||||
* Get data currently being put at the given hash.
|
||||
*/
|
||||
std::vector<Sp<Value>> getPut(const InfoHash&);
|
||||
std::vector<Sp<Value>> getPut(const InfoHash&) const override;
|
||||
|
||||
/**
|
||||
* Get data currently being put at the given hash with the given id.
|
||||
*/
|
||||
Sp<Value> getPut(const InfoHash&, const Value::Id&);
|
||||
Sp<Value> getPut(const InfoHash&, const Value::Id&) const override;
|
||||
|
||||
/**
|
||||
* Stop any put/announce operation at the given location,
|
||||
* for the value with the given id.
|
||||
*/
|
||||
bool cancelPut(const InfoHash&, const Value::Id&);
|
||||
bool cancelPut(const InfoHash&, const Value::Id&) override;
|
||||
|
||||
/**
|
||||
* Listen on the network for any changes involving a specified hash.
|
||||
@@ -230,28 +229,28 @@ public:
|
||||
*
|
||||
* @return a token to cancel the listener later.
|
||||
*/
|
||||
virtual size_t listen(const InfoHash&, ValueCallback, Value::Filter={}, Where={});
|
||||
size_t listen(const InfoHash&, ValueCallback, Value::Filter={}, Where={}) override;
|
||||
|
||||
virtual size_t listen(const InfoHash& key, GetCallback cb, Value::Filter f={}, Where w={}) {
|
||||
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){
|
||||
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={}) {
|
||||
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));
|
||||
}
|
||||
|
||||
virtual bool cancelListen(const InfoHash&, size_t token);
|
||||
bool cancelListen(const InfoHash&, size_t token) override;
|
||||
|
||||
/**
|
||||
* Inform the DHT of lower-layer connectivity changes.
|
||||
* This will cause the DHT to assume a public IP address change.
|
||||
* The DHT will recontact neighbor nodes, re-register for listen ops etc.
|
||||
*/
|
||||
void connectivityChanged(sa_family_t);
|
||||
void connectivityChanged() {
|
||||
void connectivityChanged(sa_family_t) override;
|
||||
void connectivityChanged() override {
|
||||
reported_addr.clear();
|
||||
connectivityChanged(AF_INET);
|
||||
connectivityChanged(AF_INET6);
|
||||
@@ -261,32 +260,32 @@ public:
|
||||
* Get the list of good nodes for local storage saving purposes
|
||||
* The list is ordered to minimize the back-to-work delay.
|
||||
*/
|
||||
std::vector<NodeExport> exportNodes() const;
|
||||
std::vector<NodeExport> exportNodes() const override;
|
||||
|
||||
std::vector<ValuesExport> exportValues() const;
|
||||
void importValues(const std::vector<ValuesExport>&);
|
||||
std::vector<ValuesExport> exportValues() const override;
|
||||
void importValues(const std::vector<ValuesExport>&) override;
|
||||
|
||||
void saveState(const std::string& path) const;
|
||||
void loadState(const std::string& path);
|
||||
|
||||
NodeStats getNodesStats(sa_family_t af) const;
|
||||
NodeStats getNodesStats(sa_family_t af) const override;
|
||||
|
||||
std::string getStorageLog() const;
|
||||
std::string getStorageLog(const InfoHash&) const;
|
||||
std::string getStorageLog() const override;
|
||||
std::string getStorageLog(const InfoHash&) const override;
|
||||
|
||||
std::string getRoutingTablesLog(sa_family_t) const;
|
||||
std::string getSearchesLog(sa_family_t) const;
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const;
|
||||
std::string getRoutingTablesLog(sa_family_t) const override;
|
||||
std::string getSearchesLog(sa_family_t) const override;
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t af = AF_UNSPEC) const override;
|
||||
|
||||
void dumpTables() const;
|
||||
std::vector<unsigned> getNodeMessageStats(bool in = false) {
|
||||
void dumpTables() const override;
|
||||
std::vector<unsigned> getNodeMessageStats(bool in = false) override {
|
||||
return network_engine.getNodeMessageStats(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the in-memory storage limit in bytes
|
||||
*/
|
||||
void setStorageLimit(size_t limit = DEFAULT_STORAGE_LIMIT) {
|
||||
void setStorageLimit(size_t limit = DEFAULT_STORAGE_LIMIT) override {
|
||||
max_store_size = limit;
|
||||
}
|
||||
|
||||
@@ -294,13 +293,13 @@ public:
|
||||
* Returns the total memory usage of stored values and the number
|
||||
* of stored values.
|
||||
*/
|
||||
std::pair<size_t, size_t> getStoreSize() const {
|
||||
std::pair<size_t, size_t> getStoreSize() const override {
|
||||
return {total_store_size, total_values};
|
||||
}
|
||||
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0);
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) override;
|
||||
|
||||
void pushNotificationReceived(const std::map<std::string, std::string>&) {}
|
||||
void pushNotificationReceived(const std::map<std::string, std::string>&) override {}
|
||||
void resubscribe(unsigned) {}
|
||||
|
||||
private:
|
||||
@@ -436,17 +435,9 @@ private:
|
||||
RoutingTable& buckets(sa_family_t af) { return af == AF_INET ? buckets4 : buckets6; }
|
||||
const RoutingTable& buckets(sa_family_t af) const { return af == AF_INET ? buckets4 : buckets6; }
|
||||
Bucket* findBucket(const InfoHash& id, sa_family_t af) {
|
||||
RoutingTable::iterator b;
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
b = buckets4.findBucket(id);
|
||||
return b == buckets4.end() ? nullptr : &(*b);
|
||||
case AF_INET6:
|
||||
b = buckets6.findBucket(id);
|
||||
return b == buckets6.end() ? nullptr : &(*b);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
auto& b = buckets(af);
|
||||
auto it = b.findBucket(id);
|
||||
return it == b.end() ? nullptr : &(*it);
|
||||
}
|
||||
const Bucket* findBucket(const InfoHash& id, sa_family_t af) const {
|
||||
return const_cast<Dht*>(this)->findBucket(id, af);
|
||||
|
||||
@@ -23,9 +23,14 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
namespace net {
|
||||
class DatagramSocket;
|
||||
}
|
||||
|
||||
class OPENDHT_PUBLIC DhtInterface {
|
||||
public:
|
||||
DhtInterface() = default;
|
||||
DhtInterface(const Logger& l) : DHT_LOG(l) {};
|
||||
virtual ~DhtInterface() = default;
|
||||
|
||||
// [[deprecated]]
|
||||
@@ -39,6 +44,8 @@ public:
|
||||
virtual NodeStatus getStatus(sa_family_t af) const = 0;
|
||||
virtual NodeStatus getStatus() const = 0;
|
||||
|
||||
virtual net::DatagramSocket* getSocket() const { return {}; };
|
||||
|
||||
/**
|
||||
* Get the ID of the DHT node.
|
||||
*/
|
||||
@@ -67,12 +74,11 @@ public:
|
||||
* used to bootstrap efficiently from previously known nodes.
|
||||
*/
|
||||
virtual void insertNode(const InfoHash& id, const SockAddr&) = 0;
|
||||
virtual void insertNode(const InfoHash& id, const sockaddr* sa, socklen_t salen) = 0;
|
||||
virtual void insertNode(const NodeExport& n) = 0;
|
||||
|
||||
virtual void pingNode(const sockaddr*, socklen_t, DoneCallbackSimple&& cb={}) = 0;
|
||||
virtual void pingNode(SockAddr, DoneCallbackSimple&& cb={}) = 0;
|
||||
|
||||
virtual time_point periodic(const uint8_t *buf, size_t buflen, const SockAddr&) = 0;
|
||||
virtual time_point periodic(const uint8_t *buf, size_t buflen, SockAddr) = 0;
|
||||
virtual time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) = 0;
|
||||
|
||||
/**
|
||||
@@ -106,7 +112,7 @@ public:
|
||||
/**
|
||||
* Get locally stored data for the given hash.
|
||||
*/
|
||||
virtual std::vector<Sp<Value>> getLocal(const InfoHash& key, Value::Filter f = {}) const = 0;
|
||||
virtual std::vector<Sp<Value>> getLocal(const InfoHash& key, const Value::Filter& f = {}) const = 0;
|
||||
|
||||
/**
|
||||
* Get locally stored data for the given key and value id.
|
||||
@@ -143,12 +149,12 @@ public:
|
||||
/**
|
||||
* Get data currently being put at the given hash.
|
||||
*/
|
||||
virtual std::vector<Sp<Value>> getPut(const InfoHash&) = 0;
|
||||
virtual std::vector<Sp<Value>> getPut(const InfoHash&) const = 0;
|
||||
|
||||
/**
|
||||
* Get data currently being put at the given hash with the given id.
|
||||
*/
|
||||
virtual Sp<Value> getPut(const InfoHash&, const Value::Id&) = 0;
|
||||
virtual Sp<Value> getPut(const InfoHash&, const Value::Id&) const = 0;
|
||||
|
||||
/**
|
||||
* Stop any put/announce operation at the given location,
|
||||
@@ -214,13 +220,18 @@ public:
|
||||
/**
|
||||
* Enable or disable logging of DHT internal messages
|
||||
*/
|
||||
virtual void setLoggers(LogMethod error = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG)
|
||||
{
|
||||
virtual void setLoggers(LogMethod error = {}, LogMethod warn = {}, LogMethod debug = {}) {
|
||||
DHT_LOG.DBG = debug;
|
||||
DHT_LOG.WARN = warn;
|
||||
DHT_LOG.ERR = error;
|
||||
}
|
||||
|
||||
virtual void setLogger(const Logger& l) {
|
||||
DHT_LOG.DBG = l.DBG;
|
||||
DHT_LOG.WARN = l.WARN;
|
||||
DHT_LOG.ERR = l.ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only print logs related to the given InfoHash (if given), or disable filter (if zeroes).
|
||||
*/
|
||||
@@ -238,8 +249,6 @@ public:
|
||||
virtual void pushNotificationReceived(const std::map<std::string, std::string>& data) = 0;
|
||||
|
||||
protected:
|
||||
bool logFilerEnable_ {};
|
||||
InfoHash logFiler_ {};
|
||||
Logger DHT_LOG;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright (C) 2016-2019 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>
|
||||
*
|
||||
* 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
|
||||
@@ -20,21 +21,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include "callbacks.h"
|
||||
#include "def.h"
|
||||
#include "dht_interface.h"
|
||||
#include "scheduler.h"
|
||||
#include "proxy.h"
|
||||
#include "http.h"
|
||||
|
||||
namespace restbed {
|
||||
class Request;
|
||||
}
|
||||
#include <restinio/all.hpp>
|
||||
#include <json/json.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace Json {
|
||||
class Value;
|
||||
class Value;
|
||||
}
|
||||
|
||||
namespace http {
|
||||
class Resolver;
|
||||
class Request;
|
||||
}
|
||||
|
||||
namespace dht {
|
||||
@@ -44,11 +52,18 @@ public:
|
||||
|
||||
DhtProxyClient();
|
||||
|
||||
explicit DhtProxyClient(std::function<void()> loopSignal, const std::string& serverHost, const std::string& pushClientId = "");
|
||||
explicit DhtProxyClient(
|
||||
std::shared_ptr<crypto::Certificate> serverCA, crypto::Identity clientIdentity,
|
||||
std::function<void()> loopSignal, const std::string& serverHost,
|
||||
const std::string& pushClientId = "", std::shared_ptr<Logger> logger = {});
|
||||
|
||||
virtual void setPushNotificationToken(const std::string& token) {
|
||||
void setHeaderFields(http::Request& request);
|
||||
|
||||
virtual void setPushNotificationToken(const std::string& token) override {
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
deviceKey_ = token;
|
||||
#else
|
||||
(void) token;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -57,20 +72,20 @@ public:
|
||||
/**
|
||||
* Get the ID of the node.
|
||||
*/
|
||||
inline const InfoHash& getNodeId() const { return myid; }
|
||||
inline const InfoHash& getNodeId() const override { return myid; }
|
||||
|
||||
/**
|
||||
* Get the current status of the node for the given family.
|
||||
*/
|
||||
NodeStatus getStatus(sa_family_t af) const;
|
||||
NodeStatus getStatus() const {
|
||||
NodeStatus getStatus(sa_family_t af) const override;
|
||||
NodeStatus getStatus() const override {
|
||||
return std::max(getStatus(AF_INET), getStatus(AF_INET6));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs final operations before quitting.
|
||||
*/
|
||||
void shutdown(ShutdownCallback cb);
|
||||
void shutdown(ShutdownCallback cb) override;
|
||||
|
||||
/**
|
||||
* Returns true if the node is running (have access to an open socket).
|
||||
@@ -78,7 +93,7 @@ public:
|
||||
* af: address family. If non-zero, will return true if the node
|
||||
* is running for the provided family.
|
||||
*/
|
||||
bool isRunning(sa_family_t af = 0) const;
|
||||
bool isRunning(sa_family_t af = 0) const override;
|
||||
|
||||
/**
|
||||
* Get a value by asking the proxy and call the provided get callback when
|
||||
@@ -90,14 +105,14 @@ public:
|
||||
cb and donecb won't be called again afterward.
|
||||
* @param f a filter function used to prefilter values.
|
||||
*/
|
||||
virtual void get(const InfoHash& key, GetCallback cb, DoneCallback donecb={}, Value::Filter&& f={}, Where&& w = {});
|
||||
virtual void get(const InfoHash& key, GetCallback cb, DoneCallbackSimple donecb={}, Value::Filter&& f={}, Where&& w = {}) {
|
||||
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));
|
||||
}
|
||||
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallback donecb={}, Value::Filter&& f={}, 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));
|
||||
}
|
||||
virtual void get(const InfoHash& key, GetCallbackSimple cb, DoneCallbackSimple donecb, Value::Filter&& f={}, 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));
|
||||
}
|
||||
|
||||
@@ -112,12 +127,12 @@ public:
|
||||
Sp<Value>,
|
||||
DoneCallback cb=nullptr,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false);
|
||||
bool permanent = false) override;
|
||||
void put(const InfoHash& key,
|
||||
const Sp<Value>& v,
|
||||
DoneCallbackSimple cb,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, v, bindDoneCb(cb), created, permanent);
|
||||
}
|
||||
@@ -126,7 +141,7 @@ public:
|
||||
Value&& v,
|
||||
DoneCallback cb=nullptr,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, std::make_shared<Value>(std::move(v)), cb, created, permanent);
|
||||
}
|
||||
@@ -134,7 +149,7 @@ public:
|
||||
Value&& v,
|
||||
DoneCallbackSimple cb,
|
||||
time_point created=time_point::max(),
|
||||
bool permanent = false)
|
||||
bool permanent = false) override
|
||||
{
|
||||
put(key, std::forward<Value>(v), bindDoneCb(cb), created, permanent);
|
||||
}
|
||||
@@ -143,13 +158,13 @@ public:
|
||||
* @param af the socket family
|
||||
* @return node stats from the proxy
|
||||
*/
|
||||
NodeStats getNodesStats(sa_family_t af) const;
|
||||
NodeStats getNodesStats(sa_family_t af) const override;
|
||||
|
||||
/**
|
||||
* @param family the socket family
|
||||
* @return public address
|
||||
*/
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0);
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) override;
|
||||
|
||||
/**
|
||||
* Listen on the network for any changes involving a specified hash.
|
||||
@@ -158,32 +173,35 @@ public:
|
||||
*
|
||||
* @return a token to cancel the listener later.
|
||||
*/
|
||||
virtual size_t listen(const InfoHash&, ValueCallback, Value::Filter={}, Where={});
|
||||
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={}) {
|
||||
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){
|
||||
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={}) {
|
||||
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));
|
||||
}
|
||||
virtual bool cancelListen(const InfoHash& key, size_t token);
|
||||
/*
|
||||
* This function relies on the cache implementation.
|
||||
* It means that there are no true cancel here, it keeps the caching in higher priority.
|
||||
*/
|
||||
virtual bool cancelListen(const InfoHash& key, size_t token) override;
|
||||
|
||||
/**
|
||||
* Call linked callback with a push notification
|
||||
* @param notification to process
|
||||
*/
|
||||
void pushNotificationReceived(const std::map<std::string, std::string>& notification);
|
||||
void pushNotificationReceived(const std::map<std::string, std::string>& notification) override;
|
||||
|
||||
time_point periodic(const uint8_t*, size_t, const SockAddr&);
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) {
|
||||
time_point periodic(const uint8_t*, size_t, SockAddr) override;
|
||||
time_point periodic(const uint8_t* buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
|
||||
return periodic(buf, buflen, SockAddr(from, fromlen));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Similar to Dht::get, but sends a Query to filter data remotely.
|
||||
* @param key the key for which to query data for.
|
||||
@@ -194,62 +212,61 @@ public:
|
||||
* @param q a query used to filter values on the remotes before they send a
|
||||
* response.
|
||||
*/
|
||||
virtual void query(const InfoHash& /*key*/, QueryCallback /*cb*/, DoneCallback /*done_cb*/ = {}, Query&& /*q*/ = {}) { }
|
||||
virtual void query(const InfoHash& key, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query&& q = {}) {
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data currently being put at the given hash.
|
||||
*/
|
||||
std::vector<Sp<Value>> getPut(const InfoHash&);
|
||||
std::vector<Sp<Value>> getPut(const InfoHash&) const override;
|
||||
|
||||
/**
|
||||
* Get data currently being put at the given hash with the given id.
|
||||
*/
|
||||
Sp<Value> getPut(const InfoHash&, const Value::Id&);
|
||||
Sp<Value> getPut(const InfoHash&, const Value::Id&) const override;
|
||||
|
||||
/**
|
||||
* Stop any put/announce operation at the given location,
|
||||
* for the value with the given id.
|
||||
*/
|
||||
bool cancelPut(const InfoHash&, const Value::Id&);
|
||||
bool cancelPut(const InfoHash&, const Value::Id&) override;
|
||||
|
||||
void pingNode(const sockaddr*, socklen_t, DoneCallbackSimple&& /*cb*/={}) { }
|
||||
void pingNode(SockAddr, DoneCallbackSimple&& /*cb*/={}) override { }
|
||||
|
||||
virtual void registerType(const ValueType& type) {
|
||||
virtual void registerType(const ValueType& type) override {
|
||||
types.registerType(type);
|
||||
}
|
||||
const ValueType& getType(ValueType::Id type_id) const {
|
||||
const ValueType& getType(ValueType::Id type_id) const override {
|
||||
return types.getType(type_id);
|
||||
}
|
||||
|
||||
std::vector<Sp<Value>> getLocal(const InfoHash& k, Value::Filter filter) const;
|
||||
Sp<Value> getLocalById(const InfoHash& k, Value::Id id) const;
|
||||
std::vector<Sp<Value>> getLocal(const InfoHash& k, const Value::Filter& filter) const override;
|
||||
Sp<Value> getLocalById(const InfoHash& k, Value::Id id) const override;
|
||||
|
||||
/**
|
||||
* NOTE: The following methods will not be implemented because the
|
||||
* DhtProxyClient doesn't have any storage nor synchronization process
|
||||
*/
|
||||
void insertNode(const InfoHash&, const SockAddr&) { }
|
||||
void insertNode(const InfoHash&, const sockaddr*, socklen_t) { }
|
||||
void insertNode(const NodeExport&) { }
|
||||
std::pair<size_t, size_t> getStoreSize() const { return {}; }
|
||||
std::vector<NodeExport> exportNodes() const { return {}; }
|
||||
std::vector<ValuesExport> exportValues() const { return {}; }
|
||||
void importValues(const std::vector<ValuesExport>&) {}
|
||||
std::string getStorageLog() const { return {}; }
|
||||
std::string getStorageLog(const InfoHash&) const { return {}; }
|
||||
std::string getRoutingTablesLog(sa_family_t) const { return {}; }
|
||||
std::string getSearchesLog(sa_family_t) const { return {}; }
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t) const { return {}; }
|
||||
void dumpTables() const {}
|
||||
std::vector<unsigned> getNodeMessageStats(bool) { return {}; }
|
||||
void setStorageLimit(size_t) {}
|
||||
void connectivityChanged(sa_family_t) {
|
||||
void insertNode(const InfoHash&, const SockAddr&) override { }
|
||||
void insertNode(const NodeExport&) override { }
|
||||
std::pair<size_t, size_t> getStoreSize() const override { return {}; }
|
||||
std::vector<NodeExport> exportNodes() const override { return {}; }
|
||||
std::vector<ValuesExport> exportValues() const override { return {}; }
|
||||
void importValues(const std::vector<ValuesExport>&) override {}
|
||||
std::string getStorageLog() const override { return {}; }
|
||||
std::string getStorageLog(const InfoHash&) const override { return {}; }
|
||||
std::string getRoutingTablesLog(sa_family_t) const override { return {}; }
|
||||
std::string getSearchesLog(sa_family_t) const override { return {}; }
|
||||
std::string getSearchLog(const InfoHash&, sa_family_t) const override { return {}; }
|
||||
void dumpTables() const override {}
|
||||
std::vector<unsigned> getNodeMessageStats(bool) override { return {}; }
|
||||
void setStorageLimit(size_t) override {}
|
||||
void connectivityChanged(sa_family_t) override {
|
||||
restartListeners();
|
||||
}
|
||||
void connectivityChanged() {
|
||||
void connectivityChanged() override {
|
||||
getProxyInfos();
|
||||
restartListeners();
|
||||
loopSignal_();
|
||||
@@ -260,6 +277,7 @@ private:
|
||||
* Start the connection with a server.
|
||||
*/
|
||||
void startProxy();
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Get informations from the proxy node
|
||||
@@ -267,25 +285,31 @@ private:
|
||||
*/
|
||||
struct InfoState;
|
||||
void getProxyInfos();
|
||||
void onProxyInfos(const Json::Value& val, sa_family_t family);
|
||||
void queryProxyInfo(std::shared_ptr<InfoState> infoState, sa_family_t family, std::shared_ptr<http::Resolver> resolver);
|
||||
void onProxyInfos(const Json::Value& val, const sa_family_t family);
|
||||
SockAddr parsePublicAddress(const Json::Value& val);
|
||||
|
||||
void opFailed();
|
||||
|
||||
bool doCancelListen(const InfoHash& key, size_t token);
|
||||
void handleExpireListener(const asio::error_code &ec, const InfoHash& key);
|
||||
|
||||
struct ListenState;
|
||||
struct Listener;
|
||||
struct OperationState;
|
||||
enum class ListenMethod {
|
||||
LISTEN,
|
||||
SUBSCRIBE,
|
||||
RESUBSCRIBE,
|
||||
};
|
||||
void sendListen(const std::shared_ptr<restbed::Request> &request,
|
||||
const ValueCallback &, const Value::Filter &filter,
|
||||
const Sp<ListenState> &state,
|
||||
ListenMethod method = ListenMethod::LISTEN);
|
||||
/**
|
||||
* Send Listen with httpClient_
|
||||
*/
|
||||
void sendListen(const restinio::http_request_header_t header, const ValueCallback& cb,
|
||||
const Sp<OperationState>& opstate, Listener& listener, ListenMethod method = ListenMethod::LISTEN);
|
||||
void handleResubscribe(const asio::error_code& ec, const InfoHash& key,
|
||||
const size_t token, std::shared_ptr<OperationState> opstate);
|
||||
|
||||
void doPut(const InfoHash&, Sp<Value>, DoneCallback, time_point created, bool permanent);
|
||||
void doPut(const InfoHash&, Sp<Value>, DoneCallbackSimple, time_point created, bool permanent);
|
||||
void handleRefreshPut(const asio::error_code& ec, InfoHash key, Value::Id id);
|
||||
|
||||
/**
|
||||
* Initialize statusIpvX_
|
||||
@@ -295,12 +319,13 @@ private:
|
||||
* cancel all Listeners
|
||||
*/
|
||||
void cancelAllListeners();
|
||||
/**
|
||||
* cancel all Operations
|
||||
*/
|
||||
void cancelAllOperations();
|
||||
|
||||
std::string serverHost_;
|
||||
std::atomic_bool isDestroying_ {false};
|
||||
|
||||
std::string proxyUrl_;
|
||||
dht::crypto::Identity clientIdentity_;
|
||||
std::shared_ptr<dht::crypto::Certificate> serverCertificate_;
|
||||
//std::pair<std::string, std::string> serverHostService_;
|
||||
std::string pushClientId_;
|
||||
|
||||
mutable std::mutex lockCurrentProxyInfos_;
|
||||
@@ -316,44 +341,43 @@ private:
|
||||
// registred types
|
||||
TypeStore types;
|
||||
|
||||
/*
|
||||
* ASIO I/O Context for sockets in httpClient_
|
||||
* Note: Each context is used in one thread only
|
||||
*/
|
||||
asio::io_context httpContext_;
|
||||
std::shared_ptr<http::Resolver> resolver_;
|
||||
|
||||
mutable std::mutex requestLock_;
|
||||
std::map<unsigned, std::shared_ptr<http::Request>> requests_;
|
||||
/*
|
||||
* Thread for executing the http io_context.run() blocking call
|
||||
*/
|
||||
std::thread httpClientThread_;
|
||||
|
||||
/**
|
||||
* Store listen requests.
|
||||
*/
|
||||
struct Listener;
|
||||
struct ProxySearch;
|
||||
|
||||
mutable std::mutex searchLock_;
|
||||
size_t listenerToken_ {0};
|
||||
std::map<InfoHash, ProxySearch> searches_;
|
||||
mutable std::mutex searchLock_;
|
||||
|
||||
/**
|
||||
* Store current put and get requests.
|
||||
*/
|
||||
struct Operation
|
||||
{
|
||||
std::shared_ptr<restbed::Request> req;
|
||||
std::thread thread;
|
||||
std::shared_ptr<std::atomic_bool> finished;
|
||||
};
|
||||
std::vector<Operation> operations_;
|
||||
std::mutex lockOperations_;
|
||||
/**
|
||||
* Callbacks should be executed in the main thread.
|
||||
*/
|
||||
std::mutex lockCallbacks_;
|
||||
std::vector<std::function<void()>> callbacks_;
|
||||
std::mutex lockCallbacks;
|
||||
|
||||
Sp<InfoState> infoState_;
|
||||
std::thread statusThread_;
|
||||
mutable std::mutex statusLock_;
|
||||
|
||||
Scheduler scheduler;
|
||||
/**
|
||||
* Retrieve if we can connect to the proxy (update statusIpvX_)
|
||||
*/
|
||||
void confirmProxy();
|
||||
Sp<Scheduler::Job> nextProxyConfirmation {};
|
||||
Sp<Scheduler::Job> listenerRestart {};
|
||||
void handleProxyConfirm(const asio::error_code &ec);
|
||||
Sp<asio::steady_timer> nextProxyConfirmationTimer_;
|
||||
Sp<asio::steady_timer> listenerRestartTimer_;
|
||||
|
||||
/**
|
||||
* Relaunch LISTEN requests if the client disconnect/reconnect.
|
||||
@@ -364,7 +388,7 @@ private:
|
||||
* Refresh a listen via a token
|
||||
* @param token
|
||||
*/
|
||||
void resubscribe(const InfoHash& key, Listener& listener);
|
||||
void resubscribe(const InfoHash& key, const size_t token, Listener& listener);
|
||||
|
||||
/**
|
||||
* If we want to use push notifications by default.
|
||||
@@ -375,11 +399,15 @@ private:
|
||||
const std::function<void()> loopSignal_;
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
void fillBody(std::shared_ptr<restbed::Request> request, bool resubscribe);
|
||||
std::string fillBody(bool resubscribe);
|
||||
void getPushRequest(Json::Value&) const;
|
||||
#endif // OPENDHT_PUSH_NOTIFICATIONS
|
||||
|
||||
std::atomic_bool isDestroying_ {false};
|
||||
Json::StreamWriterBuilder jsonBuilder_;
|
||||
std::unique_ptr<Json::CharReader> jsonReader_;
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
|
||||
std::shared_ptr<http::Request> buildRequest(const std::string& target = {});
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright (C) 2017-2019 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>
|
||||
*
|
||||
* 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,24 +27,30 @@
|
||||
#include "scheduler.h"
|
||||
#include "sockaddr.h"
|
||||
#include "value.h"
|
||||
#include "http.h"
|
||||
|
||||
#include <restinio/all.hpp>
|
||||
#include <restinio/tls.hpp>
|
||||
#include <json/json.h>
|
||||
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <restbed>
|
||||
|
||||
#ifdef OPENDHT_JSONCPP
|
||||
#include <json/json.h>
|
||||
#endif
|
||||
namespace http {
|
||||
class Request;
|
||||
struct ListenerSession;
|
||||
}
|
||||
|
||||
namespace Json {
|
||||
class Value;
|
||||
class Value;
|
||||
}
|
||||
|
||||
namespace dht {
|
||||
|
||||
class DhtRunner;
|
||||
class ThreadPool;
|
||||
|
||||
using RestRouter = restinio::router::express_router_t<>;
|
||||
using RequestStatus = restinio::request_handling_status_t;
|
||||
|
||||
/**
|
||||
* Describes the REST API
|
||||
@@ -59,7 +66,11 @@ public:
|
||||
* @note if the server fails to start (if port is already used or reserved),
|
||||
* it will fails silently
|
||||
*/
|
||||
DhtProxyServer(std::shared_ptr<DhtRunner> dht, in_port_t port = 8000, const std::string& pushServer = "");
|
||||
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 = {});
|
||||
|
||||
virtual ~DhtProxyServer();
|
||||
|
||||
DhtProxyServer(const DhtProxyServer& other) = delete;
|
||||
@@ -67,17 +78,19 @@ public:
|
||||
DhtProxyServer& operator=(const DhtProxyServer& other) = delete;
|
||||
DhtProxyServer& operator=(DhtProxyServer&& other) = delete;
|
||||
|
||||
asio::io_context& io_context() const;
|
||||
|
||||
struct ServerStats {
|
||||
/** Current number of listen operations */
|
||||
size_t listenCount;
|
||||
size_t listenCount {0};
|
||||
/** Current number of permanent put operations */
|
||||
size_t putCount;
|
||||
size_t putCount {0};
|
||||
/** Current number of push tokens with at least one listen operation */
|
||||
size_t pushListenersCount;
|
||||
size_t pushListenersCount {0};
|
||||
/** Average requests per second */
|
||||
double requestRate;
|
||||
double requestRate {0};
|
||||
/** Node Info **/
|
||||
NodeInfo nodeInfo;
|
||||
NodeInfo nodeInfo {};
|
||||
|
||||
std::string toString() const {
|
||||
std::ostringstream ss;
|
||||
@@ -95,7 +108,6 @@ public:
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
#ifdef OPENDHT_JSONCPP
|
||||
/**
|
||||
* Build a json object from a NodeStats
|
||||
*/
|
||||
@@ -108,7 +120,6 @@ public:
|
||||
result["nodeInfo"] = nodeInfo.toJson();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
ServerStats stats() const { return stats_; }
|
||||
@@ -117,12 +128,22 @@ public:
|
||||
|
||||
std::shared_ptr<DhtRunner> getNode() const { return dht_; }
|
||||
|
||||
/**
|
||||
* Stop the DhtProxyServer
|
||||
*/
|
||||
void stop();
|
||||
|
||||
private:
|
||||
class ConnectionListener;
|
||||
struct RestRouterTraitsTls;
|
||||
struct RestRouterTraits;
|
||||
|
||||
template <typename HttpResponse>
|
||||
HttpResponse initHttpResponse(HttpResponse response) const;
|
||||
|
||||
template< typename ServerSettings >
|
||||
void addServerSettings(ServerSettings& serverSettings,
|
||||
const unsigned int max_pipelined_requests = 16);
|
||||
|
||||
std::unique_ptr<RestRouter> createRestRouter();
|
||||
|
||||
void onConnectionClosed(restinio::connection_id_t);
|
||||
|
||||
/**
|
||||
* Return the PublicKey id, the node id and node stats
|
||||
* Method: GET "/"
|
||||
@@ -130,7 +151,8 @@ private:
|
||||
* On error: HTTP 503, body: {"err":"xxxx"}
|
||||
* @param session
|
||||
*/
|
||||
void getNodeInfo(const std::shared_ptr<restbed::Session>& session) const;
|
||||
RequestStatus getNodeInfo(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params) const;
|
||||
|
||||
/**
|
||||
* Return ServerStats in JSON format
|
||||
@@ -138,7 +160,8 @@ private:
|
||||
* Result: HTTP 200, body: Node infos in JSON format
|
||||
* @param session
|
||||
*/
|
||||
void getStats(const std::shared_ptr<restbed::Session>& session) const;
|
||||
RequestStatus getStats(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
/**
|
||||
* Return Values of an infoHash
|
||||
@@ -150,7 +173,8 @@ private:
|
||||
* On error: HTTP 503, body: {"err":"xxxx"}
|
||||
* @param session
|
||||
*/
|
||||
void get(const std::shared_ptr<restbed::Session>& session) const;
|
||||
RequestStatus get(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
/**
|
||||
* Listen incoming Values of an infoHash.
|
||||
@@ -162,7 +186,8 @@ private:
|
||||
* On error: HTTP 503, body: {"err":"xxxx"}
|
||||
* @param session
|
||||
*/
|
||||
void listen(const std::shared_ptr<restbed::Session>& session);
|
||||
RequestStatus listen(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
/**
|
||||
* Put a value on the DHT
|
||||
@@ -173,9 +198,10 @@ private:
|
||||
* HTTP 400, body: {"err":"xxxx"} if bad json or HTTP 502 if put fails
|
||||
* @param session
|
||||
*/
|
||||
void put(const std::shared_ptr<restbed::Session>& session);
|
||||
RequestStatus put(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
void cancelPut(const InfoHash& key, Value::Id vid);
|
||||
void handleCancelPermamentPut(const asio::error_code &ec, const InfoHash& key, Value::Id vid);
|
||||
|
||||
#ifdef OPENDHT_PROXY_SERVER_IDENTITY
|
||||
/**
|
||||
@@ -187,7 +213,8 @@ private:
|
||||
* HTTP 400, body: {"err":"xxxx"} if bad json
|
||||
* @param session
|
||||
*/
|
||||
void putSigned(const std::shared_ptr<restbed::Session>& session) const;
|
||||
RequestStatus putSigned(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params) const;
|
||||
|
||||
/**
|
||||
* Put a value to encrypt by the proxy on the DHT
|
||||
@@ -198,7 +225,9 @@ private:
|
||||
* HTTP 400, body: {"err":"xxxx"} if bad json
|
||||
* @param session
|
||||
*/
|
||||
void putEncrypted(const std::shared_ptr<restbed::Session>& session) const;
|
||||
RequestStatus putEncrypted(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
#endif // OPENDHT_PROXY_SERVER_IDENTITY
|
||||
|
||||
/**
|
||||
@@ -211,7 +240,8 @@ private:
|
||||
* On error: HTTP 503, body: {"err":"xxxx"}
|
||||
* @param session
|
||||
*/
|
||||
void getFiltered(const std::shared_ptr<restbed::Session>& session) const;
|
||||
RequestStatus getFiltered(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
/**
|
||||
* Respond allowed Methods
|
||||
@@ -220,13 +250,8 @@ private:
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
||||
* @param session
|
||||
*/
|
||||
void handleOptionsMethod(const std::shared_ptr<restbed::Session>& session) const;
|
||||
|
||||
/**
|
||||
* Remove finished listeners
|
||||
* @param testSession if we remove the listener only if the session is closed
|
||||
*/
|
||||
void removeClosedListeners(bool testSession = true);
|
||||
RequestStatus options(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
/**
|
||||
@@ -238,7 +263,9 @@ private:
|
||||
* so you need to refresh the operation each six hours.
|
||||
* @param session
|
||||
*/
|
||||
void subscribe(const std::shared_ptr<restbed::Session>& session);
|
||||
RequestStatus subscribe(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
/**
|
||||
* Unsubscribe to push notifications for an iOS or Android device.
|
||||
* Method: UNSUBSCRIBE "/{InfoHash: .*}"
|
||||
@@ -246,69 +273,100 @@ private:
|
||||
* Return: nothing
|
||||
* @param session
|
||||
*/
|
||||
void unsubscribe(const std::shared_ptr<restbed::Session>& session);
|
||||
RequestStatus unsubscribe(restinio::request_handle_t request,
|
||||
restinio::router::route_params_t params);
|
||||
|
||||
/**
|
||||
* Send a push notification via a gorush push gateway
|
||||
* @param key of the device
|
||||
* @param json, the content to send
|
||||
*/
|
||||
void sendPushNotification(const std::string& key, Json::Value&& json, bool isAndroid) const;
|
||||
void sendPushNotification(const std::string& key, Json::Value&& json, bool isAndroid);
|
||||
|
||||
/**
|
||||
* Send push notification with an expire timeout.
|
||||
* @param ec
|
||||
* @param pushToken
|
||||
* @param json
|
||||
* @param isAndroid
|
||||
*/
|
||||
void handleNotifyPushListenExpire(const asio::error_code &ec, const std::string pushToken,
|
||||
Json::Value json, const bool isAndroid);
|
||||
|
||||
/**
|
||||
* Remove a push listener between a client and a hash
|
||||
* @param ec
|
||||
* @param pushToken
|
||||
* @param key
|
||||
* @param clientId
|
||||
*/
|
||||
void cancelPushListen(const std::string& pushToken, const InfoHash& key, const std::string& clientId);
|
||||
|
||||
void handleCancelPushListen(const asio::error_code &ec, const std::string pushToken,
|
||||
const InfoHash key, const std::string clientId);
|
||||
|
||||
#endif //OPENDHT_PUSH_NOTIFICATIONS
|
||||
|
||||
void handlePrintStats(const asio::error_code &ec);
|
||||
|
||||
using clock = std::chrono::steady_clock;
|
||||
using time_point = clock::time_point;
|
||||
|
||||
std::thread server_thread {};
|
||||
std::unique_ptr<restbed::Service> service_;
|
||||
std::shared_ptr<DhtRunner> dht_;
|
||||
Json::StreamWriterBuilder jsonBuilder_;
|
||||
Json::CharReaderBuilder jsonReaderBuilder_;
|
||||
|
||||
std::mutex schedulerLock_;
|
||||
std::condition_variable schedulerCv_;
|
||||
Scheduler scheduler_;
|
||||
std::thread schedulerThread_;
|
||||
std::unique_ptr<ThreadPool> threadPool_;
|
||||
// http server
|
||||
std::thread serverThread_;
|
||||
std::unique_ptr<restinio::http_server_t<RestRouterTraitsTls>> httpsServer_;
|
||||
std::unique_ptr<restinio::http_server_t<RestRouterTraits>> httpServer_;
|
||||
|
||||
// http client
|
||||
std::pair<std::string, std::string> pushHostPort_;
|
||||
|
||||
mutable std::mutex requestLock_;
|
||||
std::map<unsigned int /*id*/, std::shared_ptr<http::Request>> requests_;
|
||||
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
|
||||
Sp<Scheduler::Job> printStatsJob_;
|
||||
mutable std::mutex statsMutex_;
|
||||
mutable ServerStats stats_;
|
||||
mutable NodeInfo nodeInfo_ {};
|
||||
std::unique_ptr<asio::steady_timer> printStatsTimer_;
|
||||
|
||||
// Handle client quit for listen.
|
||||
// NOTE: can be simplified when we will supports restbed 5.0
|
||||
std::thread listenThread_;
|
||||
struct SessionToHashToken {
|
||||
std::shared_ptr<restbed::Session> session;
|
||||
InfoHash hash;
|
||||
std::future<size_t> token;
|
||||
};
|
||||
std::vector<SessionToHashToken> currentListeners_;
|
||||
// Thread-safe access to listeners map.
|
||||
std::mutex lockListener_;
|
||||
std::atomic_bool stopListeners {false};
|
||||
// Shared with connection listener.
|
||||
std::map<restinio::connection_id_t, http::ListenerSession> listeners_;
|
||||
// Connection Listener observing conn state changes.
|
||||
std::shared_ptr<ConnectionListener> connListener_;
|
||||
|
||||
struct PermanentPut;
|
||||
struct SearchPuts;
|
||||
struct PermanentPut {
|
||||
time_point expiration;
|
||||
std::string pushToken;
|
||||
std::string clientId;
|
||||
std::unique_ptr<asio::steady_timer> expireTimer;
|
||||
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
|
||||
};
|
||||
struct SearchPuts {
|
||||
std::map<dht::Value::Id, PermanentPut> puts;
|
||||
};
|
||||
std::mutex lockSearchPuts_;
|
||||
std::map<InfoHash, SearchPuts> puts_;
|
||||
|
||||
mutable std::atomic<size_t> requestNum_ {0};
|
||||
mutable std::atomic<time_point> lastStatsReset_ {time_point::min()};
|
||||
|
||||
const std::string pushServer_;
|
||||
|
||||
mutable ServerStats stats_;
|
||||
std::string pushServer_;
|
||||
|
||||
#ifdef OPENDHT_PUSH_NOTIFICATIONS
|
||||
struct Listener;
|
||||
struct PushListener;
|
||||
struct Listener {
|
||||
std::string clientId;
|
||||
std::future<size_t> internalToken;
|
||||
std::unique_ptr<asio::steady_timer> expireTimer;
|
||||
std::unique_ptr<asio::steady_timer> expireNotifyTimer;
|
||||
};
|
||||
struct PushListener {
|
||||
std::map<InfoHash, std::vector<Listener>> listeners;
|
||||
};
|
||||
std::mutex lockPushListeners_;
|
||||
std::map<std::string, PushListener> pushListeners_;
|
||||
proxy::ListenToken tokenPushNotif_ {0};
|
||||
|
||||
+95
-84
@@ -20,12 +20,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.h"
|
||||
#include "infohash.h"
|
||||
#include "value.h"
|
||||
#include "callbacks.h"
|
||||
#include "sockaddr.h"
|
||||
#include "log_enable.h"
|
||||
#include "def.h"
|
||||
#include "network_utils.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
@@ -40,6 +41,7 @@ namespace dht {
|
||||
|
||||
struct Node;
|
||||
class SecureDht;
|
||||
class PeerDiscovery;
|
||||
struct SecureDhtConfig;
|
||||
|
||||
/**
|
||||
@@ -51,13 +53,27 @@ struct SecureDhtConfig;
|
||||
class OPENDHT_PUBLIC DhtRunner {
|
||||
|
||||
public:
|
||||
typedef std::function<void(NodeStatus, NodeStatus)> StatusCallback;
|
||||
using StatusCallback = std::function<void(NodeStatus, NodeStatus)>;
|
||||
|
||||
struct Config {
|
||||
SecureDhtConfig dht_config;
|
||||
bool threaded;
|
||||
std::string proxy_server;
|
||||
std::string push_node_id;
|
||||
SecureDhtConfig dht_config {};
|
||||
bool threaded {true};
|
||||
std::string proxy_server {};
|
||||
std::string push_node_id {};
|
||||
std::string push_token {};
|
||||
bool peer_discovery {false};
|
||||
bool peer_publish {false};
|
||||
std::shared_ptr<dht::crypto::Certificate> server_ca;
|
||||
dht::crypto::Identity client_identity;
|
||||
};
|
||||
|
||||
struct Context {
|
||||
std::shared_ptr<Logger> logger {};
|
||||
std::unique_ptr<net::DatagramSocket> sock;
|
||||
std::shared_ptr<PeerDiscovery> peerDiscovery {};
|
||||
StatusCallback statusChangedCallback {};
|
||||
CertificateStoreQuery certificateStore {};
|
||||
Context() {}
|
||||
};
|
||||
|
||||
DhtRunner();
|
||||
@@ -105,7 +121,7 @@ public:
|
||||
getFilterSet<T>());
|
||||
}
|
||||
|
||||
std::future<std::vector<std::shared_ptr<dht::Value>>> get(InfoHash key, Value::Filter f = Value::AllFilter(), Where w = {}) {
|
||||
std::future<std::vector<std::shared_ptr<dht::Value>>> get(InfoHash key, Value::Filter f = {}, Where w = {}) {
|
||||
auto p = std::make_shared<std::promise<std::vector<std::shared_ptr< dht::Value >>>>();
|
||||
auto values = std::make_shared<std::vector<std::shared_ptr< dht::Value >>>();
|
||||
get(key, [=](const std::vector<std::shared_ptr<dht::Value>>& vlist) {
|
||||
@@ -136,7 +152,7 @@ public:
|
||||
query(hash, cb, bindDoneCb(done_cb), q);
|
||||
}
|
||||
|
||||
std::future<size_t> listen(InfoHash key, ValueCallback vcb, Value::Filter f = Value::AllFilter(), Where w = {});
|
||||
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){
|
||||
@@ -145,8 +161,8 @@ public:
|
||||
return true;
|
||||
}, std::forward<Value::Filter>(f), std::forward<Where>(w));
|
||||
}
|
||||
std::future<size_t> listen(const std::string& key, GetCallback vcb, Value::Filter f = Value::AllFilter(), Where w = {});
|
||||
std::future<size_t> listen(InfoHash key, GetCallbackSimple cb, Value::Filter f = Value::AllFilter(), Where w = {}) {
|
||||
std::future<size_t> listen(const std::string& key, GetCallback vcb, Value::Filter f = {}, Where w = {});
|
||||
std::future<size_t> listen(InfoHash key, GetCallbackSimple cb, Value::Filter f = {}, Where w = {}) {
|
||||
return listen(key, bindGetCb(cb), f, w);
|
||||
}
|
||||
|
||||
@@ -168,7 +184,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::future<size_t> listen(InfoHash hash, std::function<bool(T&&)> cb, Value::Filter f = Value::AllFilter(), Where w = {})
|
||||
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) {
|
||||
for (const auto& v : vals) {
|
||||
@@ -184,7 +200,7 @@ public:
|
||||
getFilterSet<T>(f), w);
|
||||
}
|
||||
template <typename T>
|
||||
std::future<size_t> listen(InfoHash hash, std::function<bool(T&&, bool)> cb, Value::Filter f = Value::AllFilter(), Where w = {})
|
||||
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) {
|
||||
for (const auto& v : vals) {
|
||||
@@ -214,35 +230,36 @@ public:
|
||||
}
|
||||
void put(const std::string& key, Value&& value, DoneCallbackSimple cb={}, time_point created=time_point::max(), bool permanent = false);
|
||||
|
||||
void cancelPut(const InfoHash& h, const Value::Id& id);
|
||||
void cancelPut(const InfoHash& h, Value::Id id);
|
||||
void cancelPut(const InfoHash& h, const std::shared_ptr<Value>& value);
|
||||
|
||||
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={});
|
||||
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb) {
|
||||
putSigned(hash, value, bindDoneCb(cb));
|
||||
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
|
||||
void putSigned(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
putSigned(hash, value, bindDoneCb(cb), permanent);
|
||||
}
|
||||
|
||||
void putSigned(InfoHash hash, Value&& value, DoneCallback cb={});
|
||||
void putSigned(InfoHash hash, Value&& value, DoneCallbackSimple cb) {
|
||||
putSigned(hash, std::forward<Value>(value), bindDoneCb(cb));
|
||||
void putSigned(InfoHash hash, Value&& value, DoneCallback cb={}, bool permanent = false);
|
||||
void putSigned(InfoHash hash, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
putSigned(hash, std::forward<Value>(value), bindDoneCb(cb), permanent);
|
||||
}
|
||||
void putSigned(const std::string& key, Value&& value, DoneCallbackSimple cb={});
|
||||
void putSigned(const std::string& key, Value&& value, DoneCallbackSimple cb={}, bool permanent = false);
|
||||
|
||||
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallback cb={});
|
||||
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallbackSimple cb) {
|
||||
putEncrypted(hash, to, value, bindDoneCb(cb));
|
||||
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
|
||||
void putEncrypted(InfoHash hash, InfoHash to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
|
||||
}
|
||||
|
||||
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallback cb={});
|
||||
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallbackSimple cb) {
|
||||
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb));
|
||||
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallback cb={}, bool permanent = false);
|
||||
void putEncrypted(InfoHash hash, InfoHash to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
|
||||
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
|
||||
}
|
||||
void putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb={});
|
||||
void putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb={}, bool permanent = false);
|
||||
|
||||
/**
|
||||
* 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(const std::vector<SockAddr>& nodes, DoneCallbackSimple&& cb={});
|
||||
void bootstrap(std::vector<SockAddr> nodes, DoneCallbackSimple&& cb={});
|
||||
void bootstrap(const SockAddr& addr, DoneCallbackSimple&& cb={});
|
||||
|
||||
/**
|
||||
@@ -258,6 +275,13 @@ public:
|
||||
* to the DHT network is established.
|
||||
*/
|
||||
void bootstrap(const std::string& host, const std::string& service);
|
||||
void bootstrap(const std::string& hostService);
|
||||
|
||||
/**
|
||||
* 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(const InfoHash& id, const SockAddr& address);
|
||||
|
||||
/**
|
||||
* Clear the list of bootstrap added using bootstrap(const std::string&, const std::string&).
|
||||
@@ -287,17 +311,13 @@ public:
|
||||
* Returns the currently bound address.
|
||||
* @param f: address family of the bound address to retreive.
|
||||
*/
|
||||
const SockAddr& getBound(sa_family_t f = AF_INET) const {
|
||||
return (f == AF_INET) ? bound4 : bound6;
|
||||
}
|
||||
SockAddr getBound(sa_family_t f = AF_INET) const;
|
||||
|
||||
/**
|
||||
* Returns the currently bound port, in host byte order.
|
||||
* @param f: address family of the bound port to retreive.
|
||||
*/
|
||||
in_port_t getBoundPort(sa_family_t f = AF_INET) const {
|
||||
return getBound(f).getPort();
|
||||
}
|
||||
in_port_t getBoundPort(sa_family_t f = AF_INET) const;
|
||||
|
||||
std::pair<size_t, size_t> getStoreSize() const;
|
||||
|
||||
@@ -307,7 +327,8 @@ public:
|
||||
|
||||
std::vector<ValuesExport> exportValues() const;
|
||||
|
||||
void setLoggers(LogMethod err = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG);
|
||||
void setLogger(const Logger& logger = {});
|
||||
void setLoggers(LogMethod err = {}, LogMethod warn = {}, LogMethod debug = {});
|
||||
|
||||
/**
|
||||
* Only print logs related to the given InfoHash (if given), or disable filter (if zeroes).
|
||||
@@ -319,7 +340,7 @@ public:
|
||||
void importValues(const std::vector<ValuesExport>& values);
|
||||
|
||||
bool isRunning() const {
|
||||
return running;
|
||||
return running != State::Idle;
|
||||
}
|
||||
|
||||
NodeStats getNodesStats(sa_family_t af) const;
|
||||
@@ -337,7 +358,7 @@ public:
|
||||
|
||||
// securedht methods
|
||||
|
||||
void findCertificate(InfoHash hash, std::function<void(const std::shared_ptr<crypto::Certificate>)>);
|
||||
void findCertificate(InfoHash hash, std::function<void(const std::shared_ptr<crypto::Certificate>&)>);
|
||||
void registerCertificate(std::shared_ptr<crypto::Certificate> cert);
|
||||
void setLocalCertificateStore(CertificateStoreQuery&& query_method);
|
||||
|
||||
@@ -347,24 +368,14 @@ public:
|
||||
* @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(in_port_t port = 4222, const crypto::Identity identity = {}, bool threaded = false, NetId network = 0) {
|
||||
run(port, {
|
||||
/*.dht_config = */{
|
||||
/*.node_config = */{
|
||||
/*.node_id = */{},
|
||||
/*.network = */network,
|
||||
/*.is_bootstrap = */false,
|
||||
/*.maintain_storage = */false,
|
||||
/*.persist_path = */{}
|
||||
},
|
||||
/*.id = */identity
|
||||
},
|
||||
/*.threaded = */threaded,
|
||||
/*.proxy_server = */"",
|
||||
/*.push_node_id = */""
|
||||
});
|
||||
void run(in_port_t port = dht::net::DHT_DEFAULT_PORT, const crypto::Identity& identity = {}, bool threaded = true, NetId network = 0) {
|
||||
Config config;
|
||||
config.dht_config.node_config.network = network;
|
||||
config.dht_config.id = identity;
|
||||
config.threaded = threaded;
|
||||
run(port, config);
|
||||
}
|
||||
void run(in_port_t port, const Config& config);
|
||||
void run(in_port_t port, const Config& config, Context&& context = {});
|
||||
|
||||
/**
|
||||
* @param local4: Local IPv4 address and port to bind. Can be null.
|
||||
@@ -374,12 +385,14 @@ public:
|
||||
* @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);
|
||||
void run(const SockAddr& local4, const SockAddr& local6, const 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);
|
||||
void run(const char* ip4, const char* ip6, const char* service, const Config& config, Context&& context = {});
|
||||
|
||||
void run(const Config& config, Context&& context);
|
||||
|
||||
void setOnStatusChanged(StatusCallback&& cb) {
|
||||
statusCb = std::move(cb);
|
||||
@@ -392,19 +405,13 @@ public:
|
||||
*/
|
||||
time_point loop() {
|
||||
std::lock_guard<std::mutex> lck(dht_mtx);
|
||||
time_point wakeup = time_point::min();
|
||||
try {
|
||||
wakeup = loop_();
|
||||
} catch (const dht::SocketException& e) {
|
||||
startNetwork(bound4, bound6);
|
||||
}
|
||||
return wakeup;
|
||||
return loop_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gracefuly disconnect from network.
|
||||
*/
|
||||
void shutdown(ShutdownCallback cb);
|
||||
void shutdown(ShutdownCallback cb = {});
|
||||
|
||||
/**
|
||||
* Quit and wait for all threads to terminate.
|
||||
@@ -413,6 +420,8 @@ public:
|
||||
*/
|
||||
void join();
|
||||
|
||||
std::shared_ptr<PeerDiscovery> getPeerDiscovery() const { return peerDiscovery_; };
|
||||
|
||||
void setProxyServer(const std::string& proxy, const std::string& pushNodeId = "");
|
||||
|
||||
/**
|
||||
@@ -440,6 +449,12 @@ public:
|
||||
private:
|
||||
static constexpr std::chrono::seconds BOOTSTRAP_PERIOD {10};
|
||||
|
||||
enum class State {
|
||||
Idle,
|
||||
Running,
|
||||
Stopping
|
||||
};
|
||||
|
||||
/**
|
||||
* Will try to resolve the list of hostnames `bootstrap_nodes` on seperate
|
||||
* thread and then queue ping requests. This list should contain reliable
|
||||
@@ -448,14 +463,17 @@ private:
|
||||
*/
|
||||
void tryBootstrapContinuously();
|
||||
|
||||
void stopNetwork();
|
||||
void startNetwork(const SockAddr sin4, const SockAddr sin6);
|
||||
time_point loop_();
|
||||
|
||||
NodeStatus getStatus() const {
|
||||
return std::max(status4, status6);
|
||||
}
|
||||
|
||||
bool checkShutdown();
|
||||
void opEnded();
|
||||
DoneCallback bindOpDoneCallback(DoneCallback&& cb);
|
||||
DoneCallbackSimple bindOpDoneCallback(DoneCallbackSimple&& cb);
|
||||
|
||||
/** Local DHT instance */
|
||||
std::unique_ptr<SecureDht> dht_;
|
||||
|
||||
@@ -487,16 +505,8 @@ private:
|
||||
mutable std::mutex dht_mtx {};
|
||||
std::thread dht_thread {};
|
||||
std::condition_variable cv {};
|
||||
|
||||
std::thread rcv_thread {};
|
||||
std::mutex sock_mtx {};
|
||||
|
||||
struct ReceivedPacket {
|
||||
Blob data;
|
||||
SockAddr from;
|
||||
time_point received;
|
||||
};
|
||||
std::queue<ReceivedPacket> rcv {};
|
||||
std::queue<std::unique_ptr<net::ReceivedPacket>> rcv {};
|
||||
|
||||
/** true if currently actively boostraping */
|
||||
std::atomic_bool bootstraping {false};
|
||||
@@ -504,7 +514,6 @@ private:
|
||||
std::vector<std::pair<std::string,std::string>> bootstrap_nodes_all {};
|
||||
std::vector<std::pair<std::string,std::string>> bootstrap_nodes {};
|
||||
std::thread bootstrap_thread {};
|
||||
/** protects bootstrap_nodes, bootstrap_thread */
|
||||
std::mutex bootstrap_mtx {};
|
||||
std::condition_variable bootstrap_cv {};
|
||||
|
||||
@@ -512,20 +521,22 @@ private:
|
||||
std::queue<std::function<void(SecureDht&)>> pending_ops {};
|
||||
std::mutex storage_mtx {};
|
||||
|
||||
std::atomic_bool running {false};
|
||||
std::atomic_bool running_network {false};
|
||||
std::atomic<State> running {State::Idle};
|
||||
std::atomic_size_t ongoing_ops {0};
|
||||
std::vector<ShutdownCallback> shutdownCallbacks_;
|
||||
|
||||
NodeStatus status4 {NodeStatus::Disconnected},
|
||||
status6 {NodeStatus::Disconnected};
|
||||
StatusCallback statusCb {nullptr};
|
||||
|
||||
int stop_writefd {-1};
|
||||
int s4 {-1}, s6 {-1};
|
||||
SockAddr bound4 {};
|
||||
SockAddr bound6 {};
|
||||
/** PeerDiscovery Parameters */
|
||||
std::shared_ptr<PeerDiscovery> peerDiscovery_;
|
||||
|
||||
/** Push notification token */
|
||||
std::string pushToken_;
|
||||
/**
|
||||
* The Logger instance is used in enableProxy and other methods that
|
||||
* would create instances of classes using a common logger.
|
||||
*/
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
* Author: 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
|
||||
* 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 "def.h"
|
||||
#include "infohash.h"
|
||||
#include "crypto.h"
|
||||
|
||||
// some libraries may try to redefine snprintf
|
||||
// but restinio will use it in std namespace
|
||||
#ifdef _MSC_VER
|
||||
# undef snprintf
|
||||
# define snprintf snprintf
|
||||
#endif
|
||||
|
||||
#include <asio/ssl/context.hpp>
|
||||
#include <restinio/http_headers.hpp>
|
||||
#include <restinio/message_builders.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
namespace Json {
|
||||
class Value;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
struct http_parser;
|
||||
struct http_parser_settings;
|
||||
}
|
||||
|
||||
namespace restinio {
|
||||
namespace impl {
|
||||
class tls_socket_t;
|
||||
}
|
||||
}
|
||||
|
||||
namespace dht {
|
||||
struct Logger;
|
||||
|
||||
namespace crypto {
|
||||
struct Certificate;
|
||||
}
|
||||
|
||||
namespace http {
|
||||
|
||||
using HandlerCb = std::function<void(const asio::error_code& ec)>;
|
||||
using BytesHandlerCb = std::function<void(const asio::error_code& ec, size_t bytes)>;
|
||||
using ConnectHandlerCb = std::function<void(const asio::error_code& ec,
|
||||
const asio::ip::tcp::endpoint& endpoint)>;
|
||||
|
||||
using ssl_socket_t = restinio::impl::tls_socket_t;
|
||||
using socket_t = asio::ip::tcp::socket;
|
||||
|
||||
class OPENDHT_PUBLIC Url
|
||||
{
|
||||
public:
|
||||
Url(){};
|
||||
Url(const std::string& url);
|
||||
std::string url;
|
||||
std::string protocol {"http"};
|
||||
std::string host;
|
||||
std::string service {"80"};
|
||||
std::string target {"/"};
|
||||
std::string query;
|
||||
std::string fragment;
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC Connection : public std::enable_shared_from_this<Connection>
|
||||
{
|
||||
public:
|
||||
Connection(asio::io_context& ctx, const bool ssl = true, std::shared_ptr<dht::Logger> l = {});
|
||||
Connection(asio::io_context& ctx, std::shared_ptr<dht::crypto::Certificate> server_ca,
|
||||
const dht::crypto::Identity& identity, std::shared_ptr<dht::Logger> l = {});
|
||||
~Connection();
|
||||
|
||||
inline unsigned int id() const { return id_; };
|
||||
bool is_open() const;
|
||||
bool is_ssl() const;
|
||||
|
||||
void set_ssl_verification(const asio::ip::tcp::endpoint& endpoint, const asio::ssl::verify_mode verify_mode);
|
||||
|
||||
asio::streambuf& input();
|
||||
std::istream& data() { return istream_; }
|
||||
|
||||
std::string read_bytes(size_t bytes = 0);
|
||||
std::string read_until(const char delim);
|
||||
|
||||
void async_connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, ConnectHandlerCb);
|
||||
void async_handshake(HandlerCb cb);
|
||||
void async_write(BytesHandlerCb cb);
|
||||
void async_read_until(const char* delim, BytesHandlerCb cb);
|
||||
void async_read_until(char delim, BytesHandlerCb cb);
|
||||
void async_read(size_t bytes, BytesHandlerCb cb);
|
||||
void async_read_some(size_t bytes, BytesHandlerCb cb);
|
||||
|
||||
void timeout(const std::chrono::seconds timeout, HandlerCb cb = {});
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
template<typename T>
|
||||
T wrapCallabck(T cb) const {
|
||||
return [t=shared_from_this(),cb=std::move(cb)](auto ...params) {
|
||||
return cb(params...);
|
||||
};
|
||||
}
|
||||
|
||||
unsigned int id_;
|
||||
static std::atomic_uint ids_;
|
||||
|
||||
asio::io_context& ctx_;
|
||||
std::unique_ptr<socket_t> socket_;
|
||||
std::shared_ptr<asio::ssl::context> ssl_ctx_;
|
||||
std::unique_ptr<ssl_socket_t> ssl_socket_;
|
||||
|
||||
asio::ip::tcp::endpoint endpoint_;
|
||||
|
||||
asio::streambuf write_buf_;
|
||||
asio::streambuf read_buf_;
|
||||
std::istream istream_;
|
||||
|
||||
std::unique_ptr<asio::steady_timer> timeout_timer_;
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Session value associated with a connection_id_t key.
|
||||
*/
|
||||
struct ListenerSession
|
||||
{
|
||||
ListenerSession() = default;
|
||||
dht::InfoHash hash;
|
||||
std::future<size_t> token;
|
||||
std::shared_ptr<restinio::response_builder_t<restinio::chunked_output_t>> response;
|
||||
};
|
||||
|
||||
/* @class Resolver
|
||||
* @brief The purpose is to only resolve once to avoid mutliple dns requests per operation.
|
||||
*/
|
||||
class OPENDHT_PUBLIC Resolver
|
||||
{
|
||||
public:
|
||||
using ResolverCb = std::function<void(const asio::error_code& ec,
|
||||
const std::vector<asio::ip::tcp::endpoint>& endpoints)>;
|
||||
|
||||
Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger = {});
|
||||
Resolver(asio::io_context& ctx, const std::string& host, const std::string& service,
|
||||
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
|
||||
|
||||
// use already resolved endpoints with classes using this resolver
|
||||
Resolver(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint> endpoints,
|
||||
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
|
||||
Resolver(asio::io_context& ctx, const std::string& url, std::vector<asio::ip::tcp::endpoint> endpoints,
|
||||
std::shared_ptr<dht::Logger> logger = {});
|
||||
|
||||
~Resolver();
|
||||
|
||||
inline const Url& get_url() const {
|
||||
return url_;
|
||||
}
|
||||
|
||||
void add_callback(ResolverCb cb, sa_family_t family = AF_UNSPEC);
|
||||
|
||||
std::shared_ptr<Logger> getLogger() const {
|
||||
return logger_;
|
||||
}
|
||||
|
||||
private:
|
||||
void resolve(const std::string& host, const std::string& service);
|
||||
|
||||
std::mutex mutex_;
|
||||
|
||||
Url url_;
|
||||
asio::error_code ec_;
|
||||
asio::ip::tcp::resolver resolver_;
|
||||
std::shared_ptr<bool> destroyed_;
|
||||
std::vector<asio::ip::tcp::endpoint> endpoints_;
|
||||
|
||||
bool completed_ {false};
|
||||
std::queue<ResolverCb> cbs_;
|
||||
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
};
|
||||
|
||||
struct Response
|
||||
{
|
||||
unsigned int status_code {0};
|
||||
std::map<std::string, std::string> headers;
|
||||
std::string body;
|
||||
bool aborted {false};
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC Request : public std::enable_shared_from_this<Request>
|
||||
{
|
||||
public:
|
||||
enum class State {
|
||||
CREATED,
|
||||
SENDING,
|
||||
HEADER_RECEIVED,
|
||||
RECEIVING,
|
||||
DONE
|
||||
};
|
||||
using OnStatusCb = std::function<void(unsigned int 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 int status_code)>;
|
||||
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, 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 = {});
|
||||
Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, std::shared_ptr<dht::Logger> logger = {});
|
||||
|
||||
// user defined resolver
|
||||
Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, sa_family_t family = AF_UNSPEC);
|
||||
Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, const std::string& target, sa_family_t family = AF_UNSPEC);
|
||||
|
||||
// user defined resolved endpoints
|
||||
Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints,
|
||||
const bool ssl = false, std::shared_ptr<dht::Logger> logger = {});
|
||||
|
||||
~Request();
|
||||
|
||||
inline unsigned int id() const { return id_; };
|
||||
void set_connection(std::shared_ptr<Connection> connection);
|
||||
std::shared_ptr<Connection> get_connection() const;
|
||||
inline const Url& get_url() const {
|
||||
return resolver_->get_url();
|
||||
};
|
||||
inline std::string& to_string() {
|
||||
return request_;
|
||||
}
|
||||
|
||||
void set_certificate_authority(std::shared_ptr<dht::crypto::Certificate> certificate);
|
||||
void set_identity(const dht::crypto::Identity& identity);
|
||||
void set_logger(std::shared_ptr<dht::Logger> logger);
|
||||
|
||||
/**
|
||||
* Define the HTTP header/body as per https://tools.ietf.org/html/rfc7230.
|
||||
*/
|
||||
void set_header(restinio::http_request_header_t header);
|
||||
void set_method(restinio::http_method_id_t method);
|
||||
void set_target(std::string target);
|
||||
void set_header_field(restinio::http_field_t field, std::string value);
|
||||
void set_connection_type(restinio::http_connection_header_t connection);
|
||||
void set_body(std::string body);
|
||||
void set_auth(const std::string& username, const std::string& password);
|
||||
|
||||
void add_on_status_callback(OnStatusCb cb);
|
||||
void add_on_body_callback(OnDataCb cb);
|
||||
void add_on_state_change_callback(OnStateChangeCb cb);
|
||||
void add_on_done_callback(OnDoneCb cb);
|
||||
|
||||
void send();
|
||||
|
||||
/**
|
||||
* User action to cancel the Request and call the completion callbacks.
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
using OnCompleteCb = std::function<void()>;
|
||||
|
||||
struct Callbacks {
|
||||
OnStatusCb on_status;
|
||||
OnDataCb on_header_field;
|
||||
OnDataCb on_header_value;
|
||||
OnDataCb on_body;
|
||||
OnStateChangeCb on_state_change;
|
||||
};
|
||||
|
||||
void notify_state_change(State state);
|
||||
|
||||
void build();
|
||||
|
||||
void init_default_headers();
|
||||
/**
|
||||
* Initialized and wraps the http_parser callbacks with our user defined callbacks.
|
||||
*/
|
||||
void init_parser();
|
||||
|
||||
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);
|
||||
void handle_response(const asio::error_code& ec, size_t bytes);
|
||||
|
||||
void onHeadersComplete();
|
||||
void onBody(const char* at, size_t length);
|
||||
void onComplete();
|
||||
|
||||
std::shared_ptr<dht::Logger> logger_;
|
||||
|
||||
restinio::http_request_header_t header_;
|
||||
std::map<restinio::http_field_t, std::string> headers_;
|
||||
restinio::http_connection_header_t connection_type_ {restinio::http_connection_header_t::close};
|
||||
std::string body_;
|
||||
|
||||
Callbacks cbs_;
|
||||
State state_;
|
||||
|
||||
dht::crypto::Identity client_identity_;
|
||||
std::shared_ptr<dht::crypto::Certificate> server_ca_;
|
||||
std::string service_;
|
||||
std::string host_;
|
||||
|
||||
unsigned int id_;
|
||||
static std::atomic_uint ids_;
|
||||
asio::io_context& ctx_;
|
||||
sa_family_t family_ = AF_UNSPEC;
|
||||
std::shared_ptr<Connection> conn_;
|
||||
std::shared_ptr<Resolver> resolver_;
|
||||
|
||||
Response response_ {};
|
||||
std::string request_;
|
||||
std::atomic<bool> finishing_ {false};
|
||||
std::unique_ptr<http_parser> parser_;
|
||||
std::unique_ptr<http_parser_settings> parser_s_;
|
||||
};
|
||||
|
||||
} // 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
|
||||
@@ -50,7 +50,7 @@ namespace dht {
|
||||
using byte = uint8_t;
|
||||
|
||||
namespace crypto {
|
||||
OPENDHT_PUBLIC void hash(const uint8_t* data, size_t data_length, uint8_t* hash, size_t hash_length);
|
||||
OPENDHT_PUBLIC void hash(const uint8_t* data, size_t data_length, uint8_t* hash, size_t hash_length);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
typedef typename T::iterator iterator;
|
||||
typedef typename T::const_iterator const_iterator;
|
||||
|
||||
Hash () {
|
||||
Hash () noexcept {
|
||||
data_.fill(0);
|
||||
}
|
||||
Hash (const uint8_t* h, size_t data_len) {
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
msgpack_unpack(o);
|
||||
}
|
||||
|
||||
size_t size() const { return data_.size(); }
|
||||
static constexpr size_t size() noexcept { return N; }
|
||||
const uint8_t* data() const { return data_.data(); }
|
||||
uint8_t* data() { return data_.data(); }
|
||||
iterator begin() { return data_.begin(); }
|
||||
|
||||
+14
-1
@@ -19,12 +19,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dhtrunner.h"
|
||||
#include "def.h"
|
||||
#include "log_enable.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
namespace dht {
|
||||
|
||||
class DhtRunner;
|
||||
|
||||
/**
|
||||
* Logging-related functions
|
||||
*/
|
||||
@@ -66,6 +70,15 @@ constexpr const Color::Modifier yellow(Color::FG_YELLOW);
|
||||
OPENDHT_PUBLIC void
|
||||
printLog(std::ostream &s, char const *m, va_list args);
|
||||
|
||||
OPENDHT_PUBLIC
|
||||
std::shared_ptr<Logger> getStdLogger();
|
||||
|
||||
OPENDHT_PUBLIC
|
||||
std::shared_ptr<Logger> getFileLogger(const std::string &path);
|
||||
|
||||
OPENDHT_PUBLIC
|
||||
std::shared_ptr<Logger> getSyslogLogger(const char* name);
|
||||
|
||||
OPENDHT_PUBLIC void
|
||||
enableLogging(dht::DhtRunner &dht);
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "infohash.h"
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
#ifndef OPENDHT_LOG
|
||||
#define OPENDHT_LOG true
|
||||
#endif
|
||||
@@ -32,11 +34,6 @@ namespace dht {
|
||||
|
||||
// Logging related utility functions
|
||||
|
||||
/**
|
||||
* Dummy function used to disable logging
|
||||
*/
|
||||
inline void NOLOG(char const*, va_list) {}
|
||||
|
||||
/**
|
||||
* Wrapper for logging methods
|
||||
*/
|
||||
@@ -85,9 +82,13 @@ private:
|
||||
};
|
||||
|
||||
struct Logger {
|
||||
LogMethod DBG = NOLOG;
|
||||
LogMethod WARN = NOLOG;
|
||||
LogMethod ERR = NOLOG;
|
||||
LogMethod DBG = {};
|
||||
LogMethod WARN = {};
|
||||
LogMethod ERR = {};
|
||||
|
||||
Logger() = default;
|
||||
Logger(LogMethod&& err, LogMethod&& warn, LogMethod&& dbg)
|
||||
: DBG(std::move(dbg)), WARN(std::move(warn)), ERR(std::move(err)) {}
|
||||
void setFilter(const InfoHash& f) {
|
||||
filter_ = f;
|
||||
filterEnable_ = static_cast<bool>(filter_);
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "utils.h"
|
||||
#include "rng.h"
|
||||
#include "rate_limiter.h"
|
||||
#include "log_enable.h"
|
||||
#include "network_utils.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -46,6 +48,12 @@ struct TransId;
|
||||
#define MSG_CONFIRM 0
|
||||
#endif
|
||||
|
||||
struct NetworkConfig {
|
||||
NetId network {0};
|
||||
ssize_t max_req_per_sec {0};
|
||||
ssize_t max_peer_req_per_sec {0};
|
||||
};
|
||||
|
||||
class DhtProtocolException : public DhtException {
|
||||
public:
|
||||
// sent to another peer (http-like).
|
||||
@@ -68,14 +76,14 @@ public:
|
||||
DhtProtocolException(uint16_t code, const std::string& msg="", InfoHash failing_node_id={})
|
||||
: DhtException(msg), msg(msg), code(code), failing_node_id(failing_node_id) {}
|
||||
|
||||
std::string getMsg() const { return msg; }
|
||||
const std::string& getMsg() const { return msg; }
|
||||
uint16_t getCode() const { return code; }
|
||||
const InfoHash getNodeId() const { return failing_node_id; }
|
||||
const InfoHash& getNodeId() const { return failing_node_id; }
|
||||
|
||||
private:
|
||||
std::string msg;
|
||||
uint16_t code;
|
||||
const InfoHash failing_node_id;
|
||||
InfoHash failing_node_id;
|
||||
};
|
||||
|
||||
struct ParsedMessage;
|
||||
@@ -204,8 +212,13 @@ public:
|
||||
using RequestCb = std::function<void(const Request&, RequestAnswer&&)>;
|
||||
using RequestExpiredCb = std::function<void(const Request&, bool)>;
|
||||
|
||||
NetworkEngine(Logger& log, Scheduler& scheduler, const int& s = -1, const int& s6 = -1);
|
||||
NetworkEngine(InfoHash& myid, NetId net, const int& s, const int& s6, Logger& log, Scheduler& scheduler,
|
||||
NetworkEngine(Logger& log, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock);
|
||||
NetworkEngine(
|
||||
InfoHash& myid,
|
||||
NetworkConfig config,
|
||||
std::unique_ptr<DatagramSocket>&& sock,
|
||||
Logger& log,
|
||||
Scheduler& scheduler,
|
||||
decltype(NetworkEngine::onError)&& onError,
|
||||
decltype(NetworkEngine::onNewNode)&& onNewNode,
|
||||
decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
|
||||
@@ -216,7 +229,9 @@ public:
|
||||
decltype(NetworkEngine::onAnnounce)&& onAnnounce,
|
||||
decltype(NetworkEngine::onRefresh)&& onRefresh);
|
||||
|
||||
virtual ~NetworkEngine();
|
||||
~NetworkEngine();
|
||||
|
||||
net::DatagramSocket* getSocket() const { return dht_socket.get(); };
|
||||
|
||||
void clear();
|
||||
|
||||
@@ -241,7 +256,7 @@ public:
|
||||
void tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash& hash, const Blob& ntoken, const std::vector<Value::Id>& values);
|
||||
|
||||
bool isRunning(sa_family_t af) const;
|
||||
inline want_t want () const { return dht_socket >= 0 && dht_socket6 >= 0 ? (WANT4 | WANT6) : -1; }
|
||||
inline want_t want () const { return dht_socket->hasIPv4() and dht_socket->hasIPv6() ? (WANT4 | WANT6) : -1; }
|
||||
|
||||
void connectivityChanged(sa_family_t);
|
||||
|
||||
@@ -271,8 +286,8 @@ public:
|
||||
* @return the request with information concerning its success.
|
||||
*/
|
||||
Sp<Request>
|
||||
sendPing(const sockaddr* sa, socklen_t salen, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
|
||||
return sendPing(std::make_shared<Node>(zeroes, sa, salen),
|
||||
sendPing(SockAddr&& sa, RequestCb&& on_done, RequestExpiredCb&& on_expired) {
|
||||
return sendPing(std::make_shared<Node>(zeroes, std::move(sa)),
|
||||
std::forward<RequestCb>(on_done),
|
||||
std::forward<RequestExpiredCb>(on_expired));
|
||||
}
|
||||
@@ -393,7 +408,7 @@ public:
|
||||
* @param fromlen The length of the corresponding sockaddr structure.
|
||||
* @param now The time to adjust the clock in the network engine.
|
||||
*/
|
||||
void processMessage(const uint8_t *buf, size_t buflen, const SockAddr& addr);
|
||||
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);
|
||||
@@ -421,7 +436,6 @@ private:
|
||||
/***************
|
||||
* Constants *
|
||||
***************/
|
||||
static constexpr size_t MAX_REQUESTS_PER_SEC {1600};
|
||||
/* the length of a node info buffer in ipv4 format */
|
||||
static const constexpr size_t NODE4_INFO_BUF_LEN {HASH_LEN + sizeof(in_addr) + sizeof(in_port_t)};
|
||||
/* the length of a node info buffer in ipv6 format */
|
||||
@@ -468,7 +482,7 @@ private:
|
||||
|
||||
|
||||
// basic wrapper for socket sendto function
|
||||
int send(const char *buf, size_t len, int flags, const SockAddr& addr);
|
||||
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);
|
||||
std::vector<Blob> packValueHeader(msgpack::sbuffer&, const std::vector<Sp<Value>>&);
|
||||
@@ -509,19 +523,18 @@ private:
|
||||
|
||||
/* DHT info */
|
||||
const InfoHash& myid;
|
||||
const NetId network {0};
|
||||
const int& dht_socket;
|
||||
const int& dht_socket6;
|
||||
const NetworkConfig config {};
|
||||
const std::unique_ptr<DatagramSocket> dht_socket;
|
||||
const Logger& DHT_LOG;
|
||||
|
||||
NodeCache cache {};
|
||||
|
||||
// global limiting should be triggered by at least 8 different IPs
|
||||
using IpLimiter = RateLimiter<MAX_REQUESTS_PER_SEC/8>;
|
||||
using IpLimiter = RateLimiter;
|
||||
using IpLimiterMap = std::map<SockAddr, IpLimiter, SockAddr::ipCmp>;
|
||||
IpLimiterMap address_rate_limiter {};
|
||||
RateLimiter<MAX_REQUESTS_PER_SEC> rate_limiter {};
|
||||
size_t limiter_maintenance {0};
|
||||
IpLimiterMap address_rate_limiter;
|
||||
RateLimiter rate_limiter;
|
||||
ssize_t limiter_maintenance {0};
|
||||
|
||||
// requests handling
|
||||
std::map<Tid, Sp<Request>> requests {};
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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
|
||||
* 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 "def.h"
|
||||
|
||||
#include "sockaddr.h"
|
||||
#include "utils.h"
|
||||
#include "log_enable.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
static const constexpr in_port_t DHT_DEFAULT_PORT = 4222;
|
||||
|
||||
int bindSocket(const SockAddr& addr, SockAddr& bound);
|
||||
|
||||
bool setNonblocking(int fd, bool nonblocking = true);
|
||||
|
||||
#ifdef _WIN32
|
||||
void udpPipe(int fds[2]);
|
||||
#endif
|
||||
struct ReceivedPacket {
|
||||
Blob data;
|
||||
SockAddr from;
|
||||
time_point received;
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC DatagramSocket {
|
||||
public:
|
||||
using OnReceive = std::function<void(std::unique_ptr<ReceivedPacket>&& packet)>;
|
||||
virtual ~DatagramSocket() {};
|
||||
|
||||
virtual int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) = 0;
|
||||
|
||||
inline void setOnReceive(OnReceive&& cb) {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
rx_callback = std::move(cb);
|
||||
}
|
||||
|
||||
virtual bool hasIPv4() const = 0;
|
||||
virtual bool hasIPv6() const = 0;
|
||||
|
||||
SockAddr getBound(sa_family_t family = AF_UNSPEC) const {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
return getBoundRef(family);
|
||||
}
|
||||
in_port_t getPort(sa_family_t family = AF_UNSPEC) const {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
return getBoundRef(family).getPort();
|
||||
}
|
||||
|
||||
virtual const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const = 0;
|
||||
|
||||
virtual void stop() = 0;
|
||||
protected:
|
||||
|
||||
inline void onReceived(std::unique_ptr<ReceivedPacket>&& packet) {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
if (rx_callback)
|
||||
rx_callback(std::move(packet));
|
||||
}
|
||||
protected:
|
||||
mutable std::mutex lock;
|
||||
private:
|
||||
OnReceive rx_callback;
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC UdpSocket : public DatagramSocket {
|
||||
public:
|
||||
UdpSocket(in_port_t port, const Logger& l = {});
|
||||
UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const Logger& l = {});
|
||||
~UdpSocket();
|
||||
|
||||
int sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) override;
|
||||
|
||||
const SockAddr& getBoundRef(sa_family_t family = AF_UNSPEC) const override {
|
||||
return (family == AF_INET6) ? bound6 : bound4;
|
||||
}
|
||||
|
||||
bool hasIPv4() const override {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
return s4 != -1;
|
||||
}
|
||||
bool hasIPv6() const override {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
return s6 != -1;
|
||||
}
|
||||
|
||||
void stop() override;
|
||||
private:
|
||||
Logger logger;
|
||||
int s4 {-1};
|
||||
int s6 {-1};
|
||||
int stopfd {-1};
|
||||
SockAddr bound4, bound6;
|
||||
std::thread rcv_thread {};
|
||||
std::atomic_bool running {false};
|
||||
|
||||
void openSockets(const SockAddr& bind4, const SockAddr& bind6);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,7 @@ struct Node {
|
||||
const InfoHash id;
|
||||
|
||||
Node(const InfoHash& id, const SockAddr& addr, bool client=false);
|
||||
Node(const InfoHash& id, SockAddr&& addr, bool client=false);
|
||||
Node(const InfoHash& id, const sockaddr* sa, socklen_t salen)
|
||||
: Node(id, SockAddr(sa, salen)) {}
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
|
||||
* Author(s) : Mingrui Zhang <mingrui.zhang@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
|
||||
* 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 "def.h"
|
||||
#include "sockaddr.h"
|
||||
#include "infohash.h"
|
||||
#include "log_enable.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace asio {
|
||||
class io_context;
|
||||
}
|
||||
|
||||
namespace dht {
|
||||
|
||||
class OPENDHT_PUBLIC PeerDiscovery
|
||||
{
|
||||
public:
|
||||
static constexpr in_port_t DEFAULT_PORT = 8888;
|
||||
using ServiceDiscoveredCallback = std::function<void(msgpack::object&&, SockAddr&&)>;
|
||||
|
||||
PeerDiscovery(in_port_t port = DEFAULT_PORT, std::shared_ptr<asio::io_context> ioContext = {}, std::shared_ptr<Logger> logger = {});
|
||||
~PeerDiscovery();
|
||||
|
||||
/**
|
||||
* startDiscovery - Keep Listening data from the sender until node is joinned or stop is called
|
||||
*/
|
||||
void startDiscovery(const std::string &type, ServiceDiscoveredCallback callback);
|
||||
|
||||
template<typename T>
|
||||
void startDiscovery(const std::string &type, std::function<void(T&&, SockAddr&&)> cb) {
|
||||
startDiscovery(type, [cb](msgpack::object&& ob, SockAddr&& addr) {
|
||||
cb(ob.as<T>(), std::move(addr));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* startPublish - Keeping sending data until node is joinned or stop is called
|
||||
*/
|
||||
void startPublish(const std::string &type, const msgpack::sbuffer &pack_buf);
|
||||
void startPublish(sa_family_t domain, const std::string &type, const msgpack::sbuffer &pack_buf);
|
||||
|
||||
template<typename T>
|
||||
void startPublish(const std::string &type, const T& object) {
|
||||
msgpack::sbuffer buf;
|
||||
msgpack::pack(buf, object);
|
||||
startPublish(type, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread Stopper
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Remove possible callBack to discovery
|
||||
*/
|
||||
bool stopDiscovery(const std::string &type);
|
||||
|
||||
/**
|
||||
* Remove different serivce message to send
|
||||
*/
|
||||
bool stopPublish(const std::string &type);
|
||||
bool stopPublish(sa_family_t domain, const std::string &type);
|
||||
|
||||
private:
|
||||
class DomainPeerDiscovery;
|
||||
std::unique_ptr<DomainPeerDiscovery> peerDiscovery4_;
|
||||
std::unique_ptr<DomainPeerDiscovery> peerDiscovery6_;
|
||||
std::shared_ptr<asio::io_context> ioContext_;
|
||||
std::thread ioRunnner_;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -23,19 +23,23 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
template<size_t Quota, unsigned long Period=1>
|
||||
class RateLimiter {
|
||||
public:
|
||||
RateLimiter(size_t quota, const duration& period = std::chrono::seconds(1))
|
||||
: quota_(quota), period_(period) {}
|
||||
|
||||
/** Clear outdated records and return current quota usage */
|
||||
size_t maintain(const time_point& now) {
|
||||
auto limit = now - std::chrono::seconds(Period);
|
||||
auto limit = now - period_;
|
||||
while (not records.empty() and records.front() < limit)
|
||||
records.pop();
|
||||
return records.size();
|
||||
}
|
||||
/** Return false if quota is reached, insert record and return true otherwise. */
|
||||
bool limit(const time_point& now) {
|
||||
if (maintain(now) >= Quota)
|
||||
if (quota_ == std::numeric_limits<size_t>::max())
|
||||
return true;
|
||||
if (maintain(now) >= quota_)
|
||||
return false;
|
||||
records.emplace(now);
|
||||
return true;
|
||||
@@ -44,6 +48,8 @@ public:
|
||||
return records.empty();
|
||||
}
|
||||
private:
|
||||
const size_t quota_;
|
||||
const duration period_;
|
||||
std::queue<time_point> records {};
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "log_enable.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
+13
-14
@@ -195,8 +195,8 @@ public:
|
||||
std::vector<SockAddr> getPublicAddress(sa_family_t family = 0) override {
|
||||
return dht_->getPublicAddress(family);
|
||||
}
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, const SockAddr& sa) override {
|
||||
return dht_->periodic(buf, buflen, sa);
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, SockAddr sa) override {
|
||||
return dht_->periodic(buf, buflen, std::move(sa));
|
||||
}
|
||||
time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) override {
|
||||
return dht_->periodic(buf, buflen, from, fromlen);
|
||||
@@ -207,6 +207,9 @@ public:
|
||||
NodeStatus getStatus() const override {
|
||||
return dht_->getStatus();
|
||||
}
|
||||
net::DatagramSocket* getSocket() const override {
|
||||
return dht_->getSocket();
|
||||
};
|
||||
bool isRunning(sa_family_t af = 0) const override {
|
||||
return dht_->isRunning(af);
|
||||
}
|
||||
@@ -216,14 +219,11 @@ public:
|
||||
void insertNode(const InfoHash& id, const SockAddr& sa) override {
|
||||
dht_->insertNode(id, sa);
|
||||
}
|
||||
void insertNode(const InfoHash& id, const sockaddr* sa, socklen_t salen) override {
|
||||
dht_->insertNode(id, sa, salen);
|
||||
}
|
||||
void insertNode(const NodeExport& n) override {
|
||||
dht_->insertNode(n);
|
||||
}
|
||||
void pingNode(const sockaddr* sa, socklen_t salen, DoneCallbackSimple&& cb={}) override {
|
||||
dht_->pingNode(sa, salen, std::move(cb));
|
||||
void pingNode(SockAddr sa, DoneCallbackSimple&& cb={}) override {
|
||||
dht_->pingNode(std::move(sa), std::move(cb));
|
||||
}
|
||||
void query(const InfoHash& key, QueryCallback cb, DoneCallback done_cb = {}, Query&& q = {}) override {
|
||||
dht_->query(key, cb, done_cb, std::move(q));
|
||||
@@ -231,7 +231,7 @@ public:
|
||||
void query(const InfoHash& key, QueryCallback cb, DoneCallbackSimple done_cb = {}, Query&& q = {}) override {
|
||||
dht_->query(key, cb, done_cb, std::move(q));
|
||||
}
|
||||
std::vector<Sp<Value>> getLocal(const InfoHash& key, Value::Filter f = Value::AllFilter()) const override {
|
||||
std::vector<Sp<Value>> getLocal(const InfoHash& key, const Value::Filter& f = {}) const override {
|
||||
return dht_->getLocal(key, f);
|
||||
}
|
||||
Sp<Value> getLocalById(const InfoHash& key, Value::Id vid) const override {
|
||||
@@ -270,10 +270,10 @@ public:
|
||||
{
|
||||
dht_->put(key, std::move(v), cb, created, permanent);
|
||||
}
|
||||
std::vector<Sp<Value>> getPut(const InfoHash& h) override {
|
||||
std::vector<Sp<Value>> getPut(const InfoHash& h) const override {
|
||||
return dht_->getPut(h);
|
||||
}
|
||||
Sp<Value> getPut(const InfoHash& h, const Value::Id& vid) override {
|
||||
Sp<Value> getPut(const InfoHash& h, const Value::Id& vid) const override {
|
||||
return dht_->getPut(h, vid);
|
||||
}
|
||||
bool cancelPut(const InfoHash& h, const Value::Id& vid) override {
|
||||
@@ -311,10 +311,9 @@ public:
|
||||
dht_->pushNotificationReceived(notification);
|
||||
}
|
||||
|
||||
void setLoggers(LogMethod error = NOLOG, LogMethod warn = NOLOG, LogMethod debug = NOLOG) override
|
||||
{
|
||||
DhtInterface::setLoggers(error, warn, debug);
|
||||
dht_->setLoggers(error, warn, debug);
|
||||
void setLogger(const Logger& logger) override {
|
||||
DhtInterface::setLogger(logger);
|
||||
dht_->setLogger(logger);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef __ANDROID__
|
||||
typedef uint16_t in_port_t;
|
||||
#endif
|
||||
@@ -39,6 +40,7 @@ typedef uint16_t in_port_t;
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cstring>
|
||||
@@ -58,7 +60,7 @@ public:
|
||||
SockAddr(const SockAddr& o) {
|
||||
set(o.get(), o.getLength());
|
||||
}
|
||||
SockAddr(SockAddr&& o) noexcept : len(o.len), addr(std::move(o.addr)) {
|
||||
SockAddr(SockAddr&& o) noexcept : addr(std::move(o.addr)), len(o.len) {
|
||||
o.len = 0;
|
||||
}
|
||||
|
||||
@@ -118,7 +120,7 @@ public:
|
||||
/**
|
||||
* Returns the address family or AF_UNSPEC if the address is not set.
|
||||
*/
|
||||
sa_family_t getFamily() const { return len > sizeof(sa_family_t) ? addr->sa_family : AF_UNSPEC; }
|
||||
sa_family_t getFamily() const { return len ? addr->sa_family : AF_UNSPEC; }
|
||||
|
||||
/**
|
||||
* Resize the managed structure to the appropriate size (if needed),
|
||||
@@ -146,6 +148,21 @@ public:
|
||||
addr->sa_family = af;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Network Interface to any
|
||||
*/
|
||||
void setAny() {
|
||||
auto family = getFamily();
|
||||
switch(family) {
|
||||
case AF_INET:
|
||||
getIPv4().sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
break;
|
||||
case AF_INET6:
|
||||
getIPv6().sin6_addr = in6addr_any;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive the port (in host byte order) or 0 if the address is not
|
||||
* of a supported family.
|
||||
@@ -175,6 +192,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address part of the socket address from a numeric IP address (string representation).
|
||||
* Family must be already set. Throws in case of parse failue.
|
||||
*/
|
||||
void setAddress(const char* address);
|
||||
|
||||
/**
|
||||
* Returns the accessible byte length at the pointer returned by #get().
|
||||
* If zero, #get() returns null.
|
||||
@@ -226,7 +249,8 @@ public:
|
||||
bool isUnspecified() const;
|
||||
|
||||
bool isMappedIPv4() const;
|
||||
SockAddr getMappedIPv4() const;
|
||||
SockAddr getMappedIPv4();
|
||||
SockAddr getMappedIPv6();
|
||||
|
||||
/**
|
||||
* A comparator to classify IP addresses, only considering the
|
||||
@@ -257,9 +281,9 @@ public:
|
||||
}
|
||||
};
|
||||
private:
|
||||
socklen_t len {0};
|
||||
struct free_delete { void operator()(void* p) { ::free(p); } };
|
||||
std::unique_ptr<sockaddr, free_delete> addr {};
|
||||
socklen_t len {0};
|
||||
|
||||
void set(const sockaddr* sa, socklen_t length) {
|
||||
if (len != length) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
@@ -27,7 +29,7 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
class ThreadPool {
|
||||
class OPENDHT_PUBLIC ThreadPool {
|
||||
public:
|
||||
static ThreadPool& computation();
|
||||
static ThreadPool& io();
|
||||
@@ -41,14 +43,20 @@ public:
|
||||
template<class T>
|
||||
std::future<T> get(std::function<T()>&& cb) {
|
||||
auto ret = std::make_shared<std::promise<T>>();
|
||||
run(std::bind([=](std::function<T()>& mcb) mutable {
|
||||
ret->set_value(mcb());
|
||||
}, std::move(cb)));
|
||||
run([cb = std::move(cb), ret]() mutable {
|
||||
try {
|
||||
ret->set_value(cb());
|
||||
} catch (...) {
|
||||
try {
|
||||
ret->set_exception(std::current_exception());
|
||||
} catch(...) {}
|
||||
}
|
||||
});
|
||||
return ret->get_future();
|
||||
}
|
||||
template<class T>
|
||||
std::shared_ptr<std::future<T>> getShared(std::function<T()>&& cb) {
|
||||
return std::make_shared<std::future<T>>(get(std::move(cb)));
|
||||
std::shared_future<T> getShared(std::function<T()>&& cb) {
|
||||
return get(std::move(cb));
|
||||
}
|
||||
|
||||
void stop();
|
||||
@@ -66,4 +74,23 @@ private:
|
||||
bool running_ {true};
|
||||
};
|
||||
|
||||
class OPENDHT_PUBLIC Executor : public std::enable_shared_from_this<Executor> {
|
||||
public:
|
||||
Executor(ThreadPool& pool, unsigned maxConcurrent = 1)
|
||||
: threadPool_(pool), maxConcurrent_(maxConcurrent)
|
||||
{}
|
||||
|
||||
void run(std::function<void()>&& task);
|
||||
|
||||
private:
|
||||
std::reference_wrapper<ThreadPool> threadPool_;
|
||||
const unsigned maxConcurrent_ {1};
|
||||
std::mutex lock_ {};
|
||||
unsigned current_ {0};
|
||||
std::queue<std::function<void()>> tasks_ {};
|
||||
|
||||
void run_(std::function<void()>&& task);
|
||||
void schedule();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -40,6 +40,8 @@ namespace dht {
|
||||
using NetId = uint32_t;
|
||||
using want_t = int_fast8_t;
|
||||
|
||||
OPENDHT_PUBLIC const char* version();
|
||||
|
||||
// shortcut for std::shared_ptr
|
||||
template<class T>
|
||||
using Sp = std::shared_ptr<T>;
|
||||
@@ -90,6 +92,21 @@ print_dt(DT d) {
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(d).count();
|
||||
}
|
||||
|
||||
template <class DT>
|
||||
static std::string
|
||||
print_duration(DT d) {
|
||||
if (d < std::chrono::seconds(0)) {
|
||||
return "-" + print_duration(-d);
|
||||
}
|
||||
if (d < std::chrono::milliseconds(1)) {
|
||||
return std::to_string(std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(d).count()) + " us";
|
||||
} else if (d < std::chrono::seconds(1)) {
|
||||
return std::to_string(std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(d).count()) + " ms";
|
||||
} else {
|
||||
return std::to_string(print_dt(d)) + " s";
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Duration = duration>
|
||||
class uniform_duration_distribution : public std::uniform_int_distribution<typename Duration::rep> {
|
||||
using Base = std::uniform_int_distribution<typename Duration::rep>;
|
||||
|
||||
+28
-33
@@ -20,7 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "infohash.h"
|
||||
#include "crypto.h"
|
||||
//#include "crypto.h"
|
||||
#include "utils.h"
|
||||
#include "sockaddr.h"
|
||||
|
||||
@@ -46,6 +46,12 @@ namespace dht {
|
||||
struct Value;
|
||||
struct Query;
|
||||
|
||||
namespace crypto {
|
||||
class PublicKey;
|
||||
class PrivateKey;
|
||||
class Certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* A storage policy is applied once to every incoming value storage requests.
|
||||
* If the policy returns false, the value is dropped.
|
||||
@@ -167,7 +173,7 @@ struct OPENDHT_PUBLIC Value
|
||||
static Filter chain(Filter&& f1, Filter&& f2) {
|
||||
if (not f1) return std::move(f2);
|
||||
if (not f2) return std::move(f1);
|
||||
return [f1,f2](const Value& v) {
|
||||
return [f1 = std::move(f1), f2 = std::move(f2)](const Value& v) {
|
||||
return f1(v) and f2(v);
|
||||
};
|
||||
}
|
||||
@@ -180,12 +186,12 @@ struct OPENDHT_PUBLIC Value
|
||||
}
|
||||
static Filter chainAll(std::vector<Filter>&& set) {
|
||||
if (set.empty()) return {};
|
||||
return std::bind([](const Value& v, std::vector<Filter>& s) {
|
||||
for (const auto& f : s)
|
||||
return [set = std::move(set)](const Value& v) {
|
||||
for (const auto& f : set)
|
||||
if (f and not f(v))
|
||||
return false;
|
||||
return true;
|
||||
}, std::placeholders::_1, std::move(set));
|
||||
};
|
||||
}
|
||||
static Filter chain(std::initializer_list<Filter> l) {
|
||||
return chainAll(std::vector<Filter>(l.begin(), l.end()));
|
||||
@@ -241,15 +247,9 @@ struct OPENDHT_PUBLIC Value
|
||||
};
|
||||
}
|
||||
|
||||
static Filter OwnerFilter(const crypto::PublicKey& pk) {
|
||||
return OwnerFilter(pk.getId());
|
||||
}
|
||||
static Filter OwnerFilter(const crypto::PublicKey& pk);
|
||||
|
||||
static Filter OwnerFilter(const InfoHash& pkh) {
|
||||
return [pkh](const Value& v) {
|
||||
return v.owner and v.owner->getId() == pkh;
|
||||
};
|
||||
}
|
||||
static Filter OwnerFilter(const InfoHash& pkh);
|
||||
|
||||
static Filter SeqNumFilter(uint16_t seq_no) {
|
||||
return [seq_no](const Value& v) {
|
||||
@@ -341,20 +341,13 @@ struct OPENDHT_PUBLIC Value
|
||||
* Afterward, checkSignature() will return true and owner will
|
||||
* be set to the corresponding public key.
|
||||
*/
|
||||
void sign(const crypto::PrivateKey& key) {
|
||||
if (isEncrypted())
|
||||
throw DhtException("Can't sign encrypted data.");
|
||||
owner = std::make_shared<const crypto::PublicKey>(key.getPublicKey());
|
||||
signature = key.sign(getToSign());
|
||||
}
|
||||
void sign(const crypto::PrivateKey& key);
|
||||
|
||||
/**
|
||||
* Check that the value is signed and that the signature matches.
|
||||
* If true, the owner field will contain the signer public key.
|
||||
*/
|
||||
bool checkSignature() const {
|
||||
return isSigned() and owner->checkSignature(getToSign(), signature);
|
||||
}
|
||||
bool checkSignature() const;
|
||||
|
||||
std::shared_ptr<const crypto::PublicKey> getOwner() const {
|
||||
return std::static_pointer_cast<const crypto::PublicKey>(owner);
|
||||
@@ -363,15 +356,7 @@ struct OPENDHT_PUBLIC Value
|
||||
/**
|
||||
* Sign the value with from and returns the encrypted version for to.
|
||||
*/
|
||||
Value encrypt(const crypto::PrivateKey& from, const crypto::PublicKey& to) {
|
||||
if (isEncrypted())
|
||||
throw DhtException("Data is already encrypted.");
|
||||
setRecipient(to.getId());
|
||||
sign(from);
|
||||
Value nv {id};
|
||||
nv.setCypher(to.encrypt(getToEncrypt()));
|
||||
return nv;
|
||||
}
|
||||
Value encrypt(const crypto::PrivateKey& from, const crypto::PublicKey& to);
|
||||
|
||||
Value() {}
|
||||
|
||||
@@ -424,7 +409,11 @@ struct OPENDHT_PUBLIC Value
|
||||
inline bool operator== (const Value& o) {
|
||||
return id == o.id &&
|
||||
(isEncrypted() ? cypher == o.cypher :
|
||||
((owner == o.owner || *owner == *o.owner) && type == o.type && data == o.data && user_type == o.user_type && signature == o.signature));
|
||||
(
|
||||
#ifndef OPENDHT_LIGHT
|
||||
(owner == o.owner || *owner == *o.owner) &&
|
||||
#endif
|
||||
type == o.type && data == o.data && user_type == o.user_type && signature == o.signature));
|
||||
}
|
||||
|
||||
void setRecipient(const InfoHash& r) {
|
||||
@@ -482,7 +471,8 @@ struct OPENDHT_PUBLIC Value
|
||||
template <typename Packer>
|
||||
void msgpack_pack_to_sign(Packer& pk) const
|
||||
{
|
||||
bool has_owner = owner && *owner;
|
||||
#ifndef OPENDHT_LIGHT
|
||||
bool has_owner = owner && *owner
|
||||
pk.pack_map((user_type.empty()?0:1) + (has_owner?(recipient ? 5 : 4):2));
|
||||
if (has_owner) { // isSigned
|
||||
pk.pack(std::string("seq")); pk.pack(seq);
|
||||
@@ -491,6 +481,9 @@ struct OPENDHT_PUBLIC Value
|
||||
pk.pack(std::string("to")); pk.pack(recipient);
|
||||
}
|
||||
}
|
||||
#else
|
||||
pk.pack_map((user_type.empty()?0:1) + 2);
|
||||
#endif
|
||||
pk.pack(std::string("type")); pk.pack(type);
|
||||
pk.pack(std::string("data")); pk.pack_bin(data.size());
|
||||
pk.pack_bin_body((const char*)data.data(), data.size());
|
||||
@@ -535,9 +528,11 @@ struct OPENDHT_PUBLIC Value
|
||||
pk.pack(static_cast<uint64_t>(type));
|
||||
break;
|
||||
case Value::Field::OwnerPk:
|
||||
#ifndef OPENDHT_LIGHT
|
||||
if (owner)
|
||||
owner->msgpack_pack(pk);
|
||||
else
|
||||
#endif
|
||||
InfoHash().msgpack_pack(pk);
|
||||
break;
|
||||
case Value::Field::SeqNum:
|
||||
|
||||
+419
-30
@@ -1,5 +1,5 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
@@ -33,21 +33,23 @@
|
||||
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||
# 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>
|
||||
#
|
||||
# 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 4
|
||||
#serial 11
|
||||
|
||||
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
|
||||
dnl (serial version number 13).
|
||||
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
m4_if([$1], [11], [],
|
||||
[$1], [14], [],
|
||||
[$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])],
|
||||
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"],
|
||||
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$2], [], [],
|
||||
[$2], [ext], [],
|
||||
@@ -59,18 +61,11 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
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 switch in -std=gnu++$1 -std=gnu++0x; do
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
switch="-std=gnu++${alternative}"
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
@@ -96,22 +91,27 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
dnl HP's aCC needs +std=c++11 according to:
|
||||
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
|
||||
dnl Cray's crayCC needs "-h std=c++11"
|
||||
for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
fi
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
ac_success=yes
|
||||
done
|
||||
if test x$ac_success = xyes; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
@@ -148,6 +148,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
)
|
||||
|
||||
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 Tests for new features in C++11
|
||||
|
||||
@@ -185,11 +190,13 @@ namespace cxx11
|
||||
|
||||
struct Base
|
||||
{
|
||||
virtual ~Base() {}
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
struct Derived : public Base
|
||||
{
|
||||
virtual ~Derived() override {}
|
||||
virtual void f() override {}
|
||||
};
|
||||
|
||||
@@ -518,7 +525,7 @@ namespace cxx14
|
||||
|
||||
}
|
||||
|
||||
namespace test_digit_seperators
|
||||
namespace test_digit_separators
|
||||
{
|
||||
|
||||
constexpr auto ten_million = 100'000'000;
|
||||
@@ -560,3 +567,385 @@ namespace cxx14
|
||||
#endif // __cplusplus >= 201402L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++17
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++17, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 201703L
|
||||
|
||||
#error "This is not a C++17 compiler"
|
||||
|
||||
#else
|
||||
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace cxx17
|
||||
{
|
||||
|
||||
namespace test_constexpr_lambdas
|
||||
{
|
||||
|
||||
constexpr int foo = [](){return 42;}();
|
||||
|
||||
}
|
||||
|
||||
namespace test::nested_namespace::definitions
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
namespace test_fold_expression
|
||||
{
|
||||
|
||||
template<typename... Args>
|
||||
int multiply(Args... args)
|
||||
{
|
||||
return (args * ... * 1);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
bool all(Args... args)
|
||||
{
|
||||
return (args && ...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_static_assert
|
||||
{
|
||||
|
||||
static_assert (true);
|
||||
|
||||
}
|
||||
|
||||
namespace test_auto_brace_init_list
|
||||
{
|
||||
|
||||
auto foo = {5};
|
||||
auto bar {5};
|
||||
|
||||
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
|
||||
static_assert(std::is_same<int, decltype(bar)>::value);
|
||||
}
|
||||
|
||||
namespace test_typename_in_template_template_parameter
|
||||
{
|
||||
|
||||
template<template<typename> typename X> struct D;
|
||||
|
||||
}
|
||||
|
||||
namespace test_fallthrough_nodiscard_maybe_unused_attributes
|
||||
{
|
||||
|
||||
int f1()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
[[nodiscard]] int f2()
|
||||
{
|
||||
[[maybe_unused]] auto unused = f1();
|
||||
|
||||
switch (f1())
|
||||
{
|
||||
case 17:
|
||||
f1();
|
||||
[[fallthrough]];
|
||||
case 42:
|
||||
f1();
|
||||
}
|
||||
return f1();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_aggregate_initialization
|
||||
{
|
||||
|
||||
struct base1
|
||||
{
|
||||
int b1, b2 = 42;
|
||||
};
|
||||
|
||||
struct base2
|
||||
{
|
||||
base2() {
|
||||
b3 = 42;
|
||||
}
|
||||
int b3;
|
||||
};
|
||||
|
||||
struct derived : base1, base2
|
||||
{
|
||||
int d;
|
||||
};
|
||||
|
||||
derived d1 {{1, 2}, {}, 4}; // full initialization
|
||||
derived d2 {{}, {}, 4}; // value-initialized bases
|
||||
|
||||
}
|
||||
|
||||
namespace test_general_range_based_for_loop
|
||||
{
|
||||
|
||||
struct iter
|
||||
{
|
||||
int i;
|
||||
|
||||
int& operator* ()
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
const int& operator* () const
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
iter& operator++()
|
||||
{
|
||||
++i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct sentinel
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
bool operator== (const iter& i, const sentinel& s)
|
||||
{
|
||||
return i.i == s.i;
|
||||
}
|
||||
|
||||
bool operator!= (const iter& i, const sentinel& s)
|
||||
{
|
||||
return !(i == s);
|
||||
}
|
||||
|
||||
struct range
|
||||
{
|
||||
iter begin() const
|
||||
{
|
||||
return {0};
|
||||
}
|
||||
|
||||
sentinel end() const
|
||||
{
|
||||
return {5};
|
||||
}
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
range r {};
|
||||
|
||||
for (auto i : r)
|
||||
{
|
||||
[[maybe_unused]] auto v = i;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambda_capture_asterisk_this_by_value
|
||||
{
|
||||
|
||||
struct t
|
||||
{
|
||||
int i;
|
||||
int foo()
|
||||
{
|
||||
return [*this]()
|
||||
{
|
||||
return i;
|
||||
}();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_enum_class_construction
|
||||
{
|
||||
|
||||
enum class byte : unsigned char
|
||||
{};
|
||||
|
||||
byte foo {42};
|
||||
|
||||
}
|
||||
|
||||
namespace test_constexpr_if
|
||||
{
|
||||
|
||||
template <bool cond>
|
||||
int f ()
|
||||
{
|
||||
if constexpr(cond)
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_selection_statement_with_initializer
|
||||
{
|
||||
|
||||
int f()
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
|
||||
int f2()
|
||||
{
|
||||
if (auto i = f(); i > 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
switch (auto i = f(); i + 4)
|
||||
{
|
||||
case 17:
|
||||
return 2;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_template_argument_deduction_for_class_templates
|
||||
{
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
pair (T1 p1, T2 p2)
|
||||
: m1 {p1},
|
||||
m2 {p2}
|
||||
{}
|
||||
|
||||
T1 m1;
|
||||
T2 m2;
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
[[maybe_unused]] auto p = pair{13, 42u};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_non_type_auto_template_parameters
|
||||
{
|
||||
|
||||
template <auto n>
|
||||
struct B
|
||||
{};
|
||||
|
||||
B<5> b1;
|
||||
B<'a'> b2;
|
||||
|
||||
}
|
||||
|
||||
namespace test_structured_bindings
|
||||
{
|
||||
|
||||
int arr[2] = { 1, 2 };
|
||||
std::pair<int, int> pr = { 1, 2 };
|
||||
|
||||
auto f1() -> int(&)[2]
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
auto f2() -> std::pair<int, int>&
|
||||
{
|
||||
return pr;
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int x1 : 2;
|
||||
volatile double y1;
|
||||
};
|
||||
|
||||
S f3()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto [ x1, y1 ] = f1();
|
||||
auto& [ xr1, yr1 ] = f1();
|
||||
auto [ x2, y2 ] = f2();
|
||||
auto& [ xr2, yr2 ] = f2();
|
||||
const auto [ x3, y3 ] = f3();
|
||||
|
||||
}
|
||||
|
||||
namespace test_exception_spec_type_system
|
||||
{
|
||||
|
||||
struct Good {};
|
||||
struct Bad {};
|
||||
|
||||
void g1() noexcept;
|
||||
void g2();
|
||||
|
||||
template<typename T>
|
||||
Bad
|
||||
f(T*, T*);
|
||||
|
||||
template<typename T1, typename T2>
|
||||
Good
|
||||
f(T1*, T2*);
|
||||
|
||||
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
|
||||
|
||||
}
|
||||
|
||||
namespace test_inline_variables
|
||||
{
|
||||
|
||||
template<class T> void f(T)
|
||||
{}
|
||||
|
||||
template<class T> inline T g(T)
|
||||
{
|
||||
return T{};
|
||||
}
|
||||
|
||||
template<> inline void f<>(int)
|
||||
{}
|
||||
|
||||
template<> int g<>(int)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx17
|
||||
|
||||
#endif // __cplusplus < 201703L
|
||||
|
||||
]])
|
||||
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
Name: OpenDHT (C Wrapper)
|
||||
Description: Distributed Hash Table library (C Wrapper)
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lopendht-c
|
||||
Requires.private: opendht gnutls >= 3.1 @argon2_lib@
|
||||
Cflags: -I${includedir}
|
||||
+15
-4
@@ -1,5 +1,5 @@
|
||||
# distutils: language = c++
|
||||
# distutils: extra_compile_args = -std=c++11
|
||||
# distutils: extra_compile_args = -std=c++14
|
||||
# distutils: include_dirs = ../../include
|
||||
# distutils: library_dirs = ../../src
|
||||
# distutils: libraries = opendht gnutls
|
||||
@@ -65,6 +65,14 @@ cdef inline bool get_callback(shared_ptr[cpp.Value] value, void *user_data) with
|
||||
pv._value = value
|
||||
return cb(pv) if not f or f(pv) else True
|
||||
|
||||
cdef inline bool value_callback(shared_ptr[cpp.Value] value, bool expired, void *user_data) with gil:
|
||||
cbs = <object>user_data
|
||||
cb = cbs['valcb']
|
||||
f = cbs['filter'] if 'filter' in cbs else None
|
||||
pv = Value()
|
||||
pv._value = value
|
||||
return cb(pv, expired) if not f or f(pv) else True
|
||||
|
||||
cdef inline void done_callback(bool done, cpp.vector[shared_ptr[cpp.Node]]* nodes, void *user_data) with gil:
|
||||
node_ids = []
|
||||
for n in deref(nodes):
|
||||
@@ -450,6 +458,9 @@ cdef class DhtConfig(object):
|
||||
self._config.dht_config.node_config.network = netid
|
||||
def setMaintainStorage(self, bool maintain_storage):
|
||||
self._config.dht_config.node_config.maintain_storage = maintain_storage
|
||||
def setRateLimit(self, ssize_t max_req_per_sec, ssize_t max_peer_req_per_sec):
|
||||
self._config.dht_config.node_config.max_req_per_sec = max_req_per_sec
|
||||
self._config.dht_config.node_config.max_peer_req_per_sec = max_peer_req_per_sec
|
||||
|
||||
cdef class DhtRunner(_WithID):
|
||||
cdef cpp.shared_ptr[cpp.DhtRunner] thisptr
|
||||
@@ -591,14 +602,14 @@ cdef class DhtRunner(_WithID):
|
||||
while pending > 0:
|
||||
lock.wait()
|
||||
return ok
|
||||
def listen(self, InfoHash key, get_cb):
|
||||
def listen(self, InfoHash key, value_cb):
|
||||
t = ListenToken()
|
||||
t._h = key._infohash
|
||||
cb_obj = {'get':get_cb}
|
||||
cb_obj = {'valcb':value_cb}
|
||||
t._cb['cb'] = cb_obj
|
||||
# avoid the callback being destructed if the token is destroyed
|
||||
ref.Py_INCREF(cb_obj)
|
||||
t._t = self.thisptr.get().listen(t._h, cpp.bindGetCb(get_callback, <void*>cb_obj)).share()
|
||||
t._t = self.thisptr.get().listen(t._h, cpp.bindValueCb(value_callback, <void*>cb_obj)).share()
|
||||
return t
|
||||
def cancelListen(self, ListenToken token):
|
||||
self.thisptr.get().cancelListen(token._h, token._t)
|
||||
|
||||
@@ -185,6 +185,7 @@ cdef extern from "opendht/node.h" namespace "dht":
|
||||
cdef extern from "opendht/callbacks.h" namespace "dht":
|
||||
ctypedef void (*ShutdownCallbackRaw)(void *user_data)
|
||||
ctypedef bool (*GetCallbackRaw)(shared_ptr[Value] values, void *user_data)
|
||||
ctypedef bool (*ValueCallbackRaw)(shared_ptr[Value] values, bool expired, void *user_data)
|
||||
ctypedef void (*DoneCallbackRaw)(bool done, vector[shared_ptr[Node]]* nodes, void *user_data)
|
||||
ctypedef void (*DoneCallbackSimpleRaw)(bool done, void *user_data)
|
||||
|
||||
@@ -192,6 +193,8 @@ cdef extern from "opendht/callbacks.h" namespace "dht":
|
||||
ShutdownCallback() except +
|
||||
cppclass GetCallback:
|
||||
GetCallback() except +
|
||||
cppclass ValueCallback:
|
||||
ValueCallback() except +
|
||||
cppclass DoneCallback:
|
||||
DoneCallback() except +
|
||||
cppclass DoneCallbackSimple:
|
||||
@@ -199,6 +202,7 @@ cdef extern from "opendht/callbacks.h" namespace "dht":
|
||||
|
||||
cdef ShutdownCallback bindShutdownCb(ShutdownCallbackRaw cb, void *user_data)
|
||||
cdef GetCallback bindGetCb(GetCallbackRaw cb, void *user_data)
|
||||
cdef ValueCallback bindValueCb(ValueCallbackRaw cb, void *user_data)
|
||||
cdef DoneCallback bindDoneCb(DoneCallbackRaw cb, void *user_data)
|
||||
cdef DoneCallbackSimple bindDoneCbSimple(DoneCallbackSimpleRaw cb, void *user_data)
|
||||
|
||||
@@ -207,6 +211,9 @@ cdef extern from "opendht/callbacks.h" namespace "dht":
|
||||
uint32_t network
|
||||
bool is_bootstrap
|
||||
bool maintain_storage
|
||||
string persist_path
|
||||
size_t max_req_per_sec
|
||||
size_t max_peer_req_per_sec
|
||||
cppclass SecureDhtConfig:
|
||||
Config node_config
|
||||
Identity id
|
||||
@@ -234,7 +241,7 @@ cdef extern from "opendht/dhtrunner.h" namespace "dht":
|
||||
string getSearchesLog(sa_family_t af) const
|
||||
void get(InfoHash key, GetCallback get_cb, DoneCallback done_cb, nullptr_t f, Where w)
|
||||
void put(InfoHash key, shared_ptr[Value] val, DoneCallback done_cb)
|
||||
ListenToken listen(InfoHash key, GetCallback get_cb)
|
||||
ListenToken listen(InfoHash key, ValueCallback get_cb)
|
||||
void cancelListen(InfoHash key, SharedListenToken token)
|
||||
vector[unsigned] getNodeMessageStats(bool i)
|
||||
|
||||
|
||||
+2
-2
@@ -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++11"],
|
||||
extra_link_args=["-std=c++11"],
|
||||
extra_compile_args=["-std=c++14"],
|
||||
extra_link_args=["-std=c++14"],
|
||||
libraries=["opendht"],
|
||||
library_dirs = ['@CURRENT_BINARY_DIR@', '@PROJECT_BINARY_DIR@']
|
||||
))
|
||||
|
||||
@@ -43,7 +43,7 @@ loop = asyncio.get_event_loop()
|
||||
pending_tests = {}
|
||||
keys = [dht.InfoHash.getRandom() for _ in range(args.num_ops)]
|
||||
|
||||
def listen_cb(key, val):
|
||||
def listen_cb(key, val, expired):
|
||||
global pending_tests
|
||||
kstr = str(key)
|
||||
if kstr in pending_tests:
|
||||
@@ -54,7 +54,7 @@ def listen_cb(key, val):
|
||||
return True
|
||||
|
||||
def listen(key):
|
||||
node1.listen(key, lambda v: loop.call_soon_threadsafe(listen_cb, key, v))
|
||||
node1.listen(key, lambda v, e: loop.call_soon_threadsafe(listen_cb, key, v, e))
|
||||
|
||||
for key in keys:
|
||||
listen(key)
|
||||
|
||||
@@ -19,13 +19,16 @@ import opendht as dht
|
||||
import time
|
||||
import asyncio
|
||||
|
||||
config = dht.DhtConfig()
|
||||
config.setRateLimit(-1, -1)
|
||||
|
||||
ping_node = dht.DhtRunner()
|
||||
ping_node.run()
|
||||
ping_node.run(config=config)
|
||||
#ping_node.enableLogging()
|
||||
#ping_node.bootstrap("bootstrap.ring.cx", "4222")
|
||||
|
||||
pong_node = dht.DhtRunner()
|
||||
pong_node.run()
|
||||
pong_node.run(config=config)
|
||||
#pong_node.enableLogging()
|
||||
pong_node.ping(ping_node.getBound())
|
||||
|
||||
@@ -42,7 +45,6 @@ def done(h, ok):
|
||||
|
||||
def ping(node, h):
|
||||
global i
|
||||
time.sleep(0.0075)
|
||||
i += 1
|
||||
if i < MAX:
|
||||
node.put(h, dht.Value(b"hey"), lambda ok, nodes: done(node.getNodeId().decode(), ok))
|
||||
@@ -54,8 +56,8 @@ def pong(node, h):
|
||||
loop.call_soon_threadsafe(ping, node, h)
|
||||
return True
|
||||
|
||||
ping_node.listen(loc_ping, lambda v: pong(pong_node, loc_pong))
|
||||
pong_node.listen(loc_pong, lambda v: pong(ping_node, loc_ping))
|
||||
ping_node.listen(loc_ping, lambda v, e: pong(pong_node, loc_pong) if not e else True)
|
||||
pong_node.listen(loc_pong, lambda v, e: pong(ping_node, loc_ping) if not e else True)
|
||||
|
||||
ping(pong_node, loc_ping)
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
*.lock
|
||||
target
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "opendht"
|
||||
version = "0.1.0"
|
||||
authors = ["Sébastien Blin <sebastien.blin@savoirfairelinux.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
libc="0.2.0"
|
||||
os_socketaddr="0.1.0"
|
||||
@@ -0,0 +1,21 @@
|
||||
# Rust bindings for opendht
|
||||
|
||||
## Build
|
||||
|
||||
Install rust on your system (https://rustup.rs/ is the recommanded way). Once done:
|
||||
|
||||
```
|
||||
cargo build
|
||||
```
|
||||
|
||||
## Run tests
|
||||
|
||||
```
|
||||
cargo test
|
||||
```
|
||||
|
||||
## Run dht node
|
||||
|
||||
```
|
||||
cargo run --example dhtnode
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
extern crate opendht;
|
||||
use std::{ thread, time };
|
||||
|
||||
use opendht::{ InfoHash, DhtRunner, DhtRunnerConfig, Value };
|
||||
// use opendht::crypto::*;
|
||||
|
||||
fn main() {
|
||||
println!("{}", InfoHash::random());
|
||||
println!("{}", InfoHash::new());
|
||||
println!("{}", InfoHash::new().is_zero());
|
||||
println!("{}", InfoHash::get("alice"));
|
||||
println!("{}", InfoHash::get("alice").is_zero());
|
||||
|
||||
|
||||
let mut dht = DhtRunner::new();
|
||||
let /*mut*/ config = DhtRunnerConfig::new();
|
||||
//// If you want to inject a certificate, uncomment the following lines and previous mut.
|
||||
//// Note: you can generate a certificate with
|
||||
//// openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout example.key -out example.crt -subj /CN=example.com
|
||||
//let cert = DhtCertificate::import("example.crt").ok().expect("Invalid cert file");
|
||||
//let pk = PrivateKey::import("example.key", "");
|
||||
//config.set_identity(cert, pk);
|
||||
dht.run_config(1412, config);
|
||||
dht.bootstrap("bootstrap.jami.net", 4222);
|
||||
println!("Current node id: {}", dht.node_id());
|
||||
|
||||
let /* mut */ data = 42;
|
||||
let mut get_cb = |v: Box<Value>| {
|
||||
//data += 1;
|
||||
println!("GET: VALUE CB - data: {} - v: {}", data, v);
|
||||
true
|
||||
};
|
||||
let mut done_cb = |ok: bool| {
|
||||
println!("GET: DONE CB - data: {} - ok: {}", data, ok);
|
||||
};
|
||||
|
||||
dht.get(&InfoHash::get("alice"), &mut get_cb, &mut done_cb);
|
||||
|
||||
let mut put_done_cb = |ok: bool| {
|
||||
println!("PUT: DONE CB - data: {} - ok: {}", data, ok);
|
||||
};
|
||||
dht.put(&InfoHash::get("bob"), Value::new("hi!"), &mut put_done_cb, false);
|
||||
|
||||
|
||||
println!("Start listening /foo");
|
||||
let mut value_cb = |v, expired| {
|
||||
println!("LISTEN: DONE CB - data: {} - v: {} - expired: {}", data, v, expired);
|
||||
true
|
||||
};
|
||||
let token = dht.listen(&InfoHash::get("foo"), &mut value_cb);
|
||||
let one_min = time::Duration::from_secs(10);
|
||||
thread::sleep(one_min);
|
||||
dht.cancel_listen(&InfoHash::get("foo"), token);
|
||||
println!("Public ips: {:#?}", dht.public_addresses());
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
use crate::ffi::*;
|
||||
|
||||
pub use crate::ffi::Blob;
|
||||
|
||||
impl Blob {
|
||||
pub fn data(&self) -> DataView {
|
||||
unsafe {
|
||||
dht_blob_get_data(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Blob {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_blob_delete(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub use crate::ffi::*;
|
||||
use std::ffi::CString;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::fs::File;
|
||||
use std::ptr;
|
||||
|
||||
impl PublicKey {
|
||||
pub fn new(data: &str) -> Box<PublicKey> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_publickey_import(data.as_ptr(), data.len()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unpack(&mut self, data: Vec<u8>) -> i32 {
|
||||
unsafe {
|
||||
dht_publickey_unpack(&mut *self, data.as_ptr(), data.len())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pack(&mut self, data: &str) -> i32 {
|
||||
let data = CString::new(data).unwrap();
|
||||
unsafe {
|
||||
dht_publickey_pack(&mut *self,
|
||||
data.as_ptr(),
|
||||
data.as_bytes().len())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> InfoHash {
|
||||
unsafe {
|
||||
dht_publickey_get_id(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn long_id(&self) -> PkId {
|
||||
unsafe {
|
||||
dht_publickey_get_long_id(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_signature(&self, data: &str, signature: &str) -> bool {
|
||||
let data = CString::new(data).unwrap();
|
||||
let signature = CString::new(signature).unwrap();
|
||||
unsafe {
|
||||
dht_publickey_check_signature(self,
|
||||
data.as_ptr(), data.as_bytes().len(),
|
||||
signature.as_ptr(), signature.as_bytes().len())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encrypt(&self, data: &str) -> Box<Blob> {
|
||||
let data = CString::new(data).unwrap();
|
||||
unsafe {
|
||||
Box::from_raw(dht_publickey_encrypt(self,
|
||||
data.as_ptr(), data.as_bytes().len()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PublicKey {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_publickey_delete(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrivateKey {
|
||||
pub fn new(key_length_bits: u32) -> Box<PrivateKey> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_privatekey_generate(key_length_bits))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn import(file: &str, password: &str) -> io::Result<Box<PrivateKey>> {
|
||||
let mut f = File::open(file)?;
|
||||
let mut buffer = Vec::new();
|
||||
f.read_to_end(&mut buffer)?;
|
||||
Ok(PrivateKey::from_bytes(&buffer, password))
|
||||
}
|
||||
|
||||
pub fn from_bytes(buffer: &Vec<u8>, password: &str) -> Box<PrivateKey> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_privatekey_import((&*buffer).as_ptr(), buffer.len(),
|
||||
password.as_ptr() as *const i8))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> Box<PublicKey> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_privatekey_get_publickey(self))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Drop for PrivateKey {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_privatekey_delete(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DhtCertificate {
|
||||
pub fn import(file: &str) -> io::Result<Box<DhtCertificate>> {
|
||||
let mut f = File::open(file)?;
|
||||
let mut buffer = Vec::new();
|
||||
f.read_to_end(&mut buffer)?;
|
||||
Ok(DhtCertificate::from_bytes(&buffer))
|
||||
}
|
||||
|
||||
pub fn from_bytes(buffer: &Vec<u8>) -> Box<DhtCertificate> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_certificate_import((&*buffer).as_ptr(), buffer.len()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_slice(buffer: &str) -> Box<DhtCertificate> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_certificate_import((&*buffer).as_ptr(), buffer.len()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> InfoHash {
|
||||
unsafe {
|
||||
dht_certificate_get_id(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn long_id(&self) -> PkId {
|
||||
unsafe {
|
||||
dht_certificate_get_long_id(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn publickey(&self) -> Box<PublicKey> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_certificate_get_publickey(&*self))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DhtCertificate {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_certificate_delete(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DhtIdentity {
|
||||
pub fn new(common_name: &str) -> DhtIdentity {
|
||||
unsafe {
|
||||
DhtIdentity::generate(common_name, Box::from_raw(ptr::null_mut()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate(common_name: &str, ca: Box<DhtIdentity>) -> DhtIdentity {
|
||||
let common_name = CString::new(common_name).unwrap();
|
||||
unsafe {
|
||||
dht_identity_generate(common_name.as_ptr(), &*ca)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DhtIdentity {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_identity_delete(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use libc::c_void;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
pub use crate::ffi::*;
|
||||
use std::net::SocketAddr;
|
||||
use os_socketaddr::OsSocketAddr;
|
||||
|
||||
impl DhtRunnerConfig {
|
||||
|
||||
pub fn new() -> Box<DhtRunnerConfig> {
|
||||
let mut config: Box<DhtRunnerConfig> = Box::new(DhtRunnerConfig {
|
||||
dht_config: DhtSecureConfig {
|
||||
node_config: DhtNodeConfig {
|
||||
node_id: InfoHash::new(),
|
||||
network: 0,
|
||||
is_bootstrap: false,
|
||||
maintain_storage: false,
|
||||
persist_path: ptr::null(),
|
||||
},
|
||||
id: DhtIdentity {
|
||||
privatekey: ptr::null_mut(),
|
||||
certificate: ptr::null_mut(),
|
||||
},
|
||||
},
|
||||
threaded: false,
|
||||
proxy_server: ptr::null(),
|
||||
push_node_id: ptr::null(),
|
||||
push_token: ptr::null(),
|
||||
peer_discovery: false,
|
||||
peer_publish: false,
|
||||
server_ca: ptr::null_mut(),
|
||||
client_identity: DhtIdentity {
|
||||
privatekey: ptr::null_mut(),
|
||||
certificate: ptr::null_mut(),
|
||||
},
|
||||
});
|
||||
unsafe {
|
||||
dht_runner_config_default(&mut *config);
|
||||
}
|
||||
config
|
||||
}
|
||||
|
||||
pub fn set_proxy_server(&mut self, proxy_server: &str) {
|
||||
self.proxy_server = CString::new(proxy_server).unwrap().as_ptr();
|
||||
}
|
||||
|
||||
pub fn set_push_node_id(&mut self, push_node_id: &str) {
|
||||
self.push_node_id = CString::new(push_node_id).unwrap().as_ptr();
|
||||
}
|
||||
|
||||
pub fn set_push_token(&mut self, push_token: &str) {
|
||||
self.push_token = CString::new(push_token).unwrap().as_ptr();
|
||||
}
|
||||
|
||||
pub fn set_identity(&mut self, certificate: Box<DhtCertificate>, privatekey: Box<PrivateKey>) {
|
||||
self.dht_config.id.privatekey = Box::into_raw(privatekey);
|
||||
self.dht_config.id.certificate = Box::into_raw(certificate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl DhtNodeConfig
|
||||
{
|
||||
pub fn set_persist_path(&mut self, persist_path: &str) {
|
||||
self.persist_path = CString::new(persist_path).unwrap().as_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
struct GetHandler<'a>
|
||||
{
|
||||
get_cb: &'a mut(dyn FnMut(Box<Value>) -> bool),
|
||||
done_cb: &'a mut(dyn FnMut(bool))
|
||||
}
|
||||
|
||||
impl<'a> GetHandler<'a>
|
||||
{
|
||||
fn get_cb(&mut self, v: Box<Value>) -> bool{
|
||||
(self.get_cb)(v)
|
||||
}
|
||||
|
||||
fn done_cb(&mut self, ok: bool) {
|
||||
(self.done_cb)(ok)
|
||||
}
|
||||
}
|
||||
|
||||
extern fn get_handler_cb(v: *mut Value, ptr: *mut c_void) -> bool {
|
||||
if ptr.is_null() {
|
||||
return true;
|
||||
}
|
||||
unsafe {
|
||||
let handler = ptr as *mut GetHandler;
|
||||
(*handler).get_cb((*v).boxed())
|
||||
}
|
||||
}
|
||||
|
||||
extern fn done_handler_cb(ok: bool, ptr: *mut c_void) {
|
||||
unsafe {
|
||||
let handler = Box::from_raw(ptr as *mut GetHandler);
|
||||
(*handler.done_cb)(ok)
|
||||
}
|
||||
}
|
||||
|
||||
struct PutHandler<'a>
|
||||
{
|
||||
done_cb: &'a mut(dyn FnMut(bool))
|
||||
}
|
||||
|
||||
impl<'a> PutHandler<'a>
|
||||
{
|
||||
fn done_cb(&mut self, ok: bool) {
|
||||
(self.done_cb)(ok)
|
||||
}
|
||||
}
|
||||
|
||||
extern fn put_handler_done(ok: bool, ptr: *mut c_void) {
|
||||
unsafe {
|
||||
let handler = Box::from_raw(ptr as *mut PutHandler);
|
||||
(*handler.done_cb)(ok)
|
||||
}
|
||||
}
|
||||
|
||||
struct ListenHandler<'a>
|
||||
{
|
||||
cb: &'a mut(dyn FnMut(Box<Value>, bool) -> bool)
|
||||
}
|
||||
|
||||
impl<'a> ListenHandler<'a>
|
||||
{
|
||||
fn cb(&mut self, v: Box<Value>, expired: bool) -> bool {
|
||||
(self.cb)(v, expired)
|
||||
}
|
||||
}
|
||||
|
||||
extern fn listen_handler(v: *mut Value, expired: bool, ptr: *mut c_void) -> bool {
|
||||
unsafe {
|
||||
let handler = ptr as *mut ListenHandler;
|
||||
(*handler).cb((*v).boxed(), expired)
|
||||
}
|
||||
}
|
||||
|
||||
extern fn listen_handler_done(ptr: *mut c_void) {
|
||||
unsafe {
|
||||
Box::from_raw(ptr as *mut ListenHandler);
|
||||
}
|
||||
}
|
||||
|
||||
impl DhtRunner {
|
||||
pub fn new() -> Box<DhtRunner> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_runner_new())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&mut self, port: u16) {
|
||||
unsafe {
|
||||
dht_runner_run(&mut *self, port)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_config(&mut self, port: u16, config: Box<DhtRunnerConfig>) {
|
||||
unsafe {
|
||||
dht_runner_run_config(&mut *self, port, &*config)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bootstrap(&mut self, host: &str, service: u16) {
|
||||
unsafe {
|
||||
dht_runner_bootstrap(&mut *self,
|
||||
CString::new(host).unwrap().as_ptr(),
|
||||
CString::new(service.to_string()).unwrap().as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node_id(&self) -> InfoHash {
|
||||
unsafe {
|
||||
dht_runner_get_node_id(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> InfoHash {
|
||||
unsafe {
|
||||
dht_runner_get_id(&*self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<'a>(&mut self, h: &InfoHash,
|
||||
get_cb: &'a mut(dyn FnMut(Box<Value>) -> bool),
|
||||
done_cb: &'a mut(dyn FnMut(bool))) {
|
||||
let handler = Box::new(GetHandler {
|
||||
get_cb,
|
||||
done_cb,
|
||||
});
|
||||
let handler = Box::into_raw(handler) as *mut c_void;
|
||||
unsafe {
|
||||
dht_runner_get(&mut *self, h, get_handler_cb, done_handler_cb, handler)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put<'a>(&mut self, h: &InfoHash, v: Box<Value>,
|
||||
done_cb: &'a mut(dyn FnMut(bool)), permanent: bool) {
|
||||
let handler = Box::new(PutHandler {
|
||||
done_cb,
|
||||
});
|
||||
let handler = Box::into_raw(handler) as *mut c_void;
|
||||
unsafe {
|
||||
dht_runner_put(&mut *self, h, &*v, put_handler_done, handler, permanent)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put_signed<'a>(&mut self, h: &InfoHash, v: Box<Value>,
|
||||
done_cb: &'a mut(dyn FnMut(bool)), permanent: bool) {
|
||||
let handler = Box::new(PutHandler {
|
||||
done_cb,
|
||||
});
|
||||
let handler = Box::into_raw(handler) as *mut c_void;
|
||||
unsafe {
|
||||
dht_runner_put_signed(&mut *self, h, &*v, put_handler_done, handler, permanent)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put_encrypted<'a>(&mut self, h: &InfoHash, to: &InfoHash, v: Box<Value>,
|
||||
done_cb: &'a mut(dyn FnMut(bool)), permanent: bool) {
|
||||
let handler = Box::new(PutHandler {
|
||||
done_cb,
|
||||
});
|
||||
let handler = Box::into_raw(handler) as *mut c_void;
|
||||
unsafe {
|
||||
dht_runner_put_encrypted(&mut *self, h, to, &*v, put_handler_done, handler, permanent)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cancel_put<'a>(&mut self, h: &InfoHash, vid: u64) {
|
||||
unsafe {
|
||||
dht_runner_cancel_put(&mut *self, h, vid)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn listen<'a>(&mut self, h: &InfoHash,
|
||||
cb: &'a mut(dyn FnMut(Box<Value>, bool) -> bool)) -> Box<OpToken> {
|
||||
let handler = Box::new(ListenHandler {
|
||||
cb,
|
||||
});
|
||||
let handler = Box::into_raw(handler) as *mut c_void;
|
||||
unsafe {
|
||||
Box::from_raw(dht_runner_listen(&mut *self, h, listen_handler, listen_handler_done, handler))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cancel_listen(&mut self, h: &InfoHash, token: Box<OpToken>) {
|
||||
unsafe {
|
||||
dht_runner_cancel_listen(&mut *self, h, &*token)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown(&mut self,
|
||||
done_cb: extern fn(bool, *mut c_void),
|
||||
cb_user_data: *mut c_void)
|
||||
{
|
||||
unsafe {
|
||||
dht_runner_shutdown(&mut *self, done_cb, cb_user_data)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn public_addresses(&self) -> Vec<SocketAddr> {
|
||||
let mut result = Vec::new();
|
||||
unsafe {
|
||||
let mut addresses = dht_runner_get_public_address(&*self);
|
||||
while !addresses.is_null() && !(*addresses).is_null() {
|
||||
let sock = (*(*addresses)).into_addr();
|
||||
if sock.is_some() {
|
||||
result.push(sock.unwrap());
|
||||
}
|
||||
addresses = (addresses as usize + std::mem::size_of::<*mut OsSocketAddr>()) as *mut *mut OsSocketAddr;
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DhtRunner {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_runner_delete(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OpToken {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_op_token_delete(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use libc::{c_char, c_int, c_uint, c_void, in_port_t, size_t};
|
||||
use os_socketaddr::OsSocketAddr;
|
||||
|
||||
const HASH_LEN: usize = 20;
|
||||
const PKID_LEN: usize = 32;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DataView
|
||||
{
|
||||
pub data: *const u8,
|
||||
pub size: size_t
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Value
|
||||
{
|
||||
_opaque: [u8; 0]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Blob
|
||||
{
|
||||
_opaque: [u8; 0]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(PartialEq)]
|
||||
pub struct InfoHash
|
||||
{
|
||||
pub d: [u8; HASH_LEN],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PkId
|
||||
{
|
||||
pub d: [u8; PKID_LEN],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PublicKey
|
||||
{
|
||||
_opaque: [u8; 0]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PrivateKey
|
||||
{
|
||||
_opaque: [u8; 0]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct OpToken
|
||||
{
|
||||
_opaque: [u8; 0]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DhtRunner
|
||||
{
|
||||
_opaque: [u8; 0]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DhtNodeConfig
|
||||
{
|
||||
pub node_id: InfoHash,
|
||||
pub network: u32,
|
||||
pub is_bootstrap: bool,
|
||||
pub maintain_storage: bool,
|
||||
pub persist_path: *const c_char,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DhtCertificate
|
||||
{
|
||||
_opaque: [u8; 0]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DhtIdentity
|
||||
{
|
||||
pub privatekey: *mut PrivateKey,
|
||||
pub certificate: *mut DhtCertificate,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DhtSecureConfig
|
||||
{
|
||||
pub node_config: DhtNodeConfig,
|
||||
pub id: DhtIdentity,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DhtRunnerConfig
|
||||
{
|
||||
pub dht_config: DhtSecureConfig,
|
||||
pub threaded: bool,
|
||||
pub proxy_server: *const c_char,
|
||||
pub push_node_id: *const c_char,
|
||||
pub push_token: *const c_char,
|
||||
pub peer_discovery: bool,
|
||||
pub peer_publish: bool,
|
||||
pub server_ca: *mut DhtCertificate,
|
||||
pub client_identity: DhtIdentity,
|
||||
}
|
||||
|
||||
|
||||
#[link(name = "opendht-c")]
|
||||
extern {
|
||||
// dht::Value
|
||||
pub fn dht_value_new(data: *const u8, size: size_t) -> *mut Value;
|
||||
pub fn dht_value_ref(data: *const Value) -> *mut Value;
|
||||
pub fn dht_value_unref(data: *mut Value);
|
||||
pub fn dht_value_get_data(data: *const Value) -> DataView;
|
||||
pub fn dht_value_get_id(data: *const Value) -> u64;
|
||||
pub fn dht_value_get_owner(data: *const Value) -> *mut PublicKey;
|
||||
pub fn dht_value_get_recipient(data: *const Value) -> InfoHash;
|
||||
pub fn dht_value_get_user_type(data: *const Value) -> *const c_char;
|
||||
|
||||
// dht::Blob
|
||||
pub fn dht_blob_get_data(data: *const Blob) -> DataView;
|
||||
pub fn dht_blob_delete(data: *mut Blob);
|
||||
|
||||
// dht::InfoHash
|
||||
pub fn dht_infohash_print(h: *const InfoHash) -> *const c_char;
|
||||
pub fn dht_infohash_random(h: *mut InfoHash);
|
||||
pub fn dht_infohash_get(h: *mut InfoHash, dat: *mut u8, dat_size: size_t);
|
||||
pub fn dht_infohash_from_hex(h: *mut InfoHash, dat: *const c_char);
|
||||
pub fn dht_infohash_is_zero(j: *const InfoHash) -> bool;
|
||||
|
||||
// dht::PkId
|
||||
pub fn dht_pkid_print(h: *const PkId) -> *const c_char;
|
||||
|
||||
// dht::crypto::PublicKey
|
||||
pub fn dht_publickey_import(dat: *const u8, dat_size: size_t) -> *mut PublicKey;
|
||||
pub fn dht_publickey_delete(pk: *mut PublicKey);
|
||||
pub fn dht_publickey_unpack(pk: *mut PublicKey, dat: *const u8, dat_size: size_t) -> c_int;
|
||||
pub fn dht_publickey_pack(pk: *mut PublicKey, out: *const c_char, out_size: size_t) -> c_int;
|
||||
pub fn dht_publickey_get_id(pk: *const PublicKey) -> InfoHash;
|
||||
pub fn dht_publickey_get_long_id(pk: *const PublicKey) -> PkId;
|
||||
pub fn dht_publickey_check_signature(pk: *const PublicKey, data: *const c_char, data_size: size_t, signature: *const c_char, signature_size: size_t) -> bool;
|
||||
pub fn dht_publickey_encrypt(pk: *const PublicKey, data: *const c_char, data_size: size_t) -> *mut Blob;
|
||||
|
||||
// dht::crypto::PrivateKey
|
||||
pub fn dht_privatekey_generate(key_length_bits: c_uint) -> *mut PrivateKey;
|
||||
pub fn dht_privatekey_import(dat: *const u8, data_size: size_t, password: *const c_char) -> *mut PrivateKey;
|
||||
pub fn dht_privatekey_get_publickey(pk: *const PrivateKey) -> *mut PublicKey;
|
||||
pub fn dht_privatekey_delete(pk: *mut PrivateKey);
|
||||
|
||||
// dht::crypto::Certificate
|
||||
pub fn dht_certificate_import(dat: *const u8, dat_size: size_t) -> *mut DhtCertificate;
|
||||
pub fn dht_certificate_get_id(cert: *const DhtCertificate) -> InfoHash;
|
||||
pub fn dht_certificate_get_long_id(cert: *const DhtCertificate) -> PkId;
|
||||
pub fn dht_certificate_get_publickey(cert: *const DhtCertificate) -> *mut PublicKey;
|
||||
pub fn dht_certificate_delete(cert: *mut DhtCertificate);
|
||||
|
||||
pub fn dht_identity_generate(common_name: *const c_char, ca: *const DhtIdentity) -> DhtIdentity;
|
||||
pub fn dht_identity_delete(ca: *mut DhtIdentity);
|
||||
|
||||
// dht::OpToken
|
||||
pub fn dht_op_token_delete(token: *mut OpToken);
|
||||
|
||||
// dht::DhtRunner
|
||||
pub fn dht_runner_config_default(config: *mut DhtRunnerConfig);
|
||||
pub fn dht_runner_new() -> *mut DhtRunner;
|
||||
pub fn dht_runner_get_id(dht: *const DhtRunner) -> InfoHash;
|
||||
pub fn dht_runner_get_node_id(dht: *const DhtRunner) -> InfoHash;
|
||||
pub fn dht_runner_delete(dht: *mut DhtRunner);
|
||||
pub fn dht_runner_run(dht: *mut DhtRunner, port: in_port_t);
|
||||
pub fn dht_runner_run_config(dht: *mut DhtRunner, port: in_port_t, config: *const DhtRunnerConfig);
|
||||
pub fn dht_runner_bootstrap(dht: *mut DhtRunner, host: *const c_char, service: *const c_char);
|
||||
pub fn dht_runner_get(dht: *mut DhtRunner, h: *const InfoHash,
|
||||
get_cb: extern fn(*mut Value, *mut c_void) -> bool,
|
||||
done_cb: extern fn(bool, *mut c_void),
|
||||
cb_user_data: *mut c_void);
|
||||
pub fn dht_runner_put(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value,
|
||||
done_cb: extern fn(bool, *mut c_void),
|
||||
cb_user_data: *mut c_void,
|
||||
permanent: bool);
|
||||
pub fn dht_runner_put_signed(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value,
|
||||
done_cb: extern fn(bool, *mut c_void),
|
||||
cb_user_data: *mut c_void,
|
||||
permanent: bool);
|
||||
pub fn dht_runner_put_encrypted(dht: *mut DhtRunner, h: *const InfoHash,
|
||||
to: *const InfoHash, v: *const Value,
|
||||
done_cb: extern fn(bool, *mut c_void),
|
||||
cb_user_data: *mut c_void,
|
||||
permanent: bool);
|
||||
pub fn dht_runner_put_permanent(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value,
|
||||
done_cb: extern fn(bool, *mut c_void),
|
||||
cb_user_data: *mut c_void);
|
||||
pub fn dht_runner_cancel_put(dht: *mut DhtRunner, h: *const InfoHash, vid: u64);
|
||||
pub fn dht_runner_listen(dht: *mut DhtRunner, h: *const InfoHash,
|
||||
cb: extern fn(*mut Value, bool, *mut c_void) -> bool,
|
||||
done_cb: extern fn(*mut c_void),
|
||||
cb_user_data: *mut c_void) -> *mut OpToken;
|
||||
pub fn dht_runner_cancel_listen(dht: *mut DhtRunner, h: *const InfoHash,
|
||||
token: *const OpToken);
|
||||
pub fn dht_runner_shutdown(dht: *mut DhtRunner, done_cb: extern fn(bool, *mut c_void),
|
||||
cb_user_data: *mut c_void);
|
||||
pub fn dht_runner_get_public_address(dht: *const DhtRunner) -> *mut *mut OsSocketAddr;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
use crate::ffi::*;
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
|
||||
pub use crate::ffi::InfoHash;
|
||||
|
||||
impl InfoHash {
|
||||
pub fn new() -> InfoHash {
|
||||
InfoHash {
|
||||
d: [0; 20]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random() -> InfoHash {
|
||||
let mut h = InfoHash::new();
|
||||
unsafe {
|
||||
dht_infohash_random(&mut h);
|
||||
}
|
||||
h
|
||||
}
|
||||
|
||||
pub fn get(data: &str) -> InfoHash {
|
||||
let mut h = InfoHash::new();
|
||||
unsafe {
|
||||
let c_str = CString::new(data).unwrap();
|
||||
dht_infohash_get(&mut h, c_str.as_ptr() as *mut u8, data.len());
|
||||
}
|
||||
h
|
||||
}
|
||||
|
||||
pub fn from_bytes(data: &Vec<u8>) -> InfoHash {
|
||||
let mut h = InfoHash::new();
|
||||
unsafe {
|
||||
dht_infohash_get(&mut h, data.as_ptr() as *mut u8, data.len());
|
||||
}
|
||||
h
|
||||
}
|
||||
|
||||
pub fn from_hex(data: &str) -> InfoHash {
|
||||
let mut h = InfoHash::new();
|
||||
unsafe {
|
||||
let c_str = CString::new(data).unwrap();
|
||||
dht_infohash_from_hex(&mut h, c_str.as_ptr());
|
||||
}
|
||||
h
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
unsafe {
|
||||
dht_infohash_is_zero(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for InfoHash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
unsafe {
|
||||
let self_str = CStr::from_ptr(
|
||||
dht_infohash_print(self)
|
||||
).to_str().unwrap_or("");
|
||||
write!(f, "{}", self_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
extern crate libc;
|
||||
extern crate os_socketaddr;
|
||||
|
||||
mod blob;
|
||||
pub mod crypto;
|
||||
mod dhtrunner;
|
||||
mod ffi;
|
||||
mod infohash;
|
||||
mod pkid;
|
||||
mod value;
|
||||
|
||||
pub use blob::Blob;
|
||||
pub use dhtrunner::{ DhtRunner, DhtRunnerConfig, OpToken };
|
||||
pub use infohash::InfoHash;
|
||||
pub use pkid::PkId;
|
||||
pub use value::{ DataView, Value };
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
|
||||
use crate::ffi::*;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt;
|
||||
|
||||
pub use crate::ffi::PkId;
|
||||
|
||||
impl fmt::Display for PkId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
unsafe {
|
||||
let self_str = CStr::from_ptr(
|
||||
dht_pkid_print(self)
|
||||
).to_str().unwrap_or("");
|
||||
write!(f, "{}", self_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Savoir-faire Linux Inc.
|
||||
* Author: Sébastien Blin <sebastien.blin@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/>.
|
||||
*/
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::ffi::*;
|
||||
use std::fmt;
|
||||
use std::ffi::{ CString, IntoStringError };
|
||||
use std::str;
|
||||
use std::slice;
|
||||
|
||||
pub use crate::ffi::{DataView, Value};
|
||||
|
||||
impl Value {
|
||||
pub fn new(data: &str) -> Box<Value> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_value_new(data.as_bytes().as_ptr(),
|
||||
data.as_bytes().len()))
|
||||
}
|
||||
}
|
||||
pub fn from_bytes(data: &Vec<u8>) -> Box<Value> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_value_new(data.as_ptr(),
|
||||
data.len()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> u64 {
|
||||
unsafe {
|
||||
dht_value_get_id(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn dataview(&self) -> DataView {
|
||||
unsafe {
|
||||
dht_value_get_data(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> Vec<u8> {
|
||||
unsafe {
|
||||
let dv = dht_value_get_data(self);
|
||||
let slice = slice::from_raw_parts_mut(dv.data as *mut _, dv.size);
|
||||
slice.to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn boxed(&mut self) -> Box<Value> {
|
||||
unsafe {
|
||||
Box::from_raw(dht_value_ref(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recipient(&self) -> InfoHash {
|
||||
unsafe {
|
||||
dht_value_get_recipient(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn owner(&self) -> Option<Box<PublicKey>> {
|
||||
unsafe {
|
||||
let ptr = dht_value_get_owner(self);
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
}
|
||||
Some(Box::from_raw(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn user_type(&self) -> Result<String, IntoStringError> {
|
||||
unsafe {
|
||||
CString::from_raw(dht_value_get_user_type(self) as *mut _).into_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Value {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dht_value_unref(&mut *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Value {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
unsafe {
|
||||
let dataview = self.dataview();
|
||||
let slice = slice::from_raw_parts(dataview.data, dataview.size);
|
||||
write!(f, "{}", str::from_utf8(slice).unwrap_or(""))
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-7
@@ -1,8 +1,8 @@
|
||||
lib_LTLIBRARIES = libopendht.la
|
||||
|
||||
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@
|
||||
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@
|
||||
libopendht_la_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@
|
||||
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_SOURCES = \
|
||||
dht.cpp \
|
||||
storage.h \
|
||||
@@ -26,7 +26,9 @@ libopendht_la_SOURCES = \
|
||||
securedht.cpp \
|
||||
dhtrunner.cpp \
|
||||
default_types.cpp \
|
||||
log.cpp
|
||||
log.cpp \
|
||||
network_utils.cpp \
|
||||
thread_pool.cpp
|
||||
|
||||
if WIN32
|
||||
libopendht_la_SOURCES += rng.cpp
|
||||
@@ -53,10 +55,12 @@ nobase_include_HEADERS = \
|
||||
../include/opendht/default_types.h \
|
||||
../include/opendht/log.h \
|
||||
../include/opendht/log_enable.h \
|
||||
../include/opendht/rng.h
|
||||
../include/opendht/network_utils.h \
|
||||
../include/opendht/rng.h \
|
||||
../include/opendht/thread_pool.h
|
||||
|
||||
if ENABLE_PROXY_SERVER
|
||||
libopendht_la_SOURCES += dht_proxy_server.cpp thread_pool.h thread_pool.cpp
|
||||
libopendht_la_SOURCES += dht_proxy_server.cpp
|
||||
nobase_include_HEADERS += ../include/opendht/dht_proxy_server.h
|
||||
endif
|
||||
|
||||
@@ -67,7 +71,13 @@ endif
|
||||
|
||||
libopendht_la_SOURCES += base64.h base64.cpp
|
||||
if PROXY_CLIENT_OR_SERVER
|
||||
nobase_include_HEADERS += ../include/opendht/proxy.h
|
||||
libopendht_la_SOURCES += http.cpp
|
||||
nobase_include_HEADERS += ../include/opendht/proxy.h ../include/opendht/http.h
|
||||
endif
|
||||
|
||||
if ENABLE_PEER_DISCOVERY
|
||||
libopendht_la_SOURCES += peer_discovery.cpp
|
||||
nobase_include_HEADERS += ../include/opendht/peer_discovery.h
|
||||
endif
|
||||
|
||||
if ENABLE_INDEXATION
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2019 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
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "callbacks.h"
|
||||
|
||||
namespace dht {
|
||||
@@ -24,6 +46,18 @@ bindGetCb(const GetCallbackSimple& cb)
|
||||
};
|
||||
}
|
||||
|
||||
ValueCallback
|
||||
bindValueCb(const ValueCallbackRaw& raw_cb, void* user_data)
|
||||
{
|
||||
if (not raw_cb) return {};
|
||||
return [=](const std::vector<std::shared_ptr<Value>>& values, bool expired) {
|
||||
for (const auto& v : values)
|
||||
if (not raw_cb(v, expired, user_data))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
ShutdownCallback
|
||||
bindShutdownCb(const ShutdownCallbackRaw& shutdown_cb_raw, void* user_data)
|
||||
{
|
||||
@@ -109,6 +143,7 @@ NodeInfo::toJson() const
|
||||
val["node_id"] = node_id.toString();
|
||||
val["ipv4"] = ipv4.toJson();
|
||||
val["ipv6"] = ipv6.toJson();
|
||||
val["ops"] = Json::Value::LargestUInt(ongoing_ops);
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -119,6 +154,7 @@ NodeInfo::NodeInfo(const Json::Value& v)
|
||||
node_id = InfoHash(v["node_id"].asString());
|
||||
ipv4 = NodeStats(v["ipv4"]);
|
||||
ipv6 = NodeStats(v["ipv6"]);
|
||||
ongoing_ops = v["ops"].asLargestUInt();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+76
-33
@@ -31,6 +31,7 @@ extern "C" {
|
||||
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
|
||||
@@ -51,6 +52,9 @@ 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_DECRYPT 1
|
||||
|
||||
namespace dht {
|
||||
namespace crypto {
|
||||
|
||||
@@ -91,12 +95,12 @@ bool aesKeySizeGood(size_t key_size)
|
||||
#define GCM_DIGEST_SIZE GCM_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
Blob aesEncrypt(const Blob& data, const Blob& key)
|
||||
Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key)
|
||||
{
|
||||
if (not aesKeySizeGood(key.size()))
|
||||
throw DecryptError("Wrong key size");
|
||||
|
||||
Blob ret(data.size() + GCM_IV_SIZE + GCM_DIGEST_SIZE);
|
||||
Blob ret(data_length + GCM_IV_SIZE + GCM_DIGEST_SIZE);
|
||||
{
|
||||
crypto::random_device rdev;
|
||||
std::generate_n(ret.begin(), GCM_IV_SIZE, std::bind(rand_byte, std::ref(rdev)));
|
||||
@@ -104,10 +108,12 @@ Blob aesEncrypt(const Blob& data, const Blob& key)
|
||||
struct gcm_aes_ctx aes;
|
||||
gcm_aes_set_key(&aes, key.size(), key.data());
|
||||
gcm_aes_set_iv(&aes, GCM_IV_SIZE, ret.data());
|
||||
gcm_aes_update(&aes, data.size(), data.data());
|
||||
#if DHT_AES_LEGACY_ENCRYPT
|
||||
gcm_aes_update(&aes, data_length, data);
|
||||
#endif
|
||||
|
||||
gcm_aes_encrypt(&aes, data.size(), ret.data() + GCM_IV_SIZE, data.data());
|
||||
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, ret.data() + GCM_IV_SIZE + data.size());
|
||||
gcm_aes_encrypt(&aes, data_length, ret.data() + GCM_IV_SIZE, data);
|
||||
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, ret.data() + GCM_IV_SIZE + data_length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -136,21 +142,26 @@ Blob aesDecrypt(const Blob& data, const Blob& key)
|
||||
|
||||
size_t data_sz = data.size() - GCM_IV_SIZE - GCM_DIGEST_SIZE;
|
||||
Blob ret(data_sz);
|
||||
//gcm_aes_update(&aes, data_sz, data.data() + GCM_IV_SIZE);
|
||||
gcm_aes_decrypt(&aes, data_sz, ret.data(), data.data() + GCM_IV_SIZE);
|
||||
//gcm_aes_digest(aes, GCM_DIGEST_SIZE, digest.data());
|
||||
gcm_aes_digest(&aes, GCM_DIGEST_SIZE, digest.data());
|
||||
|
||||
// TODO compute the proper digest directly from the decryption pass
|
||||
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_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 DHT_AES_LEGACY_DECRYPT
|
||||
//gcm_aes_decrypt(&aes, data_sz, ret.data(), 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_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.end() - GCM_DIGEST_SIZE))
|
||||
throw DecryptError("Can't decrypt data");
|
||||
#else
|
||||
throw DecryptError("Can't decrypt data");
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -214,15 +225,14 @@ PrivateKey::PrivateKey(gnutls_x509_privkey_t k) : x509_key(k)
|
||||
}
|
||||
}
|
||||
|
||||
PrivateKey::PrivateKey(const Blob& import, const std::string& password)
|
||||
PrivateKey::PrivateKey(const uint8_t* src, size_t src_size, const char* password_ptr)
|
||||
{
|
||||
int err = gnutls_x509_privkey_init(&x509_key);
|
||||
if (err != GNUTLS_E_SUCCESS)
|
||||
throw CryptoException("Can't initialize private key !");
|
||||
|
||||
const gnutls_datum_t dt {(uint8_t*)import.data(), static_cast<unsigned>(import.size())};
|
||||
const char* password_ptr = password.empty() ? nullptr : password.c_str();
|
||||
int flags = password.empty() ? GNUTLS_PKCS_PLAIN
|
||||
const gnutls_datum_t dt {(uint8_t*)src, static_cast<unsigned>(src_size)};
|
||||
int flags = password_ptr ? GNUTLS_PKCS_PLAIN
|
||||
: ( GNUTLS_PKCS_PBES2_AES_128 | GNUTLS_PKCS_PBES2_AES_192 | GNUTLS_PKCS_PBES2_AES_256
|
||||
| GNUTLS_PKCS_PKCS12_3DES | GNUTLS_PKCS_PKCS12_ARCFOUR | GNUTLS_PKCS_PKCS12_RC2_40);
|
||||
|
||||
@@ -338,9 +348,7 @@ PrivateKey::serialize(const std::string& password) const
|
||||
size_t buf_sz = 8192;
|
||||
Blob buffer;
|
||||
buffer.resize(buf_sz);
|
||||
int err = password.empty()
|
||||
? gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN, buffer.data(), &buf_sz)
|
||||
: gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, buffer.data(), &buf_sz);
|
||||
auto err = serialize(buffer.data(), &buf_sz, password);
|
||||
if (err != GNUTLS_E_SUCCESS) {
|
||||
std::cerr << "Could not export private key - " << gnutls_strerror(err) << std::endl;
|
||||
return {};
|
||||
@@ -349,6 +357,16 @@ PrivateKey::serialize(const std::string& password) const
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int
|
||||
PrivateKey::serialize(uint8_t* out, size_t* out_len, const std::string& password) const
|
||||
{
|
||||
if (!x509_key)
|
||||
return -1;
|
||||
return password.empty()
|
||||
? gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN, out, out_len)
|
||||
: gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, out, out_len);
|
||||
}
|
||||
|
||||
PublicKey
|
||||
PrivateKey::getPublicKey() const
|
||||
{
|
||||
@@ -364,9 +382,9 @@ PublicKey::PublicKey()
|
||||
throw CryptoException(std::string("Can't initialize public key: ") + gnutls_strerror(err));
|
||||
}
|
||||
|
||||
PublicKey::PublicKey(const Blob& dat) : PublicKey()
|
||||
PublicKey::PublicKey(const uint8_t* dat, size_t dat_size) : PublicKey()
|
||||
{
|
||||
unpack(dat.data(), dat.size());
|
||||
unpack(dat, dat_size);
|
||||
}
|
||||
|
||||
PublicKey::~PublicKey()
|
||||
@@ -439,13 +457,12 @@ PublicKey::msgpack_unpack(msgpack::object o)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PublicKey::checkSignature(const Blob& data, const Blob& signature) const
|
||||
bool PublicKey::checkSignature(const uint8_t* data, size_t data_len, const uint8_t* signature, size_t signature_len) const
|
||||
{
|
||||
if (!pk)
|
||||
return false;
|
||||
const gnutls_datum_t sig {(uint8_t*)signature.data(), (unsigned)signature.size()};
|
||||
const gnutls_datum_t dat {(uint8_t*)data.data(), (unsigned)data.size()};
|
||||
const gnutls_datum_t sig {(uint8_t*)signature, (unsigned)signature_len};
|
||||
const gnutls_datum_t dat {(uint8_t*)data, (unsigned)data_len};
|
||||
int rc = gnutls_pubkey_verify_data2(pk, GNUTLS_SIGN_RSA_SHA512, 0, &dat, &sig);
|
||||
return rc >= 0;
|
||||
}
|
||||
@@ -465,7 +482,7 @@ PublicKey::encryptBloc(const uint8_t* src, size_t src_size, uint8_t* dst, size_t
|
||||
}
|
||||
|
||||
Blob
|
||||
PublicKey::encrypt(const Blob& data) const
|
||||
PublicKey::encrypt(const uint8_t* data, size_t data_len) const
|
||||
{
|
||||
if (!pk)
|
||||
throw CryptoException("Can't read public key !");
|
||||
@@ -481,9 +498,9 @@ PublicKey::encrypt(const Blob& data) const
|
||||
const unsigned cypher_block_sz = key_len / 8;
|
||||
|
||||
/* Use plain RSA if the data is small enough */
|
||||
if (data.size() <= max_block_sz) {
|
||||
if (data_len <= max_block_sz) {
|
||||
Blob ret(cypher_block_sz);
|
||||
encryptBloc(data.data(), data.size(), ret.data(), cypher_block_sz);
|
||||
encryptBloc(data, data_len, ret.data(), cypher_block_sz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -498,7 +515,7 @@ PublicKey::encrypt(const Blob& data) const
|
||||
crypto::random_device rdev;
|
||||
std::generate_n(key.begin(), key.size(), std::bind(rand_byte, std::ref(rdev)));
|
||||
}
|
||||
auto data_encrypted = aesEncrypt(data, key);
|
||||
auto data_encrypted = aesEncrypt(data, data_len, key);
|
||||
|
||||
Blob ret;
|
||||
ret.reserve(cypher_block_sz + data_encrypted.size());
|
||||
@@ -702,6 +719,17 @@ CertificateRequest::pack() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string
|
||||
CertificateRequest::toString() const
|
||||
{
|
||||
gnutls_datum_t dat {nullptr, 0};
|
||||
if (auto err = gnutls_x509_crq_export2(request, GNUTLS_X509_FMT_PEM, &dat))
|
||||
throw CryptoException(std::string("Can't export certificate request: ") + gnutls_strerror(err));
|
||||
std::string ret(dat.data, dat.data + dat.size);
|
||||
gnutls_free(dat.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Certificate
|
||||
|
||||
static std::string
|
||||
@@ -1043,6 +1071,21 @@ generateEcIdentity(const std::string& name, const Identity& ca) {
|
||||
return generateEcIdentity(name, ca, !ca.first || !ca.second);
|
||||
}
|
||||
|
||||
void
|
||||
saveIdentity(const Identity& id, const std::string& path, const std::string& privkey_password)
|
||||
{
|
||||
{
|
||||
auto ca_key_data = id.first->serialize(privkey_password);
|
||||
std::ofstream key_file(path + ".pem");
|
||||
key_file.write((char*)ca_key_data.data(), ca_key_data.size());
|
||||
}
|
||||
{
|
||||
auto ca_key_data = id.second->getPacked();
|
||||
std::ofstream crt_file(path + ".crt");
|
||||
crt_file.write((char*)ca_key_data.data(), ca_key_data.size());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setValidityPeriod(gnutls_x509_crt_t cert, int64_t validity)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "default_types.h"
|
||||
|
||||
@@ -83,6 +86,8 @@ IpServiceAnnouncement::storePolicy(InfoHash h, std::shared_ptr<Value>& v, const
|
||||
|
||||
const ValueType DhtMessage::TYPE(1, "DHT message", std::chrono::minutes(5), DhtMessage::storePolicy);
|
||||
const ValueType IpServiceAnnouncement::TYPE(2, "Internet Service Announcement", std::chrono::minutes(15), IpServiceAnnouncement::storePolicy);
|
||||
|
||||
#ifndef OPENDHT_LIGHT
|
||||
const ValueType ImMessage::TYPE = {3, "IM message", std::chrono::minutes(5)};
|
||||
const ValueType TrustRequest::TYPE = {4, "Certificate trust request", std::chrono::hours(24*7)};
|
||||
const ValueType IceCandidates::TYPE = {5, "ICE candidates", std::chrono::minutes(1)};
|
||||
@@ -96,6 +101,13 @@ DEFAULT_TYPES
|
||||
IceCandidates::TYPE,
|
||||
TrustRequest::TYPE
|
||||
}};
|
||||
#else
|
||||
const std::array<std::reference_wrapper<const ValueType>, 1>
|
||||
DEFAULT_TYPES
|
||||
{{
|
||||
ValueType::USER_DATA
|
||||
}};
|
||||
#endif
|
||||
|
||||
const std::array<std::reference_wrapper<const ValueType>, 1>
|
||||
DEFAULT_INSECURE_TYPES
|
||||
|
||||
+65
-76
@@ -39,6 +39,7 @@ constexpr std::chrono::minutes Dht::MAX_STORAGE_MAINTENANCE_EXPIRE_TIME;
|
||||
constexpr std::chrono::minutes Dht::SEARCH_EXPIRE_TIME;
|
||||
constexpr std::chrono::seconds Dht::LISTEN_EXPIRE_TIME;
|
||||
constexpr std::chrono::seconds Dht::REANNOUNCE_MARGIN;
|
||||
static constexpr size_t MAX_REQUESTS_PER_SEC {1600};
|
||||
|
||||
NodeStatus
|
||||
Dht::getStatus(sa_family_t af) const
|
||||
@@ -75,10 +76,10 @@ Dht::shutdown(ShutdownCallback cb)
|
||||
for (auto& str : store)
|
||||
*remaining += maintainStorage(str, true, str_donecb);
|
||||
|
||||
DHT_LOG.w("shuting down node: after storage, %u ops", *remaining);
|
||||
|
||||
if (!*remaining) {
|
||||
DHT_LOG.w("shuting down node: %u ops remaining", *remaining);
|
||||
if (cb)
|
||||
cb();
|
||||
if (cb) cb();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -921,8 +922,7 @@ Dht::put(const InfoHash& id, Sp<Value> val, DoneCallback callback, time_point cr
|
||||
}
|
||||
if (val->id == Value::INVALID_ID) {
|
||||
crypto::random_device rdev;
|
||||
std::uniform_int_distribution<Value::Id> rand_id {};
|
||||
val->id = rand_id(rdev);
|
||||
val->id = std::uniform_int_distribution<Value::Id>{1}(rdev);
|
||||
}
|
||||
scheduler.syncTime();
|
||||
const auto& now = scheduler.time();
|
||||
@@ -986,19 +986,15 @@ Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filt
|
||||
{
|
||||
scheduler.syncTime();
|
||||
|
||||
auto q = std::make_shared<Query>(Select {}, std::move(where));
|
||||
auto op = std::make_shared<GetStatus<std::map<Value::Id, Sp<Value>>>>();
|
||||
auto f = filter.chain(q->where.getFilter());
|
||||
|
||||
auto gcb = [getcb, donecb, op, f](const std::vector<Sp<Value>>& vals) {
|
||||
auto gcb = [getcb, donecb, op](const std::vector<Sp<Value>>& vals) {
|
||||
auto& o = *op;
|
||||
return callbackWrapper(getcb, donecb, vals, [&o,&f](const std::vector<Sp<Value>>& values) {
|
||||
return callbackWrapper(getcb, donecb, vals, [&o](const std::vector<Sp<Value>>& values) {
|
||||
std::vector<Sp<Value>> newvals {};
|
||||
for (const auto& v : values) {
|
||||
auto it = o.values.find(v->id);
|
||||
if (it == o.values.cend() or (it->second != v && !(*it->second == *v))) {
|
||||
if (not f or f(*v))
|
||||
newvals.push_back(v);
|
||||
newvals.push_back(v);
|
||||
}
|
||||
}
|
||||
return newvals;
|
||||
@@ -1008,6 +1004,9 @@ Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filt
|
||||
}, o);
|
||||
};
|
||||
|
||||
auto q = std::make_shared<Query>(Select {}, std::move(where));
|
||||
auto f = filter.chain(q->where.getFilter());
|
||||
|
||||
/* Try to answer this search locally. */
|
||||
gcb(getLocal(id, f));
|
||||
|
||||
@@ -1075,7 +1074,7 @@ void Dht::query(const InfoHash& id, QueryCallback cb, DoneCallback done_cb, Quer
|
||||
}
|
||||
|
||||
std::vector<Sp<Value>>
|
||||
Dht::getLocal(const InfoHash& id, Value::Filter f) const
|
||||
Dht::getLocal(const InfoHash& id, const Value::Filter& f) const
|
||||
{
|
||||
auto s = store.find(id);
|
||||
if (s == store.end()) return {};
|
||||
@@ -1092,17 +1091,14 @@ Dht::getLocalById(const InfoHash& id, Value::Id vid) const
|
||||
}
|
||||
|
||||
std::vector<Sp<Value>>
|
||||
Dht::getPut(const InfoHash& id)
|
||||
Dht::getPut(const InfoHash& id) const
|
||||
{
|
||||
std::vector<Sp<Value>> ret;
|
||||
auto find_values = [&](std::map<InfoHash, Sp<Search>> srs) {
|
||||
auto find_values = [&](const std::map<InfoHash, Sp<Search>>& srs) {
|
||||
auto srp = srs.find(id);
|
||||
if (srp == srs.end())
|
||||
return;
|
||||
auto& search = srp->second;
|
||||
ret.reserve(ret.size() + search->announce.size());
|
||||
for (const auto& a : search->announce)
|
||||
ret.push_back(a.value);
|
||||
if (srp == srs.end()) return;
|
||||
auto vals = srp->second->getPut();
|
||||
ret.insert(ret.end(), vals.begin(), vals.end());
|
||||
};
|
||||
find_values(searches4);
|
||||
find_values(searches6);
|
||||
@@ -1110,18 +1106,11 @@ Dht::getPut(const InfoHash& id)
|
||||
}
|
||||
|
||||
Sp<Value>
|
||||
Dht::getPut(const InfoHash& id, const Value::Id& vid)
|
||||
Dht::getPut(const InfoHash& id, const Value::Id& vid) const
|
||||
{
|
||||
auto find_value = [&](std::map<InfoHash, Sp<Search>> srs) {
|
||||
auto find_value = [&](const std::map<InfoHash, Sp<Search>>& srs) {
|
||||
auto srp = srs.find(id);
|
||||
if (srp == srs.end())
|
||||
return Sp<Value> {};
|
||||
auto& search = srp->second;
|
||||
for (auto& a : search->announce) {
|
||||
if (a.value->id == vid)
|
||||
return a.value;
|
||||
}
|
||||
return Sp<Value> {};
|
||||
return (srp != srs.end()) ? srp->second->getPut(vid) : Sp<Value> {};
|
||||
};
|
||||
if (auto v4 = find_value(searches4))
|
||||
return v4;
|
||||
@@ -1134,29 +1123,17 @@ bool
|
||||
Dht::cancelPut(const InfoHash& id, const Value::Id& vid)
|
||||
{
|
||||
bool canceled {false};
|
||||
if (storageErase(id, vid))
|
||||
canceled = true;
|
||||
auto sr_cancel_put = [&](std::map<InfoHash, Sp<Search>> srs) {
|
||||
auto sr_cancel_put = [&](std::map<InfoHash, Sp<Search>>& srs) {
|
||||
auto srp = srs.find(id);
|
||||
if (srp == srs.end())
|
||||
return;
|
||||
|
||||
auto& sr = srp->second;
|
||||
for (auto it = sr->announce.begin(); it != sr->announce.end();) {
|
||||
if (it->value->id == vid) {
|
||||
canceled = true;
|
||||
it = sr->announce.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
return (srp != srs.end()) ? srp->second->cancelPut(vid) : false;
|
||||
};
|
||||
sr_cancel_put(searches4);
|
||||
sr_cancel_put(searches6);
|
||||
canceled |= sr_cancel_put(searches4);
|
||||
canceled |= sr_cancel_put(searches6);
|
||||
if (canceled)
|
||||
storageErase(id, vid);
|
||||
return canceled;
|
||||
}
|
||||
|
||||
|
||||
// Storage
|
||||
|
||||
void
|
||||
@@ -1225,7 +1202,7 @@ Dht::storageStore(const InfoHash& id, const Sp<Value>& value, time_point created
|
||||
|
||||
StorageBucket* store_bucket {nullptr};
|
||||
if (sa)
|
||||
store_bucket = &store_quota.emplace(sa, StorageBucket{}).first->second;
|
||||
store_bucket = &store_quota[sa];
|
||||
|
||||
auto store = st->second.store(id, value, created, expiration, store_bucket);
|
||||
if (auto vs = store.first) {
|
||||
@@ -1712,11 +1689,23 @@ Dht::~Dht()
|
||||
s.second->clear();
|
||||
}
|
||||
|
||||
Dht::Dht() : store(), network_engine(DHT_LOG, scheduler) {}
|
||||
net::NetworkConfig
|
||||
fromDhtConfig(const Config& config)
|
||||
{
|
||||
net::NetworkConfig netConf;
|
||||
netConf.network = config.network;
|
||||
netConf.max_req_per_sec = config.max_req_per_sec ? config.max_req_per_sec : MAX_REQUESTS_PER_SEC;
|
||||
netConf.max_peer_req_per_sec = config.max_peer_req_per_sec
|
||||
? config.max_peer_req_per_sec
|
||||
: netConf.max_req_per_sec/8;
|
||||
return netConf;
|
||||
}
|
||||
|
||||
Dht::Dht(const int& s, const int& s6, const Config& config)
|
||||
: myid(config.node_id ? config.node_id : InfoHash::getRandom()), store(), store_quota(),
|
||||
network_engine(myid, config.network, s, s6, DHT_LOG, scheduler,
|
||||
Dht::Dht() : store(), network_engine(DHT_LOG, scheduler, {}) {}
|
||||
|
||||
Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Logger& l)
|
||||
: DhtInterface(l), myid(config.node_id ? config.node_id : InfoHash::getRandom()), store(), store_quota(),
|
||||
network_engine(myid, fromDhtConfig(config), std::move(sock), DHT_LOG, scheduler,
|
||||
std::bind(&Dht::onError, this, _1, _2),
|
||||
std::bind(&Dht::onNewNode, this, _1, _2),
|
||||
std::bind(&Dht::onReportedAddr, this, _1, _2),
|
||||
@@ -1731,13 +1720,14 @@ Dht::Dht(const int& s, const int& s6, const Config& config)
|
||||
maintain_storage(config.maintain_storage)
|
||||
{
|
||||
scheduler.syncTime();
|
||||
if (s < 0 && s6 < 0)
|
||||
return;
|
||||
if (s >= 0) {
|
||||
auto s = network_engine.getSocket();
|
||||
if (not s or (not s->hasIPv4() and not s->hasIPv6()))
|
||||
throw DhtException("Opened socket required");
|
||||
if (s->hasIPv4()) {
|
||||
buckets4 = {Bucket {AF_INET}};
|
||||
buckets4.is_client = config.is_bootstrap;
|
||||
}
|
||||
if (s6 >= 0) {
|
||||
if (s->hasIPv6()) {
|
||||
buckets6 = {Bucket {AF_INET6}};
|
||||
buckets6.is_client = config.is_bootstrap;
|
||||
}
|
||||
@@ -1745,9 +1735,7 @@ Dht::Dht(const int& s, const int& s6, const Config& config)
|
||||
search_id = std::uniform_int_distribution<decltype(search_id)>{}(rd);
|
||||
|
||||
uniform_duration_distribution<> time_dis {std::chrono::seconds(3), std::chrono::seconds(5)};
|
||||
auto confirm_nodes_time = scheduler.time() + time_dis(rd);
|
||||
DHT_LOG.d(myid, "Scheduling %s", myid.toString().c_str());
|
||||
nextNodesConfirmation = scheduler.add(confirm_nodes_time, std::bind(&Dht::confirmNodes, this));
|
||||
nextNodesConfirmation = scheduler.add(scheduler.time() + time_dis(rd), std::bind(&Dht::confirmNodes, this));
|
||||
|
||||
// Fill old secret
|
||||
{
|
||||
@@ -1758,7 +1746,7 @@ Dht::Dht(const int& s, const int& s6, const Config& config)
|
||||
|
||||
expire();
|
||||
|
||||
DHT_LOG.d("DHT initialised with node ID %s", myid.toString().c_str());
|
||||
DHT_LOG.d("DHT node initialised with ID %s", myid.toString().c_str());
|
||||
|
||||
if (not persistPath.empty())
|
||||
loadState(persistPath);
|
||||
@@ -1925,14 +1913,14 @@ Dht::maintainStorage(decltype(store)::value_type& storage, bool force, const Don
|
||||
}
|
||||
|
||||
time_point
|
||||
Dht::periodic(const uint8_t *buf, size_t buflen, const SockAddr& from)
|
||||
Dht::periodic(const uint8_t *buf, size_t buflen, SockAddr from)
|
||||
{
|
||||
scheduler.syncTime();
|
||||
if (buflen) {
|
||||
try {
|
||||
network_engine.processMessage(buf, buflen, from);
|
||||
network_engine.processMessage(buf, buflen, std::move(from));
|
||||
} catch (const std::exception& e) {
|
||||
DHT_LOG.e("Can't process message from %s: %s", from.toString().c_str(), e.what());
|
||||
DHT_LOG.w("Can't process message: %s", e.what());
|
||||
}
|
||||
}
|
||||
return scheduler.run();
|
||||
@@ -2016,14 +2004,15 @@ Dht::exportValues() const
|
||||
void
|
||||
Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
{
|
||||
for (const auto& h : import) {
|
||||
if (h.second.empty())
|
||||
const auto& now = scheduler.time();
|
||||
|
||||
for (const auto& node : import) {
|
||||
if (node.second.empty())
|
||||
continue;
|
||||
|
||||
const auto& now = scheduler.time();
|
||||
try {
|
||||
msgpack::unpacked msg;
|
||||
msgpack::unpack(msg, (const char*)h.second.data(), h.second.size());
|
||||
msgpack::unpack(msg, (const char*)node.second.data(), node.second.size());
|
||||
auto valarr = msg.get();
|
||||
if (valarr.type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
@@ -2037,14 +2026,14 @@ Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
val_time = time_point{time_point::duration{valel.via.array.ptr[0].as<time_point::duration::rep>()}};
|
||||
tmp_val.msgpack_unpack(valel.via.array.ptr[1]);
|
||||
} catch (const std::exception&) {
|
||||
DHT_LOG.e(h.first, "Error reading value at %s", h.first.toString().c_str());
|
||||
DHT_LOG.e(node.first, "Error reading value at %s", node.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
val_time = std::min(val_time, now);
|
||||
storageStore(h.first, std::make_shared<Value>(std::move(tmp_val)), val_time);
|
||||
storageStore(node.first, std::make_shared<Value>(std::move(tmp_val)), val_time);
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
DHT_LOG.e(h.first, "Error reading values at %s", h.first.toString().c_str());
|
||||
DHT_LOG.e(node.first, "Error reading values at %s", node.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2093,13 +2082,13 @@ Dht::insertNode(const InfoHash& id, const SockAddr& addr)
|
||||
}
|
||||
|
||||
void
|
||||
Dht::pingNode(const sockaddr* sa, socklen_t salen, DoneCallbackSimple&& cb)
|
||||
Dht::pingNode(SockAddr sa, DoneCallbackSimple&& cb)
|
||||
{
|
||||
scheduler.syncTime();
|
||||
DHT_LOG.d("Sending ping to %s", print_addr(sa, salen).c_str());
|
||||
auto& count = sa->sa_family == AF_INET ? pending_pings4 : pending_pings6;
|
||||
DHT_LOG.d("Sending ping to %s", sa.toString().c_str());
|
||||
auto& count = sa.getFamily() == AF_INET ? pending_pings4 : pending_pings6;
|
||||
count++;
|
||||
network_engine.sendPing(sa, salen, [&count,cb](const net::Request&, net::RequestAnswer&&) {
|
||||
network_engine.sendPing(std::move(sa), [&count,cb](const net::Request&, net::RequestAnswer&&) {
|
||||
count--;
|
||||
if (cb)
|
||||
cb(true);
|
||||
|
||||
+778
-620
File diff suppressed because it is too large.
Load diff
+1028
-705
File diff suppressed because it is too large.
Load diff
+496
-398
File diff suppressed because it is too large.
Load diff
+967
@@ -0,0 +1,967 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
|
||||
* Author: 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
|
||||
* 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 "http.h"
|
||||
#include "log_enable.h"
|
||||
#include "crypto.h"
|
||||
#include "base64.h"
|
||||
|
||||
#include <asio.hpp>
|
||||
#include <restinio/impl/tls_socket.hpp>
|
||||
#include <http_parser.h>
|
||||
#include <json/json.h>
|
||||
|
||||
namespace dht {
|
||||
namespace http {
|
||||
|
||||
constexpr char HTTP_HEADER_CONTENT_TYPE_JSON[] = "application/json";
|
||||
constexpr char HTTP_HEADER_DELIM[] = "\r\n\r\n";
|
||||
|
||||
Url::Url(const std::string& url): url(url)
|
||||
{
|
||||
size_t addr_begin = 0;
|
||||
// protocol
|
||||
const size_t proto_end = url.find("://");
|
||||
if (proto_end != std::string::npos){
|
||||
addr_begin = proto_end + 3;
|
||||
if (url.substr(0, proto_end) == "https"){
|
||||
protocol = "https";
|
||||
service = protocol;
|
||||
}
|
||||
}
|
||||
// host and service
|
||||
size_t addr_size = url.substr(addr_begin).find("/");
|
||||
if (addr_size == std::string::npos)
|
||||
addr_size = url.size() - addr_begin;
|
||||
auto host_service = splitPort(url.substr(addr_begin, addr_size));
|
||||
host = host_service.first;
|
||||
if (!host_service.second.empty())
|
||||
service = host_service.second;
|
||||
// target, query and fragment
|
||||
size_t query_begin = url.find("?");
|
||||
auto addr_end = addr_begin + addr_size;
|
||||
if (addr_end < url.size())
|
||||
target = url.substr(addr_end);
|
||||
size_t fragment_begin = url.find("#");
|
||||
if (fragment_begin == std::string::npos){
|
||||
query = url.substr(query_begin + 1);
|
||||
} else {
|
||||
target = url.substr(addr_end, fragment_begin - addr_end);
|
||||
query = url.substr(query_begin + 1, fragment_begin - query_begin - 1);
|
||||
fragment = url.substr(fragment_begin);
|
||||
}
|
||||
}
|
||||
|
||||
// connection
|
||||
|
||||
std::atomic_uint Connection::ids_ {1};
|
||||
|
||||
Connection::Connection(asio::io_context& ctx, const bool ssl, std::shared_ptr<dht::Logger> l)
|
||||
: id_(Connection::ids_++), ctx_(ctx), istream_(&read_buf_), logger_(l)
|
||||
{
|
||||
if (ssl){
|
||||
ssl_ctx_ = std::make_shared<asio::ssl::context>(asio::ssl::context::sslv23);
|
||||
ssl_ctx_->set_default_verify_paths();
|
||||
ssl_ctx_->set_verify_mode(asio::ssl::verify_none);
|
||||
ssl_socket_ = std::make_unique<ssl_socket_t>(ctx_, ssl_ctx_);
|
||||
if (logger_)
|
||||
logger_->d("[connection:%i] start https session", id_);
|
||||
}
|
||||
else {
|
||||
socket_ = std::make_unique<socket_t>(ctx);
|
||||
if (logger_)
|
||||
logger_->d("[connection:%i] start http session", id_);
|
||||
}
|
||||
}
|
||||
|
||||
Connection::Connection(asio::io_context& ctx, std::shared_ptr<dht::crypto::Certificate> server_ca,
|
||||
const dht::crypto::Identity& identity, std::shared_ptr<dht::Logger> l)
|
||||
: id_(Connection::ids_++), ctx_(ctx), istream_(&read_buf_), logger_(l)
|
||||
{
|
||||
ssl_ctx_ = std::make_shared<asio::ssl::context>(asio::ssl::context::sslv23);
|
||||
ssl_ctx_->set_default_verify_paths();
|
||||
asio::error_code ec;
|
||||
if (server_ca){
|
||||
auto ca = server_ca->toString(false/*chain*/);
|
||||
ssl_ctx_->add_certificate_authority(asio::const_buffer{ca.data(), ca.size()}, ec);
|
||||
if (ec)
|
||||
throw std::runtime_error("Error adding certificate authority: " + ec.message());
|
||||
else if (logger_)
|
||||
logger_->d("[connection:%i] certficate authority %s", id_, server_ca->getUID().c_str());
|
||||
}
|
||||
if (identity.first){
|
||||
auto key = identity.first->serialize();
|
||||
ssl_ctx_->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 client private key: " + ec.message());
|
||||
}
|
||||
if (identity.second){
|
||||
auto cert = identity.second->toString(true/*chain*/);
|
||||
ssl_ctx_->use_certificate_chain(asio::const_buffer{cert.data(), cert.size()}, ec);
|
||||
if (ec)
|
||||
throw std::runtime_error("Error adding client certificate: " + ec.message());
|
||||
else if (logger_)
|
||||
logger_->d("[connection:%i] client certificate %s", id_, identity.second->getUID().c_str());
|
||||
}
|
||||
ssl_ctx_->set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert);
|
||||
ssl_socket_ = std::make_unique<ssl_socket_t>(ctx_, ssl_ctx_);
|
||||
}
|
||||
|
||||
Connection::~Connection() {
|
||||
close();
|
||||
}
|
||||
|
||||
void
|
||||
Connection::close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
if (ssl_socket_) {
|
||||
if (ssl_socket_->is_open())
|
||||
ssl_socket_->close(ec);
|
||||
}
|
||||
else if (socket_) {
|
||||
if (socket_->is_open())
|
||||
socket_->close(ec);
|
||||
}
|
||||
if (ec and logger_)
|
||||
logger_->e("[connection:%i] error closing: %s", id_, ec.message().c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
Connection::is_open() const
|
||||
{
|
||||
if (ssl_socket_) return ssl_socket_->is_open();
|
||||
else if (socket_) return socket_->is_open();
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Connection::is_ssl() const
|
||||
{
|
||||
return ssl_ctx_ ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
Connection::set_ssl_verification(const asio::ip::tcp::endpoint& endpoint, const asio::ssl::verify_mode verify_mode)
|
||||
{
|
||||
if (ssl_socket_ and verify_mode != asio::ssl::verify_none) {
|
||||
ssl_socket_->asio_ssl_stream().set_verify_mode(verify_mode);
|
||||
ssl_socket_->asio_ssl_stream().set_verify_callback([
|
||||
id = id_,
|
||||
logger = logger_,
|
||||
hostname = endpoint.address().to_string()
|
||||
] (bool preverified, asio::ssl::verify_context& ctx) -> bool {
|
||||
if (logger)
|
||||
logger->d("[connection:%i] verify %s compliance to RFC 2818", id, hostname.c_str());
|
||||
if (preverified)
|
||||
return preverified;
|
||||
// starts from CA and goes down the presented chain
|
||||
auto verifier = asio::ssl::rfc2818_verification(hostname);
|
||||
bool verified = verifier(preverified, ctx);
|
||||
auto verify_ec = X509_STORE_CTX_get_error(ctx.native_handle());
|
||||
if (verified != 0 /*X509_V_OK*/ and logger)
|
||||
logger->e("[http::connection:%i] ssl verification error=%i", id, verify_ec);
|
||||
return verified;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
asio::streambuf&
|
||||
Connection::input()
|
||||
{
|
||||
return write_buf_;
|
||||
}
|
||||
|
||||
std::string
|
||||
Connection::read_bytes(size_t bytes)
|
||||
{
|
||||
if (bytes == 0)
|
||||
bytes = read_buf_.in_avail();
|
||||
std::string content;
|
||||
content.resize(bytes);
|
||||
auto rb = istream_.readsome(&content[0], bytes);
|
||||
content.resize(rb);
|
||||
return content;
|
||||
}
|
||||
|
||||
std::string
|
||||
Connection::read_until(const char delim)
|
||||
{
|
||||
std::string content;
|
||||
std::getline(istream_, content, delim);
|
||||
return content;
|
||||
}
|
||||
|
||||
void
|
||||
Connection::async_connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, ConnectHandlerCb cb)
|
||||
{
|
||||
if (ssl_socket_)
|
||||
asio::async_connect(ssl_socket_->lowest_layer(), std::move(endpoints), wrapCallabck(std::move(cb)));
|
||||
else if (socket_)
|
||||
asio::async_connect(*socket_, std::move(endpoints), wrapCallabck(std::move(cb)));
|
||||
else if (cb)
|
||||
cb(asio::error::operation_aborted, {});
|
||||
}
|
||||
|
||||
void
|
||||
Connection::async_handshake(HandlerCb cb)
|
||||
{
|
||||
if (ssl_socket_) {
|
||||
std::weak_ptr<Connection> wthis = shared_from_this();
|
||||
ssl_socket_->async_handshake(asio::ssl::stream<asio::ip::tcp::socket>::client,
|
||||
[wthis, cb](const asio::error_code& ec)
|
||||
{
|
||||
if (ec == asio::error::operation_aborted)
|
||||
return;
|
||||
if (auto sthis = wthis.lock()) {
|
||||
auto& this_ = *sthis;
|
||||
auto verify_ec = SSL_get_verify_result(this_.ssl_socket_->asio_ssl_stream().native_handle());
|
||||
if (this_.logger_) {
|
||||
if (verify_ec == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT /*18*/
|
||||
|| verify_ec == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN /*19*/)
|
||||
this_.logger_->d("[connection:%i] allow self-signed certificate in handshake", this_.id_);
|
||||
else if (verify_ec != X509_V_OK)
|
||||
this_.logger_->e("[connection:%i] verify handshake error: %i", this_.id_, verify_ec);
|
||||
}
|
||||
}
|
||||
if (cb)
|
||||
cb(ec);
|
||||
});
|
||||
}
|
||||
else if (socket_)
|
||||
cb(asio::error::no_protocol_option);
|
||||
else if (cb)
|
||||
cb(asio::error::operation_aborted);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::async_write(BytesHandlerCb cb)
|
||||
{
|
||||
if (!is_open()) return;
|
||||
if (ssl_socket_) asio::async_write(*ssl_socket_, write_buf_, wrapCallabck(std::move(cb)));
|
||||
else if (socket_) asio::async_write(*socket_, write_buf_, wrapCallabck(std::move(cb)));
|
||||
else if (cb) cb(asio::error::operation_aborted, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::async_read_until(const char* delim, BytesHandlerCb cb)
|
||||
{
|
||||
if (!is_open()) return;
|
||||
if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallabck(std::move(cb)));
|
||||
else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallabck(std::move(cb)));
|
||||
else if (cb) cb(asio::error::operation_aborted, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::async_read_until(char delim, BytesHandlerCb cb)
|
||||
{
|
||||
if (!is_open()) return;
|
||||
if (ssl_socket_) asio::async_read_until(*ssl_socket_, read_buf_, delim, wrapCallabck(std::move(cb)));
|
||||
else if (socket_) asio::async_read_until(*socket_, read_buf_, delim, wrapCallabck(std::move(cb)));
|
||||
else if (cb) cb(asio::error::operation_aborted, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::async_read(size_t bytes, BytesHandlerCb cb)
|
||||
{
|
||||
if (!is_open()) return;
|
||||
if (ssl_socket_) asio::async_read(*ssl_socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallabck(std::move(cb)));
|
||||
else if (socket_) asio::async_read(*socket_, read_buf_, asio::transfer_exactly(bytes), wrapCallabck(std::move(cb)));
|
||||
else if (cb) cb(asio::error::operation_aborted, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::async_read_some(size_t bytes, BytesHandlerCb cb)
|
||||
{
|
||||
if (!is_open()) {
|
||||
if (cb) cb(asio::error::operation_aborted, 0);
|
||||
return;
|
||||
}
|
||||
auto buf = read_buf_.prepare(bytes);
|
||||
auto onEnd = [this_=shared_from_this(), cb=std::move(cb)](const asio::error_code& ec, size_t t){
|
||||
this_->read_buf_.commit(t);
|
||||
cb(ec, t);
|
||||
};
|
||||
if (ssl_socket_) ssl_socket_->async_read_some(buf, onEnd);
|
||||
else socket_->async_read_some(buf, onEnd);
|
||||
}
|
||||
|
||||
void
|
||||
Connection::timeout(const std::chrono::seconds timeout, HandlerCb cb)
|
||||
{
|
||||
if (!is_open()){
|
||||
if (logger_)
|
||||
logger_->e("[connection:%i] closed, can't timeout", id_);
|
||||
if (cb)
|
||||
cb(asio::error::operation_aborted);
|
||||
return;
|
||||
}
|
||||
if (!timeout_timer_)
|
||||
timeout_timer_ = std::make_unique<asio::steady_timer>(ctx_);
|
||||
timeout_timer_->expires_at(std::chrono::steady_clock::now() + timeout);
|
||||
timeout_timer_->async_wait([id=id_, logger=logger_, cb](const asio::error_code &ec){
|
||||
if (ec == asio::error::operation_aborted)
|
||||
return;
|
||||
else if (ec){
|
||||
if (logger)
|
||||
logger->e("[connection:%i] timeout error: %s", id, ec.message().c_str());
|
||||
}
|
||||
if (cb)
|
||||
cb(ec);
|
||||
});
|
||||
}
|
||||
|
||||
// Resolver
|
||||
|
||||
Resolver::Resolver(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger)
|
||||
: url_(url), resolver_(ctx), destroyed_(std::make_shared<bool>(false)), logger_(logger)
|
||||
{
|
||||
resolve(url_.host, url_.service);
|
||||
}
|
||||
|
||||
Resolver::Resolver(asio::io_context& ctx, const std::string& host, const std::string& service,
|
||||
const bool ssl, std::shared_ptr<dht::Logger> logger)
|
||||
: resolver_(ctx), destroyed_(std::make_shared<bool>(false)), logger_(logger)
|
||||
{
|
||||
url_.host = host;
|
||||
url_.service = service;
|
||||
url_.protocol = (ssl ? "https" : "http");
|
||||
resolve(url_.host, url_.service);
|
||||
}
|
||||
|
||||
Resolver::Resolver(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint> endpoints, const bool ssl,
|
||||
std::shared_ptr<dht::Logger> logger)
|
||||
: resolver_(ctx), destroyed_(std::make_shared<bool>(false)), logger_(logger)
|
||||
{
|
||||
url_.protocol = (ssl ? "https" : "http");
|
||||
endpoints_ = std::move(endpoints);
|
||||
completed_ = true;
|
||||
}
|
||||
|
||||
Resolver::~Resolver()
|
||||
{
|
||||
decltype(cbs_) cbs;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
cbs = std::move(cbs_);
|
||||
}
|
||||
while (not cbs.empty()){
|
||||
auto cb = cbs.front();
|
||||
if (cb)
|
||||
cb(asio::error::operation_aborted, {});
|
||||
cbs.pop();
|
||||
}
|
||||
*destroyed_ = true;
|
||||
}
|
||||
|
||||
inline
|
||||
std::vector<asio::ip::tcp::endpoint>
|
||||
filter(const std::vector<asio::ip::tcp::endpoint>& epts, sa_family_t family)
|
||||
{
|
||||
if (family == AF_UNSPEC)
|
||||
return epts;
|
||||
std::vector<asio::ip::tcp::endpoint> ret;
|
||||
for (const auto& ep : epts) {
|
||||
if (family == AF_INET && ep.address().is_v4())
|
||||
ret.emplace_back(ep);
|
||||
else if (family == AF_INET6 && ep.address().is_v6())
|
||||
ret.emplace_back(ep);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
Resolver::add_callback(ResolverCb cb, sa_family_t family)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (!completed_)
|
||||
cbs_.emplace(family == AF_UNSPEC ? std::move(cb) : [cb, family](const asio::error_code& ec, const std::vector<asio::ip::tcp::endpoint>& endpoints){
|
||||
if (ec)
|
||||
cb(ec, endpoints);
|
||||
else
|
||||
cb(ec, filter(endpoints, family));
|
||||
});
|
||||
else
|
||||
cb(ec_, family == AF_UNSPEC ? endpoints_ : filter(endpoints_, family));
|
||||
}
|
||||
|
||||
void
|
||||
Resolver::resolve(const std::string& host, const std::string& service)
|
||||
{
|
||||
asio::ip::tcp::resolver::query query_(host, service);
|
||||
|
||||
resolver_.async_resolve(query_, [this, host, service, destroyed = destroyed_]
|
||||
(const asio::error_code& ec, asio::ip::tcp::resolver::results_type endpoints)
|
||||
{
|
||||
if (ec == asio::error::operation_aborted or *destroyed)
|
||||
return;
|
||||
if (logger_){
|
||||
if (ec)
|
||||
logger_->e("[http:client] [resolver] error for %s:%s: %s",
|
||||
host.c_str(), service.c_str(), ec.message().c_str());
|
||||
}
|
||||
decltype(cbs_) cbs;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
ec_ = ec;
|
||||
endpoints_ = std::vector<asio::ip::tcp::endpoint>{endpoints.begin(), endpoints.end()};
|
||||
completed_ = true;
|
||||
cbs = std::move(cbs_);
|
||||
}
|
||||
while (not cbs.empty()){
|
||||
auto cb = cbs.front();
|
||||
if (cb)
|
||||
cb(ec, endpoints_);
|
||||
cbs.pop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Request
|
||||
|
||||
std::atomic_uint Request::ids_ {1};
|
||||
|
||||
|
||||
Request::Request(asio::io_context& ctx, const std::string& url, const Json::Value& json, OnJsonCb jsoncb,
|
||||
std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(std::move(logger)), id_(Request::ids_++), ctx_(ctx),
|
||||
resolver_(std::make_shared<Resolver>(ctx, url, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
set_header_field(restinio::http_field_t::content_type, HTTP_HEADER_CONTENT_TYPE_JSON);
|
||||
set_header_field(restinio::http_field_t::accept, HTTP_HEADER_CONTENT_TYPE_JSON);
|
||||
Json::StreamWriterBuilder wbuilder;
|
||||
set_method(restinio::http_method_post());
|
||||
set_body(Json::writeString(wbuilder, json));
|
||||
add_on_done_callback([this, jsoncb](const Response& response){
|
||||
Json::Value json;
|
||||
if (response.status_code != 0) {
|
||||
std::string err;
|
||||
Json::CharReaderBuilder rbuilder;
|
||||
auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader());
|
||||
if (!reader->parse(response.body.data(), response.body.data() + response.body.size(), &json, &err) and logger_)
|
||||
logger_->e("[http:request:%i] can't parse response to json", id_, err.c_str());
|
||||
}
|
||||
if (jsoncb)
|
||||
jsoncb(std::move(json), response.status_code);
|
||||
});
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, const std::string& url, std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(logger), id_(Request::ids_++), ctx_(ctx),
|
||||
resolver_(std::make_shared<Resolver>(ctx, url, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, const std::string& url, OnDoneCb onDone, std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(logger), id_(Request::ids_++), ctx_(ctx), resolver_(std::make_shared<Resolver>(ctx, url, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
add_on_done_callback(std::move(onDone));
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, const std::string& host, const std::string& service,
|
||||
const bool ssl, std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(logger), id_(Request::ids_++), ctx_(ctx),
|
||||
resolver_(std::make_shared<Resolver>(ctx, host, service, ssl, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, sa_family_t family)
|
||||
: logger_(resolver->getLogger()), id_(Request::ids_++), ctx_(ctx), family_(family), resolver_(resolver)
|
||||
{
|
||||
init_default_headers();
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, std::vector<asio::ip::tcp::endpoint>&& endpoints, const bool ssl,
|
||||
std::shared_ptr<dht::Logger> logger)
|
||||
: logger_(logger), id_(Request::ids_++), ctx_(ctx),
|
||||
resolver_(std::make_shared<Resolver>(ctx, std::move(endpoints), ssl, logger))
|
||||
{
|
||||
init_default_headers();
|
||||
}
|
||||
|
||||
Request::Request(asio::io_context& ctx, std::shared_ptr<Resolver> resolver, const std::string& target, sa_family_t family)
|
||||
: logger_(resolver->getLogger()), id_(Request::ids_++), ctx_(ctx), family_(family), resolver_(resolver)
|
||||
{
|
||||
set_header_field(restinio::http_field_t::host, get_url().host + ":" + get_url().service);
|
||||
set_target(target);
|
||||
}
|
||||
|
||||
Request::~Request()
|
||||
{
|
||||
resolver_.reset();
|
||||
terminate(asio::error::connection_aborted);
|
||||
}
|
||||
|
||||
void
|
||||
Request::init_default_headers()
|
||||
{
|
||||
const auto& url = resolver_->get_url();
|
||||
set_header_field(restinio::http_field_t::user_agent, "Mozilla/5.0");
|
||||
set_header_field(restinio::http_field_t::accept, "text/html");
|
||||
set_target(url.target);
|
||||
}
|
||||
|
||||
void
|
||||
Request::cancel()
|
||||
{
|
||||
if (auto c = conn_)
|
||||
c->close();
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_connection(std::shared_ptr<Connection> connection) {
|
||||
conn_ = std::move(connection);
|
||||
}
|
||||
|
||||
std::shared_ptr<Connection>
|
||||
Request::get_connection() const {
|
||||
return conn_;
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_certificate_authority(std::shared_ptr<dht::crypto::Certificate> certificate) {
|
||||
server_ca_ = certificate;
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_identity(const dht::crypto::Identity& identity) {
|
||||
client_identity_ = identity;
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_logger(std::shared_ptr<dht::Logger> logger) {
|
||||
logger_ = logger;
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_header(restinio::http_request_header_t header)
|
||||
{
|
||||
header_ = header;
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_method(restinio::http_method_id_t method) {
|
||||
header_.method(method);
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_target(std::string target) {
|
||||
header_.request_target(std::move(target));
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_header_field(restinio::http_field_t field, std::string value) {
|
||||
headers_[field] = std::move(value);
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_connection_type(restinio::http_connection_header_t connection) {
|
||||
connection_type_ = connection;
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_body(std::string body) {
|
||||
body_ = std::move(body);
|
||||
}
|
||||
|
||||
void
|
||||
Request::set_auth(const std::string& username, const std::string& password)
|
||||
{
|
||||
std::vector<uint8_t> creds;
|
||||
creds.reserve(username.size() + password.size() + 1);
|
||||
creds.insert(creds.end(), username.begin(), username.end());
|
||||
creds.emplace_back(':');
|
||||
creds.insert(creds.end(), password.begin(), password.end());
|
||||
set_header_field(restinio::http_field_t::authorization, "Basic " + base64_encode(creds));
|
||||
}
|
||||
|
||||
void
|
||||
Request::build()
|
||||
{
|
||||
std::stringstream request;
|
||||
bool append_body = !body_.empty();
|
||||
|
||||
// first header
|
||||
request << header_.method().c_str() << " " << header_.request_target() << " " <<
|
||||
"HTTP/" << header_.http_major() << "." << header_.http_minor() << "\r\n";
|
||||
|
||||
// other headers
|
||||
for (auto header: headers_){
|
||||
request << restinio::field_to_string(header.first) << ": " << header.second << "\r\n";
|
||||
if (header.first == restinio::http_field_t::expect and header.second == "100-continue")
|
||||
append_body = false;
|
||||
}
|
||||
|
||||
// last connection header
|
||||
const char* conn_str = nullptr;
|
||||
switch (connection_type_){
|
||||
case restinio::http_connection_header_t::keep_alive:
|
||||
conn_str = "keep-alive";
|
||||
break;
|
||||
case restinio::http_connection_header_t::upgrade:
|
||||
if (logger_)
|
||||
logger_->e("Unsupported connection type 'upgrade', fallback to 'close'");
|
||||
// fallthrough
|
||||
case restinio::http_connection_header_t::close:
|
||||
conn_str = "close"; // default
|
||||
break;
|
||||
}
|
||||
if (conn_str)
|
||||
request << "Connection: " << conn_str << "\r\n";
|
||||
|
||||
// body & content-length
|
||||
if (append_body) {
|
||||
request << "Content-Length: " << body_.size() << "\r\n\r\n"
|
||||
<< body_;
|
||||
} else
|
||||
request << "\r\n";
|
||||
request_ = request.str();
|
||||
}
|
||||
|
||||
void
|
||||
Request::add_on_status_callback(OnStatusCb cb) {
|
||||
cbs_.on_status = std::move(cb);
|
||||
}
|
||||
|
||||
void
|
||||
Request::add_on_body_callback(OnDataCb cb) {
|
||||
cbs_.on_body = std::move(cb);
|
||||
}
|
||||
|
||||
void
|
||||
Request::add_on_state_change_callback(OnStateChangeCb cb) {
|
||||
cbs_.on_state_change = std::move(cb);
|
||||
}
|
||||
|
||||
void
|
||||
Request::add_on_done_callback(OnDoneCb cb) {
|
||||
add_on_state_change_callback([onDone=std::move(cb)](State state, const Response& response){
|
||||
if (state == Request::State::DONE)
|
||||
onDone(response);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
Request::notify_state_change(State state) {
|
||||
state_ = state;
|
||||
if (cbs_.on_state_change)
|
||||
cbs_.on_state_change(state, response_);
|
||||
}
|
||||
|
||||
void
|
||||
Request::init_parser()
|
||||
{
|
||||
if (!parser_)
|
||||
parser_ = std::make_unique<http_parser>();
|
||||
http_parser_init(parser_.get(), HTTP_RESPONSE);
|
||||
parser_->data = static_cast<void*>(this);
|
||||
|
||||
if (!parser_s_)
|
||||
parser_s_ = std::make_unique<http_parser_settings>();
|
||||
http_parser_settings_init(parser_s_.get());
|
||||
|
||||
cbs_.on_status = [this, statusCb = std::move(cbs_.on_status)](unsigned int status_code){
|
||||
response_.status_code = status_code;
|
||||
if (statusCb)
|
||||
statusCb(status_code);
|
||||
};
|
||||
auto header_field = std::make_shared<std::string>();
|
||||
cbs_.on_header_field = [header_field](const char* at, size_t length) {
|
||||
*header_field = std::string(at, length);
|
||||
};
|
||||
cbs_.on_header_value = [this, header_field](const char* at, size_t length) {
|
||||
response_.headers[*header_field] = std::string(at, length);
|
||||
};
|
||||
|
||||
// http_parser raw c callback (note: no context can be passed into them)
|
||||
parser_s_->on_status = [](http_parser* parser, const char* /*at*/, size_t /*length*/) -> int {
|
||||
static_cast<Request*>(parser->data)->cbs_.on_status(parser->status_code);
|
||||
return 0;
|
||||
};
|
||||
parser_s_->on_header_field = [](http_parser* parser, const char* at, size_t length) -> int {
|
||||
static_cast<Request*>(parser->data)->cbs_.on_header_field(at, length);
|
||||
return 0;
|
||||
};
|
||||
parser_s_->on_header_value = [](http_parser* parser, const char* at, size_t length) -> int {
|
||||
static_cast<Request*>(parser->data)->cbs_.on_header_value(at, length);
|
||||
return 0;
|
||||
};
|
||||
parser_s_->on_body = [](http_parser* parser, const char* at, size_t length) -> int {
|
||||
static_cast<Request*>(parser->data)->onBody(at, length);
|
||||
return 0;
|
||||
};
|
||||
parser_s_->on_headers_complete = [](http_parser* parser) -> int {
|
||||
static_cast<Request*>(parser->data)->onHeadersComplete();
|
||||
return 0;
|
||||
};
|
||||
parser_s_->on_message_complete = [](http_parser* parser) -> int {
|
||||
static_cast<Request*>(parser->data)->onComplete();
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
Request::connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb)
|
||||
{
|
||||
if (endpoints.empty()){
|
||||
if (logger_)
|
||||
logger_->e("[http:request:%i] connect: no endpoints provided", id_);
|
||||
if (cb)
|
||||
cb(asio::error::connection_aborted);
|
||||
return;
|
||||
}
|
||||
if (logger_){
|
||||
std::string eps = "";
|
||||
for (const auto& endpoint : endpoints)
|
||||
eps.append(endpoint.address().to_string() + ":" + std::to_string(endpoint.port()) + " ");
|
||||
logger_->d("[http:request:%i] connect begin: %s", id_, eps.c_str());
|
||||
}
|
||||
if (get_url().protocol == "https"){
|
||||
if (server_ca_)
|
||||
conn_ = std::make_shared<Connection>(ctx_, server_ca_, client_identity_, logger_);
|
||||
else
|
||||
conn_ = std::make_shared<Connection>(ctx_, true/*ssl*/, logger_);
|
||||
}
|
||||
else
|
||||
conn_ = std::make_shared<Connection>(ctx_, false/*ssl*/, logger_);
|
||||
|
||||
// try to connect to any until one works
|
||||
std::weak_ptr<Request> wthis = shared_from_this();
|
||||
conn_->async_connect(std::move(endpoints), [wthis, cb]
|
||||
(const asio::error_code& ec, const asio::ip::tcp::endpoint& endpoint){
|
||||
auto sthis = wthis.lock();
|
||||
if (not sthis)
|
||||
return;
|
||||
auto& this_ = *sthis;
|
||||
if (ec == asio::error::operation_aborted){
|
||||
this_.terminate(ec);
|
||||
return;
|
||||
}
|
||||
else if (ec) {
|
||||
if (this_.logger_)
|
||||
this_.logger_->e("[http:request:%i] connect failed with all endpoints: %s", this_.id_, ec.message().c_str());
|
||||
} else {
|
||||
// if (this_.logger_)
|
||||
// this_.logger_->d("[http:request:%i] connect success", this_.id_);
|
||||
|
||||
const auto& url = this_.get_url();
|
||||
auto port = endpoint.port();
|
||||
if ((url.protocol == "http" && port == (in_port_t)80)
|
||||
|| (url.protocol == "https" && port == (in_port_t)443))
|
||||
this_.set_header_field(restinio::http_field_t::host, url.host);
|
||||
else
|
||||
this_.set_header_field(restinio::http_field_t::host, url.host + ":" + std::to_string(port));
|
||||
|
||||
if (url.protocol == "https") {
|
||||
if (this_.server_ca_)
|
||||
this_.conn_->set_ssl_verification(endpoint, asio::ssl::verify_peer
|
||||
| asio::ssl::verify_fail_if_no_peer_cert);
|
||||
|
||||
if (this_.conn_ and this_.conn_->is_open() and this_.conn_->is_ssl()){
|
||||
this_.conn_->async_handshake([id = this_.id_, cb, logger = this_.logger_](const asio::error_code& ec){
|
||||
if (ec == asio::error::operation_aborted)
|
||||
return;
|
||||
if (ec and logger)
|
||||
logger->e("[http:request:%i] handshake error: %s", id, ec.message().c_str());
|
||||
//else if (logger)
|
||||
// logger->d("[http:request:%i] handshake success", id);
|
||||
if (cb)
|
||||
cb(ec);
|
||||
});
|
||||
}
|
||||
else if (cb)
|
||||
cb(asio::error::operation_aborted);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (cb)
|
||||
cb(ec);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
Request::send()
|
||||
{
|
||||
notify_state_change(State::CREATED);
|
||||
|
||||
std::weak_ptr<Request> wthis = shared_from_this();
|
||||
resolver_->add_callback([wthis](const asio::error_code& ec,
|
||||
std::vector<asio::ip::tcp::endpoint> endpoints) {
|
||||
if (auto sthis = wthis.lock()) {
|
||||
auto& this_ = *sthis;
|
||||
if (ec){
|
||||
if (this_.logger_)
|
||||
this_.logger_->e("[http:request:%i] resolve error: %s", this_.id_, ec.message().c_str());
|
||||
this_.terminate(asio::error::connection_aborted);
|
||||
}
|
||||
else if (!this_.conn_ or !this_.conn_->is_open()) {
|
||||
this_.connect(std::move(endpoints), [wthis](const asio::error_code &ec) {
|
||||
if (auto sthis = wthis.lock()) {
|
||||
if (ec)
|
||||
sthis->terminate(asio::error::not_connected);
|
||||
else
|
||||
sthis->post();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
this_.post();
|
||||
}
|
||||
}, family_);
|
||||
}
|
||||
|
||||
void
|
||||
Request::post()
|
||||
{
|
||||
if (!conn_ or !conn_->is_open()){
|
||||
terminate(asio::error::not_connected);
|
||||
return;
|
||||
}
|
||||
build();
|
||||
init_parser();
|
||||
|
||||
if (logger_)
|
||||
logger_->d("[http:request:%i] sending %zu bytes", id_, request_.size());
|
||||
|
||||
// write the request to buffer
|
||||
std::ostream request_stream(&conn_->input());
|
||||
request_stream << request_;
|
||||
|
||||
// send the request
|
||||
notify_state_change(State::SENDING);
|
||||
|
||||
std::weak_ptr<Request> wthis = shared_from_this();
|
||||
conn_->async_write([wthis](const asio::error_code& ec, size_t) {
|
||||
if (auto sthis = wthis.lock())
|
||||
sthis->handle_request(ec);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
Request::terminate(const asio::error_code& ec)
|
||||
{
|
||||
if (finishing_.exchange(true))
|
||||
return;
|
||||
|
||||
response_.aborted = ec == asio::error::operation_aborted;
|
||||
|
||||
if (logger_) {
|
||||
if (ec and ec != asio::error::eof and ec != asio::error::operation_aborted)
|
||||
logger_->e("[http:request:%i] end with error: %s", id_, ec.message().c_str());
|
||||
else
|
||||
logger_->d("[http:request:%i] done with status code %u", id_, response_.status_code);
|
||||
}
|
||||
|
||||
if (!parser_ or !http_should_keep_alive(parser_.get()))
|
||||
if (auto c = conn_)
|
||||
c->close();
|
||||
notify_state_change(State::DONE);
|
||||
}
|
||||
|
||||
void
|
||||
Request::handle_request(const asio::error_code& ec)
|
||||
{
|
||||
if (ec and ec != asio::error::eof){
|
||||
terminate(ec);
|
||||
return;
|
||||
}
|
||||
if (!conn_->is_open()){
|
||||
terminate(asio::error::not_connected);
|
||||
return;
|
||||
}
|
||||
// if (logger_)
|
||||
// logger_->d("[http:request:%i] send success", id_);
|
||||
// read response
|
||||
notify_state_change(State::RECEIVING);
|
||||
|
||||
std::weak_ptr<Request> wthis = shared_from_this();
|
||||
conn_->async_read_until(HTTP_HEADER_DELIM, [wthis](const asio::error_code& ec, size_t n_bytes){
|
||||
if (auto sthis = wthis.lock())
|
||||
sthis->handle_response(ec, n_bytes);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
Request::handle_response(const asio::error_code& ec, size_t n_bytes)
|
||||
{
|
||||
if (ec && ec != asio::error::eof){
|
||||
terminate(ec);
|
||||
return;
|
||||
}
|
||||
auto request = (ec == asio::error::eof) ? std::string{} : conn_->read_bytes();
|
||||
size_t ret = http_parser_execute(parser_.get(), parser_s_.get(), request.c_str(), request.size());
|
||||
if (ret != request.size()) {
|
||||
if (logger_)
|
||||
logger_->e("Error parsing HTTP: %zu %s %s", ret,
|
||||
http_errno_name(HTTP_PARSER_ERRNO(parser_)),
|
||||
http_errno_description(HTTP_PARSER_ERRNO(parser_)));
|
||||
terminate(asio::error::basic_errors::broken_pipe);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ != State::DONE and parser_ and not http_body_is_final(parser_.get())) {
|
||||
auto toRead = parser_->content_length ? std::min<uint64_t>(parser_->content_length, 64 * 1024) : 64 * 1024;
|
||||
std::weak_ptr<Request> wthis = shared_from_this();
|
||||
conn_->async_read_some(toRead, [wthis](const asio::error_code& ec, size_t bytes){
|
||||
if (auto sthis = wthis.lock())
|
||||
sthis->handle_response(ec, bytes);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Request::onBody(const char* at, size_t length)
|
||||
{
|
||||
if (cbs_.on_body)
|
||||
cbs_.on_body(at, length);
|
||||
else
|
||||
response_.body.insert(response_.body.end(), at, at+length);
|
||||
}
|
||||
|
||||
void
|
||||
Request::onComplete() {
|
||||
terminate(asio::error::eof);
|
||||
}
|
||||
|
||||
void
|
||||
Request::onHeadersComplete() {
|
||||
notify_state_change(State::HEADER_RECEIVED);
|
||||
|
||||
auto expect_it = headers_.find(restinio::http_field_t::expect);
|
||||
if (expect_it != headers_.end() and (expect_it->second == "100-continue") and response_.status_code != 200){
|
||||
notify_state_change(State::SENDING);
|
||||
request_.append(body_);
|
||||
std::ostream request_stream(&conn_->input());
|
||||
request_stream << body_ << "\r\n";
|
||||
std::weak_ptr<Request> wthis = shared_from_this();
|
||||
conn_->async_write([wthis](const asio::error_code& ec, size_t) {
|
||||
if (auto sthis = wthis.lock())
|
||||
sthis->handle_request(ec);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace http
|
||||
} // namespace dht
|
||||
+29
-11
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "log.h"
|
||||
#include "dhtrunner.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <syslog.h>
|
||||
@@ -55,9 +56,9 @@ printLog(std::ostream& s, char const *m, va_list args) {
|
||||
s << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
enableLogging(dht::DhtRunner &dht) {
|
||||
dht.setLoggers(
|
||||
std::shared_ptr<Logger>
|
||||
getStdLogger() {
|
||||
return std::make_shared<Logger>(
|
||||
[](char const *m, va_list args) {
|
||||
std::cerr << red;
|
||||
printLog(std::cerr, m, args);
|
||||
@@ -72,20 +73,20 @@ enableLogging(dht::DhtRunner &dht) {
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
enableFileLogging(dht::DhtRunner &dht, const std::string &path) {
|
||||
auto logfile = std::make_shared<std::fstream>();
|
||||
std::shared_ptr<Logger>
|
||||
getFileLogger(const std::string &path) {
|
||||
auto logfile = std::make_shared<std::ofstream>();
|
||||
logfile->open(path, std::ios::out);
|
||||
|
||||
dht.setLoggers(
|
||||
return std::make_shared<Logger>(
|
||||
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
|
||||
[=](char const *m, va_list args) { printLog(*logfile, m, args); },
|
||||
[=](char const *m, va_list args) { printLog(*logfile, m, args); }
|
||||
);
|
||||
}
|
||||
|
||||
OPENDHT_PUBLIC void
|
||||
enableSyslog(dht::DhtRunner &dht, const char* name) {
|
||||
std::shared_ptr<Logger>
|
||||
getSyslogLogger(const char* name) {
|
||||
#ifndef _WIN32
|
||||
struct Syslog {
|
||||
Syslog(const char* n) {
|
||||
@@ -102,17 +103,34 @@ enableSyslog(dht::DhtRunner &dht, const char* name) {
|
||||
logfile = std::make_shared<Syslog>(name);
|
||||
opened_logfile = logfile;
|
||||
}
|
||||
dht.setLoggers(
|
||||
return std::make_shared<Logger>(
|
||||
[logfile](char const *m, va_list args) { vsyslog(LOG_ERR, m, args); },
|
||||
[logfile](char const *m, va_list args) { vsyslog(LOG_WARNING, m, args); },
|
||||
[logfile](char const *m, va_list args) { vsyslog(LOG_INFO, m, args); }
|
||||
);
|
||||
#else
|
||||
return std::make_shared<Logger>();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
enableLogging(dht::DhtRunner &dht) {
|
||||
dht.setLogger(*getStdLogger());
|
||||
}
|
||||
|
||||
void
|
||||
enableFileLogging(dht::DhtRunner &dht, const std::string &path) {
|
||||
dht.setLogger(*getFileLogger(path));
|
||||
}
|
||||
|
||||
OPENDHT_PUBLIC void
|
||||
enableSyslog(dht::DhtRunner &dht, const char* name) {
|
||||
dht.setLogger(*getSyslogLogger(name));
|
||||
}
|
||||
|
||||
void
|
||||
disableLogging(dht::DhtRunner &dht) {
|
||||
dht.setLoggers(dht::NOLOG, dht::NOLOG, dht::NOLOG);
|
||||
dht.setLogger({});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+79
-147
@@ -17,7 +17,6 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "network_engine.h"
|
||||
#include "request.h"
|
||||
#include "default_types.h"
|
||||
@@ -26,17 +25,6 @@
|
||||
|
||||
#include <msgpack.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <ws2tcpip.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
@@ -53,40 +41,11 @@ constexpr std::chrono::seconds NetworkEngine::RX_MAX_PACKET_TIME;
|
||||
constexpr std::chrono::seconds NetworkEngine::RX_TIMEOUT;
|
||||
|
||||
const std::string NetworkEngine::my_v {"RNG1"};
|
||||
constexpr size_t NetworkEngine::MAX_REQUESTS_PER_SEC;
|
||||
|
||||
static const uint8_t v4prefix[16] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0
|
||||
};
|
||||
static constexpr uint8_t v4prefix[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0};
|
||||
|
||||
constexpr unsigned SEND_NODES {8};
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static bool
|
||||
set_nonblocking(int fd, int nonblocking)
|
||||
{
|
||||
unsigned long mode = !!nonblocking;
|
||||
int rc = ioctlsocket(fd, FIONBIO, &mode);
|
||||
return rc == 0;
|
||||
}
|
||||
|
||||
extern const char *inet_ntop(int, const void *, char *, socklen_t);
|
||||
|
||||
#else
|
||||
|
||||
static bool
|
||||
set_nonblocking(int fd, int nonblocking)
|
||||
{
|
||||
int rc = fcntl(fd, F_GETFL, 0);
|
||||
if (rc < 0)
|
||||
return false;
|
||||
rc = fcntl(fd, F_SETFL, nonblocking?(rc | O_NONBLOCK):(rc & ~O_NONBLOCK));
|
||||
return rc >= 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Transaction-ids are 4-bytes long, with the first two bytes identifying
|
||||
* the kind of request, and the remaining two a sequence number in
|
||||
@@ -139,11 +98,11 @@ RequestAnswer::RequestAnswer(ParsedMessage&& msg)
|
||||
nodes6(std::move(msg.nodes6))
|
||||
{}
|
||||
|
||||
NetworkEngine::NetworkEngine(Logger& log, Scheduler& scheduler, const int& s, const int& s6)
|
||||
: myid(zeroes), dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
|
||||
NetworkEngine::NetworkEngine(Logger& log, Scheduler& scheduler, std::unique_ptr<DatagramSocket>&& sock)
|
||||
: myid(zeroes), dht_socket(std::move(sock)), DHT_LOG(log), rate_limiter((size_t)-1), scheduler(scheduler)
|
||||
{}
|
||||
|
||||
NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, const int& s, const int& s6, Logger& log, Scheduler& scheduler,
|
||||
NetworkEngine::NetworkEngine(InfoHash& myid, NetworkConfig c, std::unique_ptr<DatagramSocket>&& sock, Logger& log, Scheduler& scheduler,
|
||||
decltype(NetworkEngine::onError)&& onError,
|
||||
decltype(NetworkEngine::onNewNode)&& onNewNode,
|
||||
decltype(NetworkEngine::onReportedAddr)&& onReportedAddr,
|
||||
@@ -162,17 +121,10 @@ NetworkEngine::NetworkEngine(InfoHash& myid, NetId net, const int& s, const int&
|
||||
onListen(std::move(onListen)),
|
||||
onAnnounce(std::move(onAnnounce)),
|
||||
onRefresh(std::move(onRefresh)),
|
||||
myid(myid), network(net), dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
|
||||
{
|
||||
if (dht_socket >= 0) {
|
||||
if (!set_nonblocking(dht_socket, 1))
|
||||
throw DhtException("Can't set socket to non-blocking mode");
|
||||
}
|
||||
if (dht_socket6 >= 0) {
|
||||
if (!set_nonblocking(dht_socket6, 1))
|
||||
throw DhtException("Can't set socket to non-blocking mode");
|
||||
}
|
||||
}
|
||||
myid(myid), config(c), dht_socket(std::move(sock)), DHT_LOG(log),
|
||||
rate_limiter(config.max_req_per_sec),
|
||||
scheduler(scheduler)
|
||||
{}
|
||||
|
||||
NetworkEngine::~NetworkEngine() {
|
||||
clear();
|
||||
@@ -197,7 +149,7 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&,
|
||||
{
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_U);
|
||||
pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0));
|
||||
@@ -214,12 +166,12 @@ NetworkEngine::tellListenerRefreshed(Sp<Node> n, Tid socket_id, const InfoHash&,
|
||||
pk.pack(KEY_TID); pk.pack(socket_id);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
// send response
|
||||
send(buffer.data(), buffer.size(), 0, n->getAddr());
|
||||
send(n->getAddr(), buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -227,7 +179,7 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c
|
||||
{
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_U);
|
||||
pk.pack_map(1 + (not values.empty()?1:0) + (not token.empty()?1:0));
|
||||
@@ -244,12 +196,12 @@ NetworkEngine::tellListenerExpired(Sp<Node> n, Tid socket_id, const InfoHash&, c
|
||||
pk.pack(KEY_TID); pk.pack(socket_id);
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
// send response
|
||||
send(buffer.data(), buffer.size(), 0, n->getAddr());
|
||||
send(n->getAddr(), buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -258,11 +210,11 @@ NetworkEngine::isRunning(sa_family_t af) const
|
||||
{
|
||||
switch (af) {
|
||||
case 0:
|
||||
return dht_socket >= 0 || dht_socket6 >= 0;
|
||||
return dht_socket->hasIPv4() or dht_socket->hasIPv6();
|
||||
case AF_INET:
|
||||
return dht_socket >= 0;
|
||||
return dht_socket->hasIPv4();
|
||||
case AF_INET6:
|
||||
return dht_socket6 >= 0;
|
||||
return dht_socket->hasIPv6();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -294,7 +246,7 @@ NetworkEngine::requestStep(Sp<Request> sreq)
|
||||
auto now = scheduler.time();
|
||||
auto& node = *req.node;
|
||||
if (req.isExpired(now)) {
|
||||
DHT_LOG.d(node.id, "[node %s] expired !", node.toString().c_str());
|
||||
// DHT_LOG.d(node.id, "[node %s] expired !", node.toString().c_str());
|
||||
node.setExpired();
|
||||
if (not node.id)
|
||||
requests.erase(req.tid);
|
||||
@@ -303,9 +255,7 @@ NetworkEngine::requestStep(Sp<Request> sreq)
|
||||
req.on_expired(req, false);
|
||||
}
|
||||
|
||||
auto err = send((char*)req.msg.data(), req.msg.size(),
|
||||
(node.getReplyTime() >= now - UDP_REPLY_TIME) ? 0 : MSG_CONFIRM,
|
||||
node.getAddr());
|
||||
auto err = send(node.getAddr(), (char*)req.msg.data(), req.msg.size(), node.getReplyTime() < now - UDP_REPLY_TIME);
|
||||
if (err == ENETUNREACH ||
|
||||
err == EHOSTUNREACH ||
|
||||
err == EAFNOSUPPORT ||
|
||||
@@ -335,11 +285,11 @@ NetworkEngine::requestStep(Sp<Request> sreq)
|
||||
void
|
||||
NetworkEngine::sendRequest(const Sp<Request>& request)
|
||||
{
|
||||
auto& node = request->node;
|
||||
if (not node->id)
|
||||
auto& node = *request->node;
|
||||
if (not node.id)
|
||||
requests.emplace(request->tid, request);
|
||||
request->start = scheduler.time();
|
||||
node->requested(request);
|
||||
node.requested(request);
|
||||
requestStep(request);
|
||||
}
|
||||
|
||||
@@ -351,7 +301,7 @@ NetworkEngine::rateLimit(const SockAddr& addr)
|
||||
const auto& now = scheduler.time();
|
||||
|
||||
// occasional IP limiter maintenance (a few times every second at max rate)
|
||||
if (limiter_maintenance++ == MAX_REQUESTS_PER_SEC/8) {
|
||||
if (limiter_maintenance++ == config.max_peer_req_per_sec) {
|
||||
for (auto it = address_rate_limiter.begin(); it != address_rate_limiter.end();) {
|
||||
if (it->second.maintain(now) == 0)
|
||||
address_rate_limiter.erase(it++);
|
||||
@@ -362,7 +312,11 @@ NetworkEngine::rateLimit(const SockAddr& addr)
|
||||
}
|
||||
|
||||
// invoke per IP, then global rate limiter
|
||||
return address_rate_limiter[addr].limit(now) and rate_limiter.limit(now);
|
||||
return (config.max_peer_req_per_sec < 0
|
||||
or address_rate_limiter
|
||||
.emplace(addr, config.max_peer_req_per_sec).first->second
|
||||
.limit(now))
|
||||
and rate_limiter.limit(now);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -408,8 +362,9 @@ NetworkEngine::isNodeBlacklisted(const SockAddr& addr) const
|
||||
}
|
||||
|
||||
void
|
||||
NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const SockAddr& from)
|
||||
NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, SockAddr f)
|
||||
{
|
||||
auto from = f.getMappedIPv4();
|
||||
if (isMartian(from)) {
|
||||
DHT_LOG.w("Received packet from martian node %s", from.toString().c_str());
|
||||
return;
|
||||
@@ -430,8 +385,8 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const SockAddr&
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->network != network) {
|
||||
DHT_LOG.d("Received message from other network %u", msg->network);
|
||||
if (msg->network != config.network) {
|
||||
DHT_LOG.d("Received message from other config.network %u", msg->network);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -526,7 +481,8 @@ NetworkEngine::process(std::unique_ptr<ParsedMessage>&& msg, const SockAddr& fro
|
||||
node->received(now, req);
|
||||
if (not node->isClient())
|
||||
onNewNode(node, 1);
|
||||
throw DhtProtocolException {DhtProtocolException::UNKNOWN_TID, "Can't find transaction", msg->id};
|
||||
DHT_LOG.d(node->id, "[node %s] can't find transaction with id %u", node->toString().c_str(), msg->tid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,33 +615,9 @@ insertAddr(msgpack::packer<msgpack::sbuffer>& pk, const SockAddr& addr)
|
||||
}
|
||||
|
||||
int
|
||||
NetworkEngine::send(const char *buf, size_t len, int flags, const SockAddr& addr)
|
||||
NetworkEngine::send(const SockAddr& addr, const char *buf, size_t len, bool confirmed)
|
||||
{
|
||||
if (not addr)
|
||||
return EFAULT;
|
||||
|
||||
int s;
|
||||
if (addr.getFamily() == AF_INET)
|
||||
s = dht_socket;
|
||||
else if (addr.getFamily() == AF_INET6)
|
||||
s = dht_socket6;
|
||||
else
|
||||
s = -1;
|
||||
|
||||
if (s < 0)
|
||||
return EAFNOSUPPORT;
|
||||
#ifdef MSG_NOSIGNAL
|
||||
flags |= MSG_NOSIGNAL;
|
||||
#endif
|
||||
if (sendto(s, buf, len, flags, addr.get(), addr.getLength()) == -1) {
|
||||
int err = errno;
|
||||
DHT_LOG.e("Can't send message to %s: %s", addr.toString().c_str(), strerror(err));
|
||||
if (err == EPIPE) {
|
||||
throw SocketException(EPIPE);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
return dht_socket ? dht_socket->sendTo(addr, (const uint8_t*)buf, len, confirmed) : ENOTCONN;
|
||||
}
|
||||
|
||||
Sp<Request>
|
||||
@@ -693,7 +625,7 @@ NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& o
|
||||
TransId tid (node->getNewTid());
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_A); pk.pack_map(1);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
@@ -703,8 +635,8 @@ NetworkEngine::sendPing(Sp<Node> node, RequestCb&& on_done, RequestExpiredCb&& o
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::Ping, tid.toInt(), node,
|
||||
@@ -730,7 +662,7 @@ void
|
||||
NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_R); pk.pack_map(2);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
@@ -741,11 +673,11 @@ NetworkEngine::sendPong(const SockAddr& addr, Tid tid) {
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
send(addr, buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
Sp<Request>
|
||||
@@ -754,7 +686,7 @@ NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
|
||||
TransId tid (n->getNewTid());
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_A); pk.pack_map(2 + (want>0?1:0));
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
@@ -771,8 +703,8 @@ NetworkEngine::sendFindNode(Sp<Node> n, const InfoHash& target, want_t want,
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::FindNode, tid.toInt(), n,
|
||||
@@ -800,7 +732,7 @@ NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query&
|
||||
TransId tid (n->getNewTid());
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_A); pk.pack_map(2 +
|
||||
(query.where.getFilter() or not query.select.getSelection().empty() ? 1:0) +
|
||||
@@ -820,8 +752,8 @@ NetworkEngine::sendGetValues(Sp<Node> n, const InfoHash& info_hash, const Query&
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::GetValues, tid.toInt(), n,
|
||||
@@ -935,9 +867,9 @@ NetworkEngine::sendValueParts(const TransId& tid, const std::vector<Blob>& svals
|
||||
end = std::min(start + MTU, v.size());
|
||||
buffer.clear();
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(3+(network?1:0));
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
pk.pack_map(3+(config.network?1:0));
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
pk.pack(KEY_Y); pk.pack(KEY_V);
|
||||
pk.pack(KEY_TID); pk.pack_bin(tid.size());
|
||||
@@ -947,7 +879,7 @@ NetworkEngine::sendValueParts(const TransId& tid, const std::vector<Blob>& svals
|
||||
pk.pack(std::string("o")); pk.pack(start);
|
||||
pk.pack(std::string("d")); pk.pack_bin(end-start);
|
||||
pk.pack_bin_body((const char*)v.data()+start, end-start);
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
send(addr, buffer.data(), buffer.size());
|
||||
start = end;
|
||||
} while (start != v.size());
|
||||
i++;
|
||||
@@ -960,7 +892,7 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
|
||||
{
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_R);
|
||||
pk.pack_map(2 + (not st.empty()?1:0) + (nodes.size()>0?1:0) + (nodes6.size()>0?1:0) + (not token.empty()?1:0));
|
||||
@@ -1001,12 +933,12 @@ NetworkEngine::sendNodesValues(const SockAddr& addr, Tid tid, const Blob& nodes,
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
// send response
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
send(addr, buffer.data(), buffer.size());
|
||||
|
||||
// send parts
|
||||
if (not svals.empty())
|
||||
@@ -1091,7 +1023,7 @@ NetworkEngine::sendListen(Sp<Node> n,
|
||||
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5+(config.network?1:0));
|
||||
|
||||
auto has_query = query.where.getFilter() or not query.select.getSelection().empty();
|
||||
pk.pack(KEY_A); pk.pack_map(4 + has_query);
|
||||
@@ -1109,8 +1041,8 @@ NetworkEngine::sendListen(Sp<Node> n,
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::Listen, tid.toInt(), n,
|
||||
@@ -1134,7 +1066,7 @@ void
|
||||
NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_R); pk.pack_map(2);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
@@ -1145,11 +1077,11 @@ NetworkEngine::sendListenConfirmation(const SockAddr& addr, Tid tid) {
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
send(addr, buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
Sp<Request>
|
||||
@@ -1164,7 +1096,7 @@ NetworkEngine::sendAnnounceValue(Sp<Node> n,
|
||||
TransId tid (n->getNewTid());
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_A); pk.pack_map((created < scheduler.time() ? 5 : 4));
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
@@ -1181,8 +1113,8 @@ NetworkEngine::sendAnnounceValue(Sp<Node> n,
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::AnnounceValue, tid.toInt(), n,
|
||||
@@ -1222,7 +1154,7 @@ NetworkEngine::sendRefreshValue(Sp<Node> n,
|
||||
TransId tid (n->getNewTid());
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_A); pk.pack_map(4);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
@@ -1235,8 +1167,8 @@ NetworkEngine::sendRefreshValue(Sp<Node> n,
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_Q);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
auto req = std::make_shared<Request>(MessageType::Refresh, tid.toInt(), n,
|
||||
@@ -1267,7 +1199,7 @@ void
|
||||
NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4+(config.network?1:0));
|
||||
|
||||
pk.pack(KEY_R); pk.pack_map(3);
|
||||
pk.pack(KEY_REQ_ID); pk.pack(myid);
|
||||
@@ -1279,11 +1211,11 @@ NetworkEngine::sendValueAnnounced(const SockAddr& addr, Tid tid, Value::Id vid)
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_R);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
send(addr, buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1311,11 +1243,11 @@ NetworkEngine::sendError(const SockAddr& addr,
|
||||
pk.pack_bin_body((const char*)t.data(), t.size());
|
||||
pk.pack(KEY_Y); pk.pack(KEY_E);
|
||||
pk.pack(KEY_UA); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(KEY_NETID); pk.pack(network);
|
||||
if (config.network) {
|
||||
pk.pack(KEY_NETID); pk.pack(config.network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, addr);
|
||||
send(addr, buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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
|
||||
* 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 "network_utils.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "utils.h"
|
||||
#include <io.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#define close(x) closesocket(x)
|
||||
#define write(s, b, f) send(s, b, (int)strlen(b), 0)
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace dht {
|
||||
namespace net {
|
||||
|
||||
int
|
||||
bindSocket(const SockAddr& addr, SockAddr& bound)
|
||||
{
|
||||
bool is_ipv6 = addr.getFamily() == AF_INET6;
|
||||
int sock = socket(is_ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
throw DhtException(std::string("Can't open socket: ") + strerror(sock));
|
||||
int set = 1;
|
||||
#ifdef SO_NOSIGPIPE
|
||||
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&set, sizeof(set));
|
||||
#endif
|
||||
if (is_ipv6)
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&set, sizeof(set));
|
||||
net::setNonblocking(sock);
|
||||
int rc = bind(sock, addr.get(), addr.getLength());
|
||||
if (rc < 0) {
|
||||
rc = errno;
|
||||
close(sock);
|
||||
throw DhtException("Can't bind socket on " + addr.toString() + " " + strerror(rc));
|
||||
}
|
||||
sockaddr_storage ss;
|
||||
socklen_t ss_len = sizeof(ss);
|
||||
getsockname(sock, (sockaddr*)&ss, &ss_len);
|
||||
bound = {ss, ss_len};
|
||||
return sock;
|
||||
}
|
||||
|
||||
bool
|
||||
setNonblocking(int fd, bool nonblocking)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
unsigned long mode = !!nonblocking;
|
||||
int rc = ioctlsocket(fd, FIONBIO, &mode);
|
||||
return rc == 0;
|
||||
#else
|
||||
int rc = fcntl(fd, F_GETFL, 0);
|
||||
if (rc < 0)
|
||||
return false;
|
||||
rc = fcntl(fd, F_SETFL, nonblocking ? (rc | O_NONBLOCK) : (rc & ~O_NONBLOCK));
|
||||
return rc >= 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void udpPipe(int fds[2])
|
||||
{
|
||||
int lst = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (lst < 0)
|
||||
throw DhtException(std::string("Can't open socket: ") + strerror(WSAGetLastError()));
|
||||
sockaddr_in inaddr;
|
||||
sockaddr addr;
|
||||
memset(&inaddr, 0, sizeof(inaddr));
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
inaddr.sin_family = AF_INET;
|
||||
inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
inaddr.sin_port = 0;
|
||||
int yes = 1;
|
||||
setsockopt(lst, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes));
|
||||
int rc = bind(lst, (sockaddr*)&inaddr, sizeof(inaddr));
|
||||
if (rc < 0) {
|
||||
close(lst);
|
||||
throw DhtException("Can't bind socket on " + print_addr((sockaddr*)&inaddr, sizeof(inaddr)) + " " + strerror(rc));
|
||||
}
|
||||
socklen_t len = sizeof(addr);
|
||||
getsockname(lst, &addr, &len);
|
||||
fds[0] = lst;
|
||||
fds[1] = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
connect(fds[1], &addr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
UdpSocket::UdpSocket(in_port_t port, const Logger& l) : logger(l) {
|
||||
SockAddr bind4;
|
||||
bind4.setFamily(AF_INET);
|
||||
bind4.setPort(port);
|
||||
SockAddr bind6;
|
||||
bind6.setFamily(AF_INET6);
|
||||
bind6.setPort(port);
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
openSockets(bind4, bind6);
|
||||
}
|
||||
|
||||
UdpSocket::UdpSocket(const SockAddr& bind4, const SockAddr& bind6, const Logger& l) : logger(l)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
openSockets(bind4, bind6);
|
||||
}
|
||||
|
||||
UdpSocket::~UdpSocket() {
|
||||
stop();
|
||||
if (rcv_thread.joinable())
|
||||
rcv_thread.join();
|
||||
}
|
||||
|
||||
int
|
||||
UdpSocket::sendTo(const SockAddr& dest, const uint8_t* data, size_t size, bool replied) {
|
||||
if (not dest)
|
||||
return EFAULT;
|
||||
|
||||
int s;
|
||||
switch (dest.getFamily()) {
|
||||
case AF_INET: s = s4; break;
|
||||
case AF_INET6: s = s6; break;
|
||||
default: s = -1; break;
|
||||
}
|
||||
|
||||
if (s < 0)
|
||||
return EAFNOSUPPORT;
|
||||
|
||||
int flags = 0;
|
||||
#ifdef MSG_CONFIRM
|
||||
if (replied)
|
||||
flags |= MSG_CONFIRM;
|
||||
#endif
|
||||
#ifdef MSG_NOSIGNAL
|
||||
flags |= MSG_NOSIGNAL;
|
||||
#endif
|
||||
|
||||
if (sendto(s, (const char*)data, size, flags, dest.get(), dest.getLength()) == -1) {
|
||||
int err = errno;
|
||||
logger.d("Can't send message to %s: %s", dest.toString().c_str(), strerror(err));
|
||||
if (err == EPIPE || err == ENOTCONN || err == ECONNRESET) {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
auto bind4 = std::move(bound4), bind6 = std::move(bound6);
|
||||
openSockets(bind4, bind6);
|
||||
return sendTo(dest, data, size, false);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
UdpSocket::openSockets(const SockAddr& bind4, const SockAddr& bind6)
|
||||
{
|
||||
stop();
|
||||
if (rcv_thread.joinable())
|
||||
rcv_thread.join();
|
||||
|
||||
int stopfds[2];
|
||||
#ifndef _WIN32
|
||||
auto status = pipe(stopfds);
|
||||
if (status == -1) {
|
||||
throw DhtException(std::string("Can't open pipe: ") + strerror(errno));
|
||||
}
|
||||
#else
|
||||
udpPipe(stopfds);
|
||||
#endif
|
||||
int stop_readfd = stopfds[0];
|
||||
|
||||
stopfd = stopfds[1];
|
||||
s4 = -1;
|
||||
s6 = -1;
|
||||
|
||||
bound4 = {};
|
||||
if (bind4) {
|
||||
try {
|
||||
s4 = bindSocket(bind4, bound4);
|
||||
} catch (const DhtException& e) {
|
||||
logger.e("Can't bind inet socket: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
bound6 = {};
|
||||
if (bind6) {
|
||||
if (bind6.getPort() == 0) {
|
||||
// Attempt to use the same port as IPv4 with IPv6
|
||||
if (auto p4 = bound4.getPort()) {
|
||||
auto b6 = bind6;
|
||||
b6.setPort(p4);
|
||||
try {
|
||||
s6 = bindSocket(b6, bound6);
|
||||
} catch (const DhtException& e) {
|
||||
logger.e("Can't bind inet6 socket: %s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (s6 == -1) {
|
||||
try {
|
||||
s6 = bindSocket(bind6, bound6);
|
||||
} catch (const DhtException& e) {
|
||||
logger.e("Can't bind inet6 socket: %s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s4 == -1 && s6 == -1) {
|
||||
throw DhtException("Can't bind socket");
|
||||
}
|
||||
|
||||
running = true;
|
||||
rcv_thread = std::thread([this, stop_readfd, ls4=s4, ls6=s6]() mutable {
|
||||
int selectFd = std::max({ls4, ls6, stop_readfd}) + 1;
|
||||
try {
|
||||
while (running) {
|
||||
fd_set readfds;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(stop_readfd, &readfds);
|
||||
if(ls4 >= 0)
|
||||
FD_SET(ls4, &readfds);
|
||||
if(ls6 >= 0)
|
||||
FD_SET(ls6, &readfds);
|
||||
|
||||
int rc = select(selectFd, &readfds, nullptr, nullptr, nullptr);
|
||||
if (rc < 0) {
|
||||
if (errno != EINTR) {
|
||||
logger.e("Select error: %s", strerror(errno));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
if (not running)
|
||||
break;
|
||||
|
||||
if (rc > 0) {
|
||||
std::array<uint8_t, 1024 * 64> buf;
|
||||
sockaddr_storage from;
|
||||
socklen_t from_len = sizeof(from);
|
||||
|
||||
if (FD_ISSET(stop_readfd, &readfds)) {
|
||||
if (recv(stop_readfd, (char*)buf.data(), buf.size(), 0) < 0) {
|
||||
logger.e("Got stop packet error: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ls4 >= 0 && FD_ISSET(ls4, &readfds))
|
||||
rc = recvfrom(ls4, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
|
||||
else if (ls6 >= 0 && FD_ISSET(ls6, &readfds))
|
||||
rc = recvfrom(ls6, (char*)buf.data(), buf.size(), 0, (sockaddr*)&from, &from_len);
|
||||
else
|
||||
continue;
|
||||
|
||||
if (rc > 0) {
|
||||
auto pkt = std::unique_ptr<ReceivedPacket>(new ReceivedPacket);
|
||||
pkt->data = {buf.begin(), buf.begin()+rc};
|
||||
pkt->from = {from, from_len};
|
||||
pkt->received = clock::now();
|
||||
onReceived(std::move(pkt));
|
||||
} else if (rc == -1) {
|
||||
logger.e("Error receiving packet: %s", strerror(errno));
|
||||
int err = errno;
|
||||
if (err == EPIPE || err == ENOTCONN || err == ECONNRESET) {
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
if (ls4 >= 0) {
|
||||
close(ls4);
|
||||
try {
|
||||
ls4 = bindSocket(bound4, bound4);
|
||||
} catch (const DhtException& e) {
|
||||
logger.e("Can't bind inet socket: %s", e.what());
|
||||
}
|
||||
}
|
||||
if (ls6 >= 0) {
|
||||
close(ls6);
|
||||
try {
|
||||
ls6 = bindSocket(bound6, bound6);
|
||||
} catch (const DhtException& e) {
|
||||
logger.e("Can't bind inet6 socket: %s", e.what());
|
||||
}
|
||||
}
|
||||
if (ls4 < 0 && ls6 < 0)
|
||||
break;
|
||||
s4 = ls4;
|
||||
s6 = ls6;
|
||||
selectFd = std::max({ls4, ls6, stop_readfd}) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
logger.e("Error in UdpSocket rx thread: %s", e.what());
|
||||
}
|
||||
if (ls4 >= 0)
|
||||
close(ls4);
|
||||
if (ls6 >= 0)
|
||||
close(ls6);
|
||||
if (stop_readfd != -1)
|
||||
close(stop_readfd);
|
||||
std::lock_guard<std::mutex> lk(lock);
|
||||
s4 = -1;
|
||||
s6 = -1;
|
||||
bound4 = {};
|
||||
bound6 = {};
|
||||
if (stopfd != -1)
|
||||
close(stopfd);
|
||||
stopfd = -1;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
UdpSocket::stop()
|
||||
{
|
||||
if (running.exchange(false)) {
|
||||
auto sfd = stopfd;
|
||||
if (sfd != -1 && write(sfd, "\0", 1) == -1) {
|
||||
logger.e("Can't write to stop fd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,13 @@ Node::Node(const InfoHash& id, const SockAddr& addr, bool client)
|
||||
transaction_id = std::uniform_int_distribution<Tid>{1}(rd);
|
||||
}
|
||||
|
||||
Node::Node(const InfoHash& id, SockAddr&& addr, bool client)
|
||||
: id(id), addr(std::move(addr)), is_client(client), sockets_()
|
||||
{
|
||||
thread_local crypto::random_device rd {};
|
||||
transaction_id = std::uniform_int_distribution<Tid>{1}(rd);
|
||||
}
|
||||
|
||||
/* This is our definition of a known-good node. */
|
||||
bool
|
||||
Node::isGood(time_point now) const
|
||||
|
||||
+3
-6
@@ -105,14 +105,11 @@ public:
|
||||
void onValuesExpired(const std::vector<Sp<Value>>& vals);
|
||||
|
||||
bool addListener(size_t token, const ValueCallback& cb, const Sp<Query>& q, const Value::Filter& filter) {
|
||||
listeners.emplace(token, LocalListener{q, filter, cb});
|
||||
auto cached = cache.get(filter);
|
||||
if (not cached.empty()) {
|
||||
auto ret = cb(cached, false);
|
||||
if (not ret)
|
||||
listeners.erase(token);
|
||||
return ret;
|
||||
if (not cached.empty() and not cb(cached, false)) {
|
||||
return false;
|
||||
}
|
||||
listeners.emplace(token, LocalListener{q, filter, cb});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 130 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user