Compare commits

..

168 Commits

Author SHA1 Message Date
R4SAS
779228857e 2.22.0 2018-11-09 02:22:55 +00:00
R4SAS
8d0b696d33 packages - tunnels.conf.d fix configs place, links 2018-11-07 18:41:04 +03:00
R4SAS
b7940e0002 add tunnels.d to packages 2018-11-06 20:04:26 +03:00
orignal
b3fd8bd0ae check if keys are available before sending termination message 2018-11-04 18:51:25 -05:00
orignal
bffeb237de termination might be send for non-established session 2018-11-04 15:32:31 -05:00
orignal
23e3602ea1 common MixHash 2018-11-01 16:06:39 -04:00
orignal
34cfd205f6 create new static keys by X25519Keys 2018-11-01 10:43:31 -04:00
l-n-s
df3da8be7a Merge pull request #1264 from l-n-s/desktop
fix appdata manifest
2018-10-31 17:24:39 +00:00
l-n-s
940243f45e fix appdata manifest 2018-10-31 13:23:13 -04:00
l-n-s
75d6599143 Update desktop files (#1263)
* Rename files to freedesktop standarts

* Add application icons
2018-10-31 12:23:16 +00:00
l-n-s
929a27a5ac Add Desktop files (#1261)
* Add appstream and desktop files

* More metadata in appstream file
2018-10-30 07:48:02 +00:00
orignal
82ddee2104 Merge pull request #1260 from l-n-s/version_display
Add --version flag to display i2pd and system libraries versions
2018-10-28 11:01:46 -04:00
l-n-s
a141678119 Add --version flag to display i2pd and system libraries versions 2018-10-28 10:52:22 -04:00
orignal
96d109af81 fixed typo 2018-10-27 19:55:23 -04:00
orignal
a309eb9f3c faster CipherBlock XOR implementation for non-AVX 2018-10-27 18:41:05 -04:00
orignal
d034dab265 fill m3p2 with SessionRequest 2018-10-26 09:58:18 -04:00
orignal
883a035e5c Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2018-10-22 12:26:49 -04:00
orignal
08603091c5 2.21.1 2018-10-22 14:21:52 +00:00
orignal
a2e84e5a1e 2.21.1 2018-10-22 09:19:39 -04:00
orignal
9439621849 fixed #1259. read extra tunnels from tunnels.d 2018-10-19 15:23:46 -04:00
orignal
15ded89618 set cost=14 for unpublished NTCP2 addresses 2018-10-11 13:00:37 -04:00
orignal
b84f74c167 limit SSU message size to 32K 2018-10-11 11:17:14 -04:00
orignal
a97300f8be fixed #1256 I2NP messages up to 64K 2018-10-10 11:31:55 -04:00
orignal
9e12cff317 fix #1253 handle incorrect values of SIGNATURE_TYPE and CRYPTO_TYPE 2018-10-08 15:03:41 -04:00
R4SAS
ecdf1f4ddc updated debian patches, add patch disabling few settings in service file, fix name in control file 2018-10-05 13:44:18 +00:00
orignal
2fa7a48163 2.21.0 2018-10-04 10:17:33 -04:00
orignal
8adf76dcc9 2.21.0 2018-10-04 09:46:10 -04:00
orignal
15899c10b2 2.21.0 2018-10-04 09:38:04 -04:00
orignal
05ff05ea4b Merge pull request #1246 from 3pdotsif/openssl
added NTCP2 to qt.pro ; fix for #1111
2018-10-02 11:33:07 -04:00
3p.sif
bd62df48c2 added NTCP2 to qt.pro ; made tunnel conf param keys be optional (fixes #1111) 2018-10-02 23:09:01 +08:00
R4SAS
2366cbc833 count outgoing tags 2018-10-01 18:11:44 +03:00
R4SAS
25fb609544 [appveyor] make it work again
Temporary fix. Read: https://github.com/Alexpux/MSYS2-packages/issues/1428
Waiting for https://github.com/Alexpux/MSYS2-packages/pull/1430
2018-09-30 23:24:48 +03:00
orignal
af793395f0 don't publish O with X or P 2018-09-30 16:08:26 -04:00
orignal
8f41776858 check send queue size 2018-09-28 09:54:42 -04:00
orignal
139b13b8d1 openssl 1.1.1/boost 1.64 for andoroid binary only 2018-09-27 10:31:32 -04:00
orignal
4c611a5be1 Merge pull request #1243 from PurpleI2P/android-26up-service
try to fix working of service on api 26+
2018-09-25 11:42:34 -04:00
R4SAS
5e7a21e177 try to fix working of service on api 26+ 2018-09-25 03:37:34 +03:00
orignal
5f7dda5ba8 treat extra bandwidth as high bandwidth 2018-09-22 14:12:46 -04:00
orignal
2dfa1ca0f2 check RouterInfo's timestamp in SessionConfirmed 2018-09-21 11:45:04 -04:00
orignal
358cdcf4c4 removed RSA signatures completly 2018-09-21 11:16:38 -04:00
orignal
c8f4ace5c4 update timestamp before publishing 2018-09-21 10:13:18 -04:00
orignal
5cac6ca8bb read message body immediatly after length 2018-09-17 13:08:49 -04:00
orignal
fccad71df1 temporary buffer for EdDSA signature for openssl 1.1.1 2018-09-16 18:08:59 -04:00
orignal
97ae2674dc always use EdDsa signer fallback 2018-09-14 21:54:45 -04:00
orignal
7c70affd7f eddsa signer fallback 2018-09-14 21:23:16 -04:00
orignal
52ff568d86 fixed incorrect second signature 2018-09-14 18:58:40 -04:00
orignal
b917aeaa0b openssl 1.1.1/boost 1.64 for android 2018-09-13 09:43:10 -04:00
orignal
8de443ec4c siphash from openssl 1.1.1 2018-09-11 13:26:29 -04:00
orignal
7d9893c614 fixed build error 2018-09-09 17:27:53 -04:00
orignal
3540712517 some cleanup 2018-09-09 08:38:12 -04:00
orignal
a8b1a86bd7 X25519Keys for static key 2018-09-08 22:08:08 -04:00
orignal
1babd3a5a2 separate X25519Keys 2018-09-08 16:52:42 -04:00
l-n-s
50399e5194 fix #1238 (#1239) 2018-09-06 21:27:28 +00:00
orignal
b734acf1b1 -latomic for gcc >= 5 only 2018-09-06 11:19:10 -04:00
orignal
33aa8e2471 use x25519 from openssl 1.1.1 for ephemeral keys 2018-09-05 11:19:58 -04:00
orignal
2c58fe736b fixed build error with openssl 1.1.1 2018-09-05 09:51:03 -04:00
R4SAS
6fe1de5d86 fix make target dependecy 2018-09-04 10:51:44 +03:00
R4SAS
064460b95f osx makefile changes
Move install target from osx to homebrew
use openssl 1.1.0 when building with brew
2018-09-04 10:39:46 +03:00
orignal
2c3b19a539 use EdDSA from openssl 1.1.1 2018-09-03 17:39:49 -04:00
orignal
dc30a4c1ae Merge pull request #1234 from l-n-s/fix_typo
Fix typo
2018-09-02 15:50:22 -04:00
l-n-s
86e9901bf2 Fix typo 2018-09-02 15:39:23 -04:00
orignal
6519e0835a fixed typo 2018-09-02 07:51:58 -04:00
orignal
a52344fc01 Merge pull request #1226 from radfish/PR--make-latomic
makefile: linux: add -latomic
2018-09-01 13:31:17 -04:00
orignal
b67424643d done insert NTCP2 ipv6 address twice 2018-08-27 18:56:57 -04:00
orignal
575a4c01c9 publish NTCP2 adress if port is specified 2018-08-27 18:35:35 -04:00
orignal
f0d4ee6618 pass NTCP2 ipv6 address 2018-08-27 16:01:47 -04:00
orignal
8753186a0d publish NTCP2 ipv6 address if applicable 2018-08-27 15:01:43 -04:00
orignal
ff8fb8000d Merge pull request #1231 from majestrate/fix-socks-outproxy
enable outproxy on socks
2018-08-26 10:20:39 -04:00
orignal
9dd38b99d6 check NTCP2 for addreses comparison 2018-08-26 09:40:27 -04:00
Jeff Becker
dfe08c1ec9 enable outproxy on socks 2018-08-26 09:24:11 -04:00
orignal
062d8d0f4f fixed potential race condition 2018-08-25 13:27:03 -04:00
r4sas
c0d1e2c07a 2.20 2018-08-23 18:10:05 +03:00
r4sas
e70feceafe add install target in OSX Makefile for homebrew formula 2018-08-23 18:06:37 +03:00
orignal
71ac0286b1 2.20.0 2018-08-23 10:24:44 -04:00
orignal
022f4d2c11 don't send message to not established session 2018-08-23 07:23:50 -04:00
l-n-s
a83a839cff Build docker image from openssl branch 2018-08-22 18:22:54 -04:00
orignal
b259ee89aa send RouterInfo from NTCP2Server's thread 2018-08-22 12:33:43 -04:00
r4sas
65cf14bfce update android miniupnpc to 2.1 2018-08-20 01:01:27 +03:00
orignal
d9476fb5ca set correct IV when NTCP2 address gets published 2018-08-19 16:17:57 -04:00
r4sas
9882365ab4 fix NTCP IPv6 category name in transports, add conversion for leasesets expiring time 2018-08-18 22:56:31 +00:00
orignal
2d758ce963 change cost for NTCP and NTCP2 2018-08-18 13:52:35 -04:00
orignal
1dd003d26a check m2p3len 2018-08-18 08:27:36 -04:00
redfish
0df5b77595 makefile: linux: add -latomic
Tested on Arch Linux and Debian unstable with gcc 8.2.0. On Arch Linux
on x86_64 it built without this, but also builds with this. Without this
patch On Debian unstable on PPC linking fail with undefined symbols:
/usr/include/c++/8/bits/atomic_base.h:396: undefined reference to `__atomic_load_8'
2018-08-17 23:24:37 -04:00
orignal
e190a005db make sure assets are ready before proceed 2018-08-17 11:17:17 -04:00
r4sas
45596a0342 android - holder-based updater for certificate
If holder exsists, check string (version) of assets creation.
If it differs from current app version or null, try delete certificates forder contents
for unpacking new certificates.
2018-08-17 01:41:26 +03:00
r4sas
405429a300 android - add file for notify about successful unpacking assets 2018-08-16 23:34:05 +03:00
r4sas
d009a29426 android - dont rewrite files from assets if they exist 2018-08-16 23:34:04 +03:00
r4sas
f1fb42460a rename ipv6 transports 2018-08-16 23:34:04 +03:00
orignal
5e110e9f7b enable NTCP2 by default 2018-08-16 13:48:47 -04:00
orignal
77a409935d license added 2018-08-16 13:46:59 -04:00
orignal
863baeb68b ignore unpublished addresses 2018-08-16 11:02:53 -04:00
orignal
11142690a0 show correct value of time drift 2018-08-16 10:13:32 -04:00
orignal
02e8c5faca fixed typo 2018-08-15 13:23:10 -04:00
orignal
c41081d35c check timestamps 2018-08-15 11:42:56 -04:00
orignal
db4c26a400 copy assets before daemon start 2018-08-15 09:52:13 -04:00
r4sas
331a23fc20 build JNI for arm v7a and x86 both 2018-08-14 22:44:08 +03:00
r4sas
db5a40d743 enable NTCP2 for android, use L flag for bandwidth,
additional change for multiarch build
2018-08-14 22:41:12 +03:00
orignal
e4ab51329d move handshake messages processing to NTCP2Establisher 2018-08-14 14:01:04 -04:00
orignal
86782aeb1b don't send RouterInfo twice 2018-08-14 11:27:27 -04:00
orignal
49a44fc92e assume siphash IV in Litte Endian 2018-08-13 14:07:57 -04:00
orignal
cd39a52c25 correct endianness for siphash length 2018-08-13 13:43:51 -04:00
xcps
634101ceb5 Update HTTPServer.cpp
Fix transport sections in web interface 2
2018-08-13 22:29:58 +05:00
orignal
55555c8787 Merge pull request #1222 from PurpleI2P/show-transports
Update HTTPServer.cpp
2018-08-13 12:43:31 -04:00
xcps
d36d825ac1 Update HTTPServer.cpp
Fix transport sections in web interface
2018-08-13 21:41:43 +05:00
orignal
9bb01cd67c Merge pull request #1221 from l-n-s/issue_1220
Don't add SSU/NTCP addresses to RI if they are disabled in config
2018-08-12 13:19:56 -04:00
l-n-s
29b91075d2 Don't add SSU/NTCP addresses to RI if they are disabled in config (#1220) 2018-08-12 02:36:00 -04:00
orignal
6d46fc9f9f check send frame error code 2018-08-11 16:08:21 -04:00
orignal
a2c41c9e36 allow NTCP2 only transports 2018-08-10 15:35:43 -04:00
orignal
ee700ac861 fixed incorrect iv for published NTCP2 addresses 2018-08-10 15:14:07 -04:00
orignal
9884a4336f don't connect to NTCP2 only address using NTCP 2018-08-10 13:42:59 -04:00
orignal
5b83d4bef8 move handshake messages creation to NTCP2Establisher 2018-08-10 10:53:34 -04:00
orignal
d320a89590 don't copy buffer to ifself 2018-08-09 16:32:43 -04:00
orignal
f7e4afc282 use same buffer for input and output for AEAD/Chacha20/Poly1305 2018-08-09 15:47:02 -04:00
orignal
88e87d589b add incoming NTCP2 session to the sessions list 2018-08-09 14:20:10 -04:00
orignal
d8c6dede7e moved NTCP2 handshake buffers to establisher 2018-08-09 12:53:36 -04:00
orignal
5cc84133e3 fixed incorrect lenght 2018-08-08 17:38:21 -04:00
orignal
f7728aa1f6 reuse NTCP2 frame buffers 2018-08-08 16:23:44 -04:00
orignal
2b61f9a731 fixed #1217. verify decryption result 2018-08-07 10:35:25 -04:00
orignal
f407022fe6 connect to NTCP2 address if presented 2018-08-04 13:48:09 -04:00
orignal
41b9f19b01 get unpublished NTCP2 address 2018-08-04 08:47:58 -04:00
orignal
09c6faf923 don't overwrite NTCP2 keys 2018-08-03 21:16:35 -04:00
orignal
26d0177c01 always make NTCP address first 2018-08-03 20:28:29 -04:00
orignal
f7415c8a8f enable/disable NTCP2 address 2018-08-03 14:49:28 -04:00
orignal
4cf79088f9 NTCP2 idle timeout 2018-08-03 13:19:35 -04:00
orignal
50cd321818 NTCP2 idle timeout 2018-08-03 13:10:32 -04:00
orignal
83bbe6a9d9 show NTCP2 address 2018-08-03 12:07:09 -04:00
orignal
0a33c18e36 send termination message 2018-08-02 15:31:15 -04:00
orignal
6cf158ac63 check RouterInfo from SessionConfirmed 2018-08-02 13:58:47 -04:00
orignal
f96bfa6afa send RouterInfo 2018-08-02 12:42:39 -04:00
orignal
2b64cf9126 publish i in correct place for NTCP2 2018-08-01 12:28:34 -04:00
orignal
a8dcfc44f5 handle termination message 2018-08-01 09:43:48 -04:00
orignal
0ff9c9da27 complete Bob side of NTCP2 2018-07-31 15:41:13 -04:00
orignal
07e7c2d852 ntcp2.published and ntcp2.port parameters 2018-07-31 12:59:38 -04:00
orignal
10e4b5b2a3 ignore NTCP2 addresses 2018-07-23 15:44:36 -04:00
orignal
998653ea9d NTCP2 acceptors 2018-07-23 15:30:51 -04:00
orignal
1a38e925bf publish NTCP2 address 2018-07-23 13:51:29 -04:00
orignal
c8f51380e6 publish NTCP2 for new routers 2018-07-21 16:59:58 -04:00
R4SAS
2406d57d51 update android target API to 28, use gradle and ndk parallel building 2018-07-21 00:02:54 +03:00
R4SAS
cb1e47eb71 use preconfigured configs for android package 2018-07-20 23:15:22 +03:00
R4SAS
c0a650f28b update gitignore 2018-07-20 23:04:29 +03:00
R4SAS
460cf6fd20 update windows build script, change makefile.mingw line ending 2018-07-20 22:57:47 +03:00
orignal
5bedfc1c84 post I2NP messages to NTCP2 thread 2018-07-19 12:46:19 -04:00
orignal
5001592fb4 replace ntcp2 by ntcp2.enabled 2018-07-19 09:45:24 -04:00
orignal
f6495e59c5 better MixHash 2018-07-19 09:27:59 -04:00
orignal
66bf431481 correct KDF1 calculation 2018-07-18 16:27:43 -04:00
orignal
d9685e991e handle RouterInfo block 2018-07-18 15:57:18 -04:00
orignal
e0790700cd don't connect to unpublished NTCP2 addresses 2018-07-18 14:19:12 -04:00
orignal
910a9600bd display NTCP2 session in web console 2018-07-18 12:58:29 -04:00
orignal
fc52b2b940 fixed typo 2018-07-18 12:56:46 -04:00
orignal
b99f828583 send I2NP messages through NTCP2 2018-07-18 11:16:40 -04:00
orignal
f38891cace fixed build for gcc < 4.8 2018-07-18 11:15:27 -04:00
orignal
8c5111e11a handle NTCP2 I2NP messages 2018-07-17 15:17:05 -04:00
orignal
5575b981c8 enable NTCP2 as transport 2018-07-13 15:59:28 -04:00
orignal
0b36732911 Merge pull request #1212 from yangfl/upstream
fix typo
2018-07-10 06:59:35 -04:00
yangfl
52f3081a40 fix typo 2018-07-10 17:39:21 +08:00
orignal
00c71dc26a handle SessionConfirmed 2018-07-09 15:56:23 -04:00
orignal
5218c8584f some refactoring of NTCP2 code 2018-07-04 14:15:40 -04:00
orignal
6054bd6621 NTCP2 session establisher 2018-07-03 16:26:02 -04:00
R4SAS
55af4ed385 delete old AESNI definition 2018-06-29 02:30:03 +03:00
R4SAS
64aee9c8ae add DEBUG option for make
By default, binary will be built without stripping debug symbols
2018-06-29 02:27:19 +03:00
r4sas
5233e72205 add assets symlinks 2018-06-27 23:56:52 +03:00
R4SAS
db5b45222a store and install assets on android 2018-06-27 23:56:52 +03:00
orignal
fc4787da4e Merge pull request #1207 from AMDmi3/defined-in-macro
Fix "macro expansion producing 'defined' has undefined behavior" clang warning
2018-06-27 15:36:34 -04:00
Dmitry Marakasov
4ffbb46cf9 Fix "macro expansion producing 'defined' has undefined behavior" clang warning 2018-06-27 22:31:01 +03:00
orignal
c3c2550f17 Merge pull request #1205 from AMDmi3/fix-cpp-lib
Limit tampering with standard C++ library to Linux
2018-06-27 11:01:22 -04:00
Dmitry Marakasov
41e8ab5383 Limit tampering with standard C++ library to Linux
Otherwise it breaks e.g. FreeBSD build where it is not needed at all
2018-06-27 17:47:22 +03:00
orignal
a802940616 Merge pull request #1204 from yangfl/upstream
use builtin __AVX__ and __AES__ macros and reduce code duplication
2018-06-27 07:08:26 -04:00
yangfl
dec848f072 use builtin __AVX__ and __AES__ macros and reduce code duplication 2018-06-27 17:32:38 +08:00
108 changed files with 3251 additions and 1456 deletions

2
.gitignore vendored
View File

@@ -8,7 +8,7 @@ netDb
/i2pd /i2pd
/libi2pd.a /libi2pd.a
/libi2pdclient.a /libi2pdclient.a
i2pd.exe *.exe
# Autotools # Autotools

View File

@@ -1,6 +1,46 @@
# 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.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 +108,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 +208,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

View File

@@ -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
@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)
@@ -21,8 +21,10 @@ 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-7]\.[0-9]"),3) # gcc >= 5.0
NEEDED_CXXFLAGS += -std=c++11 NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "[7-8]"),1) # gcc 7 ubuntu or gcc 8 arch 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 +36,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 +46,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 +66,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

View File

@@ -1,11 +1,11 @@
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 BOOST_SUFFIX = -mt
INCFLAGS = -Idaemon -I. INCFLAGS = -Idaemon -I.
LDFLAGS = -s -Wl,-rpath,/usr/local/lib -Wl,-Bstatic -static-libgcc -static-libstdc++ LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++
# UPNP Support # UPNP Support
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
@@ -37,7 +37,7 @@ endif
# don't change following line to ifeq ($(USE_AESNI),yes) !!! # don't change following line to ifeq ($(USE_AESNI),yes) !!!
ifeq ($(USE_AESNI),1) ifeq ($(USE_AESNI),1)
CPU_FLAGS += -maes -DAESNI CPU_FLAGS += -maes
else else
CPU_FLAGS += -msse CPU_FLAGS += -msse
endif endif

View File

@@ -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}/

View File

@@ -1,5 +1,5 @@
#define I2Pd_AppName "i2pd" #define I2Pd_AppName "i2pd"
#define I2Pd_ver "2.19.0" #define I2Pd_ver "2.22.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

9
android/.gitignore vendored
View File

@@ -1,12 +1,15 @@
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 gradle

View File

@@ -3,17 +3,18 @@
package="org.purplei2p.i2pd" package="org.purplei2p.i2pd"
android:installLocation="auto" android:installLocation="auto"
android:versionCode="1" android:versionCode="1"
android:versionName="2.19.0"> android:versionName="2.22.0">
<uses-sdk <uses-sdk
android:minSdkVersion="14" android:minSdkVersion="14"
android:targetSdkVersion="25" /> android:targetSdkVersion="28" />
<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" /> <!-- normal perm, per https://developer.android.com/guide/topics/permissions/normal-permissions.html -->
<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" /> <!-- normal perm -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- required in API 26+ -->
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/icon" android:icon="@drawable/icon"

1
android/assets/certificates Symbolic link
View File

@@ -0,0 +1 @@
../../contrib/certificates

82
android/assets/i2pd.conf Normal file
View File

@@ -0,0 +1,82 @@
## 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
# keys = http-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 = socks-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

View 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

View 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
View File

@@ -0,0 +1 @@
../../contrib/tunnels.d

View File

@@ -17,18 +17,27 @@ repositories {
} }
} }
dependencies {
compile 'com.android.support:support-compat:28.0.0'
}
android { android {
compileSdkVersion 25 compileSdkVersion 28
buildToolsVersion "25.0.3" buildToolsVersion "28.0.1"
defaultConfig { defaultConfig {
applicationId "org.purplei2p.i2pd" applicationId "org.purplei2p.i2pd"
targetSdkVersion 25 targetSdkVersion 28
minSdkVersion 14 minSdkVersion 14
versionCode 1 versionCode 1
versionName "2.19.0" versionName "2.22.0"
ndk { ndk {
abiFilters 'armeabi-v7a' abiFilters 'armeabi-v7a'
//abiFilters 'x86' abiFilters 'x86'
}
externalNativeBuild {
ndkBuild {
arguments "-j4"
}
} }
} }
sourceSets { sourceSets {
@@ -37,6 +46,7 @@ android {
java.srcDirs = ['src'] java.srcDirs = ['src']
res.srcDirs = ['res'] res.srcDirs = ['res']
jniLibs.srcDirs = ['libs'] jniLibs.srcDirs = ['libs']
assets.srcDirs = ['assets']
} }
} }
signingConfigs { signingConfigs {

View File

@@ -0,0 +1 @@
org.gradle.parallel=true

View File

@@ -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_64_0/$(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_64_0/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_64_0/$(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_64_0/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_64_0/$(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_64_0/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_64_0/$(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_64_0/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.1/$(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.1/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.1/$(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.1/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)

View File

@@ -1,8 +1,8 @@
#APP_ABI := all #APP_ABI := all
#APP_ABI := armeabi-v7a x86 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
#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

View File

@@ -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
{ {
@@ -80,6 +83,17 @@ 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("", 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);
} }

View File

@@ -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

1
android/settings.gradle Normal file
View File

@@ -0,0 +1 @@
rootProject.name = "i2pd"

View File

@@ -1,12 +1,17 @@
package org.purplei2p.i2pd; package org.purplei2p.i2pd;
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;
@@ -104,9 +109,16 @@ public class ForegroundService extends Service {
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, I2PDActivity.class), 0); new Intent(this, I2PDActivity.class), 0);
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
String channelId = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? createNotificationChannel() : "";
// Set the info for the views that show in the notification panel. // Set the info for the views that show in the notification panel.
Notification notification = new Notification.Builder(this) Notification notification = new NotificationCompat.Builder(this, channelId)
.setOngoing(true)
.setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon .setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon
.setPriority(Notification.PRIORITY_DEFAULT)
.setCategory(Notification.CATEGORY_SERVICE)
.setTicker(text) // the status text .setTicker(text) // the status text
.setWhen(System.currentTimeMillis()) // the time stamp .setWhen(System.currentTimeMillis()) // the time stamp
.setContentTitle(getText(R.string.app_name)) // the label of the entry .setContentTitle(getText(R.string.app_name)) // the label of the entry
@@ -120,6 +132,18 @@ public class ForegroundService extends Service {
shown = true; 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();
} }

View File

@@ -1,5 +1,13 @@
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;
@@ -10,7 +18,9 @@ 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.os.Bundle; import android.os.Bundle;
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;
@@ -18,19 +28,25 @@ import android.view.MenuItem;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
// 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; 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
@@ -146,7 +162,6 @@ public class I2PDActivity extends Activity {
} }
}; };
private static volatile boolean mIsBound; private static volatile boolean mIsBound;
private void doBindService() { private void doBindService() {
@@ -282,4 +297,123 @@ public class I2PDActivity extends Activity {
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("certificates");
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);
}
}
} }

18
android_binary_only/.gitignore vendored Normal file
View 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

View File

@@ -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_64_0/$(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_64_0/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_64_0/$(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_64_0/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_64_0/$(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_64_0/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_64_0/$(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_64_0/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.1/$(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.1/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.1/$(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.1/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)

View File

@@ -1,4 +1,4 @@
version: 2.19.{build} version: 2.22.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"

View File

@@ -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 )

View File

@@ -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

View File

@@ -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}

View File

@@ -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

View File

@@ -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]

View File

@@ -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.22.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
@@ -60,11 +60,14 @@ 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
@@ -91,6 +94,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
@@ -98,5 +102,8 @@ getent passwd i2pd >/dev/null || \
%changelog %changelog
* 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

View File

@@ -1,5 +1,5 @@
Name: i2pd Name: i2pd
Version: 2.19.0 Version: 2.22.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
@@ -58,11 +58,14 @@ 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 +92,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 +100,19 @@ getent passwd i2pd >/dev/null || \
%changelog %changelog
* 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

View 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

View 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

1
contrib/tunnels.d/README Normal file
View File

@@ -0,0 +1 @@
In that directory you can store separated config files for every tunnel.

View File

@@ -152,6 +152,19 @@ namespace i2p
i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV6 (ipv6);
i2p::context.SetSupportsV4 (ipv4); i2p::context.SetSupportsV4 (ipv4);
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2)
{
bool published; i2p::config::GetOption("ntcp2.published", published);
if (published)
{
uint16_t port; i2p::config::GetOption("ntcp2.port", port);
i2p::context.PublishNTCP2Address (port, true); // publish
}
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);
@@ -276,9 +289,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();

View File

@@ -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;
@@ -259,17 +262,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 << "&nbsp;&nbsp; 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&nbsp;&nbsp;"; s << "NTCP";
else if (address->IsPublishedNTCP2 ()) s << "2";
s << "NTCP&nbsp;&nbsp;"; if (address->host.is_v6 ()) s << "v6";
s << "&nbsp;&nbsp;";
break; break;
}
case i2p::data::RouterInfo::eTransportSSU: case i2p::data::RouterInfo::eTransportSSU:
if (address->host.is_v6 ()) if (address->host.is_v6 ())
s << "SSU6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; s << "SSUv6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
else else
s << "SSU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; s << "SSU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
break; break;
@@ -369,10 +381,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";
@@ -454,14 +468,14 @@ namespace http {
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>Expires:</b> " << ConvertTime(ls.GetExpirationTime()) << "<br>\r\n";
auto leases = ls.GetNonExpiredLeases(); auto leases = ls.GetNonExpiredLeases();
s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n"; s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n";
for ( auto & l : leases ) for ( auto & l : leases )
{ {
s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n"; s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n";
s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n"; s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n";
s << "<b>EndDate:</b> " << l->endDate << "<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";
} }
@@ -540,14 +554,8 @@ namespace http {
} }
} }
void ShowTransports (std::stringstream& s) template<typename Sessions>
{ static void ShowNTCPTransports (std::stringstream& s, const Sessions& sessions, const std::string name)
s << "<b>Transports:</b><br>\r\n<br>\r\n";
auto ntcpServer = i2p::transport::transports.GetNTCPServer ();
if (ntcpServer)
{
auto sessions = ntcpServer->GetNTCPSessions ();
if (!sessions.empty ())
{ {
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0; std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
for (const auto& it: sessions ) for (const auto& it: sessions )
@@ -576,15 +584,32 @@ namespace http {
} }
if (!tmp_s.str ().empty ()) 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 << "<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"; s << tmp_s.str () << "</p>\r\n</div>\r\n";
} }
if (!tmp_s6.str ().empty ()) 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 << "<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"; s << tmp_s6.str () << "</p>\r\n</div>\r\n";
} }
} }
void ShowTransports (std::stringstream& s)
{
s << "<b>Transports:</b><br>\r\n<br>\r\n";
auto ntcpServer = i2p::transport::transports.GetNTCPServer ();
if (ntcpServer)
{
auto sessions = ntcpServer->GetNTCPSessions ();
if (!sessions.empty ())
ShowNTCPTransports (s, sessions, "NTCP");
}
auto ntcp2Server = i2p::transport::transports.GetNTCP2Server ();
if (ntcp2Server)
{
auto sessions = ntcp2Server->GetNTCP2Sessions ();
if (!sessions.empty ())
ShowNTCPTransports (s, sessions, "NTCP2");
} }
auto ssuServer = i2p::transport::transports.GetSSUServer (); auto ssuServer = i2p::transport::transports.GetSSUServer ();
if (ssuServer) if (ssuServer)
@@ -609,7 +634,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 ();
@@ -744,6 +769,16 @@ 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_Timer (socket->get_io_service ()), m_BufferLen (0),
expected_host(hostname) expected_host(hostname)
@@ -862,7 +897,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;
} }

View File

@@ -131,7 +131,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)
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
@@ -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
View File

@@ -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/

27
debian/changelog vendored
View File

@@ -1,3 +1,30 @@
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
View File

@@ -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/

5
debian/i2pd.1 vendored
View File

@@ -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"

1
debian/i2pd.dirs vendored
View File

@@ -1,2 +1,3 @@
etc/i2pd etc/i2pd
etc/i2pd/tunnels.conf.d
var/lib/i2pd var/lib/i2pd

3
debian/i2pd.init vendored
View File

@@ -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
View File

@@ -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/ 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
View File

@@ -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.conf.d
usr/share/i2pd/certificates var/lib/i2pd/certificates usr/share/i2pd/certificates var/lib/i2pd/certificates

3
debian/i2pd.openrc vendored
View File

@@ -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"

View File

@@ -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
View 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

View File

@@ -1 +1,2 @@
01-tune-build-opts.patch 01-tune-build-opts.patch
02-fix-1210.patch

2
debian/rules vendored
View File

@@ -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

View File

@@ -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.

View File

@@ -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__)
} }
} }
} }

View File

@@ -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)")
@@ -232,6 +233,13 @@ 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)")
;
m_OptionsDesc m_OptionsDesc
.add(general) .add(general)
.add(limits) .add(limits)
@@ -249,6 +257,7 @@ namespace config {
.add(trust) .add(trust)
.add(websocket) .add(websocket)
.add(exploratory) .add(exploratory)
.add(ntcp2)
; ;
} }
@@ -276,6 +285,23 @@ namespace config {
std::cout << m_OptionsDesc; std::cout << m_OptionsDesc;
exit(EXIT_SUCCESS); 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);
}
} }
void ParseConfig(const std::string& path) void ParseConfig(const std::string& path)

View File

@@ -12,9 +12,8 @@
#if LEGACY_OPENSSL #if LEGACY_OPENSSL
#include "ChaCha20.h" #include "ChaCha20.h"
#include "Poly1305.h" #include "Poly1305.h"
#else
#include <openssl/evp.h>
#endif #endif
#include "Ed25519.h"
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Log.h" #include "Log.h"
@@ -278,6 +277,80 @@ namespace crypto
BN_free (pk); BN_free (pk);
} }
// x25519
X25519Keys::X25519Keys ()
{
#if OPENSSL_X25519
m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL);
#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
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)
{ {
@@ -522,9 +595,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 +616,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,7 +652,7 @@ namespace crypto
} }
// AES // AES
#ifdef AESNI #ifdef __AES__
#ifdef ARM64AES #ifdef ARM64AES
void init_aesenc(void){ void init_aesenc(void){
// TODO: Implementation // TODO: Implementation
@@ -632,7 +684,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__
@@ -673,7 +725,7 @@ namespace crypto
#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" \
@@ -694,9 +746,9 @@ namespace crypto
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 +756,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" \
@@ -735,9 +785,9 @@ namespace crypto
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 +795,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,15 +812,13 @@ 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);
} }
@@ -780,9 +826,9 @@ namespace crypto
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 +848,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 +859,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 +881,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 +904,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 +920,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 +951,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 +974,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 +990,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 +1026,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 +1039,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 +1068,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);
@@ -1076,9 +1091,6 @@ namespace crypto
uint8_t polyKey[64]; uint8_t polyKey[64];
memset(polyKey, 0, sizeof(polyKey)); memset(polyKey, 0, sizeof(polyKey));
chacha20 (polyKey, 64, nonce, key, 0); chacha20 (polyKey, 64, nonce, key, 0);
// encrypt data
memcpy (buf, msg, msgLen);
chacha20 (buf, msgLen, nonce, key, 1);
// create Poly1305 message // create Poly1305 message
if (!ad) adLen = 0; if (!ad) adLen = 0;
@@ -1096,7 +1108,21 @@ namespace crypto
memcpy (polyMsg.data () + offset, padding, rem); offset += rem; memcpy (polyMsg.data () + offset, padding, rem); offset += rem;
} }
} }
memcpy (polyMsg.data () + offset, encrypt ? buf : msg, msgLen); offset += msgLen; // encrypted data // encrypt/decrypt data and add to hash
if (buf != msg)
memcpy (buf, msg, msgLen);
if (encrypt)
{
chacha20 (buf, msgLen, nonce, key, 1); // encrypt
memcpy (polyMsg.data () + offset, buf, msgLen); // after encryption
}
else
{
memcpy (polyMsg.data () + offset, buf, msgLen); // before decryption
chacha20 (buf, msgLen, nonce, key, 1); // decrypt
}
offset += msgLen; // encrypted data
auto rem = msgLen & 0x0F; // %16 auto rem = msgLen & 0x0F; // %16
if (rem) if (rem)
{ {
@@ -1139,7 +1165,8 @@ 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); EVP_CIPHER_CTX_free (ctx);

View File

@@ -13,11 +13,24 @@
#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
#else
# define LEGACY_OPENSSL 0
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
# define OPENSSL_EDDSA 1
# define OPENSSL_X25519 1
# define OPENSSL_SIPHASH 1
# endif
#endif
namespace i2p namespace i2p
{ {
namespace crypto namespace crypto
@@ -48,6 +61,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,9 +108,9 @@ namespace crypto
void operator^=(const ChipherBlock& other) // XOR void operator^=(const ChipherBlock& other) // XOR
{ {
#ifdef __AVX__
if (i2p::cpu::avx) if (i2p::cpu::avx)
{ {
#ifdef AVX
__asm__ __asm__
( (
"vmovups (%[buf]), %%xmm0 \n" "vmovups (%[buf]), %%xmm0 \n"
@@ -82,18 +121,23 @@ namespace crypto
: [buf]"r"(buf), [other]"r"(other.buf) : [buf]"r"(buf), [other]"r"(other.buf)
: "%xmm0", "%xmm1", "memory" : "%xmm0", "%xmm1", "memory"
); );
#else }
for (int i = 0; i < 16; i++) else
buf[i] ^= other.buf[i];
#endif #endif
{
if (!(((size_t)buf | (size_t)other.buf) & 0x03)) // multiple of 4 ?
{
// we are good to cast to uint32_t *
for (int i = 0; i < 4; i++)
((uint32_t *)buf)[i] ^= ((uint32_t *)other.buf)[i];
} }
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];
} }
} }
}
}; };
typedef i2p::data::Tag<32> AESKey; typedef i2p::data::Tag<32> AESKey;
@@ -123,7 +167,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 +187,7 @@ namespace crypto
}; };
#endif #endif
#ifdef AESNI #ifdef __AES__
class ECBEncryption: public ECBCryptoAESNI class ECBEncryption: public ECBCryptoAESNI
#else #else
class ECBEncryption class ECBEncryption
@@ -159,7 +203,7 @@ namespace crypto
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
@@ -263,9 +307,7 @@ namespace crypto
} }
} }
// 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)

View File

@@ -64,7 +64,7 @@ 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
} }
} }
} }

View File

@@ -36,7 +36,7 @@ namespace i2p
std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len) std::shared_ptr<I2NPMessage> NewI2NPMessage (size_t len)
{ {
return (len < I2NP_MAX_SHORT_MESSAGE_SIZE/2) ? NewI2NPShortMessage () : NewI2NPMessage (); return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage ();
} }
void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID) void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID)

View File

@@ -26,6 +26,9 @@ namespace i2p
const size_t I2NP_SHORT_HEADER_EXPIRATION_OFFSET = I2NP_SHORT_HEADER_TYPEID_OFFSET + 1; const size_t I2NP_SHORT_HEADER_EXPIRATION_OFFSET = I2NP_SHORT_HEADER_TYPEID_OFFSET + 1;
const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4; const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4;
// I2NP NTCP2 header
const size_t I2NP_NTCP2_HEADER_SIZE = I2NP_HEADER_EXPIRATION_OFFSET + 4;
// Tunnel Gateway header // Tunnel Gateway header
const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0; const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0;
const size_t TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET = TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET + 4; const size_t TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET = TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET + 4;
@@ -103,7 +106,7 @@ namespace tunnel
class TunnelPool; class TunnelPool;
} }
const size_t I2NP_MAX_MESSAGE_SIZE = 32768; const size_t I2NP_MAX_MESSAGE_SIZE = 62708;
const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096; const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096;
const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT) const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT)
const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds
@@ -194,6 +197,24 @@ namespace tunnel
len = offset + I2NP_SHORT_HEADER_SIZE + bufbe16toh (header + I2NP_HEADER_SIZE_OFFSET); len = offset + I2NP_SHORT_HEADER_SIZE + bufbe16toh (header + I2NP_HEADER_SIZE_OFFSET);
return bufbe32toh (header + I2NP_HEADER_MSGID_OFFSET); return bufbe32toh (header + I2NP_HEADER_MSGID_OFFSET);
} }
// for NTCP2 only
uint8_t * GetNTCP2Header () { return GetPayload () - I2NP_NTCP2_HEADER_SIZE; };
size_t GetNTCP2Length () const { return GetPayloadLength () + I2NP_NTCP2_HEADER_SIZE; };
void FromNTCP2 ()
{
const uint8_t * ntcp2 = GetNTCP2Header ();
memcpy (GetHeader () + I2NP_HEADER_TYPEID_OFFSET, ntcp2 + I2NP_HEADER_TYPEID_OFFSET, 5); // typeid + msgid
SetExpiration (bufbe32toh (ntcp2 + I2NP_HEADER_EXPIRATION_OFFSET)*1000LL);
SetSize (len - offset - I2NP_HEADER_SIZE);
SetChks (0);
}
void ToNTCP2 ()
{
uint8_t * ntcp2 = GetNTCP2Header ();
htobe32buf (ntcp2 + I2NP_HEADER_EXPIRATION_OFFSET, bufbe64toh (GetHeader () + I2NP_HEADER_EXPIRATION_OFFSET)/1000LL);
memcpy (ntcp2 + I2NP_HEADER_TYPEID_OFFSET, GetHeader () + I2NP_HEADER_TYPEID_OFFSET, 5); // typeid + msgid
}
void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0); void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0);
void RenewI2NPMessageHeader (); void RenewI2NPMessageHeader ();

View File

@@ -72,29 +72,10 @@ namespace data
break; break;
} }
case SIGNING_KEY_TYPE_RSA_SHA256_2048: case SIGNING_KEY_TYPE_RSA_SHA256_2048:
{
memcpy (m_StandardIdentity.signingKey, signingKey, 128);
excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256 - 128
excessBuf = new uint8_t[excessLen];
memcpy (excessBuf, signingKey + 128, excessLen);
break;
}
case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA384_3072:
{
memcpy (m_StandardIdentity.signingKey, signingKey, 128);
excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384 - 128
excessBuf = new uint8_t[excessLen];
memcpy (excessBuf, signingKey + 128, excessLen);
break;
}
case SIGNING_KEY_TYPE_RSA_SHA512_4096: case SIGNING_KEY_TYPE_RSA_SHA512_4096:
{ LogPrint (eLogError, "Identity: RSA signing key type ", (int)type, " is not supported");
memcpy (m_StandardIdentity.signingKey, signingKey, 128);
excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512 - 128
excessBuf = new uint8_t[excessLen];
memcpy (excessBuf, signingKey + 128, excessLen);
break; break;
}
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
{ {
size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32
@@ -368,32 +349,10 @@ namespace data
break; break;
} }
case SIGNING_KEY_TYPE_RSA_SHA256_2048: case SIGNING_KEY_TYPE_RSA_SHA256_2048:
{
uint8_t signingKey[i2p::crypto::RSASHA2562048_KEY_LENGTH];
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
UpdateVerifier (new i2p::crypto:: RSASHA2562048Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA384_3072:
{
uint8_t signingKey[i2p::crypto::RSASHA3843072_KEY_LENGTH];
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
UpdateVerifier (new i2p::crypto:: RSASHA3843072Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA512_4096: case SIGNING_KEY_TYPE_RSA_SHA512_4096:
{ LogPrint (eLogError, "Identity: RSA signing key type ", (int)keyType, " is not supported");
uint8_t signingKey[i2p::crypto::RSASHA5124096_KEY_LENGTH];
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
UpdateVerifier (new i2p::crypto:: RSASHA5124096Verifier (signingKey));
break; break;
}
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
{ {
size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32
@@ -564,13 +523,9 @@ namespace data
m_Signer.reset (new i2p::crypto::ECDSAP521Signer (m_SigningPrivateKey)); m_Signer.reset (new i2p::crypto::ECDSAP521Signer (m_SigningPrivateKey));
break; break;
case SIGNING_KEY_TYPE_RSA_SHA256_2048: case SIGNING_KEY_TYPE_RSA_SHA256_2048:
m_Signer.reset (new i2p::crypto::RSASHA2562048Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA384_3072:
m_Signer.reset (new i2p::crypto::RSASHA3843072Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_RSA_SHA512_4096: case SIGNING_KEY_TYPE_RSA_SHA512_4096:
m_Signer.reset (new i2p::crypto::RSASHA5124096Signer (m_SigningPrivateKey)); LogPrint (eLogError, "Identity: RSA signing key type ", (int)m_Public->GetSigningKeyType (), " is not supported");
break; break;
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().certificate - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH)); m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().certificate - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH));
@@ -642,7 +597,7 @@ namespace data
case SIGNING_KEY_TYPE_RSA_SHA256_2048: case SIGNING_KEY_TYPE_RSA_SHA256_2048:
case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA384_3072:
case SIGNING_KEY_TYPE_RSA_SHA512_4096: case SIGNING_KEY_TYPE_RSA_SHA512_4096:
LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Create EdDSA"); LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Creating EdDSA");
// no break here // no break here
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey); i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
@@ -719,7 +674,9 @@ namespace data
XORMetric operator^(const IdentHash& key1, const IdentHash& key2) XORMetric operator^(const IdentHash& key1, const IdentHash& key2)
{ {
XORMetric m; XORMetric m;
#if defined(__AVX__) // for AVX #ifdef __AVX__
if(i2p::cpu::avx)
{
__asm__ __asm__
( (
"vmovups %1, %%ymm0 \n" "vmovups %1, %%ymm0 \n"
@@ -730,13 +687,16 @@ namespace data
: "m"(*key1), "m"(*key2) : "m"(*key1), "m"(*key2)
: "memory", "%xmm0", "%xmm1" // should be replaced by %ymm0/1 once supported by compiler : "memory", "%xmm0", "%xmm1" // should be replaced by %ymm0/1 once supported by compiler
); );
#else }
else
#endif
{
const uint64_t * hash1 = key1.GetLL (), * hash2 = key2.GetLL (); const uint64_t * hash1 = key1.GetLL (), * hash2 = key2.GetLL ();
m.metric_ll[0] = hash1[0] ^ hash2[0]; m.metric_ll[0] = hash1[0] ^ hash2[0];
m.metric_ll[1] = hash1[1] ^ hash2[1]; m.metric_ll[1] = hash1[1] ^ hash2[1];
m.metric_ll[2] = hash1[2] ^ hash2[2]; m.metric_ll[2] = hash1[2] ^ hash2[2];
m.metric_ll[3] = hash1[3] ^ hash2[3]; m.metric_ll[3] = hash1[3] ^ hash2[3];
#endif }
return m; return m;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,27 @@
/*
* 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
*
*/
#ifndef NTCP2_H__ #ifndef NTCP2_H__
#define NTCP2_H__ #define NTCP2_H__
#include <inttypes.h> #include <inttypes.h>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <list>
#include <map>
#include <array>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "Crypto.h"
#include "util.h"
#include "RouterInfo.h" #include "RouterInfo.h"
#include "TransportSession.h" #include "TransportSession.h"
@@ -12,6 +29,99 @@ namespace i2p
{ {
namespace transport namespace transport
{ {
const size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519;
const int NTCP2_MAX_PADDING_RATIO = 6; // in %
const int NTCP2_CONNECT_TIMEOUT = 5; // 5 seconds
const int NTCP2_ESTABLISH_TIMEOUT = 10; // 10 seconds
const int NTCP2_TERMINATION_TIMEOUT = 120; // 2 minutes
const int NTCP2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
const int NTCP2_CLOCK_SKEW = 60; // in seconds
const int NTCP2_MAX_OUTGOING_QUEUE_SIZE = 500; // how many messages we can queue up
enum NTCP2BlockType
{
eNTCP2BlkDateTime = 0,
eNTCP2BlkOptions, // 1
eNTCP2BlkRouterInfo, // 2
eNTCP2BlkI2NPMessage, // 3
eNTCP2BlkTermination, // 4
eNTCP2BlkPadding = 254
};
enum NTCP2TerminationReason
{
eNTCP2NormalClose = 0,
eNTCP2TerminationReceived, // 1
eNTCP2IdleTimeout, // 2
eNTCP2RouterShutdown, // 3
eNTCP2DataPhaseAEADFailure, // 4
eNTCP2IncompatibleOptions, // 5
eNTCP2IncompatibleSignatureType, // 6
eNTCP2ClockSkew, // 7
eNTCP2PaddingViolation, // 8
eNTCP2AEADFramingError, // 9
eNTCP2PayloadFormatError, // 10
eNTCP2Message1Error, // 11
eNTCP2Message2Error, // 12
eNTCP2Message3Error, // 13
eNTCP2IntraFrameReadTimeout, // 14
eNTCP2RouterInfoSignatureVerificationFail, // 15
eNTCP2IncorrectSParameter, // 16
eNTCP2Banned, // 17
};
typedef std::array<uint8_t, NTCP2_UNENCRYPTED_FRAME_MAX_SIZE> NTCP2FrameBuffer;
struct NTCP2Establisher
{
NTCP2Establisher ();
~NTCP2Establisher ();
const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); };
const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob
uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set
const uint8_t * GetK () const { return m_K; };
const uint8_t * GetCK () const { return m_CK; };
const uint8_t * GetH () const { return m_H; };
void KDF1Alice ();
void KDF1Bob ();
void KDF2Alice ();
void KDF2Bob ();
void KDF3Alice (); // for SessionConfirmed part 2
void KDF3Bob ();
void MixKey (const uint8_t * inputKeyMaterial);
void MixHash (const uint8_t * buf, size_t len);
void KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH
void KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate
void CreateEphemeralKey ();
void CreateSessionRequestMessage ();
void CreateSessionCreatedMessage ();
void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce);
void CreateSessionConfirmedMessagePart2 (const uint8_t * nonce);
bool ProcessSessionRequestMessage (uint16_t& paddingLen);
bool ProcessSessionCreatedMessage (uint16_t& paddingLen);
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce);
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf);
i2p::crypto::X25519Keys m_EphemeralKeys;
uint8_t m_RemoteEphemeralPublicKey[32]; // x25519
uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/;
i2p::data::IdentHash m_RemoteIdentHash;
uint16_t m3p2Len;
uint8_t * m_SessionRequestBuffer, * m_SessionCreatedBuffer, * m_SessionConfirmedBuffer;
size_t m_SessionRequestBufferLen, m_SessionCreatedBufferLen;
};
class NTCP2Server; class NTCP2Server;
class NTCP2Session: public TransportSession, public std::enable_shared_from_this<NTCP2Session> class NTCP2Session: public TransportSession, public std::enable_shared_from_this<NTCP2Session>
{ {
@@ -20,25 +130,29 @@ namespace transport
NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr); NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr);
~NTCP2Session (); ~NTCP2Session ();
void Terminate (); void Terminate ();
void TerminateByTimeout ();
void Done (); void Done ();
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; };
bool IsEstablished () const { return m_IsEstablished; };
bool IsTerminated () const { return m_IsTerminated; };
void ClientLogin (); // Alice void ClientLogin (); // Alice
void ServerLogin (); // Bob void ServerLogin (); // Bob
void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) {}; // TODO
void SendLocalRouterInfo (); // after handshake
void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
private: private:
void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived); void Established ();
void CreateNonce (uint64_t seqn, uint8_t * nonce); void CreateNonce (uint64_t seqn, uint8_t * nonce);
void KeyDerivationFunction1 (const uint8_t * rs, const uint8_t * priv, const uint8_t * pub, uint8_t * derived); // for SessionRequest
void KeyDerivationFunction2 (const uint8_t * priv, const uint8_t * pub, const uint8_t * sessionRequest, size_t sessionRequestLen, uint8_t * derived); // for SessionCreate
void KeyDerivationFunction3 (const uint8_t * staticPrivKey, uint8_t * derived); // for SessionConfirmed part 2
void KeyDerivationFunctionDataPhase (); void KeyDerivationFunctionDataPhase ();
void SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey);
// establish // establish
void CreateEphemeralKey (uint8_t * pub);
void SendSessionRequest (); void SendSessionRequest ();
void SendSessionCreated (); void SendSessionCreated ();
void SendSessionConfirmed (); void SendSessionConfirmed ();
@@ -50,6 +164,7 @@ namespace transport
void HandleSessionCreatedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionCreatedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleSessionConfirmedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionConfirmedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleSessionConfirmedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
// data // data
void ReceiveLength (); void ReceiveLength ();
@@ -60,6 +175,11 @@ namespace transport
void SendNextFrame (const uint8_t * payload, size_t len); void SendNextFrame (const uint8_t * payload, size_t len);
void HandleNextFrameSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleNextFrameSent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void SendQueue ();
void SendRouterInfo ();
void SendTermination (NTCP2TerminationReason reason);
void SendTerminationAndTerminate (NTCP2TerminationReason reason);
void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
private: private:
@@ -67,16 +187,29 @@ namespace transport
boost::asio::ip::tcp::socket m_Socket; boost::asio::ip::tcp::socket m_Socket;
bool m_IsEstablished, m_IsTerminated; bool m_IsEstablished, m_IsTerminated;
uint8_t m_EphemeralPrivateKey[32]; // x25519 std::unique_ptr<NTCP2Establisher> m_Establisher;
uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /* derived after SessionCreated */, m_Y[32] /* or X for Bob */;
uint8_t * m_SessionRequestBuffer, * m_SessionCreatedBuffer, * m_SessionConfirmedBuffer;
size_t m_SessionRequestBufferLen, m_SessionCreatedBufferLen;
// data phase // data phase
uint8_t m_Kab[33], m_Kba[32], m_Sipkeysab[33], m_Sipkeysba[32]; uint8_t m_Kab[33], m_Kba[32], m_Sipkeysab[33], m_Sipkeysba[32];
const uint8_t * m_SendKey, * m_ReceiveKey;
#if OPENSSL_SIPHASH
EVP_PKEY * m_SendSipKey, * m_ReceiveSipKey;
EVP_MD_CTX * m_SendMDCtx, * m_ReceiveMDCtx;
#else
const uint8_t * m_SendSipKey, * m_ReceiveSipKey;
#endif
uint16_t m_NextReceivedLen; uint16_t m_NextReceivedLen;
uint8_t * m_NextReceivedBuffer, * m_NextSendBuffer; uint8_t * m_NextReceivedBuffer, * m_NextSendBuffer;
uint8_t m_ReceiveIV[8], m_SendIV[8]; union
{
uint8_t buf[8];
uint16_t key;
} m_ReceiveIV, m_SendIV;
uint64_t m_ReceiveSequenceNumber, m_SendSequenceNumber; uint64_t m_ReceiveSequenceNumber, m_SendSequenceNumber;
i2p::I2NPMessagesHandler m_Handler;
bool m_IsSending;
std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
}; };
class NTCP2Server class NTCP2Server
@@ -89,14 +222,28 @@ namespace transport
void Start (); void Start ();
void Stop (); void Stop ();
bool AddNTCP2Session (std::shared_ptr<NTCP2Session> session);
void RemoveNTCP2Session (std::shared_ptr<NTCP2Session> session);
std::shared_ptr<NTCP2Session> FindNTCP2Session (const i2p::data::IdentHash& ident);
boost::asio::io_service& GetService () { return m_Service; }; boost::asio::io_service& GetService () { return m_Service; };
void Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr<NTCP2Session> conn); void Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr<NTCP2Session> conn);
NTCP2FrameBuffer * NewNTCP2FrameBuffer () { return m_NTCP2FrameBuffersPool.Acquire(); }
void DeleteNTCP2FrameBuffer (NTCP2FrameBuffer * buf) { return m_NTCP2FrameBuffersPool.Release(buf); }
private: private:
void Run (); void Run ();
void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr<NTCP2Session> conn); void HandleAccept (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error);
void HandleAcceptV6 (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error);
void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr<NTCP2Session> conn, std::shared_ptr<boost::asio::deadline_timer> timer);
// timer
void ScheduleTermination ();
void HandleTerminationTimer (const boost::system::error_code& ecode);
private: private:
@@ -104,6 +251,17 @@ namespace transport
std::thread * m_Thread; std::thread * m_Thread;
boost::asio::io_service m_Service; boost::asio::io_service m_Service;
boost::asio::io_service::work m_Work; boost::asio::io_service::work m_Work;
boost::asio::deadline_timer m_TerminationTimer;
std::unique_ptr<boost::asio::ip::tcp::acceptor> m_NTCP2Acceptor, m_NTCP2V6Acceptor;
std::map<i2p::data::IdentHash, std::shared_ptr<NTCP2Session> > m_NTCP2Sessions;
std::list<std::shared_ptr<NTCP2Session> > m_PendingIncomingSessions;
i2p::util::MemoryPool<NTCP2FrameBuffer> m_NTCP2FrameBuffersPool;
public:
// for HTTP/I2PControl
const decltype(m_NTCP2Sessions)& GetNTCP2Sessions () const { return m_NTCP2Sessions; };
}; };
} }
} }

View File

@@ -402,7 +402,7 @@ namespace transport
uint32_t tsA1 = be32toh (tsA); uint32_t tsA1 = be32toh (tsA);
if (tsA1 < ts - NTCP_CLOCK_SKEW || tsA1 > ts + NTCP_CLOCK_SKEW) if (tsA1 < ts - NTCP_CLOCK_SKEW || tsA1 > ts + NTCP_CLOCK_SKEW)
{ {
LogPrint (eLogError, "NTCP: Phase3 time difference ", ts - tsA1, " exceeds clock skew"); LogPrint (eLogError, "NTCP: Phase3 time difference ", (int)(ts - tsA1), " exceeds clock skew");
Terminate (); Terminate ();
return; return;
} }
@@ -485,7 +485,7 @@ namespace transport
auto ts = i2p::util::GetSecondsSinceEpoch (); auto ts = i2p::util::GetSecondsSinceEpoch ();
if (tsB < ts - NTCP_CLOCK_SKEW || tsB > ts + NTCP_CLOCK_SKEW) if (tsB < ts - NTCP_CLOCK_SKEW || tsB > ts + NTCP_CLOCK_SKEW)
{ {
LogPrint (eLogError, "NTCP: Phase4 time difference ", ts - tsB, " exceeds clock skew"); LogPrint (eLogError, "NTCP: Phase4 time difference ", (int)(ts - tsB), " exceeds clock skew");
Terminate (); Terminate ();
return; return;
} }
@@ -819,7 +819,7 @@ namespace transport
for (const auto& address: addresses) for (const auto& address: addresses)
{ {
if (!address) continue; if (!address) continue;
if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP) if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !address->IsNTCP2 ())
{ {
if (address->host.is_v4()) if (address->host.is_v4())
{ {

View File

@@ -130,18 +130,17 @@ namespace data
lastDestinationCleanup = ts; lastDestinationCleanup = ts;
} }
if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL && !m_HiddenMode) // publish if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL) // update timestamp and publish
{ {
Publish (); i2p::context.UpdateTimestamp (ts);
if (!m_HiddenMode) Publish ();
lastPublish = ts; lastPublish = ts;
} }
if (ts - lastExploratory >= 30) // exploratory every 30 seconds if (ts - lastExploratory >= 30) // exploratory every 30 seconds
{ {
auto numRouters = m_RouterInfos.size (); auto numRouters = m_RouterInfos.size ();
if (numRouters == 0) if (!numRouters)
{
throw std::runtime_error("No known routers, reseed seems to be totally failed"); throw std::runtime_error("No known routers, reseed seems to be totally failed");
}
else // we have peers now else // we have peers now
m_FloodfillBootstrap = nullptr; m_FloodfillBootstrap = nullptr;
if (numRouters < 2500 || ts - lastExploratory >= 90) if (numRouters < 2500 || ts - lastExploratory >= 90)
@@ -734,7 +733,7 @@ namespace data
m_Requests.RequestComplete (ident, nullptr); m_Requests.RequestComplete (ident, nullptr);
} }
else else
// no more requests for detination possible. delete it // no more requests for destination possible. delete it
m_Requests.RequestComplete (ident, nullptr); m_Requests.RequestComplete (ident, nullptr);
} }
else if(!m_FloodfillBootstrap) else if(!m_FloodfillBootstrap)

View File

@@ -133,9 +133,14 @@ namespace crypto
struct Poly1305 struct Poly1305
{ {
#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 8) // older than gcc 4.8
Poly1305(const uint8_t * key) : m_Leftover(0), m_Final(0)
{
memset (&m_H, 0, sizeof (m_H));
#else
Poly1305(const uint8_t * key) : m_Leftover(0), m_H{0}, m_Final(0) Poly1305(const uint8_t * key) : m_Leftover(0), m_H{0}, m_Final(0)
{ {
#endif
m_R.PutKey(key); m_R.PutKey(key);
m_Pad.Put(key + 16); m_Pad.Put(key + 16);
} }

View File

@@ -219,7 +219,7 @@ namespace data
BN_CTX * bnctx = BN_CTX_new (); BN_CTX * bnctx = BN_CTX_new ();
BIGNUM * s = BN_new (), * n = BN_new (); BIGNUM * s = BN_new (), * n = BN_new ();
BN_bin2bn (signature, signatureLength, s); BN_bin2bn (signature, signatureLength, s);
BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n); BN_bin2bn (it->second, 512, n); // RSA 4096 assumed
BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n
uint8_t * enSigBuf = new uint8_t[signatureLength]; uint8_t * enSigBuf = new uint8_t[signatureLength];
i2p::crypto::bn2buf (s, enSigBuf, signatureLength); i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
@@ -300,7 +300,7 @@ namespace data
s.read (localFileName, fileNameLength); s.read (localFileName, fileNameLength);
localFileName[fileNameLength] = 0; localFileName[fileNameLength] = 0;
s.seekg (extraFieldLength, std::ios::cur); s.seekg (extraFieldLength, std::ios::cur);
// take care about data desriptor if presented // take care about data descriptor if presented
if (bitFlag & ZIP_BIT_FLAG_DATA_DESCRIPTOR) if (bitFlag & ZIP_BIT_FLAG_DATA_DESCRIPTOR)
{ {
size_t pos = s.tellg (); size_t pos = s.tellg ();

View File

@@ -50,7 +50,9 @@ namespace i2p
port = rand () % (30777 - 9111) + 9111; // I2P network ports range port = rand () % (30777 - 9111) + 9111; // I2P network ports range
bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv4; i2p::config::GetOption("ipv4", ipv4);
bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool ntcp2; i2p::config::GetOption("ntcp2", ntcp2); bool ssu; i2p::config::GetOption("ssu", ssu);
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
bool nat; i2p::config::GetOption("nat", nat); bool nat; i2p::config::GetOption("nat", nat);
std::string ifname; i2p::config::GetOption("ifname", ifname); std::string ifname; i2p::config::GetOption("ifname", ifname);
std::string ifname4; i2p::config::GetOption("ifname4", ifname4); std::string ifname4; i2p::config::GetOption("ifname4", ifname4);
@@ -67,7 +69,9 @@ namespace i2p
if(ifname4.size()) if(ifname4.size())
host = i2p::util::net::GetInterfaceAddress(ifname4, false).to_string(); host = i2p::util::net::GetInterfaceAddress(ifname4, false).to_string();
if (ssu)
routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ());
if (ntcp)
routerInfo.AddNTCPAddress (host.c_str(), port); routerInfo.AddNTCPAddress (host.c_str(), port);
} }
if (ipv6) if (ipv6)
@@ -81,7 +85,9 @@ namespace i2p
if(ifname6.size()) if(ifname6.size())
host = i2p::util::net::GetInterfaceAddress(ifname6, true).to_string(); host = i2p::util::net::GetInterfaceAddress(ifname6, true).to_string();
if (ssu)
routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ());
if (ntcp)
routerInfo.AddNTCPAddress (host.c_str(), port); routerInfo.AddNTCPAddress (host.c_str(), port);
} }
@@ -93,11 +99,12 @@ namespace i2p
m_RouterInfo.SetRouterIdentity (GetIdentity ()); m_RouterInfo.SetRouterIdentity (GetIdentity ());
m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ());
if (ntcp2) if (ntcp2) // we don't store iv in the address if non published so we must update it from keys
{ {
NewNTCP2Keys (); if (!m_NTCP2Keys) NewNTCP2Keys ();
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); UpdateNTCP2Address (true);
} }
} }
void RouterContext::UpdateRouterInfo () void RouterContext::UpdateRouterInfo ()
@@ -109,12 +116,12 @@ namespace i2p
void RouterContext::NewNTCP2Keys () void RouterContext::NewNTCP2Keys ()
{ {
m_StaticKeys.reset (new i2p::crypto::X25519Keys ());
m_StaticKeys->GenerateKeys ();
m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
RAND_bytes (m_NTCP2Keys->staticPrivateKey, 32); m_StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey);
memcpy (m_NTCP2Keys->staticPublicKey, m_StaticKeys->GetPublicKey (), 32);
RAND_bytes (m_NTCP2Keys->iv, 16); RAND_bytes (m_NTCP2Keys->iv, 16);
BN_CTX * ctx = BN_CTX_new ();
i2p::crypto::GetEd25519 ()->ScalarMulB (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey, ctx);
BN_CTX_free (ctx);
// save // save
std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out); std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out);
fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
@@ -145,7 +152,7 @@ namespace i2p
bool updated = false; bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ()) for (auto& address : m_RouterInfo.GetAddresses ())
{ {
if (address->port != port) if (!address->IsNTCP2 () && address->port != port)
{ {
address->port = port; address->port = port;
updated = true; updated = true;
@@ -155,6 +162,53 @@ namespace i2p
UpdateRouterInfo (); UpdateRouterInfo ();
} }
void RouterContext::PublishNTCP2Address (int port, bool publish)
{
if (!m_NTCP2Keys) return;
if (!port)
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ())
{
if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish))
{
address->port = port;
address->cost = publish ? 3 : 14;
address->ntcp2->isPublished = publish;
address->ntcp2->iv = m_NTCP2Keys->iv;
updated = true;
}
}
if (updated)
UpdateRouterInfo ();
}
void RouterContext::UpdateNTCP2Address (bool enable)
{
auto& addresses = m_RouterInfo.GetAddresses ();
bool found = false, updated = false;
for (auto it = addresses.begin (); it != addresses.end (); ++it)
{
if ((*it)->IsNTCP2 ())
{
found = true;
if (!enable)
{
addresses.erase (it);
updated= true;
}
break;
}
}
if (enable && !found)
{
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
updated = true;
}
if (updated)
UpdateRouterInfo ();
}
void RouterContext::UpdateAddress (const boost::asio::ip::address& host) void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
{ {
bool updated = false; bool updated = false;
@@ -291,7 +345,7 @@ namespace i2p
auto& addresses = m_RouterInfo.GetAddresses (); auto& addresses = m_RouterInfo.GetAddresses ();
for (auto it = addresses.begin (); it != addresses.end (); ++it) for (auto it = addresses.begin (); it != addresses.end (); ++it)
{ {
if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !(*it)->IsNTCP2 () &&
(*it)->host.is_v4 ()) (*it)->host.is_v4 ())
{ {
addresses.erase (it); addresses.erase (it);
@@ -318,8 +372,10 @@ namespace i2p
caps |= i2p::data::RouterInfo::eFloodfill; caps |= i2p::data::RouterInfo::eFloodfill;
m_RouterInfo.SetCaps (caps); m_RouterInfo.SetCaps (caps);
// insert NTCP back
auto& addresses = m_RouterInfo.GetAddresses (); auto& addresses = m_RouterInfo.GetAddresses ();
// insert NTCP back
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
if (ntcp) {
for (const auto& addr : addresses) for (const auto& addr : addresses)
{ {
if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU && if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU &&
@@ -330,6 +386,7 @@ namespace i2p
break; break;
} }
} }
}
// delete previous introducers // delete previous introducers
for (auto& addr : addresses) for (auto& addr : addresses)
if (addr->ssu) if (addr->ssu)
@@ -397,6 +454,39 @@ namespace i2p
UpdateRouterInfo (); UpdateRouterInfo ();
} }
void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host)
{
bool updated = false, found = false;
int port = 0;
auto& addresses = m_RouterInfo.GetAddresses ();
for (auto& addr: addresses)
{
if (addr->IsPublishedNTCP2 ())
{
if (addr->host.is_v6 ())
{
if (addr->host != host)
{
addr->host = host;
updated = true;
}
found = true;
break;
}
else
port = addr->port; // NTCP2 v4
}
}
if (!found && port) // we have found NTCP2 v4 but not v6
{
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port);
updated = true;
}
if (updated)
UpdateRouterInfo ();
}
void RouterContext::UpdateStats () void RouterContext::UpdateStats ()
{ {
if (m_IsFloodfill) if (m_IsFloodfill)
@@ -408,6 +498,12 @@ namespace i2p
} }
} }
void RouterContext::UpdateTimestamp (uint64_t ts)
{
if (ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL)
UpdateRouterInfo ();
}
bool RouterContext::Load () bool RouterContext::Load ()
{ {
std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary); std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary);
@@ -429,7 +525,21 @@ namespace i2p
m_Keys.FromBuffer (buf, len); m_Keys.FromBuffer (buf, len);
delete[] buf; delete[] buf;
} }
// read NTCP2 keys if available
std::ifstream n2k (i2p::fs::DataDirPath (NTCP2_KEYS), std::ifstream::in | std::ifstream::binary);
if (n2k)
{
n2k.seekg (0, std::ios::end);
len = n2k.tellg();
n2k.seekg (0, std::ios::beg);
if (len == sizeof (NTCP2PrivateKeys))
{
m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
}
n2k.close ();
}
// read RouterInfo
m_RouterInfo.SetRouterIdentity (GetIdentity ()); m_RouterInfo.SetRouterIdentity (GetIdentity ());
i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO));
if (!routerInfo.IsUnreachable ()) // router.info looks good if (!routerInfo.IsUnreachable ()) // router.info looks good
@@ -452,28 +562,14 @@ namespace i2p
SetReachable (); // we assume reachable until we discover firewall through peer tests SetReachable (); // we assume reachable until we discover firewall through peer tests
// read NTCP2 // read NTCP2
bool ntcp2; i2p::config::GetOption("ntcp2", ntcp2); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2) if (ntcp2)
{ {
std::ifstream n2k (i2p::fs::DataDirPath (NTCP2_KEYS), std::ifstream::in | std::ifstream::binary); if (!m_NTCP2Keys) NewNTCP2Keys ();
if (n2k) UpdateNTCP2Address (true); // enable NTCP2
{
n2k.seekg (0, std::ios::end);
len = fk.tellg();
n2k.seekg (0, std::ios::beg);
if (len == sizeof (NTCP2PrivateKeys))
{
m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
}
n2k.close ();
}
if (!m_NTCP2Keys)
{
NewNTCP2Keys ();
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
}
} }
else
UpdateNTCP2Address (false); // disable NTCP2
return true; return true;
} }
@@ -531,4 +627,18 @@ namespace i2p
{ {
return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false; return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false;
} }
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
{
if (!m_StaticKeys)
{
if (!m_NTCP2Keys) NewNTCP2Keys ();
auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey);
if (!m_StaticKeys)
m_StaticKeys.reset (x);
else
delete x;
}
return *m_StaticKeys;
}
} }

View File

@@ -62,6 +62,7 @@ namespace i2p
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; }; const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; }; const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; }; const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
i2p::crypto::X25519Keys& GetStaticKeys ();
uint32_t GetUptime () const; uint32_t GetUptime () const;
uint32_t GetStartupTime () const { return m_StartupTime; }; uint32_t GetStartupTime () const { return m_StartupTime; };
@@ -78,6 +79,8 @@ namespace i2p
void UpdatePort (int port); // called from Daemon void UpdatePort (int port); // called from Daemon
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
void PublishNTCP2Address (int port, bool publish = true);
void UpdateNTCP2Address (bool enable);
bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
bool IsUnreachable () const; bool IsUnreachable () const;
@@ -98,7 +101,9 @@ namespace i2p
void SetSupportsV4 (bool supportsV4); void SetSupportsV4 (bool supportsV4);
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from NTCP2 session
void UpdateStats (); void UpdateStats ();
void UpdateTimestamp (uint64_t ts); // in seconds, called from NetDb before publishing
void CleanupDestination (); // garlic destination void CleanupDestination (); // garlic destination
// implements LocalDestination // implements LocalDestination
@@ -130,7 +135,7 @@ namespace i2p
i2p::data::RouterInfo m_RouterInfo; i2p::data::RouterInfo m_RouterInfo;
i2p::data::PrivateKeys m_Keys; i2p::data::PrivateKeys m_Keys;
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor; std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor;
uint64_t m_LastUpdateTime; uint64_t m_LastUpdateTime; // in seconds
bool m_AcceptsTunnels, m_IsFloodfill; bool m_AcceptsTunnels, m_IsFloodfill;
uint64_t m_StartupTime; // in seconds since epoch uint64_t m_StartupTime; // in seconds since epoch
uint64_t m_BandwidthLimit; // allowed bandwidth uint64_t m_BandwidthLimit; // allowed bandwidth
@@ -140,6 +145,7 @@ namespace i2p
int m_NetID; int m_NetID;
std::mutex m_GarlicMutex; std::mutex m_GarlicMutex;
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys; std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
}; };
extern RouterContext context; extern RouterContext context;

View File

@@ -176,13 +176,13 @@ namespace data
auto address = std::make_shared<Address>(); auto address = std::make_shared<Address>();
s.read ((char *)&address->cost, sizeof (address->cost)); s.read ((char *)&address->cost, sizeof (address->cost));
s.read ((char *)&address->date, sizeof (address->date)); s.read ((char *)&address->date, sizeof (address->date));
bool isNtcp2 = false; bool isNTCP2Only = false;
char transportStyle[6]; char transportStyle[6];
auto transportStyleLen = ReadString (transportStyle, 6, s) - 1; auto transportStyleLen = ReadString (transportStyle, 6, s) - 1;
if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2 if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2
{ {
address->transportStyle = eTransportNTCP; address->transportStyle = eTransportNTCP;
if (transportStyleLen > 4 || transportStyle[4] == '2') isNtcp2= true; if (transportStyleLen > 4 && transportStyle[4] == '2') isNTCP2Only= true;
} }
else if (!strcmp (transportStyle, "SSU")) else if (!strcmp (transportStyle, "SSU"))
{ {
@@ -259,6 +259,7 @@ namespace data
if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ()); if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ());
supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6; supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6;
Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16); Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16);
address->ntcp2->isPublished = true; // presence if "i" means "published"
} }
else if (key[0] == 'i') else if (key[0] == 'i')
{ {
@@ -292,7 +293,8 @@ namespace data
if (!s) return; if (!s) return;
} }
if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented
if (supportedTransports && !isNtcp2) // we ignore NTCP2 addresses for now. TODO: if (isNTCP2Only && address->ntcp2) address->ntcp2->isNTCP2Only = true;
if (supportedTransports)
{ {
addresses->push_back(address); addresses->push_back(address);
m_SupportedTransports |= supportedTransports; m_SupportedTransports |= supportedTransports;
@@ -373,7 +375,7 @@ namespace data
break; break;
case CAPS_FLAG_EXTRA_BANDWIDTH1: case CAPS_FLAG_EXTRA_BANDWIDTH1:
case CAPS_FLAG_EXTRA_BANDWIDTH2: case CAPS_FLAG_EXTRA_BANDWIDTH2:
m_Caps |= Caps::eExtraBandwidth; m_Caps |= Caps::eExtraBandwidth | Caps::eHighBandwidth;
break; break;
case CAPS_FLAG_HIDDEN: case CAPS_FLAG_HIDDEN:
m_Caps |= Caps::eHidden; m_Caps |= Caps::eHidden;
@@ -404,16 +406,14 @@ namespace data
if (m_Caps & eExtraBandwidth) caps += (m_Caps & eHighBandwidth) ? if (m_Caps & eExtraBandwidth) caps += (m_Caps & eHighBandwidth) ?
CAPS_FLAG_EXTRA_BANDWIDTH2 : // 'X' CAPS_FLAG_EXTRA_BANDWIDTH2 : // 'X'
CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P' CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P'
else
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
caps += CAPS_FLAG_FLOODFILL; // floodfill caps += CAPS_FLAG_FLOODFILL; // floodfill
} }
else else
{ {
if (m_Caps & eExtraBandwidth) if (m_Caps & eExtraBandwidth)
{
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 /* 'X' */ : CAPS_FLAG_EXTRA_BANDWIDTH1; /*'P' */ caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 /* 'X' */ : CAPS_FLAG_EXTRA_BANDWIDTH1; /*'P' */
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
}
else else
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth
} }
@@ -455,7 +455,7 @@ namespace data
else else
WriteString ("", s); WriteString ("", s);
if (!address.IsNTCP2 ()) // we don't publish NTCP2 address fow now. TODO: implement if (!address.IsNTCP2 () || address.IsPublishedNTCP2 ())
{ {
WriteString ("host", properties); WriteString ("host", properties);
properties << '='; properties << '=';
@@ -537,7 +537,14 @@ namespace data
} }
} }
if (!address.IsNTCP2 ()) // we don't publish NTCP2 address fow now. TODO: implement if (address.IsPublishedNTCP2 ())
{
// publish i for NTCP2
WriteString ("i", properties); properties << '=';
WriteString (address.ntcp2->iv.ToBase64 (), properties); properties << ';';
}
if (!address.IsNTCP2 () || address.IsPublishedNTCP2 ())
{ {
WriteString ("port", properties); WriteString ("port", properties);
properties << '='; properties << '=';
@@ -551,7 +558,6 @@ namespace data
WriteString (address.ntcp2->staticKey.ToBase64 (), properties); properties << ';'; WriteString (address.ntcp2->staticKey.ToBase64 (), properties); properties << ';';
WriteString ("v", properties); properties << '='; WriteString ("v", properties); properties << '=';
WriteString ("2", properties); properties << ';'; WriteString ("2", properties); properties << ';';
// TODO: publish "i"
} }
uint16_t size = htobe16 (properties.str ().size ()); uint16_t size = htobe16 (properties.str ().size ());
@@ -660,12 +666,12 @@ namespace data
addr->host = boost::asio::ip::address::from_string (host); addr->host = boost::asio::ip::address::from_string (host);
addr->port = port; addr->port = port;
addr->transportStyle = eTransportNTCP; addr->transportStyle = eTransportNTCP;
addr->cost = 2; addr->cost = 6;
addr->date = 0; addr->date = 0;
for (const auto& it: *m_Addresses) // don't insert same address twice for (const auto& it: *m_Addresses) // don't insert same address twice
if (*it == *addr) return; if (*it == *addr) return;
m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4; m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4;
m_Addresses->push_back(std::move(addr)); m_Addresses->push_front(std::move(addr)); // always make NTCP first
} }
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu) void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
@@ -688,16 +694,17 @@ namespace data
m_Caps |= eSSUIntroducer; m_Caps |= eSSUIntroducer;
} }
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv) void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host, int port)
{ {
for (const auto& it: *m_Addresses) // don't insert one more NTCP2
if (it->ntcp2) return;
auto addr = std::make_shared<Address>(); auto addr = std::make_shared<Address>();
addr->port = 0; addr->host = host;
addr->port = port;
addr->transportStyle = eTransportNTCP; addr->transportStyle = eTransportNTCP;
addr->cost = 14; addr->cost = port ? 3 : 14; // override from RouterContext::PublishNTCP2Address
addr->date = 0; addr->date = 0;
addr->ntcp2.reset (new NTCP2Ext ()); addr->ntcp2.reset (new NTCP2Ext ());
addr->ntcp2->isNTCP2Only = true; // NTCP2 only address
if (port) addr->ntcp2->isPublished = true;
memcpy (addr->ntcp2->staticKey, staticKey, 32); memcpy (addr->ntcp2->staticKey, staticKey, 32);
memcpy (addr->ntcp2->iv, iv, 16); memcpy (addr->ntcp2->iv, iv, 16);
m_Addresses->push_back(std::move(addr)); m_Addresses->push_back(std::move(addr));
@@ -853,37 +860,55 @@ namespace data
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetNTCPAddress (bool v4only) const std::shared_ptr<const RouterInfo::Address> RouterInfo::GetNTCPAddress (bool v4only) const
{ {
return GetAddress (eTransportNTCP, v4only); return GetAddress (
[v4only](std::shared_ptr<const RouterInfo::Address> address)->bool
{
return (address->transportStyle == eTransportNTCP) && !address->IsNTCP2Only () && (!v4only || address->host.is_v4 ());
});
} }
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUAddress (bool v4only) const std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUAddress (bool v4only) const
{ {
return GetAddress (eTransportSSU, v4only); return GetAddress (
[v4only](std::shared_ptr<const RouterInfo::Address> address)->bool
{
return (address->transportStyle == eTransportSSU) && (!v4only || address->host.is_v4 ());
});
} }
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUV6Address () const std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUV6Address () const
{ {
return GetAddress (eTransportSSU, false, true); return GetAddress (
[](std::shared_ptr<const RouterInfo::Address> address)->bool
{
return (address->transportStyle == eTransportSSU) && address->host.is_v6 ();
});
} }
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const template<typename Filter>
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const
{ {
// TODO: make it more gereric using comparator
#if (BOOST_VERSION >= 105300) #if (BOOST_VERSION >= 105300)
auto addresses = boost::atomic_load (&m_Addresses); auto addresses = boost::atomic_load (&m_Addresses);
#else #else
auto addresses = m_Addresses; auto addresses = m_Addresses;
#endif #endif
for (const auto& address : *addresses) for (const auto& address : *addresses)
{ if (filter (address)) return address;
if (address->transportStyle == s)
{
if ((!v4only || address->host.is_v4 ()) && (!v6only || address->host.is_v6 ()))
return address;
}
}
return nullptr; return nullptr;
} }
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetNTCP2Address (bool publishedOnly, bool v4only) const
{
return GetAddress (
[publishedOnly, v4only](std::shared_ptr<const RouterInfo::Address> address)->bool
{
return address->IsNTCP2 () && (!publishedOnly || address->IsPublishedNTCP2 ()) && (!v4only || address->host.is_v4 ());
});
}
std::shared_ptr<RouterProfile> RouterInfo::GetProfile () const std::shared_ptr<RouterProfile> RouterInfo::GetProfile () const
{ {
if (!m_Profile) if (!m_Profile)

View File

@@ -94,6 +94,8 @@ namespace data
{ {
Tag<32> staticKey; Tag<32> staticKey;
Tag<16> iv; Tag<16> iv;
bool isPublished = false;
bool isNTCP2Only = false;
}; };
struct Address struct Address
@@ -115,7 +117,8 @@ namespace data
bool operator==(const Address& other) const bool operator==(const Address& other) const
{ {
return transportStyle == other.transportStyle && host == other.host && port == other.port; return transportStyle == other.transportStyle && IsNTCP2 () == other.IsNTCP2 () &&
host == other.host && port == other.port;
} }
bool operator!=(const Address& other) const bool operator!=(const Address& other) const
@@ -124,6 +127,8 @@ namespace data
} }
bool IsNTCP2 () const { return (bool)ntcp2; }; bool IsNTCP2 () const { return (bool)ntcp2; };
bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; };
bool IsNTCP2Only () const { return ntcp2 && ntcp2->isNTCP2Only; };
}; };
typedef std::list<std::shared_ptr<Address> > Addresses; typedef std::list<std::shared_ptr<Address> > Addresses;
@@ -140,12 +145,13 @@ namespace data
uint64_t GetTimestamp () const { return m_Timestamp; }; uint64_t GetTimestamp () const { return m_Timestamp; };
Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr
std::shared_ptr<const Address> GetNTCPAddress (bool v4only = true) const; std::shared_ptr<const Address> GetNTCPAddress (bool v4only = true) const;
std::shared_ptr<const Address> GetNTCP2Address (bool publishedOnly, bool v4only = true) const;
std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const; std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
std::shared_ptr<const Address> GetSSUV6Address () const; std::shared_ptr<const Address> GetSSUV6Address () const;
void AddNTCPAddress (const char * host, int port); void AddNTCPAddress (const char * host, int port);
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv); void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0);
bool AddIntroducer (const Introducer& introducer); bool AddIntroducer (const Introducer& introducer);
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only
@@ -213,7 +219,8 @@ namespace data
size_t ReadString (char* str, size_t len, std::istream& s) const; size_t ReadString (char* str, size_t len, std::istream& s) const;
void WriteString (const std::string& str, std::ostream& s) const; void WriteString (const std::string& str, std::ostream& s) const;
void ExtractCaps (const char * value); void ExtractCaps (const char * value);
std::shared_ptr<const Address> GetAddress (TransportStyle s, bool v4only, bool v6only = false) const; template<typename Filter>
std::shared_ptr<const Address> GetAddress (Filter filter) const;
void UpdateCapsProperty (); void UpdateCapsProperty ();
private: private:

View File

@@ -320,7 +320,7 @@ namespace transport
uint8_t * msgBuf = msg->GetSSUHeader (); uint8_t * msgBuf = msg->GetSSUHeader ();
uint32_t fragmentNum = 0; uint32_t fragmentNum = 0;
while (len > 0) while (len > 0 && fragmentNum <= 127)
{ {
Fragment * fragment = new Fragment; Fragment * fragment = new Fragment;
fragment->fragmentNum = fragmentNum; fragment->fragmentNum = fragmentNum;
@@ -332,7 +332,7 @@ namespace transport
payload++; payload++;
htobe32buf (payload, msgID); htobe32buf (payload, msgID);
payload += 4; payload += 4;
bool isLast = (len <= payloadSize); bool isLast = (len <= payloadSize) || fragmentNum == 127; // 127 fragments max
size_t size = isLast ? len : payloadSize; size_t size = isLast ? len : payloadSize;
uint32_t fragmentInfo = (fragmentNum << 17); uint32_t fragmentInfo = (fragmentNum << 17);
if (isLast) if (isLast)

View File

@@ -929,7 +929,13 @@ namespace transport
if (m_State == eSessionStateEstablished) if (m_State == eSessionStateEstablished)
{ {
for (const auto& it: msgs) for (const auto& it: msgs)
if (it) m_Data.Send (it); if (it)
{
if (it->GetLength () <= SSU_MAX_I2NP_MESSAGE_SIZE)
m_Data.Send (it);
else
LogPrint (eLogError, "SSU: I2NP message of size ", it->GetLength (), " can't be sent. Dropped");
}
} }
} }

View File

@@ -28,6 +28,7 @@ namespace transport
const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds
const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes
const int SSU_CLOCK_SKEW = 60; // in seconds const int SSU_CLOCK_SKEW = 60; // in seconds
const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768;
// payload types (4 bits) // payload types (4 bits)
const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0; const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0;

View File

@@ -6,6 +6,26 @@ namespace i2p
{ {
namespace crypto namespace crypto
{ {
#if OPENSSL_EDDSA
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey)
{
m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32);
m_MDCtx = EVP_MD_CTX_create ();
EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey);
}
EDDSA25519Verifier::~EDDSA25519Verifier ()
{
EVP_MD_CTX_destroy (m_MDCtx);
EVP_PKEY_free (m_Pkey);
}
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len);
}
#else
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey) EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey)
{ {
memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH); memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH);
@@ -14,6 +34,10 @@ namespace crypto
BN_CTX_free (ctx); BN_CTX_free (ctx);
} }
EDDSA25519Verifier::~EDDSA25519Verifier ()
{
}
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{ {
uint8_t digest[64]; uint8_t digest[64];
@@ -26,8 +50,9 @@ namespace crypto
return GetEd25519 ()->Verify (m_PublicKey, digest, signature); return GetEd25519 ()->Verify (m_PublicKey, digest, signature);
} }
#endif
EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) EDDSA25519SignerCompat::EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey)
{ {
// expand key // expand key
Ed25519::ExpandPrivateKey (signingPrivateKey, m_ExpandedPrivateKey); Ed25519::ExpandPrivateKey (signingPrivateKey, m_ExpandedPrivateKey);
@@ -47,10 +72,58 @@ namespace crypto
BN_CTX_free (ctx); BN_CTX_free (ctx);
} }
void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const EDDSA25519SignerCompat::~EDDSA25519SignerCompat ()
{
}
void EDDSA25519SignerCompat::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{ {
GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature);
} }
#if OPENSSL_EDDSA
EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey):
m_Fallback (nullptr)
{
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32);
uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH];
size_t len = EDDSA25519_PUBLIC_KEY_LENGTH;
EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len);
if (memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH))
{
LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback");
EVP_PKEY_free (m_Pkey);
m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey);
}
else
{
m_MDCtx = EVP_MD_CTX_create ();
EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey);
}
}
EDDSA25519Signer::~EDDSA25519Signer ()
{
if (m_Fallback) delete m_Fallback;
else
{
EVP_MD_CTX_destroy (m_MDCtx);
EVP_PKEY_free (m_Pkey);
}
}
void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
if (m_Fallback) return m_Fallback->Sign (buf, len, signature);
else
{
size_t l = 64;
uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232
EVP_DigestSign (m_MDCtx, sig, &l, buf, len);
memcpy (signature, sig, 64);
}
}
#endif
} }
} }

View File

@@ -6,7 +6,6 @@
#include <openssl/dsa.h> #include <openssl/dsa.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/rsa.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include "Crypto.h" #include "Crypto.h"
#include "Ed25519.h" #include "Ed25519.h"
@@ -149,6 +148,7 @@ namespace crypto
enum { hashLen = 64 }; enum { hashLen = 64 };
}; };
// EcDSA
template<typename Hash, int curve, size_t keyLen> template<typename Hash, int curve, size_t keyLen>
class ECDSAVerifier: public Verifier class ECDSAVerifier: public Verifier
{ {
@@ -269,97 +269,6 @@ namespace crypto
CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey); CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey);
} }
// RSA
template<typename Hash, int type, size_t keyLen>
class RSAVerifier: public Verifier
{
public:
RSAVerifier (const uint8_t * signingKey)
{
m_PublicKey = RSA_new ();
RSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, keyLen, NULL) /* n */ , BN_dup (GetRSAE ()) /* d */, NULL);
}
~RSAVerifier ()
{
RSA_free (m_PublicKey);
}
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
uint8_t digest[Hash::hashLen];
Hash::CalculateHash (buf, len, digest);
return RSA_verify (type, digest, Hash::hashLen, signature, GetSignatureLen (), m_PublicKey);
}
size_t GetPublicKeyLen () const { return keyLen; }
size_t GetSignatureLen () const { return keyLen; }
size_t GetPrivateKeyLen () const { return GetSignatureLen ()*2; };
private:
RSA * m_PublicKey;
};
template<typename Hash, int type, size_t keyLen>
class RSASigner: public Signer
{
public:
RSASigner (const uint8_t * signingPrivateKey)
{
m_PrivateKey = RSA_new ();
RSA_set0_key (m_PrivateKey, BN_bin2bn (signingPrivateKey, keyLen, NULL), /* n */
BN_dup (GetRSAE ()) /* e */, BN_bin2bn (signingPrivateKey + keyLen, keyLen, NULL) /* d */);
}
~RSASigner ()
{
RSA_free (m_PrivateKey);
}
void Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
uint8_t digest[Hash::hashLen];
Hash::CalculateHash (buf, len, digest);
unsigned int signatureLen = keyLen;
RSA_sign (type, digest, Hash::hashLen, signature, &signatureLen, m_PrivateKey);
}
private:
RSA * m_PrivateKey;
};
inline void CreateRSARandomKeys (size_t publicKeyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
RSA * rsa = RSA_new ();
BIGNUM * e = BN_dup (GetRSAE ()); // make it non-const
RSA_generate_key_ex (rsa, publicKeyLen*8, e, NULL);
const BIGNUM * n, * d, * e1;
RSA_get0_key (rsa, &n, &e1, &d);
bn2buf (n, signingPrivateKey, publicKeyLen);
bn2buf (d, signingPrivateKey + publicKeyLen, publicKeyLen);
bn2buf (n, signingPublicKey, publicKeyLen);
BN_free (e); // this e is not assigned to rsa->e
RSA_free (rsa);
}
// RSA_SHA256_2048
const size_t RSASHA2562048_KEY_LENGTH = 256;
typedef RSAVerifier<SHA256Hash, NID_sha256, RSASHA2562048_KEY_LENGTH> RSASHA2562048Verifier;
typedef RSASigner<SHA256Hash, NID_sha256, RSASHA2562048_KEY_LENGTH> RSASHA2562048Signer;
// RSA_SHA384_3072
const size_t RSASHA3843072_KEY_LENGTH = 384;
typedef RSAVerifier<SHA384Hash, NID_sha384, RSASHA3843072_KEY_LENGTH> RSASHA3843072Verifier;
typedef RSASigner<SHA384Hash, NID_sha384, RSASHA3843072_KEY_LENGTH> RSASHA3843072Signer;
// RSA_SHA512_4096
const size_t RSASHA5124096_KEY_LENGTH = 512;
typedef RSAVerifier<SHA512Hash, NID_sha512, RSASHA5124096_KEY_LENGTH> RSASHA5124096Verifier;
typedef RSASigner<SHA512Hash, NID_sha512, RSASHA5124096_KEY_LENGTH> RSASHA5124096Signer;
// EdDSA // EdDSA
class EDDSA25519Verifier: public Verifier class EDDSA25519Verifier: public Verifier
@@ -367,6 +276,8 @@ namespace crypto
public: public:
EDDSA25519Verifier (const uint8_t * signingKey); EDDSA25519Verifier (const uint8_t * signingKey);
~EDDSA25519Verifier ();
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; };
@@ -374,18 +285,25 @@ namespace crypto
private: private:
#if OPENSSL_EDDSA
EVP_PKEY * m_Pkey;
EVP_MD_CTX * m_MDCtx;
#else
EDDSAPoint m_PublicKey; EDDSAPoint m_PublicKey;
uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
#endif
}; };
class EDDSA25519Signer: public Signer class EDDSA25519SignerCompat: public Signer
{ {
public: public:
EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr);
// we pass signingPublicKey to check if it matches private key // we pass signingPublicKey to check if it matches private key
~EDDSA25519SignerCompat ();
void Sign (const uint8_t * buf, int len, uint8_t * signature) const; void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation
private: private:
@@ -393,11 +311,46 @@ namespace crypto
uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
}; };
#if OPENSSL_EDDSA
class EDDSA25519Signer: public Signer
{
public:
EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr);
// we pass signingPublicKey to check if it matches private key
~EDDSA25519Signer ();
void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
private:
EVP_PKEY * m_Pkey;
EVP_MD_CTX * m_MDCtx;
EDDSA25519SignerCompat * m_Fallback;
};
#else
typedef EDDSA25519SignerCompat EDDSA25519Signer;
#endif
inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{ {
#if OPENSSL_EDDSA
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL);
EVP_PKEY_keygen_init (pctx);
EVP_PKEY_keygen (pctx, &pkey);
EVP_PKEY_CTX_free (pctx);
size_t len = EDDSA25519_PUBLIC_KEY_LENGTH;
EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len);
len = EDDSA25519_PRIVATE_KEY_LENGTH;
EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len);
EVP_PKEY_free (pkey);
#else
RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH); RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
EDDSA25519Signer signer (signingPrivateKey); EDDSA25519Signer signer (signingPrivateKey);
memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH);
#endif
} }

View File

@@ -79,6 +79,7 @@ namespace transport
bool IsTerminationTimeoutExpired (uint64_t ts) const bool IsTerminationTimeoutExpired (uint64_t ts) const
{ return ts >= m_LastActivityTimestamp + GetTerminationTimeout (); }; { return ts >= m_LastActivityTimestamp + GetTerminationTimeout (); };
virtual void SendLocalRouterInfo () { SendI2NPMessages ({ CreateDatabaseStoreMsg () }); };
virtual void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) = 0; virtual void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) = 0;
protected: protected:

View File

@@ -117,7 +117,8 @@ namespace transport
Transports::Transports (): Transports::Transports ():
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr), m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr),
m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys m_NTCPServer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr),
m_DHKeysPairSupplier (5), // 5 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0),
m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0),
@@ -191,6 +192,13 @@ namespace transport
LogPrint(eLogError, "Transports: invalid NTCP proxy url ", ntcpproxy); LogPrint(eLogError, "Transports: invalid NTCP proxy url ", ntcpproxy);
return; return;
} }
// create NTCP2. TODO: move to acceptor
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2)
{
m_NTCP2Server = new NTCP2Server ();
m_NTCP2Server->Start ();
}
// create acceptors // create acceptors
auto& addresses = context.GetRouterInfo ().GetAddresses (); auto& addresses = context.GetRouterInfo ().GetAddresses ();
@@ -262,6 +270,13 @@ namespace transport
m_NTCPServer = nullptr; m_NTCPServer = nullptr;
} }
if (m_NTCP2Server)
{
m_NTCP2Server->Stop ();
delete m_NTCP2Server;
m_NTCP2Server = nullptr;
}
m_DHKeysPairSupplier.Stop (); m_DHKeysPairSupplier.Stop ();
m_IsRunning = false; m_IsRunning = false;
if (m_Service) m_Service->stop (); if (m_Service) m_Service->stop ();
@@ -386,7 +401,22 @@ namespace transport
{ {
if (peer.router) // we have RI already if (peer.router) // we have RI already
{ {
if (!peer.numAttempts) // NTCP if (!peer.numAttempts) // NTCP2
{
peer.numAttempts++;
if (m_NTCP2Server) // we support NTCP2
{
// NTCP2 have priority over NTCP
auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only
if (address)
{
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router);
m_NTCP2Server->Connect (address->host, address->port, s);
return true;
}
}
}
if (peer.numAttempts == 1) // NTCP1
{ {
peer.numAttempts++; peer.numAttempts++;
auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ());
@@ -446,7 +476,7 @@ namespace transport
else else
LogPrint (eLogDebug, "Transports: NTCP address is not present for ", i2p::data::GetIdentHashAbbreviation (ident), ", trying SSU"); LogPrint (eLogDebug, "Transports: NTCP address is not present for ", i2p::data::GetIdentHashAbbreviation (ident), ", trying SSU");
} }
if (peer.numAttempts == 1)// SSU if (peer.numAttempts == 2)// SSU
{ {
peer.numAttempts++; peer.numAttempts++;
if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ()))
@@ -709,7 +739,7 @@ namespace transport
sendDatabaseStore = false; // we have it in the list already sendDatabaseStore = false; // we have it in the list already
} }
if (sendDatabaseStore) if (sendDatabaseStore)
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); session->SendLocalRouterInfo ();
else else
session->SetTerminationTimeout (10); // most likely it's publishing, no follow-up messages expected, set timeout to 10 seconds session->SetTerminationTimeout (10); // most likely it's publishing, no follow-up messages expected, set timeout to 10 seconds
it->second.sessions.push_back (session); it->second.sessions.push_back (session);

View File

@@ -15,6 +15,7 @@
#include "TransportSession.h" #include "TransportSession.h"
#include "NTCPSession.h" #include "NTCPSession.h"
#include "SSU.h" #include "SSU.h"
#include "NTCP2.h"
#include "RouterInfo.h" #include "RouterInfo.h"
#include "I2NPProtocol.h" #include "I2NPProtocol.h"
#include "Identity.h" #include "Identity.h"
@@ -80,6 +81,7 @@ namespace transport
bool IsBoundNTCP() const { return m_NTCPServer != nullptr; } bool IsBoundNTCP() const { return m_NTCPServer != nullptr; }
bool IsBoundSSU() const { return m_SSUServer != nullptr; } bool IsBoundSSU() const { return m_SSUServer != nullptr; }
bool IsBoundNTCP2() const { return m_NTCP2Server != nullptr; }
bool IsOnline() const { return m_IsOnline; }; bool IsOnline() const { return m_IsOnline; };
void SetOnline (bool online) { m_IsOnline = online; }; void SetOnline (bool online) { m_IsOnline = online; };
@@ -154,6 +156,7 @@ namespace transport
NTCPServer * m_NTCPServer; NTCPServer * m_NTCPServer;
SSUServer * m_SSUServer; SSUServer * m_SSUServer;
NTCP2Server * m_NTCP2Server;
mutable std::mutex m_PeersMutex; mutable std::mutex m_PeersMutex;
std::map<i2p::data::IdentHash, Peer> m_Peers; std::map<i2p::data::IdentHash, Peer> m_Peers;
@@ -179,6 +182,7 @@ namespace transport
// for HTTP only // for HTTP only
const NTCPServer * GetNTCPServer () const { return m_NTCPServer; }; const NTCPServer * GetNTCPServer () const { return m_NTCPServer; };
const SSUServer * GetSSUServer () const { return m_SSUServer; }; const SSUServer * GetSSUServer () const { return m_SSUServer; };
const NTCP2Server * GetNTCP2Server () const { return m_NTCP2Server; };
const decltype(m_Peers)& GetPeers () const { return m_Peers; }; const decltype(m_Peers)& GetPeers () const { return m_Peers; };
}; };

View File

@@ -511,7 +511,7 @@ namespace tunnel
HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ());
break; break;
default: default:
LogPrint (eLogWarning, "Tunnel: unexpected messsage type ", (int) typeID); LogPrint (eLogWarning, "Tunnel: unexpected message type ", (int) typeID);
} }
msg = m_Queue.Get (); msg = m_Queue.Get ();

View File

@@ -7,7 +7,7 @@
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
#define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MAJOR 2
#define I2PD_VERSION_MINOR 19 #define I2PD_VERSION_MINOR 22
#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_MICRO 0
#define I2PD_VERSION_PATCH 0 #define I2PD_VERSION_PATCH 0
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
@@ -21,7 +21,7 @@
#define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MAJOR 0
#define I2P_VERSION_MINOR 9 #define I2P_VERSION_MINOR 9
#define I2P_VERSION_MICRO 35 #define I2P_VERSION_MICRO 37
#define I2P_VERSION_PATCH 0 #define I2P_VERSION_PATCH 0
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)

View File

@@ -377,7 +377,7 @@ namespace client
} }
numAddresses++; numAddresses++;
auto it = m_Addresses.find (name); auto it = m_Addresses.find (name);
if (it != m_Addresses.end ()) // aleady exists ? if (it != m_Addresses.end ()) // already exists ?
{ {
if (it->second != ident->GetIdentHash ()) // address changed? if (it->second != ident->GetIdentHash ()) // address changed?
{ {
@@ -741,7 +741,7 @@ namespace client
std::string response; std::string response;
uint8_t recv_buf[4096]; uint8_t recv_buf[4096];
bool end = false; bool end = false;
int numAttempts = 5; int numAttempts = 0;
while (!end) while (!end)
{ {
stream->AsyncReceive (boost::asio::buffer (recv_buf, 4096), stream->AsyncReceive (boost::asio::buffer (recv_buf, 4096),
@@ -755,7 +755,8 @@ namespace client
}, },
SUBSCRIPTION_REQUEST_TIMEOUT); SUBSCRIPTION_REQUEST_TIMEOUT);
std::unique_lock<std::mutex> l(newDataReceivedMutex); std::unique_lock<std::mutex> l(newDataReceivedMutex);
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) // wait 1 more second
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT + 1)) == std::cv_status::timeout)
{ {
LogPrint (eLogError, "Addressbook: subscriptions request timeout expired"); LogPrint (eLogError, "Addressbook: subscriptions request timeout expired");
numAttempts++; numAttempts++;

View File

@@ -410,18 +410,44 @@ namespace client
void ClientContext::ReadTunnels () void ClientContext::ReadTunnels ()
{ {
boost::property_tree::ptree pt; int numClientTunnels = 0, numServerTunnels = 0;
std::string tunConf; i2p::config::GetOption("tunconf", tunConf); std::string tunConf; i2p::config::GetOption("tunconf", tunConf);
if (tunConf == "") { if (tunConf.empty ())
{
// TODO: cleanup this in 2.8.0 // TODO: cleanup this in 2.8.0
tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
if (i2p::fs::Exists(tunConf)) { if (i2p::fs::Exists(tunConf))
LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); LogPrint(eLogWarning, "Clients: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
} else { else
tunConf = i2p::fs::DataDirPath ("tunnels.conf"); tunConf = i2p::fs::DataDirPath ("tunnels.conf");
} }
LogPrint(eLogDebug, "Clients: tunnels config file: ", tunConf);
ReadTunnels (tunConf, numClientTunnels, numServerTunnels);
std::string tunDir; i2p::config::GetOption("tunnelsdir", tunDir);
if (tunDir.empty ())
tunDir = i2p::fs::DataDirPath ("tunnels.d");
if (i2p::fs::Exists (tunDir))
{
std::vector<std::string> files;
if (i2p::fs::ReadDir (tunDir, files))
{
for (auto& it: files)
{
LogPrint(eLogDebug, "Clients: tunnels extra config file: ", it);
ReadTunnels (it, numClientTunnels, numServerTunnels);
} }
LogPrint(eLogDebug, "FS: tunnels config file: ", tunConf); }
}
LogPrint (eLogInfo, "Clients: ", numClientTunnels, " I2P client tunnels created");
LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created");
}
void ClientContext::ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels)
{
boost::property_tree::ptree pt;
try try
{ {
boost::property_tree::read_ini (tunConf, pt); boost::property_tree::read_ini (tunConf, pt);
@@ -432,7 +458,6 @@ namespace client
return; return;
} }
int numClientTunnels = 0, numServerTunnels = 0;
for (auto& section: pt) for (auto& section: pt)
{ {
std::string name = section.first; std::string name = section.first;
@@ -500,7 +525,8 @@ namespace client
if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS) if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS)
{ {
// socks proxy // socks proxy
auto tun = std::make_shared<i2p::proxy::SOCKSProxy>(name, address, port, false, "", destinationPort, localDestination); std::string outproxy = section.second.get("outproxy", "");
auto tun = std::make_shared<i2p::proxy::SOCKSProxy>(name, address, port, !outproxy.empty(), outproxy, destinationPort, localDestination);
clientTunnel = tun; clientTunnel = tun;
clientEndpoint = tun->GetLocalEndpoint (); clientEndpoint = tun->GetLocalEndpoint ();
} }
@@ -671,8 +697,6 @@ namespace client
LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());
} }
} }
LogPrint (eLogInfo, "Clients: ", numClientTunnels, " I2P client tunnels created");
LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created");
} }
void ClientContext::ReadHttpProxy () void ClientContext::ReadHttpProxy ()

View File

@@ -87,6 +87,7 @@ namespace client
private: private:
void ReadTunnels (); void ReadTunnels ();
void ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels);
void ReadHttpProxy (); void ReadHttpProxy ();
void ReadSocksProxy (); void ReadSocksProxy ();
template<typename Section, typename Type> template<typename Section, typename Type>

View File

@@ -387,7 +387,7 @@ namespace proxy {
LogPrint(eLogDebug, "HTTPProxy: ", m_ClientRequestURL.host); LogPrint(eLogDebug, "HTTPProxy: ", m_ClientRequestURL.host);
m_ClientRequestURL.schema = ""; m_ClientRequestURL.schema = "";
m_ClientRequestURL.host = ""; m_ClientRequestURL.host = "";
std::string origURI = m_ClientRequest.uri; // TODO: what do we need to chage uri for? std::string origURI = m_ClientRequest.uri; // TODO: what do we need to change uri for?
m_ClientRequest.uri = m_ClientRequestURL.to_string(); m_ClientRequest.uri = m_ClientRequestURL.to_string();
m_ClientRequest.write(m_ClientRequestBuffer); m_ClientRequest.write(m_ClientRequestBuffer);

View File

@@ -250,7 +250,7 @@ namespace client
if (handler) if (handler)
(this->*handler)(m_Payload, m_PayloadLen); (this->*handler)(m_Payload, m_PayloadLen);
else else
LogPrint (eLogError, "I2CP: Unknown I2CP messsage ", (int)m_Header[I2CP_HEADER_TYPE_OFFSET]); LogPrint (eLogError, "I2CP: Unknown I2CP message ", (int)m_Header[I2CP_HEADER_TYPE_OFFSET]);
} }
void I2CPSession::Terminate () void I2CPSession::Terminate ()
@@ -398,7 +398,7 @@ namespace client
} }
else else
{ {
LogPrint (eLogError, "I2CP: create session signature verification falied"); LogPrint (eLogError, "I2CP: create session signature verification failed");
SendSessionStatusMessage (3); // invalid SendSessionStatusMessage (3); // invalid
} }
} }
@@ -455,16 +455,16 @@ namespace client
LogPrint(eLogError, "I2CP: invalid reconfigure message signature"); LogPrint(eLogError, "I2CP: invalid reconfigure message signature");
} }
else else
LogPrint(eLogError, "I2CP: mapping size missmatch"); LogPrint(eLogError, "I2CP: mapping size mismatch");
} }
else else
LogPrint(eLogError, "I2CP: destination missmatch"); LogPrint(eLogError, "I2CP: destination mismatch");
} }
else else
LogPrint(eLogError, "I2CP: malfromed destination"); LogPrint(eLogError, "I2CP: malfromed destination");
} }
else else
LogPrint(eLogError, "I2CP: session missmatch"); LogPrint(eLogError, "I2CP: session mismatch");
} }
else else
LogPrint(eLogError, "I2CP: short message"); LogPrint(eLogError, "I2CP: short message");

View File

@@ -1027,12 +1027,30 @@ namespace client
{ {
auto it = params->find (SAM_PARAM_SIGNATURE_TYPE); auto it = params->find (SAM_PARAM_SIGNATURE_TYPE);
if (it != params->end ()) if (it != params->end ())
{
// TODO: extract string values // TODO: extract string values
try
{
signatureType = std::stoi(it->second); signatureType = std::stoi(it->second);
}
catch (const std::exception& ex)
{
LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, "error: ", ex.what ());
}
}
it = params->find (SAM_PARAM_CRYPTO_TYPE); it = params->find (SAM_PARAM_CRYPTO_TYPE);
if (it != params->end ()) if (it != params->end ())
{
try
{
cryptoType = std::stoi(it->second); cryptoType = std::stoi(it->second);
} }
catch (const std::exception& ex)
{
LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ());
}
}
}
localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params);
} }
if (localDestination) if (localDestination)

View File

@@ -46,7 +46,7 @@ namespace client
const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n"; const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n";
const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n"; const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n";
const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n";
const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=INVALID_KEY_NOT_FOUND NAME=%s\n"; const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=KEY_NOT_FOUND NAME=%s\n";
const char SAM_PARAM_MIN[] = "MIN"; const char SAM_PARAM_MIN[] = "MIN";
const char SAM_PARAM_MAX[] = "MAX"; const char SAM_PARAM_MAX[] = "MAX";
const char SAM_PARAM_STYLE[] = "STYLE"; const char SAM_PARAM_STYLE[] = "STYLE";

View File

@@ -84,8 +84,8 @@ namespace proxy
SOCKS5_HOST_UNREACH = 4, // Host unreachable SOCKS5_HOST_UNREACH = 4, // Host unreachable
SOCKS5_CONN_REFUSED = 5, // Connection refused by the peer SOCKS5_CONN_REFUSED = 5, // Connection refused by the peer
SOCKS5_TTL_EXPIRED = 6, // TTL Expired SOCKS5_TTL_EXPIRED = 6, // TTL Expired
SOCKS5_CMD_UNSUP = 7, // Command unsuported SOCKS5_CMD_UNSUP = 7, // Command unsupported
SOCKS5_ADDR_UNSUP = 8, // Address type unsuported SOCKS5_ADDR_UNSUP = 8, // Address type unsupported
SOCKS4_OK = 90, // No error for SOCKS4 SOCKS4_OK = 90, // No error for SOCKS4
SOCKS4_FAIL = 91, // Failed establishing connecting or not allowed SOCKS4_FAIL = 91, // Failed establishing connecting or not allowed
SOCKS4_IDENTD_MISSING = 92, // Couldn't connect to the identd server SOCKS4_IDENTD_MISSING = 92, // Couldn't connect to the identd server

View File

@@ -31,16 +31,15 @@ void ClientTunnelConfig::saveToStringStream(std::stringstream& out) {
out << "address=" << address << "\n" out << "address=" << address << "\n"
<< "port=" << port << "\n" << "port=" << port << "\n"
<< "destination=" << dest << "\n" << "destination=" << dest << "\n"
<< "keys=" << keys << "\n"
<< "destinationport=" << destinationPort << "\n" << "destinationport=" << destinationPort << "\n"
<< "signaturetype=" << sigType << "\n"; << "signaturetype=" << sigType << "\n";
if(!keys.empty()) out << "keys=" << keys << "\n";
} }
void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
out << "host=" << host << "\n" out << "host=" << host << "\n"
<< "port=" << port << "\n" << "port=" << port << "\n"
<< "keys=" << keys << "\n"
<< "signaturetype=" << sigType << "\n" << "signaturetype=" << sigType << "\n"
<< "inport=" << inPort << "\n" << "inport=" << inPort << "\n"
<< "accesslist=" << accessList << "\n" << "accesslist=" << accessList << "\n"
@@ -49,5 +48,6 @@ void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
<< "address=" << address << "\n" << "address=" << address << "\n"
<< "hostoverride=" << hostOverride << "\n" << "hostoverride=" << hostOverride << "\n"
<< "webircpassword=" << webircpass << "\n"; << "webircpassword=" << webircpass << "\n";
if(!keys.empty()) out << "keys=" << keys << "\n";
} }

View File

@@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.19.0" android:versionCode="2" android:installLocation="auto"> <manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.22.0" android:versionCode="1" android:installLocation="auto">
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/> <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- <application android:hardwareAccelerated="true" --> <!-- <application android:hardwareAccelerated="true" -->

View File

@@ -51,7 +51,7 @@ interface IMinistro
* "sources" StringArray Sources list from where Ministro will download the libs. Make sure you are using ONLY secure locations. * "sources" StringArray Sources list from where Ministro will download the libs. Make sure you are using ONLY secure locations.
* "repository" String Overwrites the default Ministro repository. Possible values: default, stable, testing and unstable * "repository" String Overwrites the default Ministro repository. Possible values: default, stable, testing and unstable
* "required.modules" StringArray Required modules by your application * "required.modules" StringArray Required modules by your application
* "application.title" String Application name, used to show more informations to user * "application.title" String Application name, used to show more information to user
* "qt.provider" String Qt libs provider, currently only "necessitas" is supported. * "qt.provider" String Qt libs provider, currently only "necessitas" is supported.
* "minimum.ministro.api" Integer Minimum Ministro API level, used to check if Ministro service compatible with your application. Current API Level is 3 ! * "minimum.ministro.api" Integer Minimum Ministro API level, used to check if Ministro service compatible with your application. Current API Level is 3 !
* "minimum.qt.version" Integer Minimim Qt version (e.g. 0x040800, which means Qt 4.8.0, check http://qt-project.org/doc/qt-4.8/qtglobal.html#QT_VERSION)! * "minimum.qt.version" Integer Minimim Qt version (e.g. 0x040800, which means Qt 4.8.0, check http://qt-project.org/doc/qt-4.8/qtglobal.html#QT_VERSION)!

View File

@@ -97,7 +97,7 @@ import android.view.ActionMode.Callback;
public class QtActivity extends Activity public class QtActivity extends Activity
{ {
private final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro instalation is finished private final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro installation is finished
private static final int MINISTRO_API_LEVEL = 5; // Ministro api level (check IMinistro.aidl file) private static final int MINISTRO_API_LEVEL = 5; // Ministro api level (check IMinistro.aidl file)
private static final int NECESSITAS_API_LEVEL = 2; // Necessitas api level used by platform plugin private static final int NECESSITAS_API_LEVEL = 2; // Necessitas api level used by platform plugin
private static final int QT_VERSION = 0x050100; // This app requires at least Qt version 5.1.0 private static final int QT_VERSION = 0x050100; // This app requires at least Qt version 5.1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Some files were not shown because too many files have changed in this diff Show More