mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
397 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b8baa85a3 | ||
|
|
73921b1024 | ||
|
|
ece140f18c | ||
|
|
5e42947fbd | ||
|
|
1bfb9b02f5 | ||
|
|
16a14c2b76 | ||
|
|
f6199c6c17 | ||
|
|
d7e7f06e88 | ||
|
|
4c4e856a1a | ||
|
|
07bbbbaf61 | ||
|
|
3236827781 | ||
|
|
0be664cc3d | ||
|
|
6cc6849ccc | ||
|
|
5d5cd71714 | ||
|
|
d248343517 | ||
|
|
64d800427f | ||
|
|
c4c896a833 | ||
|
|
b6b5bb3f75 | ||
|
|
5d69bb7383 | ||
|
|
76e222079a | ||
|
|
73abb9278d | ||
|
|
8fd843e7ce | ||
|
|
6a497a23d9 | ||
|
|
3ac74e1091 | ||
|
|
ef0fb48f1f | ||
|
|
414ef2bc3d | ||
|
|
ea791309ad | ||
|
|
706da6e431 | ||
|
|
ed116e7cea | ||
|
|
5b56f4007b | ||
|
|
e2071542bf | ||
|
|
cdb217b774 | ||
|
|
079798940b | ||
|
|
f1c24689bf | ||
|
|
1f9cf6ed7c | ||
|
|
43f218410f | ||
|
|
3fd9d5f641 | ||
|
|
f5ab8f2062 | ||
|
|
8774a8fbc2 | ||
|
|
6f4f0f03d2 | ||
|
|
00b5fdce03 | ||
|
|
baee6a0d91 | ||
|
|
ff44bcc489 | ||
|
|
c797ac4268 | ||
|
|
d22a76d4d1 | ||
|
|
a6642e0ebc | ||
|
|
3d4d260a34 | ||
|
|
8e4b9da97d | ||
|
|
2be80ba30f | ||
|
|
2e44c88d6c | ||
|
|
21eb1ce6c9 | ||
|
|
cdfd411df7 | ||
|
|
a6149ca90c | ||
|
|
642435486c | ||
|
|
fc84d6c4b7 | ||
|
|
aa4bddd6ec | ||
|
|
8ec12a1b65 | ||
|
|
0fbf552e95 | ||
|
|
09b1b120d7 | ||
|
|
557244bc3f | ||
|
|
24c5ed1cff | ||
|
|
32e55ebd0c | ||
|
|
ea3070d02b | ||
|
|
9aaba49a9f | ||
|
|
9b64be07a9 | ||
|
|
42c3c28ea7 | ||
|
|
9e9236badb | ||
|
|
560ebcec8d | ||
|
|
9b1fe4338b | ||
|
|
9188e3ad3f | ||
|
|
af65af5be9 | ||
|
|
2f0115c300 | ||
|
|
0646461342 | ||
|
|
ec30ec0996 | ||
|
|
cdecb7a43c | ||
|
|
aa9c1b66a0 | ||
|
|
846eac29dc | ||
|
|
0f9e3c5b33 | ||
|
|
aa27746982 | ||
|
|
d8a4954bf1 | ||
|
|
d40a029dae | ||
|
|
96d961c393 | ||
|
|
7b6814e32d | ||
|
|
6fee2d3536 | ||
|
|
636fc633d4 | ||
|
|
72a239838e | ||
|
|
a463dbc5fb | ||
|
|
016ae3b9e9 | ||
|
|
7d0d421724 | ||
|
|
83b5856a19 | ||
|
|
f617b27110 | ||
|
|
a91a0263cf | ||
|
|
80ffe13f3e | ||
|
|
1eb726c9bb | ||
|
|
1fa3ba8b42 | ||
|
|
b6bfd66a49 | ||
|
|
1be0e7ddaa | ||
|
|
2cac9b03ff | ||
|
|
f5f4190803 | ||
|
|
a14d554947 | ||
|
|
6d9e5147b5 | ||
|
|
841452cb9e | ||
|
|
9c76368dbc | ||
|
|
bd5122c6ea | ||
|
|
6643258618 | ||
|
|
bc3f02cb6b | ||
|
|
d848ae332a | ||
|
|
08ddc98303 | ||
|
|
a3344c4290 | ||
|
|
22c1ce3ea5 | ||
|
|
afb14e6782 | ||
|
|
e177363377 | ||
|
|
ce213934c9 | ||
|
|
af286ec52e | ||
|
|
f7f2b7607b | ||
|
|
60a282826c | ||
|
|
3eba599aec | ||
|
|
74d876f145 | ||
|
|
d7609f119c | ||
|
|
65c2c7d80b | ||
|
|
468a32a819 | ||
|
|
b89cf73ae2 | ||
|
|
9cf43dea1a | ||
|
|
670ffe2078 | ||
|
|
884cf756ed | ||
|
|
e44ba54857 | ||
|
|
3712749a94 | ||
|
|
6569c4aa03 | ||
|
|
d6b2b3c996 | ||
|
|
06c7900ece | ||
|
|
52a6a12a9a | ||
|
|
e647603dce | ||
|
|
dadf6174ba | ||
|
|
84de7675c4 | ||
|
|
6311a80d0e | ||
|
|
9504e69598 | ||
|
|
5398b651f7 | ||
|
|
b5596c4596 | ||
|
|
fdcea5537c | ||
|
|
8ca8bc810d | ||
|
|
8f909b051f | ||
|
|
90f2b2d249 | ||
|
|
f74b27c58c | ||
|
|
3f091f4748 | ||
|
|
d84c9ad611 | ||
|
|
e55e15693d | ||
|
|
c54e6bafdb | ||
|
|
2e56c4895d | ||
|
|
bce4224d6e | ||
|
|
812e2814bc | ||
|
|
7cd17f8e1f | ||
|
|
6193b06708 | ||
|
|
12af68bdb5 | ||
|
|
881f7e9062 | ||
|
|
1db4076bbd | ||
|
|
1933e44719 | ||
|
|
25441cb650 | ||
|
|
bc755ac32f | ||
|
|
1fa34be52a | ||
|
|
f7a6d57855 | ||
|
|
8a987af244 | ||
|
|
65cbb06080 | ||
|
|
979ea9c252 | ||
|
|
aa1f4ee72a | ||
|
|
74ce485b73 | ||
|
|
165e6508f8 | ||
|
|
c7af2889fa | ||
|
|
5ab3390434 | ||
|
|
67f60f1889 | ||
|
|
985a468d0f | ||
|
|
34dc6fbdc1 | ||
|
|
b57152cc25 | ||
|
|
dc9562e430 | ||
|
|
05689fe183 | ||
|
|
8f6f95211e | ||
|
|
f30b6c9e6e | ||
|
|
12ac7d6a00 | ||
|
|
10251a6447 | ||
|
|
089cbbc20a | ||
|
|
95ab68acd1 | ||
|
|
abc4f6c70b | ||
|
|
8fc3a1f9c9 | ||
|
|
5c3d0fc02c | ||
|
|
7efb47fed4 | ||
|
|
7692332f0e | ||
|
|
ef6db64e9f | ||
|
|
e68f1dbc99 | ||
|
|
0c9ebc36d4 | ||
|
|
fcd6eb7801 | ||
|
|
328c2182c2 | ||
|
|
08706f5dfb | ||
|
|
d49f165f0d | ||
|
|
cf0fc3a4a9 | ||
|
|
72c8fd257c | ||
|
|
fa620e41a4 | ||
|
|
b07f851ce7 | ||
|
|
16b3108719 | ||
|
|
f385c624c7 | ||
|
|
f7e9975192 | ||
|
|
cde989b59d | ||
|
|
c0e263abd3 | ||
|
|
79c0c11e80 | ||
|
|
ca671551c8 | ||
|
|
42ed312384 | ||
|
|
0e9074aaba | ||
|
|
7c1961d4ef | ||
|
|
71e57717c2 | ||
|
|
8a549b83a2 | ||
|
|
d7081c5f23 | ||
|
|
588d64a30b | ||
|
|
8335bdf3d4 | ||
|
|
85394f2438 | ||
|
|
42b556574f | ||
|
|
f34e65ad9e | ||
|
|
51352a6819 | ||
|
|
d9887ec370 | ||
|
|
c994950aaf | ||
|
|
a26ed6fe6c | ||
|
|
a12a7e73f9 | ||
|
|
779228857e | ||
|
|
8d0b696d33 | ||
|
|
23ae220aa7 | ||
|
|
b7940e0002 | ||
|
|
b3fd8bd0ae | ||
|
|
bffeb237de | ||
|
|
23e3602ea1 | ||
|
|
34cfd205f6 | ||
|
|
df3da8be7a | ||
|
|
940243f45e | ||
|
|
75d6599143 | ||
|
|
929a27a5ac | ||
|
|
82ddee2104 | ||
|
|
a141678119 | ||
|
|
96d109af81 | ||
|
|
a309eb9f3c | ||
|
|
d034dab265 | ||
|
|
883a035e5c | ||
|
|
08603091c5 | ||
|
|
a2e84e5a1e | ||
|
|
d148898ad7 | ||
|
|
9439621849 | ||
|
|
36cf622979 | ||
|
|
15ded89618 | ||
|
|
b84f74c167 | ||
|
|
a97300f8be | ||
|
|
9e12cff317 | ||
|
|
ecdf1f4ddc | ||
|
|
2fa7a48163 | ||
|
|
5e31e533e2 | ||
|
|
8adf76dcc9 | ||
|
|
15899c10b2 | ||
|
|
05ff05ea4b | ||
|
|
bd62df48c2 | ||
|
|
2366cbc833 | ||
|
|
25fb609544 | ||
|
|
af793395f0 | ||
|
|
8f41776858 | ||
|
|
139b13b8d1 | ||
|
|
4c611a5be1 | ||
|
|
5e7a21e177 | ||
|
|
5f7dda5ba8 | ||
|
|
2dfa1ca0f2 | ||
|
|
358cdcf4c4 | ||
|
|
c8f4ace5c4 | ||
|
|
5cac6ca8bb | ||
|
|
fccad71df1 | ||
|
|
97ae2674dc | ||
|
|
7c70affd7f | ||
|
|
52ff568d86 | ||
|
|
b917aeaa0b | ||
|
|
8de443ec4c | ||
|
|
7d9893c614 | ||
|
|
3540712517 | ||
|
|
a8b1a86bd7 | ||
|
|
1babd3a5a2 | ||
|
|
5ecd04dd4f | ||
|
|
50399e5194 | ||
|
|
b734acf1b1 | ||
|
|
33aa8e2471 | ||
|
|
2c58fe736b | ||
|
|
6fe1de5d86 | ||
|
|
064460b95f | ||
|
|
2c3b19a539 | ||
|
|
dc30a4c1ae | ||
|
|
86e9901bf2 | ||
|
|
6519e0835a | ||
|
|
a52344fc01 | ||
|
|
b67424643d | ||
|
|
575a4c01c9 | ||
|
|
f0d4ee6618 | ||
|
|
8753186a0d | ||
|
|
ff8fb8000d | ||
|
|
9dd38b99d6 | ||
|
|
dfe08c1ec9 | ||
|
|
fb26e78ecc | ||
|
|
4c687036c4 | ||
|
|
062d8d0f4f | ||
|
|
73b6338f62 | ||
|
|
c0d1e2c07a | ||
|
|
e70feceafe | ||
|
|
71ac0286b1 | ||
|
|
022f4d2c11 | ||
|
|
a83a839cff | ||
|
|
b259ee89aa | ||
|
|
65cf14bfce | ||
|
|
d9476fb5ca | ||
|
|
9882365ab4 | ||
|
|
2d758ce963 | ||
|
|
1dd003d26a | ||
|
|
0df5b77595 | ||
|
|
e190a005db | ||
|
|
45596a0342 | ||
|
|
405429a300 | ||
|
|
d009a29426 | ||
|
|
f1fb42460a | ||
|
|
5e110e9f7b | ||
|
|
77a409935d | ||
|
|
863baeb68b | ||
|
|
11142690a0 | ||
|
|
02e8c5faca | ||
|
|
c41081d35c | ||
|
|
db4c26a400 | ||
|
|
331a23fc20 | ||
|
|
db5a40d743 | ||
|
|
e4ab51329d | ||
|
|
8490e7ca7c | ||
|
|
86782aeb1b | ||
|
|
49a44fc92e | ||
|
|
cd39a52c25 | ||
|
|
634101ceb5 | ||
|
|
55555c8787 | ||
|
|
d36d825ac1 | ||
|
|
9bb01cd67c | ||
|
|
29b91075d2 | ||
|
|
6d46fc9f9f | ||
|
|
a2c41c9e36 | ||
|
|
ee700ac861 | ||
|
|
9884a4336f | ||
|
|
5b83d4bef8 | ||
|
|
d320a89590 | ||
|
|
f7e4afc282 | ||
|
|
88e87d589b | ||
|
|
d8c6dede7e | ||
|
|
5cc84133e3 | ||
|
|
f7728aa1f6 | ||
|
|
2b61f9a731 | ||
|
|
f407022fe6 | ||
|
|
41b9f19b01 | ||
|
|
09c6faf923 | ||
|
|
26d0177c01 | ||
|
|
f7415c8a8f | ||
|
|
4cf79088f9 | ||
|
|
50cd321818 | ||
|
|
83bbe6a9d9 | ||
|
|
0a33c18e36 | ||
|
|
6cf158ac63 | ||
|
|
f96bfa6afa | ||
|
|
2b64cf9126 | ||
|
|
a8dcfc44f5 | ||
|
|
0ff9c9da27 | ||
|
|
07e7c2d852 | ||
|
|
10e4b5b2a3 | ||
|
|
998653ea9d | ||
|
|
1a38e925bf | ||
|
|
c8f51380e6 | ||
|
|
2406d57d51 | ||
|
|
cb1e47eb71 | ||
|
|
c0a650f28b | ||
|
|
460cf6fd20 | ||
|
|
5bedfc1c84 | ||
|
|
5001592fb4 | ||
|
|
f6495e59c5 | ||
|
|
66bf431481 | ||
|
|
d9685e991e | ||
|
|
e0790700cd | ||
|
|
910a9600bd | ||
|
|
fc52b2b940 | ||
|
|
b99f828583 | ||
|
|
f38891cace | ||
|
|
8c5111e11a | ||
|
|
5575b981c8 | ||
|
|
0b36732911 | ||
|
|
52f3081a40 | ||
|
|
00c71dc26a | ||
|
|
5218c8584f | ||
|
|
6054bd6621 | ||
|
|
55af4ed385 | ||
|
|
64aee9c8ae | ||
|
|
5233e72205 | ||
|
|
db5b45222a | ||
|
|
fc4787da4e | ||
|
|
4ffbb46cf9 | ||
|
|
c3c2550f17 | ||
|
|
41e8ab5383 | ||
|
|
a802940616 | ||
|
|
dec848f072 | ||
|
|
fb229d4064 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -8,7 +8,7 @@ netDb
|
|||||||
/i2pd
|
/i2pd
|
||||||
/libi2pd.a
|
/libi2pd.a
|
||||||
/libi2pdclient.a
|
/libi2pdclient.a
|
||||||
i2pd.exe
|
*.exe
|
||||||
|
|
||||||
|
|
||||||
# Autotools
|
# Autotools
|
||||||
|
|||||||
100
ChangeLog
100
ChangeLog
@@ -1,6 +1,102 @@
|
|||||||
# for this file format description,
|
# for this file format description,
|
||||||
# see https://github.com/olivierlacan/keep-a-changelog
|
# see https://github.com/olivierlacan/keep-a-changelog
|
||||||
|
|
||||||
|
## [2.25.0] - 2019-05-09
|
||||||
|
### Added
|
||||||
|
- Create, publish and handle encrypted LeaseSet2
|
||||||
|
- Support of b33 addresses
|
||||||
|
- RedDSA key blinding
|
||||||
|
- .b32.i2p addresses in jump links
|
||||||
|
- ntcp2.addressv6 parameter
|
||||||
|
### Changed
|
||||||
|
- Allow HTTP headers without value
|
||||||
|
- Set data directory from external storage path for Android
|
||||||
|
- addresshelper support is configurable per tunnel
|
||||||
|
- gradlew script for android build
|
||||||
|
### Fixed
|
||||||
|
- Deletion of expired encrypted LeaseSet2 on floodfills
|
||||||
|
- ipv6 fallback address
|
||||||
|
- SSU incoming packets routing
|
||||||
|
|
||||||
|
## [2.24.0] - 2019-03-21
|
||||||
|
### Added
|
||||||
|
- Support of transient keys for LeaseSet2
|
||||||
|
- Support of encrypted LeaseSet2
|
||||||
|
- Recognize signature type 11 (RedDSA)
|
||||||
|
- Support websocket connections over HTTP proxy
|
||||||
|
- Ability to disable full addressbook persist
|
||||||
|
### Changed
|
||||||
|
- Don't load peer profiles if non-persistant
|
||||||
|
- REUSE_ADDR for ipv6 acceptors
|
||||||
|
- Reset eTags if addressbook can't be loaded
|
||||||
|
### Fixed
|
||||||
|
- Build with boost 1.70
|
||||||
|
- Filter out unspecified addresses from RouterInfo
|
||||||
|
- Check floodfill status change
|
||||||
|
- Correct SAM response for invalid key
|
||||||
|
- SAM crash on termination for Windows
|
||||||
|
- Race condition for publishing
|
||||||
|
|
||||||
|
## [2.23.0] - 2019-01-21
|
||||||
|
### Added
|
||||||
|
- Standard LeaseSet2 support
|
||||||
|
- Ability to adjust timestamps through the NTP
|
||||||
|
- Ability to disable peer profile persist
|
||||||
|
- Request permission for android >= 6
|
||||||
|
- Initial addressbook to android assets
|
||||||
|
- Cancel graceful shutdown for android
|
||||||
|
- Russian translation for android
|
||||||
|
### Changed
|
||||||
|
- Chacha20 and Poly1305 implementation
|
||||||
|
- Eliminate extra copy of NTCP2 send buffers
|
||||||
|
- Extract content of tunnel.d from assets on android
|
||||||
|
- Removed name resolvers from transports
|
||||||
|
- Update reseed certificates
|
||||||
|
### Fixed
|
||||||
|
- LeaseSet published content verification
|
||||||
|
- Exclude invalid LeaseSets from the list on a floodfill
|
||||||
|
- Build for OpenWrt with openssl 1.1.1
|
||||||
|
|
||||||
|
## [2.22.0] - 2018-11-09
|
||||||
|
### Added
|
||||||
|
- Multiple tunnel config files from tunnels.d folder
|
||||||
|
### Changed
|
||||||
|
- Fetch own RouterInfo upon SessionRequest for NTCP2
|
||||||
|
- Faster XOR between AES blocks for non AVX capable CPUs
|
||||||
|
### Fixed
|
||||||
|
- Fixed NTCP2 termination send
|
||||||
|
|
||||||
|
## [2.21.1] - 2018-10-22
|
||||||
|
### Changed
|
||||||
|
- cost=13 for unpublished NTCP2 address
|
||||||
|
### Fixed
|
||||||
|
- Handle I2NP messages longer than 32K
|
||||||
|
|
||||||
|
## [2.21.0] - 2018-10-04
|
||||||
|
### Added
|
||||||
|
- EdDSA, x25519 and SipHash from openssl 1.1.1
|
||||||
|
- NTCP2 ipv6 incoming connections
|
||||||
|
- Show total number of destination's outgoing tags in the web console
|
||||||
|
### Changed
|
||||||
|
- Android build with openssl 1.1.1/boost 1.64
|
||||||
|
- Bandwidth classes 'P' and 'X' don't add 'O' anymore
|
||||||
|
### Fixed
|
||||||
|
- Update own RouterInfo if no SSU
|
||||||
|
- Recognize 'P' and 'X' routers as high bandwidth without 'O'
|
||||||
|
- NTCP address doesn't disappear if NTCP2 enabled
|
||||||
|
- Android with api 26+
|
||||||
|
|
||||||
|
## [2.20.0] - 2018-08-23
|
||||||
|
### Added
|
||||||
|
- Full implementation of NTCP2
|
||||||
|
- Assets for android
|
||||||
|
### Changed
|
||||||
|
- armeabi-v7a and x86 in one apk for android
|
||||||
|
- NTCP2 is enabled by default
|
||||||
|
- Show lease's expiration time in readable format in the web console
|
||||||
|
### Fixed
|
||||||
|
- Correct names for transports in the web console
|
||||||
|
|
||||||
## [2.19.0] - 2018-06-26
|
## [2.19.0] - 2018-06-26
|
||||||
### Added
|
### Added
|
||||||
- ECIES support for RouterInfo
|
- ECIES support for RouterInfo
|
||||||
@@ -68,7 +164,7 @@
|
|||||||
- NTCP soft and hard descriptors limits
|
- NTCP soft and hard descriptors limits
|
||||||
- Support full timestamps in logs
|
- Support full timestamps in logs
|
||||||
### Changed
|
### Changed
|
||||||
- Faster implmentation of GOST R 34.11 hash
|
- Faster implementation of GOST R 34.11 hash
|
||||||
- Reject routers with RSA signtures
|
- Reject routers with RSA signtures
|
||||||
- Reload config and shudown from Windows GUI
|
- Reload config and shudown from Windows GUI
|
||||||
- Update tunnels address(destination) without restart
|
- Update tunnels address(destination) without restart
|
||||||
@@ -168,7 +264,7 @@
|
|||||||
- Initial iOS support
|
- Initial iOS support
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Reduced file descriptiors usage
|
- Reduced file descriptors usage
|
||||||
- Strict reseed checks enabled by default
|
- Strict reseed checks enabled by default
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|||||||
12
Makefile
12
Makefile
@@ -18,6 +18,14 @@ USE_AVX := yes
|
|||||||
USE_STATIC := no
|
USE_STATIC := no
|
||||||
USE_MESHNET := no
|
USE_MESHNET := no
|
||||||
USE_UPNP := no
|
USE_UPNP := no
|
||||||
|
DEBUG := yes
|
||||||
|
|
||||||
|
ifeq ($(DEBUG),yes)
|
||||||
|
CXX_DEBUG = -g
|
||||||
|
else
|
||||||
|
CXX_DEBUG = -Os
|
||||||
|
LD_DEBUG = -s
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(WEBSOCKETS),1)
|
ifeq ($(WEBSOCKETS),1)
|
||||||
NEEDED_CXXFLAGS += -DWITH_EVENTS
|
NEEDED_CXXFLAGS += -DWITH_EVENTS
|
||||||
@@ -40,7 +48,7 @@ else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
|
|||||||
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
|
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
|
||||||
include Makefile.mingw
|
include Makefile.mingw
|
||||||
else # not supported
|
else # not supported
|
||||||
$(error Not supported platform)
|
$(error Not supported platform)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_MESHNET),yes)
|
ifeq ($(USE_MESHNET),yes)
|
||||||
@@ -122,6 +130,8 @@ doxygen:
|
|||||||
.PHONY: deps
|
.PHONY: deps
|
||||||
.PHONY: doxygen
|
.PHONY: doxygen
|
||||||
.PHONY: dist
|
.PHONY: dist
|
||||||
|
.PHONY: last-dist
|
||||||
.PHONY: api
|
.PHONY: api
|
||||||
.PHONY: api_client
|
.PHONY: api_client
|
||||||
.PHONY: mk_obj_dir
|
.PHONY: mk_obj_dir
|
||||||
|
.PHONY: install
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
CXX = clang++
|
CXX = clang++
|
||||||
CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
|
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
|
||||||
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
|
## NOTE: NEEDED_CXXFLAGS is here so that custom CXXFLAGS can be specified at build time
|
||||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||||
## For example, when adding 'hardening flags' to the build
|
## For example, when adding 'hardening flags' to the build
|
||||||
@@ -8,5 +8,5 @@ CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-ind
|
|||||||
## custom FLAGS to work at build-time.
|
## custom FLAGS to work at build-time.
|
||||||
NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
||||||
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
INCFLAGS = -I/usr/include/ -I/usr/local/include/
|
||||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
LDFLAGS = ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||||
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
# root directory holding homebrew
|
# root directory holding homebrew
|
||||||
BREWROOT = /usr/local
|
BREWROOT = /usr/local
|
||||||
BOOSTROOT = ${BREWROOT}/opt/boost
|
BOOSTROOT = ${BREWROOT}/opt/boost
|
||||||
SSLROOT = ${BREWROOT}/opt/libressl
|
SSLROOT = ${BREWROOT}/opt/openssl@1.1
|
||||||
UPNPROOT = ${BREWROOT}/opt/miniupnpc
|
UPNPROOT = ${BREWROOT}/opt/miniupnpc
|
||||||
CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
|
CXXFLAGS = ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
|
||||||
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
||||||
|
LDFLAGS = ${LD_DEBUG}
|
||||||
|
|
||||||
ifndef TRAVIS
|
ifndef TRAVIS
|
||||||
CXX = clang++
|
CXX = clang++
|
||||||
@@ -13,7 +14,7 @@ endif
|
|||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
LDLIBS = -lz ${SSLROOT}/lib/libcrypto.a ${SSLROOT}/lib/libssl.a ${BOOSTROOT}/lib/libboost_system.a ${BOOSTROOT}/lib/libboost_date_time.a ${BOOSTROOT}/lib/libboost_filesystem.a ${BOOSTROOT}/lib/libboost_program_options.a -lpthread
|
LDLIBS = -lz ${SSLROOT}/lib/libcrypto.a ${SSLROOT}/lib/libssl.a ${BOOSTROOT}/lib/libboost_system.a ${BOOSTROOT}/lib/libboost_date_time.a ${BOOSTROOT}/lib/libboost_filesystem.a ${BOOSTROOT}/lib/libboost_program_options.a -lpthread
|
||||||
else
|
else
|
||||||
LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
LDFLAGS += -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
||||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -34,15 +35,20 @@ endif
|
|||||||
# Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2
|
# Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2
|
||||||
# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic
|
# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic
|
||||||
ifeq ($(USE_AESNI),yes)
|
ifeq ($(USE_AESNI),yes)
|
||||||
CXXFLAGS += -maes -DAESNI
|
CXXFLAGS += -maes
|
||||||
endif
|
endif
|
||||||
ifeq ($(USE_AVX),1)
|
ifeq ($(USE_AVX),1)
|
||||||
CXXFLAGS += -mavx
|
CXXFLAGS += -mavx
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
install: all
|
||||||
# Disabled, since it will be the default make rule. I think its better
|
install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
|
||||||
# to define the default rule in Makefile and not Makefile.<ostype> - torkel
|
install -m 755 ${I2PD} ${PREFIX}/bin/
|
||||||
#install: all
|
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
|
||||||
# test -d ${PREFIX} || mkdir -p ${PREFIX}/
|
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
|
||||||
# cp -r i2p ${PREFIX}/
|
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
|
||||||
|
@gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
|
||||||
|
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
|
||||||
|
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
# set defaults instead redefine
|
# set defaults instead redefine
|
||||||
CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
|
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
|
||||||
INCFLAGS ?=
|
LDFLAGS ?= ${LD_DEBUG}
|
||||||
|
|
||||||
## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time
|
## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time
|
||||||
## **without** overwriting the CXXFLAGS which we need in order to build.
|
## **without** overwriting the CXXFLAGS which we need in order to build.
|
||||||
## For example, when adding 'hardening flags' to the build
|
## For example, when adding 'hardening flags' to the build
|
||||||
## (e.g. -fstack-protector-strong -Wformat -Werror=format-security), we do not want to remove
|
## (e.g. -fstack-protector-strong -Wformat -Werror=format-security), we do not want to remove
|
||||||
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
|
## -std=c++11. If you want to remove this variable please do so in a way that allows setting
|
||||||
## custom FLAGS to work at build-time.
|
## custom FDLAGS to work at build-time.
|
||||||
|
|
||||||
# detect proper flag for c++11 support by compilers
|
# detect proper flag for c++11 support by compilers
|
||||||
CXXVER := $(shell $(CXX) -dumpversion)
|
CXXVER := $(shell $(CXX) -dumpversion)
|
||||||
@@ -19,10 +19,9 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7
|
|||||||
NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
||||||
else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6
|
else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6
|
||||||
NEEDED_CXXFLAGS += -std=c++0x
|
NEEDED_CXXFLAGS += -std=c++0x
|
||||||
else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0
|
else ifeq ($(shell expr match ${CXXVER} "[5-9]"),1) # gcc >= 5
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
|
||||||
else ifeq ($(shell expr match ${CXXVER} "[7-8]"),1) # gcc 7 ubuntu or gcc 8 arch
|
|
||||||
NEEDED_CXXFLAGS += -std=c++11
|
NEEDED_CXXFLAGS += -std=c++11
|
||||||
|
LDLIBS = -latomic
|
||||||
else # not supported
|
else # not supported
|
||||||
$(error Compiler too old)
|
$(error Compiler too old)
|
||||||
endif
|
endif
|
||||||
@@ -34,7 +33,7 @@ ifeq ($(USE_STATIC),yes)
|
|||||||
# Using 'getaddrinfo' in statically linked applications requires at runtime
|
# Using 'getaddrinfo' in statically linked applications requires at runtime
|
||||||
# the shared libraries from the glibc version used for linking
|
# the shared libraries from the glibc version used for linking
|
||||||
LIBDIR := /usr/lib
|
LIBDIR := /usr/lib
|
||||||
LDLIBS = $(LIBDIR)/libboost_system.a
|
LDLIBS += $(LIBDIR)/libboost_system.a
|
||||||
LDLIBS += $(LIBDIR)/libboost_date_time.a
|
LDLIBS += $(LIBDIR)/libboost_date_time.a
|
||||||
LDLIBS += $(LIBDIR)/libboost_filesystem.a
|
LDLIBS += $(LIBDIR)/libboost_filesystem.a
|
||||||
LDLIBS += $(LIBDIR)/libboost_program_options.a
|
LDLIBS += $(LIBDIR)/libboost_program_options.a
|
||||||
@@ -44,7 +43,7 @@ ifeq ($(USE_STATIC),yes)
|
|||||||
LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl
|
LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl
|
||||||
USE_AESNI := no
|
USE_AESNI := no
|
||||||
else
|
else
|
||||||
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# UPNP Support (miniupnpc 1.5 and higher)
|
# UPNP Support (miniupnpc 1.5 and higher)
|
||||||
@@ -64,7 +63,7 @@ ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0)
|
|||||||
ifeq ($(machine), aarch64)
|
ifeq ($(machine), aarch64)
|
||||||
CXXFLAGS += -DARM64AES
|
CXXFLAGS += -DARM64AES
|
||||||
else
|
else
|
||||||
CPU_FLAGS += -maes -DAESNI
|
CPU_FLAGS += -maes
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|||||||
110
Makefile.mingw
110
Makefile.mingw
@@ -1,54 +1,56 @@
|
|||||||
USE_WIN32_APP=yes
|
USE_WIN32_APP=yes
|
||||||
CXX = g++
|
CXX = g++
|
||||||
WINDRES = windres
|
WINDRES = windres
|
||||||
CXXFLAGS = -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
|
CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
|
||||||
NEEDED_CXXFLAGS = -std=c++11
|
NEEDED_CXXFLAGS = -std=c++11
|
||||||
BOOST_SUFFIX = -mt
|
INCFLAGS = -Idaemon -I.
|
||||||
INCFLAGS = -Idaemon -I.
|
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++
|
||||||
LDFLAGS = -s -Wl,-rpath,/usr/local/lib -Wl,-Bstatic -static-libgcc -static-libstdc++
|
|
||||||
|
# Boost libraries suffix
|
||||||
# UPNP Support
|
BOOST_SUFFIX = -mt
|
||||||
ifeq ($(USE_UPNP),yes)
|
|
||||||
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
# UPNP Support
|
||||||
LDLIBS = -lminiupnpc
|
ifeq ($(USE_UPNP),yes)
|
||||||
endif
|
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
||||||
|
LDLIBS = -lminiupnpc
|
||||||
LDLIBS += \
|
endif
|
||||||
-lboost_system$(BOOST_SUFFIX) \
|
|
||||||
-lboost_date_time$(BOOST_SUFFIX) \
|
LDLIBS += \
|
||||||
-lboost_filesystem$(BOOST_SUFFIX) \
|
-lboost_system$(BOOST_SUFFIX) \
|
||||||
-lboost_program_options$(BOOST_SUFFIX) \
|
-lboost_date_time$(BOOST_SUFFIX) \
|
||||||
-lssl \
|
-lboost_filesystem$(BOOST_SUFFIX) \
|
||||||
-lcrypto \
|
-lboost_program_options$(BOOST_SUFFIX) \
|
||||||
-lz \
|
-lssl \
|
||||||
-lwsock32 \
|
-lcrypto \
|
||||||
-lws2_32 \
|
-lz \
|
||||||
-lgdi32 \
|
-lwsock32 \
|
||||||
-liphlpapi \
|
-lws2_32 \
|
||||||
-lstdc++ \
|
-lgdi32 \
|
||||||
-lpthread
|
-liphlpapi \
|
||||||
|
-lstdc++ \
|
||||||
ifeq ($(USE_WIN32_APP), yes)
|
-lpthread
|
||||||
CXXFLAGS += -DWIN32_APP
|
|
||||||
LDFLAGS += -mwindows
|
ifeq ($(USE_WIN32_APP), yes)
|
||||||
DAEMON_RC += Win32/Resource.rc
|
CXXFLAGS += -DWIN32_APP
|
||||||
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
LDFLAGS += -mwindows
|
||||||
endif
|
DAEMON_RC += Win32/Resource.rc
|
||||||
|
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
||||||
# don't change following line to ifeq ($(USE_AESNI),yes) !!!
|
endif
|
||||||
ifeq ($(USE_AESNI),1)
|
|
||||||
CPU_FLAGS += -maes -DAESNI
|
# don't change following line to ifeq ($(USE_AESNI),yes) !!!
|
||||||
else
|
ifeq ($(USE_AESNI),1)
|
||||||
CPU_FLAGS += -msse
|
CPU_FLAGS += -maes
|
||||||
endif
|
else
|
||||||
|
CPU_FLAGS += -msse
|
||||||
ifeq ($(USE_AVX),1)
|
endif
|
||||||
CPU_FLAGS += -mavx
|
|
||||||
endif
|
ifeq ($(USE_AVX),1)
|
||||||
|
CPU_FLAGS += -mavx
|
||||||
ifeq ($(USE_ASLR),yes)
|
endif
|
||||||
LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols
|
|
||||||
endif
|
ifeq ($(USE_ASLR),yes)
|
||||||
|
LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols
|
||||||
obj/%.o : %.rc
|
endif
|
||||||
$(WINDRES) -i $< -o $@
|
|
||||||
|
obj/%.o : %.rc
|
||||||
|
$(WINDRES) -i $< -o $@
|
||||||
|
|||||||
13
Makefile.osx
13
Makefile.osx
@@ -1,8 +1,7 @@
|
|||||||
CXX = clang++
|
CXX = clang++
|
||||||
CXXFLAGS = -Os -Wall -std=c++11 -DMAC_OSX
|
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
|
||||||
#CXXFLAGS = -g -O2 -Wall -std=c++11
|
|
||||||
INCFLAGS = -I/usr/local/include
|
INCFLAGS = -I/usr/local/include
|
||||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||||
|
|
||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
||||||
@@ -21,7 +20,7 @@ ifeq ($(USE_UPNP),yes)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),1)
|
ifeq ($(USE_AESNI),1)
|
||||||
CXXFLAGS += -maes -DAESNI
|
CXXFLAGS += -maes
|
||||||
else
|
else
|
||||||
CXXFLAGS += -msse
|
CXXFLAGS += -msse
|
||||||
endif
|
endif
|
||||||
@@ -29,9 +28,3 @@ endif
|
|||||||
ifeq ($(USE_AVX),1)
|
ifeq ($(USE_AVX),1)
|
||||||
CXXFLAGS += -mavx
|
CXXFLAGS += -mavx
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Disabled, since it will be the default make rule. I think its better
|
|
||||||
# to define the default rule in Makefile and not Makefile.<ostype> - torkel
|
|
||||||
#install: all
|
|
||||||
# test -d ${PREFIX} || mkdir -p ${PREFIX}/
|
|
||||||
# cp -r i2p ${PREFIX}/
|
|
||||||
|
|||||||
21
README.md
21
README.md
@@ -1,3 +1,6 @@
|
|||||||
|

|
||||||
|

|
||||||
|
|
||||||
i2pd
|
i2pd
|
||||||
====
|
====
|
||||||
|
|
||||||
@@ -38,8 +41,12 @@ Resources
|
|||||||
Installing
|
Installing
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The easiest way to install i2pd is by using
|
The easiest way to install i2pd is by using precompiled packages and binaries.
|
||||||
[precompiled binaries](https://github.com/PurpleI2P/i2pd/releases/latest).
|
You can fetch most of them on [release](https://github.com/PurpleI2P/i2pd/releases/latest) page.
|
||||||
|
Please see [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/install/) for more info.
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
|
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
|
||||||
i2pd from source on your OS.
|
i2pd from source on your OS.
|
||||||
|
|
||||||
@@ -54,11 +61,11 @@ Build instructions:
|
|||||||
|
|
||||||
**Supported systems:**
|
**Supported systems:**
|
||||||
|
|
||||||
* GNU/Linux x86/x64 - [](https://travis-ci.org/PurpleI2P/i2pd)
|
* GNU/Linux - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||||
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
||||||
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||||
* CentOS / Fedora - [](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
|
* CentOS / Fedora / Mageia - [](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
|
||||||
* Docker image - [](https://hub.docker.com/r/meeh/i2pd/builds/)
|
* Docker image - [](https://hub.docker.com/r/meeh/i2pd/builds/)
|
||||||
* FreeBSD
|
* FreeBSD
|
||||||
* Android
|
* Android
|
||||||
* iOS
|
* iOS
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace util
|
|||||||
if (isDaemon)
|
if (isDaemon)
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "Daemon: running as service");
|
LogPrint(eLogDebug, "Daemon: running as service");
|
||||||
I2PService service(SERVICE_NAME);
|
I2PService service((PSTR)SERVICE_NAME);
|
||||||
if (!I2PService::Run(service))
|
if (!I2PService::Run(service))
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||||
|
|||||||
@@ -24,17 +24,22 @@
|
|||||||
#define ID_GRACEFUL_SHUTDOWN 2004
|
#define ID_GRACEFUL_SHUTDOWN 2004
|
||||||
#define ID_STOP_GRACEFUL_SHUTDOWN 2005
|
#define ID_STOP_GRACEFUL_SHUTDOWN 2005
|
||||||
#define ID_RELOAD 2006
|
#define ID_RELOAD 2006
|
||||||
|
#define ID_ACCEPT_TRANSIT 2007
|
||||||
|
#define ID_DECLINE_TRANSIT 2008
|
||||||
|
|
||||||
#define ID_TRAY_ICON 2050
|
#define ID_TRAY_ICON 2050
|
||||||
#define WM_TRAYICON (WM_USER + 1)
|
#define WM_TRAYICON (WM_USER + 1)
|
||||||
|
|
||||||
#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100
|
#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100
|
||||||
#define FRAME_UPDATE_TIMER 2101
|
#define FRAME_UPDATE_TIMER 2101
|
||||||
|
#define IDT_GRACEFUL_TUNNELCHECK_TIMER 2102
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace win32
|
namespace win32
|
||||||
{
|
{
|
||||||
|
static DWORD GracefulShutdownEndtime = 0;
|
||||||
|
|
||||||
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
|
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
|
||||||
{
|
{
|
||||||
HMENU hPopup = CreatePopupMenu();
|
HMENU hPopup = CreatePopupMenu();
|
||||||
@@ -42,11 +47,17 @@ namespace win32
|
|||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||||||
|
if(!i2p::context.AcceptsTunnels())
|
||||||
|
InsertMenu (hPopup, -1,
|
||||||
|
i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING,
|
||||||
|
ID_ACCEPT_TRANSIT, "Accept &transit");
|
||||||
|
else
|
||||||
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload configs");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload configs");
|
||||||
if (!i2p::util::DaemonWin32::Instance ().isGraceful)
|
if (!i2p::util::DaemonWin32::Instance ().isGraceful)
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
||||||
else
|
else
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "&Stop graceful shutdown");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
|
||||||
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
|
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
|
||||||
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
|
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
|
||||||
@@ -148,7 +159,13 @@ namespace win32
|
|||||||
s << "; ";
|
s << "; ";
|
||||||
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
|
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
|
||||||
s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ());
|
s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ());
|
||||||
s << "\n";
|
if (GracefulShutdownEndtime != 0)
|
||||||
|
{
|
||||||
|
DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCount()) / 1000;
|
||||||
|
s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s << "\n";
|
||||||
s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; ";
|
s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; ";
|
||||||
s << "Outbound: " << i2p::transport::transports.GetOutBandwidth() / 1024 << " KiB/s\n";
|
s << "Outbound: " << i2p::transport::transports.GetOutBandwidth() / 1024 << " KiB/s\n";
|
||||||
s << "Received: "; ShowTransfered (s, i2p::transport::transports.GetTotalReceivedBytes());
|
s << "Received: "; ShowTransfered (s, i2p::transport::transports.GetTotalReceivedBytes());
|
||||||
@@ -166,10 +183,13 @@ namespace win32
|
|||||||
|
|
||||||
static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
static UINT s_uTaskbarRestart;
|
||||||
|
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
|
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
||||||
AddTrayIcon (hWnd);
|
AddTrayIcon (hWnd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -178,6 +198,7 @@ namespace win32
|
|||||||
RemoveTrayIcon (hWnd);
|
RemoveTrayIcon (hWnd);
|
||||||
KillTimer (hWnd, FRAME_UPDATE_TIMER);
|
KillTimer (hWnd, FRAME_UPDATE_TIMER);
|
||||||
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
||||||
|
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
||||||
PostQuitMessage (0);
|
PostQuitMessage (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -197,10 +218,28 @@ namespace win32
|
|||||||
PostMessage (hWnd, WM_CLOSE, 0, 0);
|
PostMessage (hWnd, WM_CLOSE, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case ID_ACCEPT_TRANSIT:
|
||||||
|
{
|
||||||
|
i2p::context.SetAcceptsTunnels (true);
|
||||||
|
std::stringstream text;
|
||||||
|
text << "I2Pd now accept transit tunnels";
|
||||||
|
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case ID_DECLINE_TRANSIT:
|
||||||
|
{
|
||||||
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
|
std::stringstream text;
|
||||||
|
text << "I2Pd now decline new transit tunnels";
|
||||||
|
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case ID_GRACEFUL_SHUTDOWN:
|
case ID_GRACEFUL_SHUTDOWN:
|
||||||
{
|
{
|
||||||
i2p::context.SetAcceptsTunnels (false);
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
||||||
|
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second
|
||||||
|
GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
|
||||||
i2p::util::DaemonWin32::Instance ().isGraceful = true;
|
i2p::util::DaemonWin32::Instance ().isGraceful = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -208,6 +247,8 @@ namespace win32
|
|||||||
{
|
{
|
||||||
i2p::context.SetAcceptsTunnels (true);
|
i2p::context.SetAcceptsTunnels (true);
|
||||||
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
||||||
|
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
|
||||||
|
GracefulShutdownEndtime = 0;
|
||||||
i2p::util::DaemonWin32::Instance ().isGraceful = false;
|
i2p::util::DaemonWin32::Instance ().isGraceful = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -223,7 +264,7 @@ namespace win32
|
|||||||
{
|
{
|
||||||
char buf[30];
|
char buf[30];
|
||||||
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
||||||
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
||||||
snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort);
|
snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort);
|
||||||
ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL);
|
ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -290,14 +331,27 @@ namespace win32
|
|||||||
}
|
}
|
||||||
case WM_TIMER:
|
case WM_TIMER:
|
||||||
{
|
{
|
||||||
if (wParam == IDT_GRACEFUL_SHUTDOWN_TIMER)
|
switch(wParam)
|
||||||
{
|
{
|
||||||
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
|
case IDT_GRACEFUL_SHUTDOWN_TIMER:
|
||||||
return 0;
|
{
|
||||||
}
|
GracefulShutdownEndtime = 0;
|
||||||
if (wParam == FRAME_UPDATE_TIMER)
|
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
|
||||||
{
|
return 0;
|
||||||
InvalidateRect(hWnd, NULL, TRUE);
|
}
|
||||||
|
case FRAME_UPDATE_TIMER:
|
||||||
|
{
|
||||||
|
InvalidateRect(hWnd, NULL, TRUE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case IDT_GRACEFUL_TUNNELCHECK_TIMER:
|
||||||
|
{
|
||||||
|
if (i2p::tunnel::tunnels.CountTransitTunnels() == 0)
|
||||||
|
PostMessage (hWnd, WM_CLOSE, 0, 0);
|
||||||
|
else
|
||||||
|
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -318,6 +372,12 @@ namespace win32
|
|||||||
EndPaint(hWnd, &ps);
|
EndPaint(hWnd, &ps);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (uMsg == s_uTaskbarRestart)
|
||||||
|
AddTrayIcon (hWnd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return DefWindowProc( hWnd, uMsg, wParam, lParam);
|
return DefWindowProc( hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,7 +297,8 @@ void InstallService(PCSTR pszServiceName, PCSTR pszDisplayName, DWORD dwStartTyp
|
|||||||
FreeHandles(schSCManager, schService);
|
FreeHandles(schSCManager, schService);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strncat(szPath, " --daemon", MAX_PATH);
|
char SvcOpt[] = " --daemon";
|
||||||
|
strncat(szPath, SvcOpt, strlen(SvcOpt));
|
||||||
|
|
||||||
// Open the local default service control manager database
|
// Open the local default service control manager database
|
||||||
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
|
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#define I2Pd_AppName "i2pd"
|
#define I2Pd_AppName "i2pd"
|
||||||
#define I2Pd_ver "2.19.0"
|
#define I2Pd_ver "2.25.0"
|
||||||
#define I2Pd_Publisher "PurpleI2P"
|
#define I2Pd_Publisher "PurpleI2P"
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
@@ -32,6 +32,7 @@ Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntex
|
|||||||
Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||||
Source: ..\contrib\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
Source: ..\contrib\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||||
Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
||||||
|
Source: ..\contrib\tunnels.d\*; DestDir: {userappdata}\i2pd\tunnels.d; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
||||||
|
|
||||||
[Icons]
|
[Icons]
|
||||||
Name: {group}\I2Pd; Filename: {app}\i2pd.exe
|
Name: {group}\I2Pd; Filename: {app}\i2pd.exe
|
||||||
|
|||||||
13
android/.gitignore
vendored
13
android/.gitignore
vendored
@@ -1,15 +1,16 @@
|
|||||||
gen
|
gen
|
||||||
tests
|
tests
|
||||||
|
bin
|
||||||
|
libs
|
||||||
|
log*
|
||||||
|
obj
|
||||||
|
.gradle
|
||||||
.idea
|
.idea
|
||||||
|
.externalNativeBuild
|
||||||
ant.properties
|
ant.properties
|
||||||
local.properties
|
local.properties
|
||||||
build.sh
|
build.sh
|
||||||
bin
|
|
||||||
log*
|
|
||||||
.gradle
|
|
||||||
android.iml
|
android.iml
|
||||||
build
|
build
|
||||||
gradle
|
|
||||||
gradlew
|
|
||||||
gradlew.bat
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.purplei2p.i2pd"
|
package="org.purplei2p.i2pd"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto">
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="2.19.0">
|
|
||||||
|
|
||||||
<uses-sdk
|
|
||||||
android:minSdkVersion="14"
|
|
||||||
android:targetSdkVersion="25" />
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" /> <!-- normal perm, per https://developer.android.com/guide/topics/permissions/normal-permissions.html -->
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- normal perm -->
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@drawable/icon"
|
android:icon="@drawable/icon"
|
||||||
@@ -52,5 +48,4 @@
|
|||||||
android:value="org.purplei2p.i2pd.I2PDPermsAskerActivity" />
|
android:value="org.purplei2p.i2pd.I2PDPermsAskerActivity" />
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
693
android/assets/addressbook/addresses.csv
Normal file
693
android/assets/addressbook/addresses.csv
Normal file
@@ -0,0 +1,693 @@
|
|||||||
|
00.i2p,zmzpltxslembpaupg3srh4bbhv5txgh5jmms6sfj4hzsvlv3xugq
|
||||||
|
0ipfs.i2p,cdii3ou5mve5sfxyirs6kogt4tbvivk2d6o25awbcbazjrlhjeza
|
||||||
|
0xcc.i2p,gawouxh2sg32cluwlqsnpy3dwedvoqtfroi4evvdvm2pfv7tdadq
|
||||||
|
1.fcp.freenet.i2p,cuxbeputgxn75ak4nr7ltp7fjktnzl5sul3wstwnsoytbbpb4ixq
|
||||||
|
102chan.i2p,xxu3lso4h2rh6wmrxiou3ax7r7la7x6dhoepnku3jvrlwp35pefq
|
||||||
|
1st.i2p,rduua7bhest6rwsmmyttzssfdw3p4eu6bgl3mb4hin32qo3x5zfq
|
||||||
|
2.fcp.freenet.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
|
||||||
|
333.i2p,ctvfe2fimcsdfxmzmd42brnbf7ceenwrbroyjx3wzah5eudjyyza
|
||||||
|
55cancri.i2p,b4iqenefh2fr4xtuq6civfc6nhnia6e2yo36pf7vcgdvrwmh7xua
|
||||||
|
adab.i2p,pxjr6f2cig6v7v7ekam3smdnkqgmgseyy5cdwrozdyejm7jknkha
|
||||||
|
alice.i2p,iq26r2ls2qlkhbn62cvgb6a4iib7m5lkoulohdua5z6uvzlovjtq
|
||||||
|
always.i2p,wp43sdtuxum6gxbjvyeor35r5yvgtkp3dcu7dv47lx22zeb3relq
|
||||||
|
amazone.i2p,e6kq73lsxaeyiwpmykdbdo3uy4ppj64bl7y3viegp6mqrilqybqa
|
||||||
|
amiga.i2p,edy2xappzjjh7bxqounevji4wd2binqkv7gft4usrkan45xhbk5q
|
||||||
|
amobius.i2p,rj6432agdprun5baai2hj62xfhb4l75uvzl55dhj6z5zzoxv3htq
|
||||||
|
anarchistfaq.i2p,xosberjz2geveh5dcstztq5kwew6xx2brrqaorkjf2323bjzcd3q
|
||||||
|
animal.i2p,5iedafy32swqq4t2wcmjb4fvg3onscng7ct7wb237jkvrclaftla
|
||||||
|
anodex.i2p,25cb5kixhxm6i6c6wequrhi65mez4duc4l5qk6ictbik3tnxlu6a
|
||||||
|
anoncoin.i2p,nmi3loretkk4zbili32t2e5wyznwoxcsgzmd2z4ll3msgndyqpfa
|
||||||
|
anongw.i2p,owrnciwubb3f3dctvlmnaknb6tjdxtlzvv7klocb45mmhievdjhq
|
||||||
|
anonsfw.i2p,ir6hzi66izmvqx3usjl6br3nndkpazonlckrzt3gtltqcy5ralyq
|
||||||
|
anonymnet.i2p,77ouyl2ane7ffgydosd4ye42g67aomtc4jrusmi76lds5qonlffa
|
||||||
|
anonynanny.i2p,l2lnhq2dynnmf3m46tcbpcmbbn4kifjgt26go6n2hlapy4drhyja
|
||||||
|
anonyradio.i2p,cbobsax3rhoyjbk7ii2nd2fnl5bxh3x7bbearokyxgvmudn7o5bq
|
||||||
|
antipiracyagency.i2p,by4kcmklz7xnkai6ndfio47kts3rndm6wwleegtxghllimikdapq
|
||||||
|
antipiratbyran.i2p,y2qbhrvuciifbszaqqwxd5t75bomp7kzdqx4yxsrkaq542t75k3a
|
||||||
|
aosp.i2p,ly7raldsh2na2cgw5yvueyvqqjgx3vbqinecjrqdldgya76i2p2q
|
||||||
|
arc2.i2p,rnmosuwvtftfcrk5sk7zoyhyadh2g4dhe2mif5ml7qjisgkyw2na
|
||||||
|
archaicbinarybbs.i2p,t7o2tw36cffedgfr6kahewpkrntofnliuapji2e4rucl3os55epa
|
||||||
|
archiv.tutorials.i2p,lldr2miowq6353fxy44pnxfk37d6yn2f6kaivzecbmvvnnf5exyq
|
||||||
|
archive.i2p,x54d5st3dl6mwgfxj6raiekqkypo5pdvuex3n62szwju7hgefiyq
|
||||||
|
archive.syndie.i2p,abbyu5n3mh3nj7pe3b6byldrxswvva5ttxcafsnnseidanurq3kq
|
||||||
|
ardor-wallet.i2p,tm23k5ny3umhf6vf3kghnnwacli5zywq5wrr3xcqowbcofuyr4gq
|
||||||
|
ardvark.i2p,jcmw2sol3hruwc6rfinonx4e23pjkukkg7lg7xt7xb2gpiyyraiq
|
||||||
|
arf.i2p,o46lsq4u7udxg3qqlidrmpj4lb4nr7ldxmbb2x53nftndaeyxqeq
|
||||||
|
arkan.i2p,7o5y2lyyrjx5tf6l4fyumywui7msjv5azaaheatvw5sqj7mxbuvq
|
||||||
|
asciiwhite.i2p,itbzny5ktuenhjwjfqx3jravolhlj5wullhhr2m4qr6k2emnm5dq
|
||||||
|
aspnet.i2p,tsb7zqru57p4q2a7cto2lko4w5cg4lieglwm6t27c44fkphqmf2a
|
||||||
|
asylum.i2p,p45ejjw4p2q6nq3mzi6cm6ep35grtzshboidj2lojmrmic22noha
|
||||||
|
auchan.i2p,6vxz4yp3vhjwbkmxajj7wiikxafwujig63gkhjknbq6xh4rqpm5a
|
||||||
|
aum.i2p,ohdfneqxapfd3fwfbum4tut7z6k3rnr7rrguoxdrrfe2tln2kpbq
|
||||||
|
awup.i2p,v6g32duzrkacnrezfbll3pza5u37h7lnukr2wbsk6rqen6prhbga
|
||||||
|
b.i2p,272kt3gcx6wjurunzaiiwld7s5p4mpjewfubzmlcvw2vie62ckpq
|
||||||
|
bacardi.i2p,hivhnx2v47vh234c7coi2urj5cyvbl4bu3ypjr7snklortyqeljq
|
||||||
|
backup.i2p,kepphem42whle3rkfv26wcksmnegdbg6rdp6t3oobdkc2fmzrdkq
|
||||||
|
badfish.i2p,f6v26gyr4eipy3a7pi2voulw5qvob6dg7zij6xpo2ywbi5tvbu6a
|
||||||
|
badtoyz.i2p,3qz6ubtwlt2c4iasofjirkckq43u5fgkzyg7mlutcsym5gzhijna
|
||||||
|
barry.i2p,4kyahq53ol52n23l44tefgeaxqpp3cbb632t5k3umdvqcooevdzq
|
||||||
|
bash.i2p,s3wouoilbl3mrefxjhp4qoyujgok34e7y6vmpbu6hx4342ivqo4q
|
||||||
|
bdl.i2p,kp6fnuulenbjm7r26pfbmjcq3u7c7kvxeajodvgr5flcnskdgi5a
|
||||||
|
bdsm.i2p,pa7fxql5jljegg7j5tglhnnaod2sptq3gxvdn3ji6muqyhgn3poq
|
||||||
|
betaguru.i2p,d7cduwwhrcc2voameqfkvd66u3advu4jw2p6pysgax35vq6ovriq
|
||||||
|
beyond.i2p,uaicfqlrpjtitqbqkpfujanj5dollzfzee5glsuls67ekw6hlpoa
|
||||||
|
bible.i2p,pypz7ca24n3lyp4tm3kvncg3ltp3gd5pgnacc6zltoeffiyyegda
|
||||||
|
bible4u.i2p,xs6lr2g5jiaajtb3nkno2zmy34eipitrggooxb7wtey7uko7bqmq
|
||||||
|
bigbrother.i2p,tnxiifs6uticzyg6ac4lhv2l5luwi6xra7yngocro56ive5e4jsq
|
||||||
|
bitlox.i2p,lqw5khxcdntlv3u4vhn53upcqirplvnc4etjlmoytrzs66ytettq
|
||||||
|
bittorrent.i2p,pgax2vz572i4zsp6u6paox5xubmjrkqohq6g4hvlp6ruzzy56l5q
|
||||||
|
bk1k.i2p,nlyegmtyfffo5jfgg5h4dxxnlmqko2g36gpaye5a7vd3is35xxfq
|
||||||
|
bl.i2p,e73d6uhnfbylza6wqkhxejmqeyfb7thkzw35gn5ojmna64jzyk2a
|
||||||
|
black.i2p,sjwueu62qpe6dtv5b322k3f23fl4uz3w6qe6wcrwauiwpnymypfq
|
||||||
|
blackbox.i2p,7josyf7zjieoib3ovmr5a4dh5w64kmfh45lv5h436eljtgfegtqa
|
||||||
|
blackexchange.i2p,ztgr5kghkyn43fhhkuycroxgfti6cojo3vg4wdd3usqonyvrla5q
|
||||||
|
blog.curiosity.i2p,yiz6jec5k7ccxdgnh7msqa4ze52bqqmf6rpq6bqdyojra2erd4ta
|
||||||
|
blog.polecat.i2p,orlccceubewvxo3fbdyydq6e4uuidbs4xd5u2gyqbculnowo3ehq
|
||||||
|
blog.tinlans.i2p,ylkch2nkrwehakx4z6wiyjbeqwlgasknukdkex6r6yq4xusrjnda
|
||||||
|
bluebeam.i2p,lvxp3cbcfwtol57d5pmrsck32t7ndutlxubjb4smaf32bynhlk6a
|
||||||
|
blueheron.i2p,anfb5jrhixjmvkyxctqwkezqer7dbob22wge2bh6wsewbhgnftfa
|
||||||
|
bnc.i2p,fr4zbcygmx2vdct6nrabakfys4b4derm6jqu2ovppkgqillvlqxa
|
||||||
|
bob.i2p,i76m7dwm5hnapljendbie6fc5y3mjlkdlduo3tvbwiwmvhxbpyaa
|
||||||
|
bobcat.i2p,ftuukjtcquuvppt726w37boit7gp5hf2yxwfop35prx3grzzzxlq
|
||||||
|
bobthebuilder.i2p,qlahgthqhr4uojkkwahnper2cl3ro5f5gtzy5t4lzapbzo4osy6q
|
||||||
|
boerse.i2p,7633w56hd53sesr6b532r5qlbdnvyl5bnvama6ign6xryaxol4rq
|
||||||
|
bofh.i2p,auvuinzogu6gc4pwsgbjijuszxgcjygciu2wy53pfz7mo5nfpc5a
|
||||||
|
boing.i2p,bgsq33bh74j66hn4oh7oovlvuhhdyw22lq2qi2fnv3jyh2ryap3a
|
||||||
|
books.manveru.i2p,eb2tisc2vr5jvjqrixrozcujiucwxg4m722stxwho5666ipl67zq
|
||||||
|
bote.i2p,bhjhc3lsdqzoyhxwzyrd63kvyg4br6n2337d74blyintae66mr2a
|
||||||
|
bozo.i2p,7a2d23h6htprhzrol36vgwgklsbqrnuya4tbaaaspmaeaodt57iq
|
||||||
|
brittanyworld.i2p,e76umhhic3474sdxiuax25ixyfg7y3z7oojj4fmxvhgv3ruet6aa
|
||||||
|
bt.i2p,uhkuu54pg47zey76h45tnvsdtpkf5bthbtrjgnaloi5m54h4hlaq
|
||||||
|
bugfuzz.i2p,ubszn4gsf22vga67rvzzlg4qj2bfcq6o52fmxz46xruawqm6z7rq
|
||||||
|
burntout.i2p,lkep3fd7tjvxrs25crr2c3jy7xm4s7bqiua5r327zgpw37sgyerq
|
||||||
|
bytepay.i2p,7amc4ztwkzu3cgsaaaw3223ohuihn5hlsqc6gpf2rxdyptdkyugq
|
||||||
|
ca.i2pd.i2p,u5safmawcxj5vlrdtqrsqbsndkr5cfenpicgg5euu4xqm73yicba
|
||||||
|
cases.i2p,kmpmk2fmineaiwublteqlifg4fkmewnhmxqlcgg7qwecz6daj43a
|
||||||
|
cathugger.i2p,vq43xjjcnejqpzfprws5qzrea2siieshu4tglpdepql2w3w3bpba
|
||||||
|
cbs.i2p,u3lp7wazvq6opodzwjg5sc5w5kwxehmxd4wcdpt4s4j2k4dx4apq
|
||||||
|
cerapadus.i2p,zroed2cxga5zeuu6rcvmp2yfi77nzduw7yhdplbeuqkuyxwbrzaq
|
||||||
|
cerebrum.i2p,u5gtsfn267udwfh2uq35jiabkufifvcbgv456zz34cydutsiw2eq
|
||||||
|
cgan.i2p,43z65gdr52xe3fxmkumwp3dzhedu4tu4rdtzr24hz5b4awcpfbqa
|
||||||
|
chat.i2p,ollpwnp6yidc3obbb3famgt6rw5jg5w3k3a6z7hhaegj6gcohiuq
|
||||||
|
chess.fillament.i2p,tv6wbanei647yf5bie4dhg2wmybkjurezlpdfwftc5ajqlfswwya
|
||||||
|
chess.i2p,sbnoqznp5yzxals3vs6nzyqaj2fetvonys4e3b3x4ktmfeus54sa
|
||||||
|
china.i2p,wit6f2zx6dtuqqze6nhbykrds3idppfirxvhf2f7ydqoqf4xdzeq
|
||||||
|
chitanka.i2p,u4s3jneepk3akoez46kqiwikoezi6zyj2ibjkjyi4uuvsbcojzba
|
||||||
|
ciaran.i2p,2r3645eete6xwbfu62ogonudcrcgqq25sbnij5v4geru74yrscna
|
||||||
|
ciphercraft.i2p,7s5pkqbpbfdkxtwuu2e2iwstbikyewvvscy76lij4x5pfbygbjca
|
||||||
|
closedshop.i2p,6fg67mbw2okopzyonsck4bsy3cy7l2fame56uiysr2cezhjhzdbq
|
||||||
|
cneal.i2p,g4za73ffigv3ht4jnhzy4dae52djjq7lqcguqsfg3w5cxzqm7nba
|
||||||
|
co.i2p,3mvo5eifcwplcsoubtvqkzdahwo2sdhfygfdde7lj2glybk4q22q
|
||||||
|
codevoid.i2p,2mukrqwtinsw27uoejtrz74zxtilyhnnfdyso7j3yo6vaa6nzlaa
|
||||||
|
colombo-bt.i2p,cyr75zgiu2uuzap5zeosforbgvpfbqos2g6spe4qfulvzpyhnzxa
|
||||||
|
complication.i2p,x2av6rwj5e5tp64yhdmifdyleo4wblw4ncrrcrabxwscuevpdv7a
|
||||||
|
comwiz.i2p,6p7zqfotzbd66etl5xqy3p6xvr5ijucru3am2xqa7wmnj6vf3djq
|
||||||
|
confessions.i2p,lh5vitshufxpmyr44zgyymebo5elc42eda7pxvn5lmtes47c7rxa
|
||||||
|
connelly.i2p,5yrris3nigb3fapvzrlrcaew6cdmzdknzvgrc7y2jpn3ntqurweq
|
||||||
|
costeira.i2p,abhty5xlmnyab2kqdxcd56352kcescxoux3p6dbqdrghggyygnxa
|
||||||
|
cowsay.i2p,q4ghzfpah4ffvm3bhc6fdkrznk5f6jxfjm2daytlparznai5d54q
|
||||||
|
crstrack.i2p,mm3zx3besctrx6peq5wzzueil237jdgscuvn5ugwilxrwzyuajja
|
||||||
|
crypthost.i2p,zywhrxtnkjc3rxxvxbocom7ml4hnutomgtuvqrwyf3rhuupnq5ca
|
||||||
|
crypto.i2p,vffax5jzewwv6pfim55hvhqyynafkygdalvzoqd74lkib3hla3ta
|
||||||
|
cryptostorm.i2p,mlu7mswyirjf53usqq7gyamvqc6rqihezgdbevov3dkxmkfo57aq
|
||||||
|
curiosity.i2p,eomeif4xrykxlzhawc3icdilje5iammijos6tyizwhrfh3j7qdvq
|
||||||
|
cvs.i2p,yd6k7dzpsa2tnlzx4q7xqkmd4qsjk5xk5hbiqpiarwbeyvxaxgba
|
||||||
|
danwin1210.i2p,eoqdf4no5dxn4tw5n256kkd4lzz3uk4p47np4mepsykpsdzrnvba
|
||||||
|
darknetnow.i2p,gkx3o5fy7mv7l4psqqnhp35d5iun7rt3soci6ylf3rgb7a5a655q
|
||||||
|
darknut.i2p,2mk37gtvpk2i63o6vl7vna4dr46rqexxetupgn5efuuins7x3qya
|
||||||
|
darkrealm.i2p,gbh4eerxdsph7etxsxznfhvmuiz54trlkenakqep343u4xcoekzq
|
||||||
|
darrob.i2p,hz2xhtpeo6btgiwi6od4qj2575ml5o2246rd5orarruyjhd63zja
|
||||||
|
dashninja.i2p,dzjzoefy7fx57h5xkdknikvfv3ckbxu2bx5wryn6taud343g2jma
|
||||||
|
davidkra.i2p,nq7ca2egm563nir3xegfv52ocgmxstpz56droji4jgnzfoosk45a
|
||||||
|
dcherukhin.i2p,qa4boq364ndjdgow4kadycr5vvch7hofzblcqangh3nobzvyew7a
|
||||||
|
de-ebook-archiv.i2p,6mhurvyn6b6j6xa4a3wpuz7ovpsejbuncvyl6rnhepasfgdgmn7q
|
||||||
|
de-ebooks.i2p,epqdyuuhtydkg5muwwq47n7jvr66pq4jheve7ky5euls6klzwuyq
|
||||||
|
dead.i2p,7ko27dxvicr2sezvykkrfiktlghx5y5onup3f2bas5ipocy6ibvq
|
||||||
|
deadgod.i2p,63bveyh7wefb44hlia7wtxxb3jal3r67thd6jekmwrtq4ulaaksa
|
||||||
|
debian-multimedia.i2p,cylxxz2y35x6cvyrl57wu3brckurtexatyi2i5awz3eeamqwjspq
|
||||||
|
decadence.i2p,pw5ys7k2grjb5myydpv6ohikm6nna7y6u2dro44i4rucgulu3ikq
|
||||||
|
deepwebradio.i2p,2nait2gdeozkgf6gyhzjfij6mwldwkxxwcvtxobb4b5q5cvtm5la
|
||||||
|
def2.i2p,cepsrw27kdegwo7ihzouwvgcvw2obswwjs23ollgj7hk2yrce3da
|
||||||
|
def3.i2p,xbf3ots2purqun7orn72ypkpjmrzbfrkj3u654zfe77hbrbow6la
|
||||||
|
def4.i2p,yyzdq4fwwmnlojp23drfpfqujln2vcjozjrfzfeuriuqzdq7g4mq
|
||||||
|
deploy.i2p,ujzspsqkbz5z272eozsrdv4ukl434h3fuliwrfxxnab74jmd7e6a
|
||||||
|
det.i2p,y6d4fs3rpqrctuv77ltfajf5m4tl4kzcu7rtwhxgiohylfxxow4q
|
||||||
|
detonate.i2p,nykapdsjjswdkjov7x3jzslhg4ig3cpkhmshxqzijuhbisx25jja
|
||||||
|
dev.i2p,cfscxpnm3w3qxnlv3oikewxm4qrot4u6dwp52ec2iuo6m7xb5mna
|
||||||
|
di.i2p,3irnooyt5spqiem66upksabez4f3yyrvvjwkmwyzlbealg64mgxa
|
||||||
|
diasporg.i2p,edvccoobtjukjgw2os5eetywanbb2mpag5aknkrpia5qx2koksua
|
||||||
|
diftracker.i2p,m4mer767ipj7mq6l7gdrmrq37yzvsj3kzezd7n7nsfuctntjseka
|
||||||
|
dm.i2p,heysbdivyeugdbggpscco5wje3dsvwgcpp5ot4sopooebnmiqvtq
|
||||||
|
docs.i2p,ato242wckzs4eaawlr5matzxudt6t5enw73e4p6r3wajwkxsm3za
|
||||||
|
docs.i2p2.i2p,las5l45ulwwf5i72nht6vk33sfkidcpr2okpf5b6mvgbk3a2ujna
|
||||||
|
downloads.legion.i2p,xpmxdpuuptlekyhs7mmdwkvry7h2jbvpqpzsijqe3a5ctxgodesq
|
||||||
|
dox.i2p,vk27cjdrtegfdnrjqutebgxkpyrfj42trdfbsupl5zn2kp34wb3a
|
||||||
|
dropbox.i2p,omax2s5n4mzvymidpuxp2yqknf23asvu54uon6cxl6gdrlblnuiq
|
||||||
|
duck.i2p,3u2mqm3mvcyc27yliky3xnr4khpgfd4eeadhwwjneaqhj25a65ua
|
||||||
|
dumpteam.i2p,2fwlpuouwxlk2nj4xklvm43m52tqyhqnu2fcfiuv7clvf3wd5nwa
|
||||||
|
dust.i2p,u6xgh6zhhhvdvefbqksfljfs3nyjvqcrmyamp5bryz5f4injmniq
|
||||||
|
dvdr-core.i2p,fg6l2ej6qrk5rkyfzdptxx5xkcm4kvdla4gg2tun7z7fm5cxxw5q
|
||||||
|
dyad.i2p,7n2ljphvp2dep7imoujvydxp4myuxfld3axwfgcny5xc5x6jj6ka
|
||||||
|
e-reading.i2p,z54dnry6rxtmzcg7e6y3qtsig5yf5fmehuvakcg5wnuahx3iafuq
|
||||||
|
easygpg2.i2p,bwxry5alzx5ihgrd3glah4eotddblzhalvpheppnw4zcajzqoora
|
||||||
|
eboochka.i2p,ou7g64d5in4sugv5fgmmzwnunuw5hloixio7puthmrvrkwrp6egq
|
||||||
|
ebooks.i2p,bvpy6xf6ivyws6mshhqmdmr36pruh2hvoceznzeag52mpu647nzq
|
||||||
|
echelon.i2p,afvtspvugtd32rsalxircjglh3fhcjzk7gxrm3gw4s2yrpvzk6wq
|
||||||
|
echo.baffled.i2p,bfr3lyicr72psxvt2umqfb562rtex66w6q3hi3tktzkoyane2iha
|
||||||
|
eco.i2p,2dq2o5h6c6a674qaduipp55mid5iktumjbswuwmpsrcqaeowdvwa
|
||||||
|
eddysblog.i2p,ieac3ub4g5sy3wuhsbqfembnpp7f3a37xgcx537ytzsmgfzexnbq
|
||||||
|
edge.i2p,aknsl5wmzjmwyc4wxutfdwy2w5vgd3vcx52mqx647hcgvyurmqta
|
||||||
|
eepdot.i2p,t6edyotbxmxvy56fofdvmragvsj65te2gkhvzv5qnblicutyvgoa
|
||||||
|
eepshare-project.i2p,sn26kom4qyuzouppv4lwnk6bqabdydcegtrilybviibwiq2s4nfq
|
||||||
|
eepsites.i2p,isskhl4ak3g7qevrarlmblddgr4ugnn3ckalwpjcvxafk5rjgypq
|
||||||
|
elf.i2p,duz6ey27ohpcp3llylklzdb63lylolzcixad6bh7rt5tkq42qqpa
|
||||||
|
elgoog.i2p,z6hrgkg2ajmuzlrddjlffrgctx7x7fkipm6c4hdzmohyn5wkr4ya
|
||||||
|
ems.i2p,734zw4jsegdf55zl3z6s22tqkbxcghu4qvk6q2wevjfmx7xhbn6q
|
||||||
|
epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
|
||||||
|
es.hiddenanswers.i2p,cw7ge5ey4ekp5iep2kaw6j54boebtqytpcbnvio2bfpccd5ejzfa
|
||||||
|
eschaton.i2p,xe75f5hzmrq6rkhsef2geslmi2v2yfngdiysmlmxvh7b4pyyjk4q
|
||||||
|
esuwiki.i2p,cwxuiwcpymb72vm5vluba66ofhugyf5qeevvwo7e2fqrxl243coa
|
||||||
|
evil.i2p,ljfl7cujtmxfffcydq77pgkqfxhgbikbc6qxjgkvcpn4wzd73a4a
|
||||||
|
evilchat.i2p,s5b7l3hzs3ea535vqc5qe2ufnutyxzd63ke5hdvnhz24ltp3pjla
|
||||||
|
evilgit.i2p,mx5vyoqhg77yuhthwznsxrepjsemq4uwitx4lxdzetk36ryl5rla
|
||||||
|
exch.i2p,vsyjsbbf2pyggtilpqwqnhgcc7mymjxblamarmxe5hmbxaxvcndq
|
||||||
|
exchange.gostcoin.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
|
||||||
|
exchanged.i2p,ylmulgfskl6uiwac4hw4ecwqdzd3oxtwaemzj25zc6k5q4rkexra
|
||||||
|
exitpoint.i2p,5zmjurq3enudcenegnxu5hqmfmayz4lxvnik6ulch4xssa2ithta
|
||||||
|
exotrack.i2p,blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva
|
||||||
|
explorer.gostcoin.i2p,ktoacmumifddtqdw6ewns3szxths2hq2fat2o7xnwq4y3auga3za
|
||||||
|
fa.i2p,6n6p3aj6xqhevfojj36dixwbl4reopkhymxmatz7ai5sroh75rka
|
||||||
|
falafel.i2p,djpn5cbcgmpumwcriuzqistbae66txca2j4apjd2xesfgb7r5zmq
|
||||||
|
false.i2p,77mpz4z6s4eenjexleclqb36uxvqjtztqikjfqa4sovojh6gwwha
|
||||||
|
false2.i2p,j5i2tfumh3ti5sdtafwzzbpupmlcbg5drysfay2kxbdpsaljrosa
|
||||||
|
fantasy-worlds.i2p,62a4xcyyhvfrcq2bkckb7ia37fmrssrgx467tlkxp32fjpq577wq
|
||||||
|
fcp.entropy.i2p,de6h6ti5z3mcbdcwucu45vplikqyoeddsu3rqy7s2zy5i47j3peq
|
||||||
|
fcp.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
|
||||||
|
fedo.i2p,zoamh7e3k2vf2g6pfy46ho4taujk2f4mxqqsv3gbg554fxbvyfqq
|
||||||
|
feedspace.i2p,kvtnpx4jylgeyojfhix4x462sqn5uork3roml4sfzotkxx62i4wa
|
||||||
|
ferret.i2p,kkqie5qmja7bkf3iad4zxhrdarwj7kbrx2m3etn5kmba3shgwj4q
|
||||||
|
fido.r4sas.i2p,i522xmu63hfbaw2k54cthffcoqmeao6urjyq3jg4hddf6wf57p3q
|
||||||
|
fifi4all.i2p,v2stz6bsot7sbjzix5tky5dm5ej7gidmjnkvzqjju5xvz5sz6fwa
|
||||||
|
files.hypercubus.i2p,qfglq25jwieszgyt7muz6dambzqsrmjhhszygzzx2ttubc77sffa
|
||||||
|
files.i2p,w2sy74xe6oqnuz6sfh5fhkzu7boholgzd5f3anhj47srxwpj2vaa
|
||||||
|
files.nickster.i2p,yil7dp2hg5pbqyovsiwb2ig6zjsq4tize3fnwemmqdrr6j5itdtq
|
||||||
|
fillament.i2p,udj2kiino4cylstsj4edpz2jsls77e32jvffn2a4knjn4222s2oq
|
||||||
|
firerabbit.i2p,awqh7n3wskzl3epyvkdwgarmfybsncm7vye6psg4tpkmplh3mj2q
|
||||||
|
flibs.i2p,ocdm33e3h5tdml3yyholj4objdwsrhlugfqjnqgdkslmgdzb6b3a
|
||||||
|
flibusta.i2p,zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq
|
||||||
|
flipkick.i2p,aso5rzc4ym6g2bcbxjy2n573bmbenkjawva2jg7fhyqhwtwgu6lq
|
||||||
|
flock.i2p,hflpi33ko5bi2655lx6bpzstdnjqgzrz23inovqjx5zpntyzyb3q
|
||||||
|
floureszination.i2p,vitpvfb25sikuk3crgcvtcdi7hajxnnq2t6weay3no7ulur2wwwq
|
||||||
|
forum.fr.i2p,onvelkowkbuwrglhw2cnocggvbdudi75sll5mfirde3cbopjqivq
|
||||||
|
forum.i2p,33pebl3dijgihcdxxuxm27m3m4rgldi5didiqmjqjtg4q6fla6ya
|
||||||
|
forum.rus.i2p,zd37rfivydhkiyvau27qxwzmerlzbqtthsa5ohtcww62zrygjaga
|
||||||
|
forums.i2p,tmlxlzag7lmkgwf6g2msygby3qttxvm6ixlfkq6s6cpgwubp33ya
|
||||||
|
fproxy.i2p,keknios3gm6kh6onez6x2bm2t7stv54oanvltuagphgdfjdw5e2a
|
||||||
|
fproxy.tino.i2p,fpaituvuvyxp6xdjnv3i27alnj2ifzcvqdweqb6yj5uybotzvyha
|
||||||
|
fproxy2.i2p,r4lgw4wmza25g7j5fjocjbwzwthfg4ymcbm52ref3hh2hogskcza
|
||||||
|
fr.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
|
||||||
|
freeciv.nightblade.i2p,rluupsgxbvw5t7jno3apyzlrdirjkljft4gdoy4mxxh4fmd4xzta
|
||||||
|
freedomarchives.i2p,4ck6oliqfjz3sccpya2q4rh5xkj5xdxkqs76ieml37537nfhwd2q
|
||||||
|
freedomforum.i2p,abzmusjcm3p3llj4z7b5kkkexpsxcnsylikokouk5txfim3evqua
|
||||||
|
freefallheavens.i2p,giqnkltyugfmsb4ot5ywpvf3ievuswfurk6bjie4hxi2hh2axajq
|
||||||
|
freenet.eco.i2p,2kf7ovb35ztqkrurkm76y34jfpwi6go25xj7peznnmxrl7aieo7a
|
||||||
|
freshcoffee.i2p,sscuukigp6alcb3ylhkcugoejjfw5jqgtqbsbafw4hyku42lgc3q
|
||||||
|
frooze.i2p,m6ofa5dmyse4b4jg7kfmluuuc4pw5jqu6zh4qnboin4vropxepja
|
||||||
|
frosk.i2p,63naq7zb3hvbcppj2ng7qwf6ztusp4kwpyrzbt4ptafcdbu4pfjq
|
||||||
|
frostmirror.i2p,ycz3imuz6yte2zhlapmsm3bsvc46senvc2jxzwsbfdct5c72qulq
|
||||||
|
fs.i2p,ah4r4vzunzfa67atljlbrdgtg3zak5esh7ablpm6xno6fhqij35q
|
||||||
|
fsoc.i2p,vaqc4jm2trq7lx2kkglve7rkzxhhaptcwwl32uicx4ehf5k3hx6q
|
||||||
|
galen.i2p,4weo7zkxscxbcouiqx4mlnb35uwl2lromikzk33er3fljktyvi2q
|
||||||
|
gaming.i2p,rfxberwod6st2zc6gblqswxjl57nucgc3xrbwss43pe3dvqqzj4q
|
||||||
|
garden.i2p,qkk2dqx6nocycgt3vinsoc76cxkb4jreybcpgz3fcps2dbe4rowq
|
||||||
|
gaytorrents.i2p,fnggbr2t2aulr6rvlo4aehotx6wecfob7u3k2nxsnvtm4xex424q
|
||||||
|
general.i2p,5fklrsztdqpl3hkkwwrrw2rdowrq7wwhwb6h7avvk4fhansp4vvq
|
||||||
|
gernika.i2p,wpzqv3lxpecdsvcaadvbmrhhwlc7kp4n2mijdv2qjw3zr3ye232a
|
||||||
|
ginnegappen.i2p,kbhfkzx5jeqhfgss4xixnf4cb3jpuo432l3hxc32feelcmnr3yja
|
||||||
|
git-ssh.crypthost.i2p,llcp7jvz3hgtt3yzkdgjolwobisgvhv4xqa5a4oddejllyozur5a
|
||||||
|
git.crypthost.i2p,7frihhdcisdcyrzdbax6jzvx5gvtgwsm7m6kcem2tlaw4jtahbqa
|
||||||
|
git.psi.i2p,em763732l4b7b7zhaolctpt6wewwr7zw3nsxfchr6qmceizzmgpa
|
||||||
|
git.repo.i2p,vsd2vtgtuua2vwqsal2mpmxm2b2cpn3qzmqjoeumrrw2p4aot7uq
|
||||||
|
git.volatile.i2p,gwqdodo2stgwgwusekxpkh3hbtph5jjc3kovmov2e2fbfdxg3woq
|
||||||
|
glog.i2p,ciaqmqmd2wnws3hcpyboqymauyz4dbwmkb3gm2eckklgvdca4rgq
|
||||||
|
gloinsblog.i2p,zqazjq6ttjtbf2psrtmmjthjeuxaubi742ujrk2eptcsaoam4k7a
|
||||||
|
go.i2p,ll6q4lsirhwkln4dqxwqkh2xu4mu3jiy546b4uhe4fypyb4vvx2q
|
||||||
|
gonzo2000.i2p,nogsv7okydhbvrewv6hb4xdojncvhkusnyib4lglluc4uw67a37a
|
||||||
|
google.i2p,4p3ajq4cotnflmuv7fhef3ptop5qpm3uzzgp5bahxif3nc4w3ffq
|
||||||
|
gostcoin.i2p,4gzcllfxktrqzv3uys5k4vgkzbth4gqednwhfpt755yivm3davuq
|
||||||
|
gott.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
|
||||||
|
greenflog.i2p,zny5ftmhzxulxzyczmeat53qjnue2xtqv2clisc7dg76lwfceecq
|
||||||
|
gstbtc.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
|
||||||
|
gusion.i2p,4qyfdhizjixe2psu7wcvqufix5wlijocehpb2futurcmlhlktrta
|
||||||
|
guttersnipe.i2p,kizkhzes2bzp45widihremo6geepfk7dl6juourkvzuvlc6y3spq
|
||||||
|
hack8.i2p,un63fgjgi3auvi7zscznwqfol7ka4johgthvqf635mg3fefsjgpq
|
||||||
|
hagen.i2p,e2t6rqd2ysbvs53t5nnaf7drllkgk6kfriq3lfuz6mip6xfg644q
|
||||||
|
heisenberg.i2p,jz4quyw7zt63tmw65jfp76fblwadjss4iyi4puqdg3dye7oaqlvq
|
||||||
|
heligoland.i2p,gzrjm62ektpqjfsem3r3kwvg6zpjvvhvpjvwfxkm2ay4zu7sp6oq
|
||||||
|
hidden.i2p,iqodhhqo473qv5gwhjcs2bsrbhlqtpzgpnuumpastfiyhuwb2kyq
|
||||||
|
hiddenanswers.i2p,kj2kbzt27naifij4ki6bklsa2qfewxnkzbkgvximr4ecm7y4ojdq
|
||||||
|
hiddenbooru.i2p,zma5du344hy2ip5xcu6xmt4c7dgibnlv5jm4c2fre5nxv44sln3q
|
||||||
|
hiddenchan.i2p,6y4tltjdgqwfdcz6tqwc7dxhhuradop2vejatisu64nwjzh5tuwa
|
||||||
|
hiddengate.i2p,rvblcu54jvkkfffp3fobhunsvpgfc6546crcgzielzwe2s5m5hbq
|
||||||
|
home.duck.i2p,jsh7yfvm2t5urdcnmfzdy4n6vegqskdtlwem53chgxli4ipfmuma
|
||||||
|
hopekiller.i2p,kcaelbgsvrkiwpx36b4wxofebrl3njx7rgm5amzfmqwbomt44cxa
|
||||||
|
hotline.i2p,6cczi27iuxkm3aivazaemzltdqgh42ljzurqp43uclbz2lid2uqq
|
||||||
|
hq.postman.i2p,27ivgyi2xhbwjyqmnx3ufjvc2slg6mv7767hxct74cfwzksjemaq
|
||||||
|
http.entropy.i2p,ytu7kz5bdoc26nkpw2hajwt3q7n5rcbg2eokyefhmkxmmslimbdq
|
||||||
|
human.i2p,nrtcelq3humyfvoxmzmngpka6tmyifweouku5mbi5av4lc43hzaa
|
||||||
|
i2host.i2p,awdf3nnmxxup5q2i6dobhozgcbir7fxpccejwruqcde2ptld443q
|
||||||
|
i2jump.i2p,633kqgmwzzu6vhkevwvbf2pfyejt3gkes34i6upa4og57fgdfcxa
|
||||||
|
i2p-bt.postman.i2p,jeudwnx7mekjcowpqo6xpkwn7263c57y5piurrjrdzinjziu4fla
|
||||||
|
i2p-epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
|
||||||
|
i2p-javadocs.i2p,icgmr6hhjudl4yxhtuq4pxvss2pzypwddzowajgs5rdz6f55novq
|
||||||
|
i2p-projekt.i2p,udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna
|
||||||
|
i2pbote.i2p,tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a
|
||||||
|
i2pbuggenie.i2p,bioq5jbcnfopqwvk7qssaxcl7avzeta6mu72jmxjeowflpcrhf6q
|
||||||
|
i2pchan.i2p,tduxyvfs7fzi26znvph3mu2d2ewaess7emomfci22wvownajphuq
|
||||||
|
i2pd.i2p,4bpcp4fmvyr46vb4kqjvtxlst6puz4r3dld24umooiy5mesxzspa
|
||||||
|
i2pdocs.str4d.i2p,yfvbtrhjac3jutdsqzugog6mbz3jtyhpwovrt2mqc5mzv534y7cq
|
||||||
|
i2peek-a-boo.i2p,qgv64klyy4tgk4ranaznet5sjgi7ccsrawtjx3j5tvekvvfl67aa
|
||||||
|
i2pforum.i2p,tmipbl5d7ctnz3cib4yd2yivlrssrtpmuuzyqdpqkelzmnqllhda
|
||||||
|
i2pjump.i2p,2mwcgdjvfvd3xwumzqzqntual3l57h3zo7lwdmkjboeraudpkyka
|
||||||
|
i2plugins.i2p,bb63kmnmbpitsdu45ez54kmogvvljn3yudksurcxiyq7dn5abt7a
|
||||||
|
i2pmetrics.i2p,v65p4czypwxrn35zlrfkar2w77vr42acd7gbszegsrqq4u7sip5a
|
||||||
|
i2pnews.i2p,tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq
|
||||||
|
i2podisy.i2p,3c2jzypzjpxuq2ncr3wn3swn5d4isxlulqgccb6oq5f6zylcrvcq
|
||||||
|
i2push.i2p,mabdiml4busx53hjh4el5wlyn4go5mgji2dxsfyelagi4v5mzjxq
|
||||||
|
i2pwiki.i2p,nrbnshsndzb6homcipymkkngngw4s6twediqottzqdfyvrvjw3pq
|
||||||
|
iamevil.i2p,au7jhslyt4cxkjp365bvqvend3hhykrrhbohtjqlgoqrlijbezja
|
||||||
|
icu812.i2p,bxgqwfsnr3bgnr6adn62anjcin5nuthqglotb3wn3dgynsfofeva
|
||||||
|
id3nt.i2p,ufuqdzsxltiz224vq5gnuslt3a3t72dhy5kq6i2xway53m6pzv6q
|
||||||
|
identiguy.i2p,3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva
|
||||||
|
ilcosmista.i2p,6u2rfuq3cyeb7ytjzjxgbfa73ipzpzen5wx3tihyast2f2oeo24q
|
||||||
|
ilita.i2p,isxls447iuumsb35pq5r3di6xrxr2igugvshqwhi5hj5gvhwvqba
|
||||||
|
illuminati.i2p,syi6jakreatlm2z22u76izyqvbm4yi4yj7hr7jb63lgru5yhwwla
|
||||||
|
imhotep.i2p,qegmmhy52bdes2wqot4kfyqyg7xnxm5jzbafdb42rfoafadj2q7a
|
||||||
|
in.i2p,r5vbv2akbp6txy5amkftia757klgdy44s6cglqhmstpg65xycyjq
|
||||||
|
infosecurity.i2p,v3gkh5kqzawn2l3uzhw6xnszsh6w3nztjmlwil7p4kyrwrsm2dba
|
||||||
|
infoserver.i2p,jd3agbakybnhfvkeoxrx7t33iln6suzomv3kxkxf77j7rkonch6q
|
||||||
|
inproxy.tino.i2p,ex5yf6eqqmjkrzxnkn6cgvefgne24qxsskqnpmarmajoit43pgma
|
||||||
|
inr.i2p,joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq
|
||||||
|
instantexchange.i2p,5wiyndm44bysev22kxvczxt37p6o6qroiqykytrvn2yzi55aqfxq
|
||||||
|
investigaciones.i2p,n7hqd4asxrdwf3zwo7rzv27y2qkcfmakmz6mjar6aw6hlc4c7mha
|
||||||
|
invisible-internet.i2p,jnpykdpp46zenz4p64eb3opadl5g42dls3rurk2cvq6a3g3rvbvq
|
||||||
|
io.i2p,tx22i6crnorzuti3x6va4mijsbhoqswy2cfdxjbvprgsq4eerg7q
|
||||||
|
irc.00.i2p,bvcja52pppgfspp2ueuipoysjnvvoyblz2h6smpxcmanjquogirq
|
||||||
|
irc.arcturus.i2p,5nywlbn35p2nwsymwpfmicu6fxono6g64vwusxbsvmm2qwz6vupq
|
||||||
|
irc.baffled.i2p,5zmtoopscym6qagkvpgyn7jnkp6dwnfai745xevkxlou77c2fsjq
|
||||||
|
irc.carambar.i2p,hxzbpivxqxy6nuae4t6fnkhcgnhs4c72vt6mmsqfmfhrkn2ca6gq
|
||||||
|
irc.cerapadus.i2p,e4ckznxcxvgyikzjmjsu72i2dbj2d76ogexyukklbjvpcnhp6zzq
|
||||||
|
irc.dg.i2p,fvp3pkcw4uvijqabwtekcdilklp73gyasuek67wdcs2mucep4caq
|
||||||
|
irc.duck.i2p,chdpmm4gxffyn24xx5dhxvfd5httu42i5gtoe6cctjlsf4mbofeq
|
||||||
|
irc.echelon.i2p,ez2czsvej5p3z5bquue5q3thujcodfze7ptybctqhnqc7hms5uzq
|
||||||
|
irc.freshcoffee.i2p,ubiu2ehtfnrleemgpzsqkahwnvzuaifqa3u4wmaz5maaisd5ycfa
|
||||||
|
irc.i2p,l3ohmm4ccxvyuxuajeaddiptci5lsrnxtvtyq7iohphrt3oj2evq
|
||||||
|
irc.ilita.i2p,5xeoyfvtddmo5k3kxzv7b3d5risil6333ntqrr3yvx3yubz5tk3a
|
||||||
|
irc.ircbnc.i2p,4rqcsqd7xif6r4v55blqvmqu5er6due4eyene3mjorfkts4o3rxa
|
||||||
|
irc.killyourtv.i2p,wre4majmg2vnbi6id27et7yw6lnpf56wkbm6ftnlwpvxnktq73hq
|
||||||
|
irc.nickster.i2p,dhq3fhd5scw3jqhj5ge7kqfpprfolcgxfjbaw24obohaiqjtdu7a
|
||||||
|
irc.orz.i2p,7gifacog4aoons3syybojbbnyqqaaqijhngrehn2xlq3eucuyjcq
|
||||||
|
irc.postman.i2p,mpvr7qmek2yz2ekegp5rur573z7e77vp3xqt2lfbco5i6nkfppcq
|
||||||
|
irc.r4sas.i2p,hodhusp73gltozgrnianlbploon3rrvhrzfn5mf2g46o7aaau5la
|
||||||
|
ircssl.cerapadus.i2p,4x2i745i4w52ss3he2kse6tzwt64pr62yvrcb72lgvrb63fup6ea
|
||||||
|
irongeeks.i2p,ecduxoion5uc5hnvzjxff6iiwhdwph6gse3dknyvlo7e6gaeho7a
|
||||||
|
iscofsi.i2p,enjgdxs4um2dmhdb2ajff2egrdijkjji3g47m6unb74swbrqsddq
|
||||||
|
isotoxin.i2p,wue3ycaccf4texikza3fh6p5yrmtgnooisuypnepo5mo67lmpcqq
|
||||||
|
itemname.i2p,o35ut7hgywy35okvgkjkv3ufzv2ejv4luap4oytwbyy2jqy6u4vq
|
||||||
|
ivorytower.i2p,fpwrfvidfexsz7dspofkwtkmmizm7lyralfz5kvykffk7gubvxsq
|
||||||
|
j.i2p,kjxvohlsf5sdrzxzfcrmvquccnoevi6ytbl63mstsru5wt2dx3ea
|
||||||
|
jabber-2.i2p,pvnmzgemetkwcuvt45omgowmeznwk5xw3nc3ygeoz7yekqxy57na
|
||||||
|
jabber.duck.i2p,rhdzvvzraqzzm67zpyegb7knpfrjeffitixqzeyymdoz56uh2rtq
|
||||||
|
jake.i2p,v2axvy6pqefnla7gun5fmqs4lqe4xfyqovgzcundhxrpcdvfd7cq
|
||||||
|
jar.i2p,2fthkmujup3xiiu3yple24n6g4emzdiiimbuqwvpdddtsr3c4nrq
|
||||||
|
jazzy.i2p,ha5c3zafwkt6mwqwjcf4oqwvbwz473652ljjadiwrj4gfkfkjofa
|
||||||
|
jdot.i2p,kw4jr5qw4bhnj33avkwankjdh3zi7wtahlmgkjwvsv2isskkzgpq
|
||||||
|
jhor.i2p,c6rnm7oemydhuwzmhwwwxphkzanez5rnn7fkcs3lpgu6gkgtssoa
|
||||||
|
jikx.i2p,aazr55itvyns4lwppvx5njyx5tjdwemw4w6jbmpegdunznod2ieq
|
||||||
|
jisko.i2p,jxgfvr663uhr6m65hrgkscshysfshkq32ywdubc4ed7zda3e2pca
|
||||||
|
jmg.i2p,oglpnq7zungdukmk6gk5fzj5jp6wibuoihqgks453wztrwos4ggq
|
||||||
|
jnymo.i2p,nbfplxgykyfutyadlfko2rmizdsxox2pee2ahboj5mju4s3putda
|
||||||
|
jrandom.dev.i2p,htynimemonyzqmn76gworxyfkmqtsa7zcprbrd3i5cxqqm75tuzq
|
||||||
|
jrandom.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
|
||||||
|
jrrecology.i2p,qxi24gpbum3w3kesuxvheyu3p5u5o6tuvoypaolub2gnvbld57xq
|
||||||
|
jwebcache.i2p,xdffxnxtjd6ji2zig3cgva7igvl2tiapyjoc7ylbzwqhxudbmvfa
|
||||||
|
k1773r.i2p,zam7u6vslhemddz347uusuzjdk5wma4h5hcmcqlng4ybbpdbjhnq
|
||||||
|
kaji.i2p,z5ic7gvm2k4doczphtrnrspl2w5sfbss2de4z3ihjijhtjw67ydq
|
||||||
|
kaji2.i2p,4lscgc6napekfx7ay5fdcjofeja4fnl7tqcd3fek63t4saavur2a
|
||||||
|
keys.echelon.i2p,mwfpkdmjur5ytq4og36ym3ychinv36b2a57f4rmgqmtrwepq3fva
|
||||||
|
keys.i2p,6qv4x7ltaxckd4vbay5s4ntqqflq4efk6oke2d5yzicqrmk443ba
|
||||||
|
keyserver.sigterm.i2p,isoxvnflrdn7cm76yjlfg5tbcugoito2hur7eidbqmo33xmwz5ga
|
||||||
|
killyourtv.i2p,aululz24ugumppq56jsaw3d7mkbmcgo7dl2lgeanvpniyk2cbrda
|
||||||
|
knijka.i2p,knjkodsakcxihwk5w5new76hibywia5zqcgoqgjttzsausnd22oa
|
||||||
|
knotwork.i2p,2yocdbcjiyfaqgxb4l6oenrrrrie6nydgmbnbfulqg7cik6bozxq
|
||||||
|
kohaar.i2p,qchpjehbhqjbxdo7w3m55jbkrtsneb7oqoxcr24qttiq6j5g3z5q
|
||||||
|
krabs.i2p,3yamyk5bgfgovg6zpvtvpdjk37ivjj2wog2w7wha5agzgxxkqaca
|
||||||
|
kuroneko.i2p,wbit2huhhwlyqp2j4undccuyrodh6qcmzdeyuaoy5o4ym7g5gdgq
|
||||||
|
kycklingar.i2p,gctswdhp4447yibxfbqg3uq2bvx63qjeqnaoaux75zw73leakyva
|
||||||
|
lazyguy.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
|
||||||
|
legion.i2p,5oirascyhwfy2tr2horw6mixozsre7z6s7jfq7qbnj523q3bkebq
|
||||||
|
legwork.i2p,cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a
|
||||||
|
lenta.i2p,nevfjzoo3eeef3lbj2nqsuwj5qh3veiztiw6gzeu2eokcowns3ra
|
||||||
|
libertor.i2p,7gajvk4dnnob6wlkoo2zcws7nor3gunvoi7ofalcps5lc76wruuq
|
||||||
|
library.i2p,brqqaq44vbeagesj5o3sxcnkc5yivkwouafyxa77ciu7l644ei2a
|
||||||
|
lifebox.i2p,pyqjnycm55cuxow22voqj62qysrjdnb6nbyladaiaiirqi7vp2yq
|
||||||
|
linuxagent.i2p,ap5riaikrjq2uv5qvy7klzhhqywvqi7wqscyipsewcun7w2eynlq
|
||||||
|
lists.i2p2.i2p,vmfwbic2brek2ez223j6fc6bl5mmouzqvbsch45msvyyzih3iqua
|
||||||
|
lm.i2p,yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q
|
||||||
|
lodikon.i2p,u3f67staiwhqxpacya3clmvurdwd2kp7qcthzhstqnhrmlwc2g4a
|
||||||
|
lolicatgirls.i2p,a4lzmjyba7aq7hl6okqpds7znnwymolqnr7xhvno2wraqb7uhfla
|
||||||
|
lolifox.i2p,7fd2clkiotjnaoeigdtxlkkb24eik675ovezjf67x26ysham4zca
|
||||||
|
longhorn.i2p,pohcihzxzttjclrazhs3p76wt3ih737egb5bovqb6ym3du6z3o7a
|
||||||
|
lp.i2p,jiklbujn3cbfikf4pca526jgmorx6mxhil3twqmfoteaplx6ddwq
|
||||||
|
lucky.i2p,wx36m3wnpt2y6bngdpg3ifrarvtkpwnluarx377bllpgvkuhybaa
|
||||||
|
luckypunk.i2p,y4t6cujjxnnrtln3rgmfbgbh46hic7wkef57krd7opitbgngohka
|
||||||
|
lunokhod.i2p,3yc6sp7xic4grmpfecbwuij6z3dp5kdgoo362pszaco7io42mnwa
|
||||||
|
m16.i2p,ucsr3eveuc4mx5y6gxnoaywd4ojvbel5q3ynns6s5yfw3vusmfva
|
||||||
|
mac7.i2p,3yjowssqzydciwa5zx55kazgf7q7w6g7rkocr7bngy35ii44t34q
|
||||||
|
madman2003.i2p,a2sam2xbhxbzmeyobphbxrkdwlppoerewq5qvibbyk3ftsr643qq
|
||||||
|
magix.i2p,cgfnyxv62msfynsfbv3kju22j2mt6tfnopshhmrcmpcrxyts6xwq
|
||||||
|
magnets.i2p,snz46nez6hrrpg6336neinflw56l3vwatk6bzzytwu77xmsfsoca
|
||||||
|
manas.i2p,6qolj62ikkoq6wdn3hbvcbdmlvf2rcyv432kgi5uy7mvrczmjtba
|
||||||
|
manveru.i2p,pbmbofs76wpjnxi55eqtwg4y6ltyij72o4fm4sxfjol3y57ze5sq
|
||||||
|
marcos.i2p,vpo36bsil2voqaou53zshuegssqaroa5mbrzxfmhjywlbojckalq
|
||||||
|
marshmallow.i2p,svdqd6j3y3gwryufcl4fkzpmcujgvrvphvk2oy4r7m75xs327e2q
|
||||||
|
marxists.i2p,lepah55qyp2fhuwxlz7bwrhzckn4gkuofivnofoeuyfpmke5x2hq
|
||||||
|
mattermost.i2p,x5oovnhnuli5fnwtgkbd5z5jvrvdvprqyuofywx6uoxkk4bie6ya
|
||||||
|
me.i2p,dbpegthe42sx2yendpesxgispuohjixm4bds7ts5gjxzni5nu6na
|
||||||
|
meeh.i2p,4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa
|
||||||
|
mesh.firerabbit.i2p,3x5wokr4bjy5z3ynji4fyhvwzv4fvgry3xafi5df5h75doezjytq
|
||||||
|
messageinabottle.i2p,avfhe3kvrrv7utxn2vre65lg7damxzzsewq3vukwie4llitd254a
|
||||||
|
metrics.i2p,z45ieamhex2ihqv7oowk5fz4qq47rbvxhhhbaaiinpajbhuevtpq
|
||||||
|
mhatta.i2p,o4rsxdeepfrnncsnjq675xogp5v5qkbfgbt6ooqeyfvlifobrjxq
|
||||||
|
microbleu.i2p,mtapervgibruizniems2yyr47pin2wpysyh7m632rigl26vjc6qa
|
||||||
|
microsoft.i2p,hvaqr5idszdyrjph34amb4mjosqd3ynggoxlnj7ciqhnx7q6plza
|
||||||
|
mindisl0st.i2p,u7rnqhvsuyxd3fabm4kyzn7brgz3i3cporj2emk2jmbpcmltyf7a
|
||||||
|
mindspore.i2p,uuh5dd3y2rqa7x2jpggm4p2pg6znarm5uanwsvybe4tk36ymwr4q
|
||||||
|
modulus.i2p,ctz3o6hdefrzwt3hlg6rjhdcbjk6irppbndq32u6jnn4lz72f62a
|
||||||
|
monerotools.i2p,5bal7dngxde2ddmhuzbtfken6w5nmxmixtjlrlmxt3wbhnemv73q
|
||||||
|
monerujo.i2p,puri6y5dtwh6zr4u77ep6ozatun6iz7v4wai2dzxppz7654corlq
|
||||||
|
morph.i2p,iovyp2dao5rta6g5v6hke2s4ugx2btkpcljddak2yhxfrx3l4dqa
|
||||||
|
mosbot.i2p,5bhmrp43mjwlzf4x64xgdrkwmw4luvng6eq5waa663a7vnkp732a
|
||||||
|
mosfet.i2p,s5ynkgagndmpxpf2kmnenv4x72io664gzd2x3qef54ilammnte3q
|
||||||
|
moxonom.i2p,gcjdrvnlobgexh7ebv276pwmnoj3yoyaqm3w4vmmdha4lgxfinqq
|
||||||
|
mp3.aum.i2p,n7bmu5dwux7f6gedmdik6zrm77bnls4lkzo2vo3bf4bwegk7vkjq
|
||||||
|
mp3.tc.i2p,w3ied5s7ldjcvnhxu2gyofe3oogzbplkyxshzfkhspiy2526snsa
|
||||||
|
mpaa.i2p,m6cqnglo7xlytwxkdsmwf3d23d6lq5r446c3tktb2tdmuah36zya
|
||||||
|
mrbamboo.i2p,tmpmkx6wlbbrgsnexrqlrib7laoegpbfeop7bnyezegii7hecpxa
|
||||||
|
mrflibble.i2p,u7k2qcmkrril6yvudvwxjqz7k3dzgp3jdejjjeapej7liselj3eq
|
||||||
|
mrplod.i2p,fjn5hxtybxyfyvdf6u5v5seg2sjd47hb5by6sa6ais4w3xnrxwyq
|
||||||
|
mtn.i2p,xisk3h6sku3iqj52uriogaajmnku7pwjux7wa4omx2zloamuw6eq
|
||||||
|
mtn.i2p-projekt.i2p,f52x5fp6uhq53f5zle5d6rq5un34xgmxgazvilvmzcby37xcmsfa
|
||||||
|
mtn.i2p2.i2p,l6kuhtmgvbp57d7jwalj5nksi6nr4gfzbz4oit62lxgipb3llt5a
|
||||||
|
mtn.meeh.i2p,h7ylrsuzzynrxp3jql7anoozyqblavj7eqces6o3wngvuuxhs2la
|
||||||
|
mudgaard.i2p,yz32lk42gtoesknesfolq3tt4erxxcejcote5pontaeqev3bj2kq
|
||||||
|
mush.zeit.i2p,dk3sg23kljawxqp3cb6xz5mnzjlyckzvq5jhqs5gnvdsv7wqn6ha
|
||||||
|
music.i2p,akamh76yi6p7xxbvl3qv3yhaockne57yfuh77acogbgpjmwypvia
|
||||||
|
mysterious.i2p,p66g2a4nzfkvidd3l7nwphcnfa3ttyu5kiolcb4czec2rn2kvwsq
|
||||||
|
mywastedlife.i2p,ceumy3puvvsrru5bmfmtgsajsx5qyehqac7l7a23xpwtfs2bvcgq
|
||||||
|
nacl.i2p,bm2fib3tumer72lopjh4nmqomwvqu2sdfyb2hmr6lnk7jbw3vvia
|
||||||
|
nano.i2p,ex5ssv7s3hj6jp7hvadxfw3wvbjbvnczxr4pbk7qw26ihiorjmba
|
||||||
|
nassai.i2p,v653cocvn3i6bgjdm3ciwbdnu32supglv6gn4fh23bohemsp545q
|
||||||
|
neodome.i2p,5hkhjehj3ct2pvcah7dcylwef2oti3xij5myxbv3pd7rocio5vkq
|
||||||
|
news-i2pn.i2p,wwcqkwfo5yhe6uribv5tzylk25j5hkdk6gdnyftzd3k7dawlzwca
|
||||||
|
news.neodome.i2p,trhwcnygfkeqjj6g4xhmrdp4gsjqsye47lsxshbmwbten4ywt5oq
|
||||||
|
news.underscore.i2p,rl7t3kspoktuatjcu7gf7xleu7y6biibs4fspzo24kll6n7hbq4q
|
||||||
|
newsbyte.i2p,gsk3rgsejxxrfabjxu5w5plplxsu47aoeoke22vvhlwwllzosnxq
|
||||||
|
nibble.i2p,jmdxcpdzqafedn3clc4y7u6o56qocfiffrzbzncmtggqtio5qjpa
|
||||||
|
nic.i2p,vzu5ymab6klevpcdudv4ypisjqaznmt44e6lcg7dwiuza4saibxq
|
||||||
|
nickster.i2p,zkwsa6kvq2wdhovw5g5wqakpb7rlaylyhfriwmurots5pvwbqauq
|
||||||
|
nickster2.i2p,eofzi7npzpk4p5gb4qper4hmwgxo6kepo3dheeblakewedxj2bwq
|
||||||
|
nickyb.i2p,gmpxk4tje7mnud32kg2kjmf36f6cpwqakzc2dxuzjnnz4qr5w4sa
|
||||||
|
nightblade.i2p,p4gkon7ytswxrbwkl7vruw6mg7kfw5aofovqjgt4c7tnqmbq6lha
|
||||||
|
ninja.i2p,q6dg6hlb3egzdqz352ri5rc4fx4gcrdeu3tpiyfxlv73yfjgrhya
|
||||||
|
nm.i2p,3itdpqzyn3ii7sivppo4sxxwhvgtpskzkbokrdibim6gqpvlw5ya
|
||||||
|
nntp.baffled.i2p,kc6muo2tih5mttbpzecteegvtonuysjidk3emcy4cm4yifzild2a
|
||||||
|
nntp.duck.i2p,gvzzor4utsqxswvf6jaglfks7yxudlz2s326ftrk56i4lpd2s47q
|
||||||
|
nntp.fr.i2p,npoztnqadfnu4vrokoh6rusoi3yne47s6jurc3lzhcrzzia5eqva
|
||||||
|
nntp.i2p,wwdzmeyler4djegvyt2bxmkwrckfgg3epkkwowyb75s47he6df6q
|
||||||
|
no.i2p,lpsg4x4gdrf7antxcdy47cl6abcqei5ommgzt55retq7go5ku3ba
|
||||||
|
noname56.i2p,oiyoslismzyxuw7ehxoigmtkdj35idim6flmlplddxuiiif6msfa
|
||||||
|
nop.i2p,ssag45lathm4gqp46si7c4w4tioyvjpcza5uvz5x2zuljnplylca
|
||||||
|
normal.i2p,j5fex634r2altzb3kjvu35qekt2r3hgsqzg5qxoy7dp53heu5pma
|
||||||
|
normanabcd.i2p,si2vh43gvxjnw2shwr24j76xyanow4oa6gbu4idookbraoxl3s3a
|
||||||
|
nothingburger.i2p,tesfpn757ysc7nih7mxher2b3jstkc3l5fhfcyb5kxhzhvv52trq
|
||||||
|
nothingspecial.i2p,wzrwqrp52bilqijrlboclynuev4kzpjzfzlvzl5aqxqt5fdnpbga
|
||||||
|
novospice.i2p,ukqap24nwac4gns77s4zy7j5cagt7l7syb5zo7eukfg3zn5gg5qq
|
||||||
|
nsa.i2p,nsetvbclpomqxfcit4mghn6z7vdhnza6jdzczby4crnto32uykga
|
||||||
|
nvspc.i2p,anlncoi2fzbsadbujidqmtji7hshfw3nrkqvbgdleepbxx3d5xra
|
||||||
|
nxt-wallet.i2p,33pp74k4ivy67z332qpyl3qlcqmi6gxqumrow4bldkblxxlxqq5a
|
||||||
|
obmen.i2p,vodkv54jaetjw7q2t2iethc4cbi4gjdrmw2ovfmr43mcybt7ekxa
|
||||||
|
obscuratus.i2p,i4j37hcmfssokfb6w3npup77v6v4awdxzxa65ranu34urjs4cota
|
||||||
|
ogg.aum.i2p,wchgsx6d6p3czloeqvna2db5jr7odw4v4kqrn4gr4qiipfyrbh5q
|
||||||
|
ogg.baffled.i2p,tfbvj2xal6lcuxv3hzuw7cw4g3whguombcv2zuotzvul4qtrimgq
|
||||||
|
ol.i2p,bnb46culzbssz6aipcjkuytanflz6dtndyhmlaxn3pfiv6zqrohq
|
||||||
|
onboard.i2p,qwlgxrmv62mhdu6bgkh4ufnxowxsatfb6tbs2zr666qyunwqnecq
|
||||||
|
onelon.i2p,irkvgdnlc6tidoqomre4qr7q4w4qcjfyvbovatgyolk6d4uvcyha
|
||||||
|
onhere.i2p,vwjowg5exhxxsmt4uhjeumuecf5tvticndq2qilfnhzrdumcnuva
|
||||||
|
oniichan.i2p,nnkikjorplul4dlytwfovkne66lwo7ln26xzuq33isvixw3wu3yq
|
||||||
|
onionforum.i2p,yadam2bp6hccgy7uvcigf5cabknovj5hrplcqxnufcu4ey33pu5q
|
||||||
|
ooo.i2p,iqp5wt326fyai5jajsa3vkkk5uk56ofn4anocgpe5iwlpisq6l7a
|
||||||
|
opal.i2p,li5kue3hfaqhhvaoxiw2ollhhkw765myhwcijgock5rs4erdqdaa
|
||||||
|
open4you.i2p,ice6ax5qrzwfwzsy64bctffj6zlzpuzdr5np65zsxlbt7hztyc6a
|
||||||
|
opendiftracker.i2p,bikpeyxci4zuyy36eau5ycw665dplun4yxamn7vmsastejdqtfoq
|
||||||
|
openforums.i2p,lho7cvuuzddql24utu7x6mzfsdmxqq7virxp5bcqsxzry2vmwj5q
|
||||||
|
opentracker.dg2.i2p,w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa
|
||||||
|
orion.i2p,5vntdqqckjex274sma3uqckwqep2czxs5zew25zlntwoofxk3sga
|
||||||
|
orz.i2p,oxomqkekybmyk6befjlouesit5mhstonzvzd2xnvsk7i6uyrqsfq
|
||||||
|
os3.i2p,s7x4ww5osrrfein3xgwyq67wnk6lgliw4mzt7shtu66wrb2zdojq
|
||||||
|
osiristomb.i2p,t3slf77axkv3qm7c3gzpv3jgmkraoqqe2bojr6h66eipibofsyzq
|
||||||
|
ot.knotwork.i2p,cxhvvfkbp2qbv5qojph7zb46molpe2ffanghnerjag3xdmy6ltxq
|
||||||
|
outproxy-tor.meeh.i2p,77igjr2pbg73ox5ngqy5ohzvrnur3ezqcogtl4vpuqtrcl3irsqq
|
||||||
|
outproxy.h2ik.i2p,nwgvfpfarpnyjjl4pwsxr2zdsppcx5we3kos2vlwicbiukopgaza
|
||||||
|
outproxyng.h2ik.i2p,v32zse2zczzgegelwxbx7n5i2lm2xhh2avltg76h6fz5tb53sfxq
|
||||||
|
overchan.oniichan.i2p,g7c54d4b7yva4ktpbaabqeu2yx6axalh4gevb44afpbwm23xuuya
|
||||||
|
p4bl0.i2p,lkgdfm4w6e2kkjhcdzr4ahhz26s3aunhrn6t2or436o73qh4z7ga
|
||||||
|
pants.i2p,xez3clscjfafkqwk6f473ccp3yvac4kh6rdp6dptwxa2lhixizgq
|
||||||
|
papel.i2p,mxskjqntn2d34q4ovsnd5mud7cgde734tdjldd3lt4hczh2645zq
|
||||||
|
pasta-nojs.i2p,dkkl3ab6iovxfqnp44wsjgqaabznvu7u3hugpzyagbeqlxgvx3la
|
||||||
|
paste.crypthost.i2p,2zaj4u4s4l3lgas2h5p6c6pvzr2dckylkrh5ngabursj4oh25ozq
|
||||||
|
paste.i2p2.i2p,b2gizskfea4sjxlw6ru2tb6kdrj47dsjc77cijsf5mzh4ogbmfvq
|
||||||
|
paste.r4sas.i2p,csen43keji3qiw6uobsgzysxyjd225g6446ylq5uuz6ur2glkzaa
|
||||||
|
pastebin.i2p,mnicncxrg2qqi55qftigiitaheugnj4rpysbk7zabdrirgktelqa
|
||||||
|
pastethis.i2p,erkqiwnjl7vtysqd3wvddv6tfvnhswarqkbn4blhdlhfxn7cf2ha
|
||||||
|
pdforge.i2p,wzeg3ehf6d2mqjqji3sd3rns776thvhe2vam2r6gjlmsqis2dctq
|
||||||
|
perv.i2p,f3k3wm4ae7t7ottfjd4hu6is7zsls73izl2gm2qynzficxcdsiwq
|
||||||
|
pgp.duck.i2p,wujajyxj3cgsfsbtr3g7g7npv5ft3de6pcstxlav26zq6cxdjmha
|
||||||
|
pharos.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
|
||||||
|
pharoz.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
|
||||||
|
phonebooth.i2p,noxia7rv6uvamoy2fkcgyj4ssjpdt4io6lzgx6jl6wujpufxedrq
|
||||||
|
photo.i2p,fqhuy77ugd5htnubzkyy5guvwboqn6goahtmn2g7feewvdj7k3iq
|
||||||
|
piespy.i2p,vzusfjzcu5ntnvobcvyzc4dcu4j6ommtnpmba2puk3kexgdzrl7a
|
||||||
|
pisekot.i2p,7yzdwhy723fodqz4onp6k3nyvixra2sa6dl45tcblhmyoa7i36nq
|
||||||
|
pizdabol.i2p,5vik2232yfwyltuwzq7ht2yocla46q76ioacin2bfofgy63hz6wa
|
||||||
|
planet.i2p,y45f23mb2apgywmftrjmfg35oynzfwjed7rxs2mh76pbdeh4fatq
|
||||||
|
plugins.i2p,wwgtflbaa7od2fxbw4u7q7uugmdclxf56alddvizugwcz5edjgia
|
||||||
|
polecat.i2p,het5jrdn35nhkanxmom5mjyggyvmn2wdj2agyqlrv4mhzhtmavwq
|
||||||
|
politguy.i2p,6dkkh3wnlwlr6k7wnlp4dbtf7pebjrph5afra2vqgfjnbihdglkq
|
||||||
|
pomoyka.i2p,omt56v4jxa4hurbwk44vqbbcwn3eavuynyc24c25cy7grucjh24q
|
||||||
|
pool.gostcoin.i2p,m4f4k3eeaj7otbc254ccj7d5hivguqgnohwelkibr4ddk43qhywa
|
||||||
|
pop.mail.i2p,bup6pmac7adgzkb5r6eknk2juczkxigolkwqkbmenawkes5s5qfq
|
||||||
|
pop.postman.i2p,ipkiowj7x4yjj7jc35yay3c6gauynkkl64gzzyxra3wmyhtfxlya
|
||||||
|
pravtor.i2p,2sr27o5x2v2pyqro7wl5nl6krrsbizwrzsky5y7pkohwh24gn6xq
|
||||||
|
pris.i2p,ahiwycgzuutdxvfqu3wseqffdnhy675nes57s4it2uysy5pxmz6a
|
||||||
|
project-future.i2p,ivqynpfwxzl746gxf376lxqvgktql2lqshzwnwjk2twut6xq7xta
|
||||||
|
projectmayhem2012-086.i2p,ehkjj4ptsagxlo27wpv4a5dk4zxqf4kg4p6fh35xrlz4y6mhe4eq
|
||||||
|
protokol.i2p,f4xre35ehc5l6ianjvt3zcktxkjlyp2iwdje65qnu2j6vurhy6nq
|
||||||
|
proxynet.i2p,7gar5a3n4hzvsgi73iizo65mjza4kujf7feopfxuwu5p6wtwog5a
|
||||||
|
psi.i2p,avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a
|
||||||
|
psy.i2p,s3elzoj3wo6v6wqu5ehd56vevpz2vrhhjc5m6mxoazicrl43y62q
|
||||||
|
psyco.i2p,eoilbrgyaiikxzdtmk2zeoalteupjrvcu3ui23p4wvfqo25bb73q
|
||||||
|
pt.hiddenanswers.i2p,o5jlxbbnx3byzgmihqye3kysop5jgl3unsrkmurbtr2nrnl2y74a
|
||||||
|
ptm.i2p,7dna5745ynxgogpjermnq26hwrqyjdlsibpjfmjxlwig247bjisa
|
||||||
|
ptt.i2p,q7r32j7lc3xgrcw2ym33wv4lfgqbez7vtm4lts7n34qfe3iygeha
|
||||||
|
pull.git.repo.i2p,3so7htzxzz6h46qvjm3fbd735zl3lrblerlj2xxybhobublcv67q
|
||||||
|
push.git.repo.i2p,jef4g5vxnqybm4zpouum3lzbl6ti6456q57nbyj5kfyldkempm3a
|
||||||
|
pycache.awup.i2p,w45lkxdnqhil4sgzanmxce62sv3q4szeowcjb2e72a5y5vbhm4ra
|
||||||
|
r4sas.i2p,2gafixvoztrndawkmhfxamci5lgd3urwnilxqmlo6ittu552cndq
|
||||||
|
radio.r4sas.i2p,cv72xsje5ihg6e24atitmhyk2cbml6eggi6b6fjfh2vgw62gdpla
|
||||||
|
ragnarok.i2p,jpzw6kbuzz3ll2mfi3emcaan4gidyt7ysdhu62r5k5xawrva7kca
|
||||||
|
ransack.i2p,mqamk4cfykdvhw5kjez2gnvse56gmnqxn7vkvvbuor4k4j2lbbnq
|
||||||
|
rasputin-sucks.i2p,fdozdbyak4rul4jwpqfisbkcx4xbrkuvf2o5r6fd3xryyrjgvjiq
|
||||||
|
rebel.i2p,nch2arl45crkyk6bklyk2hrdwjf5nztyxdtoshy6llhwqgxho5jq
|
||||||
|
red.i2p,fzbdltgsg7jrpz7gmjfvhpcdnw5yrglwspnxqp4zoym3bglntzfa
|
||||||
|
redpanda.i2p,3wcnp6afz4cikqzdu2ktb5wfz7hb3ejdbpn7ocpy7fmeqyzbaiea
|
||||||
|
redzara.i2p,ty7bt62rw5ryvk44dd3v5sua6c7wnbpxxqb6v4dohajmwmezi7va
|
||||||
|
reefer.i2p,4cde25mrrnt5n4nvp5tl62gej33nekfvq2viubmx4xdakhm5pfaa
|
||||||
|
relatelist.i2p,utrer5zgnou72hs4eztmk37pmzdtfw3d6s23wwl7nk3lkqpzbdiq
|
||||||
|
repo.i2p,uxe3lqueuuyklel23sf5h25zwgqgjwsofrqchhnptd5y6pedzbxa
|
||||||
|
repo.r4sas.i2p,ymzx5zgt6qzdg6nhxnecdgbqjd34ery6mpqolnbyo5kcwxadnodq
|
||||||
|
reseed.i2p,j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq
|
||||||
|
retrobbs-nntp.i2p,fkyzl24oxcxvjzkx74t3533x7qjketzmvzk6bwn3d6hj5t7hlw6q
|
||||||
|
retrobbs.i2p,mnn77stihntxdoade3ca2vcf456w6vhhvdsfepdvq5qggikvprxq
|
||||||
|
retrobbs2.i2p,ejff7jtyaus37slkwgeqrrcmyhpj26carp7n27f5h6s5vlbeiy6q
|
||||||
|
revo-ua.i2p,hpojpumki22xjwhmhe6zkiy44oanyn7u4ctcfe3in2ibwm5l32hq
|
||||||
|
riaa.i2p,lfbezn7amkzhswnx7lb4lxihyggl2kuqo5c7vwkcv6bwqmr4cuoa
|
||||||
|
rideronthestorm.i2p,xrdc2qc7quhumhglpbcuiqxr42nuffv4xj4a73jbr4ygepitibqq
|
||||||
|
romster.i2p,eaf2stdqdbepylt53egvixdi34g2usvgi7a4oixsja6atkran43a
|
||||||
|
rootd.i2p,mzbe5wofwn7eaqq4yefrmxizqaxoslwqxrv5qcv2opx5lnhg64dq
|
||||||
|
rospravosudie.i2p,z55khrnlj6bzhs5zielutm6ae6t2bbhfuiujwlrp3teubqyc4w7q
|
||||||
|
rotten.i2p,j4bm3rvezlejnb44elniagi5v2gazh7jaqrzhbod2pbxmgeb2frq
|
||||||
|
rpi.i2p,56p5qxsrvo5ereibevetw2qbj5bronmos7wxunku27g2s4kpbnlq
|
||||||
|
rslight.i2p,bitag46q3465nylvzuikfwjcj7ewi4gjkjtvuxhn73f6vsxffyiq
|
||||||
|
rsync.thetower.i2p,w4brpcdod7wnfqhwqrxyt4sbf2acouqfk5wyosfpq4mxq4s35kqa
|
||||||
|
ru.hiddenanswers.i2p,o6rmndvggfwnuvxwyq54y667fmmurgveerlzufyrhub6w3vkagva
|
||||||
|
ru.i2p,m7fqktjgtmsb3x7bvfrdx4tf7htnhytnz5qi2ujjcnph33u3hnja
|
||||||
|
rufurus.i2p,7msryymfdta3ssyz34qur6gi4jyfkvca5iyfmnceviipwu7g2wca
|
||||||
|
rus.i2p,gh6655arkncnbrzq5tmq4xpn36734d4tdza6flbw5xppye2dt6ga
|
||||||
|
ruslibgen.i2p,kk566cv37hivbjafiij5ryoui2ebxnm7b25gb3troniixopaj6nq
|
||||||
|
rutor.i2p,tro5tvvtd2qg34naxhvqp4236it36jjaipbda5vnjmggp55navdq
|
||||||
|
salt.i2p,6aflphlze6btsbez5cm4x53ydrmwhqrkxsud535d3qjh4wq62rxq
|
||||||
|
sasquotch.i2p,p6535uyfk2y6etc3t47vd3oqxydznqior5jxcvq5bdxe5kw5th6q
|
||||||
|
schwarzwald.i2p,4gokilzy73mmudufy3pohgatm42fcstx7uzg5hjvnfyphxpnphuq
|
||||||
|
sciencebooks.i2p,ypftjpgck75swz3bnsu4nw7rmrlr2vqsn4mwivwt3zcc3rxln5cq
|
||||||
|
scp.duck.i2p,ghbpsolpnveizxu4wbs7jbs2vj3kntnsexfcdleyhpqdhfpxleda
|
||||||
|
search.i2p,nz4qj6xaw5fda3rsmsax6yjthqy4c7uak2j3dzcehtkgyso4q46q
|
||||||
|
secretchat.i2p,cl3j2zxhpw6u6jevny45i557ojhwfxn4g375nnuqhy6lp27mry2q
|
||||||
|
secure.thetinhat.i2p,4q3qyzgz3ub5npbmt3vqqege5lg4zy62rhbgage4lpvnujwfpala
|
||||||
|
seeker.i2p,ipll7sit24oyhnwawpvokz5u7dabq6klveuqpx3sbi6o5qemy2bq
|
||||||
|
seomon.i2p,5mvpsy4h45w4fx7upen7ay3vkrs5klphz5nptmtcqvc3fsajsm4q
|
||||||
|
septu.i2p,5lqvih7yzbqacfi63hwnmih57dxopu5g2o5o4e2aorq7bt4ooyra
|
||||||
|
serien.i2p,3z5k3anbbk32thinvwcy4g5al7dmb75fagcm3zgh4rzrt3maphda
|
||||||
|
ses.i2p,5qfoz6qfgbo7z5sdi26naxstpi2xiltamkcdbhmj6y6q2bo4inja
|
||||||
|
shiftfox.i2p,wpvnuzslu7hjy4gujvnphtyckchdoxccrlhbyomsmjizykczyseq
|
||||||
|
shoieq3.i2p,3fjk4nfk3mccch4hdreghnyijcvovsi3yucjz3qzj5sxngqk5j6q
|
||||||
|
shoronil.i2p,7shqzgmb6tabiwrnwlasruq7pswy2d3emvfhaitehkqgod7i62sa
|
||||||
|
short.i2p,z5mt5rvnanlex6r3x3jnjhzzfqpv36r4ylesynigytegjmebauba
|
||||||
|
sion.i2p,lcbmmw2tvplvqh2dq5lmpxl3vnd5o4j3bdul5moa23deakjrso5q
|
||||||
|
sirup.i2p,aohdp4yajnkitrtw7v2mo3sp7swuqhjfwlsi5xwd7dudzftumsma
|
||||||
|
site.games.i2p,zeuczucfxeev3k7tvqlfcdpfbnqggheiknyyb5r2q4utn3d2auja
|
||||||
|
skank.i2p,qiii4iqrj3fwv4ucaji2oykcvsob75jviycv3ghw7dhzxg2kq53q
|
||||||
|
slack.i2p,gfcsh2yrb2tx7hyvmobriv52skz7qoobn7n7y7n6xaehhh4rpbja
|
||||||
|
slacker.i2p,wq7m2wdguzweleb666ygv3bmfhha63zj74rub76vfesbyhsyk6iq
|
||||||
|
smeghead.i2p,ojf4czveeuekxqkjvkszvv7eiop5dg7x2p6rgfzl4ng4xrjk6lja
|
||||||
|
smtp.mail.i2p,kdn7zx7fgoe4bn5abaaj5cb3e4ql22fklb5veui5yajpj4cxapya
|
||||||
|
smtp.postman.i2p,jj7pt6chsziz6oxxnzpqj7mzhxm2xfhcrbh7dl3tegifb577vx5q
|
||||||
|
socks1.tor.i2p,sifawcdexgdmoc3krv46pvvz74nzd6fkju2vzykjxsx3egqsb6wq
|
||||||
|
sonax.i2p,jmuxdhlok5ggojehesfjlit2e2q3fhzwwfxjndts7vzdshucbjjq
|
||||||
|
sponge.i2p,o5hu7phy7udffuhts6w5wn5mw3sepwe3hyvw6kthti33wa2xn5tq
|
||||||
|
squid.i2p,r4ll5zkbokgxlttqc2lrojvvey5yar4xr5prnndvnmggnqzjaeoq
|
||||||
|
squid2.i2p,hum4wlwizbsckbudcklflei66qxhpxsdkyo4l2rn256smmjleila
|
||||||
|
sqz.i2p,3jvbwc7sy4lnhj25nj7yepx7omli4ulqirnawv3mz6qlhgokjgzq
|
||||||
|
ssh.i2p,xpvdadaouc4qr75pteymyozc7mcsynjfkuqqkkla542lpcsqionq
|
||||||
|
stasher.i2p,6ilgpudnba4kroleunc2weh5txgoxys5yucij5gla6pjyki4oewa
|
||||||
|
stats.i2p,7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq
|
||||||
|
status.str4d.i2p,ycyyjo3psqbo45nuz243xvgvwnmzlanzqbzxv3kh6gyjztv7425q
|
||||||
|
sto-man.i2p,rg4eilfpe24ws6nctix63qw2dlvd2tqgwdcgdxzji6l5bc4dc7aa
|
||||||
|
str4d.i2p,wrrwzdgsppwl2g2bdohhajz3dh45ui6u3y7yuop5ivvfzxtwnipa
|
||||||
|
stream.i2p,prmbv3xm63ksoetnhbzqg4nzu2lhqdnqytgsydb7u3quxfrg7rna
|
||||||
|
streams.darkrealm.i2p,ud3gcmvysjch4lbjr2khmhqpf7r2x5if4q43xkqdptl4k7lc4muq
|
||||||
|
striker.i2p,4gswsrfpbd44hwjoj33jbqfbwzxfkwpuplb3ydq5zm7nfu2pxvdq
|
||||||
|
subrosa.i2p,g3lnglrnoual7wyabnwwv37uwhadgbxiqz36pf3f5cwfuxsx4mxq
|
||||||
|
subterra.i2p,vdmhe4u26unzgd7ysq6w36ubjncms5wzbhzr2gq576sq4xut5zwq
|
||||||
|
sugadude.i2p,yzjn76iyqard64wgggfrnywkxi7tbfkw7mjhpviqz3p2dguey4yq
|
||||||
|
suicidal.i2p,yfamynllow5xiqbbca7eh5xn733wtnuti5bi4ovc7dwycntqmiuq
|
||||||
|
sungo.i2p,h67s3jw56rwfyoxqxj3fngrluybsgxc2meendngkehzqowxnpj3q
|
||||||
|
surrender.adab.i2p,jgz7xglgfgnjfklrytyn427np2ubipztlm5bxrtbiucayglukrta
|
||||||
|
susi.i2p,qc6g2qfi2ccw7vjwpst6rwuofgzbeoewsb2usv7rubutf4gzqveq
|
||||||
|
syncline.i2p,5kcqmhislu3lmr7llgmdl72yu3efhyriljdc6wp774ftpwlcs5ra
|
||||||
|
syndie-project.i2p,xa63tpfoaqt3zru2ehxjjfbpadwj4ha6qsdvtcqtyr3b7hmt4iaq
|
||||||
|
syndie.echelon.i2p,vwrl2qmcif722fdkn3ldxcgz76df5cq4qypbndzthxwgmykyewta
|
||||||
|
syndie.i2p,7lm3yzpuejhpl4tt4l7o4ndqlu7hgijohofh7oaydx7q7kelenbq
|
||||||
|
syndiemedia.i2p,4lrbbblclodhobn3jadt5bf2yab2pxzoz4ey4a2cvrl44tdv3jma
|
||||||
|
tabak.i2p,y5o2vwb6kart7ivpnbpk4yte3i7kf2dsx7fy3i6w7htqtxhmbzia
|
||||||
|
tahoeserve.i2p,yhs7tsjeznxdenmdho5gjmk755wtredfzipb5t272oi5otipfkoa
|
||||||
|
tc.i2p,qkv2yk6rof3rh7n3eelg5niujae6cmdzcpqbv3wsttedxtqqqj7a
|
||||||
|
telegram.i2p,i6jow7hymogz2s42xq62gqgej2zdm4xtnmpc6vjcwktdxpdoupja
|
||||||
|
templar.i2p,zxeralsujowfpyi2ynyjooxy222pzz4apc2qcwrfx5ikhf64et7q
|
||||||
|
terror.i2p,wsijm6aqz4qtuyn2jedpx6imar5uq4yuhjdgtfqumxbqww47vbnq
|
||||||
|
thebland.i2p,oiviukgwapzxsrwxsoucpqa47s3wt6nfuhfjxvgbqsyrze2mwrda
|
||||||
|
thebreton.i2p,woutbsflcrlgppx4y7ag2kawlqijyenvlwrhbbvbkoaksuhf2hkq
|
||||||
|
thedarkside.i2p,fxt3z33nzkrg5kjrk7bp5vvmu7w2vsn4i6jo6cily3hsm6u664ca
|
||||||
|
theland.i2p,26ppxbseda6xmim37ksarccdb4q5ctdagfmt2u5aba6xjh452zsa
|
||||||
|
thetower.i2p,3xqa5nype64y6fxgqjq6r5w2qpiqftoraj2niebumseat4cj654a
|
||||||
|
thornworld.i2p,vinz4ygmodxarocntyjlfwk2wjpvzndlf4hxss2w2t3fk52oplva
|
||||||
|
tino.i2p,e4bfnhvaofu4s67ztcgiskos2mqyhskid64dvlqexxs2c2bno3iq
|
||||||
|
tinyurl.i2p,mc4oxv3v7dnyzpvok7v5qxkwtgjprgyz6w7x3tag4fipsen6rdwa
|
||||||
|
tome.i2p,qktkxwawgixrm5lzofnj5n24zspbnzxy4pvjm7uvaxvmgwrsuvgq
|
||||||
|
tor-gw.meeh.i2p,ounrqi7cfemnt66yhnhigt2u27fkctbvct527cp2522ozy3btjza
|
||||||
|
tor-www-proxy.i2p,xov45rvjks5fe4ofmpblkj23bnwxgslbypbgvchbr7yul2ujej2q
|
||||||
|
torapa.i2p,eejqjtpko6mdd4opvntbpsuandstrebxpbymfhix7avp5obrw5ta
|
||||||
|
torrentfinder.i2p,mpc73okj7wq2xl6clofl64cn6v7vrvhpmi6d524nrsvbeuvjxalq
|
||||||
|
torrfreedom.i2p,nfrjvknwcw47itotkzmk6mdlxmxfxsxhbhlr5ozhlsuavcogv4hq
|
||||||
|
trac.i2p,kyioa2lgdi2za2fwfwajnb3ljz6zwlx7yzjdpnxnch5uw3iqn6ca
|
||||||
|
trac.i2p2.i2p,i43xzkihpdq34f2jlmtgiyyay5quafg5rebog7tk7xil2c6kbyoa
|
||||||
|
tracker-fr.i2p,qfrvqrfoqkistgzo2oxpfduz4ktkhtqopleozs3emblmm36fepea
|
||||||
|
tracker.awup.i2p,dl47cno335ltvqm6noi5zcij5hpvbj7vjkzuofu262efvu6yp6cq
|
||||||
|
tracker.crypthost.i2p,ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq
|
||||||
|
tracker.fr.i2p,rzwqr7pfibq5wlcq4a7akm6ohfyhz7hchmy4wz5t55lhd7dwao5q
|
||||||
|
tracker.i2p,lsjcplya2b4hhmezz2jy5gqh6zlk3nskisjkhhwapy3jjly4ds5q
|
||||||
|
tracker.lodikon.i2p,q2a7tqlyddbyhxhtuia4bmtqpohpp266wsnrkm6cgoahdqrjo3ra
|
||||||
|
tracker.mastertracker.i2p,tiwurhqvaaguwpz2shdahqmcfze5ejre52ed2rmoadnjkkilskda
|
||||||
|
tracker.postman.i2p,jfcylf4j3gfmqogkltwy7v5m47wp4h7ffrnfsva6grfdavdn7ueq
|
||||||
|
tracker.psi.i2p,vmow3h54yljn7zvzbqepdddt5fmygijujycod2q6yznpy2rrzuwa
|
||||||
|
tracker.thebland.i2p,s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq
|
||||||
|
tracker.welterde.i2p,cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa
|
||||||
|
tracker2.postman.i2p,ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna
|
||||||
|
traditio.i2p,wkpjjloylf6jopu2itgpktr45t2xvpjijxilxd5tq4i7wkqgwhhq
|
||||||
|
trevorreznik.i2p,wc2z6o5fxm2saqzpfcawr63lejwccvzkysmgtfudkrigqopzfdma
|
||||||
|
true.i2p,pdilhl5vmefyzrrnmak5bnmxqxk2pmw7rpy4f7wbaeppqu2vvugq
|
||||||
|
trwcln.i2p,evml6jiiujhulsgxkdu3wcmkwbokxlv4is6w5qj46tp3ajz3hqzq
|
||||||
|
trypanom.i2p,tgv5acj4khwvr6t44cmryohybd2e5o2kndysnzae6qwcr4hzda3q
|
||||||
|
ts.i2p,nebcjgfx3f7q4wzihqmguwcdeopaf7f6wyk2dojw4bcuku472zxq
|
||||||
|
ttc.i2p,wb4tsfyvfv4idgrultsq6o7inza4fxkc7dijsfpncbx7zko4cdlq
|
||||||
|
ttp.i2p,uuczclxejmetohwf2vqewovx3qcumdfh5zecjb3xkcdmk6e5j72a
|
||||||
|
tumbach.i2p,u6pciacxnpbsq7nwc3tgutywochfd6aysgayijr7jxzoysgxklvq
|
||||||
|
tutorials.i2p,zy37tq6ynucp3ufoyeegswqjaeofmj57cpm5ecd7nbanh2h6f2ja
|
||||||
|
ugha.i2p,z3f3owc72awbywk4p6qb5l2mxgitvs6ejztggbpn2a3ddmymfjda
|
||||||
|
uk.i2p,vydbychnep3mzkzhg43ptewp242issy47whamfbxodc4ma6wc63a
|
||||||
|
underground.i2p,dlnuthb6tpw3kchlb7xoztyspy4ehlggjhl44l64vbcrulrfeica
|
||||||
|
underscore.i2p,3gmezyig6gvsjbpkq2kihoskpuqpkfrajmhhm7hpyrjuvtasgepa
|
||||||
|
unqueued.i2p,3gvn4kwd7z74jxc2sn4ucx52dpvpscxbzjluux3ul4t3eu5g64xq
|
||||||
|
up.i2p,25it5olgdo7pht25z6buzd32sw7jvc65oziqeuocfozfhgua655q
|
||||||
|
update.dg.i2p,iqj6ysfh3wl26m4buvyna73yhduifv523l7bwuexxak4mgldexja
|
||||||
|
update.killyourtv.i2p,gqdfg25jlqtm35qnmt4b7r53d6u2vep4ob23fwd42iyy4j6cvdqq
|
||||||
|
update.postman.i2p,u5rbu6yohfafplp6lgbbmmcuip34s7g3zqdd63cp27dl3nbd7gtq
|
||||||
|
utansans.i2p,u2oyre7ygqv4qs5xjjijfg3x7ddwtod6nqwgbomuuzljzvnq4rda
|
||||||
|
v2mail.i2p,4gg7fykcqe7oaqt4w5fmlarnia7vtmwkv3h45zzgoj6o6crryg5a
|
||||||
|
vadino.i2p,aalttzlt3z25ktokesceweabm5yyhhvml2z3rfotndgpfyh6myra
|
||||||
|
visibility.i2p,pwgma3snbsgkddxgb54mrxxkt3l4jzchrtp52vxmw7rbkjygylxq
|
||||||
|
volatile.i2p,q6rve733tvhgyys57jfw4fymqf3xsnza6dqailcdjcq7w4fa5m3a
|
||||||
|
vpnbest.i2p,ov5f74ndsy5rfkuyps56waf42vxncufqu5rzm3vsnxkdtogccaea
|
||||||
|
vudu.i2p,3zlwci7pvgep2igygzyjej24ue7mjsktlhaff6crpsr75yquak2q
|
||||||
|
w.i2p,j2xorlcb3qxubnthzqu7lt4fvxqn63it4ikwmze55yjkzeeampuq
|
||||||
|
wa11ed.city.i2p,7mxwtmala3ycg2sybjwwfil7s6dqck2fbemeutghhwu73rznmqoa
|
||||||
|
wahoo.i2p,vqe5vkpe5wbda7lwekcd2jaj44ar3rawgv54u5rcolezbg5f5vwa
|
||||||
|
wallet.gostcoin.i2p,reuvum7lgetglafn72chypesvto773oy53zumagrpigkckybrwda
|
||||||
|
wallsgetbombed.i2p,tzhea5d65fllm4263wztghgw4ijdgibsca5xsecp6lk4xlsbdeuq
|
||||||
|
web.telegram.i2p,re6cgwg2yrkgaixlqvt5ufajbb3w42fsldlq7k5brpvnd5gp6x5a
|
||||||
|
wiht.i2p,yojmpj3sh76g3i6ogzgsf7eouipdgdij5o2blcpdgmu5oyjk5xca
|
||||||
|
wiki.fr.i2p,lrqa7hw52uxjb5q3pedmjs6hzos5zrod4y6a4e25hu7vcjhohvxq
|
||||||
|
wiki.ilita.i2p,r233yskmowqe4od4he4b37wydr5fqzvj3z77v5fdei2etp2kg34a
|
||||||
|
wintermute.i2p,4gvlfrdy2rkmem33c342tjntpvqik65wekcvm4275qbkuwotoila
|
||||||
|
wspucktracker.i2p,ubd2txda3kllumx7ftg4unzgqy536cn6dd2ax6mlhodczfas7rgq
|
||||||
|
www.aum.i2p,3xolizygkzkqrldncjqsb734szznw2u36lliceuacqnbs2n65aeq
|
||||||
|
www.baffled.i2p,lqrsfslwu4xnubkk2hofhmuvvr4dia2zevxefinbzdsjurvehtqq
|
||||||
|
www.fr.i2p,rmkgvlfwo3vkb3xrr6epoypxasdzzuilv3sckcqbo6c4os5jo2ea
|
||||||
|
www.i2p,ojxyenivrrqvycgbxbm3phgisu5abspzq4g2us4fjlwz4tx222va
|
||||||
|
www.i2p2.i2p,rjxwbsw4zjhv4zsplma6jmf5nr24e4ymvvbycd3swgiinbvg7oga
|
||||||
|
www.imule.i2p,657xcllunctawyjtar5kgh3wpt6z4l7ba6mmam5rf7hev5w2lsvq
|
||||||
|
www.infoserver.i2p,fq7xhxkdcauhwn4loufcadiiy24zbei25elnup33a3gfrdzrtlyq
|
||||||
|
www.janonymous.i2p,vosqx5qw22hwrzcgsm4ib7hymf5ryovsbtaexqrzmnzshy5bhakq
|
||||||
|
www.mail.i2p,nctas6ioo7aaekfstv3o45yh6ywzwa3vznrdae52ouupzke5pyba
|
||||||
|
www.nntp.i2p,kly3o7zmetuwyz7xonnhttw4lj2244pkbibjz26uflyfte3b3dka
|
||||||
|
www.postman.i2p,rb3srw2gaooyw63q62cp4udrxxa6molr2irbkgrloveylpkkblhq
|
||||||
|
www.syndie.i2p,vojgy5ep4wffmtpjmpnbpa4gq64bgn4yicuw6qmhbm6nqa2ysrva
|
||||||
|
www1.squid.i2p,vbh3bltd2duwbukafgj6f6vfi6aigwso7snucp5zohnf66a2hkpa
|
||||||
|
xc.i2p,mt45a2z3sb2iyy2mwauj4rwa2lwu4peanfy6gx6ybidwnbasusyq
|
||||||
|
xeha.i2p,oartgetziabrdemxctowp7bbeggc7ktmj7tr4qgk5y5jcz4prbtq
|
||||||
|
xilog.i2p,eoc5i5q52hutnmsmq56edvooulutaxfikddgdz27otmgtsxmiloq
|
||||||
|
xmpp.crypthost.i2p,ittkqpjuliwsdewdugkhvgzstejr2jp5tzou7p332lxx4xw7srba
|
||||||
|
xmpp.rpi.i2p,3yv65pfwiwfuv4ciwtx34clqps6o2mc3vtyltcbqdkcki6untbca
|
||||||
|
xn--l2bl5aw.i2p,d2epikjh5crt2l5xjmtceqw2ho44hzp6x3u7hgjrd4mi4wywikwa
|
||||||
|
xolotl.i2p,rwr6rrlmrotxfkxt22mah42cycliy2g5k7hgxyxkpcyyxkd2bgwq
|
||||||
|
xotc.i2p,gqgvzum3xdgtaahkjfw3layb33vjrucmw5btyhrppm463cz3c5oq
|
||||||
|
z-lab.i2p,s6g2pz3mrwzsl4ts65ox3scqawfj7mzvd7hn2ekiiycawopkriba
|
||||||
|
zab.i2p,n4xen5sohufgjhv327ex4qra77f4tpqohlcyoa3atoboknzqazeq
|
||||||
|
zcash.i2p,zcashmliuw3yd2ptfyd5sadatcpyxj4ldiqahtjzg73cgoevxp4q
|
||||||
|
zener.i2p,mcbyglflte3dhwhqyafsfpnqtcapqkv2sepqd62wzd7fo2dzz4ca
|
||||||
|
zerobin.i2p,3564erslxzaoucqasxsjerk4jz2xril7j2cbzd4p7flpb4ut67hq
|
||||||
|
zeroman.i2p,gq77fmto535koofcd53f6yzcc5y57ccrxg3pb6twhcodc7v5dutq
|
||||||
|
zeronet.i2p,fe6pk5sibhkr64veqxkfochdfptehyxrrbs3edwjs5ckjbjn4bna
|
||||||
|
znc.i2p,uw2yt6njjl676fupd72hiezwmd4ouuywowrph6fvhkzhlnvp7jwa
|
||||||
|
znc.str4d.i2p,ufkajv3stxpxlwgwwb2ae6oixdjircnbwog77qxpxv7nt67rpcxq
|
||||||
|
zzz.i2p,ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq
|
||||||
|
1
android/assets/certificates
Symbolic link
1
android/assets/certificates
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../contrib/certificates
|
||||||
90
android/assets/i2pd.conf
Normal file
90
android/assets/i2pd.conf
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
## Configuration file for a typical i2pd user
|
||||||
|
## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
|
||||||
|
## for more options you can use in this file.
|
||||||
|
|
||||||
|
#logfile = /sdcard/i2pd/i2pd.log
|
||||||
|
loglevel = none
|
||||||
|
#tunnelsdir = /sdcard/i2pd/tunnels.d
|
||||||
|
|
||||||
|
# host = 1.2.3.4
|
||||||
|
# port = 4567
|
||||||
|
|
||||||
|
ipv4 = true
|
||||||
|
ipv6 = false
|
||||||
|
|
||||||
|
# ntcp = true
|
||||||
|
# ntcpproxy = http://127.0.0.1:8118
|
||||||
|
# ssu = true
|
||||||
|
|
||||||
|
bandwidth = L
|
||||||
|
# share = 100
|
||||||
|
|
||||||
|
# notransit = true
|
||||||
|
# floodfill = true
|
||||||
|
|
||||||
|
[ntcp2]
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[http]
|
||||||
|
enabled = true
|
||||||
|
address = 127.0.0.1
|
||||||
|
port = 7070
|
||||||
|
# auth = true
|
||||||
|
# user = i2pd
|
||||||
|
# pass = changeme
|
||||||
|
|
||||||
|
[httpproxy]
|
||||||
|
enabled = true
|
||||||
|
address = 127.0.0.1
|
||||||
|
port = 4444
|
||||||
|
inbound.length = 1
|
||||||
|
inbound.quantity = 5
|
||||||
|
outbound.length = 1
|
||||||
|
outbound.quantity = 5
|
||||||
|
signaturetype=7
|
||||||
|
keys = proxy-keys.dat
|
||||||
|
# addresshelper = true
|
||||||
|
# outproxy = http://false.i2p
|
||||||
|
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc.
|
||||||
|
|
||||||
|
[socksproxy]
|
||||||
|
enabled = true
|
||||||
|
address = 127.0.0.1
|
||||||
|
port = 4447
|
||||||
|
keys = proxy-keys.dat
|
||||||
|
# outproxy.enabled = false
|
||||||
|
# outproxy = 127.0.0.1
|
||||||
|
# outproxyport = 9050
|
||||||
|
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
|
||||||
|
|
||||||
|
[sam]
|
||||||
|
enabled = false
|
||||||
|
# address = 127.0.0.1
|
||||||
|
# port = 7656
|
||||||
|
|
||||||
|
[precomputation]
|
||||||
|
elgamal = true
|
||||||
|
|
||||||
|
[upnp]
|
||||||
|
enabled = true
|
||||||
|
# name = I2Pd
|
||||||
|
|
||||||
|
[reseed]
|
||||||
|
verify = true
|
||||||
|
## Path to local reseed data file (.su3) for manual reseeding
|
||||||
|
# file = /path/to/i2pseeds.su3
|
||||||
|
## or HTTPS URL to reseed from
|
||||||
|
# file = https://legit-website.com/i2pseeds.su3
|
||||||
|
## Path to local ZIP file or HTTPS URL to reseed from
|
||||||
|
# zipfile = /path/to/netDb.zip
|
||||||
|
## If you run i2pd behind a proxy server, set proxy server for reseeding here
|
||||||
|
## Should be http://address:port or socks://address:port
|
||||||
|
# proxy = http://127.0.0.1:8118
|
||||||
|
## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default
|
||||||
|
# threshold = 25
|
||||||
|
|
||||||
|
[limits]
|
||||||
|
transittunnels = 50
|
||||||
|
|
||||||
|
[persist]
|
||||||
|
profiles = false
|
||||||
3
android/assets/subscriptions.txt
Normal file
3
android/assets/subscriptions.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
http://inr.i2p/export/alive-hosts.txt
|
||||||
|
http://stats.i2p/cgi-bin/newhosts.txt
|
||||||
|
http://i2p-projekt.i2p/hosts.txt
|
||||||
33
android/assets/tunnels.conf
Normal file
33
android/assets/tunnels.conf
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
[IRC-IRC2P]
|
||||||
|
#type = client
|
||||||
|
#address = 127.0.0.1
|
||||||
|
#port = 6668
|
||||||
|
#destination = irc.postman.i2p
|
||||||
|
#destinationport = 6667
|
||||||
|
#keys = irc-keys.dat
|
||||||
|
|
||||||
|
#[IRC-ILITA]
|
||||||
|
#type = client
|
||||||
|
#address = 127.0.0.1
|
||||||
|
#port = 6669
|
||||||
|
#destination = irc.ilita.i2p
|
||||||
|
#destinationport = 6667
|
||||||
|
#keys = irc-keys.dat
|
||||||
|
|
||||||
|
#[SMTP]
|
||||||
|
#type = client
|
||||||
|
#address = 127.0.0.1
|
||||||
|
#port = 7659
|
||||||
|
#destination = smtp.postman.i2p
|
||||||
|
#destinationport = 25
|
||||||
|
#keys = smtp-keys.dat
|
||||||
|
|
||||||
|
#[POP3]
|
||||||
|
#type = client
|
||||||
|
#address = 127.0.0.1
|
||||||
|
#port = 7660
|
||||||
|
#destination = pop.postman.i2p
|
||||||
|
#destinationport = 110
|
||||||
|
#keys = pop3-keys.dat
|
||||||
|
|
||||||
|
# see more examples at https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/
|
||||||
1
android/assets/tunnels.d
Symbolic link
1
android/assets/tunnels.d
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../contrib/tunnels.d
|
||||||
@@ -2,9 +2,10 @@ buildscript {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
classpath 'com.android.tools.build:gradle:3.3.2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,18 +18,29 @@ repositories {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation 'com.android.support:support-compat:28.0.0'
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 25
|
compileSdkVersion 28
|
||||||
buildToolsVersion "25.0.3"
|
buildToolsVersion "28.0.3"
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "org.purplei2p.i2pd"
|
applicationId "org.purplei2p.i2pd"
|
||||||
targetSdkVersion 25
|
targetSdkVersion 28
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
versionCode 1
|
versionCode 2250
|
||||||
versionName "2.19.0"
|
versionName "2.25.0"
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters 'armeabi-v7a'
|
abiFilters 'armeabi-v7a'
|
||||||
//abiFilters 'x86'
|
abiFilters 'x86'
|
||||||
|
//abiFilters 'arm64-v8a'
|
||||||
|
//abiFilters 'x86_64'
|
||||||
|
}
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "-j3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -37,6 +49,16 @@ android {
|
|||||||
java.srcDirs = ['src']
|
java.srcDirs = ['src']
|
||||||
res.srcDirs = ['res']
|
res.srcDirs = ['res']
|
||||||
jniLibs.srcDirs = ['libs']
|
jniLibs.srcDirs = ['libs']
|
||||||
|
assets.srcDirs = ['assets']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
splits {
|
||||||
|
abi {
|
||||||
|
// change that to true if you need splitted apk
|
||||||
|
enable false
|
||||||
|
reset()
|
||||||
|
include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||||
|
universalApk true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
@@ -60,5 +82,3 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1
android/gradle.properties
Normal file
1
android/gradle.properties
Normal file
@@ -0,0 +1 @@
|
|||||||
|
org.gradle.parallel=true
|
||||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Thu Mar 14 18:21:08 MSK 2019
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||||
172
android/gradlew
vendored
Executable file
172
android/gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
84
android/gradlew.bat
vendored
Normal file
84
android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
@@ -25,49 +25,49 @@ include $(BUILD_SHARED_LIBRARY)
|
|||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_system
|
LOCAL_MODULE := boost_system
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_system.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_date_time
|
LOCAL_MODULE := boost_date_time
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_filesystem
|
LOCAL_MODULE := boost_filesystem
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_program_options
|
LOCAL_MODULE := boost_program_options
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := crypto
|
LOCAL_MODULE := crypto
|
||||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libcrypto.a
|
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include
|
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := ssl
|
LOCAL_MODULE := ssl
|
||||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libssl.a
|
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libssl.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include
|
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
||||||
LOCAL_STATIC_LIBRARIES := crypto
|
LOCAL_STATIC_LIBRARIES := crypto
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := miniupnpc
|
LOCAL_MODULE := miniupnpc
|
||||||
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnp-2.0/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
|
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnp-2.0/include
|
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|||||||
@@ -1,27 +1,22 @@
|
|||||||
#APP_ABI := all
|
|
||||||
#APP_ABI := armeabi-v7a x86
|
#APP_ABI := armeabi-v7a x86
|
||||||
#APP_ABI := x86
|
#APP_PLATFORM := android-14
|
||||||
#APP_ABI := x86_64
|
|
||||||
APP_ABI := armeabi-v7a
|
|
||||||
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
|
|
||||||
APP_PLATFORM := android-14
|
|
||||||
|
|
||||||
# http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse
|
# ABI arm64-v8a and x86_64 supported only from platform-21
|
||||||
NDK_TOOLCHAIN_VERSION := 4.9
|
#APP_ABI := arm64-v8a x86_64
|
||||||
# APP_STL := stlport_shared --> does not seem to contain C++11 features
|
#APP_PLATFORM := android-21
|
||||||
APP_STL := gnustl_shared
|
|
||||||
|
NDK_TOOLCHAIN_VERSION := clang
|
||||||
|
#APP_STL := c++_shared
|
||||||
|
APP_STL := c++_static
|
||||||
|
|
||||||
# Enable c++11 extensions in source code
|
# Enable c++11 extensions in source code
|
||||||
APP_CPPFLAGS += -std=c++11
|
APP_CPPFLAGS += -std=c++11 -fexceptions -frtti
|
||||||
|
|
||||||
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
|
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
APP_CPPFLAGS += -DANDROID_ARM7A
|
APP_CPPFLAGS += -DANDROID_ARM7A
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Forcing debug optimization. Use `ndk-build NDK_DEBUG=1` instead.
|
|
||||||
#APP_OPTIM := debug
|
|
||||||
|
|
||||||
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
|
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
|
||||||
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
|
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
|
||||||
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
|
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
#include "DaemonAndroid.h"
|
|
||||||
#include "Daemon.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
#include <exception>
|
||||||
#include <boost/exception/diagnostic_information.hpp>
|
#include <boost/exception/diagnostic_information.hpp>
|
||||||
#include <boost/exception_ptr.hpp>
|
#include <boost/exception_ptr.hpp>
|
||||||
#include <exception>
|
|
||||||
//#include "mainwindow.h"
|
//#include "mainwindow.h"
|
||||||
|
#include "FS.h"
|
||||||
|
#include "DaemonAndroid.h"
|
||||||
|
#include "Daemon.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@@ -36,7 +39,7 @@ namespace android
|
|||||||
emit resultReady();
|
emit resultReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller::Controller(DaemonAndroidImpl& daemon):
|
Controller::Controller(DaemonAndroidImpl& daemon):
|
||||||
m_Daemon (daemon)
|
m_Daemon (daemon)
|
||||||
{
|
{
|
||||||
Worker *worker = new Worker (m_Daemon);
|
Worker *worker = new Worker (m_Daemon);
|
||||||
@@ -54,19 +57,21 @@ namespace android
|
|||||||
workerThread.quit();
|
workerThread.quit();
|
||||||
workerThread.wait();
|
workerThread.wait();
|
||||||
Log.d(TAG"Waiting for daemon worker thread finished.");
|
Log.d(TAG"Waiting for daemon worker thread finished.");
|
||||||
if(m_Daemon.isRunning())
|
if(m_Daemon.isRunning())
|
||||||
{
|
{
|
||||||
Log.d(TAG"Stopping the daemon...");
|
Log.d(TAG"Stopping the daemon...");
|
||||||
m_Daemon.stop();
|
m_Daemon.stop();
|
||||||
Log.d(TAG"Stopped the daemon.");
|
Log.d(TAG"Stopped the daemon.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
std::string dataDir = "";
|
||||||
|
|
||||||
DaemonAndroidImpl::DaemonAndroidImpl ()
|
DaemonAndroidImpl::DaemonAndroidImpl ()
|
||||||
//:
|
//:
|
||||||
/*mutex(nullptr), */
|
/*mutex(nullptr), */
|
||||||
//m_IsRunning(false),
|
//m_IsRunning(false),
|
||||||
//m_RunningChangedCallback(nullptr)
|
//m_RunningChangedCallback(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +84,18 @@ namespace android
|
|||||||
{
|
{
|
||||||
//mutex=new QMutex(QMutex::Recursive);
|
//mutex=new QMutex(QMutex::Recursive);
|
||||||
//setRunningCallback(0);
|
//setRunningCallback(0);
|
||||||
//m_IsRunning=false;
|
//m_IsRunning=false;
|
||||||
|
|
||||||
|
// make sure assets are ready before proceed
|
||||||
|
i2p::fs::DetectDataDir(dataDir, false);
|
||||||
|
int numAttempts = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (i2p::fs::Exists (i2p::fs::DataDirPath("assets.ready"))) break; // assets ready
|
||||||
|
numAttempts++;
|
||||||
|
std::this_thread::sleep_for (std::chrono::seconds(1)); // otherwise wait for 1 more second
|
||||||
|
}
|
||||||
|
while (numAttempts <= 10); // 10 seconds max
|
||||||
return Daemon.init(argc,argv);
|
return Daemon.init(argc,argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,16 +127,16 @@ namespace android
|
|||||||
|
|
||||||
bool DaemonAndroidImpl::isRunning()
|
bool DaemonAndroidImpl::isRunning()
|
||||||
{
|
{
|
||||||
return m_IsRunning;
|
return m_IsRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonAndroidImpl::setRunning(bool newValue)
|
void DaemonAndroidImpl::setRunning(bool newValue)
|
||||||
{
|
{
|
||||||
bool oldValue = m_IsRunning;
|
bool oldValue = m_IsRunning;
|
||||||
if(oldValue!=newValue)
|
if(oldValue!=newValue)
|
||||||
{
|
{
|
||||||
m_IsRunning = newValue;
|
m_IsRunning = newValue;
|
||||||
if(m_RunningChangedCallback)
|
if(m_RunningChangedCallback)
|
||||||
m_RunningChangedCallback();
|
m_RunningChangedCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,14 +185,14 @@ namespace android
|
|||||||
catch (boost::exception& ex)
|
catch (boost::exception& ex)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << boost::diagnostic_information(ex);
|
ss << boost::diagnostic_information(ex);
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << ex.what();
|
ss << ex.what();
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@@ -189,5 +205,10 @@ namespace android
|
|||||||
{
|
{
|
||||||
daemon.stop();
|
daemon.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDataDir(std::string jdataDir)
|
||||||
|
{
|
||||||
|
dataDir = jdataDir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,45 +7,47 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace android
|
namespace android
|
||||||
{
|
{
|
||||||
class DaemonAndroidImpl
|
class DaemonAndroidImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DaemonAndroidImpl ();
|
DaemonAndroidImpl ();
|
||||||
~DaemonAndroidImpl ();
|
~DaemonAndroidImpl ();
|
||||||
|
|
||||||
//typedef void (*runningChangedCallback)();
|
//typedef void (*runningChangedCallback)();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return success
|
* @return success
|
||||||
*/
|
*/
|
||||||
bool init(int argc, char* argv[]);
|
bool init(int argc, char* argv[]);
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
void restart();
|
void restart();
|
||||||
//void setRunningCallback(runningChangedCallback cb);
|
//void setRunningCallback(runningChangedCallback cb);
|
||||||
//bool isRunning();
|
//bool isRunning();
|
||||||
private:
|
private:
|
||||||
//void setRunning(bool running);
|
//void setRunning(bool running);
|
||||||
private:
|
private:
|
||||||
//QMutex* mutex;
|
//QMutex* mutex;
|
||||||
//bool m_IsRunning;
|
//bool m_IsRunning;
|
||||||
//runningChangedCallback m_RunningChangedCallback;
|
//runningChangedCallback m_RunningChangedCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns "ok" if daemon init failed
|
* returns "ok" if daemon init failed
|
||||||
* returns errinfo if daemon initialized and started okay
|
* returns errinfo if daemon initialized and started okay
|
||||||
*/
|
*/
|
||||||
std::string start();
|
std::string start();
|
||||||
|
|
||||||
// stops the daemon
|
// stops the daemon
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
/*
|
// set datadir received from jni
|
||||||
|
void SetDataDir(std::string jdataDir);
|
||||||
|
/*
|
||||||
class Worker : public QObject
|
class Worker : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Worker (DaemonAndroidImpl& daemon);
|
Worker (DaemonAndroidImpl& daemon);
|
||||||
@@ -54,33 +56,33 @@ namespace android
|
|||||||
|
|
||||||
DaemonAndroidImpl& m_Daemon;
|
DaemonAndroidImpl& m_Daemon;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startDaemon();
|
void startDaemon();
|
||||||
void restartDaemon();
|
void restartDaemon();
|
||||||
void stopDaemon();
|
void stopDaemon();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void resultReady();
|
void resultReady();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Controller : public QObject
|
class Controller : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QThread workerThread;
|
QThread workerThread;
|
||||||
public:
|
public:
|
||||||
Controller(DaemonAndroidImpl& daemon);
|
Controller(DaemonAndroidImpl& daemon);
|
||||||
~Controller();
|
~Controller();
|
||||||
private:
|
private:
|
||||||
DaemonAndroidImpl& m_Daemon;
|
DaemonAndroidImpl& m_Daemon;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void handleResults(){}
|
void handleResults(){}
|
||||||
signals:
|
signals:
|
||||||
void startDaemon();
|
void startDaemon();
|
||||||
void stopDaemon();
|
void stopDaemon();
|
||||||
void restartDaemon();
|
void restartDaemon();
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
//#include <string.h>
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include "org_purplei2p_i2pd_I2PD_JNI.h"
|
#include "org_purplei2p_i2pd_I2PD_JNI.h"
|
||||||
#include "DaemonAndroid.h"
|
#include "DaemonAndroid.h"
|
||||||
@@ -7,60 +5,90 @@
|
|||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
||||||
(JNIEnv * env, jclass clazz) {
|
(JNIEnv *env, jclass clazz) {
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
#if defined(__ARM_ARCH_7A__)
|
#if defined(__ARM_ARCH_7A__)
|
||||||
#if defined(__ARM_NEON__)
|
#if defined(__ARM_NEON__)
|
||||||
#if defined(__ARM_PCS_VFP)
|
#if defined(__ARM_PCS_VFP)
|
||||||
#define ABI "armeabi-v7a/NEON (hard-float)"
|
#define ABI "armeabi-v7a/NEON (hard-float)"
|
||||||
#else
|
#else
|
||||||
#define ABI "armeabi-v7a/NEON"
|
#define ABI "armeabi-v7a/NEON"
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if defined(__ARM_PCS_VFP)
|
#if defined(__ARM_PCS_VFP)
|
||||||
#define ABI "armeabi-v7a (hard-float)"
|
#define ABI "armeabi-v7a (hard-float)"
|
||||||
#else
|
#else
|
||||||
#define ABI "armeabi-v7a"
|
#define ABI "armeabi-v7a"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define ABI "armeabi"
|
#define ABI "armeabi"
|
||||||
#endif
|
#endif
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
#define ABI "x86"
|
#define ABI "x86"
|
||||||
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
||||||
#define ABI "x86_64"
|
#define ABI "x86_64"
|
||||||
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
|
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
|
||||||
#define ABI "mips64"
|
#define ABI "mips64"
|
||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
#define ABI "mips"
|
#define ABI "mips"
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#define ABI "arm64-v8a"
|
#define ABI "arm64-v8a"
|
||||||
#else
|
#else
|
||||||
#define ABI "unknown"
|
#define ABI "unknown"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return env->NewStringUTF(ABI);
|
return env->NewStringUTF(ABI);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
||||||
(JNIEnv * env, jclass clazz) {
|
(JNIEnv *env, jclass clazz) {
|
||||||
return env->NewStringUTF(i2p::android::start().c_str());
|
return env->NewStringUTF(i2p::android::start().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
||||||
(JNIEnv * env, jclass clazz) {
|
(JNIEnv *env, jclass clazz) {
|
||||||
i2p::android::stop();
|
i2p::android::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
|
||||||
(JNIEnv * env, jclass clazz) {
|
(JNIEnv *env, jclass clazz) {
|
||||||
i2p::context.SetAcceptsTunnels (false);
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
|
||||||
|
(JNIEnv *env, jclass clazz) {
|
||||||
|
i2p::context.SetAcceptsTunnels (true);
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
||||||
(JNIEnv * env, jclass clazz, jboolean isConnected)
|
(JNIEnv *env, jclass clazz, jboolean isConnected) {
|
||||||
{
|
|
||||||
bool isConnectedBool = (bool) isConnected;
|
bool isConnectedBool = (bool) isConnected;
|
||||||
i2p::transport::transports.SetOnline (isConnectedBool);
|
i2p::transport::transports.SetOnline (isConnectedBool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir
|
||||||
|
(JNIEnv *env, jclass clazz, jstring jdataDir) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Method 1: convert UTF-16 jstring to std::string (https://stackoverflow.com/a/41820336)
|
||||||
|
const jclass stringClass = env->GetObjectClass(jdataDir);
|
||||||
|
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
|
||||||
|
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jdataDir, getBytes, env->NewStringUTF("UTF-8"));
|
||||||
|
|
||||||
|
size_t length = (size_t) env->GetArrayLength(stringJbytes);
|
||||||
|
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
|
||||||
|
|
||||||
|
std::string dataDir = std::string((char *)pBytes, length);
|
||||||
|
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
|
||||||
|
|
||||||
|
env->DeleteLocalRef(stringJbytes);
|
||||||
|
env->DeleteLocalRef(stringClass); */
|
||||||
|
|
||||||
|
// Method 2: get string chars and make char array.
|
||||||
|
auto dataDir = env->GetStringUTFChars(jdataDir, NULL);
|
||||||
|
env->ReleaseStringUTFChars(jdataDir, dataDir);
|
||||||
|
|
||||||
|
// Set DataDir
|
||||||
|
i2p::android::SetDataDir(dataDir);
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,19 +13,25 @@ extern "C" {
|
|||||||
* Signature: ()Ljava/lang/String;
|
* Signature: ()Ljava/lang/String;
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
||||||
(JNIEnv *, jclass);
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
|
||||||
(JNIEnv *, jclass);
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
|
||||||
(JNIEnv *, jclass);
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
|
||||||
(JNIEnv *, jclass);
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
||||||
(JNIEnv * env, jclass clazz, jboolean isConnected);
|
(JNIEnv * env, jclass clazz, jboolean isConnected);
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir
|
||||||
|
(JNIEnv *env, jclass clazz, jstring jdataDir);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,4 @@
|
|||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-25
|
target=android-28
|
||||||
|
|||||||
20
android/res/values-ru/strings.xml
Executable file
20
android/res/values-ru/strings.xml
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">i2pd</string>
|
||||||
|
<string name="action_stop">Остановить</string>
|
||||||
|
<string name="action_graceful_stop">Корректная остановка</string>
|
||||||
|
<string name="action_cancel_graceful_stop">Отменить корректную остановку</string>
|
||||||
|
<string name="graceful_stop_is_already_in_progress">Корректная остановка уже запущена</string>
|
||||||
|
<string name="graceful_stop_is_in_progress">Корректная остановка запущена</string>
|
||||||
|
<string name="already_stopped">Уже остановлено</string>
|
||||||
|
<string name="uninitialized">Приложение инициализируется</string>
|
||||||
|
<string name="starting">Приложение запускается</string>
|
||||||
|
<string name="jniLibraryLoaded">Загружены JNI библиотеки</string>
|
||||||
|
<string name="startedOkay">Приложение запущено</string>
|
||||||
|
<string name="startFailed">Запуск не удался</string>
|
||||||
|
<string name="gracefulShutdownInProgress">Корректная остановка запущена</string>
|
||||||
|
<string name="stopped">Приложение было остановлено</string>
|
||||||
|
<string name="remaining">осталось</string>
|
||||||
|
<string name="title_activity_i2_pdperms_asker_prompt">Запрос</string>
|
||||||
|
<string name="permDenied">Права для записи на SD карту отклонены, вам необходимо предоставить их для продолжения</string>
|
||||||
|
</resources>
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||||
<string name="app_name">i2pd</string>
|
<string name="app_name">i2pd</string>
|
||||||
<string name="action_stop">Stop</string>
|
<string name="action_stop">Stop</string>
|
||||||
<string name="action_graceful_stop">Graceful Stop</string>
|
<string name="action_graceful_stop">Graceful Stop</string>
|
||||||
|
<string name="action_cancel_graceful_stop">Cancel Graceful Stop</string>
|
||||||
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string>
|
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string>
|
||||||
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string>
|
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string>
|
||||||
<string name="already_stopped">Already stopped</string>
|
<string name="already_stopped">Already stopped</string>
|
||||||
<string name="uninitialized">i2pd initializing</string>
|
<string name="uninitialized">Application initializing</string>
|
||||||
<string name="starting">i2pd is starting</string>
|
<string name="starting">Application starting</string>
|
||||||
<string name="jniLibraryLoaded">i2pd: loaded JNI libraries</string>
|
<string name="jniLibraryLoaded">Loaded JNI libraries</string>
|
||||||
<string name="startedOkay">i2pd started</string>
|
<string name="startedOkay">Application Started</string>
|
||||||
<string name="startFailed">i2pd start failed</string>
|
<string name="startFailed">Start failed</string>
|
||||||
<string name="gracefulShutdownInProgress">i2pd: graceful shutdown in progress</string>
|
<string name="gracefulShutdownInProgress">Graceful shutdown in progress</string>
|
||||||
<string name="stopped">i2pd has stopped</string>
|
<string name="stopped">Application stopped</string>
|
||||||
<string name="remaining">remaining</string>
|
<string name="remaining">remaining</string>
|
||||||
<string name="title_activity_i2_pdperms_asker_prompt">Prompt</string>
|
<string name="title_activity_i2_pdperms_asker_prompt">Prompt</string>
|
||||||
|
<string name="permDenied">SD card write permission denied, you need to allow this to continue</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
1
android/settings.gradle
Normal file
1
android/settings.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = "i2pd"
|
||||||
@@ -2,18 +2,18 @@ package org.purplei2p.i2pd;
|
|||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.purplei2p.i2pd.R;
|
||||||
|
|
||||||
public class DaemonSingleton {
|
public class DaemonSingleton {
|
||||||
private static final String TAG="i2pd";
|
private static final String TAG = "i2pd";
|
||||||
private static final DaemonSingleton instance = new DaemonSingleton();
|
private static final DaemonSingleton instance = new DaemonSingleton();
|
||||||
public interface StateUpdateListener { void daemonStateUpdate(); }
|
public interface StateUpdateListener { void daemonStateUpdate(); }
|
||||||
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
|
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
|
||||||
|
|
||||||
public static DaemonSingleton getInstance() {
|
public static DaemonSingleton getInstance() { return instance; }
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); }
|
public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); }
|
||||||
public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); }
|
public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); }
|
||||||
@@ -33,27 +33,34 @@ public class DaemonSingleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void startAcceptingTunnels() {
|
||||||
|
if(isStartedOkay()){
|
||||||
|
setState(State.startedOkay);
|
||||||
|
I2PD_JNI.startAcceptingTunnels();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private volatile boolean startedOkay;
|
private volatile boolean startedOkay;
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
uninitialized(R.string.uninitialized),
|
uninitialized(R.string.uninitialized),
|
||||||
starting(R.string.starting),
|
starting(R.string.starting),
|
||||||
jniLibraryLoaded(R.string.jniLibraryLoaded),
|
jniLibraryLoaded(R.string.jniLibraryLoaded),
|
||||||
startedOkay(R.string.startedOkay),
|
startedOkay(R.string.startedOkay),
|
||||||
startFailed(R.string.startFailed),
|
startFailed(R.string.startFailed),
|
||||||
gracefulShutdownInProgress(R.string.gracefulShutdownInProgress),
|
gracefulShutdownInProgress(R.string.gracefulShutdownInProgress),
|
||||||
stopped(R.string.stopped);
|
stopped(R.string.stopped);
|
||||||
|
|
||||||
State(int statusStringResourceId) {
|
State(int statusStringResourceId) {
|
||||||
this.statusStringResourceId = statusStringResourceId;
|
this.statusStringResourceId = statusStringResourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int statusStringResourceId;
|
private final int statusStringResourceId;
|
||||||
|
|
||||||
public int getStatusStringResourceId() {
|
public int getStatusStringResourceId() {
|
||||||
return statusStringResourceId;
|
return statusStringResourceId;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private volatile State state = State.uninitialized;
|
private volatile State state = State.uninitialized;
|
||||||
|
|
||||||
@@ -75,6 +82,7 @@ public class DaemonSingleton {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
synchronized (DaemonSingleton.this) {
|
synchronized (DaemonSingleton.this) {
|
||||||
|
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
|
||||||
daemonStartResult = I2PD_JNI.startDaemon();
|
daemonStartResult = I2PD_JNI.startDaemon();
|
||||||
if("ok".equals(daemonStartResult)){
|
if("ok".equals(daemonStartResult)){
|
||||||
setState(State.startedOkay);
|
setState(State.startedOkay);
|
||||||
@@ -84,7 +92,6 @@ public class DaemonSingleton {
|
|||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
lastThrowable=tr;
|
lastThrowable=tr;
|
||||||
setState(State.startFailed);
|
setState(State.startFailed);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,125 +1,149 @@
|
|||||||
package org.purplei2p.i2pd;
|
package org.purplei2p.i2pd;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
public class ForegroundService extends Service {
|
public class ForegroundService extends Service {
|
||||||
private static final String TAG="FgService";
|
private static final String TAG="FgService";
|
||||||
|
|
||||||
private volatile boolean shown;
|
private volatile boolean shown;
|
||||||
|
|
||||||
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
||||||
new DaemonSingleton.StateUpdateListener() {
|
new DaemonSingleton.StateUpdateListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void daemonStateUpdate() {
|
public void daemonStateUpdate() {
|
||||||
try {
|
try {
|
||||||
synchronized (ForegroundService.this) {
|
synchronized (ForegroundService.this) {
|
||||||
if (shown) cancelNotification();
|
if (shown) cancelNotification();
|
||||||
showNotification();
|
showNotification();
|
||||||
}
|
}
|
||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
Log.e(TAG,"error ignored",tr);
|
Log.e(TAG,"error ignored",tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private NotificationManager notificationManager;
|
private NotificationManager notificationManager;
|
||||||
|
|
||||||
// Unique Identification Number for the Notification.
|
// Unique Identification Number for the Notification.
|
||||||
// We use it on Notification start, and to cancel it.
|
// We use it on Notification start, and to cancel it.
|
||||||
private int NOTIFICATION = 1;
|
private int NOTIFICATION = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for clients to access. Because we know this service always
|
* Class for clients to access. Because we know this service always
|
||||||
* runs in the same process as its clients, we don't need to deal with
|
* runs in the same process as its clients, we don't need to deal with
|
||||||
* IPC.
|
* IPC.
|
||||||
*/
|
*/
|
||||||
public class LocalBinder extends Binder {
|
public class LocalBinder extends Binder {
|
||||||
ForegroundService getService() {
|
ForegroundService getService() {
|
||||||
return ForegroundService.this;
|
return ForegroundService.this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener);
|
DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener);
|
||||||
if (!shown) daemonStateUpdatedListener.daemonStateUpdate();
|
if (!shown) daemonStateUpdatedListener.daemonStateUpdate();
|
||||||
}
|
}
|
||||||
// Tell the user we started.
|
// Tell the user we started.
|
||||||
// Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
|
// Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
|
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener);
|
DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener);
|
||||||
cancelNotification();
|
cancelNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void cancelNotification() {
|
private synchronized void cancelNotification() {
|
||||||
// Cancel the persistent notification.
|
// Cancel the persistent notification.
|
||||||
notificationManager.cancel(NOTIFICATION);
|
notificationManager.cancel(NOTIFICATION);
|
||||||
|
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
|
||||||
// Tell the user we stopped.
|
// Tell the user we stopped.
|
||||||
// Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
|
//Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
|
||||||
shown=false;
|
shown=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return mBinder;
|
return mBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the object that receives interactions from clients. See
|
// This is the object that receives interactions from clients. See
|
||||||
// RemoteService for a more complete example.
|
// RemoteService for a more complete example.
|
||||||
private final IBinder mBinder = new LocalBinder();
|
private final IBinder mBinder = new LocalBinder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a notification while this service is running.
|
* Show a notification while this service is running.
|
||||||
*/
|
*/
|
||||||
private synchronized void showNotification() {
|
private synchronized void showNotification() {
|
||||||
// In this sample, we'll use the same text for the ticker and the expanded notification
|
// In this sample, we'll use the same text for the ticker and the expanded notification
|
||||||
CharSequence text = getText(DaemonSingleton.getInstance().getState().getStatusStringResourceId());
|
CharSequence text = getText(DaemonSingleton.getInstance().getState().getStatusStringResourceId());
|
||||||
|
|
||||||
// The PendingIntent to launch our activity if the user selects this notification
|
// The PendingIntent to launch our activity if the user selects this notification
|
||||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
|
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
|
||||||
new Intent(this, I2PDActivity.class), 0);
|
new Intent(this, I2PDActivity.class), 0);
|
||||||
|
|
||||||
// Set the info for the views that show in the notification panel.
|
// If earlier version channel ID is not used
|
||||||
Notification notification = new Notification.Builder(this)
|
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||||
.setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon
|
String channelId = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? createNotificationChannel() : "";
|
||||||
.setTicker(text) // the status text
|
|
||||||
.setWhen(System.currentTimeMillis()) // the time stamp
|
|
||||||
.setContentTitle(getText(R.string.app_name)) // the label of the entry
|
|
||||||
.setContentText(text) // the contents of the entry
|
|
||||||
.setContentIntent(contentIntent) // The intent to send when the entry is clicked
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Send the notification.
|
// Set the info for the views that show in the notification panel.
|
||||||
//mNM.notify(NOTIFICATION, notification);
|
Notification notification = new NotificationCompat.Builder(this, channelId)
|
||||||
startForeground(NOTIFICATION, notification);
|
.setOngoing(true)
|
||||||
shown=true;
|
.setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon
|
||||||
}
|
.setPriority(Notification.PRIORITY_DEFAULT)
|
||||||
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
|
.setTicker(text) // the status text
|
||||||
|
.setWhen(System.currentTimeMillis()) // the time stamp
|
||||||
|
.setContentTitle(getText(R.string.app_name)) // the label of the entry
|
||||||
|
.setContentText(text) // the contents of the entry
|
||||||
|
.setContentIntent(contentIntent) // The intent to send when the entry is clicked
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Send the notification.
|
||||||
|
//mNM.notify(NOTIFICATION, notification);
|
||||||
|
startForeground(NOTIFICATION, notification);
|
||||||
|
shown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
private synchronized String createNotificationChannel() {
|
||||||
|
String channelId = getString(R.string.app_name);
|
||||||
|
CharSequence channelName = "I2Pd service";
|
||||||
|
NotificationChannel chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);
|
||||||
|
//chan.setLightColor(Color.PURPLE);
|
||||||
|
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||||
|
NotificationManager service = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
service.createNotificationChannel(chan);
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +1,64 @@
|
|||||||
package org.purplei2p.i2pd;
|
package org.purplei2p.i2pd;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
|
||||||
|
// For future package update checking
|
||||||
|
import org.purplei2p.i2pd.BuildConfig;
|
||||||
|
|
||||||
public class I2PDActivity extends Activity {
|
public class I2PDActivity extends Activity {
|
||||||
private static final String TAG = "i2pdActvt";
|
private static final String TAG = "i2pdActvt";
|
||||||
public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000;
|
private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
|
||||||
|
public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000;
|
||||||
|
|
||||||
private TextView textView;
|
private TextView textView;
|
||||||
|
private boolean assetsCopied;
|
||||||
|
private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/";
|
||||||
|
|
||||||
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||||
|
|
||||||
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
||||||
new DaemonSingleton.StateUpdateListener() {
|
new DaemonSingleton.StateUpdateListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void daemonStateUpdate() {
|
public void daemonStateUpdate()
|
||||||
|
{
|
||||||
|
processAssets();
|
||||||
runOnUiThread(new Runnable(){
|
runOnUiThread(new Runnable(){
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
if(textView==null)return;
|
if(textView==null) return;
|
||||||
Throwable tr = daemon.getLastThrowable();
|
Throwable tr = daemon.getLastThrowable();
|
||||||
if(tr!=null) {
|
if(tr!=null) {
|
||||||
textView.setText(throwableToString(tr));
|
textView.setText(throwableToString(tr));
|
||||||
@@ -44,10 +66,10 @@ public class I2PDActivity extends Activity {
|
|||||||
}
|
}
|
||||||
DaemonSingleton.State state = daemon.getState();
|
DaemonSingleton.State state = daemon.getState();
|
||||||
textView.setText(
|
textView.setText(
|
||||||
String.valueOf(state)+
|
String.valueOf(getText(state.getStatusStringResourceId()))+
|
||||||
(DaemonSingleton.State.startFailed.equals(state)?": "+daemon.getDaemonStartResult():"")+
|
(DaemonSingleton.State.startFailed.equals(state) ? ": "+daemon.getDaemonStartResult() : "")+
|
||||||
(DaemonSingleton.State.gracefulShutdownInProgress.equals(state)?": "+formatGraceTimeRemaining()+" "+getText(R.string.remaining):"")
|
(DaemonSingleton.State.gracefulShutdownInProgress.equals(state) ? ": "+formatGraceTimeRemaining()+" "+getText(R.string.remaining) : "")
|
||||||
);
|
);
|
||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
Log.e(TAG,"error ignored",tr);
|
Log.e(TAG,"error ignored",tr);
|
||||||
}
|
}
|
||||||
@@ -55,121 +77,149 @@ public class I2PDActivity extends Activity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static volatile long graceStartedMillis;
|
private static volatile long graceStartedMillis;
|
||||||
private static final Object graceStartedMillis_LOCK=new Object();
|
private static final Object graceStartedMillis_LOCK=new Object();
|
||||||
|
|
||||||
private static String formatGraceTimeRemaining() {
|
private static String formatGraceTimeRemaining() {
|
||||||
long remainingSeconds;
|
long remainingSeconds;
|
||||||
synchronized (graceStartedMillis_LOCK){
|
synchronized (graceStartedMillis_LOCK){
|
||||||
remainingSeconds=Math.round(Math.max(0,graceStartedMillis+GRACEFUL_DELAY_MILLIS-System.currentTimeMillis())/1000.0D);
|
remainingSeconds=Math.round(Math.max(0,graceStartedMillis+GRACEFUL_DELAY_MILLIS-System.currentTimeMillis())/1000.0D);
|
||||||
}
|
}
|
||||||
long remainingMinutes=(long)Math.floor(remainingSeconds/60.0D);
|
long remainingMinutes=(long)Math.floor(remainingSeconds/60.0D);
|
||||||
long remSec=remainingSeconds-remainingMinutes*60;
|
long remSec=remainingSeconds-remainingMinutes*60;
|
||||||
return remainingMinutes+":"+(remSec/10)+remSec%10;
|
return remainingMinutes+":"+(remSec/10)+remSec%10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
textView = new TextView(this);
|
textView = new TextView(this);
|
||||||
setContentView(textView);
|
setContentView(textView);
|
||||||
daemon.addStateChangeListener(daemonStateUpdatedListener);
|
daemon.addStateChangeListener(daemonStateUpdatedListener);
|
||||||
daemonStateUpdatedListener.daemonStateUpdate();
|
daemonStateUpdatedListener.daemonStateUpdate();
|
||||||
|
|
||||||
//set the app be foreground
|
// request permissions
|
||||||
doBindService();
|
if (Build.VERSION.SDK_INT >= 23)
|
||||||
|
{
|
||||||
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
|
||||||
|
{
|
||||||
|
ActivityCompat.requestPermissions(this,
|
||||||
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final Timer gracefulQuitTimer = getGracefulQuitTimer();
|
// set the app be foreground
|
||||||
if(gracefulQuitTimer!=null){
|
doBindService();
|
||||||
long gracefulStopAtMillis;
|
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
|
||||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
|
||||||
}
|
|
||||||
rescheduleGraceStop(gracefulQuitTimer, gracefulStopAtMillis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
final Timer gracefulQuitTimer = getGracefulQuitTimer();
|
||||||
|
if(gracefulQuitTimer!=null){
|
||||||
|
long gracefulStopAtMillis;
|
||||||
|
synchronized (graceStartedMillis_LOCK) {
|
||||||
|
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
||||||
|
}
|
||||||
|
rescheduleGraceStop(gracefulQuitTimer, gracefulStopAtMillis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
textView = null;
|
textView = null;
|
||||||
daemon.removeStateChangeListener(daemonStateUpdatedListener);
|
daemon.removeStateChangeListener(daemonStateUpdatedListener);
|
||||||
//cancelGracefulStop();
|
//cancelGracefulStop();
|
||||||
try{
|
try{
|
||||||
doUnbindService();
|
doUnbindService();
|
||||||
}catch(Throwable tr){
|
}catch(Throwable tr){
|
||||||
Log.e(TAG, "", tr);
|
Log.e(TAG, "", tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void cancelGracefulStop() {
|
@Override
|
||||||
Timer gracefulQuitTimer = getGracefulQuitTimer();
|
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
|
||||||
if(gracefulQuitTimer!=null) {
|
{
|
||||||
gracefulQuitTimer.cancel();
|
switch (requestCode)
|
||||||
setGracefulQuitTimer(null);
|
{
|
||||||
}
|
case MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE:
|
||||||
}
|
{
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||||
private CharSequence throwableToString(Throwable tr) {
|
Log.e(TAG, "Memory permission granted");
|
||||||
StringWriter sw = new StringWriter(8192);
|
else
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
Log.e(TAG, "Memory permission declined");
|
||||||
tr.printStackTrace(pw);
|
// TODO: terminate
|
||||||
pw.close();
|
return;
|
||||||
return sw.toString();
|
}
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private LocalService mBoundService;
|
private static void cancelGracefulStop() {
|
||||||
|
Timer gracefulQuitTimer = getGracefulQuitTimer();
|
||||||
|
if(gracefulQuitTimer!=null) {
|
||||||
|
gracefulQuitTimer.cancel();
|
||||||
|
setGracefulQuitTimer(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ServiceConnection mConnection = new ServiceConnection() {
|
private CharSequence throwableToString(Throwable tr) {
|
||||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
StringWriter sw = new StringWriter(8192);
|
||||||
// This is called when the connection with the service has been
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
// established, giving us the service object we can use to
|
tr.printStackTrace(pw);
|
||||||
// interact with the service. Because we have bound to a explicit
|
pw.close();
|
||||||
// service that we know is running in our own process, we can
|
return sw.toString();
|
||||||
// cast its IBinder to a concrete class and directly access it.
|
}
|
||||||
// mBoundService = ((LocalService.LocalBinder)service).getService();
|
|
||||||
|
|
||||||
// Tell the user about this for our demo.
|
// private LocalService mBoundService;
|
||||||
// Toast.makeText(Binding.this, R.string.local_service_connected,
|
|
||||||
// Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onServiceDisconnected(ComponentName className) {
|
private ServiceConnection mConnection = new ServiceConnection() {
|
||||||
// This is called when the connection with the service has been
|
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||||
// unexpectedly disconnected -- that is, its process crashed.
|
// This is called when the connection with the service has been
|
||||||
// Because it is running in our same process, we should never
|
// established, giving us the service object we can use to
|
||||||
// see this happen.
|
// interact with the service. Because we have bound to a explicit
|
||||||
// mBoundService = null;
|
// service that we know is running in our own process, we can
|
||||||
// Toast.makeText(Binding.this, R.string.local_service_disconnected,
|
// cast its IBinder to a concrete class and directly access it.
|
||||||
// Toast.LENGTH_SHORT).show();
|
// mBoundService = ((LocalService.LocalBinder)service).getService();
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// Tell the user about this for our demo.
|
||||||
|
// Toast.makeText(Binding.this, R.string.local_service_connected,
|
||||||
|
// Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
private static volatile boolean mIsBound;
|
public void onServiceDisconnected(ComponentName className) {
|
||||||
|
// This is called when the connection with the service has been
|
||||||
|
// unexpectedly disconnected -- that is, its process crashed.
|
||||||
|
// Because it is running in our same process, we should never
|
||||||
|
// see this happen.
|
||||||
|
// mBoundService = null;
|
||||||
|
// Toast.makeText(Binding.this, R.string.local_service_disconnected,
|
||||||
|
// Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private void doBindService() {
|
private static volatile boolean mIsBound;
|
||||||
synchronized (I2PDActivity.class) {
|
|
||||||
if (mIsBound) return;
|
|
||||||
// Establish a connection with the service. We use an explicit
|
|
||||||
// class name because we want a specific service implementation that
|
|
||||||
// we know will be running in our own process (and thus won't be
|
|
||||||
// supporting component replacement by other applications).
|
|
||||||
bindService(new Intent(this, ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
mIsBound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doUnbindService() {
|
private void doBindService() {
|
||||||
synchronized (I2PDActivity.class) {
|
synchronized (I2PDActivity.class) {
|
||||||
if (mIsBound) {
|
if (mIsBound) return;
|
||||||
// Detach our existing connection.
|
// Establish a connection with the service. We use an explicit
|
||||||
unbindService(mConnection);
|
// class name because we want a specific service implementation that
|
||||||
mIsBound = false;
|
// we know will be running in our own process (and thus won't be
|
||||||
}
|
// supporting component replacement by other applications).
|
||||||
}
|
bindService(new Intent(this, ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE);
|
||||||
}
|
mIsBound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doUnbindService() {
|
||||||
|
synchronized (I2PDActivity.class) {
|
||||||
|
if (mIsBound) {
|
||||||
|
// Detach our existing connection.
|
||||||
|
unbindService(mConnection);
|
||||||
|
mIsBound = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
@@ -186,100 +236,256 @@ public class I2PDActivity extends Activity {
|
|||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
|
||||||
switch(id){
|
switch(id){
|
||||||
case R.id.action_stop:
|
case R.id.action_stop:
|
||||||
i2pdStop();
|
i2pdStop();
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_graceful_stop:
|
case R.id.action_graceful_stop:
|
||||||
i2pdGracefulStop();
|
if (getGracefulQuitTimer()!= null)
|
||||||
return true;
|
{
|
||||||
}
|
item.setTitle(R.string.action_graceful_stop);
|
||||||
|
i2pdCancelGracefulStop ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.setTitle(R.string.action_cancel_graceful_stop);
|
||||||
|
i2pdGracefulStop();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void i2pdStop() {
|
private void i2pdStop() {
|
||||||
cancelGracefulStop();
|
cancelGracefulStop();
|
||||||
new Thread(new Runnable(){
|
new Thread(new Runnable(){
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Log.d(TAG, "stopping");
|
|
||||||
try{
|
|
||||||
daemon.stopDaemon();
|
|
||||||
}catch (Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
},"stop").start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static volatile Timer gracefulQuitTimer;
|
|
||||||
|
|
||||||
private void i2pdGracefulStop() {
|
|
||||||
if(daemon.getState()==DaemonSingleton.State.stopped){
|
|
||||||
Toast.makeText(this, R.string.already_stopped,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(getGracefulQuitTimer()!=null){
|
|
||||||
Toast.makeText(this, R.string.graceful_stop_is_already_in_progress,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Toast.makeText(this, R.string.graceful_stop_is_in_progress,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
new Thread(new Runnable(){
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Log.d(TAG, "stopping");
|
||||||
try{
|
try{
|
||||||
|
daemon.stopDaemon();
|
||||||
|
}catch (Throwable tr) {
|
||||||
|
Log.e(TAG, "", tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},"stop").start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static volatile Timer gracefulQuitTimer;
|
||||||
|
|
||||||
|
private void i2pdGracefulStop() {
|
||||||
|
if(daemon.getState()==DaemonSingleton.State.stopped){
|
||||||
|
Toast.makeText(this, R.string.already_stopped,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(getGracefulQuitTimer()!=null){
|
||||||
|
Toast.makeText(this, R.string.graceful_stop_is_already_in_progress,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Toast.makeText(this, R.string.graceful_stop_is_in_progress,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
new Thread(new Runnable(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
Log.d(TAG, "grac stopping");
|
Log.d(TAG, "grac stopping");
|
||||||
if(daemon.isStartedOkay()) {
|
if(daemon.isStartedOkay()) {
|
||||||
daemon.stopAcceptingTunnels();
|
daemon.stopAcceptingTunnels();
|
||||||
long gracefulStopAtMillis;
|
long gracefulStopAtMillis;
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
synchronized (graceStartedMillis_LOCK) {
|
||||||
graceStartedMillis = System.currentTimeMillis();
|
graceStartedMillis = System.currentTimeMillis();
|
||||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
||||||
}
|
}
|
||||||
rescheduleGraceStop(null,gracefulStopAtMillis);
|
rescheduleGraceStop(null,gracefulStopAtMillis);
|
||||||
}else{
|
} else {
|
||||||
i2pdStop();
|
i2pdStop();
|
||||||
}
|
}
|
||||||
} catch(Throwable tr) {
|
} catch(Throwable tr) {
|
||||||
Log.e(TAG,"",tr);
|
Log.e(TAG,"",tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},"gracInit").start();
|
},"gracInit").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void i2pdCancelGracefulStop()
|
||||||
|
{
|
||||||
|
cancelGracefulStop();
|
||||||
|
Toast.makeText(this, R.string.startedOkay, Toast.LENGTH_SHORT).show();
|
||||||
|
new Thread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Log.d(TAG, "grac stopping cancel");
|
||||||
|
if(daemon.isStartedOkay())
|
||||||
|
daemon.startAcceptingTunnels();
|
||||||
|
else
|
||||||
|
i2pdStop();
|
||||||
|
}
|
||||||
|
catch(Throwable tr)
|
||||||
|
{
|
||||||
|
Log.e(TAG,"",tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) {
|
},"gracCancel").start();
|
||||||
if(gracefulQuitTimerOld!=null)gracefulQuitTimerOld.cancel();
|
}
|
||||||
final Timer gracefulQuitTimer = new Timer(true);
|
|
||||||
setGracefulQuitTimer(gracefulQuitTimer);
|
|
||||||
gracefulQuitTimer.schedule(new TimerTask(){
|
|
||||||
|
|
||||||
@Override
|
private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) {
|
||||||
public void run() {
|
if(gracefulQuitTimerOld!=null)gracefulQuitTimerOld.cancel();
|
||||||
i2pdStop();
|
final Timer gracefulQuitTimer = new Timer(true);
|
||||||
}
|
setGracefulQuitTimer(gracefulQuitTimer);
|
||||||
|
gracefulQuitTimer.schedule(new TimerTask(){
|
||||||
|
|
||||||
}, Math.max(0,gracefulStopAtMillis-System.currentTimeMillis()));
|
@Override
|
||||||
final TimerTask tickerTask = new TimerTask() {
|
public void run() {
|
||||||
@Override
|
i2pdStop();
|
||||||
public void run() {
|
}
|
||||||
daemonStateUpdatedListener.daemonStateUpdate();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
gracefulQuitTimer.scheduleAtFixedRate(tickerTask,0/*start delay*/,1000/*millis period*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Timer getGracefulQuitTimer() {
|
}, Math.max(0,gracefulStopAtMillis-System.currentTimeMillis()));
|
||||||
return gracefulQuitTimer;
|
final TimerTask tickerTask = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
daemonStateUpdatedListener.daemonStateUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gracefulQuitTimer.scheduleAtFixedRate(tickerTask,0/*start delay*/,1000/*millis period*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Timer getGracefulQuitTimer() {
|
||||||
|
return gracefulQuitTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setGracefulQuitTimer(Timer gracefulQuitTimer) {
|
private static void setGracefulQuitTimer(Timer gracefulQuitTimer) {
|
||||||
I2PDActivity.gracefulQuitTimer = gracefulQuitTimer;
|
I2PDActivity.gracefulQuitTimer = gracefulQuitTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the asset at the specified path to this app's data directory. If the
|
||||||
|
* asset is a directory, its contents are also copied.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* Path to asset, relative to app's assets directory.
|
||||||
|
*/
|
||||||
|
private void copyAsset(String path) {
|
||||||
|
AssetManager manager = getAssets();
|
||||||
|
|
||||||
|
// If we have a directory, we make it and recurse. If a file, we copy its
|
||||||
|
// contents.
|
||||||
|
try {
|
||||||
|
String[] contents = manager.list(path);
|
||||||
|
|
||||||
|
// The documentation suggests that list throws an IOException, but doesn't
|
||||||
|
// say under what conditions. It'd be nice if it did so when the path was
|
||||||
|
// to a file. That doesn't appear to be the case. If the returned array is
|
||||||
|
// null or has 0 length, we assume the path is to a file. This means empty
|
||||||
|
// directories will get turned into files.
|
||||||
|
if (contents == null || contents.length == 0)
|
||||||
|
throw new IOException();
|
||||||
|
|
||||||
|
// Make the directory.
|
||||||
|
File dir = new File(i2pdpath, path);
|
||||||
|
dir.mkdirs();
|
||||||
|
|
||||||
|
// Recurse on the contents.
|
||||||
|
for (String entry : contents) {
|
||||||
|
copyAsset(path + "/" + entry);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
copyFileAsset(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the asset file specified by path to app's data directory. Assumes
|
||||||
|
* parent directories have already been created.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* Path to asset, relative to app's assets directory.
|
||||||
|
*/
|
||||||
|
private void copyFileAsset(String path) {
|
||||||
|
File file = new File(i2pdpath, path);
|
||||||
|
if(!file.exists()) try {
|
||||||
|
InputStream in = getAssets().open(path);
|
||||||
|
OutputStream out = new FileOutputStream(file);
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int read = in.read(buffer);
|
||||||
|
while (read != -1) {
|
||||||
|
out.write(buffer, 0, read);
|
||||||
|
read = in.read(buffer);
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteRecursive(File fileOrDirectory) {
|
||||||
|
if (fileOrDirectory.isDirectory()) {
|
||||||
|
for (File child : fileOrDirectory.listFiles()) {
|
||||||
|
deleteRecursive(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileOrDirectory.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processAssets() {
|
||||||
|
if (!assetsCopied) try {
|
||||||
|
assetsCopied = true; // prevent from running on every state update
|
||||||
|
|
||||||
|
File holderfile = new File(i2pdpath, "assets.ready");
|
||||||
|
String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
|
||||||
|
if (holderfile.exists()) try { // if holder file exists, read assets version string
|
||||||
|
BufferedReader br = new BufferedReader(new FileReader(holderfile));
|
||||||
|
String line;
|
||||||
|
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
text.append(line);
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
Log.e(TAG, "", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if version differs from current app version or null, try to delete certificates folder
|
||||||
|
if (!text.toString().contains(versionName)) try {
|
||||||
|
holderfile.delete();
|
||||||
|
File certpath = new File(i2pdpath, "certificates");
|
||||||
|
deleteRecursive(certpath);
|
||||||
|
}
|
||||||
|
catch (Throwable tr) {
|
||||||
|
Log.e(TAG, "", tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy assets. If processed file exists, it won't be overwrited
|
||||||
|
copyAsset("addressbook");
|
||||||
|
copyAsset("certificates");
|
||||||
|
copyAsset("tunnels.d");
|
||||||
|
copyAsset("i2pd.conf");
|
||||||
|
copyAsset("subscriptions.txt");
|
||||||
|
copyAsset("tunnels.conf");
|
||||||
|
|
||||||
|
// update holder file about successful copying
|
||||||
|
FileWriter writer = new FileWriter(holderfile);
|
||||||
|
writer.append(versionName);
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
catch (Throwable tr)
|
||||||
|
{
|
||||||
|
Log.e(TAG,"copy assets",tr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,157 +15,156 @@ import java.lang.reflect.Method;
|
|||||||
//android.permission.WRITE_EXTERNAL_STORAGE
|
//android.permission.WRITE_EXTERNAL_STORAGE
|
||||||
public class I2PDPermsAskerActivity extends Activity {
|
public class I2PDPermsAskerActivity extends Activity {
|
||||||
|
|
||||||
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
|
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
|
||||||
|
|
||||||
private Button button_request_write_ext_storage_perms;
|
private Button button_request_write_ext_storage_perms;
|
||||||
private TextView textview_retry;
|
private TextView textview_retry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
//if less than Android 6, no runtime perms req system present
|
//if less than Android 6, no runtime perms req system present
|
||||||
if (android.os.Build.VERSION.SDK_INT < 23) {
|
if (android.os.Build.VERSION.SDK_INT < 23) {
|
||||||
startMainActivity();
|
startMainActivity();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_perms_asker);
|
setContentView(R.layout.activity_perms_asker);
|
||||||
button_request_write_ext_storage_perms = (Button) findViewById(R.id.button_request_write_ext_storage_perms);
|
button_request_write_ext_storage_perms = (Button) findViewById(R.id.button_request_write_ext_storage_perms);
|
||||||
textview_retry = (TextView) findViewById(R.id.textview_retry);
|
textview_retry = (TextView) findViewById(R.id.textview_retry);
|
||||||
|
|
||||||
button_request_write_ext_storage_perms.setOnClickListener(new View.OnClickListener() {
|
button_request_write_ext_storage_perms.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
request_write_ext_storage_perms();
|
request_write_ext_storage_perms();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
request_write_ext_storage_perms();
|
request_write_ext_storage_perms();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void request_write_ext_storage_perms() {
|
private void request_write_ext_storage_perms() {
|
||||||
|
|
||||||
textview_retry.setVisibility(TextView.GONE);
|
textview_retry.setVisibility(TextView.GONE);
|
||||||
button_request_write_ext_storage_perms.setVisibility(Button.GONE);
|
button_request_write_ext_storage_perms.setVisibility(Button.GONE);
|
||||||
|
|
||||||
Method methodCheckPermission;
|
Method methodCheckPermission;
|
||||||
Method method_shouldShowRequestPermissionRationale;
|
Method method_shouldShowRequestPermissionRationale;
|
||||||
Method method_requestPermissions;
|
Method method_requestPermissions;
|
||||||
try {
|
try {
|
||||||
methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class);
|
methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class);
|
||||||
method_shouldShowRequestPermissionRationale =
|
method_shouldShowRequestPermissionRationale =
|
||||||
getClass().getMethod("shouldShowRequestPermissionRationale", String.class);
|
getClass().getMethod("shouldShowRequestPermissionRationale", String.class);
|
||||||
method_requestPermissions =
|
method_requestPermissions =
|
||||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
getClass().getMethod("requestPermissions", String[].class, int.class);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
Integer resultObj;
|
Integer resultObj;
|
||||||
try {
|
try {
|
||||||
resultObj = (Integer) methodCheckPermission.invoke(
|
resultObj = (Integer) methodCheckPermission.invoke(
|
||||||
this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultObj != PackageManager.PERMISSION_GRANTED) {
|
if (resultObj != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
||||||
// Should we show an explanation?
|
// Should we show an explanation?
|
||||||
Boolean aBoolean;
|
Boolean aBoolean;
|
||||||
try {
|
try {
|
||||||
aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this,
|
aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this,
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
if (aBoolean) {
|
if (aBoolean) {
|
||||||
|
|
||||||
// Show an explanation to the user *asynchronously* -- don't block
|
// Show an explanation to the user *asynchronously* -- don't block
|
||||||
// this thread waiting for the user's response! After the user
|
// this thread waiting for the user's response! After the user
|
||||||
// sees the explanation, try again to request the permission.
|
// sees the explanation, try again to request the permission.
|
||||||
|
|
||||||
showExplanation();
|
showExplanation();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// No explanation needed, we can request the permission.
|
// No explanation needed, we can request the permission.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
method_requestPermissions.invoke(this,
|
method_requestPermissions.invoke(this,
|
||||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
PERMISSION_WRITE_EXTERNAL_STORAGE);
|
PERMISSION_WRITE_EXTERNAL_STORAGE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else startMainActivity();
|
} else startMainActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
public void onRequestPermissionsResult(int requestCode,
|
||||||
String permissions[], int[] grantResults) {
|
String permissions[], int[] grantResults) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case PERMISSION_WRITE_EXTERNAL_STORAGE: {
|
case PERMISSION_WRITE_EXTERNAL_STORAGE: {
|
||||||
// If request is cancelled, the result arrays are empty.
|
// If request is cancelled, the result arrays are empty.
|
||||||
if (grantResults.length > 0
|
if (grantResults.length > 0
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
||||||
// permission was granted, yay! Do the
|
// permission was granted, yay! Do the
|
||||||
// contacts-related task you need to do.
|
// contacts-related task you need to do.
|
||||||
|
|
||||||
startMainActivity();
|
startMainActivity();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// permission denied, boo! Disable the
|
// permission denied, boo! Disable the
|
||||||
// functionality that depends on this permission.
|
// functionality that depends on this permission.
|
||||||
textview_retry.setText("SD card write permission denied, you need to allow this to continue");
|
textview_retry.setText(R.string.permDenied);
|
||||||
textview_retry.setVisibility(TextView.VISIBLE);
|
textview_retry.setVisibility(TextView.VISIBLE);
|
||||||
button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE);
|
button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE);
|
||||||
}
|
}
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// other 'case' lines to check for other
|
// other 'case' lines to check for other
|
||||||
// permissions this app might request.
|
// permissions this app might request.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startMainActivity() {
|
private void startMainActivity() {
|
||||||
startActivity(new Intent(this, I2PDActivity.class));
|
startActivity(new Intent(this, I2PDActivity.class));
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code
|
private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code
|
||||||
private void showExplanation() {
|
private void showExplanation() {
|
||||||
Intent intent = new Intent(this, I2PDPermsExplanationActivity.class);
|
Intent intent = new Intent(this, I2PDPermsExplanationActivity.class);
|
||||||
startActivityForResult(intent, SHOW_EXPLANATION_REQUEST);
|
startActivityForResult(intent, SHOW_EXPLANATION_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
// Check which request we're responding to
|
// Check which request we're responding to
|
||||||
if (requestCode == SHOW_EXPLANATION_REQUEST) {
|
if (requestCode == SHOW_EXPLANATION_REQUEST) {
|
||||||
// Make sure the request was successful
|
// Make sure the request was successful
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
// Request the permission
|
// Request the permission
|
||||||
Method method_requestPermissions;
|
Method method_requestPermissions;
|
||||||
try {
|
try {
|
||||||
method_requestPermissions =
|
method_requestPermissions =
|
||||||
getClass().getMethod("requestPermissions", String[].class, int.class);
|
getClass().getMethod("requestPermissions", String[].class, int.class);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
method_requestPermissions.invoke(this,
|
method_requestPermissions.invoke(this,
|
||||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
PERMISSION_WRITE_EXTERNAL_STORAGE);
|
PERMISSION_WRITE_EXTERNAL_STORAGE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
finish(); //close the app
|
finish(); //close the app
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,30 +9,30 @@ import android.widget.Button;
|
|||||||
|
|
||||||
public class I2PDPermsExplanationActivity extends Activity {
|
public class I2PDPermsExplanationActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_perms_explanation);
|
setContentView(R.layout.activity_perms_explanation);
|
||||||
ActionBar actionBar = getActionBar();
|
ActionBar actionBar = getActionBar();
|
||||||
if(actionBar!=null)actionBar.setHomeButtonEnabled(false);
|
if(actionBar!=null)actionBar.setHomeButtonEnabled(false);
|
||||||
Button button_ok = (Button) findViewById(R.id.button_ok);
|
Button button_ok = (Button) findViewById(R.id.button_ok);
|
||||||
button_ok.setOnClickListener(new View.OnClickListener() {
|
button_ok.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
returnFromActivity();
|
returnFromActivity();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void returnFromActivity() {
|
private void returnFromActivity() {
|
||||||
Intent data = new Intent();
|
Intent data = new Intent();
|
||||||
Activity parent = getParent();
|
Activity parent = getParent();
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
setResult(Activity.RESULT_OK, data);
|
setResult(Activity.RESULT_OK, data);
|
||||||
} else {
|
} else {
|
||||||
parent.setResult(Activity.RESULT_OK, data);
|
parent.setResult(Activity.RESULT_OK, data);
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,27 @@
|
|||||||
package org.purplei2p.i2pd;
|
package org.purplei2p.i2pd;
|
||||||
|
|
||||||
public class I2PD_JNI {
|
public class I2PD_JNI {
|
||||||
public static native String getABICompiledWith();
|
public static native String getABICompiledWith();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns error info if failed
|
* returns error info if failed
|
||||||
* returns "ok" if daemon initialized and started okay
|
* returns "ok" if daemon initialized and started okay
|
||||||
*/
|
*/
|
||||||
public static native String startDaemon();
|
public static native String startDaemon();
|
||||||
//should only be called after startDaemon() success
|
|
||||||
public static native void stopDaemon();
|
|
||||||
|
|
||||||
public static native void stopAcceptingTunnels();
|
//should only be called after startDaemon() success
|
||||||
|
public static native void stopDaemon();
|
||||||
|
|
||||||
|
public static native void stopAcceptingTunnels();
|
||||||
|
|
||||||
|
public static native void startAcceptingTunnels();
|
||||||
|
|
||||||
public static native void onNetworkStateChanged(boolean isConnected);
|
public static native void onNetworkStateChanged(boolean isConnected);
|
||||||
|
|
||||||
|
public static native void setDataDir(String jdataDir);
|
||||||
|
|
||||||
public static void loadLibraries() {
|
public static void loadLibraries() {
|
||||||
System.loadLibrary("gnustl_shared");
|
//System.loadLibrary("c++_shared");
|
||||||
System.loadLibrary("i2pd");
|
System.loadLibrary("i2pd");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import android.net.NetworkInfo;
|
|||||||
|
|
||||||
public class NetworkStateChangeReceiver extends BroadcastReceiver {
|
public class NetworkStateChangeReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
private static final String TAG = "i2pd";
|
private static final String TAG = "i2pd";
|
||||||
|
|
||||||
//api level 1
|
//api level 1
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
Log.d(TAG,"Network state change");
|
Log.d(TAG,"Network state change");
|
||||||
try {
|
try {
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
|
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
|
||||||
@@ -26,5 +26,5 @@ public class NetworkStateChangeReceiver extends BroadcastReceiver {
|
|||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
Log.d(TAG,"",tr);
|
Log.d(TAG,"",tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
android_binary_only/.gitignore
vendored
Normal file
18
android_binary_only/.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
gen
|
||||||
|
tests
|
||||||
|
bin
|
||||||
|
libs
|
||||||
|
log*
|
||||||
|
obj
|
||||||
|
.gradle
|
||||||
|
.idea
|
||||||
|
.externalNativeBuild
|
||||||
|
ant.properties
|
||||||
|
local.properties
|
||||||
|
build.sh
|
||||||
|
android.iml
|
||||||
|
build
|
||||||
|
gradle
|
||||||
|
gradlew
|
||||||
|
gradlew.bat
|
||||||
|
|
||||||
@@ -26,49 +26,49 @@ include $(BUILD_EXECUTABLE)
|
|||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_system
|
LOCAL_MODULE := boost_system
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_system.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_date_time
|
LOCAL_MODULE := boost_date_time
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_filesystem
|
LOCAL_MODULE := boost_filesystem
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := boost_program_options
|
LOCAL_MODULE := boost_program_options
|
||||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
|
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
|
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := crypto
|
LOCAL_MODULE := crypto
|
||||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libcrypto.a
|
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include
|
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := ssl
|
LOCAL_MODULE := ssl
|
||||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libssl.a
|
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libssl.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include
|
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include
|
||||||
LOCAL_STATIC_LIBRARIES := crypto
|
LOCAL_STATIC_LIBRARIES := crypto
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := miniupnpc
|
LOCAL_MODULE := miniupnpc
|
||||||
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnp-2.0/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
|
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnp-2.0/include
|
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
|
||||||
include $(PREBUILT_STATIC_LIBRARY)
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
#APP_ABI := all
|
APP_ABI := all
|
||||||
#APP_ABI := armeabi-v7a x86
|
#APP_ABI += x86
|
||||||
#APP_ABI := x86
|
#APP_ABI += x86_64
|
||||||
#APP_ABI := x86_64
|
#APP_ABI += armeabi-v7a
|
||||||
APP_ABI := armeabi-v7a
|
#APP_ABI += arm64-v8a
|
||||||
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
|
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
|
||||||
APP_PLATFORM := android-14
|
APP_PLATFORM := android-14
|
||||||
|
|
||||||
# http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse
|
NDK_TOOLCHAIN_VERSION := clang
|
||||||
NDK_TOOLCHAIN_VERSION := 4.9
|
APP_STL := c++_static
|
||||||
# APP_STL := stlport_shared --> does not seem to contain C++11 features
|
|
||||||
#APP_STL := gnustl_shared
|
|
||||||
APP_STL := gnustl_static
|
|
||||||
|
|
||||||
# Enable c++11 extensions in source code
|
# Enable c++11 extensions in source code
|
||||||
APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE
|
APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
version: 2.19.{build}
|
version: 2.25.0.{build}
|
||||||
pull_requests:
|
pull_requests:
|
||||||
do_not_increment_build_number: true
|
do_not_increment_build_number: true
|
||||||
branches:
|
branches:
|
||||||
@@ -18,9 +18,9 @@ environment:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc"
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc"
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu "
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force"
|
||||||
|
|
||||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force"
|
||||||
|
|
||||||
- if "%MSYSTEM%" == "MINGW64" (
|
- if "%MSYSTEM%" == "MINGW64" (
|
||||||
c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc"
|
c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc"
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ include_directories(${LIBI2PD_CLIENT_SRC_DIR})
|
|||||||
set (LIBI2PD_SRC
|
set (LIBI2PD_SRC
|
||||||
"${LIBI2PD_SRC_DIR}/BloomFilter.cpp"
|
"${LIBI2PD_SRC_DIR}/BloomFilter.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Config.cpp"
|
"${LIBI2PD_SRC_DIR}/Config.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/CPU.cpp"
|
"${LIBI2PD_SRC_DIR}/CPU.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Crypto.cpp"
|
"${LIBI2PD_SRC_DIR}/Crypto.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/CryptoKey.cpp"
|
"${LIBI2PD_SRC_DIR}/CryptoKey.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Garlic.cpp"
|
"${LIBI2PD_SRC_DIR}/Garlic.cpp"
|
||||||
@@ -77,10 +77,10 @@ set (LIBI2PD_SRC
|
|||||||
"${LIBI2PD_SRC_DIR}/api.cpp"
|
"${LIBI2PD_SRC_DIR}/api.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Event.cpp"
|
"${LIBI2PD_SRC_DIR}/Event.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Gost.cpp"
|
"${LIBI2PD_SRC_DIR}/Gost.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/ChaCha20.cpp"
|
"${LIBI2PD_SRC_DIR}/ChaCha20.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Poly1305.cpp"
|
"${LIBI2PD_SRC_DIR}/Poly1305.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/Ed25519.cpp"
|
"${LIBI2PD_SRC_DIR}/Ed25519.cpp"
|
||||||
"${LIBI2PD_SRC_DIR}/NTCP2.cpp"
|
"${LIBI2PD_SRC_DIR}/NTCP2.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WITH_WEBSOCKETS)
|
if (WITH_WEBSOCKETS)
|
||||||
@@ -190,7 +190,7 @@ if (CXX11_SUPPORTED)
|
|||||||
elseif (CXX0X_SUPPORTED) # gcc 4.6
|
elseif (CXX0X_SUPPORTED) # gcc 4.6
|
||||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x" )
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x" )
|
||||||
elseif (NOT MSVC)
|
elseif (NOT MSVC)
|
||||||
message(SEND_ERROR "C++11 standart not seems to be supported by compiler. Too old version?")
|
message(SEND_ERROR "C++11 standard not seems to be supported by compiler. Too old version?")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
@@ -202,9 +202,11 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||||||
endif ()
|
endif ()
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
# more tweaks
|
# more tweaks
|
||||||
if (NOT (MSVC OR MSYS OR APPLE))
|
if (LINUX)
|
||||||
set (CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -stdlib=libstdc++" ) # required for <atomic>
|
set (CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -stdlib=libstdc++" ) # required for <atomic>
|
||||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "stdc++") # required to link with -stdlib=libstdc++
|
list(APPEND CMAKE_REQUIRED_LIBRARIES "stdc++") # required to link with -stdlib=libstdc++
|
||||||
|
endif()
|
||||||
|
if (NOT (MSVC OR MSYS OR APPLE))
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-const-variable -Wno-overloaded-virtual -Wno-c99-extensions" )
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-const-variable -Wno-overloaded-virtual -Wno-c99-extensions" )
|
||||||
endif()
|
endif()
|
||||||
endif ()
|
endif ()
|
||||||
@@ -234,7 +236,6 @@ endif ()
|
|||||||
|
|
||||||
if (WITH_AESNI)
|
if (WITH_AESNI)
|
||||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes" )
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes" )
|
||||||
add_definitions ( -DAESNI )
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WITH_AVX)
|
if (WITH_AVX)
|
||||||
@@ -339,7 +340,7 @@ target_link_libraries(libi2pdclient libi2pd)
|
|||||||
|
|
||||||
find_package ( Boost COMPONENTS system filesystem program_options date_time REQUIRED )
|
find_package ( Boost COMPONENTS system filesystem program_options date_time REQUIRED )
|
||||||
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
if(NOT DEFINED Boost_INCLUDE_DIRS)
|
||||||
message(SEND_ERROR "Boost is not found, or your boost version was bellow 1.46. Please download Boost!")
|
message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package ( OpenSSL REQUIRED )
|
find_package ( OpenSSL REQUIRED )
|
||||||
@@ -363,8 +364,8 @@ if (NOT ZLIB_FOUND )
|
|||||||
set( ZLIB_EXTRA -DASM686=ON "-DCMAKE_ASM_MASM_FLAGS=/W0 /safeseh" )
|
set( ZLIB_EXTRA -DASM686=ON "-DCMAKE_ASM_MASM_FLAGS=/W0 /safeseh" )
|
||||||
endif()
|
endif()
|
||||||
ExternalProject_Add(zlib-project
|
ExternalProject_Add(zlib-project
|
||||||
URL http://zlib.net/zlib-1.2.8.tar.gz
|
URL https://zlib.net/zlib-1.2.11.tar.gz
|
||||||
URL_MD5 44d667c142d7cda120332623eab69f40
|
URL_HASH SHA256=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
|
||||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/zlib
|
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/zlib
|
||||||
PATCH_COMMAND "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-static.patch
|
PATCH_COMMAND "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-static.patch
|
||||||
&& "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-amd64.patch
|
&& "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-amd64.patch
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ set MSYSTEM=MINGW32
|
|||||||
|
|
||||||
set "xSH=%WD%bash -lc"
|
set "xSH=%WD%bash -lc"
|
||||||
|
|
||||||
|
set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d"
|
||||||
|
|
||||||
REM detecting number of processors and subtract 1.
|
REM detecting number of processors and subtract 1.
|
||||||
set /a threads=%NUMBER_OF_PROCESSORS%-1
|
set /a threads=%NUMBER_OF_PROCESSORS%-1
|
||||||
|
|
||||||
@@ -62,12 +64,12 @@ exit /b 0
|
|||||||
%xSH% "make clean" >> nul
|
%xSH% "make clean" >> nul
|
||||||
echo Building i2pd %tag% for win%bitness%:
|
echo Building i2pd %tag% for win%bitness%:
|
||||||
echo Build AVX+AESNI...
|
echo Build AVX+AESNI...
|
||||||
%xSH% "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1
|
%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_aesni_%tag%.log 2>&1
|
||||||
echo Build AVX...
|
echo Build AVX...
|
||||||
%xSH% "make USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx.log 2>&1
|
%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_%tag%.log 2>&1
|
||||||
echo Build AESNI...
|
echo Build AESNI...
|
||||||
%xSH% "make USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_aesni.log 2>&1
|
%xSH% "make DEBUG=no USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_aesni_%tag%.log 2>&1
|
||||||
echo Build without extensions...
|
echo Build without extensions...
|
||||||
%xSH% "make USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%.log 2>&1
|
%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build/build_win%bitness%_%tag%.log 2>&1
|
||||||
|
|
||||||
:EOF
|
:EOF
|
||||||
2
contrib/android_binary_pack/.gitignore
vendored
Normal file
2
contrib/android_binary_pack/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
archive
|
||||||
|
i2pd_*_android_binary.zip
|
||||||
45
contrib/android_binary_pack/build-archive
Executable file
45
contrib/android_binary_pack/build-archive
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (c) 2013-2017, The PurpleI2P Project
|
||||||
|
#
|
||||||
|
# This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
#
|
||||||
|
# See full license text in LICENSE file at top of project tree
|
||||||
|
|
||||||
|
GITDESC=$(git describe --tags)
|
||||||
|
|
||||||
|
declare -A ABILIST=(
|
||||||
|
["armeabi-v7a"]="armv7l"
|
||||||
|
["arm64-v8a"]="aarch64"
|
||||||
|
["x86"]="x86"
|
||||||
|
["x86_64"]="x86_64"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove old files and archives
|
||||||
|
if [ -d archive ]; then
|
||||||
|
rm -r archive
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f i2pd_*_android_binary.zip ]; then
|
||||||
|
rm i2pd_*_android_binary.zip
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prepare files for package
|
||||||
|
mkdir archive
|
||||||
|
|
||||||
|
for ABI in "${!ABILIST[@]}"; do
|
||||||
|
if [ -f ../../android_binary_only/libs/${ABI}/i2pd ]; then
|
||||||
|
cp ../../android_binary_only/libs/${ABI}/i2pd archive/i2pd-${ABILIST[$ABI]}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
cp i2pd archive/i2pd
|
||||||
|
cp -rH ../../android/assets/* archive/
|
||||||
|
|
||||||
|
# Compress files
|
||||||
|
cd archive
|
||||||
|
zip -r6 ../i2pd_${GITDESC}_android_binary.zip .
|
||||||
|
|
||||||
|
# Remove temporary folder
|
||||||
|
cd ..
|
||||||
|
rm -r archive
|
||||||
33
contrib/android_binary_pack/i2pd
Executable file
33
contrib/android_binary_pack/i2pd
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright (c) 2013-2019, The PurpleI2P Project
|
||||||
|
#
|
||||||
|
# This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
#
|
||||||
|
# See full license text in LICENSE file at top of project tree
|
||||||
|
#
|
||||||
|
# That script written for use with Termux.
|
||||||
|
|
||||||
|
# https://stackoverflow.com/a/246128
|
||||||
|
SOURCE="${0}"
|
||||||
|
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
|
||||||
|
arch=$(uname -m)
|
||||||
|
|
||||||
|
screenfind=$(which screen)
|
||||||
|
if [ -z $screenfind ]; then
|
||||||
|
echo "Can't find 'screen' installed. That script needs it!";
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z i2pd-$arch ]; then
|
||||||
|
echo "Can't find i2pd binary for your archtecture.";
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
screen -AmdS i2pd ./i2pd-$arch --datadir=$DIR
|
||||||
34
contrib/certificates/reseed/reseedi2pnetin_at_mail.i2p.crt
Normal file
34
contrib/certificates/reseed/reseedi2pnetin_at_mail.i2p.crt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIF3DCCA8SgAwIBAgIQPxUlcrbHX/xdyJ09E36rJzANBgkqhkiG9w0BAQsFADB3
|
||||||
|
MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK
|
||||||
|
ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEgMB4GA1UEAwwX
|
||||||
|
cmVzZWVkaTJwbmV0aW5AbWFpbC5pMnAwHhcNMTgxMjA3MTYzNDIxWhcNMjgxMjA3
|
||||||
|
MTYzNDIxWjB3MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhY
|
||||||
|
MR4wHAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEg
|
||||||
|
MB4GA1UEAwwXcmVzZWVkaTJwbmV0aW5AbWFpbC5pMnAwggIiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4ICDwAwggIKAoICAQC912NDk6x85uqB4gyQQcded0RVrbWehWOanDRv7kC3
|
||||||
|
92jeziPbeMtqrLsfU1MdDtQiGijpNkQ/IIitPw+6vJAIh82gyOUZvsn2XOyb/Fz0
|
||||||
|
Fu8OrDghwl39yK8kwtqCFw3VAgafgKxz2oRge9mxFBECi50vYEPIBwNhr4yc/opu
|
||||||
|
wWUmzmRyX4gD7vKmRU6ZTwX4LXnwdl+5VbW3updcZKsDuTnKvC9FGhDRR9kIk2G9
|
||||||
|
43sLN263nCYPykP7DaB1cUdi1vDEMw5dot+eu16qTIbuypEvYNvbB/9FyCQllm1h
|
||||||
|
vBbSku3IYpcnRPmoeyhoR/MmCySRbK5R4SrSsVD1YBpwxgn0Q4+fzEgFzT9P4oez
|
||||||
|
HkDGKVP2HdgmXx9j36fEqqvjqzRleWDwEWwIZVRLCFO+hhhT3JAjnNGJTWv1SQGB
|
||||||
|
8tz9nyYTJuhvyHE/CO5owFeCdeOGMq2KPge9w34T+mvewTEEhGU8yRAt8Xp8s5Y9
|
||||||
|
RCUGvuQ79+edRtj7FJg7yVB8pAQ+VB9msNQvzrTnPYC9Wo7chJhBiraMiIabzIhC
|
||||||
|
f34Gg9lkX1N0dVND5rnZWwzBM6JhNG1iZZCRHVPnXdZRixUlqmFpCP/eekshksj/
|
||||||
|
6UP/WeGA6X4HyEsC6QEf7eMhcHYjyyTzYagKrwCHg77fmIjF8rmpP2LqWSQW8bDD
|
||||||
|
uQIDAQABo2QwYjAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIG
|
||||||
|
CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wIAYDVR0OBBkEF3Jlc2VlZGkycG5l
|
||||||
|
dGluQG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQCWpXs6iuTy/w2R7q7Ua6vl
|
||||||
|
JYZwbQ+czk5ydzkBgcNkMMMNRT7sZR9xYvV+ftiL4bFQP/3ZJyo7cYz2Q6+M3oAm
|
||||||
|
YDcZWBkLUVihSlMxhWwmeFTKV2EL+bzwY1V/cy7wgukKnFIes75dLP/v25jgjdlw
|
||||||
|
Xe6R+fQM0EoHeVzzrWk/qYp6oEwtQXfZnUu/Bf45hRnnHBzzh1wCql41vbEs3Niq
|
||||||
|
+SVwY1wLT0yC1L8HqjCLX1/L5PAXxbvEGzwnXSkLKK4bPxdmVDZvS9uzXrWmTbNi
|
||||||
|
HpKIFnOif16zSgyeaOM7HETIJuVzgooUMtt+Vsr1VGdtm6K7I9J5C+rX/ckU8oaX
|
||||||
|
UjmzhWXudN0VTslogsKUCV6xG2CskeE3wnuT8HYXz9NMw6c/kIGH4hY7LcfU8Teu
|
||||||
|
QjSy2RRvy6InmZNV5sY9lzzO6romEycSoUlpCa3Ltb/5KKoYZFTsXr8suqJk89lC
|
||||||
|
e+TVMHqOZdLK/usqQDcafLypHpw9SH2Tg4jrzV/zLqacbjx6bZD5IrpY0Gf7BXg/
|
||||||
|
pikwyA9c490G6ZcWrSEP8bzh6LL2rA2AwxaeJJNVyLHCSLrn/7DezM5J/qhd90Qg
|
||||||
|
kcZGJrUOCSWl6mDvUZn5XiQ955XwOnZQ+wsM85B3CVX22x5bp0SYWHCQBPnthPwP
|
||||||
|
Q5DD3jExbpwG5n35HEcHYw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIF1TCCA72gAwIBAgIRAJBHySZnvNg3lU00//fwny4wDQYJKoZIhvcNAQELBQAw
|
|
||||||
bDELMAkGA1UEBhMCWFgxHjAcBgNVBAoTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEM
|
|
||||||
MAoGA1UECxMDSTJQMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxFTATBgNVBAMM
|
|
||||||
DHpteEBtYWlsLmkycDAeFw0xNjAxMDExNzE5MTlaFw0yNjAxMDExNzE5MTlaMGwx
|
|
||||||
CzAJBgNVBAYTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAK
|
|
||||||
BgNVBAsTA0kyUDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMRUwEwYDVQQDDAx6
|
|
||||||
bXhAbWFpbC5pMnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnDGVU
|
|
||||||
iC6pNJ3mfqZRQYACUbQ6SQI05yh3PawHqQrmiW3rD05SXBCF+6b2EpA4U0ThFhtm
|
|
||||||
cGyUObtBL749x03SUYcWhknZNq+zrvb9AypaKFpIx2DjFT8vQadn0l71cNaiwxX1
|
|
||||||
Wzk1Au6mh9SFPvH5gDF9SQol7dYYKnn9L61V7hvH9fDiZyoi9Cz3ifE3SAWoM2PJ
|
|
||||||
lBzbu16tyQE94HvIdZhp8cE/6/kiW1wjSqvT9dfZ4gMuZHOF5E8lkq/bg8tPa/oj
|
|
||||||
rglY7ozT/9/IWtJ7ERcDyepmKjq7+Xx4sNXTvc+B7D4XfMjhaxFLtV/kLQ9mqx8R
|
|
||||||
UPvPy+atw7mlfUf822YFSft2jBAxNJwCPdhXuuFkTUTIk9YXcChUCSPyv17gej/P
|
|
||||||
A++/hdhYI/kIs8AVsaJjytTqwU3A2Pt1QogM8VLsSJ2NY7gSzj868nzIZ4OuoWbz
|
|
||||||
KzpnS/3bQkYHrqMtDIjRr1bOudxbu2/ben5v8Qg9wE9uV/8YNhhaKAcfJOV6OXfF
|
|
||||||
MYec9DOEVVvECOfYUX35Vtn/w7E6SSL7Gu6QEWviA4Bf2XBh1YFX0ZpBUMY9awNz
|
|
||||||
7PDf+z+YGkrQ6ifvLPW9vHW3lmouRWzo5NgJIIvLYBJKmxkf08p94s8YailjiGzA
|
|
||||||
dJWXg3HDWgwMe7BY7AJQbU/o35Vv+0CroUsR3wIDAQABo3IwcDAOBgNVHQ8BAf8E
|
|
||||||
BAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA8GA1UdEwEB/wQF
|
|
||||||
MAMBAf8wFQYDVR0OBA4EDHpteEBtYWlsLmkycDAXBgNVHSMEEDAOgAx6bXhAbWFp
|
|
||||||
bC5pMnAwDQYJKoZIhvcNAQELBQADggIBAATXH/PNdF40DjD9DcF4W5Ot7CWGskDY
|
|
||||||
cR4ywtvU2EcDNEwv4q0FPEpxy5LPaUmTKQ6fsRXUZizjaPLpgCLbv9qYc5xRLrSi
|
|
||||||
yk9mrAbJ1iEU+DfHHBcS1VQWtc7+9LA0W3ZIA+pygjPjTxwQqQAcjn4BdfaIQpVa
|
|
||||||
VJ2kl5JtbTuYHL80GAQFYnzCCa5GKM7zgcLsyO1mQwnpDvFeSlKJJ6rx1QjhlJu+
|
|
||||||
90Ig8IOBCIgokfUv9OdYBl6rmDq9i9pvqJU+H4VepqE1jnDAO+YqQ4laZj7LVVM8
|
|
||||||
I9uia+8RKntUOBkUkLB3ouGdVJUmp3kGrkExxUdDHYP9VNJG6ZMwyKO8HXGtoTsR
|
|
||||||
TFWIEIbq/biBL9obM/d8fRV5xpfZNbPi6cRzw8REY9UIKECKr7B2B6PnDVVQIQw0
|
|
||||||
7SCVjmSYWexOqoJPZ1L7/AZDP/tFvx32cWwCszj5jqUaPo9ZNPb6DxQJDdNaZrFH
|
|
||||||
3CA+PbiaeEz9IH0yBY/6wQgO0k3qOyFQrlkC+YRoYUQNc+6xS38l5ZnYUtBAy8ms
|
|
||||||
N43eODQ/OhsLzy6PwwXdzvR/0g18SrQyTLfbn2b/kwvbC8Qe40QFfkOf5lPXjdnP
|
|
||||||
Ii/lcMuvDMlMhoWGFwWm5bkkXE81TKnFXu2/IMsW6HYb3oiTjkaCap22fCr9l0jj
|
|
||||||
fNr8P7NIRyZ8
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -2,7 +2,7 @@ FROM alpine:latest
|
|||||||
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
|
LABEL authors "Mikal Villa <mikal@sigterm.no>, Darknet Villain <supervillain@riseup.net>"
|
||||||
|
|
||||||
# Expose git branch, tag and URL variables as arguments
|
# Expose git branch, tag and URL variables as arguments
|
||||||
ARG GIT_BRANCH="master"
|
ARG GIT_BRANCH="openssl"
|
||||||
ENV GIT_BRANCH=${GIT_BRANCH}
|
ENV GIT_BRANCH=${GIT_BRANCH}
|
||||||
ARG GIT_TAG=""
|
ARG GIT_TAG=""
|
||||||
ENV GIT_TAG=${GIT_TAG}
|
ENV GIT_TAG=${GIT_TAG}
|
||||||
@@ -24,7 +24,7 @@ RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \
|
|||||||
# 1. install deps, clone and build.
|
# 1. install deps, clone and build.
|
||||||
# 2. strip binaries.
|
# 2. strip binaries.
|
||||||
# 3. Purge all dependencies and other unrelated packages, including build directory.
|
# 3. Purge all dependencies and other unrelated packages, including build directory.
|
||||||
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boost-dev build-base openssl-dev openssl git \
|
RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl git \
|
||||||
&& mkdir -p /tmp/build \
|
&& mkdir -p /tmp/build \
|
||||||
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
|
&& cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \
|
||||||
&& cd i2pd \
|
&& cd i2pd \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
## Configuration file for a typical i2pd user
|
## Configuration file for a typical i2pd user
|
||||||
## See https://i2pd.readthedocs.org/en/latest/configuration.html
|
## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
|
||||||
## for more options you can use in this file.
|
## for more options you can use in this file.
|
||||||
|
|
||||||
## Lines that begin with "## " try to explain what's going on. Lines
|
## Lines that begin with "## " try to explain what's going on. Lines
|
||||||
@@ -10,6 +10,11 @@
|
|||||||
## Default: ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf
|
## Default: ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf
|
||||||
# tunconf = /var/lib/i2pd/tunnels.conf
|
# tunconf = /var/lib/i2pd/tunnels.conf
|
||||||
|
|
||||||
|
## Tunnels config files path
|
||||||
|
## Use that path to store separated tunnels in different config files.
|
||||||
|
## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d
|
||||||
|
# tunnelsdir = /var/lib/i2pd/tunnels.conf.d
|
||||||
|
|
||||||
## Where to write pidfile (don't write by default)
|
## Where to write pidfile (don't write by default)
|
||||||
# pidfile = /var/run/i2pd.pid
|
# pidfile = /var/run/i2pd.pid
|
||||||
|
|
||||||
@@ -88,6 +93,8 @@ ipv6 = false
|
|||||||
## Address and port service will listen on
|
## Address and port service will listen on
|
||||||
address = 127.0.0.1
|
address = 127.0.0.1
|
||||||
port = 7070
|
port = 7070
|
||||||
|
## Path to web console, default "/"
|
||||||
|
# webroot = /
|
||||||
## Uncomment following lines to enable Web Console authentication
|
## Uncomment following lines to enable Web Console authentication
|
||||||
# auth = true
|
# auth = true
|
||||||
# user = i2pd
|
# user = i2pd
|
||||||
@@ -218,3 +225,7 @@ verify = true
|
|||||||
# inbound.quantity = 3
|
# inbound.quantity = 3
|
||||||
# outbound.length = 2
|
# outbound.length = 2
|
||||||
# outbound.quantity = 3
|
# outbound.quantity = 3
|
||||||
|
|
||||||
|
[persist]
|
||||||
|
## Save peer profiles on disk (default: true)
|
||||||
|
# profiles = true
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ RuntimeDirectoryMode=0700
|
|||||||
LogsDirectory=i2pd
|
LogsDirectory=i2pd
|
||||||
LogsDirectoryMode=0700
|
LogsDirectoryMode=0700
|
||||||
Type=forking
|
Type=forking
|
||||||
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
||||||
ExecReload=/bin/kill -HUP $MAINPID
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
PIDFile=/var/run/i2pd/i2pd.pid
|
PIDFile=/var/run/i2pd/i2pd.pid
|
||||||
### Uncomment, if auto restart needed
|
### Uncomment, if auto restart needed
|
||||||
@@ -23,8 +23,10 @@ KillSignal=SIGQUIT
|
|||||||
#KillSignal=SIGINT
|
#KillSignal=SIGINT
|
||||||
#TimeoutStopSec=10m
|
#TimeoutStopSec=10m
|
||||||
|
|
||||||
# If you have problems with hanging i2pd, you can try enable this
|
# If you have problems with hanging i2pd, you can try increase this
|
||||||
LimitNOFILE=4096
|
LimitNOFILE=4096
|
||||||
|
# To enable write of coredump uncomment this
|
||||||
|
#LimitCORE=infinity
|
||||||
PrivateDevices=yes
|
PrivateDevices=yes
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
||||||
|
|
||||||
Name: i2pd-git
|
Name: i2pd-git
|
||||||
Version: 2.19.0
|
Version: 2.25.0
|
||||||
Release: git%{git_hash}%{?dist}
|
Release: git%{git_hash}%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd
|
Conflicts: i2pd
|
||||||
@@ -47,23 +47,34 @@ cd build
|
|||||||
-DWITH_LIBRARY=OFF \
|
-DWITH_LIBRARY=OFF \
|
||||||
-DWITH_UPNP=ON \
|
-DWITH_UPNP=ON \
|
||||||
-DWITH_HARDENING=ON \
|
-DWITH_HARDENING=ON \
|
||||||
|
%if 0%{?fedora} > 29
|
||||||
|
-DBUILD_SHARED_LIBS:BOOL=OFF \
|
||||||
|
.
|
||||||
|
%else
|
||||||
-DBUILD_SHARED_LIBS:BOOL=OFF
|
-DBUILD_SHARED_LIBS:BOOL=OFF
|
||||||
%endif
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
make %{?_smp_mflags}
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
cd build
|
cd build
|
||||||
|
%if 0%{?mageia}
|
||||||
|
cd build
|
||||||
|
%endif
|
||||||
chrpath -d i2pd
|
chrpath -d i2pd
|
||||||
install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
|
%{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
|
||||||
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
|
%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
|
||||||
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
|
%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt
|
||||||
install -d -m 755 %{buildroot}%{_datadir}/i2pd
|
%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
|
||||||
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
|
%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README
|
||||||
install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
|
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
|
||||||
install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
|
%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1
|
||||||
install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
|
%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
|
||||||
|
%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
|
||||||
|
%{__install} -d -m 755 %{buildroot}%{_datadir}/%{name}
|
||||||
|
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/%{name}/certificates
|
||||||
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates
|
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates
|
||||||
|
|
||||||
|
|
||||||
@@ -87,16 +98,29 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%doc LICENSE README.md
|
%doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d
|
||||||
%{_sbindir}/i2pd
|
%{_sbindir}/i2pd
|
||||||
%{_datadir}/i2pd/certificates
|
|
||||||
%config(noreplace) %{_sysconfdir}/i2pd/*
|
%config(noreplace) %{_sysconfdir}/i2pd/*
|
||||||
/%{_unitdir}/i2pd.service
|
%{_unitdir}/i2pd.service
|
||||||
%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd
|
%{_mandir}/man1/i2pd.1*
|
||||||
%dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd
|
%dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd
|
||||||
|
%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd
|
||||||
|
%{_datadir}/%{name}/certificates
|
||||||
%{_sharedstatedir}/i2pd/certificates
|
%{_sharedstatedir}/i2pd/certificates
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu May 9 2019 orignal <i2porignal@yandex.ru> - 2.25.0
|
||||||
|
- update to 2.25.0
|
||||||
|
|
||||||
|
* Thu Mar 21 2019 orignal <i2porignal@yandex.ru> - 2.24.0
|
||||||
|
- update to 2.24.0
|
||||||
|
|
||||||
|
* Mon Jan 21 2019 orignal <i2porignal@yandex.ru> - 2.23.0
|
||||||
|
- update to 2.23.0
|
||||||
|
|
||||||
|
* Fri Nov 09 2018 r4sas <r4sas@i2pmail.org> - 2.22.0
|
||||||
|
- add support of tunnelsdir option
|
||||||
|
|
||||||
* Thu Feb 01 2018 r4sas <r4sas@i2pmail.org> - 2.18.0
|
* Thu Feb 01 2018 r4sas <r4sas@i2pmail.org> - 2.18.0
|
||||||
- Initial i2pd-git based on i2pd 2.18.0-1 spec
|
- Initial i2pd-git based on i2pd 2.18.0-1 spec
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.19.0
|
Version: 2.25.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
Conflicts: i2pd-git
|
Conflicts: i2pd-git
|
||||||
@@ -45,24 +45,35 @@ cd build
|
|||||||
-DWITH_LIBRARY=OFF \
|
-DWITH_LIBRARY=OFF \
|
||||||
-DWITH_UPNP=ON \
|
-DWITH_UPNP=ON \
|
||||||
-DWITH_HARDENING=ON \
|
-DWITH_HARDENING=ON \
|
||||||
|
%if 0%{?fedora} > 29
|
||||||
|
-DBUILD_SHARED_LIBS:BOOL=OFF \
|
||||||
|
.
|
||||||
|
%else
|
||||||
-DBUILD_SHARED_LIBS:BOOL=OFF
|
-DBUILD_SHARED_LIBS:BOOL=OFF
|
||||||
%endif
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
make %{?_smp_mflags}
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
cd build
|
cd build
|
||||||
|
%if 0%{?mageia}
|
||||||
|
cd build
|
||||||
|
%endif
|
||||||
chrpath -d i2pd
|
chrpath -d i2pd
|
||||||
install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
|
install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd
|
||||||
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
|
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf
|
||||||
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
|
install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf
|
||||||
install -d -m 755 %{buildroot}%{_datadir}/i2pd
|
install -d -m 755 %{buildroot}%{_datadir}/i2pd
|
||||||
|
install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d
|
||||||
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
|
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates
|
||||||
|
%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d
|
||||||
install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
|
install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service
|
||||||
install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
|
install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd
|
||||||
install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
|
install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd
|
||||||
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates
|
ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates
|
||||||
|
ln -s %{_datadir}/i2pd/tunnels.conf.d %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d
|
||||||
|
|
||||||
|
|
||||||
%pre
|
%pre
|
||||||
@@ -89,6 +100,7 @@ getent passwd i2pd >/dev/null || \
|
|||||||
%{_sbindir}/i2pd
|
%{_sbindir}/i2pd
|
||||||
%{_datadir}/i2pd/certificates
|
%{_datadir}/i2pd/certificates
|
||||||
%config(noreplace) %{_sysconfdir}/i2pd/*
|
%config(noreplace) %{_sysconfdir}/i2pd/*
|
||||||
|
%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*
|
||||||
/%{_unitdir}/i2pd.service
|
/%{_unitdir}/i2pd.service
|
||||||
%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd
|
%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd
|
||||||
%dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd
|
%dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd
|
||||||
@@ -96,6 +108,28 @@ getent passwd i2pd >/dev/null || \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu May 9 2019 orignal <i2porignal@yandex.ru> - 2.25.0
|
||||||
|
- update to 2.25.0
|
||||||
|
|
||||||
|
* Thu Mar 21 2019 orignal <i2porignal@yandex.ru> - 2.24.0
|
||||||
|
- update to 2.24.0
|
||||||
|
|
||||||
|
* Mon Jan 21 2019 orignal <i2porignal@yandex.ru> - 2.23.0
|
||||||
|
- update to 2.23.0
|
||||||
|
|
||||||
|
* Fri Nov 09 2018 r4sas <r4sas@i2pmail.org> - 2.22.0
|
||||||
|
- update to 2.22.0
|
||||||
|
- add support of tunnelsdir option
|
||||||
|
|
||||||
|
* Thu Oct 22 2018 orignal <i2porignal@yandex.ru> - 2.21.1
|
||||||
|
- update to 2.21.1
|
||||||
|
|
||||||
|
* Thu Oct 4 2018 orignal <i2porignal@yandex.ru> - 2.21.0
|
||||||
|
- update to 2.21.0
|
||||||
|
|
||||||
|
* Thu Aug 23 2018 orignal <i2porignal@yandex.ru> - 2.20.0
|
||||||
|
- update to 2.20.0
|
||||||
|
|
||||||
* Tue Jun 26 2018 orignal <i2porignal@yandex.ru> - 2.19.0
|
* Tue Jun 26 2018 orignal <i2porignal@yandex.ru> - 2.19.0
|
||||||
- update to 2.19.0
|
- update to 2.19.0
|
||||||
|
|
||||||
|
|||||||
7
contrib/tunnels.d/IRC-Ilita.conf
Normal file
7
contrib/tunnels.d/IRC-Ilita.conf
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#[IRC-ILITA]
|
||||||
|
#type = client
|
||||||
|
#address = 127.0.0.1
|
||||||
|
#port = 6669
|
||||||
|
#destination = irc.ilita.i2p
|
||||||
|
#destinationport = 6667
|
||||||
|
#keys = irc-keys.dat
|
||||||
7
contrib/tunnels.d/IRC-Irc2P.conf
Normal file
7
contrib/tunnels.d/IRC-Irc2P.conf
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#[IRC-IRC2P]
|
||||||
|
#type = client
|
||||||
|
#address = 127.0.0.1
|
||||||
|
#port = 6668
|
||||||
|
#destination = irc.postman.i2p
|
||||||
|
#destinationport = 6667
|
||||||
|
#keys = irc-keys.dat
|
||||||
4
contrib/tunnels.d/README
Normal file
4
contrib/tunnels.d/README
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# In that directory you can store separated config files for every tunnel.
|
||||||
|
# Please read documentation for more info.
|
||||||
|
#
|
||||||
|
# You can find examples in /usr/share/doc/i2pd/tunnels.d directory
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "UPnP.h"
|
#include "UPnP.h"
|
||||||
|
#include "Timestamp.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
@@ -41,6 +42,7 @@ namespace i2p
|
|||||||
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
||||||
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
||||||
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
||||||
|
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
|
||||||
#ifdef WITH_EVENTS
|
#ifdef WITH_EVENTS
|
||||||
std::unique_ptr<i2p::event::WebsocketServer> m_WebsocketServer;
|
std::unique_ptr<i2p::event::WebsocketServer> m_WebsocketServer;
|
||||||
#endif
|
#endif
|
||||||
@@ -152,6 +154,29 @@ namespace i2p
|
|||||||
i2p::context.SetSupportsV6 (ipv6);
|
i2p::context.SetSupportsV6 (ipv6);
|
||||||
i2p::context.SetSupportsV4 (ipv4);
|
i2p::context.SetSupportsV4 (ipv4);
|
||||||
|
|
||||||
|
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
||||||
|
i2p::context.PublishNTCPAddress (ntcp, !ipv6);
|
||||||
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
|
if (ntcp2)
|
||||||
|
{
|
||||||
|
bool published; i2p::config::GetOption("ntcp2.published", published);
|
||||||
|
if (published)
|
||||||
|
{
|
||||||
|
uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
|
||||||
|
if (!ntcp && !ntcp2port) ntcp2port = port; // use standard port
|
||||||
|
i2p::context.PublishNTCP2Address (ntcp2port, true); // publish
|
||||||
|
if (ipv6)
|
||||||
|
{
|
||||||
|
std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr);
|
||||||
|
auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr);
|
||||||
|
if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ())
|
||||||
|
i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i2p::context.PublishNTCP2Address (port, false); // unpublish
|
||||||
|
}
|
||||||
|
|
||||||
bool transit; i2p::config::GetOption("notransit", transit);
|
bool transit; i2p::config::GetOption("notransit", transit);
|
||||||
i2p::context.SetAcceptsTunnels (!transit);
|
i2p::context.SetAcceptsTunnels (!transit);
|
||||||
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
||||||
@@ -241,7 +266,7 @@ namespace i2p
|
|||||||
pos = comma + 1;
|
pos = comma + 1;
|
||||||
}
|
}
|
||||||
while (comma != std::string::npos);
|
while (comma != std::string::npos);
|
||||||
LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routesrs");
|
LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routers");
|
||||||
i2p::transport::transports.RestrictRoutesToRouters(idents);
|
i2p::transport::transports.RestrictRoutesToRouters(idents);
|
||||||
restricted = idents.size() > 0;
|
restricted = idents.size() > 0;
|
||||||
}
|
}
|
||||||
@@ -269,6 +294,13 @@ namespace i2p
|
|||||||
d.UPnP->Start ();
|
d.UPnP->Start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nettime; i2p::config::GetOption("nettime.enabled", nettime);
|
||||||
|
if (nettime)
|
||||||
|
{
|
||||||
|
d.m_NTPSync = std::unique_ptr<i2p::util::NTPTimeSync>(new i2p::util::NTPTimeSync);
|
||||||
|
d.m_NTPSync->Start ();
|
||||||
|
}
|
||||||
|
|
||||||
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
||||||
bool ssu; i2p::config::GetOption("ssu", ssu);
|
bool ssu; i2p::config::GetOption("ssu", ssu);
|
||||||
LogPrint(eLogInfo, "Daemon: starting Transports");
|
LogPrint(eLogInfo, "Daemon: starting Transports");
|
||||||
@@ -276,9 +308,10 @@ namespace i2p
|
|||||||
if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled");
|
if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled");
|
||||||
|
|
||||||
i2p::transport::transports.Start(ntcp, ssu);
|
i2p::transport::transports.Start(ntcp, ssu);
|
||||||
if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU()) {
|
if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
|
||||||
LogPrint(eLogInfo, "Daemon: Transports started");
|
LogPrint(eLogInfo, "Daemon: Transports started");
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
LogPrint(eLogError, "Daemon: failed to start Transports");
|
LogPrint(eLogError, "Daemon: failed to start Transports");
|
||||||
/** shut down netdb right away */
|
/** shut down netdb right away */
|
||||||
i2p::transport::transports.Stop();
|
i2p::transport::transports.Stop();
|
||||||
@@ -337,11 +370,18 @@ namespace i2p
|
|||||||
LogPrint(eLogInfo, "Daemon: stopping Tunnels");
|
LogPrint(eLogInfo, "Daemon: stopping Tunnels");
|
||||||
i2p::tunnel::tunnels.Stop();
|
i2p::tunnel::tunnels.Stop();
|
||||||
|
|
||||||
if (d.UPnP) {
|
if (d.UPnP)
|
||||||
|
{
|
||||||
d.UPnP->Stop ();
|
d.UPnP->Stop ();
|
||||||
d.UPnP = nullptr;
|
d.UPnP = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d.m_NTPSync)
|
||||||
|
{
|
||||||
|
d.m_NTPSync->Stop ();
|
||||||
|
d.m_NTPSync = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
LogPrint(eLogInfo, "Daemon: stopping Transports");
|
LogPrint(eLogInfo, "Daemon: stopping Transports");
|
||||||
i2p::transport::transports.Stop();
|
i2p::transport::transports.Stop();
|
||||||
LogPrint(eLogInfo, "Daemon: stopping NetDB");
|
LogPrint(eLogInfo, "Daemon: stopping NetDB");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
@@ -91,6 +92,8 @@ namespace http {
|
|||||||
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
|
||||||
const char HTTP_PARAM_ADDRESS[] = "address";
|
const char HTTP_PARAM_ADDRESS[] = "address";
|
||||||
|
|
||||||
|
static std::string ConvertTime (uint64_t time);
|
||||||
|
|
||||||
static void ShowUptime (std::stringstream& s, int seconds)
|
static void ShowUptime (std::stringstream& s, int seconds)
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
@@ -152,6 +155,8 @@ namespace http {
|
|||||||
|
|
||||||
static void ShowPageHead (std::stringstream& s)
|
static void ShowPageHead (std::stringstream& s)
|
||||||
{
|
{
|
||||||
|
std::string webroot;
|
||||||
|
i2p::config::GetOption("http.webroot", webroot);
|
||||||
s <<
|
s <<
|
||||||
"<!DOCTYPE html>\r\n"
|
"<!DOCTYPE html>\r\n"
|
||||||
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
|
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
|
||||||
@@ -170,16 +175,16 @@ namespace http {
|
|||||||
"<div class=header><b>i2pd</b> webconsole</div>\r\n"
|
"<div class=header><b>i2pd</b> webconsole</div>\r\n"
|
||||||
"<div class=wrapper>\r\n"
|
"<div class=wrapper>\r\n"
|
||||||
"<div class=left>\r\n"
|
"<div class=left>\r\n"
|
||||||
" <a href=\"/\">Main page</a><br>\r\n<br>\r\n"
|
" <a href=\"" << webroot << "\">Main page</a><br>\r\n<br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_LEASESETS << "\">LeaseSets</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">LeaseSets</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a><br>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a><br>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a><br>\r\n";
|
||||||
if (i2p::client::context.GetSAMBridge ())
|
if (i2p::client::context.GetSAMBridge ())
|
||||||
s << " <a href=\"/?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a><br>\r\n";
|
||||||
s <<
|
s <<
|
||||||
"</div>\r\n"
|
"</div>\r\n"
|
||||||
"<div class=right>";
|
"<div class=right>";
|
||||||
@@ -259,17 +264,26 @@ namespace http {
|
|||||||
s << "<b>Our external address:</b>" << "<br>\r\n" ;
|
s << "<b>Our external address:</b>" << "<br>\r\n" ;
|
||||||
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses())
|
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses())
|
||||||
{
|
{
|
||||||
|
if (address->IsNTCP2 () && !address->IsPublishedNTCP2 ())
|
||||||
|
{
|
||||||
|
s << "NTCP2";
|
||||||
|
if (address->host.is_v6 ()) s << "v6";
|
||||||
|
s << " supported <br>\r\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch (address->transportStyle)
|
switch (address->transportStyle)
|
||||||
{
|
{
|
||||||
case i2p::data::RouterInfo::eTransportNTCP:
|
case i2p::data::RouterInfo::eTransportNTCP:
|
||||||
if (address->host.is_v6 ())
|
{
|
||||||
s << "NTCP6 ";
|
s << "NTCP";
|
||||||
else
|
if (address->IsPublishedNTCP2 ()) s << "2";
|
||||||
s << "NTCP ";
|
if (address->host.is_v6 ()) s << "v6";
|
||||||
break;
|
s << " ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
case i2p::data::RouterInfo::eTransportSSU:
|
case i2p::data::RouterInfo::eTransportSSU:
|
||||||
if (address->host.is_v6 ())
|
if (address->host.is_v6 ())
|
||||||
s << "SSU6 ";
|
s << "SSUv6 ";
|
||||||
else
|
else
|
||||||
s << "SSU ";
|
s << "SSU ";
|
||||||
break;
|
break;
|
||||||
@@ -309,11 +323,12 @@ namespace http {
|
|||||||
|
|
||||||
void ShowLocalDestinations (std::stringstream& s)
|
void ShowLocalDestinations (std::stringstream& s)
|
||||||
{
|
{
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n";
|
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n";
|
||||||
for (auto& it: i2p::client::context.GetDestinations ())
|
for (auto& it: i2p::client::context.GetDestinations ())
|
||||||
{
|
{
|
||||||
auto ident = it.second->GetIdentHash ();
|
auto ident = it.second->GetIdentHash ();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +343,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
auto ident = dest->GetIdentHash ();
|
auto ident = dest->GetIdentHash ();
|
||||||
auto& name = dest->GetNickname ();
|
auto& name = dest->GetNickname ();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">[ ";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_I2CP_LOCAL_DESTINATION << "&i2cp_id=" << it.first << "\">[ ";
|
||||||
s << name << " ]</a> ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"<br>\r\n" << std::endl;
|
s << name << " ]</a> ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"<br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,7 +358,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets () << "</i></label>\r\n<input type='checkbox' id='slide-lease'/>\r\n<p class='content'>\r\n";
|
s << "<div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets () << "</i></label>\r\n<input type='checkbox' id='slide-lease'/>\r\n<p class='content'>\r\n";
|
||||||
for(auto& it: dest->GetLeaseSets ())
|
for(auto& it: dest->GetLeaseSets ())
|
||||||
s << it.second->GetIdentHash ().ToBase32 () << "<br>\r\n";
|
s << it.first.ToBase32 () << " " << (int)it.second->GetStoreType () << "<br>\r\n";
|
||||||
s << "</p>\r\n</div>\r\n";
|
s << "</p>\r\n</div>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "<b>LeaseSets:</b> <i>0</i><br>\r\n";
|
s << "<b>LeaseSets:</b> <i>0</i><br>\r\n";
|
||||||
@@ -369,10 +384,12 @@ namespace http {
|
|||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Tags</b><br>Incoming: <i>" << dest->GetNumIncomingTags () << "</i><br>";
|
s << "<b>Tags</b><br>Incoming: <i>" << dest->GetNumIncomingTags () << "</i><br>";
|
||||||
if (!dest->GetSessions ().empty ()) {
|
if (!dest->GetSessions ().empty ()) {
|
||||||
s << "<div class='slide'><label for='slide-tags'>Outgoing:</label>\r\n<input type='checkbox' id='slide-tags'/>\r\n<p class='content'>\r\n";
|
std::stringstream tmp_s; uint32_t out_tags = 0;
|
||||||
for (const auto& it: dest->GetSessions ())
|
for (const auto& it: dest->GetSessions ()) {
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " " << it.second->GetNumOutgoingTags () << "<br>\r\n";
|
tmp_s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " " << it.second->GetNumOutgoingTags () << "<br>\r\n";
|
||||||
s << "</p>\r\n</div>\r\n";
|
out_tags = out_tags + it.second->GetNumOutgoingTags ();
|
||||||
|
}
|
||||||
|
s << "<div class='slide'><label for='slide-tags'>Outgoing: <i>" << out_tags << "</i></label>\r\n<input type='checkbox' id='slide-tags'/>\r\n<p class='content'>\r\n" << tmp_s.str () << "</p>\r\n</div>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "Outgoing: <i>0</i><br>\r\n";
|
s << "Outgoing: <i>0</i><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
@@ -445,24 +462,35 @@ namespace http {
|
|||||||
[&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr<i2p::data::LeaseSet> leaseSet)
|
[&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr<i2p::data::LeaseSet> leaseSet)
|
||||||
{
|
{
|
||||||
// create copy of lease set so we extract leases
|
// create copy of lease set so we extract leases
|
||||||
i2p::data::LeaseSet ls(leaseSet->GetBuffer(), leaseSet->GetBufferLen());
|
auto storeType = leaseSet->GetStoreType ();
|
||||||
|
std::unique_ptr<i2p::data::LeaseSet> ls;
|
||||||
|
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET)
|
||||||
|
ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
|
||||||
|
else
|
||||||
|
ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen()));
|
||||||
|
if (!ls) return;
|
||||||
s << "<div class='leaseset";
|
s << "<div class='leaseset";
|
||||||
if (ls.IsExpired())
|
if (ls->IsExpired())
|
||||||
s << " expired"; // additional css class for expired
|
s << " expired"; // additional css class for expired
|
||||||
s << "'>\r\n";
|
s << "'>\r\n";
|
||||||
if (!ls.IsValid())
|
if (!ls->IsValid())
|
||||||
s << "<div class='invalid'>!! Invalid !! </div>\r\n";
|
s << "<div class='invalid'>!! Invalid !! </div>\r\n";
|
||||||
s << "<div class='slide'><label for='slide" << counter << "'>" << dest.ToBase32() << "</label>\r\n";
|
s << "<div class='slide'><label for='slide" << counter << "'>" << dest.ToBase32() << "</label>\r\n";
|
||||||
s << "<input type='checkbox' id='slide" << (counter++) << "'/>\r\n<p class='content'>\r\n";
|
s << "<input type='checkbox' id='slide" << (counter++) << "'/>\r\n<p class='content'>\r\n";
|
||||||
s << "<b>Expires:</b> " << ls.GetExpirationTime() << "<br>\r\n";
|
s << "<b>Store type:</b> " << (int)storeType << "<br>\r\n";
|
||||||
auto leases = ls.GetNonExpiredLeases();
|
s << "<b>Expires:</b> " << ConvertTime(ls->GetExpirationTime()) << "<br>\r\n";
|
||||||
s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n";
|
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2)
|
||||||
for ( auto & l : leases )
|
{
|
||||||
{
|
// leases information is available
|
||||||
s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n";
|
auto leases = ls->GetNonExpiredLeases();
|
||||||
s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n";
|
s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n";
|
||||||
s << "<b>EndDate:</b> " << l->endDate << "<br>\r\n";
|
for ( auto & l : leases )
|
||||||
}
|
{
|
||||||
|
s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n";
|
||||||
|
s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n";
|
||||||
|
s << "<b>EndDate:</b> " << ConvertTime(l->endDate) << "<br>\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
s << "</p>\r\n</div>\r\n</div>\r\n";
|
s << "</p>\r\n</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -496,33 +524,34 @@ namespace http {
|
|||||||
|
|
||||||
static void ShowCommands (std::stringstream& s, uint32_t token)
|
static void ShowCommands (std::stringstream& s, uint32_t token)
|
||||||
{
|
{
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
/* commands */
|
/* commands */
|
||||||
s << "<b>Router Commands</b><br>\r\n<br>\r\n";
|
s << "<b>Router Commands</b><br>\r\n<br>\r\n";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">Run peer test</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">Run peer test</a><br>\r\n";
|
||||||
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
||||||
if (i2p::context.AcceptsTunnels ())
|
if (i2p::context.AcceptsTunnels ())
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">Decline transit tunnels</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">Decline transit tunnels</a><br>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">Accept transit tunnels</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">Accept transit tunnels</a><br>\r\n";
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (Daemon.gracefulShutdownInterval)
|
if (Daemon.gracefulShutdownInterval)
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
||||||
else
|
else
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Start graceful shutdown</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Start graceful shutdown</a><br>\r\n";
|
||||||
#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
||||||
else
|
else
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a><br>\r\n";
|
||||||
#endif
|
#endif
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a><br>\r\n";
|
||||||
|
|
||||||
s << "<br>\r\n<b>Logging level</b><br>\r\n";
|
s << "<br>\r\n<b>Logging level</b><br>\r\n";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\">[none]</a> ";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\">[none]</a> ";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\">[error]</a> ";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\">[error]</a> ";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\">[warn]</a> ";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\">[warn]</a> ";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=info&token=" << token << "\">[info]</a> ";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=info&token=" << token << "\">[info]</a> ";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\">[debug]</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\">[debug]</a><br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowTransitTunnels (std::stringstream& s)
|
void ShowTransitTunnels (std::stringstream& s)
|
||||||
@@ -540,6 +569,46 @@ namespace http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Sessions>
|
||||||
|
static void ShowNTCPTransports (std::stringstream& s, const Sessions& sessions, const std::string name)
|
||||||
|
{
|
||||||
|
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
|
||||||
|
for (const auto& it: sessions )
|
||||||
|
{
|
||||||
|
if (it.second && it.second->IsEstablished () && !it.second->GetSocket ().remote_endpoint ().address ().is_v6 ())
|
||||||
|
{
|
||||||
|
// incoming connection doesn't have remote RI
|
||||||
|
if (it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
||||||
|
tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
||||||
|
<< it.second->GetSocket ().remote_endpoint().address ().to_string ();
|
||||||
|
if (!it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
||||||
|
tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
|
tmp_s << "<br>\r\n" << std::endl;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
if (it.second && it.second->IsEstablished () && it.second->GetSocket ().remote_endpoint ().address ().is_v6 ())
|
||||||
|
{
|
||||||
|
if (it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
||||||
|
tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
||||||
|
<< "[" << it.second->GetSocket ().remote_endpoint().address ().to_string () << "]";
|
||||||
|
if (!it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
||||||
|
tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
|
tmp_s6 << "<br>\r\n" << std::endl;
|
||||||
|
cnt6++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tmp_s.str ().empty ())
|
||||||
|
{
|
||||||
|
s << "<div class='slide'><label for='slide_" << boost::algorithm::to_lower_copy(name) << "'><b>" << name << "</b> ( " << cnt << " )</label>\r\n<input type='checkbox' id='slide_" << boost::algorithm::to_lower_copy(name) << "'/>\r\n<p class='content'>";
|
||||||
|
s << tmp_s.str () << "</p>\r\n</div>\r\n";
|
||||||
|
}
|
||||||
|
if (!tmp_s6.str ().empty ())
|
||||||
|
{
|
||||||
|
s << "<div class='slide'><label for='slide_" << boost::algorithm::to_lower_copy(name) << "v6'><b>" << name << "v6</b> ( " << cnt6 << " )</label>\r\n<input type='checkbox' id='slide_" << boost::algorithm::to_lower_copy(name) << "v6'/>\r\n<p class='content'>";
|
||||||
|
s << tmp_s6.str () << "</p>\r\n</div>\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShowTransports (std::stringstream& s)
|
void ShowTransports (std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<b>Transports:</b><br>\r\n<br>\r\n";
|
s << "<b>Transports:</b><br>\r\n<br>\r\n";
|
||||||
@@ -548,43 +617,14 @@ namespace http {
|
|||||||
{
|
{
|
||||||
auto sessions = ntcpServer->GetNTCPSessions ();
|
auto sessions = ntcpServer->GetNTCPSessions ();
|
||||||
if (!sessions.empty ())
|
if (!sessions.empty ())
|
||||||
{
|
ShowNTCPTransports (s, sessions, "NTCP");
|
||||||
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
|
}
|
||||||
for (const auto& it: sessions )
|
auto ntcp2Server = i2p::transport::transports.GetNTCP2Server ();
|
||||||
{
|
if (ntcp2Server)
|
||||||
if (it.second && it.second->IsEstablished () && !it.second->GetSocket ().remote_endpoint ().address ().is_v6 ())
|
{
|
||||||
{
|
auto sessions = ntcp2Server->GetNTCP2Sessions ();
|
||||||
// incoming connection doesn't have remote RI
|
if (!sessions.empty ())
|
||||||
if (it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
ShowNTCPTransports (s, sessions, "NTCP2");
|
||||||
tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
|
||||||
<< it.second->GetSocket ().remote_endpoint().address ().to_string ();
|
|
||||||
if (!it.second->IsOutgoing ()) tmp_s << " ⇒ ";
|
|
||||||
tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
|
||||||
tmp_s << "<br>\r\n" << std::endl;
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
if (it.second && it.second->IsEstablished () && it.second->GetSocket ().remote_endpoint ().address ().is_v6 ())
|
|
||||||
{
|
|
||||||
if (it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
|
||||||
tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
|
||||||
<< "[" << it.second->GetSocket ().remote_endpoint().address ().to_string () << "]";
|
|
||||||
if (!it.second->IsOutgoing ()) tmp_s6 << " ⇒ ";
|
|
||||||
tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
|
||||||
tmp_s6 << "<br>\r\n" << std::endl;
|
|
||||||
cnt6++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!tmp_s.str ().empty ())
|
|
||||||
{
|
|
||||||
s << "<div class='slide'><label for='slide_ntcp'><b>NTCP</b> ( " << cnt << " )</label>\r\n<input type='checkbox' id='slide_ntcp'/>\r\n<p class='content'>";
|
|
||||||
s << tmp_s.str () << "</p>\r\n</div>\r\n";
|
|
||||||
}
|
|
||||||
if (!tmp_s6.str ().empty ())
|
|
||||||
{
|
|
||||||
s << "<div class='slide'><label for='slide_ntcp6'><b>NTCP6</b> ( " << cnt6 << " )</label>\r\n<input type='checkbox' id='slide_ntcp6'/>\r\n<p class='content'>";
|
|
||||||
s << tmp_s6.str () << "</p>\r\n</div>\r\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
auto ssuServer = i2p::transport::transports.GetSSUServer ();
|
auto ssuServer = i2p::transport::transports.GetSSUServer ();
|
||||||
if (ssuServer)
|
if (ssuServer)
|
||||||
@@ -609,7 +649,7 @@ namespace http {
|
|||||||
auto sessions6 = ssuServer->GetSessionsV6 ();
|
auto sessions6 = ssuServer->GetSessionsV6 ();
|
||||||
if (!sessions6.empty ())
|
if (!sessions6.empty ())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide_ssu6'><b>SSU6</b> ( " << (int) sessions6.size() << " )</label>\r\n<input type='checkbox' id='slide_ssu6'/>\r\n<p class='content'>";
|
s << "<div class='slide'><label for='slide_ssuv6'><b>SSUv6</b> ( " << (int) sessions6.size() << " )</label>\r\n<input type='checkbox' id='slide_ssuv6'/>\r\n<p class='content'>";
|
||||||
for (const auto& it: sessions6)
|
for (const auto& it: sessions6)
|
||||||
{
|
{
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
@@ -628,6 +668,7 @@ namespace http {
|
|||||||
|
|
||||||
void ShowSAMSessions (std::stringstream& s)
|
void ShowSAMSessions (std::stringstream& s)
|
||||||
{
|
{
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
auto sam = i2p::client::context.GetSAMBridge ();
|
auto sam = i2p::client::context.GetSAMBridge ();
|
||||||
if (!sam) {
|
if (!sam) {
|
||||||
ShowError(s, "SAM disabled");
|
ShowError(s, "SAM disabled");
|
||||||
@@ -637,13 +678,14 @@ namespace http {
|
|||||||
for (auto& it: sam->GetSessions ())
|
for (auto& it: sam->GetSessions ())
|
||||||
{
|
{
|
||||||
auto& name = it.second->localDestination->GetNickname ();
|
auto& name = it.second->localDestination->GetNickname ();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << "\">";
|
||||||
s << name << " (" << it.first << ")</a><br>\r\n" << std::endl;
|
s << name << " (" << it.first << ")</a><br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowSAMSession (std::stringstream& s, const std::string& id)
|
static void ShowSAMSession (std::stringstream& s, const std::string& id)
|
||||||
{
|
{
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>SAM Session:</b><br>\r\n<br>\r\n";
|
s << "<b>SAM Session:</b><br>\r\n<br>\r\n";
|
||||||
auto sam = i2p::client::context.GetSAMBridge ();
|
auto sam = i2p::client::context.GetSAMBridge ();
|
||||||
if (!sam) {
|
if (!sam) {
|
||||||
@@ -656,7 +698,7 @@ namespace http {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& ident = session->localDestination->GetIdentHash();
|
auto& ident = session->localDestination->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Streams:</b><br>\r\n";
|
s << "<b>Streams:</b><br>\r\n";
|
||||||
@@ -676,11 +718,12 @@ namespace http {
|
|||||||
|
|
||||||
void ShowI2PTunnels (std::stringstream& s)
|
void ShowI2PTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>Client Tunnels:</b><br>\r\n<br>\r\n";
|
s << "<b>Client Tunnels:</b><br>\r\n<br>\r\n";
|
||||||
for (auto& it: i2p::client::context.GetClientTunnels ())
|
for (auto& it: i2p::client::context.GetClientTunnels ())
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "<br>\r\n"<< std::endl;
|
||||||
@@ -689,7 +732,7 @@ namespace http {
|
|||||||
if (httpProxy)
|
if (httpProxy)
|
||||||
{
|
{
|
||||||
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
|
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << "HTTP Proxy" << "</a> ⇐ ";
|
s << "HTTP Proxy" << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "<br>\r\n"<< std::endl;
|
||||||
@@ -698,7 +741,7 @@ namespace http {
|
|||||||
if (socksProxy)
|
if (socksProxy)
|
||||||
{
|
{
|
||||||
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
|
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << "SOCKS Proxy" << "</a> ⇐ ";
|
s << "SOCKS Proxy" << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "<br>\r\n"<< std::endl;
|
||||||
@@ -709,7 +752,7 @@ namespace http {
|
|||||||
for (auto& it: serverTunnels)
|
for (auto& it: serverTunnels)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇒ ";
|
s << it.second->GetName () << "</a> ⇒ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << ":" << it.second->GetLocalPort ();
|
s << ":" << it.second->GetLocalPort ();
|
||||||
@@ -723,7 +766,7 @@ namespace http {
|
|||||||
for (auto& it: clientForwards)
|
for (auto& it: clientForwards)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "<br>\r\n"<< std::endl;
|
||||||
@@ -736,7 +779,7 @@ namespace http {
|
|||||||
for (auto& it: serverForwards)
|
for (auto& it: serverForwards)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "<br>\r\n"<< std::endl;
|
||||||
@@ -744,9 +787,18 @@ namespace http {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ConvertTime (uint64_t time)
|
||||||
|
{
|
||||||
|
ldiv_t divTime = ldiv(time,1000);
|
||||||
|
time_t t = divTime.quot;
|
||||||
|
struct tm *tm = localtime(&t);
|
||||||
|
char date[128];
|
||||||
|
snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03ld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem);
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
|
HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
|
||||||
m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0),
|
m_Socket (socket), m_BufferLen (0), expected_host(hostname)
|
||||||
expected_host(hostname)
|
|
||||||
{
|
{
|
||||||
/* cache options */
|
/* cache options */
|
||||||
i2p::config::GetOption("http.auth", needAuth);
|
i2p::config::GetOption("http.auth", needAuth);
|
||||||
@@ -809,22 +861,8 @@ namespace http {
|
|||||||
auto provided = req.GetHeader ("Authorization");
|
auto provided = req.GetHeader ("Authorization");
|
||||||
if (provided.length () > 0)
|
if (provided.length () > 0)
|
||||||
{
|
{
|
||||||
bool result = false;
|
std::string expected = "Basic " + i2p::data::ToBase64Standard (user + ":" + pass);
|
||||||
|
if (expected == provided) return true;
|
||||||
std::string expected = user + ":" + pass;
|
|
||||||
size_t b64_sz = i2p::data::Base64EncodingBufferSize(expected.length()) + 1;
|
|
||||||
char * b64_creds = new char[b64_sz];
|
|
||||||
std::size_t len = 0;
|
|
||||||
len = i2p::data::ByteStreamToBase64((unsigned char *)expected.c_str(), expected.length(), b64_creds, b64_sz);
|
|
||||||
/* if we decoded properly then check credentials */
|
|
||||||
if(len) {
|
|
||||||
b64_creds[len] = '\0';
|
|
||||||
expected = "Basic ";
|
|
||||||
expected += b64_creds;
|
|
||||||
result = expected == provided;
|
|
||||||
}
|
|
||||||
delete [] b64_creds;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ());
|
LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ());
|
||||||
@@ -862,7 +900,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
/* deny request as it's from a non whitelisted hostname */
|
/* deny request as it's from a non whitelisted hostname */
|
||||||
res.code = 403;
|
res.code = 403;
|
||||||
content = "host missmatch";
|
content = "host mismatch";
|
||||||
SendReply(res, content);
|
SendReply(res, content);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -990,10 +1028,12 @@ namespace http {
|
|||||||
ShowError(s, "Unknown command: " + cmd);
|
ShowError(s, "Unknown command: " + cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
|
std::string redirect = "5; url=" + webroot + "?page=commands";
|
||||||
s << "<b>SUCCESS</b>: Command accepted<br><br>\r\n";
|
s << "<b>SUCCESS</b>: Command accepted<br><br>\r\n";
|
||||||
s << "<a href=\"/?page=commands\">Back to commands list</a><br>\r\n";
|
s << "<a href=\"" << webroot << "?page=commands\">Back to commands list</a><br>\r\n";
|
||||||
s << "<p>You will be redirected in 5 seconds</b>";
|
s << "<p>You will be redirected in 5 seconds</b>";
|
||||||
res.add_header("Refresh", "5; url=/?page=commands");
|
res.add_header("Refresh", redirect.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPConnection::SendReply (HTTPRes& reply, std::string& content)
|
void HTTPConnection::SendReply (HTTPRes& reply, std::string& content)
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ namespace http
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||||
boost::asio::deadline_timer m_Timer;
|
|
||||||
char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1];
|
char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1];
|
||||||
size_t m_BufferLen;
|
size_t m_BufferLen;
|
||||||
std::string m_SendBuffer;
|
std::string m_SendBuffer;
|
||||||
|
|||||||
@@ -569,8 +569,8 @@ namespace client
|
|||||||
EVP_PKEY_assign_RSA (pkey, rsa);
|
EVP_PKEY_assign_RSA (pkey, rsa);
|
||||||
X509 * x509 = X509_new ();
|
X509 * x509 = X509_new ();
|
||||||
ASN1_INTEGER_set (X509_get_serialNumber (x509), 1);
|
ASN1_INTEGER_set (X509_get_serialNumber (x509), 1);
|
||||||
X509_gmtime_adj (X509_get_notBefore (x509), 0);
|
X509_gmtime_adj (X509_getm_notBefore (x509), 0);
|
||||||
X509_gmtime_adj (X509_get_notAfter (x509), I2P_CONTROL_CERTIFICATE_VALIDITY*24*60*60); // expiration
|
X509_gmtime_adj (X509_getm_notAfter (x509), I2P_CONTROL_CERTIFICATE_VALIDITY*24*60*60); // expiration
|
||||||
X509_set_pubkey (x509, pkey); // public key
|
X509_set_pubkey (x509, pkey); // public key
|
||||||
X509_NAME * name = X509_get_subject_name (x509);
|
X509_NAME * name = X509_get_subject_name (x509);
|
||||||
X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *)"A1", -1, -1, 0); // country (Anonymous proxy)
|
X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *)"A1", -1, -1, 0); // country (Anonymous proxy)
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ namespace transport
|
|||||||
const auto& a = context.GetRouterInfo().GetAddresses();
|
const auto& a = context.GetRouterInfo().GetAddresses();
|
||||||
for (const auto& address : a)
|
for (const auto& address : a)
|
||||||
{
|
{
|
||||||
if (!address->host.is_v6 ())
|
if (!address->host.is_v6 () && address->port)
|
||||||
TryPortMapping (address);
|
TryPortMapping (address);
|
||||||
}
|
}
|
||||||
m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
|
m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
|
||||||
m_Timer.async_wait ([this](const boost::system::error_code& ecode)
|
m_Timer.async_wait ([this](const boost::system::error_code& ecode)
|
||||||
@@ -148,7 +148,7 @@ namespace transport
|
|||||||
const auto& a = context.GetRouterInfo().GetAddresses();
|
const auto& a = context.GetRouterInfo().GetAddresses();
|
||||||
for (const auto& address : a)
|
for (const auto& address : a)
|
||||||
{
|
{
|
||||||
if (!address->host.is_v6 ())
|
if (!address->host.is_v6 () && address->port)
|
||||||
CloseMapping (address);
|
CloseMapping (address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
debian/.gitignore
vendored
4
debian/.gitignore
vendored
@@ -1,9 +1,9 @@
|
|||||||
|
debhelper-build-stamp
|
||||||
files
|
files
|
||||||
i2pd-dbg.substvars
|
i2pd-dbg.substvars
|
||||||
i2pd-dbg/
|
|
||||||
i2pd.postinst.debhelper
|
i2pd.postinst.debhelper
|
||||||
i2pd.postrm.debhelper
|
i2pd.postrm.debhelper
|
||||||
i2pd.prerm.debhelper
|
i2pd.prerm.debhelper
|
||||||
i2pd.substvars
|
i2pd.substvars
|
||||||
i2pd/
|
i2pd/
|
||||||
|
i2pd-dbg/
|
||||||
|
|||||||
46
debian/changelog
vendored
46
debian/changelog
vendored
@@ -1,3 +1,49 @@
|
|||||||
|
i2pd (2.25.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.25.0/0.9.40
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Thu, 9 May 2019 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.24.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.24.0/0.9.39
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Thu, 21 Mar 2019 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.23.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.23.0/0.9.38
|
||||||
|
* update docs, dirs, install, links files
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Mon, 21 Jan 2019 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.22.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.22.0/0.9.37
|
||||||
|
* update manpage (1)
|
||||||
|
* update links, install files to support tunnelsdir option
|
||||||
|
* renamed and updated patch (#1210)
|
||||||
|
|
||||||
|
-- r4sas <r4sas@i2pmail.org> Fri, 09 Nov 2018 02:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.21.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.21.1
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Thu, 22 Oct 2018 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.21.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.21.0/0.9.37
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Thu, 4 Oct 2018 16:00:00 +0000
|
||||||
|
|
||||||
|
i2pd (2.20.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* updated to version 2.20.0/0.9.36
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Thu, 23 Aug 2018 16:00:00 +0000
|
||||||
|
|
||||||
i2pd (2.19.0-1) unstable; urgency=medium
|
i2pd (2.19.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* updated to version 2.19.0/0.9.35
|
* updated to version 2.19.0/0.9.35
|
||||||
|
|||||||
2
debian/control
vendored
2
debian/control
vendored
@@ -1,7 +1,7 @@
|
|||||||
Source: i2pd
|
Source: i2pd
|
||||||
Section: net
|
Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: R4SAS <r4sas@i2pmail.org>
|
Maintainer: r4sas <r4sas@i2pmail.org>
|
||||||
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
|
Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev
|
||||||
Standards-Version: 3.9.6
|
Standards-Version: 3.9.6
|
||||||
Homepage: http://i2pd.website/
|
Homepage: http://i2pd.website/
|
||||||
|
|||||||
1
debian/docs
vendored
1
debian/docs
vendored
@@ -2,3 +2,4 @@ README.md
|
|||||||
contrib/i2pd.conf
|
contrib/i2pd.conf
|
||||||
contrib/subscriptions.txt
|
contrib/subscriptions.txt
|
||||||
contrib/tunnels.conf
|
contrib/tunnels.conf
|
||||||
|
contrib/tunnels.d
|
||||||
|
|||||||
5
debian/i2pd.1
vendored
5
debian/i2pd.1
vendored
@@ -45,6 +45,9 @@ Log messages with full CLF-formatted date and time (\fIdisabled\fR by default)
|
|||||||
\fB\-\-datadir=\fR
|
\fB\-\-datadir=\fR
|
||||||
Path to storage of i2pd data (RI, keys, peer profiles, ...)
|
Path to storage of i2pd data (RI, keys, peer profiles, ...)
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-\-tunnelsdir=\fR
|
||||||
|
Path to tunnels configuration files (default: \fI~/.i2pd/tunnels.d\fR or \fI/var/lib/i2pd/tunnels.d\fR)
|
||||||
|
.TP
|
||||||
\fB\-\-host=\fR
|
\fB\-\-host=\fR
|
||||||
The external IP address
|
The external IP address
|
||||||
.TP
|
.TP
|
||||||
@@ -96,7 +99,7 @@ Router will use system folders like \fI/var/lib/i2pd\fR (\fIdisabled\fR by defau
|
|||||||
\fB\-\-family=\fR
|
\fB\-\-family=\fR
|
||||||
Name of a family, router belongs to.
|
Name of a family, router belongs to.
|
||||||
.PP
|
.PP
|
||||||
Switchs, which enabled by default (like \fB\-\-ssu\fR, \fB\-\-ntcp\fR, etc.), can be disabled in config file.
|
Switches, which enabled by default (like \fB\-\-ssu\fR, \fB\-\-ntcp\fR, etc.), can be disabled in config file.
|
||||||
.RE
|
.RE
|
||||||
See service-specific parameters in example config file \fI/usr/share/doc/i2pd/i2pd.conf.gz\fR
|
See service-specific parameters in example config file \fI/usr/share/doc/i2pd/i2pd.conf.gz\fR
|
||||||
.SH "FILES"
|
.SH "FILES"
|
||||||
|
|||||||
3
debian/i2pd.init
vendored
3
debian/i2pd.init
vendored
@@ -18,6 +18,7 @@ DAEMON_OPTS="" # Arguments to run the daemon with
|
|||||||
PIDFILE=/var/run/$NAME/$NAME.pid
|
PIDFILE=/var/run/$NAME/$NAME.pid
|
||||||
I2PCONF=/etc/$NAME/i2pd.conf
|
I2PCONF=/etc/$NAME/i2pd.conf
|
||||||
TUNCONF=/etc/$NAME/tunnels.conf
|
TUNCONF=/etc/$NAME/tunnels.conf
|
||||||
|
TUNDIR=/etc/$NAME/tunnels.conf.d
|
||||||
LOGFILE=/var/log/$NAME/$NAME.log
|
LOGFILE=/var/log/$NAME/$NAME.log
|
||||||
USER="i2pd"
|
USER="i2pd"
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ do_start()
|
|||||||
|| return 1
|
|| return 1
|
||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" -- \
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" -- \
|
||||||
--service --daemon --log=file --logfile=$LOGFILE --conf=$I2PCONF --tunconf=$TUNCONF \
|
--service --daemon --log=file --logfile=$LOGFILE --conf=$I2PCONF --tunconf=$TUNCONF \
|
||||||
--pidfile=$PIDFILE $DAEMON_OPTS > /dev/null 2>&1 \
|
--tunnelsdir=$TUNDIR --pidfile=$PIDFILE $DAEMON_OPTS > /dev/null 2>&1 \
|
||||||
|| return 2
|
|| return 2
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|||||||
1
debian/i2pd.install
vendored
1
debian/i2pd.install
vendored
@@ -3,4 +3,5 @@ contrib/i2pd.conf etc/i2pd/
|
|||||||
contrib/tunnels.conf etc/i2pd/
|
contrib/tunnels.conf etc/i2pd/
|
||||||
contrib/subscriptions.txt etc/i2pd/
|
contrib/subscriptions.txt etc/i2pd/
|
||||||
contrib/certificates/ usr/share/i2pd/
|
contrib/certificates/ usr/share/i2pd/
|
||||||
|
contrib/tunnels.d/README etc/i2pd/tunnels.conf.d/
|
||||||
contrib/apparmor/usr.sbin.i2pd etc/apparmor.d
|
contrib/apparmor/usr.sbin.i2pd etc/apparmor.d
|
||||||
|
|||||||
1
debian/i2pd.links
vendored
1
debian/i2pd.links
vendored
@@ -1,4 +1,5 @@
|
|||||||
etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf
|
etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf
|
||||||
etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.conf
|
etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.conf
|
||||||
etc/i2pd/subscriptions.txt var/lib/i2pd/subscriptions.txt
|
etc/i2pd/subscriptions.txt var/lib/i2pd/subscriptions.txt
|
||||||
|
etc/i2pd/tunnels.conf.d var/lib/i2pd/tunnels.d
|
||||||
usr/share/i2pd/certificates var/lib/i2pd/certificates
|
usr/share/i2pd/certificates var/lib/i2pd/certificates
|
||||||
|
|||||||
3
debian/i2pd.openrc
vendored
3
debian/i2pd.openrc
vendored
@@ -4,10 +4,11 @@ pidfile="/var/run/i2pd/i2pd.pid"
|
|||||||
logfile="/var/log/i2pd/i2pd.log"
|
logfile="/var/log/i2pd/i2pd.log"
|
||||||
mainconf="/etc/i2pd/i2pd.conf"
|
mainconf="/etc/i2pd/i2pd.conf"
|
||||||
tunconf="/etc/i2pd/tunnels.conf"
|
tunconf="/etc/i2pd/tunnels.conf"
|
||||||
|
tundir="/etc/i2pd/tunnels.conf.d"
|
||||||
|
|
||||||
name="i2pd"
|
name="i2pd"
|
||||||
command="/usr/sbin/i2pd"
|
command="/usr/sbin/i2pd"
|
||||||
command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf --pidfile=$pidfile"
|
command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf --tunnelsdir=$tundir --pidfile=$pidfile"
|
||||||
description="i2p router written in C++"
|
description="i2p router written in C++"
|
||||||
required_dirs="/var/lib/i2pd"
|
required_dirs="/var/lib/i2pd"
|
||||||
required_files="$mainconf"
|
required_files="$mainconf"
|
||||||
|
|||||||
4
debian/patches/01-tune-build-opts.patch
vendored
4
debian/patches/01-tune-build-opts.patch
vendored
@@ -13,5 +13,5 @@ index bdadfe0..2f71eec 100644
|
|||||||
USE_STATIC := no
|
USE_STATIC := no
|
||||||
USE_MESHNET := no
|
USE_MESHNET := no
|
||||||
USE_UPNP := no
|
USE_UPNP := no
|
||||||
|
DEBUG := yes
|
||||||
ifeq ($(WEBSOCKETS),1)
|
|
||||||
|
|||||||
25
debian/patches/02-fix-1210.patch
vendored
Normal file
25
debian/patches/02-fix-1210.patch
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
Description: fix #1210
|
||||||
|
Disables two options, which not presented in old systemd versions
|
||||||
|
Author: r4sas <r4sas@i2pmail.org>
|
||||||
|
|
||||||
|
Bug: https://github.com/PurpleI2P/i2pd/issues/1210
|
||||||
|
Reviewed-By: r4sas <r4sas@i2pmail.org>
|
||||||
|
Last-Update: 2018-08-25
|
||||||
|
|
||||||
|
--- a/contrib/i2pd.service
|
||||||
|
+++ b/contrib/i2pd.service
|
||||||
|
@@ -6,10 +6,10 @@ After=network.target
|
||||||
|
[Service]
|
||||||
|
User=i2pd
|
||||||
|
Group=i2pd
|
||||||
|
-RuntimeDirectory=i2pd
|
||||||
|
-RuntimeDirectoryMode=0700
|
||||||
|
-LogsDirectory=i2pd
|
||||||
|
-LogsDirectoryMode=0700
|
||||||
|
+#RuntimeDirectory=i2pd
|
||||||
|
+#RuntimeDirectoryMode=0700
|
||||||
|
+#LogsDirectory=i2pd
|
||||||
|
+#LogsDirectoryMode=0700
|
||||||
|
Type=forking
|
||||||
|
ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service
|
||||||
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
1
debian/patches/series
vendored
1
debian/patches/series
vendored
@@ -1 +1,2 @@
|
|||||||
01-tune-build-opts.patch
|
01-tune-build-opts.patch
|
||||||
|
02-fix-1210.patch
|
||||||
|
|||||||
2
debian/rules
vendored
2
debian/rules
vendored
@@ -17,6 +17,6 @@ DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow
|
|||||||
override_dh_strip:
|
override_dh_strip:
|
||||||
dh_strip --dbg-package=i2pd-dbg
|
dh_strip --dbg-package=i2pd-dbg
|
||||||
|
|
||||||
## uncoment this if you have "missing info" problem when building package
|
## uncomment this if you have "missing info" problem when building package
|
||||||
#override_dh_shlibdeps:
|
#override_dh_shlibdeps:
|
||||||
# dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
|
# dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
|
||||||
|
|||||||
@@ -1094,7 +1094,7 @@ HTML_STYLESHEET =
|
|||||||
# cascading style sheets that are included after the standard style sheets
|
# cascading style sheets that are included after the standard style sheets
|
||||||
# created by doxygen. Using this option one can overrule certain style aspects.
|
# created by doxygen. Using this option one can overrule certain style aspects.
|
||||||
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
||||||
# standard style sheet and is therefor more robust against future updates.
|
# standard style sheet and is therefore more robust against future updates.
|
||||||
# Doxygen will copy the style sheet files to the output directory.
|
# Doxygen will copy the style sheet files to the output directory.
|
||||||
# Note: The order of the extra stylesheet files is of importance (e.g. the last
|
# Note: The order of the extra stylesheet files is of importance (e.g. the last
|
||||||
# stylesheet in the list overrules the setting of the previous ones in the
|
# stylesheet in the list overrules the setting of the previous ones in the
|
||||||
@@ -1637,7 +1637,7 @@ EXTRA_PACKAGES =
|
|||||||
# Note: Only use a user-defined header if you know what you are doing! The
|
# Note: Only use a user-defined header if you know what you are doing! The
|
||||||
# following commands have a special meaning inside the header: $title,
|
# following commands have a special meaning inside the header: $title,
|
||||||
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
|
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
|
||||||
# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
|
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty string,
|
||||||
# for the replacement values of the other commands the user is referred to
|
# for the replacement values of the other commands the user is referred to
|
||||||
# HTML_HEADER.
|
# HTML_HEADER.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|||||||
@@ -21,23 +21,35 @@ namespace cpu
|
|||||||
|
|
||||||
void Detect()
|
void Detect()
|
||||||
{
|
{
|
||||||
|
#if defined(__AES__) || defined(__AVX__)
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
int info[4];
|
int info[4];
|
||||||
__cpuid(0, info[0], info[1], info[2], info[3]);
|
__cpuid(0, info[0], info[1], info[2], info[3]);
|
||||||
if (info[0] >= 0x00000001) {
|
if (info[0] >= 0x00000001) {
|
||||||
__cpuid(0x00000001, info[0], info[1], info[2], info[3]);
|
__cpuid(0x00000001, info[0], info[1], info[2], info[3]);
|
||||||
|
#ifdef __AES__
|
||||||
aesni = info[2] & bit_AES; // AESNI
|
aesni = info[2] & bit_AES; // AESNI
|
||||||
|
#endif // __AES__
|
||||||
|
#ifdef __AVX__
|
||||||
avx = info[2] & bit_AVX; // AVX
|
avx = info[2] & bit_AVX; // AVX
|
||||||
|
#endif // __AVX__
|
||||||
}
|
}
|
||||||
#endif
|
#endif // defined(__x86_64__) || defined(__i386__)
|
||||||
|
|
||||||
|
#ifdef __AES__
|
||||||
if(aesni)
|
if(aesni)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "AESNI enabled");
|
LogPrint(eLogInfo, "AESNI enabled");
|
||||||
}
|
}
|
||||||
|
#endif // __AES__
|
||||||
|
#ifdef __AVX__
|
||||||
if(avx)
|
if(avx)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "AVX enabled");
|
LogPrint(eLogInfo, "AVX enabled");
|
||||||
}
|
}
|
||||||
|
#endif // __AVX__
|
||||||
|
#endif // defined(__AES__) || defined(__AVX__)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2018, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*
|
||||||
|
* Kovri go write your own code
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "I2PEndian.h"
|
||||||
#include "ChaCha20.h"
|
#include "ChaCha20.h"
|
||||||
|
|
||||||
/**
|
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
This code is licensed under the MCGSI Public License
|
|
||||||
Copyright 2018 Jeff Becker
|
|
||||||
|
|
||||||
Kovri go write your own code
|
|
||||||
|
|
||||||
*/
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
{
|
{
|
||||||
namespace chacha
|
namespace chacha
|
||||||
{
|
{
|
||||||
constexpr int rounds = 20;
|
|
||||||
constexpr std::size_t blocksize = 64;
|
|
||||||
|
|
||||||
void u32t8le(uint32_t v, uint8_t * p)
|
void u32t8le(uint32_t v, uint8_t * p)
|
||||||
{
|
{
|
||||||
p[0] = v & 0xff;
|
p[0] = v & 0xff;
|
||||||
@@ -48,44 +51,18 @@ void quarterround(uint32_t *x, int a, int b, int c, int d)
|
|||||||
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7);
|
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct State_t
|
|
||||||
{
|
|
||||||
State_t() {};
|
|
||||||
State_t(State_t &&) = delete;
|
|
||||||
|
|
||||||
State_t & operator += (const State_t & other)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 16; i++)
|
|
||||||
data[i] += other.data[i];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Copy(const State_t & other)
|
void Chacha20Block::operator << (const Chacha20State & st)
|
||||||
{
|
{
|
||||||
memcpy(data, other.data, sizeof(uint32_t) * 16);
|
int i;
|
||||||
}
|
for (i = 0; i < 16; i++)
|
||||||
uint32_t data[16];
|
u32t8le(st.data[i], data + (i << 2));
|
||||||
};
|
}
|
||||||
|
|
||||||
struct Block_t
|
void block (Chacha20State &input, int rounds)
|
||||||
{
|
|
||||||
Block_t() {};
|
|
||||||
Block_t(Block_t &&) = delete;
|
|
||||||
|
|
||||||
uint8_t data[blocksize];
|
|
||||||
|
|
||||||
void operator << (const State_t & st)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
u32t8le(st.data[i], data + (i << 2));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void block(const State_t &input, Block_t & block, int rounds)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
State_t x;
|
Chacha20State x;
|
||||||
x.Copy(input);
|
x.Copy(input);
|
||||||
|
|
||||||
for (i = rounds; i > 0; i -= 2)
|
for (i = rounds; i > 0; i -= 2)
|
||||||
@@ -100,48 +77,62 @@ void block(const State_t &input, Block_t & block, int rounds)
|
|||||||
quarterround(x.data, 3, 4, 9, 14);
|
quarterround(x.data, 3, 4, 9, 14);
|
||||||
}
|
}
|
||||||
x += input;
|
x += input;
|
||||||
block << x;
|
input.block << x;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter)
|
||||||
|
{
|
||||||
|
state.data[0] = 0x61707865;
|
||||||
|
state.data[1] = 0x3320646e;
|
||||||
|
state.data[2] = 0x79622d32;
|
||||||
|
state.data[3] = 0x6b206574;
|
||||||
|
for (size_t i = 0; i < 8; i++)
|
||||||
|
state.data[4 + i] = chacha::u8t32le(key + i * 4);
|
||||||
|
|
||||||
|
state.data[12] = htole32 (counter);
|
||||||
|
for (size_t i = 0; i < 3; i++)
|
||||||
|
state.data[13 + i] = chacha::u8t32le(nonce + i * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chacha20SetCounter (Chacha20State& state, uint32_t counter)
|
||||||
|
{
|
||||||
|
state.data[12] = htole32 (counter);
|
||||||
|
state.offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz)
|
||||||
|
{
|
||||||
|
if (state.offset > 0)
|
||||||
|
{
|
||||||
|
// previous block if any
|
||||||
|
auto s = chacha::blocksize - state.offset;
|
||||||
|
if (sz < s) s = sz;
|
||||||
|
for (size_t i = 0; i < s; i++)
|
||||||
|
buf[i] ^= state.block.data[state.offset + i];
|
||||||
|
buf += s;
|
||||||
|
sz -= s;
|
||||||
|
state.offset += s;
|
||||||
|
if (state.offset >= chacha::blocksize) state.offset = 0;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < sz; i += chacha::blocksize)
|
||||||
|
{
|
||||||
|
chacha::block(state, chacha::rounds);
|
||||||
|
state.data[12]++;
|
||||||
|
for (size_t j = i; j < i + chacha::blocksize; j++)
|
||||||
|
{
|
||||||
|
if (j >= sz)
|
||||||
|
{
|
||||||
|
state.offset = j & 0x3F; // % 64
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[j] ^= state.block.data[j - i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace chacha
|
} // namespace chacha
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void chacha20(uint8_t * buf, size_t sz, const uint8_t * nonce, const uint8_t * key, uint32_t counter)
|
|
||||||
{
|
|
||||||
chacha::State_t state;
|
|
||||||
chacha::Block_t block;
|
|
||||||
size_t i, j;
|
|
||||||
|
|
||||||
state.data[0] = 0x61707865;
|
|
||||||
state.data[1] = 0x3320646e;
|
|
||||||
state.data[2] = 0x79622d32;
|
|
||||||
state.data[3] = 0x6b206574;
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
state.data[4 + i] = chacha::u8t32le(key + i * 4);
|
|
||||||
|
|
||||||
|
|
||||||
state.data[12] = counter;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
state.data[13 + i] = chacha::u8t32le(nonce + i * 4);
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < sz; i += chacha::blocksize)
|
|
||||||
{
|
|
||||||
chacha::block(state, block, chacha::rounds);
|
|
||||||
state.data[12]++;
|
|
||||||
for (j = i; j < i + chacha::blocksize; j++)
|
|
||||||
{
|
|
||||||
if (j >= sz) break;
|
|
||||||
buf[j] ^= block.data[j - i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,72 @@
|
|||||||
/**
|
/*
|
||||||
This code is licensed under the MCGSI Public License
|
* Copyright (c) 2013-2018, The PurpleI2P Project
|
||||||
Copyright 2018 Jeff Becker
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
Kovri go write your own code
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*
|
||||||
|
* Kovri go write your own code
|
||||||
|
*
|
||||||
|
*/
|
||||||
#ifndef LIBI2PD_CHACHA20_H
|
#ifndef LIBI2PD_CHACHA20_H
|
||||||
#define LIBI2PD_CHACHA20_H
|
#define LIBI2PD_CHACHA20_H
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "Crypto.h"
|
||||||
|
|
||||||
|
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
{
|
{
|
||||||
const std::size_t CHACHA20_KEY_BYTES = 32;
|
const std::size_t CHACHA20_KEY_BYTES = 32;
|
||||||
const std::size_t CHACHA20_NOUNCE_BYTES = 12;
|
const std::size_t CHACHA20_NOUNCE_BYTES = 12;
|
||||||
|
|
||||||
|
namespace chacha
|
||||||
|
{
|
||||||
|
constexpr std::size_t blocksize = 64;
|
||||||
|
constexpr int rounds = 20;
|
||||||
|
|
||||||
/** encrypt buf in place with chacha20 */
|
struct Chacha20State;
|
||||||
void chacha20(uint8_t * buf, size_t sz, const uint8_t * nonce, const uint8_t * key, uint32_t counter=1);
|
struct Chacha20Block
|
||||||
|
{
|
||||||
|
Chacha20Block () {};
|
||||||
|
Chacha20Block (Chacha20Block &&) = delete;
|
||||||
|
|
||||||
|
uint8_t data[blocksize];
|
||||||
|
|
||||||
|
void operator << (const Chacha20State & st);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Chacha20State
|
||||||
|
{
|
||||||
|
Chacha20State (): offset (0) {};
|
||||||
|
Chacha20State (Chacha20State &&) = delete;
|
||||||
|
|
||||||
|
Chacha20State & operator += (const Chacha20State & other)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 16; i++)
|
||||||
|
data[i] += other.data[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Copy(const Chacha20State & other)
|
||||||
|
{
|
||||||
|
memcpy(data, other.data, sizeof(uint32_t) * 16);
|
||||||
|
}
|
||||||
|
uint32_t data[16];
|
||||||
|
Chacha20Block block;
|
||||||
|
size_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter);
|
||||||
|
void Chacha20SetCounter (Chacha20State& state, uint32_t counter);
|
||||||
|
void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,8 +32,10 @@ namespace config {
|
|||||||
options_description general("General options");
|
options_description general("General options");
|
||||||
general.add_options()
|
general.add_options()
|
||||||
("help", "Show this message")
|
("help", "Show this message")
|
||||||
|
("version", "Show i2pd version")
|
||||||
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
|
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
|
||||||
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
|
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
|
||||||
|
("tunnelsdir", value<std::string>()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d")
|
||||||
("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
|
("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
|
||||||
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
|
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
|
||||||
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
|
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
|
||||||
@@ -59,7 +61,6 @@ namespace config {
|
|||||||
("ntcp", value<bool>()->default_value(true), "Enable NTCP transport (default: enabled)")
|
("ntcp", value<bool>()->default_value(true), "Enable NTCP transport (default: enabled)")
|
||||||
("ssu", value<bool>()->default_value(true), "Enable SSU transport (default: enabled)")
|
("ssu", value<bool>()->default_value(true), "Enable SSU transport (default: enabled)")
|
||||||
("ntcpproxy", value<std::string>()->default_value(""), "Proxy URL for NTCP transport")
|
("ntcpproxy", value<std::string>()->default_value(""), "Proxy URL for NTCP transport")
|
||||||
("ntcp2", value<bool>()->default_value(false), "Enable NTCP2 (experimental, default: disabled)")
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
|
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
|
||||||
("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)")
|
("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)")
|
||||||
@@ -72,7 +73,7 @@ namespace config {
|
|||||||
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
|
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
|
||||||
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
|
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
|
||||||
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
||||||
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Threshold to start probabalistic backoff with ntcp sessions (default: use system limit)")
|
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Threshold to start probabilistic backoff with ntcp sessions (default: use system limit)")
|
||||||
("limits.ntcphard", value<uint16_t>()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)")
|
("limits.ntcphard", value<uint16_t>()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)")
|
||||||
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Maximum number of threads used by NTCP DH worker (default: 1)")
|
("limits.ntcpthreads", value<uint16_t>()->default_value(1), "Maximum number of threads used by NTCP DH worker (default: 1)")
|
||||||
;
|
;
|
||||||
@@ -87,6 +88,7 @@ namespace config {
|
|||||||
("http.pass", value<std::string>()->default_value(""), "Password for basic auth (default: random, see logs)")
|
("http.pass", value<std::string>()->default_value(""), "Password for basic auth (default: random, see logs)")
|
||||||
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
|
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
|
||||||
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
|
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
|
||||||
|
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description httpproxy("HTTP Proxy options");
|
options_description httpproxy("HTTP Proxy options");
|
||||||
@@ -151,8 +153,8 @@ namespace config {
|
|||||||
("i2pcontrol.address", value<std::string>()->default_value("127.0.0.1"), "I2PCP listen address")
|
("i2pcontrol.address", value<std::string>()->default_value("127.0.0.1"), "I2PCP listen address")
|
||||||
("i2pcontrol.port", value<uint16_t>()->default_value(7650), "I2PCP listen port")
|
("i2pcontrol.port", value<uint16_t>()->default_value(7650), "I2PCP listen port")
|
||||||
("i2pcontrol.password", value<std::string>()->default_value("itoopie"), "I2PCP access password")
|
("i2pcontrol.password", value<std::string>()->default_value("itoopie"), "I2PCP access password")
|
||||||
("i2pcontrol.cert", value<std::string>()->default_value("i2pcontrol.crt.pem"), "I2PCP connection cerificate")
|
("i2pcontrol.cert", value<std::string>()->default_value("i2pcontrol.crt.pem"), "I2PCP connection certificate")
|
||||||
("i2pcontrol.key", value<std::string>()->default_value("i2pcontrol.key.pem"), "I2PCP connection cerificate key")
|
("i2pcontrol.key", value<std::string>()->default_value("i2pcontrol.key.pem"), "I2PCP connection certificate key")
|
||||||
;
|
;
|
||||||
|
|
||||||
bool upnp_default = false;
|
bool upnp_default = false;
|
||||||
@@ -162,7 +164,7 @@ namespace config {
|
|||||||
options_description upnp("UPnP options");
|
options_description upnp("UPnP options");
|
||||||
upnp.add_options()
|
upnp.add_options()
|
||||||
("upnp.enabled", value<bool>()->default_value(upnp_default), "Enable or disable UPnP: automatic port forwarding")
|
("upnp.enabled", value<bool>()->default_value(upnp_default), "Enable or disable UPnP: automatic port forwarding")
|
||||||
("upnp.name", value<std::string>()->default_value("I2Pd"), "Name i2pd appears in UPnP forwardings list")
|
("upnp.name", value<std::string>()->default_value("I2Pd"), "Name i2pd appears in UPnP forwarding list")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description precomputation("Precomputation options");
|
options_description precomputation("Precomputation options");
|
||||||
@@ -190,7 +192,7 @@ namespace config {
|
|||||||
"https://netdb.i2p2.no/,"
|
"https://netdb.i2p2.no/,"
|
||||||
// "https://us.reseed.i2p2.no:444/," // mamoth's shit
|
// "https://us.reseed.i2p2.no:444/," // mamoth's shit
|
||||||
// "https://uk.reseed.i2p2.no:444/," // mamoth's shit
|
// "https://uk.reseed.i2p2.no:444/," // mamoth's shit
|
||||||
"https://i2p-0.manas.ca:8443/,"
|
"https://reseed.i2p.net.in/,"
|
||||||
"https://download.xxlspeed.com/,"
|
"https://download.xxlspeed.com/,"
|
||||||
"https://reseed-fr.i2pd.xyz/,"
|
"https://reseed-fr.i2pd.xyz/,"
|
||||||
"https://reseed.atomike.ninja/,"
|
"https://reseed.atomike.ninja/,"
|
||||||
@@ -232,6 +234,32 @@ namespace config {
|
|||||||
("exploratory.outbound.quantity", value<int>()->default_value(3), "Exploratory outbound tunnels quantity")
|
("exploratory.outbound.quantity", value<int>()->default_value(3), "Exploratory outbound tunnels quantity")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
options_description ntcp2("NTCP2 Options");
|
||||||
|
ntcp2.add_options()
|
||||||
|
("ntcp2.enabled", value<bool>()->default_value(true), "Enable NTCP2 (default: enabled)")
|
||||||
|
("ntcp2.published", value<bool>()->default_value(false), "Publish NTCP2 (default: disabled)")
|
||||||
|
("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)")
|
||||||
|
("ntcp2.addressv6", value<std::string>()->default_value("::"), "Address to bind NTCP2 on")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description nettime("Time sync options");
|
||||||
|
nettime.add_options()
|
||||||
|
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
|
||||||
|
("nettime.ntpservers", value<std::string>()->default_value(
|
||||||
|
"0.pool.ntp.org,"
|
||||||
|
"1.pool.ntp.org,"
|
||||||
|
"2.pool.ntp.org,"
|
||||||
|
"3.pool.ntp.org"
|
||||||
|
), "Comma separated list of NTCP servers")
|
||||||
|
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
|
||||||
|
;
|
||||||
|
|
||||||
|
options_description persist("Network information persisting options");
|
||||||
|
persist.add_options()
|
||||||
|
("persist.profiles", value<bool>()->default_value(true), "Persist peer profiles (default: true)")
|
||||||
|
("persist.addressbook", value<bool>()->default_value(true), "Persist full addresses (default: true)")
|
||||||
|
;
|
||||||
|
|
||||||
m_OptionsDesc
|
m_OptionsDesc
|
||||||
.add(general)
|
.add(general)
|
||||||
.add(limits)
|
.add(limits)
|
||||||
@@ -249,6 +277,9 @@ namespace config {
|
|||||||
.add(trust)
|
.add(trust)
|
||||||
.add(websocket)
|
.add(websocket)
|
||||||
.add(exploratory)
|
.add(exploratory)
|
||||||
|
.add(ntcp2)
|
||||||
|
.add(nettime)
|
||||||
|
.add(persist)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +305,23 @@ namespace config {
|
|||||||
{
|
{
|
||||||
std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
|
std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
|
||||||
std::cout << m_OptionsDesc;
|
std::cout << m_OptionsDesc;
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
else if (m_Options.count("version"))
|
||||||
|
{
|
||||||
|
std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
|
||||||
|
std::cout << "Boost version "
|
||||||
|
<< BOOST_VERSION / 100000 << "." // maj. version
|
||||||
|
<< BOOST_VERSION / 100 % 1000 << "." // min. version
|
||||||
|
<< BOOST_VERSION % 100 // patch version
|
||||||
|
<< std::endl;
|
||||||
|
#if defined(OPENSSL_VERSION_TEXT)
|
||||||
|
std::cout << OPENSSL_VERSION_TEXT << std::endl;
|
||||||
|
#endif
|
||||||
|
#if defined(LIBRESSL_VERSION_TEXT)
|
||||||
|
std::cout << LIBRESSL_VERSION_TEXT << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ namespace config {
|
|||||||
* @param argc Cmdline arguments count, should be passed from main().
|
* @param argc Cmdline arguments count, should be passed from main().
|
||||||
* @param argv Cmdline parameters array, should be passed from main()
|
* @param argv Cmdline parameters array, should be passed from main()
|
||||||
*
|
*
|
||||||
* If --help is given in parameters, shows it's list with description
|
* If --help is given in parameters, shows its list with description
|
||||||
* terminates the program with exitcode 0.
|
* and terminates the program with exitcode 0.
|
||||||
*
|
*
|
||||||
* In case of parameter misuse boost throws an exception.
|
* In case of parameter misuse boost throws an exception.
|
||||||
* We internally handle type boost::program_options::unknown_option,
|
* We internally handle type boost::program_options::unknown_option,
|
||||||
* and then terminate program with exitcode 1.
|
* and then terminate the program with exitcode 1.
|
||||||
*
|
*
|
||||||
* Other exceptions will be passed to higher level.
|
* Other exceptions will be passed to higher level.
|
||||||
*/
|
*/
|
||||||
@@ -107,7 +107,7 @@ namespace config {
|
|||||||
/**
|
/**
|
||||||
* @brief Check is value explicitly given or default
|
* @brief Check is value explicitly given or default
|
||||||
* @param name Name of checked parameter
|
* @param name Name of checked parameter
|
||||||
* @return true if value set to default, false othervise
|
* @return true if value set to default, false otherwise
|
||||||
*/
|
*/
|
||||||
bool IsDefault(const char *name);
|
bool IsDefault(const char *name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,15 @@
|
|||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include "TunnelBase.h"
|
#include "TunnelBase.h"
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include "Crypto.h"
|
#if OPENSSL_HKDF
|
||||||
#if LEGACY_OPENSSL
|
#include <openssl/kdf.h>
|
||||||
|
#endif
|
||||||
|
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
#include "ChaCha20.h"
|
#include "ChaCha20.h"
|
||||||
#include "Poly1305.h"
|
#include "Poly1305.h"
|
||||||
#else
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
#include "Crypto.h"
|
||||||
|
#include "Ed25519.h"
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
@@ -278,6 +280,84 @@ namespace crypto
|
|||||||
BN_free (pk);
|
BN_free (pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// x25519
|
||||||
|
X25519Keys::X25519Keys ()
|
||||||
|
{
|
||||||
|
#if OPENSSL_X25519
|
||||||
|
m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL);
|
||||||
|
m_Pkey = nullptr;
|
||||||
|
#else
|
||||||
|
m_Ctx = BN_CTX_new ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub)
|
||||||
|
{
|
||||||
|
#if OPENSSL_X25519
|
||||||
|
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32);
|
||||||
|
m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL);
|
||||||
|
memcpy (m_PublicKey, pub, 32); // TODO: verify against m_Pkey
|
||||||
|
#else
|
||||||
|
memcpy (m_PrivateKey, priv, 32);
|
||||||
|
memcpy (m_PublicKey, pub, 32);
|
||||||
|
m_Ctx = BN_CTX_new ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
X25519Keys::~X25519Keys ()
|
||||||
|
{
|
||||||
|
#if OPENSSL_X25519
|
||||||
|
EVP_PKEY_CTX_free (m_Ctx);
|
||||||
|
if (m_Pkey) EVP_PKEY_free (m_Pkey);
|
||||||
|
#else
|
||||||
|
BN_CTX_free (m_Ctx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void X25519Keys::GenerateKeys ()
|
||||||
|
{
|
||||||
|
#if OPENSSL_X25519
|
||||||
|
if (m_Pkey)
|
||||||
|
{
|
||||||
|
EVP_PKEY_free (m_Pkey);
|
||||||
|
m_Pkey = nullptr;
|
||||||
|
}
|
||||||
|
EVP_PKEY_keygen_init (m_Ctx);
|
||||||
|
EVP_PKEY_keygen (m_Ctx, &m_Pkey);
|
||||||
|
EVP_PKEY_CTX_free (m_Ctx);
|
||||||
|
m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx?
|
||||||
|
size_t len = 32;
|
||||||
|
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
|
||||||
|
#else
|
||||||
|
RAND_bytes (m_PrivateKey, 32);
|
||||||
|
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared)
|
||||||
|
{
|
||||||
|
#if OPENSSL_X25519
|
||||||
|
EVP_PKEY_derive_init (m_Ctx);
|
||||||
|
auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32);
|
||||||
|
EVP_PKEY_derive_set_peer (m_Ctx, pkey);
|
||||||
|
size_t len = 32;
|
||||||
|
EVP_PKEY_derive (m_Ctx, shared, &len);
|
||||||
|
EVP_PKEY_free (pkey);
|
||||||
|
#else
|
||||||
|
GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void X25519Keys::GetPrivateKey (uint8_t * priv) const
|
||||||
|
{
|
||||||
|
#if OPENSSL_X25519
|
||||||
|
size_t len = 32;
|
||||||
|
EVP_PKEY_get_raw_private_key (m_Pkey, priv, &len);
|
||||||
|
#else
|
||||||
|
memcpy (priv, m_PrivateKey, 32);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// ElGamal
|
// ElGamal
|
||||||
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
@@ -399,7 +479,7 @@ namespace crypto
|
|||||||
bn2buf (x, encrypted + 1, len);
|
bn2buf (x, encrypted + 1, len);
|
||||||
bn2buf (y, encrypted + 1 + len, len);
|
bn2buf (y, encrypted + 1 + len, len);
|
||||||
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
|
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bn2buf (x, encrypted, len);
|
bn2buf (x, encrypted, len);
|
||||||
@@ -468,10 +548,10 @@ namespace crypto
|
|||||||
CBCDecryption decryption;
|
CBCDecryption decryption;
|
||||||
decryption.SetKey (shared);
|
decryption.SetKey (shared);
|
||||||
decryption.SetIV (iv);
|
decryption.SetIV (iv);
|
||||||
if (zeroPadding)
|
if (zeroPadding)
|
||||||
decryption.Decrypt (encrypted + 258, 256, m);
|
decryption.Decrypt (encrypted + 258, 256, m);
|
||||||
else
|
else
|
||||||
decryption.Decrypt (encrypted + 256, 256, m);
|
decryption.Decrypt (encrypted + 256, 256, m);
|
||||||
// verify and copy
|
// verify and copy
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256 (m + 33, 222, hash);
|
SHA256 (m + 33, 222, hash);
|
||||||
@@ -522,9 +602,9 @@ namespace crypto
|
|||||||
{
|
{
|
||||||
uint64_t buf[256];
|
uint64_t buf[256];
|
||||||
uint64_t hash[12]; // 96 bytes
|
uint64_t hash[12]; // 96 bytes
|
||||||
|
#ifdef __AVX__
|
||||||
if(i2p::cpu::avx)
|
if(i2p::cpu::avx)
|
||||||
{
|
{
|
||||||
#ifdef AVX
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"vmovups %[key], %%ymm0 \n"
|
"vmovups %[key], %%ymm0 \n"
|
||||||
@@ -543,30 +623,9 @@ namespace crypto
|
|||||||
[buf]"r"(buf), [hash]"r"(hash)
|
[buf]"r"(buf), [hash]"r"(hash)
|
||||||
: "memory", "%xmm0" // TODO: change to %ymm0 later
|
: "memory", "%xmm0" // TODO: change to %ymm0 later
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
// ikeypad
|
|
||||||
buf[0] = key.GetLL ()[0] ^ IPAD;
|
|
||||||
buf[1] = key.GetLL ()[1] ^ IPAD;
|
|
||||||
buf[2] = key.GetLL ()[2] ^ IPAD;
|
|
||||||
buf[3] = key.GetLL ()[3] ^ IPAD;
|
|
||||||
buf[4] = IPAD;
|
|
||||||
buf[5] = IPAD;
|
|
||||||
buf[6] = IPAD;
|
|
||||||
buf[7] = IPAD;
|
|
||||||
// okeypad
|
|
||||||
hash[0] = key.GetLL ()[0] ^ OPAD;
|
|
||||||
hash[1] = key.GetLL ()[1] ^ OPAD;
|
|
||||||
hash[2] = key.GetLL ()[2] ^ OPAD;
|
|
||||||
hash[3] = key.GetLL ()[3] ^ OPAD;
|
|
||||||
hash[4] = OPAD;
|
|
||||||
hash[5] = OPAD;
|
|
||||||
hash[6] = OPAD;
|
|
||||||
hash[7] = OPAD;
|
|
||||||
// fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
|
|
||||||
memset (hash + 10, 0, 16);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
// ikeypad
|
// ikeypad
|
||||||
buf[0] = key.GetLL ()[0] ^ IPAD;
|
buf[0] = key.GetLL ()[0] ^ IPAD;
|
||||||
@@ -600,12 +659,12 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AES
|
// AES
|
||||||
#ifdef AESNI
|
#ifdef __AES__
|
||||||
#ifdef ARM64AES
|
#ifdef ARM64AES
|
||||||
void init_aesenc(void){
|
void init_aesenc(void){
|
||||||
// TODO: Implementation
|
// TODO: Implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KeyExpansion256(round0,round1) \
|
#define KeyExpansion256(round0,round1) \
|
||||||
@@ -632,7 +691,7 @@ namespace crypto
|
|||||||
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AESNI
|
#ifdef __AES__
|
||||||
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
|
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
|
||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
@@ -669,11 +728,11 @@ namespace crypto
|
|||||||
: [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input
|
: [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input
|
||||||
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged
|
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if AESNI
|
#ifdef __AES__
|
||||||
#define EncryptAES256(sched) \
|
#define EncryptAES256(sched) \
|
||||||
"pxor (%["#sched"]), %%xmm0 \n" \
|
"pxor (%["#sched"]), %%xmm0 \n" \
|
||||||
"aesenc 16(%["#sched"]), %%xmm0 \n" \
|
"aesenc 16(%["#sched"]), %%xmm0 \n" \
|
||||||
@@ -691,12 +750,12 @@ namespace crypto
|
|||||||
"aesenc 208(%["#sched"]), %%xmm0 \n" \
|
"aesenc 208(%["#sched"]), %%xmm0 \n" \
|
||||||
"aesenclast 224(%["#sched"]), %%xmm0 \n"
|
"aesenclast 224(%["#sched"]), %%xmm0 \n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out)
|
void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
@@ -704,17 +763,15 @@ namespace crypto
|
|||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
AES_encrypt (in->buf, out->buf, &m_Key);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
AES_encrypt (in->buf, out->buf, &m_Key);
|
AES_encrypt (in->buf, out->buf, &m_Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AESNI
|
#ifdef __AES__
|
||||||
#define DecryptAES256(sched) \
|
#define DecryptAES256(sched) \
|
||||||
"pxor 224(%["#sched"]), %%xmm0 \n" \
|
"pxor 224(%["#sched"]), %%xmm0 \n" \
|
||||||
"aesdec 208(%["#sched"]), %%xmm0 \n" \
|
"aesdec 208(%["#sched"]), %%xmm0 \n" \
|
||||||
@@ -732,12 +789,12 @@ namespace crypto
|
|||||||
"aesdec 16(%["#sched"]), %%xmm0 \n" \
|
"aesdec 16(%["#sched"]), %%xmm0 \n" \
|
||||||
"aesdeclast (%["#sched"]), %%xmm0 \n"
|
"aesdeclast (%["#sched"]), %%xmm0 \n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out)
|
void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
@@ -745,17 +802,15 @@ namespace crypto
|
|||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
AES_decrypt (in->buf, out->buf, &m_Key);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
AES_decrypt (in->buf, out->buf, &m_Key);
|
AES_decrypt (in->buf, out->buf, &m_Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AESNI
|
#ifdef __AES__
|
||||||
#define CallAESIMC(offset) \
|
#define CallAESIMC(offset) \
|
||||||
"movaps "#offset"(%[shed]), %%xmm0 \n" \
|
"movaps "#offset"(%[shed]), %%xmm0 \n" \
|
||||||
"aesimc %%xmm0, %%xmm0 \n" \
|
"aesimc %%xmm0, %%xmm0 \n" \
|
||||||
@@ -764,25 +819,23 @@ namespace crypto
|
|||||||
|
|
||||||
void ECBEncryption::SetKey (const AESKey& key)
|
void ECBEncryption::SetKey (const AESKey& key)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
ExpandKey (key);
|
||||||
ExpandKey (key);
|
|
||||||
#else
|
|
||||||
AES_set_encrypt_key (key, 256, &m_Key);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
AES_set_encrypt_key (key, 256, &m_Key);
|
AES_set_encrypt_key (key, 256, &m_Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECBDecryption::SetKey (const AESKey& key)
|
void ECBDecryption::SetKey (const AESKey& key)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
ExpandKey (key); // expand encryption key first
|
ExpandKey (key); // expand encryption key first
|
||||||
// then invert it using aesimc
|
// then invert it using aesimc
|
||||||
__asm__
|
__asm__
|
||||||
@@ -802,11 +855,9 @@ namespace crypto
|
|||||||
CallAESIMC(208)
|
CallAESIMC(208)
|
||||||
: : [shed]"r"(GetKeySchedule ()) : "%xmm0", "memory"
|
: : [shed]"r"(GetKeySchedule ()) : "%xmm0", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
AES_set_decrypt_key (key, 256, &m_Key);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
AES_set_decrypt_key (key, 256, &m_Key);
|
AES_set_decrypt_key (key, 256, &m_Key);
|
||||||
}
|
}
|
||||||
@@ -815,9 +866,9 @@ namespace crypto
|
|||||||
|
|
||||||
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
@@ -837,16 +888,9 @@ namespace crypto
|
|||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
||||||
: "%xmm0", "%xmm1", "cc", "memory"
|
: "%xmm0", "%xmm1", "cc", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
for (int i = 0; i < numBlocks; i++)
|
|
||||||
{
|
|
||||||
*m_LastBlock.GetChipherBlock () ^= in[i];
|
|
||||||
m_ECBEncryption.Encrypt (m_LastBlock.GetChipherBlock (), m_LastBlock.GetChipherBlock ());
|
|
||||||
out[i] = *m_LastBlock.GetChipherBlock ();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numBlocks; i++)
|
for (int i = 0; i < numBlocks; i++)
|
||||||
{
|
{
|
||||||
@@ -867,9 +911,9 @@ namespace crypto
|
|||||||
|
|
||||||
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
@@ -883,19 +927,17 @@ namespace crypto
|
|||||||
[in]"r"(in), [out]"r"(out)
|
[in]"r"(in), [out]"r"(out)
|
||||||
: "%xmm0", "%xmm1", "memory"
|
: "%xmm0", "%xmm1", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
@@ -916,17 +958,9 @@ namespace crypto
|
|||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
||||||
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
for (int i = 0; i < numBlocks; i++)
|
|
||||||
{
|
|
||||||
ChipherBlock tmp = in[i];
|
|
||||||
m_ECBDecryption.Decrypt (in + i, out + i);
|
|
||||||
out[i] ^= *m_IV.GetChipherBlock ();
|
|
||||||
*m_IV.GetChipherBlock () = tmp;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numBlocks; i++)
|
for (int i = 0; i < numBlocks; i++)
|
||||||
{
|
{
|
||||||
@@ -947,9 +981,9 @@ namespace crypto
|
|||||||
|
|
||||||
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
@@ -963,19 +997,17 @@ namespace crypto
|
|||||||
[in]"r"(in), [out]"r"(out)
|
[in]"r"(in), [out]"r"(out)
|
||||||
: "%xmm0", "%xmm1", "memory"
|
: "%xmm0", "%xmm1", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
// encrypt IV
|
// encrypt IV
|
||||||
@@ -1001,14 +1033,9 @@ namespace crypto
|
|||||||
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
||||||
: "%xmm0", "%xmm1", "cc", "memory"
|
: "%xmm0", "%xmm1", "cc", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
m_IVEncryption.Encrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
|
||||||
m_LayerEncryption.SetIV (out);
|
|
||||||
m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
|
||||||
m_IVEncryption.Encrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
m_IVEncryption.Encrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
m_IVEncryption.Encrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
||||||
m_LayerEncryption.SetIV (out);
|
m_LayerEncryption.SetIV (out);
|
||||||
@@ -1019,9 +1046,9 @@ namespace crypto
|
|||||||
|
|
||||||
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
||||||
{
|
{
|
||||||
|
#ifdef __AES__
|
||||||
if(i2p::cpu::aesni)
|
if(i2p::cpu::aesni)
|
||||||
{
|
{
|
||||||
#ifdef AESNI
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
// decrypt IV
|
// decrypt IV
|
||||||
@@ -1048,14 +1075,9 @@ namespace crypto
|
|||||||
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
||||||
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
||||||
);
|
);
|
||||||
#else
|
|
||||||
m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
|
||||||
m_LayerDecryption.SetIV (out);
|
|
||||||
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
|
||||||
m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
||||||
m_LayerDecryption.SetIV (out);
|
m_LayerDecryption.SetIV (out);
|
||||||
@@ -1068,59 +1090,11 @@ namespace crypto
|
|||||||
|
|
||||||
bool AEADChaCha20Poly1305 (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len, bool encrypt)
|
bool AEADChaCha20Poly1305 (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len, bool encrypt)
|
||||||
{
|
{
|
||||||
if (len < msgLen) return false;
|
if (len < msgLen) return false;
|
||||||
if (encrypt && len < msgLen + 16) return false;
|
if (encrypt && len < msgLen + 16) return false;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
#if LEGACY_OPENSSL
|
#if OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
// generate one time poly key
|
int outlen = 0;
|
||||||
uint8_t polyKey[64];
|
|
||||||
memset(polyKey, 0, sizeof(polyKey));
|
|
||||||
chacha20 (polyKey, 64, nonce, key, 0);
|
|
||||||
// encrypt data
|
|
||||||
memcpy (buf, msg, msgLen);
|
|
||||||
chacha20 (buf, msgLen, nonce, key, 1);
|
|
||||||
|
|
||||||
// create Poly1305 message
|
|
||||||
if (!ad) adLen = 0;
|
|
||||||
std::vector<uint8_t> polyMsg(adLen + msgLen + 3*16);
|
|
||||||
size_t offset = 0;
|
|
||||||
uint8_t padding[16]; memset (padding, 0, 16);
|
|
||||||
if (ad)
|
|
||||||
{
|
|
||||||
memcpy (polyMsg.data (), ad, adLen); offset += adLen; // additional authenticated data
|
|
||||||
auto rem = adLen & 0x0F; // %16
|
|
||||||
if (rem)
|
|
||||||
{
|
|
||||||
// padding1
|
|
||||||
rem = 16 - rem;
|
|
||||||
memcpy (polyMsg.data () + offset, padding, rem); offset += rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memcpy (polyMsg.data () + offset, encrypt ? buf : msg, msgLen); offset += msgLen; // encrypted data
|
|
||||||
auto rem = msgLen & 0x0F; // %16
|
|
||||||
if (rem)
|
|
||||||
{
|
|
||||||
// padding2
|
|
||||||
rem = 16 - rem;
|
|
||||||
memcpy (polyMsg.data () + offset, padding, rem); offset += rem;
|
|
||||||
}
|
|
||||||
htole64buf (polyMsg.data () + offset, adLen); offset += 8;
|
|
||||||
htole64buf (polyMsg.data () + offset, msgLen); offset += 8;
|
|
||||||
|
|
||||||
if (encrypt)
|
|
||||||
{
|
|
||||||
// calculate Poly1305 tag and write in after encrypted data
|
|
||||||
Poly1305HMAC ((uint32_t *)(buf + msgLen), (uint32_t *)polyKey, polyMsg.data (), offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t tag[8];
|
|
||||||
// calculate Poly1305 tag
|
|
||||||
Poly1305HMAC (tag, (uint32_t *)polyKey, polyMsg.data (), offset);
|
|
||||||
if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int outlen = 0;
|
|
||||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
||||||
if (encrypt)
|
if (encrypt)
|
||||||
{
|
{
|
||||||
@@ -1139,14 +1113,167 @@ namespace crypto
|
|||||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, (uint8_t *)(msg + msgLen));
|
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, (uint8_t *)(msg + msgLen));
|
||||||
EVP_DecryptInit_ex(ctx, NULL, NULL, key, nonce);
|
EVP_DecryptInit_ex(ctx, NULL, NULL, key, nonce);
|
||||||
EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adLen);
|
EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adLen);
|
||||||
ret = EVP_DecryptUpdate(ctx, buf, &outlen, msg, msgLen) > 0;
|
EVP_DecryptUpdate(ctx, buf, &outlen, msg, msgLen);
|
||||||
|
ret = EVP_DecryptFinal_ex(ctx, buf + outlen, &outlen) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX_free (ctx);
|
||||||
|
#else
|
||||||
|
chacha::Chacha20State state;
|
||||||
|
// generate one time poly key
|
||||||
|
chacha::Chacha20Init (state, nonce, key, 0);
|
||||||
|
uint64_t polyKey[8];
|
||||||
|
memset(polyKey, 0, sizeof(polyKey));
|
||||||
|
chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64);
|
||||||
|
// create Poly1305 hash
|
||||||
|
Poly1305 polyHash (polyKey);
|
||||||
|
if (!ad) adLen = 0;
|
||||||
|
uint8_t padding[16]; memset (padding, 0, 16);
|
||||||
|
if (ad)
|
||||||
|
{
|
||||||
|
polyHash.Update (ad, adLen);// additional authenticated data
|
||||||
|
auto rem = adLen & 0x0F; // %16
|
||||||
|
if (rem)
|
||||||
|
{
|
||||||
|
// padding1
|
||||||
|
rem = 16 - rem;
|
||||||
|
polyHash.Update (padding, rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// encrypt/decrypt data and add to hash
|
||||||
|
Chacha20SetCounter (state, 1);
|
||||||
|
if (buf != msg)
|
||||||
|
memcpy (buf, msg, msgLen);
|
||||||
|
if (encrypt)
|
||||||
|
{
|
||||||
|
chacha::Chacha20Encrypt (state, buf, msgLen); // encrypt
|
||||||
|
polyHash.Update (buf, msgLen); // after encryption
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
polyHash.Update (buf, msgLen); // before decryption
|
||||||
|
chacha::Chacha20Encrypt (state, buf, msgLen); // decrypt
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rem = msgLen & 0x0F; // %16
|
||||||
|
if (rem)
|
||||||
|
{
|
||||||
|
// padding2
|
||||||
|
rem = 16 - rem;
|
||||||
|
polyHash.Update (padding, rem);
|
||||||
|
}
|
||||||
|
// adLen and msgLen
|
||||||
|
htole64buf (padding, adLen);
|
||||||
|
htole64buf (padding + 8, msgLen);
|
||||||
|
polyHash.Update (padding, 16);
|
||||||
|
|
||||||
|
if (encrypt)
|
||||||
|
// calculate Poly1305 tag and write in after encrypted data
|
||||||
|
polyHash.Finish ((uint64_t *)(buf + msgLen));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint64_t tag[4];
|
||||||
|
// calculate Poly1305 tag
|
||||||
|
polyHash.Finish (tag);
|
||||||
|
if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free (ctx);
|
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AEADChaCha20Poly1305Encrypt (const std::vector<std::pair<uint8_t *, size_t> >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac)
|
||||||
|
{
|
||||||
|
if (bufs.empty ()) return;
|
||||||
|
#if OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
|
int outlen = 0;
|
||||||
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
||||||
|
EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0);
|
||||||
|
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0);
|
||||||
|
EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce);
|
||||||
|
for (const auto& it: bufs)
|
||||||
|
EVP_EncryptUpdate(ctx, it.first, &outlen, it.first, it.second);
|
||||||
|
EVP_EncryptFinal_ex(ctx, NULL, &outlen);
|
||||||
|
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac);
|
||||||
|
EVP_CIPHER_CTX_free (ctx);
|
||||||
|
#else
|
||||||
|
chacha::Chacha20State state;
|
||||||
|
// generate one time poly key
|
||||||
|
chacha::Chacha20Init (state, nonce, key, 0);
|
||||||
|
uint64_t polyKey[8];
|
||||||
|
memset(polyKey, 0, sizeof(polyKey));
|
||||||
|
chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64);
|
||||||
|
Poly1305 polyHash (polyKey);
|
||||||
|
// encrypt buffers
|
||||||
|
Chacha20SetCounter (state, 1);
|
||||||
|
size_t size = 0;
|
||||||
|
for (const auto& it: bufs)
|
||||||
|
{
|
||||||
|
chacha::Chacha20Encrypt (state, it.first, it.second);
|
||||||
|
polyHash.Update (it.first, it.second); // after encryption
|
||||||
|
size += it.second;
|
||||||
|
}
|
||||||
|
// padding
|
||||||
|
uint8_t padding[16];
|
||||||
|
memset (padding, 0, 16);
|
||||||
|
auto rem = size & 0x0F; // %16
|
||||||
|
if (rem)
|
||||||
|
{
|
||||||
|
// padding2
|
||||||
|
rem = 16 - rem;
|
||||||
|
polyHash.Update (padding, rem);
|
||||||
|
}
|
||||||
|
// adLen and msgLen
|
||||||
|
// adLen is always zero
|
||||||
|
htole64buf (padding + 8, size);
|
||||||
|
polyHash.Update (padding, 16);
|
||||||
|
// MAC
|
||||||
|
polyHash.Finish ((uint64_t *)mac);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaCha20 (const uint8_t * msg, size_t msgLen, const uint8_t * key, const uint8_t * nonce, uint8_t * out)
|
||||||
|
{
|
||||||
|
#if OPENSSL_AEAD_CHACHA20_POLY1305
|
||||||
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
||||||
|
uint32_t iv[4];
|
||||||
|
iv[0] = htole32 (1); memcpy (iv + 1, nonce, 12); // counter | nonce
|
||||||
|
EVP_EncryptInit_ex(ctx, EVP_chacha20 (), NULL, key, (const uint8_t *)iv);
|
||||||
|
int outlen = 0;
|
||||||
|
EVP_EncryptUpdate(ctx, out, &outlen, msg, msgLen);
|
||||||
|
EVP_EncryptFinal_ex(ctx, NULL, &outlen);
|
||||||
|
EVP_CIPHER_CTX_free (ctx);
|
||||||
|
#else
|
||||||
|
chacha::Chacha20State state;
|
||||||
|
chacha::Chacha20Init (state, nonce, key, 1);
|
||||||
|
if (out != msg) memcpy (out, msg, msgLen);
|
||||||
|
chacha::Chacha20Encrypt (state, out, msgLen);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out)
|
||||||
|
{
|
||||||
|
#if OPENSSL_HKDF
|
||||||
|
EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, NULL);
|
||||||
|
EVP_PKEY_derive_init (pctx);
|
||||||
|
EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256());
|
||||||
|
EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32);
|
||||||
|
EVP_PKEY_CTX_set1_hkdf_key (pctx, key, keyLen);
|
||||||
|
if (info.length () > 0)
|
||||||
|
EVP_PKEY_CTX_add1_hkdf_info (pctx, info.c_str (), info.length ());
|
||||||
|
size_t outlen = 64;
|
||||||
|
EVP_PKEY_derive (pctx, out, &outlen);
|
||||||
|
EVP_PKEY_CTX_free (pctx);
|
||||||
|
#else
|
||||||
|
uint8_t prk[32]; unsigned int len;
|
||||||
|
HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len);
|
||||||
|
auto l = info.length ();
|
||||||
|
memcpy (out, info.c_str (), l); out[l] = 0x01;
|
||||||
|
HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len);
|
||||||
|
memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02;
|
||||||
|
HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// init and terminate
|
// init and terminate
|
||||||
|
|
||||||
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
||||||
@@ -1161,11 +1288,13 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
void InitCrypto (bool precomputation)
|
void InitCrypto (bool precomputation)
|
||||||
{
|
{
|
||||||
i2p::cpu::Detect ();
|
i2p::cpu::Detect ();
|
||||||
|
#if LEGACY_OPENSSL
|
||||||
SSL_library_init ();
|
SSL_library_init ();
|
||||||
|
#endif
|
||||||
/* auto numLocks = CRYPTO_num_locks();
|
/* auto numLocks = CRYPTO_num_locks();
|
||||||
for (int i = 0; i < numLocks; i++)
|
for (int i = 0; i < numLocks; i++)
|
||||||
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
||||||
@@ -1200,3 +1329,4 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
103
libi2pd/Crypto.h
103
libi2pd/Crypto.h
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
@@ -13,11 +14,30 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Tag.h"
|
#include "Tag.h"
|
||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
|
|
||||||
|
// recognize openssl version and features
|
||||||
|
#if ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
|
||||||
|
# define LEGACY_OPENSSL 1
|
||||||
|
# define X509_getm_notBefore X509_get_notBefore
|
||||||
|
# define X509_getm_notAfter X509_get_notAfter
|
||||||
|
#else
|
||||||
|
# define LEGACY_OPENSSL 0
|
||||||
|
# define OPENSSL_HKDF 1
|
||||||
|
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
||||||
|
# define OPENSSL_EDDSA 1
|
||||||
|
# define OPENSSL_X25519 1
|
||||||
|
# define OPENSSL_SIPHASH 1
|
||||||
|
# endif
|
||||||
|
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
||||||
|
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
@@ -48,6 +68,32 @@ namespace crypto
|
|||||||
uint8_t m_PublicKey[256];
|
uint8_t m_PublicKey[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// x25519
|
||||||
|
class X25519Keys
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
X25519Keys ();
|
||||||
|
X25519Keys (const uint8_t * priv, const uint8_t * pub); // for RouterContext
|
||||||
|
~X25519Keys ();
|
||||||
|
|
||||||
|
void GenerateKeys ();
|
||||||
|
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
||||||
|
void GetPrivateKey (uint8_t * priv) const;
|
||||||
|
void Agree (const uint8_t * pub, uint8_t * shared);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint8_t m_PublicKey[32];
|
||||||
|
#if OPENSSL_X25519
|
||||||
|
EVP_PKEY_CTX * m_Ctx;
|
||||||
|
EVP_PKEY * m_Pkey;
|
||||||
|
#else
|
||||||
|
BN_CTX * m_Ctx;
|
||||||
|
uint8_t m_PrivateKey[32];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
// ElGamal
|
// ElGamal
|
||||||
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false);
|
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false);
|
||||||
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false);
|
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false);
|
||||||
@@ -69,30 +115,16 @@ namespace crypto
|
|||||||
|
|
||||||
void operator^=(const ChipherBlock& other) // XOR
|
void operator^=(const ChipherBlock& other) // XOR
|
||||||
{
|
{
|
||||||
if (i2p::cpu::avx)
|
if (!(((size_t)buf | (size_t)other.buf) & 0x03)) // multiple of 4 ?
|
||||||
{
|
{
|
||||||
#ifdef AVX
|
for (int i = 0; i < 4; i++)
|
||||||
__asm__
|
reinterpret_cast<uint32_t *>(buf)[i] ^= reinterpret_cast<const uint32_t *>(other.buf)[i];
|
||||||
(
|
}
|
||||||
"vmovups (%[buf]), %%xmm0 \n"
|
|
||||||
"vmovups (%[other]), %%xmm1 \n"
|
|
||||||
"vxorps %%xmm0, %%xmm1, %%xmm0 \n"
|
|
||||||
"vmovups %%xmm0, (%[buf]) \n"
|
|
||||||
:
|
|
||||||
: [buf]"r"(buf), [other]"r"(other.buf)
|
|
||||||
: "%xmm0", "%xmm1", "memory"
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
buf[i] ^= other.buf[i];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: implement it better
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
buf[i] ^= other.buf[i];
|
buf[i] ^= other.buf[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,7 +155,7 @@ namespace crypto
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef AESNI
|
#ifdef __AES__
|
||||||
#ifdef ARM64AES
|
#ifdef ARM64AES
|
||||||
void init_aesenc(void) __attribute__((constructor));
|
void init_aesenc(void) __attribute__((constructor));
|
||||||
#endif
|
#endif
|
||||||
@@ -143,7 +175,7 @@ namespace crypto
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AESNI
|
#ifdef __AES__
|
||||||
class ECBEncryption: public ECBCryptoAESNI
|
class ECBEncryption: public ECBCryptoAESNI
|
||||||
#else
|
#else
|
||||||
class ECBEncryption
|
class ECBEncryption
|
||||||
@@ -152,14 +184,14 @@ namespace crypto
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
void SetKey (const AESKey& key);
|
void SetKey (const AESKey& key);
|
||||||
|
|
||||||
void Encrypt(const ChipherBlock * in, ChipherBlock * out);
|
void Encrypt(const ChipherBlock * in, ChipherBlock * out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AES_KEY m_Key;
|
AES_KEY m_Key;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef AESNI
|
#ifdef __AES__
|
||||||
class ECBDecryption: public ECBCryptoAESNI
|
class ECBDecryption: public ECBCryptoAESNI
|
||||||
#else
|
#else
|
||||||
class ECBDecryption
|
class ECBDecryption
|
||||||
@@ -188,7 +220,7 @@ namespace crypto
|
|||||||
void Encrypt (const uint8_t * in, uint8_t * out); // one block
|
void Encrypt (const uint8_t * in, uint8_t * out); // one block
|
||||||
|
|
||||||
ECBEncryption & ECB() { return m_ECBEncryption; }
|
ECBEncryption & ECB() { return m_ECBEncryption; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AESAlignedBuffer<16> m_LastBlock;
|
AESAlignedBuffer<16> m_LastBlock;
|
||||||
@@ -211,7 +243,7 @@ namespace crypto
|
|||||||
void Decrypt (const uint8_t * in, uint8_t * out); // one block
|
void Decrypt (const uint8_t * in, uint8_t * out); // one block
|
||||||
|
|
||||||
ECBDecryption & ECB() { return m_ECBDecryption; }
|
ECBDecryption & ECB() { return m_ECBDecryption; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AESAlignedBuffer<16> m_IV;
|
AESAlignedBuffer<16> m_IV;
|
||||||
@@ -255,17 +287,24 @@ namespace crypto
|
|||||||
};
|
};
|
||||||
|
|
||||||
// AEAD/ChaCha20/Poly1305
|
// AEAD/ChaCha20/Poly1305
|
||||||
bool AEADChaCha20Poly1305 (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len, bool encrypt); // msgLen is len without tag
|
bool AEADChaCha20Poly1305 (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len, bool encrypt); // msgLen is len without tag
|
||||||
|
|
||||||
|
void AEADChaCha20Poly1305Encrypt (const std::vector<std::pair<uint8_t *, size_t> >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac); // encrypt multiple buffers with zero ad
|
||||||
|
|
||||||
|
// ChaCha20
|
||||||
|
void ChaCha20 (const uint8_t * msg, size_t msgLen, const uint8_t * key, const uint8_t * nonce, uint8_t * out);
|
||||||
|
|
||||||
|
// HKDF
|
||||||
|
|
||||||
|
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out); // salt - 32, out - 64, info <= 32
|
||||||
|
|
||||||
// init and terminate
|
// init and terminate
|
||||||
void InitCrypto (bool precomputation);
|
void InitCrypto (bool precomputation);
|
||||||
void TerminateCrypto ();
|
void TerminateCrypto ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// take care about openssl version
|
// take care about openssl below 1.1.0
|
||||||
#include <openssl/opensslv.h>
|
|
||||||
#define LEGACY_OPENSSL ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
|
|
||||||
#if LEGACY_OPENSSL
|
#if LEGACY_OPENSSL
|
||||||
// define getters and setters introduced in 1.1.0
|
// define getters and setters introduced in 1.1.0
|
||||||
inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ namespace crypto
|
|||||||
|
|
||||||
virtual ~CryptoKeyDecryptor () {};
|
virtual ~CryptoKeyDecryptor () {};
|
||||||
virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) = 0; // 512/514 bytes encrypted, 222 bytes data
|
virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) = 0; // 512/514 bytes encrypted, 222 bytes data
|
||||||
|
virtual size_t GetPublicKeyLen () const = 0; // we need it to set key in LS2
|
||||||
};
|
};
|
||||||
|
|
||||||
// ElGamal
|
// ElGamal
|
||||||
@@ -43,7 +44,8 @@ namespace crypto
|
|||||||
|
|
||||||
ElGamalDecryptor (const uint8_t * priv);
|
ElGamalDecryptor (const uint8_t * priv);
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
size_t GetPublicKeyLen () const { return 256; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t m_PrivateKey[256];
|
uint8_t m_PrivateKey[256];
|
||||||
@@ -73,7 +75,8 @@ namespace crypto
|
|||||||
ECIESP256Decryptor (const uint8_t * priv);
|
ECIESP256Decryptor (const uint8_t * priv);
|
||||||
~ECIESP256Decryptor ();
|
~ECIESP256Decryptor ();
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
size_t GetPublicKeyLen () const { return 64; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
EC_GROUP * m_Curve;
|
EC_GROUP * m_Curve;
|
||||||
@@ -105,7 +108,8 @@ namespace crypto
|
|||||||
ECIESGOSTR3410Decryptor (const uint8_t * priv);
|
ECIESGOSTR3410Decryptor (const uint8_t * priv);
|
||||||
~ECIESGOSTR3410Decryptor ();
|
~ECIESGOSTR3410Decryptor ();
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding);
|
||||||
|
size_t GetPublicKeyLen () const { return 64; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
BIGNUM * m_PrivateKey;
|
BIGNUM * m_PrivateKey;
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ namespace client
|
|||||||
LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map<std::string, std::string> * params):
|
LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map<std::string, std::string> * params):
|
||||||
m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic),
|
m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic),
|
||||||
m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service),
|
m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service),
|
||||||
m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service)
|
m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service),
|
||||||
|
m_LeaseSetType (DEFAULT_LEASESET_TYPE)
|
||||||
{
|
{
|
||||||
int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH;
|
int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH;
|
||||||
int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY;
|
int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY;
|
||||||
@@ -64,8 +65,11 @@ namespace client
|
|||||||
{
|
{
|
||||||
it = params->find (I2CP_PARAM_OUTBOUND_NICKNAME);
|
it = params->find (I2CP_PARAM_OUTBOUND_NICKNAME);
|
||||||
if (it != params->end ()) m_Nickname = it->second;
|
if (it != params->end ()) m_Nickname = it->second;
|
||||||
// otherwise we set deafult nickname in Start when we know local address
|
// otherwise we set default nickname in Start when we know local address
|
||||||
}
|
}
|
||||||
|
it = params->find (I2CP_PARAM_LEASESET_TYPE);
|
||||||
|
if (it != params->end ())
|
||||||
|
m_LeaseSetType = std::stoi(it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception & ex)
|
catch (std::exception & ex)
|
||||||
@@ -209,7 +213,7 @@ namespace client
|
|||||||
return pool->Reconfigure(inLen, outLen, inQuant, outQuant);
|
return pool->Reconfigure(inLen, outLen, inQuant, outQuant);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const i2p::data::LeaseSet> LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident)
|
std::shared_ptr<i2p::data::LeaseSet> LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
std::shared_ptr<i2p::data::LeaseSet> remoteLS;
|
std::shared_ptr<i2p::data::LeaseSet> remoteLS;
|
||||||
{
|
{
|
||||||
@@ -268,15 +272,21 @@ namespace client
|
|||||||
if (!m_Pool) return nullptr;
|
if (!m_Pool) return nullptr;
|
||||||
if (!m_LeaseSet)
|
if (!m_LeaseSet)
|
||||||
UpdateLeaseSet ();
|
UpdateLeaseSet ();
|
||||||
|
auto ls = GetLeaseSetMt ();
|
||||||
|
return (ls && ls->GetInnerLeaseSet ()) ? ls->GetInnerLeaseSet () : ls; // always non-encrypted
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const i2p::data::LocalLeaseSet> LeaseSetDestination::GetLeaseSetMt ()
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> l(m_LeaseSetMutex);
|
std::lock_guard<std::mutex> l(m_LeaseSetMutex);
|
||||||
return m_LeaseSet;
|
return m_LeaseSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaseSetDestination::SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet)
|
void LeaseSetDestination::SetLeaseSet (std::shared_ptr<const i2p::data::LocalLeaseSet> newLeaseSet)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l(m_LeaseSetMutex);
|
std::lock_guard<std::mutex> l(m_LeaseSetMutex);
|
||||||
m_LeaseSet.reset (newLeaseSet);
|
m_LeaseSet = newLeaseSet;
|
||||||
}
|
}
|
||||||
i2p::garlic::GarlicDestination::SetLeaseSetUpdated ();
|
i2p::garlic::GarlicDestination::SetLeaseSetUpdated ();
|
||||||
if (m_IsPublic)
|
if (m_IsPublic)
|
||||||
@@ -357,51 +367,76 @@ namespace client
|
|||||||
}
|
}
|
||||||
i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET);
|
i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET);
|
||||||
std::shared_ptr<i2p::data::LeaseSet> leaseSet;
|
std::shared_ptr<i2p::data::LeaseSet> leaseSet;
|
||||||
if (buf[DATABASE_STORE_TYPE_OFFSET] == 1) // LeaseSet
|
switch (buf[DATABASE_STORE_TYPE_OFFSET])
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Destination: Remote LeaseSet");
|
case i2p::data::NETDB_STORE_TYPE_LEASESET: // 1
|
||||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
case i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2: // 3
|
||||||
auto it = m_RemoteLeaseSets.find (key);
|
|
||||||
if (it != m_RemoteLeaseSets.end ())
|
|
||||||
{
|
{
|
||||||
leaseSet = it->second;
|
LogPrint (eLogDebug, "Destination: Remote LeaseSet");
|
||||||
if (leaseSet->IsNewer (buf + offset, len - offset))
|
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
||||||
|
auto it = m_RemoteLeaseSets.find (key);
|
||||||
|
if (it != m_RemoteLeaseSets.end ())
|
||||||
{
|
{
|
||||||
leaseSet->Update (buf + offset, len - offset);
|
leaseSet = it->second;
|
||||||
|
if (leaseSet->IsNewer (buf + offset, len - offset))
|
||||||
|
{
|
||||||
|
leaseSet->Update (buf + offset, len - offset);
|
||||||
|
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
|
||||||
|
LogPrint (eLogDebug, "Destination: Remote LeaseSet updated");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Destination: Remote LeaseSet update failed");
|
||||||
|
m_RemoteLeaseSets.erase (it);
|
||||||
|
leaseSet = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogDebug, "Destination: Remote LeaseSet is older. Not updated");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET)
|
||||||
|
leaseSet = std::make_shared<i2p::data::LeaseSet> (buf + offset, len - offset); // LeaseSet
|
||||||
|
else
|
||||||
|
leaseSet = std::make_shared<i2p::data::LeaseSet2> (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset); // LeaseSet2
|
||||||
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
|
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
|
||||||
LogPrint (eLogDebug, "Destination: Remote LeaseSet updated");
|
{
|
||||||
|
if (leaseSet->GetIdentHash () != GetIdentHash ())
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Destination: New remote LeaseSet added");
|
||||||
|
m_RemoteLeaseSets[key] = leaseSet;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogDebug, "Destination: Own remote LeaseSet dropped");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Destination: Remote LeaseSet update failed");
|
LogPrint (eLogError, "Destination: New remote LeaseSet failed");
|
||||||
m_RemoteLeaseSets.erase (it);
|
|
||||||
leaseSet = nullptr;
|
leaseSet = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
LogPrint (eLogDebug, "Destination: Remote LeaseSet is older. Not updated");
|
|
||||||
}
|
}
|
||||||
else
|
case i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2: // 5
|
||||||
{
|
{
|
||||||
leaseSet = std::make_shared<i2p::data::LeaseSet> (buf + offset, len - offset);
|
auto it2 = m_LeaseSetRequests.find (key);
|
||||||
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
|
if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey)
|
||||||
{
|
{
|
||||||
if (leaseSet->GetIdentHash () != GetIdentHash ())
|
auto ls2 = std::make_shared<i2p::data::LeaseSet2> (buf + offset, len - offset, it2->second->requestedBlindedKey);
|
||||||
|
if (ls2->IsValid ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Destination: New remote LeaseSet added");
|
m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key
|
||||||
m_RemoteLeaseSets[key] = leaseSet;
|
m_RemoteLeaseSets[key] = ls2; // also store as key for next lookup
|
||||||
|
leaseSet = ls2;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogDebug, "Destination: Own remote LeaseSet dropped");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
LogPrint (eLogInfo, "Destination: Couldn't find request for encrypted LeaseSet2");
|
||||||
LogPrint (eLogError, "Destination: New remote LeaseSet failed");
|
break;
|
||||||
leaseSet = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped");
|
|
||||||
|
|
||||||
auto it1 = m_LeaseSetRequests.find (key);
|
auto it1 = m_LeaseSetRequests.find (key);
|
||||||
if (it1 != m_LeaseSetRequests.end ())
|
if (it1 != m_LeaseSetRequests.end ())
|
||||||
@@ -477,7 +512,8 @@ namespace client
|
|||||||
|
|
||||||
void LeaseSetDestination::Publish ()
|
void LeaseSetDestination::Publish ()
|
||||||
{
|
{
|
||||||
if (!m_LeaseSet || !m_Pool)
|
auto leaseSet = GetLeaseSetMt ();
|
||||||
|
if (!leaseSet || !m_Pool)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Destination: Can't publish non-existing LeaseSet");
|
LogPrint (eLogError, "Destination: Can't publish non-existing LeaseSet");
|
||||||
return;
|
return;
|
||||||
@@ -509,7 +545,7 @@ namespace client
|
|||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills);
|
auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills);
|
||||||
if (!floodfill)
|
if (!floodfill)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
|
||||||
@@ -519,7 +555,7 @@ namespace client
|
|||||||
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
|
||||||
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
|
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
|
||||||
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
|
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
|
||||||
auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound));
|
auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound));
|
||||||
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
|
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
|
||||||
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
|
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
@@ -542,7 +578,7 @@ namespace client
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ());
|
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ());
|
||||||
// Java floodfill never sends confirmantion back for unknown crypto type
|
// Java floodfill never sends confirmation back for unknown crypto type
|
||||||
// assume it successive and try to verify
|
// assume it successive and try to verify
|
||||||
m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT));
|
m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT));
|
||||||
m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer,
|
m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer,
|
||||||
@@ -557,26 +593,32 @@ namespace client
|
|||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
|
auto ls = GetLeaseSetMt ();
|
||||||
|
if (!ls)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Destination: couldn't verify LeaseSet for ", GetIdentHash().ToBase32());
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto s = shared_from_this ();
|
auto s = shared_from_this ();
|
||||||
RequestLeaseSet (GetIdentHash (),
|
// we must capture this for gcc 4.7 due the bug
|
||||||
// "this" added due to bug in gcc 4.7-4.8
|
RequestLeaseSet (ls->GetStoreHash (),
|
||||||
[s,this](std::shared_ptr<i2p::data::LeaseSet> leaseSet)
|
[s, ls, this](std::shared_ptr<const i2p::data::LeaseSet> leaseSet)
|
||||||
{
|
{
|
||||||
if (leaseSet)
|
if (leaseSet)
|
||||||
{
|
{
|
||||||
if (s->m_LeaseSet && *s->m_LeaseSet == *leaseSet)
|
if (*ls == *leaseSet)
|
||||||
{
|
{
|
||||||
// we got latest LeasetSet
|
// we got latest LeasetSet
|
||||||
LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", GetIdentHash().ToBase32());
|
LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", s->GetIdentHash().ToBase32());
|
||||||
s->m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_REGULAR_VERIFICATION_INTERNAL));
|
s->m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_REGULAR_VERIFICATION_INTERNAL));
|
||||||
s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1));
|
s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", GetIdentHash().ToBase32());
|
LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", s->GetIdentHash().ToBase32());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", GetIdentHash().ToBase32());
|
LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", s->GetIdentHash().ToBase32());
|
||||||
// we have to publish again
|
// we have to publish again
|
||||||
s->Publish ();
|
s->Publish ();
|
||||||
});
|
});
|
||||||
@@ -597,7 +639,27 @@ namespace client
|
|||||||
m_Service.post ([requestComplete](void){requestComplete (nullptr);});
|
m_Service.post ([requestComplete](void){requestComplete (nullptr);});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete));
|
m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete, nullptr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LeaseSetDestination::RequestDestinationWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, RequestComplete requestComplete)
|
||||||
|
{
|
||||||
|
if (!dest || !m_Pool || !IsReady ())
|
||||||
|
{
|
||||||
|
if (requestComplete)
|
||||||
|
m_Service.post ([requestComplete](void){requestComplete (nullptr);});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto storeHash = dest->GetStoreHash ();
|
||||||
|
auto leaseSet = FindLeaseSet (storeHash);
|
||||||
|
if (leaseSet)
|
||||||
|
{
|
||||||
|
if (requestComplete)
|
||||||
|
m_Service.post ([requestComplete, leaseSet](void){requestComplete (leaseSet);});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), storeHash, requestComplete, dest));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,13 +678,20 @@ namespace client
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaseSetDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete)
|
void LeaseSetDestination::CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, bool notify)
|
||||||
|
{
|
||||||
|
if (dest)
|
||||||
|
CancelDestinationRequest (dest->GetStoreHash (), notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeaseSetDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> requestedBlindedKey)
|
||||||
{
|
{
|
||||||
std::set<i2p::data::IdentHash> excluded;
|
std::set<i2p::data::IdentHash> excluded;
|
||||||
auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, excluded);
|
auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, excluded);
|
||||||
if (floodfill)
|
if (floodfill)
|
||||||
{
|
{
|
||||||
auto request = std::make_shared<LeaseSetRequest> (m_Service);
|
auto request = std::make_shared<LeaseSetRequest> (m_Service);
|
||||||
|
request->requestedBlindedKey = requestedBlindedKey; // for encrypted LeaseSet2
|
||||||
if (requestComplete)
|
if (requestComplete)
|
||||||
request->requestComplete.push_back (requestComplete);
|
request->requestComplete.push_back (requestComplete);
|
||||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
@@ -769,12 +838,23 @@ namespace client
|
|||||||
m_DatagramDestination (nullptr), m_RefCounter (0),
|
m_DatagramDestination (nullptr), m_RefCounter (0),
|
||||||
m_ReadyChecker(GetService())
|
m_ReadyChecker(GetService())
|
||||||
{
|
{
|
||||||
if (isPublic)
|
if (keys.IsOfflineSignature () && GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET)
|
||||||
|
SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // offline keys can be published with LS2 only
|
||||||
|
|
||||||
|
m_EncryptionKeyType = GetIdentity ()->GetCryptoKeyType ();
|
||||||
|
// extract encryption type params for LS2
|
||||||
|
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 && params)
|
||||||
|
{
|
||||||
|
auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE);
|
||||||
|
if (it != params->end ())
|
||||||
|
m_EncryptionKeyType = std::stoi(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPublic && m_EncryptionKeyType == GetIdentity ()->GetCryptoKeyType ()) // TODO: presist key type
|
||||||
PersistTemporaryKeys ();
|
PersistTemporaryKeys ();
|
||||||
else
|
else
|
||||||
i2p::data::PrivateKeys::GenerateCryptoKeyPair(GetIdentity ()->GetCryptoKeyType (),
|
i2p::data::PrivateKeys::GenerateCryptoKeyPair (m_EncryptionKeyType, m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
||||||
m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_EncryptionKeyType, m_EncryptionPrivateKey);
|
||||||
m_Decryptor = m_Keys.CreateDecryptor (m_EncryptionPrivateKey);
|
|
||||||
if (isPublic)
|
if (isPublic)
|
||||||
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
||||||
|
|
||||||
@@ -906,7 +986,7 @@ namespace client
|
|||||||
{
|
{
|
||||||
auto s = GetSharedFromThis ();
|
auto s = GetSharedFromThis ();
|
||||||
RequestDestination (dest,
|
RequestDestination (dest,
|
||||||
[s, streamRequestComplete, port](std::shared_ptr<i2p::data::LeaseSet> ls)
|
[s, streamRequestComplete, port](std::shared_ptr<const i2p::data::LeaseSet> ls)
|
||||||
{
|
{
|
||||||
if (ls)
|
if (ls)
|
||||||
streamRequestComplete(s->CreateStream (ls, port));
|
streamRequestComplete(s->CreateStream (ls, port));
|
||||||
@@ -916,6 +996,24 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port)
|
||||||
|
{
|
||||||
|
if (!streamRequestComplete)
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Destination: request callback is not specified in CreateStream");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto s = GetSharedFromThis ();
|
||||||
|
RequestDestinationWithEncryptedLeaseSet (dest,
|
||||||
|
[s, streamRequestComplete, port](std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||||
|
{
|
||||||
|
if (ls)
|
||||||
|
streamRequestComplete(s->CreateStream (ls, port));
|
||||||
|
else
|
||||||
|
streamRequestComplete (nullptr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port)
|
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port)
|
||||||
{
|
{
|
||||||
if (m_StreamingDestination)
|
if (m_StreamingDestination)
|
||||||
@@ -1004,9 +1102,10 @@ namespace client
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint (eLogInfo, "Destination: Creating new temporary keys for address ", ident, ".b32.i2p");
|
LogPrint (eLogInfo, "Destination: Creating new temporary keys of type for address ", ident, ".b32.i2p");
|
||||||
i2p::data::PrivateKeys::GenerateCryptoKeyPair(GetIdentity ()->GetCryptoKeyType (),
|
memset (m_EncryptionPrivateKey, 0, 256);
|
||||||
m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
memset (m_EncryptionPublicKey, 0, 256);
|
||||||
|
i2p::data::PrivateKeys::GenerateCryptoKeyPair (GetIdentity ()->GetCryptoKeyType (), m_EncryptionPrivateKey, m_EncryptionPublicKey);
|
||||||
|
|
||||||
std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out);
|
std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out);
|
||||||
if (f1) {
|
if (f1) {
|
||||||
@@ -1019,9 +1118,23 @@ namespace client
|
|||||||
|
|
||||||
void ClientDestination::CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels)
|
void ClientDestination::CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels)
|
||||||
{
|
{
|
||||||
auto leaseSet = new i2p::data::LocalLeaseSet (GetIdentity (), m_EncryptionPublicKey, tunnels);
|
std::shared_ptr<i2p::data::LocalLeaseSet> leaseSet;
|
||||||
// sign
|
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET)
|
||||||
Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); // TODO
|
{
|
||||||
|
leaseSet = std::make_shared<i2p::data::LocalLeaseSet> (GetIdentity (), m_EncryptionPublicKey, tunnels);
|
||||||
|
// sign
|
||||||
|
Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// standard LS2 (type 3) first
|
||||||
|
auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256;
|
||||||
|
auto ls2 = std::make_shared<i2p::data::LocalLeaseSet2> (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2,
|
||||||
|
m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels);
|
||||||
|
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) // encrypt if type 5
|
||||||
|
ls2 = std::make_shared<i2p::data::LocalEncryptedLeaseSet2> (ls2, m_Keys);
|
||||||
|
leaseSet = ls2;
|
||||||
|
}
|
||||||
SetLeaseSet (leaseSet);
|
SetLeaseSet (leaseSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ namespace client
|
|||||||
const int DEFAULT_TAGS_TO_SEND = 40;
|
const int DEFAULT_TAGS_TO_SEND = 40;
|
||||||
const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname";
|
const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname";
|
||||||
const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname";
|
const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname";
|
||||||
|
const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType";
|
||||||
|
const int DEFAULT_LEASESET_TYPE = 1;
|
||||||
|
const char I2CP_PARAM_LEASESET_ENCRYPTION_TYPE[] = "i2cp.leaseSetEncType";
|
||||||
|
|
||||||
// latency
|
// latency
|
||||||
const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min";
|
const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min";
|
||||||
@@ -79,6 +82,7 @@ namespace client
|
|||||||
std::list<RequestComplete> requestComplete;
|
std::list<RequestComplete> requestComplete;
|
||||||
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel;
|
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel;
|
||||||
std::shared_ptr<i2p::tunnel::InboundTunnel> replyTunnel;
|
std::shared_ptr<i2p::tunnel::InboundTunnel> replyTunnel;
|
||||||
|
std::shared_ptr<const i2p::data::BlindedPublicKey> requestedBlindedKey; // for encrypted LeaseSet2 only
|
||||||
|
|
||||||
void Complete (std::shared_ptr<i2p::data::LeaseSet> ls)
|
void Complete (std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||||
{
|
{
|
||||||
@@ -104,9 +108,11 @@ namespace client
|
|||||||
boost::asio::io_service& GetService () { return m_Service; };
|
boost::asio::io_service& GetService () { return m_Service; };
|
||||||
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () { return m_Pool; };
|
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () { return m_Pool; };
|
||||||
bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; };
|
bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; };
|
||||||
std::shared_ptr<const i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
std::shared_ptr<i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
||||||
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
|
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
|
||||||
|
bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, RequestComplete requestComplete = nullptr);
|
||||||
void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true);
|
void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true);
|
||||||
|
void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, bool notify = true);
|
||||||
|
|
||||||
// implements GarlicDestination
|
// implements GarlicDestination
|
||||||
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet ();
|
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet ();
|
||||||
@@ -121,7 +127,9 @@ namespace client
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet);
|
void SetLeaseSet (std::shared_ptr<const i2p::data::LocalLeaseSet> newLeaseSet);
|
||||||
|
int GetLeaseSetType () const { return m_LeaseSetType; };
|
||||||
|
void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; };
|
||||||
virtual void CleanupDestination () {}; // additional clean up in derived classes
|
virtual void CleanupDestination () {}; // additional clean up in derived classes
|
||||||
// I2CP
|
// I2CP
|
||||||
virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0;
|
virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0;
|
||||||
@@ -131,6 +139,7 @@ namespace client
|
|||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
void UpdateLeaseSet ();
|
void UpdateLeaseSet ();
|
||||||
|
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSetMt ();
|
||||||
void Publish ();
|
void Publish ();
|
||||||
void HandlePublishConfirmationTimer (const boost::system::error_code& ecode);
|
void HandlePublishConfirmationTimer (const boost::system::error_code& ecode);
|
||||||
void HandlePublishVerificationTimer (const boost::system::error_code& ecode);
|
void HandlePublishVerificationTimer (const boost::system::error_code& ecode);
|
||||||
@@ -139,7 +148,7 @@ namespace client
|
|||||||
void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len);
|
void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len);
|
||||||
void HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
void HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete);
|
void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> requestedBlindedKey = nullptr);
|
||||||
bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request);
|
bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request);
|
||||||
void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest);
|
void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest);
|
||||||
void HandleCleanupTimer (const boost::system::error_code& ecode);
|
void HandleCleanupTimer (const boost::system::error_code& ecode);
|
||||||
@@ -156,7 +165,7 @@ namespace client
|
|||||||
|
|
||||||
std::shared_ptr<i2p::tunnel::TunnelPool> m_Pool;
|
std::shared_ptr<i2p::tunnel::TunnelPool> m_Pool;
|
||||||
std::mutex m_LeaseSetMutex;
|
std::mutex m_LeaseSetMutex;
|
||||||
std::shared_ptr<i2p::data::LocalLeaseSet> m_LeaseSet;
|
std::shared_ptr<const i2p::data::LocalLeaseSet> m_LeaseSet;
|
||||||
bool m_IsPublic;
|
bool m_IsPublic;
|
||||||
uint32_t m_PublishReplyToken;
|
uint32_t m_PublishReplyToken;
|
||||||
uint64_t m_LastSubmissionTime; // in seconds
|
uint64_t m_LastSubmissionTime; // in seconds
|
||||||
@@ -165,6 +174,7 @@ namespace client
|
|||||||
boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer,
|
boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer,
|
||||||
m_PublishDelayTimer, m_CleanupTimer;
|
m_PublishDelayTimer, m_CleanupTimer;
|
||||||
std::string m_Nickname;
|
std::string m_Nickname;
|
||||||
|
int m_LeaseSetType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -203,6 +213,7 @@ namespace client
|
|||||||
std::shared_ptr<i2p::stream::StreamingDestination> GetStreamingDestination (int port = 0) const;
|
std::shared_ptr<i2p::stream::StreamingDestination> GetStreamingDestination (int port = 0) const;
|
||||||
// following methods operate with default streaming destination
|
// following methods operate with default streaming destination
|
||||||
void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0);
|
void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0);
|
||||||
|
void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> dest, int port = 0);
|
||||||
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port = 0);
|
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port = 0);
|
||||||
void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor);
|
void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor);
|
||||||
void StopAcceptingStreams ();
|
void StopAcceptingStreams ();
|
||||||
@@ -238,6 +249,7 @@ namespace client
|
|||||||
|
|
||||||
i2p::data::PrivateKeys m_Keys;
|
i2p::data::PrivateKeys m_Keys;
|
||||||
uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256];
|
uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256];
|
||||||
|
i2p::data::CryptoKeyType m_EncryptionKeyType;
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor;
|
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor;
|
||||||
|
|
||||||
int m_StreamingAckDelay;
|
int m_StreamingAckDelay;
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ namespace crypto
|
|||||||
return passed;
|
return passed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed25519::Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len,
|
void Ed25519::Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded,
|
||||||
uint8_t * signature) const
|
const uint8_t * buf, size_t len, uint8_t * signature) const
|
||||||
{
|
{
|
||||||
BN_CTX * bnCtx = BN_CTX_new ();
|
BN_CTX * bnCtx = BN_CTX_new ();
|
||||||
// calculate r
|
// calculate r
|
||||||
@@ -153,6 +153,44 @@ namespace crypto
|
|||||||
BN_CTX_free (bnCtx);
|
BN_CTX_free (bnCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ed25519::SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded,
|
||||||
|
const uint8_t * buf, size_t len, uint8_t * signature) const
|
||||||
|
{
|
||||||
|
BN_CTX * bnCtx = BN_CTX_new ();
|
||||||
|
// T = 80 random bytes
|
||||||
|
uint8_t T[80];
|
||||||
|
RAND_bytes (T, 80);
|
||||||
|
// calculate r = H*(T || publickey || data)
|
||||||
|
SHA512_CTX ctx;
|
||||||
|
SHA512_Init (&ctx);
|
||||||
|
SHA512_Update (&ctx, T, 80);
|
||||||
|
SHA512_Update (&ctx, publicKeyEncoded, 32);
|
||||||
|
SHA512_Update (&ctx, buf, len); // data
|
||||||
|
uint8_t digest[64];
|
||||||
|
SHA512_Final (digest, &ctx);
|
||||||
|
BIGNUM * r = DecodeBN<64> (digest);
|
||||||
|
BN_mod (r, r, l, bnCtx); // % l
|
||||||
|
EncodeBN (r, digest, 32);
|
||||||
|
// calculate R
|
||||||
|
uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf
|
||||||
|
EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R);
|
||||||
|
// calculate S
|
||||||
|
SHA512_Init (&ctx);
|
||||||
|
SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
|
||||||
|
SHA512_Update (&ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
|
||||||
|
SHA512_Update (&ctx, buf, len); // data
|
||||||
|
SHA512_Final (digest, &ctx);
|
||||||
|
BIGNUM * h = DecodeBN<64> (digest);
|
||||||
|
// S = (r + h*a) % l
|
||||||
|
BIGNUM * a = DecodeBN<EDDSA25519_PRIVATE_KEY_LENGTH> (privateKey);
|
||||||
|
BN_mod_mul (h, h, a, l, bnCtx); // %l
|
||||||
|
BN_mod_add (h, h, r, l, bnCtx); // %l
|
||||||
|
memcpy (signature, R, EDDSA25519_SIGNATURE_LENGTH/2);
|
||||||
|
EncodeBN (h, signature + EDDSA25519_SIGNATURE_LENGTH/2, EDDSA25519_SIGNATURE_LENGTH/2); // S
|
||||||
|
BN_free (r); BN_free (h); BN_free (a);
|
||||||
|
BN_CTX_free (bnCtx);
|
||||||
|
}
|
||||||
|
|
||||||
EDDSAPoint Ed25519::Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const
|
EDDSAPoint Ed25519::Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
// x3 = (x1*y2+y1*x2)*(z1*z2-d*t1*t2)
|
// x3 = (x1*y2+y1*x2)*(z1*z2-d*t1*t2)
|
||||||
@@ -411,6 +449,7 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !OPENSSL_X25519
|
||||||
BIGNUM * Ed25519::ScalarMul (const BIGNUM * u, const BIGNUM * k, BN_CTX * ctx) const
|
BIGNUM * Ed25519::ScalarMul (const BIGNUM * u, const BIGNUM * k, BN_CTX * ctx) const
|
||||||
{
|
{
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
@@ -488,6 +527,40 @@ namespace crypto
|
|||||||
EncodeBN (q1, buf, 32);
|
EncodeBN (q1, buf, 32);
|
||||||
BN_free (p1); BN_free (n); BN_free (q1);
|
BN_free (p1); BN_free (n); BN_free (q1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Ed25519::BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded)
|
||||||
|
{
|
||||||
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
|
// calculate alpha = seed mod l
|
||||||
|
BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian
|
||||||
|
BN_mod (alpha, alpha, l, ctx); // % l
|
||||||
|
uint8_t priv[32];
|
||||||
|
EncodeBN (alpha, priv, 32); // back to Little Endian
|
||||||
|
BN_free (alpha);
|
||||||
|
// A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha)
|
||||||
|
auto A1 = Sum (DecodePublicKey (pub, ctx), MulB (priv, ctx), ctx); // pub + B*alpha
|
||||||
|
EncodePublicKey (A1, blinded, ctx);
|
||||||
|
BN_CTX_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ed25519::BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub)
|
||||||
|
{
|
||||||
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
|
// calculate alpha = seed mod l
|
||||||
|
BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian
|
||||||
|
BN_mod (alpha, alpha, l, ctx); // % l
|
||||||
|
BIGNUM * p = DecodeBN<32> (priv); // priv is in Little Endian
|
||||||
|
BN_add (alpha, alpha, p); // alpha = alpha + priv
|
||||||
|
// a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L
|
||||||
|
BN_mod (alpha, alpha, l, ctx); // % l
|
||||||
|
EncodeBN (alpha, blindedPriv, 32);
|
||||||
|
// A' = DERIVE_PUBLIC(a')
|
||||||
|
auto A1 = MulB (blindedPriv, ctx);
|
||||||
|
EncodePublicKey (A1, blindedPub, ctx);
|
||||||
|
BN_free (alpha); BN_free (p);
|
||||||
|
BN_CTX_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey)
|
void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey)
|
||||||
{
|
{
|
||||||
@@ -497,6 +570,18 @@ namespace crypto
|
|||||||
expandedKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] |= 0x40; // set second bit
|
expandedKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] |= 0x40; // set second bit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ed25519::CreateRedDSAPrivateKey (uint8_t * priv)
|
||||||
|
{
|
||||||
|
uint8_t seed[32];
|
||||||
|
RAND_bytes (seed, 32);
|
||||||
|
BIGNUM * p = DecodeBN<32> (seed);
|
||||||
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
|
BN_mod (p, p, l, ctx); // % l
|
||||||
|
EncodeBN (p, priv, 32);
|
||||||
|
BN_CTX_free (ctx);
|
||||||
|
BN_free (p);
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<Ed25519> g_Ed25519;
|
static std::unique_ptr<Ed25519> g_Ed25519;
|
||||||
std::unique_ptr<Ed25519>& GetEd25519 ()
|
std::unique_ptr<Ed25519>& GetEd25519 ()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
|
#include "Crypto.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@@ -75,14 +76,20 @@ namespace crypto
|
|||||||
EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const;
|
EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const;
|
||||||
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
|
||||||
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
|
#if !OPENSSL_X25519
|
||||||
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
||||||
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
||||||
|
#endif
|
||||||
|
void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
||||||
|
void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
|
||||||
|
|
||||||
bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const;
|
bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const;
|
||||||
void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const;
|
void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const;
|
||||||
|
void SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const;
|
||||||
|
|
||||||
static void ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey); // key - 32 bytes, expandedKey - 64 bytes
|
static void ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey); // key - 32 bytes, expandedKey - 64 bytes
|
||||||
|
void CreateRedDSAPrivateKey (uint8_t * priv); // priv is 32 bytes
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
EDDSAPoint Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const;
|
EDDSAPoint Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const;
|
||||||
@@ -100,8 +107,10 @@ namespace crypto
|
|||||||
BIGNUM * DecodeBN (const uint8_t * buf) const;
|
BIGNUM * DecodeBN (const uint8_t * buf) const;
|
||||||
void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const;
|
void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const;
|
||||||
|
|
||||||
|
#if !OPENSSL_X25519
|
||||||
// for x25519
|
// for x25519
|
||||||
BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const;
|
BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
317
libi2pd/FS.cpp
317
libi2pd/FS.cpp
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
@@ -20,187 +21,211 @@
|
|||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
std::string appName = "i2pd";
|
std::string appName = "i2pd";
|
||||||
std::string dataDir = "";
|
std::string dataDir = "";
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::string dirSep = "\\";
|
std::string dirSep = "\\";
|
||||||
#else
|
#else
|
||||||
std::string dirSep = "/";
|
std::string dirSep = "/";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const std::string & GetAppName () {
|
const std::string & GetAppName () {
|
||||||
return appName;
|
return appName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAppName (const std::string& name) {
|
void SetAppName (const std::string& name) {
|
||||||
appName = name;
|
appName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & GetDataDir () {
|
const std::string & GetDataDir () {
|
||||||
return dataDir;
|
return dataDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
||||||
if (cmdline_param != "") {
|
if (cmdline_param != "") {
|
||||||
dataDir = cmdline_param;
|
dataDir = cmdline_param;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if defined(WIN32) || defined(_WIN32)
|
#if defined(WIN32) || defined(_WIN32)
|
||||||
char localAppData[MAX_PATH];
|
char localAppData[MAX_PATH];
|
||||||
// check executable directory first
|
|
||||||
GetModuleFileName (NULL, localAppData, MAX_PATH);
|
// check executable directory first
|
||||||
auto execPath = boost::filesystem::path(localAppData).parent_path();
|
if(!GetModuleFileName(NULL, localAppData, MAX_PATH))
|
||||||
// if config file exists in .exe's folder use it
|
{
|
||||||
if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
|
#if defined(WIN32_APP)
|
||||||
dataDir = execPath.string ();
|
MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
||||||
else
|
#else
|
||||||
{
|
fprintf(stderr, "Error: Unable to get application path!");
|
||||||
// otherwise %appdata%
|
#endif
|
||||||
SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData);
|
exit(1);
|
||||||
dataDir = std::string(localAppData) + "\\" + appName;
|
}
|
||||||
}
|
else
|
||||||
return;
|
{
|
||||||
|
auto execPath = boost::filesystem::path(localAppData).parent_path();
|
||||||
|
|
||||||
|
// if config file exists in .exe's folder use it
|
||||||
|
if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
|
||||||
|
dataDir = execPath.string ();
|
||||||
|
else // otherwise %appdata%
|
||||||
|
{
|
||||||
|
if(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
|
||||||
|
{
|
||||||
|
#if defined(WIN32_APP)
|
||||||
|
MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Error: Unable to get AppData path!");
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dataDir = std::string(localAppData) + "\\" + appName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
#elif defined(MAC_OSX)
|
#elif defined(MAC_OSX)
|
||||||
char *home = getenv("HOME");
|
char *home = getenv("HOME");
|
||||||
dataDir = (home != NULL && strlen(home) > 0) ? home : "";
|
dataDir = (home != NULL && strlen(home) > 0) ? home : "";
|
||||||
dataDir += "/Library/Application Support/" + appName;
|
dataDir += "/Library/Application Support/" + appName;
|
||||||
return;
|
return;
|
||||||
#else /* other unix */
|
#else /* other unix */
|
||||||
#if defined(ANDROID)
|
#if defined(ANDROID)
|
||||||
const char * ext = getenv("EXTERNAL_STORAGE");
|
const char * ext = getenv("EXTERNAL_STORAGE");
|
||||||
if (!ext) ext = "/sdcard";
|
if (!ext) ext = "/sdcard";
|
||||||
if (boost::filesystem::exists(ext))
|
if (boost::filesystem::exists(ext))
|
||||||
{
|
{
|
||||||
dataDir = std::string (ext) + "/" + appName;
|
dataDir = std::string (ext) + "/" + appName;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// otherwise use /data/files
|
||||||
|
char *home = getenv("HOME");
|
||||||
|
if (isService) {
|
||||||
|
dataDir = "/var/lib/" + appName;
|
||||||
|
} else if (home != NULL && strlen(home) > 0) {
|
||||||
|
dataDir = std::string(home) + "/." + appName;
|
||||||
|
} else {
|
||||||
|
dataDir = "/tmp/" + appName;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// otherwise use /data/files
|
|
||||||
#endif
|
|
||||||
char *home = getenv("HOME");
|
|
||||||
if (isService) {
|
|
||||||
dataDir = "/var/lib/" + appName;
|
|
||||||
} else if (home != NULL && strlen(home) > 0) {
|
|
||||||
dataDir = std::string(home) + "/." + appName;
|
|
||||||
} else {
|
|
||||||
dataDir = "/tmp/" + appName;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Init() {
|
bool Init() {
|
||||||
if (!boost::filesystem::exists(dataDir))
|
if (!boost::filesystem::exists(dataDir))
|
||||||
boost::filesystem::create_directory(dataDir);
|
boost::filesystem::create_directory(dataDir);
|
||||||
std::string destinations = DataDirPath("destinations");
|
|
||||||
if (!boost::filesystem::exists(destinations))
|
|
||||||
boost::filesystem::create_directory(destinations);
|
|
||||||
std::string tags = DataDirPath("tags");
|
|
||||||
if (!boost::filesystem::exists(tags))
|
|
||||||
boost::filesystem::create_directory(tags);
|
|
||||||
else
|
|
||||||
i2p::garlic::CleanUpTagsFiles ();
|
|
||||||
|
|
||||||
return true;
|
std::string destinations = DataDirPath("destinations");
|
||||||
}
|
if (!boost::filesystem::exists(destinations))
|
||||||
|
boost::filesystem::create_directory(destinations);
|
||||||
|
|
||||||
bool ReadDir(const std::string & path, std::vector<std::string> & files) {
|
std::string tags = DataDirPath("tags");
|
||||||
if (!boost::filesystem::exists(path))
|
if (!boost::filesystem::exists(tags))
|
||||||
return false;
|
boost::filesystem::create_directory(tags);
|
||||||
boost::filesystem::directory_iterator it(path);
|
else
|
||||||
boost::filesystem::directory_iterator end;
|
i2p::garlic::CleanUpTagsFiles ();
|
||||||
|
|
||||||
for ( ; it != end; it++) {
|
return true;
|
||||||
if (!boost::filesystem::is_regular_file(it->status()))
|
}
|
||||||
continue;
|
|
||||||
files.push_back(it->path().string());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
bool ReadDir(const std::string & path, std::vector<std::string> & files) {
|
||||||
}
|
if (!boost::filesystem::exists(path))
|
||||||
|
return false;
|
||||||
|
boost::filesystem::directory_iterator it(path);
|
||||||
|
boost::filesystem::directory_iterator end;
|
||||||
|
|
||||||
bool Exists(const std::string & path) {
|
for ( ; it != end; it++) {
|
||||||
return boost::filesystem::exists(path);
|
if (!boost::filesystem::is_regular_file(it->status()))
|
||||||
}
|
continue;
|
||||||
|
files.push_back(it->path().string());
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t GetLastUpdateTime (const std::string & path)
|
return true;
|
||||||
{
|
}
|
||||||
if (!boost::filesystem::exists(path)) return 0;
|
|
||||||
boost::system::error_code ec;
|
|
||||||
auto t = boost::filesystem::last_write_time (path, ec);
|
|
||||||
return ec ? 0 : t;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Remove(const std::string & path) {
|
bool Exists(const std::string & path) {
|
||||||
if (!boost::filesystem::exists(path))
|
return boost::filesystem::exists(path);
|
||||||
return false;
|
}
|
||||||
return boost::filesystem::remove(path);
|
|
||||||
}
|
uint32_t GetLastUpdateTime (const std::string & path)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::exists(path))
|
||||||
|
return 0;
|
||||||
|
boost::system::error_code ec;
|
||||||
|
auto t = boost::filesystem::last_write_time (path, ec);
|
||||||
|
return ec ? 0 : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Remove(const std::string & path) {
|
||||||
|
if (!boost::filesystem::exists(path))
|
||||||
|
return false;
|
||||||
|
return boost::filesystem::remove(path);
|
||||||
|
}
|
||||||
|
|
||||||
bool CreateDirectory (const std::string& path)
|
bool CreateDirectory (const std::string& path)
|
||||||
{
|
{
|
||||||
if (boost::filesystem::exists(path) &&
|
if (boost::filesystem::exists(path) && boost::filesystem::is_directory (boost::filesystem::status (path)))
|
||||||
boost::filesystem::is_directory (boost::filesystem::status (path))) return true;
|
return true;
|
||||||
return boost::filesystem::create_directory(path);
|
return boost::filesystem::create_directory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashedStorage::SetPlace(const std::string &path) {
|
void HashedStorage::SetPlace(const std::string &path) {
|
||||||
root = path + i2p::fs::dirSep + name;
|
root = path + i2p::fs::dirSep + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HashedStorage::Init(const char * chars, size_t count) {
|
bool HashedStorage::Init(const char * chars, size_t count) {
|
||||||
if (!boost::filesystem::exists(root)) {
|
if (!boost::filesystem::exists(root)) {
|
||||||
boost::filesystem::create_directories(root);
|
boost::filesystem::create_directories(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
auto p = root + i2p::fs::dirSep + prefix1 + chars[i];
|
auto p = root + i2p::fs::dirSep + prefix1 + chars[i];
|
||||||
if (boost::filesystem::exists(p))
|
if (boost::filesystem::exists(p))
|
||||||
continue;
|
continue;
|
||||||
if (boost::filesystem::create_directory(p))
|
if (boost::filesystem::create_directory(p))
|
||||||
continue; /* ^ throws exception on failure */
|
continue; /* ^ throws exception on failure */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HashedStorage::Path(const std::string & ident) const {
|
std::string HashedStorage::Path(const std::string & ident) const {
|
||||||
std::string safe_ident = ident;
|
std::string safe_ident = ident;
|
||||||
std::replace(safe_ident.begin(), safe_ident.end(), '/', '-');
|
std::replace(safe_ident.begin(), safe_ident.end(), '/', '-');
|
||||||
std::replace(safe_ident.begin(), safe_ident.end(), '\\', '-');
|
std::replace(safe_ident.begin(), safe_ident.end(), '\\', '-');
|
||||||
|
|
||||||
std::stringstream t("");
|
std::stringstream t("");
|
||||||
t << this->root << i2p::fs::dirSep;
|
t << this->root << i2p::fs::dirSep;
|
||||||
t << prefix1 << safe_ident[0] << i2p::fs::dirSep;
|
t << prefix1 << safe_ident[0] << i2p::fs::dirSep;
|
||||||
t << prefix2 << safe_ident << "." << suffix;
|
t << prefix2 << safe_ident << "." << suffix;
|
||||||
|
|
||||||
return t.str();
|
return t.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashedStorage::Remove(const std::string & ident) {
|
void HashedStorage::Remove(const std::string & ident) {
|
||||||
std::string path = Path(ident);
|
std::string path = Path(ident);
|
||||||
if (!boost::filesystem::exists(path))
|
if (!boost::filesystem::exists(path))
|
||||||
return;
|
return;
|
||||||
boost::filesystem::remove(path);
|
boost::filesystem::remove(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashedStorage::Traverse(std::vector<std::string> & files) {
|
void HashedStorage::Traverse(std::vector<std::string> & files) {
|
||||||
Iterate([&files] (const std::string & fname) {
|
Iterate([&files] (const std::string & fname) {
|
||||||
files.push_back(fname);
|
files.push_back(fname);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashedStorage::Iterate(FilenameVisitor v)
|
void HashedStorage::Iterate(FilenameVisitor v)
|
||||||
{
|
{
|
||||||
boost::filesystem::path p(root);
|
boost::filesystem::path p(root);
|
||||||
boost::filesystem::recursive_directory_iterator it(p);
|
boost::filesystem::recursive_directory_iterator it(p);
|
||||||
boost::filesystem::recursive_directory_iterator end;
|
boost::filesystem::recursive_directory_iterator end;
|
||||||
|
|
||||||
for ( ; it != end; it++) {
|
for ( ; it != end; it++) {
|
||||||
if (!boost::filesystem::is_regular_file( it->status() ))
|
if (!boost::filesystem::is_regular_file( it->status() ))
|
||||||
continue;
|
continue;
|
||||||
const std::string & t = it->path().string();
|
const std::string & t = it->path().string();
|
||||||
v(t);
|
v(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // fs
|
} // fs
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace fs {
|
|||||||
|
|
||||||
/** @brief Returns current application name, default 'i2pd' */
|
/** @brief Returns current application name, default 'i2pd' */
|
||||||
const std::string & GetAppName ();
|
const std::string & GetAppName ();
|
||||||
/** @brief Set applicaton name, affects autodetection of datadir */
|
/** @brief Set application name, affects autodetection of datadir */
|
||||||
void SetAppName (const std::string& name);
|
void SetAppName (const std::string& name);
|
||||||
|
|
||||||
/** @brief Returns datadir path */
|
/** @brief Returns datadir path */
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ namespace data
|
|||||||
i2p::crypto::bn2buf (x, signingKey, 32);
|
i2p::crypto::bn2buf (x, signingKey, 32);
|
||||||
i2p::crypto::bn2buf (y, signingKey + 32, 32);
|
i2p::crypto::bn2buf (y, signingKey + 32, 32);
|
||||||
BN_free (x); BN_free (y);
|
BN_free (x); BN_free (y);
|
||||||
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>(signingKey);
|
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>();
|
||||||
|
verifier->SetPublicKey (signingKey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
||||||
|
|||||||
@@ -578,7 +578,7 @@ namespace garlic
|
|||||||
tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
|
tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
||||||
if (tunnel) // we have send it through an outbound tunnel
|
if (tunnel) // we have sent it through an outbound tunnel
|
||||||
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
|
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <openssl/bn.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
|
|||||||
@@ -55,12 +55,16 @@ namespace http {
|
|||||||
static std::pair<std::string, std::string> parse_header_line(const std::string& line)
|
static std::pair<std::string, std::string> parse_header_line(const std::string& line)
|
||||||
{
|
{
|
||||||
std::size_t pos = 0;
|
std::size_t pos = 0;
|
||||||
std::size_t len = 2; /* strlen(": ") */
|
std::size_t len = 1; /*: */
|
||||||
std::size_t max = line.length();
|
std::size_t max = line.length();
|
||||||
if ((pos = line.find(": ", pos)) == std::string::npos)
|
if ((pos = line.find(':', pos)) == std::string::npos)
|
||||||
return std::make_pair("", "");
|
return std::make_pair("", ""); // no ':' found
|
||||||
while ((pos + len) < max && isspace(line.at(pos + len)))
|
if (pos + 1 < max) // ':' at the end of header is valid
|
||||||
len++;
|
{
|
||||||
|
while ((pos + len) < max && isspace(line.at(pos + len)))
|
||||||
|
len++;
|
||||||
|
if (len == 1) return std::make_pair("", ""); // no following space, but something else
|
||||||
|
}
|
||||||
return std::make_pair(line.substr(0, pos), line.substr(pos + len));
|
return std::make_pair(line.substr(0, pos), line.substr(pos + len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user