Compare commits

...

3136 Commits

Author SHA1 Message Date
2fa7a48163 2.21.0 2018-10-04 10:17:33 -04:00
8adf76dcc9 2.21.0 2018-10-04 09:46:10 -04:00
15899c10b2 2.21.0 2018-10-04 09:38:04 -04:00
05ff05ea4b Merge pull request #1246 from 3pdotsif/openssl
added NTCP2 to qt.pro ; fix for #1111
2018-10-02 11:33:07 -04:00
bd62df48c2 added NTCP2 to qt.pro ; made tunnel conf param keys be optional (fixes #1111) 2018-10-02 23:09:01 +08:00
2366cbc833 count outgoing tags 2018-10-01 18:11:44 +03:00
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
af793395f0 don't publish O with X or P 2018-09-30 16:08:26 -04:00
8f41776858 check send queue size 2018-09-28 09:54:42 -04:00
139b13b8d1 openssl 1.1.1/boost 1.64 for andoroid binary only 2018-09-27 10:31:32 -04:00
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
5e7a21e177 try to fix working of service on api 26+ 2018-09-25 03:37:34 +03:00
5f7dda5ba8 treat extra bandwidth as high bandwidth 2018-09-22 14:12:46 -04:00
2dfa1ca0f2 check RouterInfo's timestamp in SessionConfirmed 2018-09-21 11:45:04 -04:00
358cdcf4c4 removed RSA signatures completly 2018-09-21 11:16:38 -04:00
c8f4ace5c4 update timestamp before publishing 2018-09-21 10:13:18 -04:00
5cac6ca8bb read message body immediatly after length 2018-09-17 13:08:49 -04:00
fccad71df1 temporary buffer for EdDSA signature for openssl 1.1.1 2018-09-16 18:08:59 -04:00
97ae2674dc always use EdDsa signer fallback 2018-09-14 21:54:45 -04:00
7c70affd7f eddsa signer fallback 2018-09-14 21:23:16 -04:00
52ff568d86 fixed incorrect second signature 2018-09-14 18:58:40 -04:00
b917aeaa0b openssl 1.1.1/boost 1.64 for android 2018-09-13 09:43:10 -04:00
8de443ec4c siphash from openssl 1.1.1 2018-09-11 13:26:29 -04:00
7d9893c614 fixed build error 2018-09-09 17:27:53 -04:00
3540712517 some cleanup 2018-09-09 08:38:12 -04:00
a8b1a86bd7 X25519Keys for static key 2018-09-08 22:08:08 -04:00
1babd3a5a2 separate X25519Keys 2018-09-08 16:52:42 -04:00
50399e5194 fix #1238 (#1239) 2018-09-06 21:27:28 +00:00
b734acf1b1 -latomic for gcc >= 5 only 2018-09-06 11:19:10 -04:00
33aa8e2471 use x25519 from openssl 1.1.1 for ephemeral keys 2018-09-05 11:19:58 -04:00
2c58fe736b fixed build error with openssl 1.1.1 2018-09-05 09:51:03 -04:00
6fe1de5d86 fix make target dependecy 2018-09-04 10:51:44 +03:00
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
2c3b19a539 use EdDSA from openssl 1.1.1 2018-09-03 17:39:49 -04:00
dc30a4c1ae Merge pull request #1234 from l-n-s/fix_typo
Fix typo
2018-09-02 15:50:22 -04:00
86e9901bf2 Fix typo 2018-09-02 15:39:23 -04:00
6519e0835a fixed typo 2018-09-02 07:51:58 -04:00
a52344fc01 Merge pull request #1226 from radfish/PR--make-latomic
makefile: linux: add -latomic
2018-09-01 13:31:17 -04:00
b67424643d done insert NTCP2 ipv6 address twice 2018-08-27 18:56:57 -04:00
575a4c01c9 publish NTCP2 adress if port is specified 2018-08-27 18:35:35 -04:00
f0d4ee6618 pass NTCP2 ipv6 address 2018-08-27 16:01:47 -04:00
8753186a0d publish NTCP2 ipv6 address if applicable 2018-08-27 15:01:43 -04:00
ff8fb8000d Merge pull request #1231 from majestrate/fix-socks-outproxy
enable outproxy on socks
2018-08-26 10:20:39 -04:00
9dd38b99d6 check NTCP2 for addreses comparison 2018-08-26 09:40:27 -04:00
dfe08c1ec9 enable outproxy on socks 2018-08-26 09:24:11 -04:00
062d8d0f4f fixed potential race condition 2018-08-25 13:27:03 -04:00
c0d1e2c07a 2.20 2018-08-23 18:10:05 +03:00
e70feceafe add install target in OSX Makefile for homebrew formula 2018-08-23 18:06:37 +03:00
71ac0286b1 2.20.0 2018-08-23 10:24:44 -04:00
022f4d2c11 don't send message to not established session 2018-08-23 07:23:50 -04:00
a83a839cff Build docker image from openssl branch 2018-08-22 18:22:54 -04:00
b259ee89aa send RouterInfo from NTCP2Server's thread 2018-08-22 12:33:43 -04:00
65cf14bfce update android miniupnpc to 2.1 2018-08-20 01:01:27 +03:00
d9476fb5ca set correct IV when NTCP2 address gets published 2018-08-19 16:17:57 -04:00
9882365ab4 fix NTCP IPv6 category name in transports, add conversion for leasesets expiring time 2018-08-18 22:56:31 +00:00
2d758ce963 change cost for NTCP and NTCP2 2018-08-18 13:52:35 -04:00
1dd003d26a check m2p3len 2018-08-18 08:27:36 -04:00
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
e190a005db make sure assets are ready before proceed 2018-08-17 11:17:17 -04:00
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
405429a300 android - add file for notify about successful unpacking assets 2018-08-16 23:34:05 +03:00
d009a29426 android - dont rewrite files from assets if they exist 2018-08-16 23:34:04 +03:00
f1fb42460a rename ipv6 transports 2018-08-16 23:34:04 +03:00
5e110e9f7b enable NTCP2 by default 2018-08-16 13:48:47 -04:00
77a409935d license added 2018-08-16 13:46:59 -04:00
863baeb68b ignore unpublished addresses 2018-08-16 11:02:53 -04:00
11142690a0 show correct value of time drift 2018-08-16 10:13:32 -04:00
02e8c5faca fixed typo 2018-08-15 13:23:10 -04:00
c41081d35c check timestamps 2018-08-15 11:42:56 -04:00
db4c26a400 copy assets before daemon start 2018-08-15 09:52:13 -04:00
331a23fc20 build JNI for arm v7a and x86 both 2018-08-14 22:44:08 +03:00
db5a40d743 enable NTCP2 for android, use L flag for bandwidth,
additional change for multiarch build
2018-08-14 22:41:12 +03:00
e4ab51329d move handshake messages processing to NTCP2Establisher 2018-08-14 14:01:04 -04:00
86782aeb1b don't send RouterInfo twice 2018-08-14 11:27:27 -04:00
49a44fc92e assume siphash IV in Litte Endian 2018-08-13 14:07:57 -04:00
cd39a52c25 correct endianness for siphash length 2018-08-13 13:43:51 -04:00
634101ceb5 Update HTTPServer.cpp
Fix transport sections in web interface 2
2018-08-13 22:29:58 +05:00
55555c8787 Merge pull request #1222 from PurpleI2P/show-transports
Update HTTPServer.cpp
2018-08-13 12:43:31 -04:00
d36d825ac1 Update HTTPServer.cpp
Fix transport sections in web interface
2018-08-13 21:41:43 +05:00
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
29b91075d2 Don't add SSU/NTCP addresses to RI if they are disabled in config (#1220) 2018-08-12 02:36:00 -04:00
6d46fc9f9f check send frame error code 2018-08-11 16:08:21 -04:00
a2c41c9e36 allow NTCP2 only transports 2018-08-10 15:35:43 -04:00
ee700ac861 fixed incorrect iv for published NTCP2 addresses 2018-08-10 15:14:07 -04:00
9884a4336f don't connect to NTCP2 only address using NTCP 2018-08-10 13:42:59 -04:00
5b83d4bef8 move handshake messages creation to NTCP2Establisher 2018-08-10 10:53:34 -04:00
d320a89590 don't copy buffer to ifself 2018-08-09 16:32:43 -04:00
f7e4afc282 use same buffer for input and output for AEAD/Chacha20/Poly1305 2018-08-09 15:47:02 -04:00
88e87d589b add incoming NTCP2 session to the sessions list 2018-08-09 14:20:10 -04:00
d8c6dede7e moved NTCP2 handshake buffers to establisher 2018-08-09 12:53:36 -04:00
5cc84133e3 fixed incorrect lenght 2018-08-08 17:38:21 -04:00
f7728aa1f6 reuse NTCP2 frame buffers 2018-08-08 16:23:44 -04:00
2b61f9a731 fixed #1217. verify decryption result 2018-08-07 10:35:25 -04:00
f407022fe6 connect to NTCP2 address if presented 2018-08-04 13:48:09 -04:00
41b9f19b01 get unpublished NTCP2 address 2018-08-04 08:47:58 -04:00
09c6faf923 don't overwrite NTCP2 keys 2018-08-03 21:16:35 -04:00
26d0177c01 always make NTCP address first 2018-08-03 20:28:29 -04:00
f7415c8a8f enable/disable NTCP2 address 2018-08-03 14:49:28 -04:00
4cf79088f9 NTCP2 idle timeout 2018-08-03 13:19:35 -04:00
50cd321818 NTCP2 idle timeout 2018-08-03 13:10:32 -04:00
83bbe6a9d9 show NTCP2 address 2018-08-03 12:07:09 -04:00
0a33c18e36 send termination message 2018-08-02 15:31:15 -04:00
6cf158ac63 check RouterInfo from SessionConfirmed 2018-08-02 13:58:47 -04:00
f96bfa6afa send RouterInfo 2018-08-02 12:42:39 -04:00
2b64cf9126 publish i in correct place for NTCP2 2018-08-01 12:28:34 -04:00
a8dcfc44f5 handle termination message 2018-08-01 09:43:48 -04:00
0ff9c9da27 complete Bob side of NTCP2 2018-07-31 15:41:13 -04:00
07e7c2d852 ntcp2.published and ntcp2.port parameters 2018-07-31 12:59:38 -04:00
10e4b5b2a3 ignore NTCP2 addresses 2018-07-23 15:44:36 -04:00
998653ea9d NTCP2 acceptors 2018-07-23 15:30:51 -04:00
1a38e925bf publish NTCP2 address 2018-07-23 13:51:29 -04:00
c8f51380e6 publish NTCP2 for new routers 2018-07-21 16:59:58 -04:00
2406d57d51 update android target API to 28, use gradle and ndk parallel building 2018-07-21 00:02:54 +03:00
cb1e47eb71 use preconfigured configs for android package 2018-07-20 23:15:22 +03:00
c0a650f28b update gitignore 2018-07-20 23:04:29 +03:00
460cf6fd20 update windows build script, change makefile.mingw line ending 2018-07-20 22:57:47 +03:00
5bedfc1c84 post I2NP messages to NTCP2 thread 2018-07-19 12:46:19 -04:00
5001592fb4 replace ntcp2 by ntcp2.enabled 2018-07-19 09:45:24 -04:00
f6495e59c5 better MixHash 2018-07-19 09:27:59 -04:00
66bf431481 correct KDF1 calculation 2018-07-18 16:27:43 -04:00
d9685e991e handle RouterInfo block 2018-07-18 15:57:18 -04:00
e0790700cd don't connect to unpublished NTCP2 addresses 2018-07-18 14:19:12 -04:00
910a9600bd display NTCP2 session in web console 2018-07-18 12:58:29 -04:00
fc52b2b940 fixed typo 2018-07-18 12:56:46 -04:00
b99f828583 send I2NP messages through NTCP2 2018-07-18 11:16:40 -04:00
f38891cace fixed build for gcc < 4.8 2018-07-18 11:15:27 -04:00
8c5111e11a handle NTCP2 I2NP messages 2018-07-17 15:17:05 -04:00
5575b981c8 enable NTCP2 as transport 2018-07-13 15:59:28 -04:00
0b36732911 Merge pull request #1212 from yangfl/upstream
fix typo
2018-07-10 06:59:35 -04:00
52f3081a40 fix typo 2018-07-10 17:39:21 +08:00
00c71dc26a handle SessionConfirmed 2018-07-09 15:56:23 -04:00
5218c8584f some refactoring of NTCP2 code 2018-07-04 14:15:40 -04:00
6054bd6621 NTCP2 session establisher 2018-07-03 16:26:02 -04:00
55af4ed385 delete old AESNI definition 2018-06-29 02:30:03 +03:00
64aee9c8ae add DEBUG option for make
By default, binary will be built without stripping debug symbols
2018-06-29 02:27:19 +03:00
5233e72205 add assets symlinks 2018-06-27 23:56:52 +03:00
db5b45222a store and install assets on android 2018-06-27 23:56:52 +03:00
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
4ffbb46cf9 Fix "macro expansion producing 'defined' has undefined behavior" clang warning 2018-06-27 22:31:01 +03:00
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
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
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
dec848f072 use builtin __AVX__ and __AES__ macros and reduce code duplication 2018-06-27 17:32:38 +08:00
fc16e76af1 2.19.0 2018-06-26 17:46:01 +00:00
0dff636dbe 2.19.0 2018-06-26 13:38:02 -04:00
00df3f8d4e 2.19.0 2018-06-26 13:36:30 -04:00
34c45f2694 update debian changelog 2018-06-26 20:05:33 +03:00
a188de2e5c increase limits by default, fix symbolic links, change rules 2018-06-26 20:05:33 +03:00
27fbf67352 add systemd configs, change build info, update changelog 2018-06-26 20:05:33 +03:00
b226e22d2f fixed QT build 2018-06-26 07:25:16 -04:00
5bc157eb19 send data frame for NTCP2 2018-06-25 12:28:07 -04:00
f4122abbad Merge pull request #1201 from PurpleI2P/revert-1200-use-explicitpeer-settings
Revert "Read explicitPeer config settings into params"
2018-06-24 06:46:41 -04:00
f0b32e3f54 Revert "Read explicitPeer config settings into params" 2018-06-24 06:46:22 -04:00
fe00999b2c Merge pull request #1200 from shakamd/use-explicitpeer-settings
Read explicitPeer config settings into params
2018-06-24 06:26:21 -04:00
39eed0f6fb Read explicitPeer config settings into params 2018-06-23 23:52:16 +00:00
510d29b381 gcc 8 arch support 2018-06-23 06:56:05 -04:00
0aa618b938 process AEAD/Chacha20/Poly1305 frame for data phase of NTCP2 2018-06-22 15:02:49 -04:00
5884852612 correct usage of sipkeys 2018-06-22 12:20:35 -04:00
5b29592174 generate sipkeys for data pahse of NTCP2 2018-06-21 16:24:19 -04:00
96411cc93e derive keys for siphash 2018-06-21 12:39:24 -04:00
7d862d8eba service and daemon works as bool without values, other requires true/false 2018-06-21 09:40:53 +03:00
dd392941d0 update Config.cpp, links to examples, manpage 2018-06-21 09:40:53 +03:00
3cec5235c9 NTCP2 according to new specs 2018-06-20 16:09:22 -04:00
b5682012d3 process SessionRequest and send SessionCreated for NTCP2 2018-06-19 15:43:47 -04:00
4351a2736c Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2018-06-19 11:17:14 -04:00
9c7cadb191 better implementation of x25519 2018-06-19 11:14:22 -04:00
4d9143734f store standart configs as docs in deb packages 2018-06-19 15:11:48 +03:00
3cec923294 Update tunnels.conf 2018-06-19 15:08:16 +03:00
58c92b8405 aead/chacha20/poly1305 from openssl 1.1 2018-06-18 12:56:47 -04:00
985b618932 addng forgotten bracket 2018-06-16 23:07:03 +03:00
a027a42c46 fix links to online documentation in manpage 2018-06-16 22:57:18 +03:00
bdc7acffbe remove zero_tokens(), update manpage 2018-06-16 22:38:59 +03:00
6bd73cdea2 Update help message, debian manpage. Prepare changelog message 2018-06-16 18:11:46 +03:00
59954c1d7c Merge pull request #1194 from l-n-s/doc_update
Update contrib/i2pd.conf file with more options
2018-06-16 12:28:42 +00:00
a59cdcc9e0 Update contrib/i2pd.conf file with more options 2018-06-16 08:05:43 -04:00
e1bfa786fc fix #1192 2018-06-16 11:59:54 +03:00
d5214099c5 move out android binary build info from README
little change in MSYS build script
2018-06-16 10:55:59 +03:00
e05110ff44 send RouterInfo in SessionConfirmed 2018-06-15 14:56:03 -04:00
706b976a28 handle and publish NTCP2 address 2018-06-15 12:52:43 -04:00
2bd7a92d20 send SessionConfirmed 2018-06-14 15:29:36 -04:00
6b37a41e00 correct ad calculation for SessionCreated 2018-06-14 10:45:25 -04:00
5447259e1a AEAD/ChaCha20/Poly1305 decryption and SessionCreate prcessing 2018-06-13 16:16:23 -04:00
ee0ae0b74b decrypt Y for NTCP2 2018-06-13 14:56:51 -04:00
966256ac32 correct Poly1305 calculation 2018-06-13 12:58:32 -04:00
6b9061515f AEAD/ChaCha20/Poly1305 test added 2018-06-13 12:25:32 -04:00
df60e78766 AEAD/Chacha20/Poly1305 encryption 2018-06-13 11:41:46 -04:00
bf1e1ad457 eliminate extra dependencies 2018-06-13 10:49:14 -04:00
7fa5b06359 x25519 unti test 2018-06-12 18:29:06 -04:00
3b46e9f351 fixed typo 2018-06-12 14:55:40 -04:00
046a80cfe4 scalar multiplication for x25519 2018-06-12 12:42:20 -04:00
a8278fc78b router's NTCP2 private keys 2018-06-11 15:33:48 -04:00
7f3127ac89 pass unencrypted X to KDF 2018-06-11 14:32:15 -04:00
7cdb021a1f pass correct nonce to chacha20 2018-06-11 14:05:30 -04:00
74c0b729c2 connect to NTCP2 2018-06-11 12:29:30 -04:00
5cb81f8532 send SessionRequest message 2018-06-06 15:38:18 -04:00
4f23d7b7df recognize routers with NTCP2 2018-06-06 11:51:34 -04:00
a70d0edf2e encrypt SessionRequest options block 2018-06-05 16:15:33 -04:00
8c9eaccc11 KeyDerivationFunction for NTCP2 2018-06-05 15:37:08 -04:00
86c1984982 NTCP2 added 2018-06-05 12:53:13 -04:00
cd0f75106a moved Ed25519 away from signature 2018-06-04 16:06:38 -04:00
b5291b5151 Merge pull request #1190 from vmon/resolve--tunnel-get-ready-timout-bug
fixes #1124 and calls the ready callbacks if the tunnel gets ready an…
2018-05-29 09:10:02 -04:00
46283dc0ea fixes #1124 and calls the ready callbacks if the tunnel gets ready and no timeout is set 2018-05-28 17:14:17 -04:00
56e76ec59f fix using debug library compilation in release mode 2018-05-28 19:41:23 +03:00
4cedaa9e80 fixed android build 2018-05-28 09:49:59 -04:00
516f140bef ntcp2 crypto added 2018-05-24 14:32:14 -04:00
5d86c1c9a6 ntcp2 crypto added 2018-05-24 14:27:26 -04:00
d289aa71eb Merge pull request #1184 from mewmew-i2p/openssl
closes #1164 (i.e. added a log viewer to qt), + misc cosmetic
2018-05-19 14:44:39 -04:00
ed2818eaa2 qt log viewer now works 2018-05-19 23:06:06 +08:00
f8fe124428 improved comment at qt.pro file 2018-05-19 23:06:06 +08:00
5ec11c53e9 differentiation between windows release and debug build into i2pd_qt.pro 2018-05-19 23:06:05 +08:00
42d118d9a2 Merge pull request #1182 from l-n-s/issue_1178
Add /etc/resolv.conf to apparmor profile and k flag for pidfile
2018-05-18 19:56:29 +00:00
d8b4765f23 Add /etc/resolv.conf to apparmor profile and k flag for pidfile 2018-05-18 15:54:39 -04:00
be69280d0d Merge pull request #1181 from l-n-s/issue_1177
Restore reseed certificate hottuna_at_mail.i2p.crt
2018-05-18 19:47:32 +00:00
53a1a097a6 Restore reseed certificate hottuna_at_mail.i2p.crt 2018-05-18 15:45:35 -04:00
a22e9a2ca7 don't start shared local destination twice 2018-04-30 13:34:16 -04:00
db03595473 correct message size 2018-04-29 18:05:28 -04:00
8fadac0fdc Merge pull request #1172 from majestrate/check-boundary-04-2018
Check boundary
2018-04-29 18:04:15 -04:00
a63bc1cdca correct sizes 2018-04-29 11:41:03 -04:00
6265d452e9 more bounds checking 2018-04-29 11:34:23 -04:00
b095399770 Merge pull request #1170 from unlnown542a/openssl
Separated buld directory for Android i2pd only binary
2018-04-26 17:19:39 -04:00
Al
db8a546b8f android i2pd executable build instructions 2018-04-26 20:07:51 +00:00
6e95318cba I2PD_LIBS_PATH = /path/to/libraries to be same as in android normal build 2018-04-26 22:44:32 +03:00
08a8ab9892 format 2018-04-26 22:42:12 +03:00
c7b796ff31 separate Android binary build based on DaemonLinux 2018-04-26 22:40:13 +03:00
ad23ccb219 separating android binary build 2018-04-26 22:28:30 +03:00
Al
be7a84fdf3 Merge pull request #2 from PurpleI2P/openssl
sync with main repo
2018-04-26 16:53:56 +00:00
2fbbbf298b use shared pointers for tunnel reload 2018-04-25 16:18:07 -04:00
0df68872ab Merge pull request #1169 from majestrate/master
SAM fixes
2018-04-25 12:02:51 -04:00
0ced38cdcb tabify 2018-04-25 11:27:56 -04:00
b046c45a9e tabify 2018-04-25 11:25:49 -04:00
2ce1ab1634 Merge pull request #1168 from mewmew-i2p/openssl
perfecting qt status page
2018-04-25 10:21:17 -04:00
7225231814 perfecting qt status page 2018-04-25 16:36:42 +08:00
11dca2b352 Merge pull request #1167 from borned-mind/openssl
Delete some for correct compilation
2018-04-24 15:04:12 -04:00
97127e86dc Delete some for correct compilation 2018-04-25 01:59:11 +07:00
cb81195959 Merge pull request #1166 from borned-mind/openssl
Disable aesenc for arm64
2018-04-24 14:51:57 -04:00
adaff9f354 Merge branch 'openssl' of https://github.com/borned-mind/i2pd into openssl 2018-04-25 01:34:40 +07:00
66de7ad049 for first time disable aesenc for arm64 2018-04-24 18:23:40 +00:00
1e1e4da144 delete buffer 2018-04-24 14:02:48 -04:00
623433099b don't use reset 2018-04-24 11:50:51 -04:00
73b3fbc2da wrap m_OpenSockets with mutex 2018-04-24 11:42:37 -04:00
5f525d0e43 fix previous commit 2018-04-24 11:16:15 -04:00
60463fdafa shut down socket and don't allocate buffer for each write in WriteI2PData 2018-04-24 11:11:48 -04:00
b7a67b4b03 use refernce not copy 2018-04-24 09:56:24 -04:00
4643c92d33 Initial SAM cleanup 2018-04-24 09:45:16 -04:00
396cba7339 fix static building on windows, add resource files (closes #1163) 2018-04-24 03:25:25 +03:00
a2b3ee53e0 fixed build error 2018-04-23 14:39:46 -04:00
2c67d2055c Merge pull request #1161 from mewmew-i2p/openssl
qt now statically compiles for win32
2018-04-23 13:45:55 -04:00
c8de7aa23c qt now statically compiles for win32 2018-04-24 01:40:12 +08:00
fa154cc4d6 Merge remote-tracking branch 'purple/openssl' 2018-04-22 07:52:49 -04:00
d9b8731ddc Merge pull request #1160 from unlnown542a/openssl
A small pach into main trunk to build cponsole Android i2pd binary
2018-04-21 16:06:27 -04:00
Al
6cebc1a2a2 Merge pull request #1 from PurpleI2P/openssl
merge "mainline"
2018-04-21 19:10:05 +00:00
faac35cd1e Revert "Change jni to build executable. Clone with minimal changes DaemonUnix into DaemonAndroid"
This reverts commit f11266972e.
2018-04-21 21:55:45 +03:00
6916147dda Few cents to get fullly console i2pd under Android 2018-04-21 21:48:42 +03:00
e2da16e9c3 moved reseed out 2018-04-19 19:46:00 +03:00
0c661e7373 save new local destination for failed insert 2018-04-18 15:08:06 -04:00
413f8e8462 Merge pull request #1159 from majestrate/gut-streaming-limits
remove streaming bans
2018-04-16 10:06:27 -04:00
eefbbd4efe remove all related streaming limit members 2018-04-16 09:47:35 -04:00
83932a6f02 remove streaming bans 2018-04-16 09:38:32 -04:00
c175dc30f8 correct uri for outproxy 2018-04-13 16:29:49 -04:00
17aa91803a update outproxy header in right place 2018-04-13 15:40:25 -04:00
48099a367e send correct buffer to outproxy 2018-04-13 15:13:50 -04:00
a9b64893d8 replace Proxy-Authorization 2018-04-13 12:47:53 -04:00
387e030d83 correct cleanup for CONNECT 2018-04-12 21:25:20 -04:00
855cc9ed83 correct Proxy-Authroization 2018-04-12 19:10:21 -04:00
82534eef12 try fix appveyor build 2018-04-11 20:58:21 +03:00
ff4e254618 0.9.34 2018-04-11 10:30:13 -04:00
571a13f0a7 Merge remote-tracking branch 'purple/master' 2018-04-08 19:56:48 -04:00
2cb6283d00 outproxy authorization 2018-04-06 15:23:56 -04:00
f4056e57bb rollback 2018-04-05 07:16:41 -04:00
e80da3cbeb fixes for i2pd_qt MSYS2 mingw32 2018-04-05 15:40:44 +08:00
c0436297c2 fix typo in systemd service type 2018-04-01 23:37:36 +03:00
0d05b4f095 Merge pull request #1154 from yangfl/upstream
fix systemd service type
2018-03-31 16:53:58 +03:00
f06c8710be fix systemd service type 2018-03-31 14:56:45 +08:00
f11266972e Change jni to build executable. Clone with minimal changes DaemonUnix into DaemonAndroid 2018-03-30 15:50:30 +03:00
479edaf80d Merge pull request #1149 from majestrate/fix-ntcp-threading-race
Fix ntcp threading race
2018-03-24 08:29:04 -04:00
ff5c26adf2 Merge remote-tracking branch 'purple/openssl' into fix-ntcp-threading-race 2018-03-24 07:56:49 -04:00
5361e11395 fix race 2018-03-24 07:53:06 -04:00
b041bcdc65 publish updated LeaseSet in destination's thread 2018-03-23 11:41:36 -04:00
b7c350202d always create EdDSA RouterInfo 2018-03-20 20:43:47 -04:00
b1a6c5ddf7 fixed build for gcc 4.7 2018-03-16 11:12:18 -04:00
ac943b5712 Merge pull request #1147 from PurpleI2P/cmake-libs
WITH_LIBRARY usage
2018-03-12 12:35:34 +03:00
ce8d701ecb WITH_LIBRARY usage
closes #1146. Need to be checked before.
2018-03-11 19:20:47 +03:00
182ffe4495 use croorect encryption type for tunnel build 2018-03-09 14:56:06 -05:00
c13983d395 Merge pull request #1145 from PurpleI2P/openssl
recent changes
2018-03-09 14:47:56 -05:00
066f8863fd pass zero padding parameter to ECEIS encryption 2018-03-07 16:08:44 -05:00
e58aaa3f32 make sure tunnelID is non-zero 2018-03-07 12:36:38 -05:00
ca1fa11cb1 Merge pull request #1143 from l-n-s/i2pcontrol_updates
I2pcontrol updates
2018-03-05 14:34:31 -05:00
64ed485cdf Merge pull request #1142 from ffontaine/openssl
Create LogsDirectory in i2pd.service
2018-03-05 21:30:09 +03:00
b0781668e2 Create LogsDirectory in i2pd.service
Create /var/log/i2pd through LogsDirectory parameter of systemd and set
its permission to 0700 through LogsDirectoryMode. Indeed, this directory
must be created with the correct permission as it is used in ExecStart
command

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2018-03-05 19:06:14 +01:00
f9fc744949 Merge remote-tracking branch 'upstream/openssl' into i2pcontrol_updates 2018-03-05 12:35:10 -05:00
2661db23f6 I2PControl: fix indentation 2018-03-05 12:34:41 -05:00
7d78f60d29 Merge pull request #1140 from ffontaine/openssl
Install libi2pdclient
2018-03-05 10:58:07 -05:00
1d934bd543 Install libi2pdclient
When building with -DBUILD_SHARED_LIBS=ON, libi2pdclient is not
installed on target so install it by calling install. Moreover, rename
i2pdclient to libi2pdclient so library is installed with correct name.

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2018-03-05 15:17:23 +01:00
190435acd9 Merge pull request #1138 from ffontaine/openssl
Fix cmake error when -DBUILD_SHARED_LIBS=ON
2018-03-04 15:35:28 -05:00
656236cb4d Merge pull request #1137 from yangfl/upstream
Makefile: add detection for GNU userspace
2018-03-04 14:48:45 -05:00
6d15be9a32 Fix cmake error when -DBUILD_SHARED_LIBS=ON
Fixes "CMake Error: TARGETS given no LIBRARY DESTINATION for shared
library target" by adding LIBRARY parameter to INSTALL call

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2018-03-04 18:31:02 +01:00
18d3c81018 Makefile: add detection for GNU userspace 2018-03-05 00:51:53 +08:00
12292afdec I2PControl: s/remote_endpoint/peer 2018-03-04 11:28:09 -05:00
aef0f4d7b8 Merge pull request #1135 from l-n-s/issue_954
I2PControl: add new method ClientServicesInfo
2018-03-03 07:48:46 -05:00
21545ab7da I2PControl: add new method ClientServicesInfo 2018-03-03 05:52:11 -05:00
5a2b795440 fixed crash 2018-02-26 19:41:24 -05:00
1303dd478c Merge pull request #1130 from majestrate/i2cp-session-reconfig
implement i2cp session reconfigure
2018-02-26 09:33:25 -05:00
7b4fc19fca be concise 2018-02-26 08:18:01 -05:00
008a064764 revert 2018-02-26 08:12:15 -05:00
82a4630061 use correct function 2018-02-26 08:09:26 -05:00
0f77b4810d revert 2018-02-26 08:00:07 -05:00
2f7cfddfc4 Merge remote-tracking branch 'purple/openssl' into i2cp-session-reconfig 2018-02-26 07:58:03 -05:00
84608c16b3 Merge pull request #1128 from majestrate/fix-issue-1126
Fix issue 1126
2018-02-25 09:34:58 -05:00
157411dcc6 Revert "fix issue #1124"
This reverts commit 29e861d1e6.
2018-02-25 08:51:07 -05:00
59672d23cc Merge branch 'fix-issue-1124' into fix-issue-1126 2018-02-25 08:50:27 -05:00
ce30f89c60 make it compile :D 2018-02-25 08:49:39 -05:00
ce9c9411b1 fix issue #1126 2018-02-25 08:47:39 -05:00
cf0d5b616d Merge pull request #1125 from majestrate/fix-issue-1124
fix issue #1124
2018-02-22 16:18:37 -05:00
29e861d1e6 fix issue #1124 2018-02-22 06:54:33 -05:00
c7accd4a5c Merge pull request #1122 from majestrate/ntcp-threadpool
NTCP threadpool
2018-02-20 14:49:01 -05:00
b469080cd7 make ntcp worker threads configurable in number 2018-02-20 13:18:57 -05:00
547a0057e6 whitespace cleanup 2018-02-20 13:04:39 -05:00
b980ca4a9e whitespace cleanup 2018-02-20 13:03:34 -05:00
098b2e968e whitespace cleanup 2018-02-20 13:03:01 -05:00
cd59ca8376 whitespace cleanup 2018-02-20 12:59:39 -05:00
f2e6fad104 make it work 2018-02-20 12:40:28 -05:00
8d7fde0287 more 2018-02-20 11:43:13 -05:00
91fdb038d9 add threadpool for ntcp dh 2018-02-20 11:38:48 -05:00
a0188765c5 Merge pull request #1121 from majestrate/aesni-osx
More OSX fixes
2018-02-19 12:29:34 -05:00
b970a005de don't log AESNI/AVX here 2018-02-19 10:45:13 -05:00
b64878f4fa use std::move 2018-02-19 10:45:02 -05:00
c8936c79bf Merge pull request #1120 from majestrate/aesni-osx
FIX AESNI build on osx with homebrew
2018-02-19 10:19:45 -05:00
f876cc9079 update makefile 2018-02-19 10:16:48 -05:00
a5cc2f3b5d define bit_* if not already defined 2018-02-19 10:15:39 -05:00
9c93d6f931 Revert "define cpu_* if not set"
This reverts commit a077d7671f.
2018-02-19 10:15:26 -05:00
a077d7671f define cpu_* if not set 2018-02-19 10:15:03 -05:00
6485ebe9a7 Merge pull request #1119 from PurpleI2P/docker_build_badge
Added docker build badge
2018-02-18 20:24:32 +01:00
ecb6bb220a Added docker build badge 2018-02-18 20:21:19 +01:00
e3dc400d74 Merge pull request #1117 from hypnosis-i2p/openssl
fixed #1104
2018-02-17 14:49:18 -05:00
3bb4151074 fixed #1104 - android 2018-02-18 01:01:48 +08:00
1de4c2e8c6 perms prompt now doesn't show the back button - android 2018-02-18 00:25:58 +08:00
fbcc4f28e7 removed design lib from deps - android 2018-02-17 23:55:30 +08:00
30fb0f5a94 Merge pull request #1116 from majestrate/netbsd
NetBSD support
2018-02-17 07:22:51 -05:00
b02464990b work around netbsd quarkyness 2018-02-16 18:54:34 -05:00
4988a32d33 make endian work with netbsd 2018-02-16 18:27:30 -05:00
b3e5874631 fixed android build error 2018-02-16 13:56:44 -05:00
f5349dcef9 Merge pull request #1115 from majestrate/aesni-avx-runtime-detect
AESNI/AVX runtime detection [WIP]
2018-02-16 12:40:28 -05:00
486a4cfdd6 add to qt 2018-02-16 12:36:51 -05:00
2277dcb069 add cpu.cpp to cmake 2018-02-16 12:34:17 -05:00
a618a01b1e don 2018-02-16 11:26:07 -05:00
7e60069968 add uncommitted files 2018-02-16 11:01:04 -05:00
91e45d9a4a initial code for runtime detection of aesni/avx 2018-02-16 11:00:33 -05:00
dea6fbf285 Merge pull request #1114 from majestrate/websocks-datagram
Add datagrams to websocks tunnel
2018-02-16 09:18:24 -05:00
48cc0f4289 use write 2018-02-16 08:33:19 -05:00
cdc5fce583 check port 2018-02-16 08:31:20 -05:00
b41a17d548 add datagrams to websocks 2018-02-16 08:26:46 -05:00
606cbaa519 Merge pull request #1113 from majestrate/sam-xss-fix
fix xss in webui from SAM session name
2018-02-16 07:02:55 -05:00
aaf8f527ef fix xss in webui from SAM session name 2018-02-16 06:28:22 -05:00
b7596b7f70 Merge pull request #1112 from majestrate/dns-rebind
mitigate dns rebinding in webui
2018-02-15 09:57:16 -05:00
0309b574e8 mitigate dns rebinding in webui 2018-02-15 09:52:20 -05:00
ca057177c7 Merge pull request #1110 from radfish/PR--remove-openssl-1.1-warning
cmake: remove warning for OpenSSL 1.1
2018-02-11 14:36:03 -05:00
5d9bf18267 Merge pull request #1109 from radfish/PR--clang-stdlib-fix
cmake: add stdlib args for clang build on Linux
2018-02-11 14:35:32 -05:00
f1b8742782 cmake: remove warning for OpenSSL 1.1
Works fine.
2018-02-11 13:14:12 -05:00
7786c97330 cmake: add stdlib args for clang build on Linux
Otherwise linking fails with undefined symbol ... basic_string ... and
libstdc++: DSO not on included in link command.

or with
Host compiler must support std::atomic!
which is due to
undefined reference to `__gxx_personality_v0' and __cxa_begin_catch and
std::terminate()

This was already patched in 7b537a4e94
PR #972 but it got lost, and also needed some tweaking.

Thested with Clan 5.0.1 on Arch Linux (on armv7h).
2018-02-11 13:11:12 -05:00
f2a14047eb Merge pull request #1108 from majestrate/fix-issue-1107
Fix issue 1107
2018-02-11 06:48:01 -05:00
124a9cb030 correction 2018-02-11 06:07:43 -05:00
3ec000d0f8 fix issue #1107 2018-02-11 06:06:14 -05:00
aac1141ca6 fix issue #1107 2018-02-11 06:05:41 -05:00
33cb96126a appveyor: remove catgets before try update 2018-02-10 19:23:07 +03:00
441db9ad7f fix appveyor build 2018-02-10 19:20:44 +03:00
5225e1d7d1 * HTTP.cpp : use bare snprintf() instead locale-dependent strftime() 2018-02-10 12:40:01 +00:00
de849b3f6a fix date in webconsole page header on windows 2018-02-10 03:10:32 +03:00
fb4387c41f Merge pull request #1103 from hypnosis-i2p/openssl
build.gradle auto-indented; ndk-build is now called by gradle build
2018-02-08 07:18:39 -05:00
a9061a8f58 ndk-build is now called by gradle build 2018-02-08 12:55:09 +08:00
0c099dc52b Merge pull request #1102 from PurpleI2P/revert-1097-revert-1096-openssl
Revert "Revert "fixed #1088""
2018-02-07 14:50:30 -05:00
713e92c28f Revert "Revert "fixed #1088"" 2018-02-07 14:50:15 -05:00
d111025012 Merge pull request #1101 from PurpleI2P/revert-1098-revert-1095-openssl
Revert "Revert "reworked the app, fixed #1094, fixed grace stop""
2018-02-07 14:49:50 -05:00
5f2e6b1262 Revert "Revert "reworked the app, fixed #1094, fixed grace stop"" 2018-02-07 14:49:37 -05:00
b6d838731f Merge pull request #1100 from PurpleI2P/revert-1099-revert-1090-openssl
Revert "Revert "quit features replaced by stop; gradle upgraded; i2pd version name updated at build.gradle""
2018-02-07 14:49:05 -05:00
56db8b40b2 Revert "Revert "quit features replaced by stop; gradle upgraded; i2pd version name updated at build.gradle"" 2018-02-07 14:48:51 -05:00
f488c97a09 Merge pull request #1099 from PurpleI2P/revert-1090-openssl
Revert "quit features replaced by stop; gradle upgraded; i2pd version name updated at build.gradle"
2018-02-07 14:08:34 -05:00
31df49a884 Revert "quit features replaced by stop; gradle upgraded; i2pd version name updated at build.gradle" 2018-02-07 14:08:22 -05:00
e5fdced4ac Merge pull request #1098 from PurpleI2P/revert-1095-openssl
Revert "reworked the app, fixed #1094, fixed grace stop"
2018-02-07 14:07:40 -05:00
71546367cf Revert "reworked the app, fixed #1094, fixed grace stop" 2018-02-07 14:07:26 -05:00
857817dae8 Merge pull request #1097 from PurpleI2P/revert-1096-openssl
Revert "fixed #1088"
2018-02-07 14:07:00 -05:00
ae3fca15c7 Revert "fixed #1088" 2018-02-07 14:06:39 -05:00
6bb7382dbd Merge pull request #1096 from hypnosis-i2p/openssl
fixed #1088
2018-02-07 10:47:51 -05:00
badb837b46 fixed #1088 2018-02-07 23:22:31 +08:00
74f5b70a5d Merge pull request #1095 from hypnosis-i2p/openssl
reworked the app, fixed #1094, fixed grace stop
2018-02-07 07:25:33 -05:00
ac495da5fe fixes grac stop 2018-02-07 19:56:44 +08:00
56f6e57118 fixes grac stop 2018-02-07 19:54:19 +08:00
33735b343d fixes 1094; fixes grac stop 2018-02-07 19:24:43 +08:00
1b56d66fc8 android gitignore 2018-02-07 18:25:45 +08:00
0994211a48 android gitignore 2018-02-07 18:25:45 +08:00
62d9a47c3d android work 1 2018-02-07 18:25:45 +08:00
e77037c2b8 fixed warning 2018-02-05 11:13:25 -05:00
030a6ebb71 Merge pull request #1093 from l-n-s/rm_root_docker
Remove broken Dockerfile and it's entrypoint
2018-02-05 04:51:29 +00:00
5a657cff89 Remove broken Dockerfile and it's entrypoint 2018-02-04 23:44:49 -05:00
f3488be7af update rpm, increase release version for Fedora and CentOS 2018-02-05 05:52:12 +03:00
4af0caa506 fix build on GCC 8.0.1
https://bugzilla.redhat.com/show_bug.cgi?id=1541688
2018-02-05 05:07:26 +03:00
0728991821 Merge pull request #1092 from majestrate/master
fix federoa rawhide build with gcc 8
2018-02-03 15:18:15 -05:00
21c35f770b fix federoa rawhide build with gcc 8 2018-02-03 13:46:22 -05:00
f039af6eda Merge pull request #1090 from hypnosis-i2p/openssl
quit features replaced by stop; gradle upgraded; i2pd version name updated at build.gradle
2018-02-03 07:14:14 -05:00
eb3f703b46 gradle upgraded; i2pd version name updated 2018-02-03 19:58:09 +08:00
b88b82a85c quit features replaced by stop - more 2 2018-02-03 19:57:21 +08:00
1d0791dbf5 quit features replaced by stop - more 2018-02-03 19:56:17 +08:00
87f2eefd35 quit features replaced by stop 2018-02-03 19:55:32 +08:00
b8a2c9f955 Merge pull request #1089 from yangfl/upstream
i2pd.service: do not block system shutdown for 10 min
2018-02-02 22:26:06 +03:00
319d748639 i2pd.service: do not block system shutdown for 10 min 2018-02-03 02:29:28 +08:00
4f84d687e4 add endian detection for glibc 2018-02-03 02:27:22 +08:00
fbb9991128 remove obsoletes tag for rpm git package 2018-02-02 10:35:07 +03:00
62bac24246 Merge pull request #1086 from BOPOHA/patch-3
i2pd.spec delete obsoletes tag
2018-02-01 17:43:42 -05:00
4aa8461bea Merge pull request #1087 from BOPOHA/patch-4
systemd issue in centos 7
2018-02-01 17:43:17 -05:00
ce57a130fc systemd issue in centos 7
Not working pre-create pid-file dir (/run/i2pd).
It fixed with one of this ways:

> PermissionsStartOnly=True
or 
> ExecStartPre=/bin/mkdir -p -m 0700 /var/run/i2pd
> ExecStartPre=/bin/chown i2pd: /var/run/i2pd

First way is prefer because RuntimeDirectory's options already used.
2018-02-01 23:21:20 +01:00
80567312ed i2pd.spec delete obsoletes tag
https://github.com/PurpleI2P/i2pd/pull/1084#issuecomment-362215861

```
Resolving Dependencies
--> Running transaction check
---> Package i2pd.x86_64 0:2.17.0-20171206git.el7.centos will be updated
---> Package i2pd.x86_64 0:2.18.0-1.el7.centos will be obsoleting
---> Package i2pd-systemd.x86_64 0:2.17.0-20171206git.el7.centos will be obsoleted
--> Finished Dependency Resolution

Dependencies Resolved

==========================================================================
 Package   Arch        Version                     Repository        Size
==========================================================================
Installing:
 i2pd      x86_64      2.18.0-1.el7.centos         vorona-i2pd      915 k
     replacing  i2pd-systemd.x86_64 2.17.0-20171206git.el7.centos

Transaction Summary
==========================================================================
Install  1 Package

Total download size: 915 k
Is this ok [y/d/N]:
```
@l-n-s  thx, obsoletes tag is unneeded in next release)
2018-02-01 22:11:14 +01:00
180730f9cf fix rpm spec's (#1084)
* added spec for git package
* fixed double slashes
* changed versioning for stable builds
2018-02-01 19:37:38 +03:00
fca2693488 add centos/fedora build status 2018-02-01 01:12:06 +03:00
b6e75e9c5a Update changelog 2018-01-30 11:14:29 -05:00
4901434209 2.18.0 2018-01-30 10:41:35 -05:00
13d174c09c add tunconf in systemctl service file 2018-01-30 18:14:54 +03:00
5363c063d1 Merge pull request #1067 from l-n-s/rpm_updates
Update rpm spec and systemd unit
2018-01-30 15:12:54 +00:00
32d300248e update building stuff 2018-01-30 18:09:26 +03:00
3426906a4f [rpm] Fix changelogs to comply with guidelines, add tunconf key to systemd package 2018-01-30 10:03:53 -05:00
3aaa942c94 Merge pull request #1082 from PurpleI2P/apparmor-homedir
add users homedir to apparmor profile
2018-01-30 17:31:22 +03:00
95d8887ab0 update profile 2018-01-30 17:30:01 +03:00
6272e15b47 add users homedir to profile 2018-01-29 04:13:33 +03:00
20b4f6b24d update apparmor profile 2018-01-29 03:47:43 +03:00
6ee279d83e [rpm] Merge i2pd-systemd with i2pd package + changelog 2018-01-27 10:54:03 -05:00
b00ff43be7 Update README.md 2018-01-26 19:52:11 -05:00
dfbefee477 graceful shutdown complete if no transit tunnels anymore 2018-01-26 14:34:05 -05:00
8c2de4973c rollback 2018-01-26 14:33:06 -05:00
e1527dc137 update LeaseSet if a tunnel was deleted 2018-01-26 14:07:51 -05:00
0957f6b143 Merge pull request #1055 from yangfl/upstream
replace non-working CheckLibcxxAtomic
2018-01-26 15:33:39 +03:00
7db2e9dc4a don't verify signature twice 2018-01-25 10:32:08 -05:00
b1c701085b don't verify signature twice 2018-01-25 10:09:34 -05:00
e8d6c803cd Merge pull request #1076 from majestrate/fix-streaming-race-2018-01-25
try streaming race condition fix
2018-01-25 09:35:58 -05:00
f4a2dda94e try streaming race condition fix 2018-01-25 09:00:00 -05:00
c4216379ed Merge pull request #1074 from l-n-s/fix_docker_2
Fix docker 2
2018-01-24 19:46:38 +00:00
52195bf296 Merge remote-tracking branch 'upstream/openssl' into fix_docker_2 2018-01-24 14:42:55 -05:00
10fe75ed87 Merge pull request #1073 from majestrate/fix-netdb-ls-publish-2018-01-24
check for valid LS before updating
2018-01-24 13:00:30 -05:00
1c659d6ef6 Merge remote-tracking branch 'upstream/openssl' into fix_docker_2 2018-01-24 12:48:57 -05:00
3ac86db038 Fix Docker image error 2018-01-24 12:48:05 -05:00
4a77a03033 * Add LeaseSetBufferValidate which checks lease validity and extracts timestamp
* check for leases with LeaseSetBufferValidate before update in floodfill code as to prevent malicous nodes removing good LS
2018-01-24 10:16:51 -05:00
3820b51960 Revert "check for valid LS before updating"
This reverts commit e070ce4e34.
2018-01-24 09:44:55 -05:00
e070ce4e34 check for valid LS before updating 2018-01-24 09:36:09 -05:00
0bb0adbf3e fix addressbook fetch timeout 2018-01-24 15:34:32 +03:00
ddd25f0945 limit number of retries for subscriptions 2018-01-23 15:50:28 -05:00
162bd592f8 recreate http and socks proxy upon reload 2018-01-23 15:13:43 -05:00
85fa728d41 change shared local destination upon reload 2018-01-23 14:40:05 -05:00
c7db9010ad fixed #1047. Return EXIT_FAILURE 2018-01-23 11:01:50 -05:00
be16545063 Merge pull request #1070 from vmon/f--port-0-for-TCPAcceptor
the change allows when an TCPIPAcceptor is constructed by setting por…
2018-01-23 06:48:18 -05:00
c730839989 the change allows when an TCPIPAcceptor is constructed by setting port = 0, the random port chosen by asio can be retrieved using TCPIPAcceptor::GetLocalEndpoint().port() 2018-01-22 20:47:31 -05:00
4ee364640d Update rpm spec and systemd unit 2018-01-22 13:55:12 -05:00
56dd0db001 Merge pull request #1066 from PurpleI2P/revert-1065-openssl
Revert " Fixes for #1024 , #1018 #1064 "
2018-01-22 13:00:15 -05:00
626ed720a6 Revert " Fixes for #1024 , #1018 #1064 " 2018-01-22 12:59:34 -05:00
b8fd9ba83f Merge pull request #1065 from unlnown542a/openssl
Fixes for #1024 , #1018 #1064
2018-01-22 07:08:34 -05:00
316a4457af Merge github.com:unlnown542a/i2pd into openssl 2018-01-22 01:39:51 +03:00
347a2c2150 fixing conflicts 2018-01-22 01:30:21 +03:00
42d3770b14 fixed layout 2018-01-21 11:28:16 -05:00
39ca07bcc6 Merge pull request #1058 from majestrate/streaming_race_fix_2018_01_15
Streaming race fix 2018 01 15
2018-01-21 11:15:44 -05:00
df304fb38b Merge pull request #1063 from PurpleI2P/openssl
recent changes
2018-01-21 10:29:31 -05:00
914566ece0 removed unused Java router certificates 2018-01-21 10:27:41 -05:00
f537e7b2c6 removed unused cert 2018-01-21 08:09:01 -05:00
06020b8f54 re-enable packet pool 2018-01-20 13:06:08 -05:00
b486d1cd27 rollback
non buildable under x64
2018-01-20 12:07:57 -05:00
b3b38015c2 check max buffer size in Stream::Send 2018-01-20 07:31:58 -05:00
4c6988e3bc code cleanup 2018-01-18 19:35:37 +03:00
0bd4db4cc7 less lines 2018-01-18 16:41:02 +03:00
bc72800fef moved hard code into java side and successfully passed back to native 2018-01-17 20:58:56 +03:00
951f8972c7 replace non-working CheckLibcxxAtomic 2018-01-17 16:12:46 +08:00
38b694a055 Merge pull request #1060 from inetic/openssl
Inherit _publicly_ from shared_from_this in I2PService
2018-01-15 11:58:27 -05:00
44a9c3ca0c Merge pull request #1059 from K1773R/fix-headers-rn
removed redundant \r\n in HTTP header builder
2018-01-15 10:36:42 -05:00
6bf823fb15 removed \r\n in header builder which was redundant and caused the further headers to be ignored 2018-01-15 16:30:01 +01:00
43a751ee0b Merge remote-tracking branch 'purple/openssl' into streaming_race_fix_2018_01_15 2018-01-15 08:25:58 -05:00
207212557e fix sam race conditions 2018-01-15 08:19:57 -05:00
fd1aeeac92 Merge pull request #1045 from yangfl/upstream
code cleanup
2018-01-13 18:11:19 +03:00
50ba52756f fix mixing tabs and spaces 2018-01-13 22:51:02 +08:00
e630b8f8a8 Inherit _publicly_ from shared_from_this in I2PService 2018-01-12 11:04:26 +01:00
cf5081d300 fixed creating certificates.zip when target zip did not include the directory certificates, so they were bein unpacked into datadir. Added entryCompression ZipEntryCompression.STORED since final APK is being compressed as well. Put all custom tasks under android plugin definitions 2018-01-07 19:30:32 +03:00
8864cbf80a return to strdup() when filling argv[] for i2p::android::start(argc,argv).c_str() 2018-01-07 00:40:17 +03:00
81d7a832c0 netDB and certificates in internal storage 2018-01-07 00:08:07 +03:00
d41fabbc9f netDB and certificates in internal storage 2018-01-06 23:59:22 +03:00
46f62e1af9 remove trailing whitespaces 2018-01-06 22:24:03 +08:00
b91efaa973 Merge pull request #1044 from yangfl/upstream
update Makefile and CMakeLists
2018-01-06 09:22:11 -05:00
e3238ff75c CMakeLists: autodetect libatomic 2018-01-06 22:06:44 +08:00
9cc4e8d03a Makefile: get target platform from compiler 2018-01-06 22:06:28 +08:00
68b1afa2df Merge remote-tracking branch 'purple/openssl' into i2cp-session-reconfig 2018-01-04 08:33:06 -05:00
34c98e03c1 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2018-01-03 12:53:05 -05:00
41e40bbc0d fixed typo 2018-01-03 12:52:29 -05:00
80149342f2 proper bounds check 2018-01-03 10:02:11 -05:00
1967dee50c don't recreate tunnels of different size 2018-01-02 12:59:16 -05:00
ab80def94b use reference instead of copy 2018-01-02 12:06:10 -05:00
254bf313a2 fix previous commit 2018-01-02 11:48:38 -05:00
938d5d901a implement i2cp session reconfigure 2018-01-02 11:34:58 -05:00
7b00d828b2 fix lambda capture, don't capture copy 2018-01-01 09:35:32 -05:00
ca49944c85 Merge pull request #1041 from majestrate/fix-streaming-race
fix race condition
2018-01-01 09:26:21 -05:00
d5e9fc7677 fix race condition 2018-01-01 08:28:42 -05:00
6db7c5733d use outbound.nickname as tunnel name if inbound.nickname is not set 2017-12-20 11:38:35 -05:00
418f86ecbd Merge pull request #1039 from majestrate/fix-arm-compile-latomic
Fix arm compile latomic
2017-12-20 10:48:45 -05:00
c68c5af856 fix lib name 2017-12-20 08:56:39 -05:00
950dffbe06 update gitignore 2017-12-20 08:54:41 -05:00
5d557003b6 include cmake stuff 2017-12-20 08:54:02 -05:00
3b8c3c1346 try fixing issue #897 2017-12-20 08:49:47 -05:00
1853263f6c Merge pull request #1038 from PurpleI2P/master
Master
2017-12-18 08:59:19 -05:00
b0f6d81f57 Merge pull request #1037 from PurpleI2P/openssl
recent changes
2017-12-15 22:00:09 -05:00
9ba0329432 Merge pull request #1036 from KenanSulayman/patch-1
Fix typo (confrimed -> confirmed)
2017-12-15 21:56:09 -05:00
614101c4b8 Fix typo (confrimed -> confirmed) 2017-12-16 02:36:01 +01:00
50e4fb138a close #1032 (#1034) 2017-12-13 15:17:45 +03:00
6dba0c6e0e Merge pull request #1031 from AMDmi3/boost-asio-fix
Don't use deprecated boost::asio::ssl::context ctor
2017-12-11 15:30:39 -05:00
0f2d2156e6 Don't use deprecated boost::asio::ssl::context ctor
This was removed in boost 1.66, in prior versions the service
argument was not used
2017-12-11 22:34:48 +03:00
13b17c5a93 Merge pull request #1030 from AMDmi3/freebsd_kernel
Reorder preprocessor conditions in libi2pd/I2PEndian.h
2017-12-11 12:37:08 -05:00
511499d950 Reorder preprocessor conditions in libi2pd/I2PEndian.h
The problem is that __FreeBSD_kernel__ may be defined on FreeBSD as
well, while it always needs <sys/endian.h>
2017-12-11 19:59:06 +03:00
6632b71273 gradle relese build 2017-12-10 09:01:13 -05:00
60ef70cee4 gradle build added 2017-12-10 08:46:13 -05:00
b3ba0a7241 Merge pull request #1027 from majestrate/transient-by-default
Use transient destinations
2017-12-09 07:49:43 -05:00
fc73dabc0b Use transient destinations by default instead of shared local destination 2017-12-09 07:42:32 -05:00
1121d45eb6 Merge pull request #1025 from yangfl/pr
fix typo
2017-12-07 09:09:42 -05:00
18b6353803 fix typo 2017-12-07 21:26:28 +08:00
c0c0642bd1 temporary disable osx build due to of big waiting time of VM 2017-12-06 02:16:01 +03:00
3cf26a84dc Merge pull request #1022 from AMDmi3/patch-1
Don't meddle with stdlib
2017-12-05 10:14:31 -05:00
44d6d4405e Don't meddle with stdlib
Forgotten part of #1014: -stdlib should not be changed. It breaks build on e.g. FreeBSD where libc++ is used.
2017-12-05 13:45:22 +03:00
cafa027f0b Merge pull request #1021 from PurpleI2P/openssl
2.17.0
2017-12-04 13:42:04 -05:00
1c970b0714 2.17.0 2017-12-04 21:40:32 +03:00
6636e432d7 2.17.0 2017-12-04 13:05:04 -05:00
158889b85c check for invalid params 2017-12-01 16:25:32 -05:00
92bebb7ecc webconsole update (#1017)
* webconsole exploratory tunnel mark
* loglevel on commands page
* fix line break on destination page
2017-12-01 22:18:04 +03:00
fff34e77f5 pass signature and crypto type to newkeys 2017-12-01 13:43:00 -05:00
df18692af9 check I2NP messsage buffer size 2017-12-01 12:57:05 -05:00
276a78cb2e Merge pull request #1019 from PurpleI2P/openssl
recent changes
2017-12-01 12:55:45 -05:00
a1e820182c CRYPTO_TYPE for DEST GENERATE 2017-11-28 13:24:07 -05:00
272090fc8f don't accept streams from RSA detinations 2017-11-28 11:33:51 -05:00
ab6bc52a0f don't create destination with RSA signature 2017-11-28 10:59:11 -05:00
c69c369502 close div, update qt gitignore 2017-11-26 12:30:18 +03:00
a5b1b24fee implement i2p.streaming.connectDelay option 2017-11-24 15:37:17 -05:00
40cfbc5d61 Merge pull request #1016 from majestrate/fix-streaming-overflow
fix overflow
2017-11-23 13:54:34 -05:00
ffad1ecd6d reduce buffer size 2017-11-23 13:46:04 -05:00
e1b5803902 fix overflow 2017-11-23 12:27:28 -05:00
492d71a924 transient keys 2017-11-22 14:49:45 -05:00
6d01a3a7d1 fix (quote) 2017-11-21 21:33:24 +03:00
b71e20dfa3 changed back 2017-11-21 13:25:40 -05:00
474158dd18 rollback. build error 2017-11-21 11:04:32 -05:00
914db816c2 Merge pull request #1014 from AMDmi3/patch-1
Fix flags
2017-11-21 07:17:49 -05:00
4485d6fdf4 Fix flags
-stdlib should not be changed. It breaks build on e.g. FreeBSD where libc++ is used.
2017-11-21 14:35:39 +03:00
2c394661a6 Merge pull request #1011 from hypnosis-i2p/openssl
updated qt to build and to reflect some core changes like log dest
2017-11-19 07:14:50 -05:00
611c1a7502 updated qt to build and to reflect some core changes like log dest 2017-11-19 19:26:36 +08:00
4e8858a764 Merge pull request #1009 from majestrate/reseed-proxy
reseed proxy
2017-11-18 16:15:37 -05:00
fb46de5ca6 Delete old R4SAS's reseed cert 2017-11-18 23:56:52 +03:00
65db96e663 reseed proxy 2017-11-18 09:50:30 -05:00
5109d40d8e don't publish unknown crypto type to Java floodfill again 2017-11-17 14:28:48 -05:00
1ba1fa37f9 update travis-ci stuff (#1006)
* enable osx in travis config
* fix brew commands, change comiler
* disable clang build with make on linux
* update README
* tabulation fix in Crypto.cpp
2017-11-17 20:43:00 +03:00
9c97ee6407 check for existing addressbook record 2017-11-16 01:13:42 +03:00
7477d2c219 fix forgotten log colors 2017-11-15 21:51:03 +03:00
a6fb3b602e add loglevel none (closing #998) 2017-11-15 21:46:20 +03:00
d9b9457b56 update webconsole 2017-11-15 00:49:32 +03:00
cfb6ddbfc6 CRYPTO_TYPE for SAM destinations 2017-11-14 15:05:07 -05:00
7de21c1f93 show proxy tunnel name 2017-11-14 13:20:54 -05:00
100f3380c4 fix upnp definitions and make cmake silent (#999) 2017-11-14 08:38:45 +03:00
20e484bb8b travis-ci cmake fix 2017-11-14 06:34:57 +03:00
94fc1a1cee debian wheezy upnp fix 2017-11-14 03:41:01 +03:00
ae28df5276 2.16.0 2017-11-13 22:20:41 +03:00
3a4f1382f3 2.16.0 2017-11-13 14:09:55 -05:00
01a7e08585 0.2.16 2017-11-13 14:01:04 -05:00
847fd15af2 0.2.16 2017-11-13 13:59:41 -05:00
a21fb17d73 renamed ECIES-P256 2017-11-13 11:50:17 -05:00
0c34bd440b reject routers with RSA signatures 2017-11-13 11:25:42 -05:00
1008510750 Merge pull request #997 from PurpleI2P/openssl
recent changes
2017-11-13 11:23:32 -05:00
34d6eb52d0 Merge pull request #996 from majestrate/stream-limits
Stream limits
2017-11-13 07:46:06 -05:00
5820425b6c Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into stream-limits 2017-11-13 07:26:32 -05:00
a4b39a3648 disable connection limiting by default 2017-11-13 07:26:27 -05:00
3dc5542a28 update mingw makefile 2017-11-13 04:46:19 +03:00
dde4643e77 fix shutdown from webconsole in windows 2017-11-13 03:30:52 +03:00
7a857e08c1 update windows build batch 2017-11-13 03:30:52 +03:00
80a3bd6a3b correct new key pair 2017-11-12 17:31:00 -05:00
7fb8ee60b4 correct random padding for ICIES public key 2017-11-11 22:10:54 -05:00
dca4cf2edb fixed #993. bind inbound tunnel to inhost 2017-11-10 11:27:20 -05:00
2bc33f22df fixed #994. check if keys are set 2017-11-10 09:49:50 -05:00
d14c6e2829 cryptotype for server tunnels 2017-11-09 16:18:59 -05:00
a4ce224cd1 pass correct crypto type to identity 2017-11-09 15:49:27 -05:00
ab1cd3f5cf ECIES for GOST R 34.10 2017-11-09 15:01:07 -05:00
1e75de9bb8 514 bytes ECIES block 2017-11-08 21:06:58 -05:00
19a03c42a5 use generic Decrypt instead ElGamalDecrypt 2017-11-08 20:45:53 -05:00
9e5d1bf0fc cryptotype tunnel configuration parameter added 2017-11-08 15:59:41 -05:00
c5f784719d implement Decrypt for all local destination 2017-11-08 13:49:48 -05:00
60aa459dfc 0.9.32 2017-11-08 11:01:00 -05:00
53d71d29ff call RoutingDestination::Encrypt instead ElGamalEncrypt 2017-11-07 20:30:05 -05:00
81658d2ff9 generic encryption for RoutingDestination 2017-11-07 15:05:22 -05:00
9fa67b0e0a crypto key encryptor and decryptor 2017-11-06 15:54:18 -05:00
88ba494701 fixed build error 2017-11-06 15:12:51 -05:00
efacfced45 CryptoKey added 2017-11-06 13:40:58 -05:00
b3c836f298 Merge pull request #987 from majestrate/gcc-7-ubuntu-artsy-fix
fix gcc 7 on ubuntu
2017-11-05 06:22:49 -05:00
3330bf4f2f fix gcc 7 on ubuntu 2017-11-04 07:53:24 -04:00
e634c89995 generate non-ElGamal encryption keys pair 2017-11-02 16:13:10 -04:00
5aa53eee43 GetIdentity for RoutingDestination 2017-11-02 14:50:57 -04:00
42483b6f32 Merge pull request #986 from PurpleI2P/openssl
recent changes
2017-11-02 14:45:47 -04:00
00bbb81375 ECICS gerenarate keys 2017-11-01 14:06:55 -04:00
5271cdacf2 ECICSDecrypt 2017-11-01 10:59:36 -04:00
6d01726961 use AES-CBC for ECICS 2017-11-01 10:20:11 -04:00
12feac1f50 fixed build error for wheezy 2017-10-31 21:25:52 -04:00
39c1c3567b ECICSEncrypt added 2017-10-30 16:16:21 -04:00
63ae6850d3 Fix #979. Router without host but with introducers is considered as SSU v4 2017-10-30 12:58:20 -04:00
bec24e052c Merge pull request #983 from majestrate/i2np-transport-limits
fix limits when not specififed
2017-10-30 09:54:28 -04:00
91eb2b2c4a fix limits when not specififed 2017-10-30 09:53:41 -04:00
0bae2a3397 Merge pull request #982 from majestrate/i2np-transport-limits
I2np transport limits
2017-10-30 09:23:47 -04:00
42ec6db746 Merge remote-tracking branch 'purple/openssl' into i2np-transport-limits 2017-10-30 08:39:58 -04:00
7a9dc0eec0 use terminate 2017-10-30 08:37:54 -04:00
6441c9d5d8 initial ntcp soft/hard limits 2017-10-30 08:27:55 -04:00
2930d39ce7 Merge pull request #978 from majestrate/http-i2p-outproxy
support i2p outproxy in httpproxy
2017-10-29 10:30:03 -04:00
1500e805dd add is_i2p 2017-10-29 09:56:51 -04:00
b14d1801f0 support i2p outproxy 2017-10-27 08:43:54 -04:00
bc11181d5e tables for GOST R 34.11 2017-10-23 14:25:26 -04:00
9739e677aa Merge pull request #975 from chris-barry/974-apparmor-debian
Add apparmor profile to debian. #974
2017-10-16 01:19:35 +03:00
056f076ae8 Add apparmor profile to debian. #974 2017-10-15 13:40:59 -04:00
7dfb6f4a13 update makefiles 2017-10-13 21:46:10 +03:00
b347b719f3 fixed race condition 2017-10-13 14:38:32 -04:00
7b537a4e94 Merge pull request #972 from radfish/PR--cmake-stdlib-args-for-clang
cmake: add stdlib args for clang build on Linux
2017-10-08 21:46:32 -04:00
291f28fcce cmake: add stdlib args for clang build on Linux
Otherwise linking fails with undefined symbol ... basic_string ... and
libstdc++: DSO not on included in link command.
2017-10-08 19:11:12 -04:00
fa9c39732d change max bandwidth limit 2017-10-05 10:37:28 -04:00
bfdf006bd2 add SAM session in webconsole 2017-10-05 05:29:07 +03:00
057d6ca05b windows warnings, tabulation workaround 2017-10-04 20:16:34 +03:00
7d7f5ff4e2 set default nickname after initialization 2017-10-04 12:40:43 -04:00
6e32f4bc85 set nickname for destination 2017-10-04 12:27:08 -04:00
8460a8f4ef update local destination if changed 2017-09-29 15:34:26 -04:00
8c09a7429c Merge pull request #967 from brain5lug/openssl
missed self assigment check for EDDSAPoint
2017-09-29 06:40:19 -04:00
346bf14b7b added missed invariant for MemoryPool 2017-09-29 10:17:23 +03:00
8e3c9410dc missed self assigment check for EDDSAPoint 2017-09-29 00:48:14 +03:00
cb0552e20d Merge pull request #966 from brain5lug/openssl
fixed perfect forwarding for the memory pool
2017-09-28 17:38:58 -04:00
8c8127dda6 fixed perfect forwarding for the memory pool 2017-09-29 00:03:07 +03:00
1d8a481d59 fix tabulation 2017-09-27 23:41:34 +03:00
dd4f066e95 add graceful shutdown in webconsole for windows
add stop graceful shutdown menu item
add reload menu item
2017-09-27 23:30:30 +03:00
5e0d4163a2 Merge pull request #965 from majestrate/fix-leak-2017-09-27
try fixing leak
2017-09-27 10:34:34 -04:00
7fb2d13a8b use BN_CTX_start and BN_CTX_end instead of removing BN_CTX_start 2017-09-27 09:49:43 -04:00
acde10b46e Merge remote-tracking branch 'purple/openssl' into fix-leak-2017-09-27 2017-09-27 09:48:19 -04:00
c0bcab8bc5 try fixing leak 2017-09-27 09:05:52 -04:00
fd6d0922ab Merge pull request #964 from radfish/PR--cmake-openssl-warn
cmake: issue a non-fatal warning for openssl >=1.1
2017-09-26 21:16:20 -04:00
8179e7dbf8 cmake: issue a non-fatal warning for openssl >=1.1 2017-09-26 20:46:06 -04:00
eabeeaccfe Merge pull request #963 from radfish/PR--cmake-check-openssl-ver
cmake: check openssl version
2017-09-26 12:34:31 -04:00
94bba69dee cmake: check openssl version
See #835 for memory leak issues with OpenSSL >= 1.1
2017-09-26 10:56:02 -04:00
4d23de96d5 Merge pull request #961 from l-n-s/small_patches
fixed typo + added optional full date in logs `logclftime=true`
2017-09-19 22:02:30 -04:00
681810ea38 Use setter method for m_TimeFormat, set time format in Daemon.cpp instead of Log.cpp 2017-09-19 19:46:28 -04:00
d500fe66fd Add option logclftime=true for writing full date and time to logs 2017-09-18 18:49:03 -04:00
05c2adeefd fix typo 2017-09-18 15:24:53 -04:00
d46e0fb474 Merge pull request #958 from majestrate/macos-static
fix up homebrew makefile to allow static linking
2017-09-11 10:00:39 -04:00
330fab2efa update macos i2pd qt build to statically compile in libraries for portability 2017-09-11 08:57:43 -04:00
d59d36f93c fix up homebrew makefile 2017-09-11 07:48:10 -04:00
fd6827fdca add space 2017-09-09 20:13:45 +03:00
dca94f17d7 Merge pull request #952 from hypnosis-i2p/openssl
ui beautifying + fixed tunnels invalid ui data handling
2017-09-08 15:07:25 -04:00
d4e16881ff fixed tunnels invalid ui data handling 3 2017-09-09 01:13:42 +08:00
cd3f274763 fixed tunnels invalid ui data handling 2 2017-09-09 01:09:31 +08:00
1947be4957 fixed tunnels invalid ui data handling 2017-09-08 23:25:25 +08:00
21de4709ea ui beautifying more 2017-09-08 23:16:54 +08:00
ec76381a0b ui beautifying 2017-09-08 23:07:37 +08:00
66661417d7 Merge pull request #950 from hypnosis-i2p/openssl
ui critical fixes
2017-09-08 08:54:38 -04:00
81b79e6e53 ui critical fixes 2017-09-08 19:43:27 +08:00
5ae93d852e Merge pull request #948 from hypnosis-i2p/openssl
fixes #945 and #935
2017-09-08 07:00:30 -04:00
96cb663fa8 some work + fixed red errors on malformed input 2017-09-08 18:58:04 +08:00
1efc2a9b5d little ui fixes 2017-09-08 18:02:12 +08:00
9441c1cffe fixed #935 2017-09-08 17:57:15 +08:00
ef30d2d3b6 fixes #945 2017-09-08 15:59:19 +08:00
1673966e36 Merge pull request #942 from Markovskij/openssl
Make tunnels.conf more readable with QT GUI
2017-09-07 09:37:07 -04:00
1d8f913364 Merge branch 'openssl' of github.com:Markovskij/i2pd into openssl 2017-09-04 07:25:06 +03:00
a549ebc25f Add constants 2017-09-04 07:23:59 +03:00
ce853786b5 Merge pull request #2 from PurpleI2P/openssl
Update
2017-09-04 06:52:57 +03:00
7e0ab6d0b1 Merge pull request #943 from majestrate/connect-proxy
HTTP CONNECT in http proxy
2017-09-03 15:28:28 -04:00
d6f907a05b make it work 2017-09-03 11:13:43 -04:00
b2d1962b81 add http connect to http proxy (untested) 2017-09-03 09:46:55 -04:00
b0a6c9fa53 Make tunnels.conf more readable 2017-09-03 15:55:51 +03:00
7a0337f3db Merge pull request #1 from PurpleI2P/openssl
Update
2017-09-03 14:10:25 +03:00
c1dbd3ffd0 Merge pull request #940 from majestrate/defer-connect
Defer connect
2017-09-01 11:40:26 -04:00
1ea6d2016d add initial connection timeout for i2ptunnel 2017-08-31 12:08:22 -04:00
416589cc93 Revert "add deferred ready checking for destination"
This reverts commit 3f409d0e28.
2017-08-31 10:38:26 -04:00
41ce9d47e5 Revert "re trigger timer"
This reverts commit f87a51034e.
2017-08-31 10:37:58 -04:00
d7e4deab4e Revert "tabify"
This reverts commit 897cfad399.
2017-08-31 10:37:57 -04:00
27782ceddd Revert "clarify"
This reverts commit 7af3b751d4.
2017-08-31 10:37:56 -04:00
a6f62a99b9 Revert "use shared from this"
This reverts commit 4e4def4fb9.
2017-08-31 10:37:53 -04:00
4e4def4fb9 use shared from this 2017-08-31 10:24:07 -04:00
7af3b751d4 clarify 2017-08-31 10:14:06 -04:00
897cfad399 tabify 2017-08-31 10:12:59 -04:00
f87a51034e re trigger timer 2017-08-31 10:07:09 -04:00
3f409d0e28 add deferred ready checking for destination 2017-08-31 09:59:04 -04:00
543566840c Merge pull request #936 from hypnosis-i2p/openssl
ReloadConfig + --log fix
2017-08-27 13:43:09 -04:00
1c3174a277 fixed #841 2017-08-27 21:16:52 +08:00
fc2ae6f887 fixed ReloadConfig(); fixed --log 2017-08-27 20:52:55 +08:00
63e175d389 fixed #913 2017-08-27 20:39:10 +08:00
9bfbba6fea Merge pull request #934 from hypnosis-i2p/openssl
various small qt gui fixes
2017-08-27 07:28:15 -04:00
69d245c4bd Merge pull request #933 from myfingerhurt/openssl
Fix deformed json result with an extra comma
2017-08-27 06:44:02 -04:00
7738eae4b0 general settings widget ui revolution for convenience + widget locks: fixed #927 2017-08-27 16:10:09 +08:00
3d5fb07ca8 various small qt gui fixes 2017-08-27 12:41:10 +08:00
0f0fb266c7 Fix deformed json result with an extra comma
{"id":1,"result":{"i2p.router.net.bw.in":48,"i2p.router.net.bw.out":48,},"jsonrpc":"2.0"}
You can see there is an extra comma behind the number 48.
2017-08-27 12:57:06 +09:00
5c3d6298b0 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2017-08-25 14:46:24 -04:00
028f0bdb8d Fixed #931. don't insert null pointer into DHkeys list 2017-08-25 14:45:58 -04:00
44bcdc6866 Merge pull request #932 from Markovskij/openssl
Web interface fix
2017-08-24 20:46:21 -04:00
b9f6f92bad Web interface fix 2017-08-25 02:37:01 +03:00
1607535416 strip out Accept and From headers 2017-08-24 15:13:15 -04:00
f6ced9279b new reseed added 2017-08-20 17:34:53 -04:00
95af716a96 Merge pull request #925 from hypnosis-i2p/openssl
Qt GUI now shows buttons under Status and their corresponding info panes
2017-08-20 06:56:39 -04:00
07fe51fa25 some qt gui changes 2017-08-20 13:40:14 +08:00
822995cbaf ignored android/libs/ 2017-08-20 13:40:14 +08:00
db0e02c05d qt ui - status commands are now pushbuttons with no handlers 2017-08-20 13:40:14 +08:00
856dda68db qt ui - now all buttons have handlers 2017-08-20 13:40:14 +08:00
163cbcb89d qt ui - status main page now works 2017-08-20 13:40:14 +08:00
a79f614e12 qt ui - now pixel perfect buttons 2017-08-20 13:40:14 +08:00
7d3a818565 qt ui - laid out better 2017-08-20 13:40:14 +08:00
978bb47b92 qt ui - settings buttons renamed to *Settings 2017-08-20 13:40:14 +08:00
b791a6a348 qt ui - status buttons done 2017-08-20 13:40:14 +08:00
c21c1f5225 Merge pull request #920 from PurpleI2P/openssl
2.15.0
2017-08-17 14:20:41 -04:00
d6253b1dee remove dupe lines 2017-08-17 21:17:25 +03:00
390bb07cca 2.15.0 2017-08-17 14:09:16 -04:00
309822d933 teminate hadlers upon cleanup 2017-08-10 20:29:35 -04:00
8cb612c10c Merge pull request #919 from l-n-s/peertest_fix2
Don't do peertest if nat=false. FIX #915
2017-08-09 11:09:32 -04:00
7e244455c4 Don't do peertest if nat=false. FIX #915 2017-08-09 10:52:52 -04:00
907fe3d8d9 Merge pull request #918 from majestrate/readme_fixups
explicitly link to build instructions in readme
2017-08-09 08:51:02 -04:00
6420e33fb8 link to build instructions in readme 2017-08-09 08:50:00 -04:00
0b560fdd27 0.9.31 2017-08-08 09:29:30 -04:00
04297eda80 Merge pull request #916 from majestrate/vanity
add stuff for address generator tool
2017-08-07 15:05:19 -04:00
c13fd2261e add stuff for address generator tool 2017-08-07 14:00:50 -04:00
034bff5b2f added gostcoin family certificate 2017-08-02 21:19:12 -04:00
987ad214ff avoid bind exeptions during reload 2017-08-02 21:00:04 -04:00
d11ac64b95 stop I2P tunnel upon deletion 2017-07-28 15:40:07 -04:00
4c8c3b6947 add and remove tunnels without stopping others 2017-07-28 15:12:15 -04:00
d47d8d22a3 removed all Accept-* headers but Accept-Encoding 2017-07-28 11:16:42 -04:00
0ec9defc6e Merge pull request #911 from hypnosis-i2p/openssl
qt ui fixes
2017-07-28 06:27:12 -04:00
4776f11b6a http proxy and socks - initialized comboboxes correctly 2017-07-28 12:57:19 +08:00
3118d7bede restart button now has a handler 2017-07-28 11:59:45 +08:00
a83be187f3 ui fixes 2017-07-28 10:43:20 +08:00
deb5e435e5 fixed i2pd qt gui a bit 2017-07-28 09:21:41 +08:00
9f824f3aa9 remove Accept-Language 2017-07-27 18:45:53 -04:00
032e68da05 Merge pull request #908 from r4sas/openssl
add socks.outproxy.enabled and workout with Config.cpp tabulation
2017-07-19 07:12:19 -04:00
486661d6c6 implement != 2017-07-18 18:27:07 -04:00
aa86ab97f0 update i2pd.conf example, update socks proxy tunnel 2017-07-19 00:36:56 +03:00
a17f07495a add socks.outproxy.enable option 2017-07-19 00:21:02 +03:00
16d3440a4c tabulation workout on Config.cpp 2017-07-18 23:55:53 +03:00
d7b412c1eb overwrite existing address 2017-07-18 15:58:32 -04:00
e5751334d6 update doxygen config 2017-07-15 10:02:15 +03:00
1fb1d7e4e9 don't create SSU session if endpoint is not specified. Wait from RelayResponse 2017-07-13 14:13:58 -04:00
adc20e78da Merge pull request #906 from l-n-s/fix_docker
Docker: fix permissions issue
2017-07-11 21:07:25 +00:00
d499e250e0 Docker: fix permissions issue 2017-07-11 17:00:50 -04:00
68166c22b3 Merge pull request #904 from l-n-s/fix_netdb_thread
NetDb: If NetDb is empty, throw exception instead of killing NetDb thread
2017-07-11 06:28:33 -04:00
06b2b26e39 NetDb: If NetDb is empty, throw exception instead of killing NetDb thread 2017-07-11 02:55:38 -04:00
641ca3d49d install windows service with daemon argument 2017-07-10 01:14:55 +03:00
6d259e00a3 add additional break row 2017-07-08 16:59:10 +03:00
2bc5b97662 separate transports output for IPv4 and IPv6 2017-07-08 16:54:12 +03:00
676c61aa99 fix typo 2017-07-08 16:53:33 +03:00
eade8003ef Merge pull request #902 from l-n-s/fix_options
Fix options: make useless boolean flags configurable in command line
2017-07-07 22:13:01 -04:00
817bbefac6 Fix options: make useless boolean flags configurable in command line 2017-07-07 18:23:27 -04:00
cded6206dc cleanup unused destinations 2017-07-07 15:12:34 -04:00
c287fb58bd reference counter for destinations 2017-07-06 16:12:06 -04:00
1b97f9b6c9 Merge pull request #894 from kayrus/kayrus/run_systemd
Create run dir for i2pd process in systemd unit file
2017-06-23 14:52:14 +03:00
14ca3fc2f3 Merge pull request #896 from PurpleI2P/openssl
recent changes
2017-06-23 07:41:31 -04:00
4bc1143418 update makefile to use gcc 7 on archlinux 2017-06-23 13:02:31 +03:00
4267063dba Create run dir for i2pd process in systemd unit file 2017-06-23 10:25:13 +02:00
8f8b4536b6 add future R4SAS reseed cert replacement
warn: will use after 2.16.0 release
2017-06-22 15:45:23 +03:00
8121ab5163 added including of configs and certificates in mingw batch build 2017-06-22 15:37:02 +03:00
76fab1fea8 reseeds update 2017-06-18 16:41:09 -04:00
143b235a22 Merge pull request #892 from hypnosis-i2p/openssl
Qt GUI + more of SAM debug logging
2017-06-17 08:38:18 -04:00
3a89f2c32f now starting the i2pd daemon - uncommented emit start line 2017-06-17 20:31:00 +08:00
7bab92042a removed some obsolete files 2017-06-17 20:23:33 +08:00
7379b4ddd2 merged with upstream 2017-06-17 20:23:33 +08:00
298181999d qtui first draft completed 2017-06-17 20:23:33 +08:00
61e1e7fe8f added one missing sigtype to Identity.h. Some work on qt gui. 2017-06-17 20:23:33 +08:00
b3050af1a7 some work on desktop qt gui 2017-06-17 20:23:33 +08:00
275da075e0 various qt work 2017-06-17 20:23:33 +08:00
9925e2732a rework + now restarts after app kill event 2017-06-17 20:23:33 +08:00
59b3daabc5 qt gui preliminary results 2017-06-17 20:23:33 +08:00
f2b0f64138 tmp 2017-06-17 20:23:33 +08:00
5df77eb474 qt forms now work even better! 2017-06-17 20:23:33 +08:00
f202fb9af6 qt forms now work! 2017-06-17 20:23:33 +08:00
5b769869d0 fixed qt .pro file 2017-06-17 20:23:33 +08:00
8e266058ae more of SAM debug logging 2017-06-17 20:23:33 +08:00
7c21712e80 Merge pull request #891 from r4sas/win_patch
remove msvc project and fix some warnings
2017-06-11 15:13:37 +03:00
193fc343fe reupload mistakenly deleted iss project 2017-06-11 09:38:07 +03:00
a1e9c3d270 remove NSIS template 2017-06-11 09:34:19 +03:00
629261c4be remove msvc and NSIS project files
fix some windows build warnings
2017-06-11 09:29:31 +03:00
f6d3a6239c Merge pull request #884 from l-n-s/dockerfile_updates
Add updated Dockerfile
2017-06-08 16:21:45 +02:00
83c5131b67 skip expired introducer 2017-06-07 10:53:50 -04:00
36afef3498 Merge pull request #889 from PurpleI2P/openssl
recent changes
2017-06-05 09:02:42 -04:00
52c0485b0c Merge pull request #887 from BOPOHA/patch-2
bogus date in contrib/rpm/i2pd.spec
2017-06-04 18:43:03 -04:00
8c23a091da bogus date in contrib/rpm/i2pd.spec
fixed bad date and  bogus date in %changelog
2017-06-05 00:41:14 +02:00
ca121f80ee Merge pull request #885 from ryzhovau/spaces
Cosmetic changes for "Host XXX.YY not inside I2P network" message
2017-06-04 19:57:55 +03:00
b48846506f Cosmetic changes for "Host XXX.YY not inside I2P network" message
Signed-off-by: Alexander Ryzhov <github@ryzhov-al.ru>
2017-06-04 19:39:15 +03:00
a1c72be2a9 Add updated Dockerfile 2017-06-04 02:47:27 -04:00
2098368417 Merge pull request #883 from BOPOHA/patch-1
base version updated to 2.14.0
2017-06-04 05:51:33 +00:00
4014d86a57 base version updated to 2.14.0 2017-06-04 00:23:22 +02:00
e84e8748bd fixed android build 2017-06-01 10:41:15 -04:00
bd8166e630 2.14.0 2017-06-01 10:05:20 -04:00
03d1519b39 2.14.0 2017-06-01 10:04:02 -04:00
36c4719570 Merge pull request #881 from majestrate/ntcp-socks
NTCP SOCKS/HTTP Proxy support
2017-05-29 10:36:46 -04:00
7c970771c5 fix 2017-05-29 10:09:24 -04:00
3f64c042bd Fixed #880. Print if AESNI or AVX enabled 2017-05-29 10:08:49 -04:00
e336cbfb2d add http proxy, change socks4a to socks5 2017-05-29 09:57:30 -04:00
24eec76428 more 2017-05-29 02:16:57 -04:00
71c9b15ff1 more 2017-05-29 02:12:16 -04:00
2940f0d67c capture by value not reference 2017-05-29 01:53:34 -04:00
cbb1d2d3b5 more whitespace bullshit 2017-05-29 01:44:06 -04:00
36dd11a899 more whitespace bullshit 2017-05-29 01:39:11 -04:00
be88969b79 more whitespace bullshit 2017-05-29 01:38:32 -04:00
d91ad54ed9 more whitespace bullshit 2017-05-29 01:37:19 -04:00
1330228080 fix whitespace bullshit 2017-05-29 01:35:11 -04:00
3ea1eca350 ntcp socks proxy (initial) 2017-05-29 01:28:16 -04:00
a4e6d8120b handle iexp 2017-05-24 12:49:36 -04:00
3219de235c Merge pull request #875 from majestrate/cmake-avx
add AVX option to cmake build system
2017-05-22 14:37:42 -04:00
4e5c2ff620 add AVX option to cmake build system 2017-05-22 11:12:08 -04:00
63e25f0ff9 Merge pull request #873 from majestrate/fix-addressbook
try fixing issue #871
2017-05-22 10:51:48 -04:00
840225b580 try fixing issue #871 2017-05-22 10:34:29 -04:00
bd221d60d6 Merge pull request #872 from majestrate/fix-websocket-cmake
fix cmake compile error with websockets
2017-05-21 08:38:07 -04:00
8a3bb50143 fix cmake compile error with websockets 2017-05-21 08:18:16 -04:00
e4cd1a465c ignore comments 2017-05-10 09:36:58 -04:00
2173a9f246 Merge pull request #869 from bit/patch-1
Build depends on zlib.h (zlib1g-dev)
2017-05-08 14:58:33 -04:00
bit
973a838e2a Build depends on zlib.h (zlib1g-dev) 2017-05-08 12:54:08 +02:00
d95ee55497 skip comment address line 2017-05-05 13:54:21 -04:00
124e2e759c fix #846. ability to limit transit bandwidth 2017-05-04 14:58:12 -04:00
ac918e3618 0.9.30 2017-05-04 09:40:00 -04:00
009a720c32 disabled dead reseed 2017-05-02 21:08:51 -04:00
0dbfa43dad moveable to SD card 2017-05-02 19:25:34 -04:00
e0b4d36a74 changed target sdk back to 25 2017-05-02 18:06:06 -04:00
a441474d75 show transit bandwidth 2017-05-02 14:20:00 -04:00
cfd3c3628e count and show transit traffic 2017-04-27 16:11:37 -04:00
474d52f805 minor performance improvements 2017-04-27 10:12:22 -04:00
7ee8bdf2f3 Merge branch 'master' of https://github.com/PurpleI2P/i2pd into openssl 2017-04-27 10:11:45 -04:00
8a9757111f enable SAM by default 2017-04-24 12:20:15 -04:00
65dda4a70b Merge pull request #865 from l-n-s/update_config
Sample config: enable SAM by default + update description for notransit
2017-04-24 15:10:57 +00:00
1ed39dbbed Sample config: enable SAM by default + update description for notransit 2017-04-24 11:07:54 -04:00
8162c2e4e4 GST added 2017-04-23 06:52:37 -04:00
a7d74f3f98 update debian stuff 2017-04-23 07:09:12 +03:00
ad83ae1e7a removed stdafx 2017-04-22 14:52:19 -04:00
066374906e Merge pull request #862 from r4sas/makefile
update Makefile, tunnels.conf, android platform
2017-04-22 05:35:53 +04:00
ec79a4a6f6 Merge pull request #861 from majestrate/fix-case-insensative-include
remove uneeded lines in qt build file
2017-04-21 21:34:02 -04:00
9fae215db4 update android platform to 14 2017-04-22 04:20:22 +03:00
92b40c9485 update tunnels.conf 2017-04-22 04:19:32 +03:00
19fc59739f update makefile-s 2017-04-22 04:17:01 +03:00
7e0ae4c601 remove uneeded lines in qt build file 2017-04-21 21:01:48 -04:00
81c2f4b30b Merge pull request #860 from majestrate/fix-case-insensative-include
NetDb.h -> NetDb.hpp
2017-04-21 20:46:56 -04:00
e238f7ed37 NetDb.h -> NetDb.hpp for case insensative file systems clashing with libc's netdb.h 2017-04-21 20:04:16 -04:00
2756f3332c changed android target sdk to 25 2017-04-21 12:05:58 -04:00
14b3eefbaf change minimal requirement to android 4.0 2017-04-21 11:54:08 -04:00
dc946582a4 generic path to sdk 2017-04-21 09:54:35 -04:00
dfa14a73a8 Merge pull request #858 from majestrate/restructure
Restructure
2017-04-21 08:52:59 -04:00
112aa845f4 use correct #include in Win32 2017-04-21 07:20:50 -04:00
150a309175 include daemon directory for Win32 mingw 2017-04-21 07:08:31 -04:00
55c14819a3 Merge pull request #859 from PurpleI2P/openssl
recent changes
2017-04-21 06:53:56 -04:00
598897caa6 fix mingw build 2017-04-21 06:48:57 -04:00
cf3f8a796a fix path 2017-04-21 06:36:49 -04:00
bffc294b13 fix path 2017-04-21 06:35:39 -04:00
4cc3b7f9fb restructure build to separate the 3 main components into 3 subdirectories
libi2pd for core libs

libi2pd_client for i2pd client libs

daemon for i2pd daemon libs
2017-04-21 06:33:45 -04:00
b3161dde93 Merge pull request #855 from v2e/patch-2
kbps --> KBps
2017-04-19 07:05:29 -04:00
v2e
5550eabac1 kbs -- KBs in i2pd.conf 2017-04-19 11:39:01 +03:00
v2e
b2b320174b kbps -- KBps in Config.cpp 2017-04-19 11:36:19 +03:00
dd79348b35 delete used tag before update 2017-04-14 22:08:43 -04:00
bd6ce7d4da reduced memory usage 2017-04-14 10:19:26 -04:00
7a67670e1a Fixed #846. httpproxy.addresshelper config parameter added 2017-04-11 14:36:28 -04:00
539bf482b9 Merge pull request #844 from majestrate/datagram-fixes
Datagram fixes
2017-04-09 09:16:37 -04:00
ed67ce7f33 tabifty 2017-04-09 08:53:47 -04:00
d91c7e5e79 fix datagram bugs 2017-04-09 08:52:42 -04:00
4f1dfe2ef7 fixed android build 2017-04-08 17:21:56 -04:00
36ea6c13df Merge pull request #843 from majestrate/obep-ibgw
Allow point to point client tunnels to use OB tunnels that share OBEP and IBGW of remote destination
2017-04-08 15:32:26 -04:00
3acb0aac98 tabify 2017-04-08 15:16:51 -04:00
fdf4b3878f tabify 2017-04-08 15:15:59 -04:00
2fe71782a7 tabify 2017-04-08 15:14:47 -04:00
89dfe2b763 delay request 2017-04-08 15:10:16 -04:00
9b62f238ed add option for client tunnels to build tunnels such that OBEP==IBGW 2017-04-08 15:10:06 -04:00
987688f196 GOST hash of a Little Endian stream 2017-04-07 11:17:40 -04:00
46cb95f16c Merge pull request #842 from PurpleI2P/openssl
2.13.0
2017-04-06 10:02:54 -04:00
4e1fcbb706 update appveyor tag to 2.13 2017-04-06 17:01:39 +03:00
e4c038762b 2.13.0 2017-04-06 09:48:47 -04:00
86dfa200a6 update changelog to 2.13 2017-04-06 16:32:00 +03:00
165cf980d2 fixed memory leak 2017-04-05 18:26:56 -04:00
13ccb16a4a fixed memory leak 2017-04-05 17:44:23 -04:00
f4b5426865 update debian/control 2017-04-04 18:47:50 +03:00
c2f62ba52a persist incoming tags 2017-04-03 15:05:10 -04:00
b2d2c56a09 Merge pull request #839 from PurpleI2P/openssl
recent changes
2017-04-03 11:47:31 -04:00
abf0f5ac87 fixed typo 2017-03-31 12:26:20 -04:00
fa1965deb4 assign signature types 8 and 9 to GOST R 34.10 2017-03-31 10:04:39 -04:00
1f76dc78d8 cleanup acceptor for AcceptOnce 2017-03-30 20:27:31 -04:00
4448884a3e handle SIGNATURE_TYPE for DEST GENERATE 2017-03-30 15:43:02 -04:00
e3fc23bae8 restore previous acceptor later 2017-03-30 13:40:29 -04:00
29ceed74a2 don't drop destination's acceptor if inactive acceptor gets closed 2017-03-30 11:59:39 -04:00
382308c3fd change acceptor back to previous before processing 2017-03-30 11:22:38 -04:00
3d1b6e29c6 Merge pull request #838 from majestrate/sam-crash-fix-2017-03-29
try fixing sam crashyness
2017-03-29 15:01:22 -04:00
3a9a5ec669 try fixing sam crashyness 2017-03-29 14:38:55 -04:00
8c37c491a9 send STREAM CONNECT follow on data 2017-03-29 13:59:48 -04:00
fdf11e6038 allow unknown options for api 2017-03-29 10:51:32 -04:00
8e558f0826 recover public key from GOST R 34.10 signature 2017-03-26 08:55:15 -04:00
69804c23f1 check if destination keys are correct 2017-03-25 16:53:20 -04:00
9aa9a62ed4 AESNI for x86 2017-03-25 08:16:56 -04:00
d9b79f47c8 GetGroup () for GOST curve 2017-03-23 19:26:39 -04:00
249bc42667 merge S,P,L for GOST R 34.11-2012 2017-03-22 10:26:11 -04:00
644c184f7c Merge branch 'openssl' into openssl 2017-03-22 17:49:44 +04:00
66cfae7b3b more memory allocation optimization 2017-03-21 20:51:13 -04:00
bd2c2acd5f use CryptoProA params for GOST R 34.10-2012 256 bits 2017-03-21 11:48:34 -04:00
13aab750dd GOST signature unit test added 2017-03-21 10:45:57 -04:00
7a51abc2f9 GOST unit tests added 2017-03-21 09:44:09 -04:00
44a3e08095 GOST unit tests added 2017-03-21 09:43:36 -04:00
2aa8cf7104 update gitignore 2017-03-21 15:24:27 +03:00
1b1cfe1b92 rewrote win build script and moved it to build folder 2017-03-21 15:03:31 +03:00
199c2cdb66 some improvement of GOST R 34.11 2017-03-20 14:25:38 -04:00
726828a487 use GOST 34.11-2012 with GOST 34.10 2017-03-20 11:57:39 -04:00
fcbf81a3d4 correct implementation of L for GOST R 34.11-2012 2017-03-20 11:33:45 -04:00
7637b51ba5 fix #833. Handle SIGPIPE 2017-03-20 09:52:43 -04:00
3afed3b316 Merge pull request #832 from PurpleI2P/openssl
recent changes
2017-03-19 11:02:36 -04:00
3d6e334007 Appveyor merge (#1) 2017-03-18 05:22:02 +04:00
6c848a57b6 recreated appveyor config 2017-03-18 02:40:39 +03:00
eb12d43800 update windows build scripts 2017-03-17 20:59:10 +03:00
465366e644 new ressed 2017-03-16 20:55:05 -04:00
289e9c809f correct padding for GOST 34.11 2017-03-16 16:30:32 -04:00
8b40354786 GOST R 34.11-2012 implementation 2017-03-16 13:31:25 -04:00
8de8de1b1e GOST 34.11-2012 functions 2017-03-15 20:46:27 -04:00
4b76c76712 correct x for tc26 paramSetA 256 2017-03-15 14:59:17 -04:00
6b9a270506 enable TC26 paramSet A 512 for GOST 34.10-2012 2017-03-15 12:41:02 -04:00
da2c49ab66 tc26 paramSetA 512 for GOST 34.1002012 2017-03-14 21:15:17 -04:00
af2a3f3a65 Gost.cpp added 2017-03-14 21:14:23 -04:00
6369a900da added TC26 param sets for GOST R 34.10-2012 2017-03-14 20:03:44 -04:00
e877247032 support of GOST 34.10-2012 512 bits 2017-03-14 16:41:06 -04:00
5bcc5ff873 initial support of GOST R 34.10-2012 2017-03-14 16:02:16 -04:00
a52064463e fixed race condition 2017-03-14 12:03:51 -04:00
6ed7f19673 moved GOST to separate file 2017-03-13 20:28:36 -04:00
9aba0ba5a8 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2017-03-12 14:48:47 -04:00
5803a84bd7 change establish timeout to 10 seconds 2017-03-12 14:48:11 -04:00
ce0bf0f4b4 re-fix year 2017-03-12 18:29:57 +03:00
65ed57aff4 fix year 2017-03-12 18:28:25 +03:00
1317b80fca terminate incoming connection by timeout 2017-03-11 21:32:35 -05:00
f0d6145fa6 terminate incoming connection by timeout 2017-03-11 21:17:19 -05:00
c0c157ecef use common context for ElGamal encrypt/decrypt 2017-03-11 16:48:54 -05:00
4bb607f180 Merge pull request #824 from BOPOHA/openssl
i2pd.spec: changed Release format, upgrade Version
2017-03-10 19:25:28 -05:00
2eec205e31 i2pd.spec: changed Release format, upgrade Version 2017-03-11 00:31:00 +01:00
bd8cdd345a A,B,B param sets for GOST R 34.10 2017-03-10 16:57:56 -05:00
7caf3ea7d0 eliminate dependancy from GOST engine for GOST R 34.10 2017-03-10 13:21:22 -05:00
ba89c60b6d correct param set for GOST R 34.10 verification 2017-03-10 11:55:30 -05:00
084e48d6dd ZEC added 2017-03-10 11:53:49 -05:00
1bed3f3936 ZEC added 2017-03-10 11:53:05 -05:00
cd860bfbf8 correct param set for GOST R 34.10 signing 2017-03-09 21:46:34 -05:00
439c2d445c GOST R 34.10 sign 2017-03-09 20:13:21 -05:00
7f71d5dbd8 generate GOST R 34.10 keys with param set 2017-03-09 18:46:28 -05:00
831c835106 GOST R 34.10 param sets 2017-03-08 19:35:51 -05:00
5dfb7cb938 GOST R 34.10 curve added 2017-03-07 16:36:17 -05:00
044d6a2207 eliminate some BIGNUM allocation overhead 2017-03-07 15:02:01 -05:00
955b46534d eliminate some BIGNUM allocation overhead 2017-03-07 14:51:05 -05:00
0e8d80e055 eliminate some BIGNUM allocation overhead 2017-03-07 14:24:19 -05:00
92fc736cfa recreate SSU session again if session key is invalid 2017-03-05 17:08:20 -05:00
60ed43c11b #818. Exploratory config 2017-02-28 15:58:53 -05:00
319f72ae2a 0.9.29 2017-02-28 15:19:49 -05:00
04dc34260f replaced stringstream by a list of buffers 2017-02-26 15:05:14 -05:00
a8196d1f33 Merge pull request #816 from PurpleI2P/openssl
recent changes
2017-02-26 09:29:14 -05:00
1ce6ad5ccc cleanup send buffer 2017-02-24 11:04:40 -05:00
145e36925f check certificate size 2017-02-23 22:08:25 -05:00
c07928144c GOST support for Android openssl 1.1 2017-02-21 15:43:03 -05:00
d8c30f6cbb fixed typo 2017-02-21 11:38:11 -05:00
e968c6a2a4 fixed typo 2017-02-21 11:36:53 -05:00
ffc3a31d09 fixed andorid build 2017-02-21 11:23:14 -05:00
d6e037dd28 fixed build error 2017-02-19 19:31:37 -05:00
83b9b3bf4a enable GOST R 34.10 signatures from netid!=2 2017-02-19 18:08:10 -05:00
1cb89ce20d set correct curve parameters for GOST R 34.10 2017-02-19 14:45:10 -05:00
d75b916153 correct GOST engine initialization 2017-02-18 18:45:21 -05:00
192b484a8c fixed typo 2017-02-18 07:00:14 -05:00
85e2137d0e disable incorrect check 2017-02-18 09:14:23 +03:00
c1042c8f20 GOST R 34.11 hash 2017-02-17 22:26:24 -05:00
c91b05bd4b set correct curve from GOST R 34.10 signer and verifier 2017-02-17 13:37:53 -05:00
f8a09df5c0 generate GOST R 34.10 keys pair 2017-02-16 21:45:12 -05:00
9363db816c GOST R 34.10 signer and verifier 2017-02-16 21:18:18 -05:00
22af4da4d4 initial support of GOST crypto 2017-02-16 16:27:24 -05:00
16fa10b056 fix incorrect traffic counting 2017-02-16 17:45:38 +03:00
f044851abb fix typo 2017-02-16 16:29:08 +03:00
217e99a0e2 updated InnoSetup script
deleted old unused icon
added doxygen "docs/generated" folder to gitignore
2017-02-16 16:16:19 +03:00
1bc4aea217 Merge pull request #808 from l-n-s/update_docs
Update docs
2017-02-16 11:52:32 +00:00
4997934bfe Fix paths for moved contrib files 2017-02-16 06:48:06 -05:00
4905dded87 Moved files from docs/ to contrib/ 2017-02-16 06:36:01 -05:00
ff6447ae2b Merge pull request #806 from l-n-s/update_docs
Update docs
2017-02-16 06:37:55 +00:00
7f51857fa5 Update README.md 2017-02-16 01:20:59 -05:00
78c3babc37 Move docs to new repo 2017-02-16 01:14:07 -05:00
83300044dd fix osx upnp support
fix tabulation in UPnP.cpp
2017-02-15 09:04:40 +03:00
55f891e2aa fixed build error for gcc 4.7 2017-02-14 14:20:37 -05:00
7ae40d89c1 updated ChangeLog 2017-02-14 12:39:59 -05:00
29cc1cf390 Merge pull request #805 from PurpleI2P/openssl
2.12.0
2017-02-14 12:38:32 -05:00
960d9a8534 updated ChangeLog 2017-02-14 12:36:54 -05:00
bcc8529bfc update year, maintainer, ulimit -n 4096 default 2017-02-14 20:17:20 +03:00
d773647a20 2.12.0 2017-02-14 12:11:43 -05:00
3a5a0837c7 don't show error if stream closed 2017-02-14 12:11:30 -05:00
44cfe6af1c upstream pull 2017-02-13 14:17:48 +03:00
cf6d445080 winapi - fix style, delete hFont object after drawing (fixes overflow) 2017-02-13 14:12:48 +03:00
422f8b3660 publish with min interval of 20 seconds 2017-02-12 20:52:46 -05:00
b097938f47 compressed addressbook request 2017-02-12 15:11:19 -05:00
c231eff4b1 MTU size of 1488 for ipv6 2017-02-12 10:12:12 -05:00
1ddc96f965 correct publication verification 2017-02-12 10:08:52 -05:00
13111c4b42 don't re-schedule resend timer if nothing to resend 2017-02-11 18:18:37 -05:00
7c70dbce65 Merge pull request #801 from l-n-s/apparmor
Added AppArmor profile
2017-02-10 18:56:38 +00:00
25559f1772 Added AppArmor profile 2017-02-10 13:51:19 -05:00
c010c83654 signaturetype ofr HTTP and SOCKS proxy 2017-02-10 12:51:55 -05:00
2057531e8c Processing transferred data (winapi) 2017-02-09 21:41:52 +03:00
277d4d9333 Added status output to main window 2017-02-09 19:45:22 +03:00
051e642c0c fixed #798. Correct buffer size 2017-02-09 11:05:42 -05:00
a8778e358d handle HTTP response 2017-02-06 21:39:15 -05:00
d2edbfd6fa eliminate extra copy 2017-02-06 12:50:54 -05:00
d96dbe9365 use _USE_32BIT_TIME_T in win32 build
Add i2pd.exe in .gitignore
2017-02-06 16:18:23 +03:00
35b5dcdb22 new reseed 2017-02-05 17:08:42 -05:00
66f3bd186f send http headers in original order 2017-02-04 22:39:54 -05:00
7ae38a71cc reduced I2NP message size for tunnel gateway 2017-02-03 20:57:04 -05:00
2ed356be65 Merge pull request #794 from l-n-s/reseed_from_zip
Added protection from clickjacking (#706)
2017-02-03 14:38:25 -05:00
99436c1334 Added protection from clickjacking (#706) 2017-02-03 14:13:55 -05:00
9e57a4ea28 use I2NP message of tunnel data length for TunnelData 2017-02-02 20:45:33 -05:00
19e5b8cc50 Merge pull request #793 from l-n-s/reseed_from_zip
Added reseed.threshold + refactor
2017-02-02 15:52:25 -05:00
33310732a6 Add reseed.threshold option 2017-02-02 15:40:57 -05:00
a03bf89190 Refactored code to Reseed module 2017-02-02 15:25:25 -05:00
1b089ca5e6 Merge pull request #792 from l-n-s/reseed_from_zip
Added option to reseed from ZIP file
2017-02-01 17:34:51 -05:00
21e23d5511 Added option to reseed from ZIP file 2017-02-01 17:17:25 -05:00
8a2c4ab3de don't create identity if presented in netdb already 2017-02-01 15:20:03 -05:00
040585bf3d Merge pull request #791 from PurpleI2P/openssl
recent changes
2017-02-01 14:18:41 -05:00
9030b3e04c Merge pull request #790 from majestrate/sam-datagrams
udp datagrams and whitespace cleanups in SAM
2017-01-31 12:14:27 -05:00
0b46495afd i2p.router.net.tunnels.successrate 2017-01-31 12:12:39 -05:00
ace16d473f fix 2017-01-31 11:55:57 -05:00
925c51420d use correct format 2017-01-31 11:32:50 -05:00
764b8ab7a5 wrong param 2017-01-31 11:22:28 -05:00
cb6a1bfb1d unindent 2017-01-31 11:20:16 -05:00
775b9f30f0 indentation fixes and SAM datagrams 2017-01-31 11:16:55 -05:00
76fd1c5c58 udp sockets for sam 2017-01-31 11:06:45 -05:00
3e2605490f cleanup error messages 2017-01-30 20:36:35 -05:00
7094588c53 print zlib error codes 2017-01-30 19:56:06 -05:00
3523047243 #788 ReseedFromZIPFile added 2017-01-30 19:31:01 -05:00
bdcbaa031d clean transit tunnels endpoints 2017-01-29 19:16:34 -05:00
f722b3e9cb Moved reopening of log to SIGUSR1 (16)
Added --pidfile option to init.d script
2017-01-29 17:08:36 +03:00
2d46cb072e disabled cleanup() before deleting stream on termination (line 54) 2017-01-28 19:23:14 +03:00
28cf450bfa show status of shared local destination 2017-01-28 09:18:30 -05:00
4aa48fb4b6 websocks added 2017-01-27 20:41:15 -05:00
aa86593702 send correct response if JSON parse error 2017-01-27 14:51:06 -05:00
faa368cc07 show if router is connected in i2p.router.status 2017-01-26 15:59:33 -05:00
a840ed06b7 update android notification icon
update android qt app icon
add mingw build batch and .gitignore
2017-01-26 11:08:25 +03:00
7196bfd157 keep bandwidth caps if unreachable 2017-01-25 16:37:21 -05:00
a6785e9143 support of 'X' in RouterInfo 2017-01-25 16:14:01 -05:00
4d2f26b1cd limit number of precalculated DH pairs 2017-01-25 11:20:15 -05:00
188987a8ff eliminated deprecated function 2017-01-23 16:22:48 -05:00
14d74d3230 use openssl 1.1 for androidn build 2017-01-23 15:36:45 -05:00
bcd6bd6b04 correct handle of AESNI/AVX 2017-01-23 13:22:03 -05:00
8e4bd7fe4a build with openssl 1.1 2017-01-23 13:14:08 -05:00
8ab552793a Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2017-01-22 21:22:47 -05:00
29944f6bf2 cleanup stream upon termination 2017-01-22 21:22:12 -05:00
162b60a05b Added script - builder for mingw. 2017-01-22 11:00:58 +03:00
da50d92d1e Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2017-01-21 19:00:30 -05:00
a746f5657f calculate shared key in separate thread for incoming connection 2017-01-21 18:59:50 -05:00
65ccc5bfce send actual local address to webirc 2017-01-20 10:02:16 -05:00
34939f9381 calculate shared key in separate therad 2017-01-19 22:00:02 -05:00
26e7821aaa Merge pull request #781 from PurpleI2P/openssl
recent changes
2017-01-19 21:57:08 -05:00
298c5f0de2 moved v6 receiver to separate thread 2017-01-19 15:47:01 -05:00
a6c2b25f6f increased socket buffer 2017-01-19 11:19:09 -05:00
3a8c90c0d4 acquire shared 2017-01-19 10:20:34 -05:00
a25ce2296a rollback 2017-01-19 09:58:55 -05:00
280407a553 new reseed 2017-01-18 20:04:23 -05:00
32c98e2161 correct packet size 2017-01-18 19:59:25 -05:00
2cbdb0bc17 fixed shared_ptr error 2017-01-17 12:13:56 -05:00
4317694c64 memory pool for SSU packets 2017-01-16 22:22:51 -05:00
e0879fbccb Merge pull request #779 from PurpleI2P/openssl
recent changes
2017-01-16 22:06:32 -05:00
9cb8e194b0 use generic container 2017-01-16 15:58:05 -05:00
dc914b1806 multithreaded memory pool 2017-01-16 15:40:01 -05:00
c70817b21a Merge pull request #778 from majestrate/datagram-fix-2017-01-13
use std::shared_from_this for DatagramSession
2017-01-16 09:01:25 -05:00
77918fd412 use std::shared_from_this 2017-01-16 07:54:56 -05:00
90d02234c7 Merge pull request #777 from l-n-s/fix_api_netid
Respect for netId option in api.cpp #696
2017-01-13 14:30:37 -05:00
b0b1c5af71 Respect for netId option in api.cpp #696 2017-01-13 14:24:53 -05:00
a8bd87938d honor enableuniquelocal for all server tunnel types 2017-01-13 13:47:51 -05:00
10d2f0a565 Merge pull request #774 from majestrate/datagram-fix-2017-01-13
try fixing crash in datagram code
2017-01-13 12:23:32 -05:00
c68aca4ada try fixing crash in datagram code 2017-01-13 11:54:29 -05:00
f46d96c4c6 renamed maptolooback to enableuniquelocal 2017-01-12 16:17:11 -05:00
e7b1ded486 correct behaviour of IsAcceptorSet 2017-01-12 14:19:57 -05:00
719de94821 acquire unique_ptr 2017-01-11 19:45:04 -05:00
7ea0249e6e use memory poll for streaming 2017-01-10 21:31:52 -05:00
feab95ce4b initial commit for memory pool 2017-01-10 16:14:18 -05:00
ca6f755634 http.enabled 2017-01-10 15:08:01 -05:00
70b30f7849 Merge pull request #772 from majestrate/ssu-revert
don't use heap allocated buffers in ssu and fill uninitialized memory
2017-01-08 15:28:23 -05:00
01ab027615 don't use heap allocated buffers in ssu 2017-01-08 11:10:23 -05:00
11f5db871f don't copy private keys 2017-01-08 09:07:54 -05:00
d83fc3181b EdDSA keys compatible with Java 2017-01-07 21:20:09 -05:00
b4657a0d05 Merge pull request #771 from majestrate/websocks
merge recent features and bugfixes
2017-01-07 14:13:42 -05:00
a5d6820453 fix 2017-01-07 13:55:17 -05:00
7b16aa6050 revert 2017-01-07 08:40:02 -05:00
c5d3c0c6f8 * add websocks
* enable socks, websocks and httpproxy as client tunnels

* remove old websocks config
2017-01-07 08:32:50 -05:00
43c1a87c48 Merge remote-tracking branch 'purple/openssl' into websocks 2017-01-07 07:39:04 -05:00
3755002381 Moving dockerfile to trigger autobuild of docker images. 2017-01-07 02:56:45 +01:00
dba38408c9 Merge pull request #770 from PurpleI2P/docker
Improved docker image
2017-01-06 20:37:04 -05:00
5b2bc23d03 Adding readme 2017-01-07 02:30:17 +01:00
a4cfdcb5c4 Improved and minimalized docker image 2017-01-07 02:17:02 +01:00
b6097160f1 Adding default port to config docs 2017-01-06 21:47:55 +01:00
fde1c08945 change country code to A1 2017-01-06 14:02:54 -05:00
417eb56a9b rollback to 2.6.0 2017-01-06 09:59:22 -05:00
0b28812f7e rollback 2017-01-05 17:37:39 -05:00
5ad25376bb send all outgoing messages in one buffer 2017-01-05 16:03:53 -05:00
b3ab85f3b5 Merge pull request #768 from PurpleI2P/openssl
recent changes
2017-01-05 15:47:04 -05:00
11231abe8a fixed warning 2017-01-05 13:31:23 -05:00
c577706415 Merge pull request #766 from majestrate/i2pcontrol-fixes
fix i2pcontrol bugs
2017-01-05 12:32:51 -05:00
f1eea6a0bf fix i2pcontrol bugs 2017-01-05 11:57:54 -05:00
8ce55f90d3 more i2pcontrol options 2017-01-05 10:30:27 -05:00
723f35ec5a fixed crash 2017-01-04 20:55:18 -05:00
025d9d3276 fixed #765 2017-01-04 19:12:43 -05:00
4f0c1d11eb 16 bytes alignment for extra buffer 2017-01-04 17:25:30 -05:00
1aae921ce7 allocated bigger buffer for remaining data 2017-01-03 13:22:42 -05:00
2e1c508bc4 allocated bigger buffer for remaining data 2017-01-03 13:19:35 -05:00
cea6ea4344 correct receive stats 2017-01-03 12:29:36 -05:00
57310fdbd6 reduced memory footprint 2017-01-03 11:52:28 -05:00
62ca6212ce don't store SSU-specific data for NTCP address 2017-01-02 16:36:59 -05:00
d4f5871e74 Merge pull request #764 from PurpleI2P/openssl
recent changes
2017-01-02 16:16:51 -05:00
a739580d3f Merge pull request #763 from hypnosis-i2p/openssl
updated icons, added README.md to i2pd_qt folder, updated android sdk version
2017-01-02 14:35:31 -05:00
5203565175 updated icons 2017-01-03 01:14:44 +08:00
c91f6db68a updated to newer android sdk 2017-01-02 23:38:15 +08:00
b776b85fc3 Update README.md 2017-01-02 23:38:15 +08:00
b35e5f1582 Create README.md 2017-01-02 23:38:15 +08:00
7d5a929b5e #761 info instead error 2017-01-02 09:03:12 -05:00
c2e7bc13a6 last sample should have more relevance for latency 2017-01-01 14:29:39 -05:00
97818c6f32 Merge pull request #760 from majestrate/fix-http-auth
Fix http auth when long password used and add peer count on transports page
2017-01-01 09:45:13 -05:00
a8973f5463 add peer count to transports 2017-01-01 08:58:21 -05:00
75d790137d don't use sizeof 2017-01-01 08:54:11 -05:00
7ef6c72fc0 fix http auth fail when auth too long 2017-01-01 08:53:15 -05:00
c5f8e2249e Merge remote-tracking branch 'purple/openssl' into websocks 2016-12-31 17:08:49 -05:00
585a6c29d4 add relaytag after session established 2016-12-31 13:52:26 -05:00
6b6df15dd9 eliminate ban list overhead 2016-12-31 10:51:42 -05:00
f4de68cb22 avoid exception if not connected 2016-12-31 10:50:48 -05:00
86d5cbc355 Merge branch 'master' into websocks 2016-12-31 10:42:57 -05:00
88f9b69e2a Merge remote-tracking branch 'purple/openssl' 2016-12-31 08:42:42 -05:00
d77c782f69 removed IdentHash from RoutingProfile 2016-12-30 20:59:18 -05:00
c115131ed2 removed IdentHash from RoutingProfile 2016-12-30 20:09:41 -05:00
178dedf78c store relay session directly 2016-12-30 17:53:54 -05:00
b0c64afc6e Merge remote-tracking branch 'purple/openssl' 2016-12-30 04:47:01 -05:00
be0c1c0912 Merge remote-tracking branch 'purple/openssl' 2016-12-30 04:46:55 -05:00
2e8fa88fcb fixed memory leak 2016-12-29 22:06:33 -05:00
b1b5904852 show SOCKS proxy as client tunnel 2016-12-27 22:45:51 -05:00
08f029850f Merge pull request #754 from majestrate/ratelimit-datagram-ls
dont re-request LS
2016-12-26 20:05:57 -05:00
f3d4077142 dont re-request LS 2016-12-26 18:47:47 -05:00
59dd479a6d check if address not found 2016-12-26 17:19:54 -05:00
76d9f1ea37 * make loopback address mapping configurable
* add loopback address mapping to udp server tunnel
2016-12-25 08:56:47 -05:00
858b497199 prevent overflow 2016-12-25 08:18:23 -05:00
cee9f1df95 Merge pull request #750 from majestrate/tunnelgateway-leak
Fix Tunnel Gateway Leak
2016-12-24 18:01:10 -05:00
5bc2001ce3 Fix Tunnel Gateway Leak 2016-12-24 17:19:07 -05:00
652226dbf0 allow multiple acceptors 2016-12-24 16:34:18 -05:00
4688e6d534 fix segfault 2016-12-24 16:31:28 -05:00
1b0fc180c4 Fix Tunnel Gateway Leak 2016-12-24 16:05:44 -05:00
2524972807 don't use stack allocated buffers in SSU 2016-12-24 12:04:39 -05:00
8f51dc2c22 reload acceptor with correct stream 2016-12-24 09:55:59 -05:00
b363b50320 multiple acceptors 2016-12-24 08:53:35 -05:00
88a48a5c79 implement AcceptOnce for multiple acceptors 2016-12-23 10:09:40 -05:00
7be951b962 fix last commit, it was broken 2016-12-23 07:38:41 -05:00
3dcc4e6bc1 i2ptunnel fixes 2016-12-23 07:32:43 -05:00
573ee0b584 fixed typo 2016-12-22 20:34:06 -05:00
213629ef52 drop highest bit for token 2016-12-22 20:30:50 -05:00
27e1579e4c rollback 2016-12-22 19:38:17 -05:00
f2c401b6c0 fixed some memory leak 2016-12-22 15:00:40 -05:00
442c63d7a4 #746. initialize io_service after daeminization 2016-12-22 13:32:06 -05:00
5babfb0f1e fixed #724 2016-12-22 10:52:26 -05:00
0ad3078524 open log stream in log thread 2016-12-22 10:08:35 -05:00
f765c25020 Merge remote-tracking branch 'purple/openssl' 2016-12-22 09:33:02 -05:00
4145251afd new reseed 2016-12-21 21:29:46 -05:00
88c3532162 removed ssl ceritifcates 2016-12-21 14:54:48 -05:00
84b3ad3221 removed non-used ceritificates 2016-12-21 14:52:17 -05:00
e699d3d02d SNI support 2016-12-21 07:41:18 -05:00
9da984b866 use ElGamalEncrypt 2016-12-20 14:10:14 -05:00
fc08d15a79 Merge pull request #743 from PurpleI2P/openssl
2.11.0
2016-12-18 18:11:22 -05:00
ffaabe8674 update ChangeLog 2016-12-18 18:07:06 -05:00
0233ab4deb added info, modifyed timestamp 2016-12-19 00:31:29 +03:00
c9dc010c0b 2.11.0 2016-12-18 16:02:19 -05:00
557696b1d8 Merge remote-tracking branch 'purple/openssl' 2016-12-18 13:31:02 -05:00
9fefbb0c4a Merge pull request #742 from majestrate/sam-multiaccept
Multiple stream acceptors with SAM
2016-12-18 13:16:14 -05:00
eb9ea97e21 don't crash 2016-12-18 13:01:28 -05:00
673b7a95b7 fix sam crash on exit and datagram crash with no outbound tunnel 2016-12-18 12:57:49 -05:00
d5f27ecb0e fix termination crash 2016-12-18 12:57:39 -05:00
8f8b928cc4 enable multiple acceptors in sam (initial) 2016-12-18 12:57:31 -05:00
965896b932 fix sam crash on exit and datagram crash with no outbound tunnel 2016-12-18 12:56:34 -05:00
042adb5e34 fix termination crash 2016-12-18 12:28:32 -05:00
67927bd8f4 enable multiple acceptors in sam (initial) 2016-12-18 11:49:50 -05:00
259a63e612 fixed session termination crash 2016-12-18 10:11:40 -05:00
adcf2158bf Merge remote-tracking branch 'purple/openssl' 2016-12-18 10:09:45 -05:00
05c914156a fixed session termination crash 2016-12-18 09:40:52 -05:00
f69884d573 AVX disabled for debuild by patch 2016-12-18 16:27:14 +03:00
d097554f7d Merge remote-tracking branch 'purple/openssl' 2016-12-17 15:16:58 -05:00
1e2fd57c4c Merge remote-tracking branch 'purple/openssl' into websocks 2016-12-17 15:16:50 -05:00
8b8007695c don't close streams after 1 hour 2016-12-17 22:49:51 +03:00
68f3c877ee Merge branch 'master' into websocks 2016-12-17 08:54:56 -05:00
ae442ee015 Merge pull request #739 from majestrate/udp-tunnel-crash-fix
Udp tunnel crash fix
2016-12-17 07:58:45 -05:00
99b5f1b7b8 remove pedantic log entry 2016-12-17 07:36:59 -05:00
8071df0e68 don't crash on os x when no lease set found for udp tunnel 2016-12-17 07:36:47 -05:00
88d1aab7a3 Merge branch 'master' of github.com:majestrate/i2pd 2016-12-17 07:35:24 -05:00
08001ba373 remove pedantic log entry 2016-12-17 06:37:34 -05:00
ebc24cee55 Merge remote-tracking branch 'origin/openssl' 2016-12-17 06:36:26 -05:00
ae3bb30d8a don't crash on os x when no lease set found for udp tunnel 2016-12-17 06:35:38 -05:00
63d6b23344 use correct encryption key for ElGamal 2016-12-16 21:23:04 -05:00
c009e6bd04 Merge remote-tracking branch 'origin/openssl' 2016-12-15 18:24:45 -05:00
38d85a49e7 use AVX instructions for XOR in AES-CBC if applicable 2016-12-15 14:42:26 -05:00
0edc149ecc fixed typo 2016-12-15 13:36:52 -05:00
10d6cd9896 use token for commands 2016-12-15 13:10:12 -05:00
6913da7efa fixed AVX crash for mingw build 2016-12-15 10:43:48 -05:00
34df1b1646 add AVX to clobber list 2016-12-15 07:21:34 -05:00
992603496e don't copy address 2016-12-14 13:54:16 -05:00
b9552c42f1 don't overwrite whole lease 2016-12-14 11:32:20 -05:00
37e4dfc5d5 cleanup from some overhead 2016-12-14 10:59:36 -05:00
15b7284a8f AVX support for Windows 2016-12-14 09:48:05 -05:00
b57a62fece static and AVX support for OSX 2016-12-14 09:35:15 -05:00
9c7de5ad03 avoid sending RST instead FIN 2016-12-13 14:54:48 -05:00
c065fae422 store remote IdentHash only 2016-12-13 12:45:18 -05:00
cfde1f8c27 rollback 2016-12-13 12:44:05 -05:00
c45f72a63e make sure all outstading data got sent before closing socket 2016-12-13 11:01:13 -05:00
e1d9eca7bd 0.9.28 2016-12-13 09:49:42 -05:00
573e5eb5bd fix typo 2016-12-13 09:10:39 -05:00
d9090486e3 Merge remote-tracking branch 'origin/udptunnel-fix' 2016-12-12 19:20:24 -05:00
b4e7a91645 be less picky about next lease set 2016-12-12 19:16:02 -05:00
92dd68fca1 fix 2016-12-12 18:54:56 -05:00
82e955ec02 fix 2016-12-12 18:54:31 -05:00
2e66c4c9f5 Merge pull request #738 from majestrate/udptunnel-fix
make udp tunnel utilize GarlicRoutingPath correctly
2016-12-12 18:16:01 -05:00
0c6ee5e139 Merge remote-tracking branch 'origin/udptunnel-fix' 2016-12-12 15:53:48 -05:00
9a19b5994b fix 2016-12-12 15:50:36 -05:00
920586f56c Merge remote-tracking branch 'origin/openssl' into udptunnel-fix 2016-12-12 14:51:01 -05:00
919aa2895a request lease set 2016-12-12 14:50:38 -05:00
75690598e3 try fixing datagram 2016-12-12 14:50:31 -05:00
ac2caf2787 make sure all incoming data gets sent before closing a socket 2016-12-12 14:45:37 -05:00
5640c96fd5 request lease set 2016-12-12 14:39:05 -05:00
0396c4a4de try fixing datagram 2016-12-12 13:40:24 -05:00
f061fe581a Merge remote-tracking branch 'purple/openssl' 2016-12-12 10:58:20 -05:00
5405876d84 temporary exlude mamoth's shit from reseeds 2016-12-11 20:38:19 -05:00
4b9de0777b queue up LeaseSet requests 2016-12-11 14:17:09 -05:00
a59e073536 consmetic fixes 2016-12-11 12:22:23 -05:00
67492bf024 send v4 address for peer test 2016-12-11 09:53:43 -05:00
77c83c4f42 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into websocks 2016-12-11 09:36:51 -05:00
259baa0e84 use vzeroall to complete AVX mode 2016-12-10 20:41:42 -05:00
dca48c7eec use AVX for HMAC 2016-12-09 15:46:21 -05:00
0d83a34cfd add initial WebSOCKS implementation 2016-12-09 15:36:38 -05:00
7386b0a523 fixed android build 2016-12-09 13:42:00 -05:00
eda13f9023 Merge remote-tracking branch 'purple/openssl' 2016-12-09 11:42:31 -05:00
d0e9fe1e3e Merge pull request #734 from majestrate/fix-732
fixe issue 732
2016-12-09 09:59:18 -05:00
2b7bab04dd add BloomFilter to QT android 2016-12-09 09:50:42 -05:00
ad5f890a1e Merge pull request #733 from majestrate/bloom-filter
add simple bloomfilter implementation
2016-12-09 09:41:09 -05:00
fa191e2928 fixes issue 732 and wave hi to ISPG 2016-12-09 09:27:19 -05:00
6d8a23ec16 tabify 2016-12-09 09:10:08 -05:00
12371650f9 tabify 2016-12-09 09:09:35 -05:00
79e1d54e4c implement simple bloom filter 2016-12-09 09:08:03 -05:00
447f5f69c9 use AVX for DHT 2016-12-08 15:23:40 -05:00
e08a26d015 AVX instructions support 2016-12-08 12:59:19 -05:00
975265b0af more 2016-12-07 11:52:20 -05:00
4d5e9c52b2 Use eddsa-sh512-ed25519 by default 2016-12-07 09:38:19 -05:00
d1b154c285 Merge remote-tracking branch 'purple/openssl' 2016-12-07 09:34:33 -05:00
381f6b184e clean up incomplete messages 2016-12-06 16:23:52 -05:00
59681398cb don't store lookup replies anymore 2016-12-05 18:39:01 -05:00
adf887a06b request destination if we are not closest 2016-12-05 16:36:51 -05:00
42f70cd55d request destination after frist lookup 2016-12-05 15:45:04 -05:00
3704a4ff47 2.10.2 2016-12-05 00:31:41 +03:00
5b8d637f6a 2.10.2 2016-12-05 00:21:18 +03:00
436621f79f 2.10.2 2016-12-04 14:38:57 -05:00
0ea5fbfe0a Merge pull request #731 from PurpleI2P/openssl
recent changes
2016-12-03 09:38:28 -05:00
f1acd122bc Merge remote-tracking branch 'purple/openssl' 2016-12-03 08:10:00 -05:00
739b6645f8 eliminate bad_function_call exception 2016-12-02 16:10:49 -05:00
7a7ae4cc83 select ipv4 peers for peer test 2016-12-02 11:17:22 -05:00
db83cbe58f handle read_some errors 2016-12-01 22:14:43 -05:00
87228429d6 handle receive_from errors 2016-12-01 19:24:15 -05:00
2651723b50 fixed termination crash 2016-12-01 19:23:55 -05:00
b8a01d2ff1 rollback 2016-12-01 15:03:54 -05:00
5c20751937 give priority to ipv6 2016-12-01 14:06:23 -05:00
06b0a50462 static libminiupnpc 2016-12-01 20:17:28 +03:00
0d589895f6 print time difference with one in timestamp message 2016-12-01 10:51:01 -05:00
230c2aaf26 reopen UDP socket in case of error 2016-11-30 21:14:10 -05:00
1d8807a6ba handle async_receive_from errors 2016-11-30 14:51:26 -05:00
81978b214c correct NTCP sessions termination 2016-11-30 09:24:49 -05:00
8704234669 Merge remote-tracking branch 'purple/openssl' 2016-11-30 04:29:16 -05:00
5699b7bae5 5 seconds connection timeout for NTCP 2016-11-29 14:12:44 -05:00
2756cb8b8f Merge pull request #729 from PurpleI2P/openssl
recent changes
2016-11-29 13:39:26 -05:00
e726d216bb cleanup tags on stop 2016-11-28 22:47:37 -05:00
3480824290 correct leaseset requests cleanup 2016-11-28 14:37:17 -05:00
c8b935151a fixed tremination crash 2016-11-28 13:47:10 -05:00
5e5aefa290 cleanup leaseset requests on stop 2016-11-27 10:14:54 -05:00
0e14b54b6d break circular reference 2016-11-25 22:36:35 -05:00
c6ddae2d8e excluded obsolete boost dependancies 2016-11-25 13:45:41 -05:00
bc0aed186e Merge remote-tracking branch 'purple/openssl' 2016-11-25 10:46:28 -05:00
d092b21da7 assume ElGamal data size as 222 bytes 2016-11-24 16:02:14 -05:00
a8061003dd Merge pull request #725 from majestrate/fix-722
don't add multiple router addresses when specifying ifname4/6
2016-11-24 14:05:30 -05:00
50f0099645 don't add multiple router addresses 2016-11-24 13:56:37 -05:00
c270687223 Merge pull request #723 from majestrate/fix-722
add ifname4 and ifname6 options
2016-11-24 10:43:39 -05:00
a92652f4ad add ifname4 and ifname6 options 2016-11-24 10:11:46 -05:00
9ba961fa72 Merge remote-tracking branch 'purple/openssl' 2016-11-24 08:07:32 -05:00
006e4526e8 fixed memory leak 2016-11-23 16:41:27 -05:00
55dbbb3546 fixed memory leak 2016-11-23 16:30:36 -05:00
c166bc9b18 Merge pull request #719 from PurpleI2P/openssl
recent changes
2016-11-23 11:31:58 -05:00
e4fe18e435 Merge pull request #718 from l-n-s/my_fixes
Add possibility to reseed from HTTPS URL
2016-11-23 08:58:28 -05:00
cea38549da Merge remote-tracking branch 'upstream/openssl' into my_fixes 2016-11-23 07:45:06 -05:00
0487e730ba Add possibility to reseed from HTTPS URL 2016-11-23 07:42:38 -05:00
8fdd7205d7 check if routing session got detached 2016-11-22 15:20:48 -05:00
1d8d71cfb6 16-bytes alignment for IV for AES-CBC 2016-11-21 21:13:13 -05:00
10bd017e57 16-byte alignment for received I2NP message 2016-11-21 19:45:29 -05:00
f36a9c4409 Merge remote-tracking branch 'purple/openssl' 2016-11-21 06:43:23 -05:00
70f39eb959 Added new logo to webconsole 2016-11-21 00:58:38 +03:00
3a3b0cc847 New logo 2016-11-21 00:27:39 +03:00
01da9e3ca2 fix outproxy 2016-11-20 12:13:11 -05:00
f168e4586c undo pedantic whitespace 2016-11-20 09:32:28 -05:00
03ff390685 undo pedantic whitespaces 2016-11-20 09:31:33 -05:00
2a77486567 tabify 2016-11-20 09:30:46 -05:00
32a5950aad Merge remote-tracking branch 'purple/openssl' 2016-11-20 09:28:11 -05:00
f1370189b6 initial outproxy support for http proxy 2016-11-20 09:25:56 -05:00
65d721285b fixed build error for some compilers 2016-11-20 08:33:33 -05:00
565f844b7f correct termination of pending leaseset 2016-11-19 17:24:38 -05:00
248992b27b temporarty fix crash 2016-11-19 14:28:58 -05:00
3125e05b49 Merge remote-tracking branch 'purple/openssl' 2016-11-19 07:19:11 -05:00
bdd6037726 use std::map for unconfirmed tags 2016-11-18 14:50:29 -05:00
9d292bb6a4 fixed potential race condition 2016-11-18 11:16:55 -05:00
12b9b49902 fixed infinite loop bug 2016-11-18 10:27:49 -05:00
93b8bd7f02 set high bandwidth together with extra badnwidth 2016-11-18 09:27:40 -05:00
cd8169c0a5 reopen log upon daemon start 2016-11-17 22:44:02 -05:00
b4a9d4df8c fixed crash in daemon mode 2016-11-17 22:11:34 -05:00
d62525abb6 insert I2CP session with correct sessionid 2016-11-17 19:16:38 -05:00
a4988fd7cb insert I2CP session with correct sessionid 2016-11-17 19:14:25 -05:00
d91691c344 write to log through the separate thread 2016-11-17 15:46:28 -05:00
164d3566e3 fixed linker error 2016-11-17 15:00:30 -05:00
058120d001 show I2CP local destinations 2016-11-17 13:10:29 -05:00
59f292333f use correct ports 2016-11-17 11:42:23 -05:00
b7a2c11e81 use shared_ptr instead 2016-11-17 11:37:48 -05:00
3d07ddfba5 read more than 1 udp packet 2016-11-17 11:13:40 -05:00
9286e4794b add logging 2016-11-17 11:10:42 -05:00
81276cb7f5 unbreak (maybe?) 2016-11-17 10:43:27 -05:00
e270f90f8d try fixing udp tunnel (probably broken) 2016-11-17 10:36:27 -05:00
b1fdfec18c Merge remote-tracking branch 'purple/openssl' 2016-11-17 09:25:48 -05:00
1dfa09cda9 queue up multiple LeaseSet requests 2016-11-16 22:28:13 -05:00
913438e3ff addresshelper message changed to "Proxy info" 2016-11-17 06:04:29 +03:00
1aa939ae73 correct tigger for 0-hops LeaseSet update 2016-11-16 19:32:45 -05:00
a914608264 clean up non received DeliveryStatus messages 2016-11-16 14:43:29 -05:00
fb59d80897 Merge pull request #712 from PurpleI2P/openssl
recent changes
2016-11-16 14:40:50 -05:00
5d0852c1e2 fixed memory leak 2016-11-16 12:10:13 -05:00
e0e50faa47 publish 0-hops leaseset 2016-11-16 10:59:11 -05:00
f6721a2ced fixed startup crash 2016-11-15 17:45:37 -05:00
e384ec32b8 unbreak i2lua build 2016-11-15 15:40:09 -05:00
d93361939c Merge branch 'low-latency-merge' 2016-11-15 15:14:52 -05:00
644c0e3d33 Merge remote-tracking branch 'purple/openssl' 2016-11-15 15:12:09 -05:00
b1333b7d99 Merge pull request #709 from majestrate/low-latency-merge
implement latency control option
2016-11-15 15:08:09 -05:00
673a2acade Merge remote-tracking branch 'purple/openssl' into low-latency-merge 2016-11-15 14:45:16 -05:00
752e74d33c show latency of tunnels in web ui 2016-11-15 14:42:18 -05:00
6bacf94a62 handle all loopback messages 2016-11-15 14:11:55 -05:00
336cd60920 don't insert same floodfill twice 2016-11-15 12:17:21 -05:00
76c9b66db4 don't blow up 2016-11-15 11:31:15 -05:00
0c5ca28a14 fall back on regular tunnel algorithm 2016-11-15 11:27:00 -05:00
db63bb4495 make it compile for real 2016-11-15 11:18:12 -05:00
34afb54c21 make it compile 2016-11-15 11:16:32 -05:00
69888e148e use correct latency computation 2016-11-15 11:15:48 -05:00
98a55c0613 make it compile 2016-11-15 10:48:33 -05:00
5425e9aee3 select tunnels correctly 2016-11-15 10:46:58 -05:00
7fef5f5654 when selecting tunnels if we can't find a low latency tunnel fall back to regular selection algorithm 2016-11-15 10:37:58 -05:00
fc94e846a6 add latency requirement option 2016-11-15 10:20:09 -05:00
7d7bbf15bf use DSA for http and socks proxy by defualt 2016-11-15 10:10:13 -05:00
8a545b98ec Merge remote-tracking branch 'purple/openssl' 2016-11-14 16:26:37 -05:00
ecdb60b44e cleanup netdb after failed reseed 2016-11-14 16:23:42 -05:00
2eea85b786 increase reseed expiration time to 81 hours 2016-11-14 15:04:40 -05:00
87fd0e6f29 recommit fixed ASCII art 2016-11-14 22:38:35 +03:00
ea191afd9d fixed build error 2016-11-14 13:48:34 -05:00
89b624308e added ASCII art 2016-11-14 21:40:03 +03:00
facdf0ca9c Merge pull request #708 from majestrate/reseed-from-floodfill
add reseed from floodfill option
2016-11-14 13:31:51 -05:00
98484d54c0 check for outdated routers in reseed 2016-11-14 13:13:57 -05:00
ea31ca5ee8 add reseed from floodfill option 2016-11-14 12:09:07 -05:00
6b5b9b3d62 add reseed from floodfill option 2016-11-14 12:05:44 -05:00
975dab6d1d add hacking.md for notes on internal structure 2016-11-14 08:38:25 -05:00
eaa7adc88c Update usage.md 2016-11-13 23:04:41 +00:00
f76b014a52 re-run PeerTest 2016-11-13 09:14:05 -05:00
8676a1b4ef update changelog, added leaseset list to client/server tunnel pages 2016-11-12 17:49:16 +03:00
e1eaa2097e Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-11-11 12:45:06 -05:00
6f2357c695 fixed openssl 1.1 crash 2016-11-11 12:44:44 -05:00
91427264c3 Fix link to configuration 2016-11-11 10:01:38 +00:00
74aa961561 Fix RTD: Use 4 spaces, not tabs in docs 2016-11-11 09:42:18 +00:00
aa47e11471 fixed race condition 2016-11-10 21:44:40 -05:00
89d69a5d5a rollback due the race condition 2016-11-10 18:38:29 -05:00
3bbe1e9c0c excluded deprecated reseed 2016-11-10 14:59:21 -05:00
6377631ae7 OpenSSL 1.1 for EVP_PKEY 2016-11-10 12:51:39 -05:00
3562ac1438 Merge pull request #704 from majestrate/master
add .dir-locals.el for emacs users
2016-11-10 09:11:52 -05:00
e152785de9 remove tab width setting in dir-locals 2016-11-10 08:25:16 -05:00
dd259f1852 fix formatting 2016-11-10 08:22:52 -05:00
5001cea3a3 add dir-locals for emacs users with code standards set 2016-11-10 08:21:32 -05:00
a4d586b24e openssl 1.1 for ECDSA 2016-11-09 15:59:01 -05:00
46f927fc1b cleanup unclaimed out-of-sequence fragments 2016-11-09 14:51:55 -05:00
7419f992e7 Merge pull request #703 from PurpleI2P/openssl
recent changes
2016-11-09 14:49:12 -05:00
b83e7e6c5c correct PeerTest 2016-11-09 12:13:42 -05:00
5f463d5f6b rollback 2016-11-09 10:16:37 -05:00
2e301c2919 fixed VS build 2016-11-08 20:25:47 -05:00
9526d42ec5 Merge pull request #701 from PurpleI2P/atnaguzin-fix-makefile
fix branch detect
2016-11-08 17:26:29 -05:00
a566479ddb fix branch detect 2016-11-09 01:07:10 +03:00
1bba0f6bb2 store and concatenate all out-of-sequence fragments 2016-11-08 15:37:27 -05:00
232d42881b support openssl 1.1 for DH 2016-11-08 13:11:38 -05:00
abeaf76fe9 Update usage.md 2016-11-08 17:55:40 +00:00
03d4584562 Control i2pd and link to configuration page 2016-11-08 17:14:53 +00:00
f2f5226ebb extract database store key once 2016-11-07 18:32:22 -05:00
660860b92d verify LeaseSet's ident hash 2016-11-07 15:54:35 -05:00
c0a1a8b47c limit number of DH precalculations at the time 2016-11-07 14:44:32 -05:00
bd82e81e26 correct DH keys number to precalculate 2016-11-07 12:29:24 -05:00
0a94df592c 2.10.1 2016-11-07 09:18:44 -05:00
66506ea1ce Update installer.iss 2016-11-07 07:30:44 +03:00
4a4292a0dc Merge pull request #700 from PurpleI2P/openssl
recent changes
2016-11-06 14:40:43 -05:00
7bff4db483 eliminate potential excessive CPU usage 2016-11-06 09:53:45 -05:00
9208da8a50 more precise peer test 2016-11-05 21:08:14 -04:00
70fcd93ca7 fixed build error for clang 2016-11-04 12:13:03 -04:00
9ba9bd4415 preparation for openssl 1.1 2016-11-04 10:59:55 -04:00
480ce6f522 core file is limited by a system by default 2016-11-03 21:37:47 -04:00
f1254fd5d4 fixed android build 2016-11-03 21:31:21 -04:00
10ebcff48e * Log.{cpp,h}:
* use colors only when using stdout
  * use static string array instead bunch of #define's
2016-11-04 00:43:43 +00:00
6ee227675a * DaemonLinux.cpp : resource limiting 2016-11-04 00:43:29 +00:00
89059abe15 * Config.cpp : limits.coresize & limits.openfiles 2016-11-04 00:43:28 +00:00
4503223a4e * SOCKS.cpp : boost::lexical_cast -> std::to_string 2016-11-04 00:43:25 +00:00
07c31a90f3 * RouterContext.cpp : boost::lexical_cast -> std::to_string 2016-11-04 00:43:24 +00:00
bbcb9af01f * SAM.cpp : boost::lexical_cast -> std::stoi 2016-11-04 00:43:22 +00:00
1cd415a3ae * BOB.cpp : boost::lexical_cast -> std::stoi 2016-11-04 00:43:20 +00:00
c344e75701 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-11-03 15:29:09 -04:00
0305e4cf8a tunnel options for SOCKS proxy 2016-11-03 15:28:33 -04:00
bc86b0345f Merge pull request #698 from atnaguzin/systemd
systemd unit, debian patch fix, makefile last-dist added, package log&pid folder edited
2016-11-03 12:20:14 -04:00
8b0ce30dfc systemd unit, debian patch fix, makefile last-dist added, package log&pid folder edited 2016-11-03 19:08:21 +03:00
4b983300fe fixed layout 2016-11-03 11:47:33 -04:00
8829ebba6c fixed layout 2016-11-03 11:46:24 -04:00
11b90d2113 lenght and number of tunnels for HTTP Proxy 2016-11-03 11:44:25 -04:00
9d8d4c09c6 reduce explratory tunnels quatity to 3 2016-11-02 15:17:05 -04:00
c90d5bb67c don't override Host if not specified explicitly 2016-11-02 10:12:54 -04:00
7263d9f03e Event.h/.cpp added 2016-11-01 19:49:48 -04:00
d5e77e9bb2 10 seconds max timeout for NTP 2016-11-01 18:40:00 -04:00
1ecd5250fc eliminate overhead 2016-11-01 17:49:42 -04:00
44af5e04e4 correct NTP request 2016-11-01 16:27:44 -04:00
4582a4fd95 eliminate some overhead 2016-11-01 13:57:25 -04:00
2d513277f2 fixed #696. set netid before context::Init 2016-11-01 13:34:19 -04:00
7934974d92 fixed android build 2016-11-01 12:16:18 -04:00
4dce35b1e6 Merge pull request #695 from majestrate/merge-websocket
add optional websocket ui
2016-11-01 11:54:50 -04:00
e5f5f96771 merge webui code 2016-11-01 10:46:07 -04:00
d4a0076aba merge 2016-11-01 10:26:40 -04:00
cd9cd84c5b properly send expiration notice for websockets 2016-11-01 10:07:34 -04:00
93eca799dd add more websocket events 2016-11-01 10:06:38 -04:00
34f090662a stop websockets 2016-11-01 10:02:41 -04:00
1a1d54387c update build files and allow compile without websocket 2016-11-01 10:02:24 -04:00
9575f70f38 fix conflicts 2016-11-01 10:02:10 -04:00
b4e9ed7d18 add web socket ui 2016-11-01 09:59:50 -04:00
3d4e2a275c correct separator for android 2016-10-31 18:10:33 -04:00
b526718846 show HTTP proxy as client tunnel 2016-10-31 15:42:50 -04:00
a4883cfa15 print tunnel peers in direct order 2016-10-31 15:13:43 -04:00
a41f179785 get home directory from EXTERNAL_STORAGE for andorid 2016-10-31 14:00:31 -04:00
bef628212e fixed corrupted buffer duing IRC handshake 2016-10-31 09:46:59 -04:00
ef3030abe5 Merge pull request #694 from lehitoskin/graceful-typo
gracefull -> graceful
2016-10-31 06:59:18 -04:00
754ad20eff gracefull -> graceful 2016-10-31 03:27:27 -07:00
647175cf12 correct RTO reset 2016-10-30 09:29:43 -04:00
5f0a440f0a Merge pull request #692 from l-n-s/my_fixes
My fixes
2016-10-28 17:44:50 -04:00
d68544038c Merge branch 'openssl' into my_fixes 2016-10-28 20:28:11 +00:00
df36b0eb7e Uppercase first letters in config help 2016-10-28 16:17:48 -04:00
4f4748b8df Update nat option: if nat=false, skip reachability testing 2016-10-28 15:57:18 -04:00
028a896303 Merge pull request #690 from majestrate/no-churn
add trust.routers option and fix restricted routes
2016-10-28 14:37:32 -04:00
578083df3e Add libdl (-ldl) flag. Fixes openssl errors when building statically. 2016-10-28 13:18:35 -04:00
c5e1823f15 dont't set to firewalled, ssu will try introducers 2016-10-28 13:11:50 -04:00
5f396d6311 add option to only connect to certain routers 2016-10-28 12:50:26 -04:00
5c64c2ff42 handle stream ternimation properly 2016-10-28 11:33:11 -04:00
2dcb91b284 don't create same incoming stream twice 2016-10-27 20:46:05 -04:00
d708e7f682 check if a lease has been excluded from LeaseSet 2016-10-26 21:40:06 -04:00
a8a4ef82cd fixed android build 2016-10-26 16:19:32 -04:00
1286f1c968 inalidate shared routing path 2016-10-26 13:02:19 -04:00
9368a93279 * fgrep can't be used with regex 2016-10-26 00:41:48 +00:00
143aaa2d28 * util.h : drop i2p::util::lexical_cast(), not used anymore (#314) 2016-10-26 00:24:16 +00:00
b8dcdece38 * Destination.cpp : drop use of i2p::util::lexical_cast(), make more compact code 2016-10-26 00:24:13 +00:00
be7f4c5da7 * update changelog 2016-10-26 00:21:24 +00:00
890807b8d7 * build docs : markdown cleanup & reformatting 2016-10-26 00:21:22 +00:00
8e1687e7b3 * reorganize docs in build-notes*.md 2016-10-26 00:21:17 +00:00
d8510ead43 don't return expired LeaseSet 2016-10-25 14:07:34 -04:00
c74db4b81c resubmit non-confirmed LeaseSet 2016-10-24 20:58:25 -04:00
4ee9b4524d correct netid handling 2016-10-24 10:33:46 -04:00
28cf351878 fixed typo 2016-10-24 07:11:18 -04:00
c5e2ec5e00 random remote lease selection for LeaseSet update 2016-10-23 16:16:08 -04:00
fe3ebc4c84 Merge pull request #685 from majestrate/i2lua-cmake
update cmake for i2lua
2016-10-23 11:28:51 -04:00
6688f9a5ef update cmake for i2lua 2016-10-23 08:14:55 -04:00
3167ae21b0 send own LeasetSet through a stalled stream 2016-10-22 20:08:15 -04:00
bc92586323 Merge pull request #684 from PurpleI2P/openssl
recent changes
2016-10-22 20:05:28 -04:00
c40a463549 Merge pull request #683 from vaygr/openbsd-build
fixed build with OpenBSD
2016-10-22 18:12:54 -04:00
87a85fff08 Merge branch 'openssl' into openbsd-build 2016-10-22 16:44:15 -04:00
b68381db58 fixed build with OpenBSD 2016-10-22 16:38:45 -04:00
25c1884961 correct stream termination 2016-10-20 15:20:08 -04:00
9980df2c67 Merge pull request #680 from vaygr/libressl-support
fixed build with LibreSSL
2016-10-20 10:50:40 -04:00
ed09c1171b fixed build with LibreSSL 2016-10-20 10:37:45 -04:00
c473b10667 Merge pull request #679 from BOPOHA/openssl
fix paths
2016-10-20 10:33:44 -04:00
c15e53e9c0 fix paths 2016-10-20 15:49:56 +02:00
e9d3278fc5 Merge pull request #678 from l-n-s/move_rpm_files
move rpm-related files to contrib folder
2016-10-20 13:12:10 +00:00
b683c07d55 move rpm-related files to contrib folder 2016-10-20 13:08:38 +00:00
681f055b16 Merge pull request #677 from BOPOHA/patch-1
fixed Centos 7 notes
2016-10-20 12:51:22 +00:00
f4cb4c1756 fixed Centos 7 notes 2016-10-20 13:41:41 +02:00
1cc67bbbe8 Merge pull request #676 from BOPOHA/openssl
added spec and service files
2016-10-20 07:24:27 -04:00
0df0450107 added spec and service files 2016-10-20 12:18:59 +02:00
cb324ca723 portable windows data directory 2016-10-19 12:54:13 -04:00
442a0c48e7 fixed #675. I2LUA define 2016-10-19 10:23:02 -04:00
d97acacae6 sequential LeaseSet request 2016-10-17 18:45:20 -04:00
3643d6b5d5 Update changelog 2016-10-17 07:37:40 +03:00
2edd64470b Update changelog 2016-10-16 09:19:48 -04:00
c42e2fe02d Update i2pd.conf 2016-10-16 13:17:00 +00:00
12c67b5db4 2.10.0 2016-10-16 08:35:48 -04:00
a943cc09fe 2.10.0 2016-10-16 07:58:26 -04:00
1ceda52f59 2.10.0 2016-10-16 07:52:45 -04:00
04ee419951 small fixes for docs 2016-10-16 11:04:59 +00:00
f687728c3a edit link to usage documentation 2016-10-16 10:59:48 +00:00
bde5d27a20 Update README.md 2016-10-13 16:56:23 +00:00
07a1651fa2 Update usage.md
fix for readthedocs
2016-10-13 07:45:30 +00:00
32b47bee2c Update README.md
Add link to Russian docs
2016-10-12 17:52:07 +00:00
fbf75ea3b9 check if signer/verifier is set already 2016-10-12 13:28:22 -04:00
a157aba74f Merge pull request #671 from atnaguzin/patch-2
Update installer.iss
2016-10-12 12:32:12 -04:00
e45e5df377 openssl 1.1 DSA functions 2016-10-12 12:31:27 -04:00
85c7bfa160 Update installer.iss 2016-10-12 19:30:20 +03:00
8182f97c15 Merge pull request #670 from atnaguzin/patch-2
script for inno setup
2016-10-12 12:09:03 -04:00
eba824f5d0 script for inno setup 2016-10-12 19:03:35 +03:00
40456ebaae Merge pull request #669 from PurpleI2P/openssl
recent changes
2016-10-12 11:54:51 -04:00
99983798a4 configurable netid 2016-10-12 11:26:48 -04:00
93ed032015 avoid potential deadlock 2016-10-12 09:39:16 -04:00
9359f5b296 Update README.md
Less complicated description
2016-10-12 12:09:58 +00:00
3b467c19cb Merge pull request #668 from l-n-s/addressbook_configurable
Add addressbook options + improved docs
2016-10-12 07:08:55 -04:00
470a6f0ab2 Add addressbook options + improved docs 2016-10-12 10:23:43 +00:00
fe8a0c1a6b #622. Force SU3 verification by reseed.verify 2016-10-11 15:02:23 -04:00
f0d098d0ef use shared local destination for lookup if destination is not set 2016-10-11 13:39:07 -04:00
f17df1f16d spinlock added 2016-10-11 12:06:40 -04:00
b1f8f9830b fixed another cases for #651 2016-10-11 10:18:42 -04:00
e78ccc6bec fixed #651. check is destination is set 2016-10-11 07:31:16 -04:00
b54892a783 Merge pull request #664 from brain5lug/tag-cleanup
Tag class clean-up
2016-10-10 18:13:37 -04:00
16c37a0f3d indentation fix for missed Fill function 2016-10-11 00:46:18 +03:00
141fb78237 Tag class clean-up 2016-10-11 00:19:34 +03:00
eb31b9a4d6 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-10-10 16:34:08 -04:00
f10d9e1332 update reseed lists 2016-10-10 16:31:26 -04:00
6d63521622 update miniupnpc instructions 2016-10-10 11:46:52 -04:00
e1aa066489 Merge pull request #663 from l-n-s/update_readme
Update readme
2016-10-10 15:17:10 +00:00
c78ec12e99 Add specs link 2016-10-10 15:07:22 +00:00
3fa4e2f58d Update README.md 2016-10-10 15:00:36 +00:00
c64aaade70 Merge pull request #662 from majestrate/merge-recent-udp-tunnel
Merge recent udp tunnel changes
2016-10-10 09:13:57 -04:00
e8d8b290a6 rename 2016-10-10 09:07:49 -04:00
456d9e79e6 Revert "minimize count of errors "I2CP: Failed to send message. No outbound tunnels""
This reverts commit 8ff2627e8e.
2016-10-10 09:06:32 -04:00
3095e14247 undo weird mutex changes 2016-10-10 09:04:24 -04:00
a332d68704 Revert "fix f79ad91"
This reverts commit e8e3db6888.
2016-10-10 09:02:39 -04:00
84ca992e91 Revert "Unused parameter warnings removal"
This reverts commit 5350078543.
2016-10-10 08:59:48 -04:00
f91f3796a8 make sure verifier gets created once 2016-10-10 08:59:45 -04:00
22250ae552 Merge remote-tracking branch 'purple/openssl' into merge-recent-udp-tunnel 2016-10-10 08:36:06 -04:00
8a95b5b5b0 tabify 2016-10-10 08:30:33 -04:00
7506619f4c add minimum path lifetime 2016-10-10 08:25:07 -04:00
577d9ddf65 fix memory leak with udp tunnel 2016-10-10 08:23:54 -04:00
43c3bdf7c5 fix 2016-10-10 08:21:47 -04:00
8ba142eb45 increase datagram session switching interval 2016-10-10 08:21:33 -04:00
0fc4e01b1e remove tools 2016-10-10 08:18:54 -04:00
f83ebbcd3a Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-10-09 15:45:54 -04:00
77ec4b5cad added warning 2016-10-09 14:57:15 -04:00
9a687976bc Merge pull request #659 from brain5lug/thread-sanitizer
thread sanitizer configuration option have been added
2016-10-09 14:52:42 -04:00
5a796a86d7 thread sanitizer configuration option have been added 2016-10-06 22:49:44 +03:00
71d4221af2 add keyinfo tool 2016-10-05 11:40:25 -04:00
526ba37435 Merge branch 'merge-upd-tunnel-fix' into openssl 2016-10-05 11:36:15 -04:00
f3c080f8a4 Merge branch 'merge-650' into openssl 2016-10-05 11:29:55 -04:00
09a0cf07e4 Merge branch 'check_pr_653' into upstream-openssl 2016-10-05 11:24:44 -04:00
4a3bf46c30 Revert "try fixing appveyor"
This reverts commit 30dfe12910.
2016-10-05 11:03:51 -04:00
30dfe12910 try fixing appveyor 2016-10-05 10:46:15 -04:00
ae2b5dfd3e fix udp tunnel route switching logic 2016-10-05 07:42:00 -04:00
cb0f968467 Added building option "USE_ASLR" 2016-10-05 06:45:41 +05:00
e8e3db6888 fix f79ad91 2016-10-05 01:20:43 +05:00
012ade5000 Added extra-cmake-modules 2016-10-04 18:13:45 +03:00
5350078543 Unused parameter warnings removal 2016-10-04 00:24:42 +03:00
404715e02d thread sanitizer configuration option have been added 2016-10-03 23:24:22 +03:00
31dde394eb remove unnecessary brackets 2016-10-03 20:20:45 +05:00
8ff2627e8e minimize count of errors "I2CP: Failed to send message. No outbound tunnels" 2016-10-03 20:06:10 +05:00
f79ad91a9a probably fix hanging of call I2CP-SendMsgTo-FindLeaseSet 2016-10-03 20:01:31 +05:00
ff6a79bca3 Merge remote-tracking branch 'origin' into openssl 2016-10-02 03:22:50 +05:00
e4d6092939 copy addresses list atomically 2016-10-01 15:05:35 -04:00
9d998d27c5 Merge remote-tracking branch 'origin' into openssl 2016-09-29 20:58:53 +05:00
d6aca6fa00 always send reply 2016-09-29 11:24:52 -04:00
7c34c45983 Merge pull request #646 from PurpleI2P/openssl
recent changes
2016-09-27 16:19:01 -04:00
dd15472da7 Merge remote-tracking branch 'origin' into openssl 2016-09-26 02:45:44 +05:00
b03712a30e correct outbound tunnel selection 2016-09-25 17:23:21 -04:00
d025ba2793 Fixed visibility of variable outboundTunnel 2016-09-26 01:37:00 +05:00
e5e09c9b51 check for boost version 2016-09-24 08:29:08 -04:00
5b8d1df349 Merge pull request #643 from atnaguzin/patch-1
Fixed links and msys2 example filename
2016-09-24 07:32:51 -04:00
fa092c0162 Fixed links 2016-09-24 14:26:59 +03:00
08c1359a27 fixed MiniUPnP link 2016-09-24 13:50:14 +03:00
dba355eccd use atomic_store for addresses' list re-assignment 2016-09-23 13:15:08 -04:00
2ad927b677 NTP request 2016-09-21 16:18:51 -04:00
315f672254 Timestamp.cpp added 2016-09-21 12:02:52 -04:00
7a51407f6d show error message in the web-console 2016-09-19 21:37:04 -04:00
783c2b6b03 Merge pull request #640 from atnaguzin/patch-1
add sliders for LeaseSets
2016-09-19 13:24:32 -04:00
a64e1b2aa6 add sliders for LeaseSets 2016-09-19 20:22:15 +03:00
440516e95f detect clock skew 2016-09-18 18:42:21 -04:00
31f6d13cd8 Merge pull request #639 from PurpleI2P/openssl
recent changes
2016-09-18 07:43:21 -04:00
dc6108575c Merge pull request #638 from brain5lug/openssl
address sanitizer configuration option have been added
2016-09-17 07:42:54 -04:00
6c7316408b address sanitizer configuration option have been added 2016-09-17 11:01:01 +03:00
9aecc69461 Merge pull request #636 from l-n-s/reseeds_config
Adding option to configure reseed URLs
2016-09-16 19:11:08 -04:00
949be436a6 Adding option to configure reseed URLs 2016-09-16 22:56:51 +00:00
cb91891f22 check buffer size 2016-09-16 16:18:50 -04:00
8795f0c8c4 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-09-16 10:31:45 -04:00
fbb5bb2f05 fix #634.don't create timer in constructor 2016-09-16 10:31:11 -04:00
ba309fe6e5 Merge pull request #633 from brain5lug/openssl
perfect forwarding for logging arguments
2016-09-15 21:27:30 -04:00
fee5f959fd perfect forwarding for logging arguments 2016-09-16 01:47:53 +03:00
f9a5f4955c check RI signture before processing 2016-09-12 21:37:43 -04:00
325b362727 show UDP tunnels 2016-09-12 12:05:01 -04:00
75065f29f7 check if field is incomplete 2016-09-12 11:39:33 -04:00
ed874fe3ea check if RouterInfo has been decompressed completely 2016-09-11 21:36:17 -04:00
502e6b0ce5 Merge pull request #631 from rabits/patch-1
Fixed upstart i2pd forking
2016-09-10 19:35:02 -04:00
516380f979 Fixed upstart forking
Upstart can't track daemonize fork without expect fork
2016-09-11 01:15:22 +04:00
6885761f87 check if sessions list is empty 2016-09-08 10:56:22 -04:00
a4762fe65c remove expired session through one pass 2016-09-08 10:46:13 -04:00
bee407ea34 clean-up datagram session toghters with leasesets and tags 2016-09-08 10:16:42 -04:00
db71673722 fixed #629. catch HTTPServer exceptions 2016-09-08 09:19:30 -04:00
9ecbbf09cc Merge pull request #628 from majestrate/merge_udp_tunnel
Merge Recent Changes
2016-09-07 15:27:54 -04:00
b6b14f4957 Merge remote-tracking branch 'purple/openssl' into merge_udp_tunnel 2016-09-07 15:08:45 -04:00
6e0d6dcac5 reselect tunnels if LeaseSet delivery was not confirmed 2016-09-07 13:25:11 -04:00
47a0ebdc91 Merge pull request #627 from vovasty/ios-build
build instruction for iOS
2016-09-06 16:01:27 -04:00
f3a61007a7 build instruction for iOS 2016-09-06 12:26:59 -07:00
4a56d6bf1c Merge pull request #626 from majestrate/webui-freeze-fix
Webui freeze fix
2016-09-04 18:47:09 -04:00
517d4dc6f5 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into webui-freeze-fix 2016-09-04 16:43:55 -04:00
722f1c4430 try fixing webui freeze 2016-09-04 16:43:34 -04:00
f4d1b87f73 expire tags 2016-09-03 18:34:18 -04:00
f64f875806 don't show udp tunnels in ui yet 2016-09-03 18:04:54 -04:00
7ae09fa1fe try fixing memory errors 2016-09-03 17:58:16 -04:00
8a29dfc3fa tabify and use shared pointers 2016-09-03 17:53:46 -04:00
1015188c4e use shared pointers 2016-09-03 16:54:39 -04:00
f0bc2a3645 add null checks 2016-09-03 16:43:02 -04:00
82f46464f3 prevent double free 2016-09-03 16:29:50 -04:00
d336d920e8 fix typo 2016-09-03 16:16:16 -04:00
2f61dd1c41 fix double free 2016-09-03 16:12:43 -04:00
10ffd5c1ab don't check for expired lease 2016-09-03 16:06:14 -04:00
7e99be12b0 fix typo 2016-09-03 16:03:38 -04:00
d37a790b57 fix another typo 2016-09-03 15:58:52 -04:00
7ea8509dfe fix typo 2016-09-03 15:54:22 -04:00
783c0c7c7b update datagram lease selection 2016-09-03 15:53:28 -04:00
68b0775e4b update datagram path logic 2016-09-03 15:35:42 -04:00
682334d844 fix typo 2016-09-03 15:35:32 -04:00
75981491a7 adding usage docs 2016-09-03 22:23:48 +03:00
7cc805b203 update datagram session logic 2016-09-03 14:56:51 -04:00
8cdd3a0abb update routing path when we get a new lease set 2016-09-03 14:42:27 -04:00
571c630d93 try creating routing session if not present 2016-09-03 14:37:36 -04:00
fa1021df59 add webui for udp tunnels 2016-09-03 13:58:34 -04:00
9acbb2203c Update Indentation and don't spam route changes in datagram sessions 2016-09-03 11:46:47 -04:00
c770bcbf96 prevent race condition in datagram destination
clean up style a bit
2016-09-03 10:24:06 -04:00
caace05ba6 fix up compiler warnings 2016-09-03 10:01:23 -04:00
c65dc44f20 Fix up I2PTunnel UDP tunnels 2016-09-03 09:38:53 -04:00
3ea624e1db cosmetic fix 2016-09-01 15:54:48 -04:00
c9c58074fa Merge remote-tracking branch 'purple/openssl' 2016-09-01 11:28:04 -04:00
aa687afd37 updated LeaseSet must be sent after completion 2016-09-01 09:48:04 -04:00
8cb69c1482 fixed #624. correct v6 address size 2016-08-31 22:47:32 -04:00
a68326490d fix 2016-08-30 20:02:27 -04:00
ab763c38d9 use shared pointers 2016-08-30 19:59:24 -04:00
970557660e Add NetDb::VisitRandomRouterInfos 2016-08-30 15:54:53 -04:00
fa8548fe34 implement SetCustomPeerSelector and ensure locking is good 2016-08-30 15:11:39 -04:00
ac88c1a8f1 add ClientDestination::Ready 2016-08-30 13:27:57 -04:00
f2893097a7 check before bind to 127.x.x.x 2016-08-30 02:53:26 +05:00
c0cba7b376 move ready to run 2016-08-29 16:59:17 -04:00
87d1058de3 fix 2016-08-29 16:57:34 -04:00
85e65da492 server tunnel on linux binds on 127.x.x.x 2016-08-30 01:48:47 +05:00
ce97fa87e7 don't use std::promise * 2016-08-29 15:34:59 -04:00
10ffdb2766 add NetDb::WaitForReady 2016-08-29 15:26:19 -04:00
fec49e5609 add hooks for visiting netdb 2016-08-29 14:16:29 -04:00
28fdd992c9 add hooks for custom peer selection 2016-08-29 12:09:37 -04:00
048d3c8386 Merge remote-tracking branch 'purple/openssl' 2016-08-29 10:56:27 -04:00
50e3d6ff37 Merge pull request #623 from majestrate/fix_streaming_hang
make sure m_RTO > 0 in Streaming.cpp so it doesn't hang
2016-08-29 10:48:15 -04:00
37b80f0ce3 make sure m_RTO > 0 in Streaming.cpp so it doesn't hang 2016-08-29 10:44:54 -04:00
7d37b02cff datagram fixes 2016-08-29 10:42:51 -04:00
c6556b8442 make sure m_RTO > 0 in Streaming.cpp so it doesn't hang 2016-08-29 10:41:15 -04:00
5685c376cb fix broken build 2016-08-27 16:13:11 -04:00
2ce64e1bf5 fix typo 2016-08-27 16:10:18 -04:00
7d03a41e3e try manual expiration of tags 2016-08-27 16:09:02 -04:00
35b68db847 schedule cleanup again and add logging 2016-08-27 15:45:56 -04:00
0b21fce94e try adding garlic and session tags to datagram destination 2016-08-27 13:17:34 -04:00
abaf36a2de try unbreaking static build 2016-08-27 09:29:18 -04:00
26440d94f1 * HTTPServer : keep response data for async_write() 2016-08-26 14:42:34 +00:00
205b61e4cf * HTTPServer : fix tag 2016-08-26 14:42:34 +00:00
fc5fc5bbee don't throw exception if connection failed 2016-08-26 10:06:28 -04:00
c4171a01bd fix #622. extract correct CN 2016-08-26 09:48:19 -04:00
32669cb07f stop termination timer on shutdown 2016-08-24 12:34:18 -04:00
7018c381ee Merge remote-tracking branch 'purple/openssl' 2016-08-24 11:42:35 -04:00
b02677ee21 common termination timer for all SSU sessions 2016-08-24 11:21:49 -04:00
63edc60753 Merge pull request #618 from PurpleI2P/openssl
recent changes
2016-08-24 11:12:04 -04:00
065d01bcf6 logging update 2016-08-22 18:29:12 -04:00
42b15e8bbe fix 2016-08-22 17:31:23 -04:00
e8195b78ba fix 2016-08-22 17:26:43 -04:00
1d7d7cf9a0 more changes 2016-08-22 17:19:22 -04:00
979575c311 fix 2016-08-22 13:59:51 -04:00
be12739342 fix 2016-08-22 13:55:44 -04:00
7f7acd8bde fixes 2016-08-22 13:54:00 -04:00
f5e2899275 post work to io service 2016-08-22 13:04:36 -04:00
bee34a3222 fix 2016-08-21 22:54:06 -04:00
5b00cb1e64 osx fix 2016-08-21 22:38:41 -04:00
6bb9de5a96 osx fix 2016-08-21 22:34:48 -04:00
b977050caf osx fix 2016-08-21 22:29:55 -04:00
3f63732c31 osx fix 2016-08-21 22:26:30 -04:00
211660eb3d osx fix 2016-08-21 22:23:27 -04:00
0c709f431f osx fix 2016-08-21 22:18:59 -04:00
9062bf14b6 osx fix 2016-08-21 22:16:35 -04:00
47ebb6ae6c osx fix 2016-08-21 22:11:41 -04:00
b1e3f88704 osx fix 2016-08-21 22:00:31 -04:00
bc439cc47f osx fix 2016-08-21 21:57:36 -04:00
1bba5d5c94 osx fix 2016-08-21 21:55:00 -04:00
d159d49700 os x fix 2016-08-21 21:51:32 -04:00
7ef7ef03dd fix 2016-08-21 21:47:56 -04:00
808b758cd7 fix 2016-08-21 21:45:08 -04:00
ff6d66b96e init addressbook first 2016-08-21 21:40:21 -04:00
da82b14307 changes 2016-08-21 21:28:24 -04:00
7b5e18d94b changes 2016-08-21 21:17:09 -04:00
72974c85c8 try fix 2016-08-21 20:23:39 -04:00
28627a81dc update 2016-08-21 20:18:41 -04:00
bbfe6b66ef fix 2016-08-21 19:48:47 -04:00
bce0e3ebf6 fix 2016-08-21 19:45:32 -04:00
bf46c241d0 fixes 2016-08-21 19:38:12 -04:00
287e32aaed logging 2016-08-21 19:33:33 -04:00
aa11a5deb8 fix 2016-08-21 19:27:01 -04:00
194d63acd8 fixes 2016-08-21 19:17:08 -04:00
46d640cd86 fixes 2016-08-21 18:46:34 -04:00
51783a45e6 set last activity 2016-08-21 15:56:52 -04:00
2679c58892 logging and ip checks 2016-08-21 15:51:39 -04:00
2a5af37075 retrgiger expiration 2016-08-21 15:47:00 -04:00
e529d3ecc9 fixes 2016-08-21 15:39:11 -04:00
e8f9ecc7d9 fixes 2016-08-21 15:33:19 -04:00
aa3723d2bd udp tunnels 2016-08-21 15:02:17 -04:00
bbbda44218 * HTTPServer : show termination time in main page (closes #506) 2016-08-21 13:49:11 +00:00
f99aea5cb1 * Makefile.linux : use linker flags instead full paths to obj files (#602) 2016-08-21 13:49:08 +00:00
65c003eef8 Merge pull request #615 from AMDmi3/miniupnpc-library-detection
Find miniupnpc library as well as header
2016-08-19 07:01:35 -04:00
959843ee9c Find miniupnpc library as well as header 2016-08-19 12:16:28 +03:00
c16632d99a Merge remote-tracking branch 'purple/master' 2016-08-18 18:37:32 -04:00
3d066ea1b8 common termination timer for all NTCP sessions 2016-08-17 10:58:57 -04:00
e163730118 Merge pull request #614 from PurpleI2P/openssl
recent changes
2016-08-17 10:37:09 -04:00
3c8838af08 Merge branch 'upstream-master' 2016-08-16 10:55:54 -04:00
ac5394a1dc Merge pull request #613 from majestrate/fix-static-cmake
Fix static cmake
2016-08-16 10:51:26 -04:00
2e74d91ddc try fixing https://github.com/PurpleI2P/i2pd/issues/612 2016-08-16 10:27:33 -04:00
2d82c4ada4 try fixing https://github.com/PurpleI2P/i2pd/issues/612 2016-08-16 10:25:56 -04:00
03f0ca965e fixed race condition 2016-08-15 22:36:58 -04:00
a527dcd95b moved HTTP to libi2pd 2016-08-15 14:01:57 -04:00
de29abb05c check string buffer size 2016-08-15 13:12:56 -04:00
cb7efcb188 add 'O' to extra bandwidth for flooadfill 2016-08-14 17:58:50 -04:00
bf4f22b203 add 'O' to extra bandwidth 2016-08-14 17:52:11 -04:00
7f3a467a66 Merge pull request #608 from atnaguzin/patch-1
Updated debian/changelog
2016-08-13 14:47:28 -04:00
72ef621f9d Update changelog 2016-08-13 16:52:51 +03:00
73452f758c Update changelog 2016-08-13 16:52:27 +03:00
049e1b2679 Update changelog 2016-08-13 16:50:08 +03:00
4631123231 reseed-ru.lngserv.ru added 2016-08-13 09:05:35 -04:00
c86bcb4dd6 r4sas_at_mail.i2p.crt added 2016-08-13 08:23:32 -04:00
a6280661ee Merge pull request #607 from atnaguzin/patch-1
Updated i2pd.conf
2016-08-12 16:29:04 -04:00
ca7709a284 Update i2pd.conf 2016-08-12 23:23:10 +03:00
384c06f2e9 Merge pull request #606 from atnaguzin/patch-1
Updates in debian part.
2016-08-12 16:20:30 -04:00
774c11781d Update changelog 2016-08-12 22:47:20 +03:00
7a692898e4 moved tunnels.conf 2016-08-12 22:36:31 +03:00
2f1971ea8f moved tunnels.conf 2016-08-12 22:36:17 +03:00
ce13de7d6c moved subscriptions.txt 2016-08-12 22:35:09 +03:00
d51ad77ab4 moved subscriptions.txt 2016-08-12 22:34:29 +03:00
a9b289626e Update logrotate 2016-08-12 22:30:26 +03:00
8a542f2ce8 Update i2pd.upstart 2016-08-12 22:29:32 +03:00
14a2c9d48f Update i2pd.install 2016-08-12 22:28:35 +03:00
37fef7e4f8 Update ChangeLog 2016-08-12 15:21:55 -04:00
b83ab85fd9 Update i2pd.init 2016-08-12 22:21:33 +03:00
d424e1e9ff Update ChangeLog 2016-08-12 15:19:45 -04:00
aaa52bd767 Update i2pd.default 2016-08-12 22:17:25 +03:00
56254e728c Merge tag 'tags/2.9.0' 2016-08-12 13:25:25 -04:00
284159aadc Merge pull request #605 from manasb/manasb-patch-docs
fix a typo
2016-08-12 12:56:33 -04:00
29593f0161 fix a typo 2016-08-12 12:43:59 -04:00
deca217544 don't always set port 4567 2016-08-12 11:07:00 -04:00
c09212de81 Merge pull request #604 from PurpleI2P/openssl
recent changes
2016-08-12 10:44:02 -04:00
db8d93d308 2.9.0 2016-08-12 10:43:06 -04:00
4c96106666 reseed.file added 2016-08-12 10:37:03 -04:00
8e849ea6f8 reseed from file 2016-08-12 10:33:53 -04:00
82d80d2ead moved Config.cpp to libi2pd 2016-08-12 10:28:36 -04:00
a5da55d0f7 Update build_notes_android.md 2016-08-12 09:38:31 -04:00
702e6c8080 buld instruction without QT 2016-08-12 09:30:35 -04:00
46e957ab7e Merge pull request #603 from atnaguzin/patch-2
Replaced arrows to HTML code. Deleted tab spaces.
2016-08-11 07:20:54 -04:00
c27f8a5c1e Replaced arrows to HTML code. Deleted tab spaces. 2016-08-11 12:25:26 +03:00
8e835f2f6b fixed race condition 2016-08-09 20:51:54 -04:00
35e8a027ad Merge pull request #600 from brain5lug/openssl
copy elimination for ranges #part4
2016-08-09 20:50:44 -04:00
94642f9066 copy elimination for ranges #part4 2016-08-10 01:16:24 +03:00
2dd5de4373 handle default subscription in separate thread 2016-08-09 10:17:40 -04:00
793e80490c Merge pull request #598 from brain5lug/openssl
copy elimination for ranges #part3
2016-08-09 07:25:24 -04:00
727a1f4ddd Merge pull request #599 from atnaguzin/patch-1
Update HTTPServer.cpp
2016-08-09 07:22:34 -04:00
6a752a56ff Update HTTPServer.cpp 2016-08-09 13:54:47 +03:00
32466e3804 don't notify before wait 2016-08-08 22:15:09 -04:00
a530503c0c copy elimination for ranges #part3 2016-08-09 01:53:37 +03:00
7ba4af7e2e fixed build error 2016-08-08 17:31:32 -04:00
c9c05ad2a8 Merge pull request #596 from atnaguzin/patch-2
"SAM sessions" link check added
2016-08-08 17:23:58 -04:00
ab1df3a1d0 Update HTTPServer.cpp 2016-08-08 23:37:16 +03:00
56a60772a4 fixed potential deadlock 2016-08-08 11:53:38 -04:00
63e6731207 Merge pull request #595 from brain5lug/openssl
copy elimination for ranges #part2
2016-08-07 18:31:32 -04:00
8b53ded53a copy elimination for ranges #part2 2016-08-08 00:52:48 +03:00
d5075d706c eliminate decay timer 2016-08-07 16:27:36 -04:00
03927b0a68 Merge branch 'upstream-openssl' 2016-08-06 20:27:57 -04:00
0d88b8012b Merge pull request #591 from brain5lug/openssl
The temporary object elemination part#1
2016-08-05 19:33:19 -04:00
a583c21136 merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-08-06 01:26:34 +03:00
b8ec63cf8c copy ellimination for ranges #part1 2016-08-06 01:03:13 +03:00
4b9afdf53a fix typo 2016-08-05 18:06:06 +00:00
788d1650a2 Merge pull request #590 from brain5lug/openssl
tiny commit to check pulling
2016-08-04 17:31:52 -04:00
8f58886a21 tiny commit to check pulling 2016-08-04 23:27:07 +03:00
94b3bb2391 adjust termination timeout 2016-08-04 10:26:50 -04:00
c8f5fb4d03 close duplicate ntcp sessions 2016-08-03 10:40:30 -04:00
070a21a9eb Merge remote-tracking branch 'purple/openssl' 2016-07-31 19:29:12 -04:00
5698ff9c4c wait for UPnP discovery during startup 2016-07-31 10:22:41 -04:00
47b562b032 temporary disable OS X 2016-07-30 18:22:14 -04:00
69234db848 Merge pull request #588 from atnaguzin/patch-1
Update 01-tune-build-opts.patch
2016-07-30 14:58:09 -04:00
ebc132ea65 Update 01-tune-build-opts.patch 2016-07-30 21:27:17 +03:00
0899eeddc0 UPnP for x86_64 2016-07-29 10:59:44 -04:00
cf8ff2cf86 make it compile 2016-07-28 15:35:13 -04:00
ee9dc789af change scope of Stream::Terminate 2016-07-28 15:34:32 -04:00
570598f556 abruptly close 2016-07-28 15:33:03 -04:00
e8c3546433 try fixing 2016-07-28 13:27:51 -04:00
1062776762 cleanup router's tags 2016-07-28 13:24:25 -04:00
584379b502 fix 2016-07-28 12:48:32 -04:00
87e1c45c05 fug 2016-07-28 12:34:33 -04:00
9447afe49c try changing i2cp option 2016-07-28 12:32:05 -04:00
fc5b1ae3e2 fug 2016-07-28 12:28:18 -04:00
13735d0475 move setting 2016-07-28 12:26:05 -04:00
6b3a783ce9 change type 2016-07-28 12:21:59 -04:00
3b66bba92e more fixes 2016-07-28 12:17:24 -04:00
a2e01f8a53 more tweaks 2016-07-28 11:42:31 -04:00
34da9a9655 streaming limiting tweaks 2016-07-28 11:37:33 -04:00
df8d73ae43 typo 2016-07-28 11:20:24 -04:00
aa3a93b6a0 implement streaming limiting (initial) 2016-07-28 11:16:29 -04:00
17bfa35f77 don't use warning for no tags 2016-07-28 10:02:26 -04:00
59797a5c9a streaming log tweaks and dont set RTT to 0 2016-07-28 10:01:20 -04:00
61fe2923e4 don't set socket option for closed sockets 2016-07-28 09:53:39 -04:00
50b9eca34c check for bogus times in packets 2016-07-28 09:50:19 -04:00
f5684eba90 color log messages for warn and error 2016-07-28 09:49:43 -04:00
f32510e10a set socket options 2016-07-28 09:25:05 -04:00
4fb0eeda37 Merge remote-tracking branch 'purple/openssl' 2016-07-28 09:06:58 -04:00
b1aeae6772 * util.{cpp,h} : kill with fire i2p::util::http (#314, closes #432) 2016-07-27 13:10:29 +00:00
5a6bd38d22 * docs/configuration.md 2016-07-27 13:10:29 +00:00
97da8e2f2e * HTTPServer.cpp : true random password 2016-07-27 13:10:28 +00:00
10be150503 invoke GracefulShutdown for Win32 2016-07-26 12:11:52 -04:00
36aa248556 Graceful shutdown 2016-07-26 11:52:44 -04:00
183c22cc84 rollback 2016-07-26 11:22:53 -04:00
63f4cf3d07 graceful shutdown for windows 2016-07-26 11:10:10 -04:00
eeeae12639 check for correctly loaded privatekeys 2016-07-25 11:13:54 -04:00
0d854c6ea6 Merge remote-tracking branch 'purple/master' 2016-07-25 10:29:10 -04:00
1e1c4d159b do reload 2016-07-25 10:28:20 -04:00
4dc9f6948d bounds checks 2016-07-25 09:57:35 -04:00
c06e739c9b Merge pull request #583 from PurpleI2P/openssl
recent changes
2016-07-25 09:43:18 -04:00
061720bcf0 handle'\r\n' terminated address from Transmission 2016-07-24 10:20:37 -04:00
11585327bf correct status response 2016-07-24 09:24:20 -04:00
2793eeb10a Merge pull request #581 from PurpleI2P/reloadconfig_on_SIGHUP
Reload client config on SIGHUP
2016-07-24 08:15:00 -04:00
8fb093b272 Reload client config on SIGHUP 2016-07-24 17:58:26 +08:00
c90c008f65 Merge remote-tracking branch 'purple/openssl' 2016-07-23 21:22:02 -04:00
3d1a7f173c select Charlie based on Alice's address type 2016-07-22 13:08:41 -04:00
ba078f3ff5 support peer test for ipv6 2016-07-22 12:50:03 -04:00
6d54401d7c Merge remote-tracking branch 'devnull/linux_tunnel_reload_on_hup' 2016-07-22 12:42:59 -04:00
c9a0897208 Merge remote-tracking branch 'purple/openssl' 2016-07-22 11:57:48 -04:00
6a1049bfb7 override address if v6 only 2016-07-22 10:34:56 -04:00
5995ab3f4c Merge branch 'upstream-openssl' 2016-07-22 10:18:58 -04:00
a4112ebed2 add both v4 and v6 addresses 2016-07-22 10:16:57 -04:00
289cae4213 Merge remote-tracking branch 'purple/openssl' 2016-07-22 09:59:56 -04:00
eaac21cda1 * check router info addresses for nullptr
* Request LS before expiration for smoother handover
2016-07-22 09:56:17 -04:00
3b9b827ebf getnick doean't return error if was set before 2016-07-21 20:42:40 -04:00
c908beade2 Added client tunnel reload on SIGHUP for Linux 2016-07-21 17:57:43 -06:00
abcf030181 more BOB error messages 2016-07-21 14:02:13 -04:00
22a16da09e fixed android build 2016-07-20 21:44:17 -04:00
0e31da5e51 Merge pull request #578 from PurpleI2P/openssl
recent changes
2016-07-20 18:33:43 -04:00
61e6a03d70 check correct #ifdef for windows 2016-07-20 09:33:50 -04:00
3f2119556f upnp.name 2016-07-19 12:05:32 -04:00
77493d0d09 configurable UPnP name 2016-07-19 12:03:03 -04:00
340c73cbdf send actual status back 2016-07-19 11:08:28 -04:00
ea7f4447b2 * Reseed.cpp : check response code 2016-07-19 00:59:16 +00:00
19f3c75a8d * Reseed.cpp : use new response parsing 2016-07-19 00:59:15 +00:00
25ba08abcf * Reseed.cpp : use new http classes 2016-07-19 00:59:13 +00:00
26be0c7c82 * move i2p::util::config::GetHost to RouterContext.cpp 2016-07-19 00:59:11 +00:00
b7c5e3b5d5 correct termination of UPnP 2016-07-18 14:01:58 -04:00
701653a6bd Merge pull request #576 from rjmalagon/patch-1
Update BOB.cpp
2016-07-16 12:18:51 -04:00
2c099c7f0e Update BOB.cpp
fixed typo
2016-07-16 10:21:07 -04:00
fba53117d8 Update BOB.cpp
Fix a little typo
2016-07-16 09:21:01 -05:00
e1bf53d90a handle status command 2016-07-16 09:31:33 -04:00
ecc82739d8 * HTTP.cpp : fix is_gzipped() 2016-07-16 12:13:00 +00:00
d16afa9692 * Addressbook.cpp : tune logs 2016-07-16 12:11:23 +00:00
9f3ce09e88 * Addressbook.{cpp,h} : show new hosts 2016-07-16 12:11:23 +00:00
cbfb1edb79 * Addressbook.{cpp,h}:
* Request() now renamed and returns value
  * move spawning download thread to Addressbook class
  * CheckSubscription() renamed and handles return value of Request()
2016-07-16 12:11:10 +00:00
b6c336bf72 * Addressbook.cpp : use HTTPRes class for response parsing 2016-07-16 12:10:43 +00:00
403e34506e * Addressbook.cpp : use HTTPReq class for building request 2016-07-16 12:10:37 +00:00
83db868542 * Addressbook.cpp : use new URL class, unwrap some conditions 2016-07-16 12:10:34 +00:00
1b6e673b50 Merge pull request #574 from majestrate/master
Floodfill fixes, testnet fixes, add lease set view page in HTTPServer
2016-07-15 14:52:12 -04:00
a0144f093f fix typo 2016-07-15 13:59:56 -04:00
a5d84bf8a9 pedantic whitespace fix 2016-07-15 13:54:34 -04:00
84bb740e62 clean up code 2016-07-15 13:52:55 -04:00
d37482ada1 IT WORKS, floodfill confirmed working on test network 2016-07-15 13:31:31 -04:00
75fc8202ab fix off by ones 2016-07-15 12:49:45 -04:00
24aff15752 off by one 2016-07-15 10:55:02 -04:00
338b9928f0 repeat correction 2016-07-15 10:45:38 -04:00
b9607b4b8e correct last commit 2016-07-15 10:44:43 -04:00
586f241074 OFF BY ONE 2016-07-15 10:44:08 -04:00
e298987d9e fixed build error 2016-07-15 09:45:54 -04:00
71cc4b5bf2 add lease set page in http server 2016-07-15 09:38:21 -04:00
4fdd9feddc don't try to republish forever 2016-07-14 16:59:26 -04:00
caf7da1053 set reachable/unreachable for v4 only 2016-07-14 14:29:45 -04:00
7d04ba0fc3 CXXFLAGS -> NEEDED_CXXFLAGS 2016-07-14 14:25:20 -04:00
d98d091c43 use list instead vector for addresses 2016-07-14 14:10:38 -04:00
3ad196c4c7 fix meshnet mode:
* don't default to ipv4 when creating router.info
* add i2p::util::config::GetHost for getting host to use from config
* proper check for no transports in Transports.cpp on startup
2016-07-14 09:23:33 -04:00
562f320198 load libstd 2016-07-13 22:34:53 -04:00
3e5581e094 create addresses in defualt constructor 2016-07-13 22:33:39 -04:00
c4721e1020 + HTTP.{cpp,h} : add HTTPRes::is_gzipped() 2016-07-14 00:34:42 +00:00
728f2670f3 * HTTPServer.cpp : drop jumpservices : now handled by HTTPProxy itself 2016-07-14 00:34:38 +00:00
8dd157d2eb * HTTPProxy.cpp : html error messages 2016-07-14 00:32:41 +00:00
2d40d69fa2 fixed race condition 2016-07-13 12:56:23 -04:00
f2f0d69bce Update configuration.md 2016-07-13 11:14:06 -04:00
812f5045b0 enable UPnP for windows and android by default 2016-07-13 11:12:51 -04:00
9a8e7b11e5 detect network status at android 2016-07-13 10:09:22 -04:00
e213e695c8 Merge pull request #572 from hypnosis-i2p/openssl
reworked android. added a build script.
2016-07-13 08:46:23 -04:00
e24eea313c updated 2016-07-13 19:40:09 +08:00
a3286ebac3 updated 2016-07-13 19:36:18 +08:00
95ae23a32c gitignore 2016-07-13 11:08:35 +08:00
d240f3242c gitignore 2016-07-13 11:08:35 +08:00
814f60a512 reworked android. added a build script. 2016-07-13 11:08:35 +08:00
fac6229e43 * cmake debug (closes #562) 2016-07-13 01:01:47 +00:00
c528d739c8 Merge branch 'new-proxy' into openssl 2016-07-13 00:49:00 +00:00
c664be52d7 limit outgoing queue size 2016-07-12 16:26:36 -04:00
4ac4f44ba7 limit delayed messages queue size 2016-07-12 12:37:39 -04:00
174430e3b5 * HTTPServer.cpp : rename command 2016-07-12 02:30:39 +00:00
762b21f809 * Streaming.cpp : tune log messages 2016-07-12 02:23:24 +00:00
9340bf385e * Daemon.cpp : make upnp configurable via options 2016-07-12 02:21:52 +00:00
9f5be52a97 * UPnP.cpp : tune log messages 2016-07-12 02:21:52 +00:00
9dc5a4fce3 * UPnP.{cpp,h} : cleanup & add class stub if opt-out 2016-07-12 02:21:52 +00:00
fda3cd5fe7 * Config.cpp : add --upnp.enabled option 2016-07-12 02:21:52 +00:00
6b8469e9a3 * docs/configuration.md : fix markdown 2016-07-12 02:21:52 +00:00
7dbbe5a7d8 wait until tunnels get created 2016-07-11 14:35:59 -04:00
2d6fdeb7ad Merge pull request #567 from hypnosis-i2p/openssl
android without qt — initial push
2016-07-09 21:50:33 -04:00
4d3a01a5fe android ported all + isConnected notif 2016-07-10 09:42:42 +08:00
8cc6756815 Merge pull request #566 from PurpleI2P/openssl
recent changes
2016-07-09 21:41:43 -04:00
5967ab75b1 Merge branch 'openssl' of https://github.com/hypnosis-i2p/i2pd into openssl 2016-07-10 04:54:15 +08:00
69c954760a android without qt initial commit 2016-07-10 04:54:11 +08:00
40a4c3ccbd junk 2016-07-10 00:19:20 +08:00
aacb9d9570 merged 2016-07-10 00:19:20 +08:00
9b6c229b71 remember tunnels selection for following messages 2016-07-08 14:17:41 -04:00
1da5be2871 clean up unconfirmed tags faster 2016-07-07 22:39:20 -04:00
66dafca61a select existing connection for first hop of a tunnel 2016-07-06 22:34:24 -04:00
1f22b5b083 junk 2016-07-07 02:46:11 +08:00
5be0b7a731 merged 2016-07-07 02:45:13 +08:00
b64b5d9103 Update build_notes_android.md 2016-07-06 17:55:36 +00:00
953d78da9e Update build_notes_android.md 2016-07-06 16:10:30 +00:00
ce9e0981a2 Update index.rst 2016-07-06 16:03:54 +00:00
76e1114a1f Update build_notes_android.md 2016-07-06 11:30:11 -04:00
cfc80b491f Update build_notes_android.md 2016-07-06 11:29:43 -04:00
43ed05d3c2 Create build_notes_android.md 2016-07-06 11:29:00 -04:00
4cf5ce871f destroy socket upon receive an ack for close 2016-07-05 17:52:11 -04:00
91ec08df4e wait for close from other side 2016-07-05 09:52:18 -04:00
c79363ef63 Merge pull request #563 from PurpleI2P/openssl
recent changes
2016-07-05 09:40:17 -04:00
cc6672198a Merge pull request #560 from atnaguzin/openssl
updated appveyor.yml
2016-07-02 07:14:21 -04:00
17cdf7c79d Merge pull request #7 from PurpleI2P/openssl
fixed VS build error
2016-07-02 13:52:18 +03:00
725f939f35 fixed VS build error 2016-07-02 06:45:15 -04:00
e2df00bb2e Merge pull request #6 from PurpleI2P/openssl
Upstream pull
2016-07-01 15:34:01 +03:00
a9a33c6179 fixed build error 2016-07-01 08:31:27 -04:00
8e7eb87a2d Merge pull request #558 from atnaguzin/patch-1
Update i2pd_qt.pro
2016-07-01 08:10:25 -04:00
217004e7a5 Update appveyor.yml 2016-07-01 13:22:47 +03:00
4d10848984 Update i2pd_qt.pro 2016-07-01 13:07:24 +03:00
da2c04f681 * HTTPProxy.cpp : show created stream IDs in log 2016-07-01 00:39:07 +00:00
8deb327b3b * HTTPProxy.cpp :
* migrate to HTTPReq
  * change work with buffers
  * code cleanup
2016-07-01 00:38:55 +00:00
642b01bf0d * HTTPProxy.cpp : add SanitizeHTTPRequest() 2016-07-01 00:38:31 +00:00
9fd78b1eb1 * HTTPProxy.cpp : rename variable 2016-07-01 00:38:31 +00:00
66c09fc44c * HTTPProxy.cpp : HandleJumpServices() -> ExtractAddressHelper() 2016-07-01 00:38:31 +00:00
2cb5e1a6c2 * HTTPProxy.cpp : kill ExtractRequest() 2016-07-01 00:38:31 +00:00
02ac638bd4 * HTTP.cpp : add comments, update test case 2016-07-01 00:34:31 +00:00
323f74c43a * HTTP.cpp : fuck the "special cases", use nginx rewriting frontend or some 2016-07-01 00:34:28 +00:00
1e56d17d39 Merge pull request #5 from PurpleI2P/openssl
upstream pull
2016-07-01 02:12:09 +03:00
16af8e082b Merge pull request #557 from majestrate/merge-testnet-changes
Merge testnet changes
2016-06-30 18:24:49 -04:00
9215a54c23 revert 2016-06-30 18:05:41 -04:00
fab34d3dbb clean up identation 2016-06-30 17:59:14 -04:00
03d7330af5 Merge pull request #556 from PurpleI2P/openssl
floodfill fixes
2016-06-30 17:51:26 -04:00
346b0c9d68 disable testnet by default 2016-06-30 17:50:47 -04:00
c29359e7a8 Merge remote-tracking branch 'purple/openssl' into meshnet 2016-06-30 17:48:46 -04:00
4b903931bc update i2pd testnet addressbook url 2016-06-30 17:34:16 -04:00
4e0929e71a don't print out junk when logging 2016-06-30 17:24:33 -04:00
1bad097a13 don't check for LS expired for FF 2016-06-30 17:21:18 -04:00
331065eec6 remove expired LS 2016-06-30 17:01:00 -04:00
f51ba499d5 Merge pull request #555 from majestrate/fix-ff-off-by-one
off by one?
2016-06-30 15:07:26 -04:00
f62ccc2d48 off by one? 2016-06-30 14:26:05 -04:00
cf485aa62e Merge pull request #554 from atnaguzin/openssl
added hiding information in webconsole
2016-06-30 14:25:39 -04:00
6b16a48568 revert 2016-06-30 14:24:55 -04:00
ff7cf503ae added hiding information in webconsole 2016-06-30 21:21:37 +03:00
2412a0d502 off by one? 2016-06-30 13:35:36 -04:00
b1612bb1ed Merge pull request #4 from PurpleI2P/openssl
Upstream pull
2016-06-30 20:30:45 +03:00
b8a205f755 netdb.cpp:
* explicitly define replyIdent

Daemon.cpp:
* wait for 1 second before checking if transports are bound to wait for transports to bind
2016-06-30 13:25:20 -04:00
eab08ea78c don't accept our own RouterInfo 2016-06-30 13:15:36 -04:00
d7653769b4 more logging 2016-06-30 12:57:20 -04:00
c72d9695da testnet changes 2016-06-30 12:27:23 -04:00
0493f00a7a pass null tunnel config for zero hops tunnel 2016-06-30 12:24:26 -04:00
ff757ddc88 don't check for exact LS 2016-06-30 11:27:40 -04:00
c4c495948a don't flood if older 2016-06-30 11:10:01 -04:00
986ee6bac3 Merge remote-tracking branch 'purple/openssl' into meshnet 2016-06-30 11:03:15 -04:00
6ab7e79987 send own copy of a message during flood 2016-06-30 11:01:21 -04:00
c6e35876fa if LS is older, assume updated so we reply 2016-06-30 10:51:39 -04:00
eb31accf20 Merge remote-tracking branch 'purple/openssl' into meshnet 2016-06-30 10:25:44 -04:00
ea1ba0f09b don't flood to itself 2016-06-30 10:21:53 -04:00
10911f5b64 make it compile 2016-06-30 09:52:37 -04:00
0eab8e9322 more pedantic logging changes 2016-06-30 09:49:28 -04:00
fb2602716e add floodfill to exclude 2016-06-30 09:48:08 -04:00
be68906ae9 logging tweaks 2016-06-30 09:45:06 -04:00
c53d6d80ba Merge branch 'master' into meshnet 2016-06-30 09:15:30 -04:00
1362177352 Merge remote-tracking branch 'purple/openssl' 2016-06-30 08:57:59 -04:00
28ab1230e2 '@' can exist in url path 2016-06-30 08:00:18 -04:00
0784934520 Merge pull request #551 from majestrate/http-router-ident
add RouterInfo hash to web ui
2016-06-30 07:46:28 -04:00
79fbf9d47f add RouterInfo hash to web ui 2016-06-30 07:41:40 -04:00
dabdc8e4c5 Merge branch 'upstream-openssl' 2016-06-30 07:40:15 -04:00
466ad192b0 add RouterInfo hash to web ui 2016-06-30 07:36:35 -04:00
ac59d9e1b6 Merge branch 'upstream-openssl' 2016-06-30 07:36:14 -04:00
d44245e1e9 add RouterInfo hash to web ui 2016-06-30 07:35:30 -04:00
c50105493a fixed zero-hops tunnels 2016-06-29 21:37:17 -04:00
2768a62f92 more logging 2016-06-29 18:05:08 -04:00
5841d0d87d add more specific logging 2016-06-29 17:59:56 -04:00
2a796051bf try fixing LS 2016-06-29 17:42:26 -04:00
50286fd173 use inet_ntop properly 2016-06-29 16:10:43 -04:00
44f0bad2a6 fug 2016-06-29 15:52:32 -04:00
611b9c4fd1 ugh 2016-06-29 15:50:39 -04:00
3f50776062 ugh 2016-06-29 15:48:02 -04:00
c70d2ad6fa try fixing 2016-06-29 15:42:03 -04:00
9dd0bd604c fix 2016-06-29 15:37:37 -04:00
0565519509 don't print out raw ident 2016-06-29 15:15:33 -04:00
c282d95be1 undo change 2016-06-29 15:10:33 -04:00
766286b8bc undo pedantic change 2016-06-29 14:57:42 -04:00
f405c62f1e pedantic style and logging changes 2016-06-29 14:56:00 -04:00
93fbd7b3ba Merge branch 'upstream-openssl' into meshnet 2016-06-29 13:32:39 -04:00
ae5cea7f36 change order of initialization 2016-06-29 11:59:43 -04:00
8b7b6cfbc5 try fixing segfault 2016-06-29 11:57:44 -04:00
f6e988d6fd support zero-hops tunnels for destinations 2016-06-29 11:26:46 -04:00
f88f68f248 Add bind to network interface option 2016-06-29 11:06:51 -04:00
14f2b24b16 update logging 2016-06-29 10:11:14 -04:00
f2dde98e2f add meshnet option to cmake build files 2016-06-29 09:37:38 -04:00
90d8ec0e81 add more logging 2016-06-29 09:37:21 -04:00
14cdb531c8 * Streaming.cpp : tune logs 2016-06-29 02:14:39 +00:00
3a50320f79 add more logging 2016-06-28 15:35:58 -04:00
597b5e6cfb use different constants for now in meshnet mode 2016-06-28 14:50:25 -04:00
2cd056cfb3 try banning non responsive routers 2016-06-28 14:43:55 -04:00
be6aab4c40 revert 2016-06-28 14:24:18 -04:00
d030df925f Merge remote-tracking branch 'purple/openssl' into meshnet 2016-06-28 14:21:09 -04:00
50756eb94a Merge branch 'restricted_routes' into meshnet 2016-06-28 13:28:57 -04:00
21b3576b66 stop using auto 2016-06-28 12:20:18 -04:00
2e5226356b * Tag.h : add (c) header 2016-06-28 14:31:40 +00:00
21b76d3d2b * Config.cpp : drop compat parser 2016-06-28 14:31:40 +00:00
2d252e6459 * HTTP.cpp : rename method 2016-06-28 14:31:40 +00:00
43be363542 Merge remote-tracking branch 'purple/openssl' into meshnet 2016-06-28 09:34:38 -04:00
8cb3e3418a send garlic cloves directly if garlic was received derectly 2016-06-28 09:31:41 -04:00
cd47ddd539 default to USE_MESHNET=yes 2016-06-28 07:57:48 -04:00
2be1c10522 Tag.h and Gzip.h/.cpp added 2016-06-28 07:11:55 -04:00
7f26670173 + tests/test-base-64.cpp 2016-06-28 01:45:14 +00:00
d838ce85c3 * Base.h : extract Tag template class to separate header 2016-06-28 01:45:11 +00:00
6350f5e6e8 * Base.cpp : extract gzip classes to separate file 2016-06-28 01:45:07 +00:00
10f3690ede Merge pull request #547 from atnaguzin/openssl
fixed #546
2016-06-27 20:30:31 -04:00
06daa8bb0e try shooting in the dark for workarround 2016-06-27 17:39:13 -04:00
34a90f442e try shooting in the dark for workarround 2016-06-27 17:37:31 -04:00
afe81dcdbe add logging 2016-06-27 17:25:29 -04:00
24d616672b revert daemon.cpp change 2016-06-27 17:11:03 -04:00
9cfc61cd45 fixed #546 2016-06-28 00:00:54 +03:00
487df84b90 Merge pull request #3 from PurpleI2P/openssl
Upstream pull
2016-06-27 23:54:53 +03:00
614c1306f6 use correct netid when using separate test network 2016-06-27 16:40:46 -04:00
07dca9bd16 tweak ssu mtu again for meshnet 2016-06-27 15:28:26 -04:00
1ebcbd5b0e use smaller mtu for meshnet mode 2016-06-27 15:06:15 -04:00
32644ddada try fixing duplicate Routers In tunnel path 2016-06-27 14:16:29 -04:00
cf3bab996e when routers < 5 and in meshnet mode do not select random peers 2016-06-27 14:00:04 -04:00
926ffe2581 change default addressbook for meshnet mode 2016-06-27 13:46:14 -04:00
fff3587d99 only set as testing when not in meshnet mode 2016-06-27 13:20:21 -04:00
866cf940da make always reachable when in meshnet mode 2016-06-27 13:15:05 -04:00
7868e1527e try fixing ipv6 ssu 2016-06-27 11:08:23 -04:00
556bfb752a disable meshnet by default, use make USE_MESHNET=yes to build for cjdns 2016-06-27 10:33:14 -04:00
a3b08654b4 try adding ipv6 only mode for ssu 2016-06-27 10:24:37 -04:00
4cf4436169 initial meshnet mode 2016-06-27 09:47:53 -04:00
e2acc55819 * HTTPProxy.cpp : unwrap HandleStreamRequestComplete() 2016-06-27 13:14:42 +00:00
6b29d6b8dc * HTTPProxy.cpp : unwrap AsyncSockRead() 2016-06-27 13:14:39 +00:00
b668c4c302 * add global switch USE_UPNP to makefile 2016-06-27 13:12:01 +00:00
646778227a * tune log messages 2016-06-27 13:11:10 +00:00
a973630cb4 * fix tests 2016-06-27 13:11:10 +00:00
4e7375c09c * Addressbook.cpp : move storage creation to Start() 2016-06-27 13:11:10 +00:00
881d0652e7 * update debian package defaults 2016-06-27 13:11:10 +00:00
0c46993baa Merge pull request #544 from atnaguzin/openssl
Updating i2pd_qt.pro
2016-06-27 06:54:49 -04:00
09b15f4940 edited i2pd_qt.pro 2016-06-27 05:55:07 +03:00
ebf7be56bb Merge pull request #2 from PurpleI2P/openssl
upstream pull
2016-06-27 05:52:56 +03:00
727068cc4b * HTTPProxy.cpp : migrate HTTPRequestFailed() to new http classes 2016-06-27 02:37:33 +00:00
6f77c6f3f4 * HTTPProxy.cpp : don't reuse part of httppserver, addresshelpers handling will be moved to proxy in future 2016-06-27 02:37:32 +00:00
c5e3e17eae * HTTPProxy.cpp : extract IsI2PAddress() from class 2016-06-27 02:37:30 +00:00
effdb70417 Merge branch 'upstream-openssl' into restricted_routes 2016-06-26 21:53:13 -04:00
e28f910c88 * enable travis for UPNP=ON back 2016-06-27 01:30:02 +00:00
c84468dbed * fix cmake build with upnp=on 2016-06-27 01:12:20 +00:00
4b9e39ac64 limit SSU outgoing windows 2016-06-26 17:03:04 -04:00
6b0c05ee7c Merge pull request #542 from majestrate/fix-rpi-static
fix static build for rpi linux
2016-06-26 13:31:14 -04:00
5c6ec70126 fix static build for rpi linux 2016-06-26 11:17:05 -04:00
2757ef94c9 don't include UPNP twice for android 2016-06-26 08:37:40 -04:00
9ba7120011 fixed build error 2016-06-26 08:32:36 -04:00
124f9ec44e Merge pull request #1 from PurpleI2P/openssl
upstream pull
2016-06-26 15:29:43 +03:00
0d229175cd Merge pull request #539 from hypnosis-i2p/openssl
added tray icon to linux and windows versions
2016-06-25 21:01:54 -04:00
10638b6e40 fixed unnecessary resources setting 2016-06-26 02:48:13 +08:00
134baad56d added tray icon to linux and windows versions 2016-06-26 02:32:54 +08:00
9a5984d750 Merge branch 'upstream-openssl' into restricted_routes 2016-06-25 10:55:22 -04:00
073f42e64a Merge branch 'upstream-openssl' into restricted_routes 2016-06-25 10:54:41 -04:00
096927beed don't sedn explicit Ack if no NACKs only 2016-06-24 21:54:58 -04:00
4bc76995d1 docs: default httpproxy.port changed to actual 4444 2016-06-24 19:29:59 -04:00
9f41151156 HTTP proxy redirects to 0.0.0.0:7070/?page=jumpservices 2016-06-24 19:25:48 -04:00
6b3bd755b0 fixtypo 2016-06-24 19:07:47 -04:00
7e580e6a0b Update HTTPServer.cpp 2016-06-24 17:58:46 -04:00
047c8eda22 stop accepting tunnels by graceful shutdown 2016-06-24 16:26:13 -04:00
f22e5c209c fixed QT linux build 2016-06-24 16:05:03 -04:00
8cc3a08871 Merge pull request #536 from hypnosis-i2p/openssl
Added graceful quit button; the code for stopping tunnels pending
2016-06-24 15:43:12 -04:00
35f6c6cb98 graceful quit button added 2016-06-25 03:38:50 +08:00
814b174f25 android version code bump 2016-06-25 03:38:50 +08:00
5fbaf0bc7d disabled UPNP=ON 2016-06-24 15:29:36 -04:00
ba772ab481 static miniupnpc 2016-06-24 14:20:35 -04:00
0a4888a18f link with miniupnp 2016-06-24 14:18:50 -04:00
fedbf2cc44 link UPnP with app if USE_UPNP is set 2016-06-24 13:15:51 -04:00
0f68bbac8e single #ifdef for protocol type 2016-06-23 14:01:41 -04:00
13e965096b UPnP for android 2016-06-23 12:57:36 -04:00
92961bb7bf i2cp for android 2016-06-23 11:23:06 -04:00
340686ba06 * HTTPProxy.{cpp,h} : rename classes, drop typedef 2016-06-23 13:24:44 +00:00
d8906f508c * HTTPProxy.cpp : HTTP error message cleanup 2016-06-23 13:24:44 +00:00
dde53ea4ba * HTTPProxy.cpp : HTTPRequestFailed() now responds with error message 2016-06-23 13:24:44 +00:00
225ed5b662 * HTTPProxy.{cpp,h} : move & sort headers 2016-06-23 13:24:44 +00:00
02857cf2b5 * Base.cpp : drop logger dependency 2016-06-23 13:24:44 +00:00
118a771980 * update changelog 2016-06-23 13:24:37 +00:00
359123564f Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-06-22 15:49:02 -04:00
49d2878938 use local sockets for android 2016-06-22 15:48:36 -04:00
f08ea4a9a3 Merge pull request #535 from PurpleI2P/openssl
2.8.0
2016-06-22 15:47:22 -04:00
f2bc71bc2a Merge branch 'upstream-openssl' 2016-06-22 13:19:00 -04:00
2b1e40c6c6 Update build_notes_windows.md 2016-06-22 11:15:40 -04:00
105c2deeb3 Merge pull request #534 from atnaguzin/patch-2
markup update
2016-06-22 11:06:44 -04:00
c3dbbc9144 Update build_notes_windows.md 2016-06-22 18:04:11 +03:00
ca55a9a8a6 build with UPnP 2016-06-22 10:53:29 -04:00
7ea5af448e UPNP support from windows 2016-06-22 09:41:01 -04:00
2f6898142e Merge pull request #533 from atnaguzin/openssl
updated config files
2016-06-22 07:13:23 -04:00
02e0b8cc32 Update i2pd.conf 2016-06-22 11:49:22 +03:00
b962a4c69b updated config files 2016-06-22 11:46:37 +03:00
ed3e83df67 android is supported now 2016-06-21 12:34:20 -04:00
b07bff61f0 set target SDK to 23 2016-06-21 09:09:31 -04:00
a7c955055c Merge branch 'upstream-openssl' into restricted_routes 2016-06-21 08:15:26 -04:00
13f33a9d19 2.8.0 2016-06-20 21:39:47 -04:00
be3fa6091d app appears as 'i2pd' 2016-06-20 15:28:25 -04:00
8ffddf06e4 fixed memory leak 2016-06-20 12:15:15 -04:00
9b7f583b2b icon and external storage permissions 2016-06-20 11:31:27 -04:00
9fe4f3adea teminate NTCP session on close completely 2016-06-19 21:05:48 -04:00
74d9f89c09 Merge pull request #529 from majestrate/fix-long-uptime-memleak
close ntcp sessions to prevent memory leaks
2016-06-19 21:00:25 -04:00
63c36e917e Merge branch 'upstream-openssl' into restricted_routes 2016-06-19 16:50:51 -04:00
184c6ee252 close ntcp sessions to prevent memory leaks 2016-06-19 16:48:03 -04:00
1c024afc1b Merge pull request #528 from hypnosis-i2p/openssl
fixed #519
2016-06-19 15:09:10 -04:00
51519361e2 various + fixed #519 2016-06-20 02:50:37 +08:00
bd092295a4 fixed #519 2016-06-20 02:50:37 +08:00
153c275d74 use /sdcard for android only if available 2016-06-19 09:58:29 -04:00
db0dfa1bf1 Merge pull request #526 from hypnosis-i2p/openssl
Android setForeground fix + notific.icon + fs crash fix + backg.thread restored
2016-06-19 09:44:59 -04:00
debd13d8c3 fixes: icon + localservice.java 2016-06-19 21:13:21 +08:00
4b8466e5e5 restored backg. thread; removed deinit() 2016-06-19 20:44:23 +08:00
9d9793e1af fs fixed. need another solution 2016-06-19 20:35:37 +08:00
46fafebade setForeground works. 2016-06-19 20:35:17 +08:00
1dae3d951a added qt java wrapper 2016-06-19 17:26:34 +08:00
fb213a1efd Merge pull request #523 from PurpleI2P/openssl
android build
2016-06-18 21:26:40 -04:00
93deb37c94 add primordial goo tier "hidden mode" (aka toy feature needs more work doesn't do it correctly all the way) 2016-06-18 11:10:58 -04:00
004a93a841 Merge branch 'transport_failsafe' into restricted_routes 2016-06-18 09:01:53 -04:00
da5be9f01d temporary disable background thread 2016-06-17 16:37:08 -04:00
344d0ae3ec some cleanup 2016-06-17 16:30:50 -04:00
3639c86adf some cleanup 2016-06-17 12:04:05 -04:00
4fc80fd366 eliminated DaemonQTImpl singleton 2016-06-17 11:25:28 -04:00
336ab2d82a Merge remote-tracking branch 'purple/openssl' into restricted_routes 2016-06-17 11:04:46 -04:00
74a7e67002 implement restricted routes (initial) 2016-06-17 11:03:33 -04:00
f76c04b7a6 fixed build errors 2016-06-17 10:26:51 -04:00
8130487b18 Merge pull request #522 from hypnosis-i2p/openssl
Qt: (1) Daemon now operates in backgr.mode, (2) added GUI Quit button
2016-06-17 10:06:33 -04:00
83790a5a73 qt: daemon now operates in the background thread; added Quit GUI button 2016-06-17 21:54:22 +08:00
1b35f68de9 qt: daemon now operates in the background thread; added Quit GUI button 2016-06-17 21:54:22 +08:00
3e912c6198 qt: daemon now operates in the background thread; added Quit GUI button 2016-06-17 21:52:14 +08:00
f995595202 Merge pull request #521 from PurpleI2P/openssl
android
2016-06-17 09:41:35 -04:00
6264569ca0 use /sdcard/i2pd at android 2016-06-17 09:10:11 -04:00
e868d427dd add options to not use ntcp or ssu 2016-06-17 09:02:12 -04:00
b9cbdb2dc4 Removed dependancy from stdafx 2016-06-16 18:20:07 -04:00
7ae563867c mainfest 2016-06-16 16:22:14 -04:00
f2f760bda4 link against correct openssl libs 2016-06-16 14:29:32 -04:00
ed561ad86b x86 build added 2016-06-16 11:42:34 -04:00
675861c323 Auto webconsole page refresh commented 2016-06-16 09:18:46 -04:00
ba330a42d6 Auto webconsole page refresh removed 2016-06-16 09:15:30 -04:00
2a9727c6b7 Merge pull request #520 from l-n-s/pretty_docs
More informative README and docs index
2016-06-15 19:55:33 -04:00
5be147e8cc More informative README and docs index 2016-06-16 01:11:42 +03:00
eb96edbd31 separate DaemonQT and DaemonQTImpl 2016-06-15 14:43:29 -04:00
14c85fa975 configurable pathes to dependancies 2016-06-15 13:18:04 -04:00
b0e3339370 DaemonQT 2016-06-15 12:20:31 -04:00
70e502e55d QT doesn't depend on Linux daemon anymore 2016-06-15 11:28:59 -04:00
ff38a3bbfe don't demonize 2016-06-15 10:17:02 -04:00
b5723a6c18 use QT's main loop 2016-06-15 09:31:52 -04:00
89012cd73b Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-06-14 14:37:52 -04:00
756e86662b fixed android build 2016-06-14 14:37:22 -04:00
27ca3b4b01 Enable C++11 2016-06-14 13:21:22 -04:00
a5be4c9d0e moved std::to_string to util.h from android 2016-06-14 11:55:44 -04:00
07cc547bab Merge pull request #517 from anon5/openssl
Android i2pd armeabi-v7a with Qt
2016-06-14 11:23:49 -04:00
f672af9706 .apk runs on emulator 2016-06-14 23:17:37 +08:00
58b058ab3a .apk builds. untested 2016-06-14 23:17:37 +08:00
28c2ca8bf8 gitignore improved - added various generated files 2016-06-14 23:17:37 +08:00
d7a06dc7a9 Merge pull request #516 from PurpleI2P/openssl
recent changes
2016-06-14 11:10:20 -04:00
8970e6a48a Merge pull request #515 from vampik/patch-1
Fix html attributes
2016-06-14 07:21:02 -04:00
b8eef181b9 Fix html attributes 2016-06-14 11:25:51 +03:00
fb94d6ae2b read header and payload separately 2016-06-13 13:20:21 -04:00
fa68e392c8 don't abort when ntcp fails to bind 2016-06-13 11:34:44 -04:00
9eaa51442f update comment 2016-06-13 09:01:38 -04:00
68482d712b Merge pull request #513 from majestrate/fix_http_proxy_500
fix 500 response in http proxy
2016-06-13 08:54:06 -04:00
09fc767bb0 fix another typo 2016-06-13 08:53:35 -04:00
ea7e6615f2 fix typo 2016-06-13 08:52:54 -04:00
a183ca8661 fix special case 2016-06-13 08:52:21 -04:00
05939a2bbc special case for i2p.rocks in proxy 2016-06-13 08:50:53 -04:00
543a372435 Merge branch 'fix_http_proxy_500' 2016-06-13 07:51:16 -04:00
e795de5562 fix 500 response in http proxy 2016-06-13 07:48:20 -04:00
ae6877ce2f handle incomplete message header 2016-06-12 08:22:55 -04:00
a0f3e81b11 Merge pull request #512 from D504/openssl
Remove unused assigning (success is assinged anyway)
2016-06-11 08:18:24 -04:00
88f52c4902 Remove unused assigning (success is assinged anyway) 2016-06-11 11:20:20 +03:00
bf8db7725f set -1 as default session id 2016-06-10 22:13:20 -04:00
f4d8c3304a execute lookup wothout session 2016-06-10 18:43:35 -04:00
44556b7f5e correct string size for mapping 2016-06-10 15:25:30 -04:00
2e1e95d483 pass URL params 2016-06-10 15:12:50 -04:00
ccc24337be Merge pull request #511 from PurpleI2P/openssl
recent changes
2016-06-10 14:46:23 -04:00
b15b38868d rolled back to previous implementation 2016-06-10 14:01:39 -04:00
8feca6874a process complete message 2016-06-10 12:18:19 -04:00
ecd3a49d48 handle DestroySession properly 2016-06-10 11:47:22 -04:00
6de7cd5063 don't send 'accepted' if not requested 2016-06-10 11:39:20 -04:00
f6d7f7d984 set port to 80 is not specified 2016-06-09 15:48:31 -04:00
d5d501875e send correct ackThrough 2016-06-09 14:56:12 -04:00
88561c22d3 make sure ackThrough is correct 2016-06-09 14:34:38 -04:00
b786576bcb * HTTPProxy.cpp : always set dest_port 2016-06-09 14:30:36 +00:00
21b5f2c96a fixed crash upon I2CP session disconnect 2016-06-08 14:14:19 -04:00
d8f24b442b fixed mapping 2016-06-08 14:05:20 -04:00
a1c81a63dd Merge remote-tracking branch 'purple/openssl'
Conflicts:
	I2CP.cpp
2016-06-08 10:37:51 -04:00
4d2b535b04 correct concatenation of long I2CP messages 2016-06-08 10:29:48 -04:00
3cfbc05bf9 set pointer to null after delete 2016-06-08 09:56:13 -04:00
895820f14c Merge branch 'upstream-openssl' 2016-06-08 09:55:55 -04:00
37fc21f3cf always assume 20 bytes for signing private key 2016-06-08 09:33:25 -04:00
5e068c3af5 0.9.26 2016-06-07 13:05:44 -04:00
e2c192d254 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-06-06 15:37:10 -04:00
e481ed37ce ReconfigureSessionMessage 2016-06-06 15:36:02 -04:00
4d7c089b09 I2CP config 2016-06-05 10:31:55 -04:00
a4dc67cba0 * HTTP.{cpp,h} : drop HTTPReq.host 2016-06-04 14:44:26 +00:00
03973cc6d4 * HTTPProxy.cpp : drop X-Forwarded-*, Proxy-*, Via headers from request 2016-06-04 14:01:37 +00:00
66c301c031 * HTTPProxy.cpp : allow "tranparent" proxy (#508) 2016-06-04 13:07:39 +00:00
e4edc59689 * HTTPProxy.cpp : force clean recv buffer (#508) 2016-06-04 13:07:37 +00:00
f2d9d38c6f Merge remote-tracking branch 'purple/openssl' 2016-06-03 14:07:02 -04:00
667ea43b3c GetBandwidthLimitMessage 2016-06-03 13:48:21 -04:00
f3856819fe Merge remote-tracking branch 'purple/openssl' 2016-06-03 13:01:49 -04:00
d6bfe7810a skip SigningPrivateKey 2016-06-03 13:01:12 -04:00
7a52ae18f1 Merge remote-tracking branch 'purple/openssl' 2016-06-03 12:13:08 -04:00
444539b826 SendMessageExpires 2016-06-03 12:03:36 -04:00
c8d6425123 DestLookupMessage 2016-06-03 11:49:39 -04:00
e50c35d38c * fix mistype 2016-06-03 01:16:29 +00:00
aa764fbd1c * HTTPProxy: fix converted request (#508)
* I2PService: reword log message, to avoid ambiguity
2016-06-03 01:09:08 +00:00
2628426084 * http proxy : fix converted request (#508) 2016-06-03 00:05:38 +00:00
aa6bc8042a address lookup 2016-06-02 15:49:14 -04:00
26a6c9e932 procee session options 2016-06-02 13:26:41 -04:00
0f9376e959 Merge remote-tracking branch 'purple/openssl' 2016-06-02 07:53:10 -04:00
ace3e86546 MessageStatusMessage 2016-06-01 15:30:57 -04:00
d79c6b8f06 MessagePayloadMessage 2016-06-01 14:38:13 -04:00
6538a2e673 HostLookupMessage 2016-06-01 11:11:18 -04:00
153d883aeb SessionDestoryedMessage 2016-06-01 10:05:40 -04:00
689432f627 fixed typo 2016-05-31 21:37:32 -04:00
cd237219e4 * extract unused image to separate file 2016-06-01 00:14:46 +00:00
8589493581 * add test for MergeChunkedResponse() (#432) 2016-06-01 00:14:40 +00:00
ca2e148ad7 * enable -Wextra for linux builds 2016-06-01 00:14:34 +00:00
f7ca44cad8 * fix compile warnings: reopen() usage 2016-06-01 00:14:28 +00:00
1b2ac38a50 * fix compilation warnings 2016-06-01 00:14:15 +00:00
f62d25fa5f * Config.cpp : fix wrong group for options & code style 2016-06-01 00:09:04 +00:00
025eec1782 I2CP configuration 2016-05-31 11:54:45 -04:00
846ff46b2e fixed build error 2016-05-30 21:42:25 -04:00
f9718bccb9 * update debian changelog (closes #502) 2016-05-31 00:34:33 +00:00
f66f4ffee6 * add generic changelog (#502) 2016-05-31 00:34:31 +00:00
a47417ff49 * I2PService.cpp: tune logs 2016-05-31 00:34:29 +00:00
c9836cf0f7 * fix doxygen warnings 2016-05-31 00:34:26 +00:00
289b679e3c * add doxygen support 2016-05-31 00:34:24 +00:00
23e019ec83 * debian/i2pd.openrc (working version) 2016-05-31 00:34:14 +00:00
eeffcea69e CreateSessionMessage 2016-05-30 15:19:22 -04:00
ae10793d0f SendMessageMessage 2016-05-30 14:31:56 -04:00
a062bca431 CreateLeaseSetMessage 2016-05-30 12:56:42 -04:00
6a453bcc8a check for null pointer 2016-05-30 12:08:20 -04:00
5a2c4919c6 close previous file first upon repon 2016-05-30 09:41:45 -04:00
09a80ed654 RequestVariableLeaseSetMessage 2016-05-29 16:35:57 -04:00
72e954b78f Merge remote-tracking branch 'purple/openssl' 2016-05-29 09:39:23 -04:00
a1c27aed6a Merge remote-tracking branch 'purple/master' 2016-05-29 09:36:34 -04:00
0b3a719a95 Merge branch 'master' of github.com:majestrate/i2pd
Fixed Conflicts:
	SAM.cpp
2016-05-29 09:36:01 -04:00
6c9b4a8c5d moved LeaseSet creating away from LeaseSetDestination 2016-05-29 09:33:50 -04:00
d9babda1b8 + debian/i2pd.openrc (experimental) 2016-05-29 01:31:38 +00:00
ea8e1be294 * update default init-script : make --port optional 2016-05-29 01:31:36 +00:00
44eccd85fd * HTTPServer.cpp :
* autorefresh for status page
  * autoreturn to commands list
2016-05-28 01:49:37 +00:00
a62720b9d8 Merge branch 'new-proxy' into openssl 2016-05-28 00:22:49 +00:00
1a9422c3f9 send SetDateMessage 2016-05-27 16:22:42 -04:00
5e52b3609c Merge pull request #503 from PurpleI2P/openssl
recent changes
2016-05-27 14:31:03 -04:00
8622385e88 I2CPDestination added 2016-05-27 13:46:28 -04:00
d0ffaab339 * HTTPProxy:
* use new http classes instead homemade parser
  * proper error handling for "address not found", "addresshelper" and "not .i2p domain" cases
  * use std::vector instead uint8_t[] for buffers
  * general code cleanup
2016-05-27 01:32:58 +00:00
347157b999 * HTTPProxy.cpp : direct use of parsed url parts in CreateHTTPRequest() 2016-05-27 01:32:15 +00:00
a9f3235fd3 * HTTPProxy.cpp : unwrap HandleStreamRequestComplete() 2016-05-27 01:32:12 +00:00
4098a5c08e * HTTPProxy.cpp : rename variable 2016-05-27 01:32:10 +00:00
dba7a2ee4f * HTTPProxy.cpp : HandleJumpServices() -> ExtractAddressHelper() 2016-05-27 01:32:07 +00:00
a5f49550b3 * HTTPProxy.cpp : unwrap AsyncSockRead() 2016-05-27 01:32:05 +00:00
5c9a69e0e8 * drop boost_regex from build deps 2016-05-27 01:32:03 +00:00
2bf32fb3fa * HTTPProxy.cpp : kill ExtractRequest(), drop boost::regex 2016-05-27 01:32:01 +00:00
0de1e2c6fc * HTTPProxy.cpp : extract IsI2PAddress() from class and generalize 2016-05-27 01:31:57 +00:00
61868d97c4 * HTTPProxy.cpp : migrate HTTPRequestFailed(), RedirectToJumpService() to new http classes 2016-05-27 01:31:55 +00:00
c994c11d8c * HTTPProxy.{cpp,h} : rename classes, drop typedef 2016-05-27 01:31:51 +00:00
5ad10955be use m_Response field for HTTP proxy response 2016-05-26 16:27:53 -04:00
95f100f378 HTTP error message cleanup 2016-05-26 16:21:27 -04:00
3d6c93cd6b moved transient encryption keys to LeaseSetDestination 2016-05-26 15:53:32 -04:00
fc25da37c5 removed GetPrivateKeys from LocalDestination 2016-05-26 14:54:33 -04:00
896bb2187e * HTTPProxy.cpp : HTTPRequestFailed() now responds with error message 2016-05-26 00:17:25 +00:00
99398bf0da * HTTPProxy.{cpp,h} : move & sort headers 2016-05-26 00:17:23 +00:00
827a54435d * Tunnel.cpp : tune log messages 2016-05-26 00:17:20 +00:00
3c9459e489 * fix mistype in log message 2016-05-26 00:10:01 +00:00
9291f5c9c6 * I2PControl.cpp :
* unwrap big else {} block
  * smaller try {} block, only for json parsing & request handling
  * respond with valid error message on exception
2016-05-26 00:09:44 +00:00
0ab5f993c7 * I2PControl.cpp :
* use new http classes for parsing request
  * implement correct reading rest of json data if HTTP/Content-length is used
  * general cleanup
2016-05-26 00:09:25 +00:00
4f8db487e7 * I2PControl.{cpp,h} : add BuildErrorResponse() 2016-05-26 00:09:25 +00:00
0e1765e045 * I2PControl.cpp : SendResponse() third arg now std::string & 2016-05-26 00:09:25 +00:00
ebc411bbbd * I2PControl.cpp :
* use new http classes for building HTTP response
  * drop boost::lexical_cast & boost::local_time deps
2016-05-26 00:09:13 +00:00
a76d8f0f9f * HTTP.{cpp,h} : add add_header() variant with std::string 2016-05-26 00:08:04 +00:00
f245feb0b0 * HTTP.h : export MergeChunkedResponse() 2016-05-26 00:08:02 +00:00
43a90d7b98 * HTTP.cpp : fix parse_header_line (#501) 2016-05-26 00:08:00 +00:00
2e1a9a8df9 * HTTP.{cpp,h} : move length() method to base class 2016-05-26 00:07:57 +00:00
57bb0da1d6 correct LeaseSet message size 2016-05-25 18:47:16 -04:00
0d2df22074 fixed crash 2016-05-25 17:41:24 -04:00
c7173d5e1c use shared ClientDestination 2016-05-25 16:18:02 -04:00
789eb48698 removed deprecated constructor 2016-05-25 15:30:04 -04:00
e686fad546 rmoved deprecated constructor 2016-05-25 15:18:21 -04:00
4e4f9b6f8b use LocalLeaseSet for own LeaseSets 2016-05-25 15:10:28 -04:00
f2292fd618 LocalLeaseSet added 2016-05-25 14:17:34 -04:00
7035ead9e7 provide reply tunnel expcilitly for LeaseSet 2016-05-25 12:55:58 -04:00
f01f6e94d1 fix #500. check result of readline 2016-05-24 16:27:34 -04:00
f10064ce39 * HTTPServer.cpp : update response building 2016-05-24 12:40:24 +00:00
b68f06ca83 * update tests 2016-05-24 12:40:24 +00:00
2ce61402bb * HTTP.{cpp,h} * add 'body' member ot HTTPRes * change HTTPRes::to_string() to add 'Date', 'Content-Length' headers and body 2016-05-24 12:40:24 +00:00
70e9d85a75 * HTTP.cpp : add internal function gen_rfc1123_date() 2016-05-24 12:40:23 +00:00
a461f462d2 * HTTP.{cpp,h} : add HTTPMsg::{add,del}_header() helpers 2016-05-24 12:40:23 +00:00
50ff0d251a * HTTP.h : add base class HTTPMsg 2016-05-24 12:40:23 +00:00
f6103d3841 moved streaming and datagram destination from LeaseSetDestination to ClientDestination 2016-05-23 14:31:22 -04:00
cb68d19bed ClientDestination/LeaseSetDestination split 2016-05-23 10:33:01 -04:00
89d2505a7c * fix time in webconsole (#496) 2016-05-19 14:15:55 +00:00
9ddfc750e5 * update manpage: add --logfile description (#495) 2016-05-19 14:15:52 +00:00
3b80de1747 Merge pull request #494 from PurpleI2P/openssl
2.7.0
2016-05-18 09:23:55 -04:00
90ea714e48 version 2.7.0 2016-05-18 09:22:48 -04:00
f9e4182624 temporary disable 'reload config' item 2016-05-18 09:22:11 -04:00
0291cc2ef4 Merge pull request #493 from PurpleI2P/openssl
recent changes
2016-05-17 15:06:39 -04:00
caf2e469a6 remove mascot 2016-05-17 12:35:08 -04:00
45da2843ee Merge pull request #492 from weekendi2p/openssl
fix jumpservices uri
2016-05-16 20:10:51 -04:00
8353f928a1 fix jumpservices 2016-05-17 01:42:58 +02:00
9c1a6d042e Merge remote-tracking branch 'purple/openssl' 2016-05-16 16:04:48 -04:00
448b25a8b2 receive I2CP messages 2016-05-13 15:13:36 -04:00
4c2d4009da handle protocol byte 2016-05-12 16:17:10 -04:00
67f1e07508 I2CP added 2016-05-12 15:37:46 -04:00
c49fdf1233 initial commit for reload config command 2016-05-12 11:38:18 -04:00
7c835bae20 changed back to <openssl/ 2016-05-11 16:02:26 -04:00
ae81cc2644 windows doesn't support graceful shutdown yet 2016-05-11 15:33:53 -04:00
3907b4101a include openssl through OPENSSL macro 2016-05-11 15:12:38 -04:00
aa5ea0e3a1 support gcc 6 2016-05-11 11:57:02 -04:00
d21043802e Merge branch 'upstream' 2016-05-11 10:02:49 -04:00
995bdb3f9e Merge pull request #490 from majestrate/pr-fix-http-unit-tests-osx
add missing header to unbreak build
2016-05-11 09:36:27 -04:00
8363b4fda7 add missing header 2016-05-11 09:33:25 -04:00
23979f4ce6 Merge pull request #489 from majestrate/pr-fix-http-unit-tests-osx
fix http unit test SIGBUS in os x
2016-05-11 09:06:29 -04:00
28b5f39b84 fix http unit test SIGBUS in os x 2016-05-11 08:42:50 -04:00
47ce2398a4 fix http unit test SIGBUS in os x 2016-05-11 08:41:32 -04:00
0a83d8e6a0 Merge branch 'openssl' 2016-05-11 08:19:51 -04:00
aa215f2a5a regular/homebrew build selection for Mac OS X 2016-05-11 07:08:02 -04:00
b03a6a5327 Merge branch 'new-webconsole' into openssl
+ new http/url classes
* extract most page/cmd handlers from HTTPConnection class
* general cleanup of HTTPServer.{cpp,h}
+ http basic auth for webconsole
+ gracefull/quick shutdown commands
- drop direct access for b32 addresses from webconsole: use proxy instead
2016-05-11 01:29:47 +00:00
ca36a6fe41 update our IP after signture verification 2016-05-10 15:55:48 -04:00
bd6285c8b1 Merge pull request #487 from majestrate/fix-mac-build
fix mac build
2016-05-09 20:28:25 -04:00
00cfdc7d92 fix mac brew, use libressl and homebrew 2016-05-04 12:12:24 -04:00
5e2dc14dd5 get family string from local RouterInfo 2016-04-28 18:16:11 -04:00
c5f2890cbe Merge pull request #484 from weekendi2p/openssl
Show family name in web interface
2016-04-28 17:30:56 -04:00
36aaca997a Merge pull request #1 from PurpleI2P/openssl
sync
2016-04-28 20:21:27 +00:00
e9f7c61113 Merge pull request #483 from majestrate/fix-issue-482
try fixing issue #482
2016-04-27 12:23:15 -04:00
2373b94d3e try fixing issue #482 2016-04-27 12:08:08 -04:00
f131e31949 * HTTPServer.cpp: add request logging 2016-04-27 00:39:34 +00:00
8fd55a210a * HTTPServer.cpp: add 'Shutdown' commands 2016-04-27 00:39:34 +00:00
678650beaf * HTTPServer.{cpp,h}: basic auth 2016-04-27 00:39:34 +00:00
e09386be44 * add http.auth, http.user & http.pass options 2016-04-27 00:39:34 +00:00
75db2867dc * HTTPServer.cpp: protect SAM pages if disabled 2016-04-27 00:39:34 +00:00
80e37df012 * HTTPServer.{cpp,h}: change page/cmd processing flow 2016-04-27 00:39:33 +00:00
1f404bb622 * HTTPServer.cpp: move html parts outside HTTPConnection class 2016-04-27 00:39:33 +00:00
54078087e5 * HTTPServer.cpp: move common code to function 2016-04-27 00:39:33 +00:00
23b8df1c36 * HTTPServer.cpp: move commands to separate page 2016-04-27 00:39:33 +00:00
65395516b0 * HTTPServer.cpp: drop separate function handlers for commands 2016-04-27 00:39:33 +00:00
849308e28d * HTTPServer.cpp: drop boost::date_time dep 2016-04-27 00:39:24 +00:00
4d98a64000 * HTTPServer.{cpp,h}: extract html-rendering methods from class 2016-04-27 00:39:24 +00:00
0c8fdfca7d * HTTPServer.{cpp,h}: merge HandleWriteReply & Terminate : the same purpose 2016-04-27 00:39:24 +00:00
fd928e8d12 * HTTPServer.h: not virtual: not inherited anywhere 2016-04-27 00:39:24 +00:00
2a1fe99a29 * HTTPServer.{cpp,h}: drop rest of streaming support 2016-04-27 00:39:24 +00:00
4fa4ba6301 * HTTPServer.cpp: move known jump services to std::map 2016-04-27 00:39:24 +00:00
48b3959cfb * HTTPServer.{cpp,h}: cleanup 2016-04-27 00:39:24 +00:00
9bbff744e9 * HTTPServer.{cpp,h}: chg HandleRequest() signature 2016-04-27 00:39:24 +00:00
19b0c266f9 * HTTPServer.{cpp,h}: * extract css-styles to separate block * split /?page= from /?cmd= requests * cleaner html-template 2016-04-27 00:39:24 +00:00
fead940d10 * HTTPServer.{cpp,h}: * move query parsing code to one place * use /?cmd=X instead /?X * unified handler signatures 2016-04-27 00:39:24 +00:00
687e17ac52 * HTTPServer.{cpp,h}: throw away direct quering b32 addresses: use proxy 2016-04-27 00:39:12 +00:00
b1c85dcb74 * HTTPServer.{cpp,h}: throw away request/reply/url, use new impl 2016-04-27 00:39:12 +00:00
a15aad9f9c * unit-tests 2016-04-27 00:39:12 +00:00
06a1a8690d * add HTTP.{cpp,h} to build 2016-04-27 00:39:12 +00:00
42b9b6426a + new http req/res/url structs 2016-04-27 00:39:12 +00:00
332f0118a2 * rename namespace for http 2016-04-27 00:39:12 +00:00
6ed709d6e6 * HTTPServer.{cpp,h}: extract itoopie{Image,Favicon} from HTTPConnection (!) class 2016-04-27 00:39:12 +00:00
7a461c1684 * HTTPServer.{cpp,h}: move #include to one place 2016-04-27 00:39:12 +00:00
7cf171671d * HTTPConnection::reply : to_buffers() -> to_string() 2016-04-27 00:39:12 +00:00
ebee94fb11 removed 1 blank line.. 2016-04-27 01:19:27 +02:00
61e8becd38 wrong file version 2016-04-27 00:48:23 +02:00
a78caa2976 added SetFamilyString(); GetFamilyString() and shows family in webiface 2016-04-27 00:31:33 +02:00
c54f7c81c4 Merge pull request #480 from weekendi2p/openssl
new family: volatile
2016-04-26 13:06:58 -04:00
85840872ab family: volatile.crt 2016-04-26 19:39:10 +02:00
d582c30f6e allow same port at different interfaces 2016-04-24 17:32:24 -04:00
392f5f914a Merge remote-tracking branch 'purple/openssl' 2016-04-23 08:38:34 -04:00
799d25925a Merge pull request #478 from PurpleI2P/openssl
recent changes
2016-04-22 12:49:42 -04:00
4431d50635 limits.transittunnels 2016-04-20 15:02:11 -04:00
e120e9a78e configurable transit tunnels limit 2016-04-20 14:53:50 -04:00
b6e379d14e Merge pull request #475 from weekendi2p/openssl
added limits.transittunnels
2016-04-20 13:32:17 -04:00
9a86034162 limits options 2016-04-20 19:24:50 +02:00
8456c8b47b limits options 2016-04-20 19:22:04 +02:00
bb656ce44b added some limits options 2016-04-20 19:12:14 +02:00
3c2a3898e1 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-04-18 21:08:26 -04:00
c265bd6c4d delete pre-calculated tablle upon termination 2016-04-18 21:07:45 -04:00
aff65083cc precomputation.elgamal 2016-04-17 17:03:56 -04:00
aff8cd478c optional elgamal precomputation for x64 2016-04-17 16:57:58 -04:00
bce2a63772 rollback some changes 2016-04-14 14:05:25 -04:00
3f9d2601b4 + HTTPConnection::SendError() 2016-04-14 00:34:15 +00:00
04bfd52fba * HTTPConnection::SendReply() : cleaner code 2016-04-14 00:34:14 +00:00
87dd890eb0 * HTTPConnection::reply : to_buffers() -> to_string() 2016-04-14 00:34:13 +00:00
a5c0b48b57 * HandleDestinationRequestTimeout() : readable code 2016-04-14 00:34:11 +00:00
5d38693b4d * HTTPServer : fold namespace to two constants 2016-04-14 00:34:10 +00:00
a4773d259d * use std::to_string() instead boost's function 2016-04-14 00:34:08 +00:00
f9b6b1bf76 Merge pull request #473 from PurpleI2P/openssl
precalculate elgamal
2016-04-13 15:10:55 -04:00
ef106f3232 fixed typo 2016-04-13 11:22:08 -04:00
c0b0df34d2 clean montgomery context 2016-04-12 19:07:11 -04:00
d15cc7cc47 changed tray icon back to ictoopie 2016-04-11 12:39:32 -04:00
6336d38a3e Removed downloads. Added Docimentation 2016-04-11 12:04:15 -04:00
6a9d2ba653 use precalculated table for DH 2016-04-10 21:16:18 -04:00
34a8d4a57d use precalculated table for ElGamal encryption 2016-04-10 17:06:02 -04:00
ffc666eaaa g^x mod p using precalculated table 2016-04-09 22:44:13 -04:00
c45aab7cef precalculate g^x mod p table 2016-04-08 15:45:23 -04:00
eefff148e9 Merge pull request #470 from PurpleI2P/openssl
recent changes
2016-04-08 09:41:46 -04:00
05f7578928 Merge remote-tracking branch 'purple/openssl' 2016-04-08 09:39:09 -04:00
2ebb2d8f0e fixed race condition 2016-04-06 21:02:58 -04:00
afe2935c9d webconsole update 2016-04-06 16:33:23 -04:00
380c7b7720 use 226 bits private keys for non-x64 2016-04-06 16:11:18 -04:00
8657226594 use 226 bits private keys for non-x64 2016-04-06 15:49:46 -04:00
41da48f5ff Merge pull request #468 from PurpleI2P/openssl
recent changes
2016-04-06 12:27:15 -04:00
405aa906c5 short exponent for non-x64 2016-04-05 13:18:25 -04:00
1c507a47d2 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-04-05 10:22:35 -04:00
f48a7df80f recreate router.info if missing or malformed 2016-04-05 10:22:32 -04:00
5f73f09836 * RouterInfo::SaveToFile() now returns bool 2016-04-05 11:37:39 +00:00
f63dd75f08 * set bw limits thru i2pcontrol (#461) (experimental) 2016-04-05 11:37:25 +00:00
cc55335a8d * docs/configuration.md 2016-04-05 11:08:07 +00:00
b5875f3a0a * update year in copyrights 2016-04-05 11:08:05 +00:00
cb8333a48f * update manpage 2016-04-05 11:08:02 +00:00
f412f4ca88 * use commented i2pd.conf as default 2016-04-05 11:08:00 +00:00
941f30d1ea show streams from all streaming destinations 2016-04-04 22:17:04 -04:00
97afa502c5 shard_ptr for SAMSession 2016-04-02 22:16:49 -04:00
9ae9ea18e1 Merge remote-tracking branch 'purple/openssl' 2016-04-02 10:13:53 -04:00
0bf2abaa4c fixed race condition at startup 2016-04-02 08:57:35 -04:00
924f281536 * Don't set m_Session to nullptr in SAMSocket::Terminate
* check for null localDestination in SAMSocket::Terminate
2016-04-02 08:05:14 -04:00
1fc5dacd87 Merge pull request #464 from majestrate/master
Add locking to SAM
2016-04-01 12:56:30 -04:00
5c877de2c2 check if hosts is incomplete 2016-04-01 12:51:34 -04:00
751b95d4af add locking to SAM when adding/removing sockets 2016-04-01 11:36:56 -04:00
e0d5ba9915 Merge tag 'tags/2.6.0' 2016-04-01 10:57:22 -04:00
b8a6946661 Merge pull request #462 from PurpleI2P/openssl
2.6.0
2016-03-31 10:34:08 -04:00
e5fac08d1d release 2.6.0 2016-03-31 09:12:21 -04:00
df5b7c7d0d specify bandwidth for floodfill 2016-03-30 21:31:17 -04:00
27649f7d4c * update docs 2016-03-31 00:18:54 +00:00
350dea6228 * update --bandwidth option handling 2016-03-31 00:18:52 +00:00
aef6b7712c * Transports: update IsBandwidthExceeded() and comments in header 2016-03-31 00:18:49 +00:00
642bcfcdea * RouterContext : replace Set(Low|High|Extra)Bandwidth with SetBandwidth() 2016-03-31 00:18:46 +00:00
e625d8aabc * RouterInfo.cpp : remove .c_str() 2016-03-31 00:18:44 +00:00
5888ecbdcd * RouterInfo::UpdateCapsProperty() : add only one bw letter 2016-03-31 00:18:42 +00:00
e2a76056b8 * RouterInfo.h : add comments with bandwidth letter speed in KBps 2016-03-31 00:18:40 +00:00
a98498eb06 Merge remote-tracking branch 'purple/openssl' 2016-03-30 07:17:03 -04:00
8366c8d2a7 don't initiate graceful shutdown twice 2016-03-29 21:37:30 -04:00
ed8d441a02 Merge pull request #459 from PurpleI2P/add_exceptions
Adding exceptions on clients
2016-03-30 00:08:52 +02:00
f1fb265119 Adding exceptions for SOCKS, SAM and BOB proxy/briges 2016-03-30 00:03:15 +02:00
6c628094ce Adding exception handler on HTTP Proxy 2016-03-29 23:55:29 +02:00
a60c52e2f0 Merge pull request #454 from PurpleI2P/Travis_fixes
Adding working Travis build config for Linux Clang + OS X Clang / GCC
2016-03-29 19:25:23 +02:00
ac2e1709f8 graceful shutdown by SIGINT 2016-03-29 12:50:34 -04:00
db88183a23 graceful shutdown by SIGINT 2016-03-29 12:34:53 -04:00
c7d55ad858 Trying to fix broken builds on 10.7. Works fine on local 10.11 2016-03-29 16:01:07 +02:00
06a4e6c323 OSX worker already got boost and cmake installed 2016-03-29 15:30:06 +02:00
d1de89f387 Merge pull request #455 from PurpleI2P/openssl
recent changes
2016-03-29 09:20:54 -04:00
bbba01da92 OSX travis update (Test) 2016-03-29 15:09:40 +02:00
25dbf62274 Merge pull request #453 from manasb/openssl
update mca2-i2p.crt for correct CN
2016-03-28 18:17:02 -04:00
ed6851863b update mca2-i2p.crt 2016-03-28 18:08:11 -04:00
ba924e295e Merge pull request #452 from manasb/openssl
Rename i2p.crt to mca2-i2p.crt
2016-03-28 17:56:39 -04:00
0828065a62 Rename i2p.crt to mca2-i2p.crt 2016-03-28 17:51:24 -04:00
68c789dceb Merge pull request #451 from majestrate/master
fix failed build on freebsd 10.1
2016-03-28 17:36:25 -04:00
6424084502 Merge pull request #450 from manasb/openssl
i2p family cert file
2016-03-28 17:35:44 -04:00
4abea18afe Merge remote-tracking branch 'purple/openssl' 2016-03-28 17:16:05 -04:00
0a3c4f131e fix issue #449 failed build of freebsd 10.1 2016-03-28 17:15:27 -04:00
f5e1077e20 i2p family cert file 2016-03-28 17:05:39 -04:00
44d1c3fd2f Merge pull request #448 from xcps/openssl
default subscription address to inr, jump services b32
2016-03-28 14:42:21 -04:00
e345161763 default subscription address to inr, jump services b32 2016-03-28 14:33:55 -04:00
64d7c87591 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd 2016-03-28 12:26:09 -04:00
1fae3baaa3 * logger: print also thread id 2016-03-28 14:44:56 +00:00
38103aaac5 * logger: explicit allow log output 2016-03-28 14:44:54 +00:00
cc25b22f11 * update docs 2016-03-28 11:36:07 +00:00
e6dbeda18e * rename tunnels.conf -> tunnels.conf, add detection of old config 2016-03-28 11:36:05 +00:00
8437d45866 * rename i2p.conf -> i2pd.conf, add detection of old config 2016-03-28 11:35:49 +00:00
0bb89de821 Merge branch 'logs-refactoring' into openssl 2016-03-28 11:33:58 +00:00
905cad56d8 * add note 2016-03-28 06:02:56 +00:00
65eeb70eb3 Merge pull request #444 from i2phttp/openssl
Renamed i2pd.conf->i2p.conf with some fixes
2016-03-27 22:54:23 -04:00
266744f640 fixe memory leak 2016-03-27 12:06:00 -04:00
23d6739580 Renamed i2pd.conf->i2p.conf with some fixes 2016-03-27 16:27:36 +03:00
5c9970c786 delete packet if not saved 2016-03-27 09:16:30 -04:00
3eae716a2d * drop MsgQueue wrapper : not used anymore 2016-03-27 00:17:34 +00:00
c57b13d922 * migration 2016-03-27 00:17:29 +00:00
17fb419fb1 * new logs: code 2016-03-27 00:15:50 +00:00
598d0e216a * fix build requrements 2016-03-27 00:05:47 +00:00
7bbe926232 * use freopen() instead close()/open() : avoid potential fd leak 2016-03-27 00:05:47 +00:00
2e848a7c9a * chg default branch for 'dist' target 2016-03-27 00:05:47 +00:00
437225b43e * convert makefiles back to unix linefeeds 2016-03-27 00:05:47 +00:00
d39229713f lookup address upon request 2016-03-26 15:02:27 -04:00
93911be1b9 Merge pull request #441 from xcps/openssl
Sent/received traffic amount humanize
2016-03-26 10:34:53 -04:00
b74055478c Merge pull request #440 from majestrate/master
add syslog option for logging
2016-03-26 10:34:26 -04:00
8614c4db73 Sent/received traffic amount humanize 2016-03-26 10:32:19 -04:00
215d39fc54 address lookup 2016-03-26 10:31:47 -04:00
c4e5a130ee don't break win32 2016-03-26 09:49:45 -04:00
630072b574 Merge remote-tracking branch 'purple/openssl' 2016-03-26 09:41:31 -04:00
5261a3e845 add syslog logging option 2016-03-26 09:40:19 -04:00
0096a91a57 Merge pull request #439 from xcps/check_if_i2p_address
check if i2p address before call jump service
2016-03-26 02:48:17 -04:00
56699a9f89 check if i2p address to call jump service 2016-03-26 02:45:37 -04:00
31ff1372ae Merge pull request #438 from PurpleI2P/openssl
transort resolvers
2016-03-25 21:47:24 -04:00
3afb1922bb Update family.md 2016-03-25 16:04:44 -04:00
83c0a8b047 Merge pull request #437 from 0niichan/patch-8
Fixed b64 textarea in the webconsole
2016-03-25 11:53:22 -04:00
6699bd47b5 Fixed b64 textarea in the webconsole 2016-03-25 22:48:58 +07:00
34223b8d4f select appropritae address 2016-03-24 20:14:58 -04:00
5befe1f019 select appropritae address 2016-03-24 20:04:45 -04:00
87f86e72f4 Merge pull request #436 from majestrate/master
add option for toggling ipv4
2016-03-24 19:56:29 -04:00
53b7eba31a Merge branch 'master' of https://github.com/PurpleI2P/i2pd 2016-03-24 18:46:09 -04:00
12c12a8ad1 add no ipv4 option in config 2016-03-24 18:44:41 -04:00
897cc7d355 Merge remote-tracking branch 'purple/openssl' 2016-03-24 18:40:15 -04:00
2e5c56205c address resolver 2016-03-24 14:48:07 -04:00
bc5ff37e37 check for chunk size 2016-03-24 11:18:11 -04:00
20341a381f show version in the 'About' window 2016-03-24 11:05:47 -04:00
926b945846 * UPnP.h : comments 2016-03-24 10:32:20 +00:00
aa877a73ba * fix mistype 2016-03-24 10:32:18 +00:00
b28208d1bf 0.9.25 2016-03-23 19:03:17 -04:00
9bd97383bd don't connect to ipv6 address if not supported 2016-03-23 16:04:42 -04:00
522c7b2f9d Merge pull request #433 from 0niichan/patch-7
Fix height and width of the main window
2016-03-22 15:43:53 -04:00
1833c0acbc Fix height and width of the main window 2016-03-23 02:37:22 +07:00
c5644ee3f9 hold previous lookup response 2016-03-22 13:10:02 -04:00
447566fe14 gcc 4.8 2016-03-22 09:50:24 -04:00
9692c34f6c don't insert same address twice 2016-03-22 07:30:16 -04:00
37c450f1e1 fixed race condition 2016-03-21 15:13:07 -04:00
a003e396c5 fixed UPnP build 2016-03-21 13:45:35 -04:00
996f61efe1 use shared_ptr for Address 2016-03-21 13:02:51 -04:00
40cdcf8b06 Merge pull request #431 from PurpleI2P/openssl
recent changes
2016-03-21 10:54:02 -04:00
5947364846 updated reseeds list 2016-03-21 09:02:44 -04:00
9470107bba show mascot image 2016-03-20 18:34:29 -04:00
54b945511b Merge pull request #428 from 0niichan/0niichan-Fixed-Anke.ico
Fixed anke.ico
2016-03-20 17:02:52 -04:00
acfaa0041e fixed anke.ico 2016-03-20 17:01:20 -04:00
aeed2dbc3e Fixed anke.ico 2016-03-21 03:36:17 +07:00
0c6befe8a5 fixed build 2016-03-20 16:00:29 -04:00
bdcb26edae mascot bitmap added to resources 2016-03-20 14:58:35 -04:00
e091667b42 Merge pull request #426 from 0niichan/"Anke"-by-MilkHater,-the-I2Pd-mascot-1
"Anke" by MilkHater, the I2Pd mascot
2016-03-20 14:42:45 -04:00
d35b14f4cc "Anke" by MilkHater, the I2Pd mascot
700px .bmp and 2200px .jpg
2016-03-20 23:00:20 +07:00
87996c6811 Merge pull request #425 from 0niichan/"Anke"-by-MilkHater,-the-I2Pd-mascot
"Anke" by MilkHater, the I2Pd mascot
2016-03-20 09:52:27 -04:00
a880c733c8 "Anke" by MilkHater, the I2Pd mascot 2016-03-20 20:47:09 +07:00
ca10dfeb5f Merge pull request #424 from 0niichan/New-.ico-by-MilkHater
New .ico by MilkHater
2016-03-20 09:10:40 -04:00
91f55a637b New .ico by MilkHater 2016-03-20 20:02:04 +07:00
8ae43cfd14 Merge pull request #421 from l-n-s/openssl
Added example configuration file
2016-03-19 19:18:45 -04:00
83d9513c4a Added example configuration file 2016-03-20 01:39:35 +03:00
1c76d43e44 mention true/false values for bool params 2016-03-19 08:17:30 -04:00
1036ce0fa5 create addressbook before etags 2016-03-19 08:07:09 -04:00
3dbab68f17 don't send own RouterInfo twice 2016-03-18 22:53:03 -04:00
5896cebeaa list 'enabled' options 2016-03-18 13:35:33 -04:00
fbe629154d Merge pull request #418 from xcps/connection_strip
strip connection http header
2016-03-18 11:09:15 -04:00
364136213b extra space 2016-03-18 10:06:53 -04:00
136b663cef strip connection http header 2016-03-18 10:00:10 -04:00
803f11bebb local addresses 2016-03-16 15:40:29 -04:00
7c8036807a Cross compiling notes for Win32 target 2016-03-15 19:04:57 -05:00
84ccca0e98 read persistent ETags 2016-03-15 14:37:07 -04:00
74efdb95e8 persist etag 2016-03-14 22:00:05 -04:00
10e45ac493 Merge pull request #414 from mlt/fix413
Fix VS2013 build and close #413
2016-03-14 18:19:37 -04:00
60befdb36e VS2013 snprintf compatibility 2016-03-14 15:18:51 -05:00
59f99ea9bb Ask to minimize on Win32app close
This closes #413
2016-03-14 15:15:13 -05:00
1a894abcff persist etag for addressbook subscription 2016-03-14 16:05:57 -04:00
4934fc8809 fixed typo 2016-03-14 13:33:51 -04:00
18cc6a184f Merge pull request #412 from PurpleI2P/openssl
recent changes
2016-03-14 11:52:43 -04:00
0a08765d73 Win32: hide to tray, webconsole menu item
Standard icon works for me on Windows 8
2016-03-14 02:35:15 -05:00
355c7437ed supoort win32 console application 2016-03-11 22:24:23 -05:00
3c55c2d777 fixed race condition at startup 2016-03-11 19:27:43 -05:00
94806ad0b3 try subscriptions right after initial download 2016-03-11 16:29:49 -05:00
6840259734 Merge pull request #410 from xcps/jumpservice
jump services
2016-03-11 07:05:25 -05:00
a1fc48f2a6 Update HTTPServer.cpp 2016-03-11 16:16:11 +05:00
400e3d21f9 jump services 2016-03-11 15:30:50 +05:00
8f3daad502 Sane TTL for UPnP API>=14 and remove old miniupnpc support 2016-03-11 02:37:04 -06:00
b0395933de * Addressbook: fix module name 2016-03-11 00:46:58 +00:00
f8f2ab9cba fixed windows build 2016-03-10 19:34:32 -05:00
ae5f5375da Merge pull request #406 from mlt/msvc
Compatibility fixes for 64 bit MSVC build
2016-03-10 18:07:54 -05:00
ab5f1e712b AppVeyor msys fix attempt 2016-03-10 14:40:35 -06:00
4532ca97fa caffeine insomnia for win32 2016-03-10 14:20:46 -06:00
5a9ef57f78 Make mingw via cmake happy with _WIN32 in FS.CPP 2016-03-10 14:20:45 -06:00
8791f382b3 Make a deep copy of our addresses for UPnP
Somehow "Expression: vector iterators incompatible" gets thrown especially on fresh start
TODO: figure out details
2016-03-10 14:20:45 -06:00
abdef67ccc _WIN32_WINNT drove nuts 64 bit MSVC builds
TODO: figure out why
2016-03-10 14:20:44 -06:00
33494c4f4b Catch up for miniupnpc API 15 2016-03-10 14:20:43 -06:00
daad975f5d fixup! invoke win32app functions from main 2016-03-10 14:20:43 -06:00
18c00f0a4b Avoid debug symbol files (PDB) collision with MSVC 2016-03-10 14:20:41 -06:00
e7f46b4fbe Create missing directories on the way 2016-03-10 14:20:40 -06:00
74827cd8cf Workaround c++11 dynamic array for MSVC 2016-03-10 14:20:40 -06:00
5ffe1893cd reduce windows binary size 2016-03-10 14:46:45 -05:00
f24618e8df Merge pull request #409 from PurpleI2P/openssl
recent changes
2016-03-10 13:37:59 -05:00
0e5b32ef13 2.5.1 2016-03-10 13:34:16 -05:00
0493a321d2 oveeride --log for windows 2016-03-10 12:23:17 -05:00
38b6c12153 fixed bug with missed data directory 2016-03-10 12:05:28 -05:00
74d4b8e0b9 invoke win32app functions from main 2016-03-09 14:41:14 -05:00
f843d34234 Merge pull request #407 from PurpleI2P/openssl
recent changes
2016-03-09 13:41:55 -05:00
95b2bf3645 fixed windows build 2016-03-09 09:38:19 -05:00
121ac4f1de * move mingw-specific rules to Makefile.mingw 2016-03-09 13:36:39 +00:00
ec8550d587 use ictoopie_16 in tray 2016-03-08 21:18:48 -05:00
e403c419e5 16x16 icon added 2016-03-08 17:40:43 -05:00
4b0d587fe1 Daemon::run 2016-03-08 15:02:32 -05:00
ebd356c7bd set correct icons 2016-03-08 11:24:29 -05:00
507093dbad compile with resources 2016-03-07 21:36:11 -05:00
4cfdc77015 invoke daemon 2016-03-07 16:17:06 -05:00
9096cacba8 tray icon added 2016-03-07 16:06:34 -05:00
607336d3ce tray icon added 2016-03-07 15:57:32 -05:00
6383fc3575 initial commit of Win32App 2016-03-07 14:54:57 -05:00
a5576ddbf3 don't acquire DH keys pair until connection is established 2016-03-06 09:57:38 -05:00
e2a70873b8 fixed garbage in console for windows 2016-03-05 21:46:01 -05:00
23c7340afe Merge pull request #404 from PurpleI2P/openssl
2.5.0
2016-03-04 21:35:41 -05:00
380b56a89d 2.5.0 2016-03-04 21:34:23 -05:00
8e09f3478f fixed warnings 2016-03-04 20:35:53 -05:00
c1ce51eb12 Merge pull request #403 from xcps/webirc2
variable name
2016-03-04 09:53:52 -05:00
9aeb773169 variable name 2016-03-04 19:26:28 +05:00
091c13ff41 Merge pull request #402 from xcps/webirc2
WebIRC support
2016-03-04 07:05:37 -05:00
ef0bab0c6e webirc support 2016-03-04 11:37:38 +05:00
70bd16adf6 set established state for zero-hops tunnles 2016-03-03 17:57:15 -05:00
96a713afeb zero-hops outbound tunnels 2016-03-03 16:24:13 -05:00
bf3615fb32 Merge pull request #401 from PurpleI2P/openssl
recent changes
2016-03-03 10:31:04 -05:00
0f56b1c943 show number of received bytes for zero-hops inbound tunnel 2016-03-03 07:30:38 -05:00
d541572882 enable zero-hops inbound tunnel 2016-03-02 22:41:53 -05:00
ecfdc377ec send close floodfills only in DatabaseSearchReply 2016-03-02 19:46:32 -05:00
fa67e90767 inbound zero-hops tunnel 2016-03-02 16:12:02 -05:00
81b72d5481 fixed crash on termination if proxies were excluded 2016-03-02 12:04:02 -05:00
ef6028e933 replace std::map to std::list for inbound tunnels 2016-03-02 11:58:52 -05:00
5d41fe4a35 Merge pull request #400 from majestrate/webui-add-tunnel-count
Add Transit/Client Tunnel Count to web ui
2016-03-02 10:13:51 -05:00
1dc6cec1aa add client/transit tunnel count in webui 2016-03-02 10:05:26 -05:00
9378668e52 add colin 2016-03-02 10:03:50 -05:00
eb96ead80e add tunnel counts to front page of web ui 2016-03-02 10:03:36 -05:00
9403fbaf81 common tunnels' hash table 2016-03-01 20:48:56 -05:00
79190f313d use shared_ptr for transit tunnels 2016-03-01 15:22:36 -05:00
4c124284b6 Merge pull request #399 from PurpleI2P/openssl
irc tunnel and gzip
2016-03-01 13:39:26 -05:00
6d892179c8 added gzip parameter for server tunnels 2016-02-29 14:44:15 -05:00
61675c20d8 don't delete log file upon HUP 2016-02-29 11:02:55 -05:00
4aae878db8 increase LeaseSet expiration threshold 2016-02-28 21:43:18 -05:00
918884bd11 Merge pull request #398 from xcps/irc_ip2b32
irc tunnel
2016-02-28 16:19:19 -05:00
8799f9079b change part for replace 2016-02-29 02:15:29 +05:00
0b471cfd06 Merge pull request #397 from xcps/irc_ip2b32
Irc ip to b32
2016-02-28 14:14:11 -05:00
7b39a12396 ready 2016-02-28 22:32:34 +05:00
57a53b4b6c fixed I2PServerTunnelHTTP call 2016-02-28 21:13:01 +05:00
f6d0b3368f znx cert added 2016-02-28 09:56:17 -05:00
0fe7bdf849 init 2016-02-28 18:17:36 +05:00
a26dc39a6d ident fix 2016-02-28 18:17:35 +05:00
e45cfe7d0c init 2016-02-28 18:17:35 +05:00
efefa8caf5 Merge pull request #395 from PurpleI2P/openssl
socks outproxy
2016-02-27 16:16:15 -05:00
cc13db9b1f updated FreeBSD instructions 2016-02-27 15:44:36 -05:00
f339544256 Merge pull request #394 from majestrate/outproxy-socks
support for outproxy via local upstream socks proxy
2016-02-26 21:42:04 -05:00
1a05bcb295 initial support for out proxy via local upstream socks proxy 2016-02-26 17:06:11 -05:00
190e26276a reuse tunnel pair for LS request 2016-02-26 16:17:29 -05:00
bb33760e87 don't re-request twice 2016-02-26 16:16:59 -05:00
9e105b4983 Merge pull request #393 from PurpleI2P/openssl
recent changes
2016-02-26 15:13:31 -05:00
8dcf70408d hostoverride added 2016-02-25 20:32:05 -05:00
9d6d1825c7 pass flag to SSU header 2016-02-25 18:40:40 -05:00
1a4923cdce don't request relayTag if we are reachable 2016-02-25 15:57:58 -05:00
316e440390 Merge pull request #392 from PurpleI2P/openssl
recent changes
2016-02-25 13:51:03 -05:00
7d66019220 start checking for expiration after 10 minutes 2016-02-24 11:50:56 -05:00
f98a6fb665 tighten RouterInfo expiration 2016-02-24 11:31:14 -05:00
dbdc7279c4 Merge pull request #391 from PurpleI2P/openssl
new fs
2016-02-24 11:21:36 -05:00
7726705b5c process request relay tag extended SSU option 2016-02-23 12:16:53 -05:00
34b7e8815a Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-02-23 11:17:14 -05:00
8ac2b58a44 Merge branch 'master' of https://github.com/PurpleI2P/i2pd into openssl 2016-02-23 11:17:01 -05:00
fe97f0929b delete expired floodfills thorugh a separate loop 2016-02-22 20:51:32 -05:00
6eec353c2b moved tunnel config file inialization to ClientContext 2016-02-22 15:27:40 -05:00
2b4c3b8d1f start up if i2p.conf is not presented 2016-02-22 15:17:58 -05:00
df99b37c4d Merge pull request #388 from l-n-s/openssl
added family documentation
2016-02-22 13:45:29 -05:00
ab6f3fcf8e added family documentation 2016-02-22 20:49:17 +03:00
ca6f656e1b ignore non-reachable floodfills 2016-02-22 10:27:43 -05:00
88798b1a9e fixed windows build 2016-02-22 09:53:26 -05:00
c197270125 Merge branch 'new-fs' into openssl
Conflicts:
	Family.cpp
2016-02-22 13:04:53 +00:00
dc344d4658 * add comment 2016-02-22 12:57:25 +00:00
b4864831e0 Merge pull request #387 from PurpleI2P/openssl
family
2016-02-21 20:29:49 -05:00
476dffff13 Create family.md 2016-02-21 15:26:14 -05:00
389ee974f3 family 2016-02-20 21:20:21 -05:00
0d15eceacb * Profiling : move storage from FS.cpp to Profiling.cpp 2016-02-21 01:49:35 +00:00
b69fbdda9a * NetDb : move storage from FS.cpp to NetDb.cpp 2016-02-21 01:49:32 +00:00
d3746e0119 * FS.h : add include guards 2016-02-21 01:49:29 +00:00
230af9cafa set router's family 2016-02-20 20:20:19 -05:00
4db63d113c i2pd-dev certificate updated 2016-02-20 09:22:09 -05:00
008583396d extract CN 2016-02-20 08:33:13 -05:00
33a33e3c71 * i2p::util::http::GetHttpContent() : use std::transform instead boost 2016-02-20 01:47:34 +00:00
d312d753e9 * Destination.cpp : fix lambda with 4.7 2016-02-20 01:47:32 +00:00
02310d4af6 * Family : use i2p::fs::ReadDir instead direct boost::filesystem call 2016-02-20 01:47:29 +00:00
0e6d8c4e25 i2pd-dev family certificate added 2016-02-19 20:09:48 -05:00
55315fca80 Merge branch 'openssl' into new-fs
Conflicts:
	AddressBook.cpp
	NetDb.cpp
	filelist.mk
2016-02-20 00:59:48 +00:00
4eef9e780f extract and verify family from RouterInfo 2016-02-19 16:37:41 -05:00
7bfc3562af extract EcDSA key from family certificate 2016-02-19 16:13:46 -05:00
5b0b0d6d36 Merge pull request #386 from PurpleI2P/openssl
recent changes
2016-02-19 13:18:36 -05:00
cb64072f7b fixed windows build 2016-02-19 11:18:01 -05:00
c5b6da7201 case-insensitive http responses 2016-02-19 10:04:52 -05:00
f1d4818045 Family.cpp added 2016-02-18 22:39:09 -05:00
76b49f6985 uncompress stream by chunks 2016-02-18 22:34:55 -05:00
094d9193b9 start addressbook first 2016-02-18 22:34:14 -05:00
3053a9b6a0 enable i2p gzip compression 2016-02-18 20:35:14 -05:00
47bf0ef591 free pkey after usage 2016-02-18 16:28:43 -05:00
e2aa2709ac family added 2016-02-18 15:57:43 -05:00
9a6d478eb1 handle compressed addressbook 2016-02-18 13:19:31 -05:00
4f37e7dc3c Merge pull request #383 from PurpleI2P/openssl
recent changes
2016-02-18 09:06:48 -05:00
2a4ba8d349 * Addressbook : move storage init code from constructor to Init() : was too early 2016-02-18 10:42:50 +00:00
85bd7a63c6 * AddressBook : embed HashedStorage instance into AddressBookFilesystemStorage class 2016-02-18 10:42:50 +00:00
138d57143a * FS.cpp : add const to accessors 2016-02-18 10:42:50 +00:00
464a228106 * FS.cpp : rename method 2016-02-18 10:42:50 +00:00
2b92a039bb * FS.h : more comments 2016-02-18 10:42:50 +00:00
f190ee951c * use characters sets from Base.cpp - remove ABook class 2016-02-18 10:42:50 +00:00
68cc75cada * Base.cpp : add T32 character set + accessor 2016-02-18 10:42:41 +00:00
b4e324ec0e flood to 3 closest floodfills 2016-02-17 21:24:21 -05:00
32fe2e7974 correct monotonic expiration time calculation 2016-02-17 19:36:07 -05:00
713513aacc flood newer RI/LS only 2016-02-17 15:36:55 -05:00
b4ffca56a3 update lease's expiration time continiously 2016-02-17 13:10:29 -05:00
f2168774a5 check leaseset timestamp 2016-02-16 22:57:38 -05:00
febc00d357 fixed race condition of DeliveryStatus message 2016-02-16 16:10:22 -05:00
01a8c507e5 Merge pull request #381 from PurpleI2P/openssl
recent changes
2016-02-16 16:01:12 -05:00
bf7982cc2e build with make added 2016-02-16 15:08:35 -05:00
2e9689886b build with make added 2016-02-16 15:07:56 -05:00
2003b34036 12 hours expiration if more than 2500 routers 2016-02-15 21:40:49 -05:00
e1995b5c70 try to download default hosts.txt until success 2016-02-15 18:20:01 -05:00
3890acabc4 Merge pull request #380 from PurpleI2P/openssl
fixed http issues
2016-02-15 16:22:15 -05:00
ba6c0d0423 fixed messy http pages 2016-02-15 15:16:53 -05:00
882e7a845e process remaining data from stream 2016-02-14 22:10:56 -05:00
ca56d3fc23 handle LeaseSet expiration correctly 2016-02-14 18:30:07 -05:00
49b1e76585 use rtt for ack timeout 2016-02-13 23:10:51 -05:00
80f81685d1 use rtt for ack timeout 2016-02-13 23:02:58 -05:00
21dead3125 increase lease expiration threshold 2016-02-13 17:56:42 -05:00
1521d08285 family cetificates added 2016-02-13 17:13:07 -05:00
59b2e31add ssl certificates updated 2016-02-13 17:10:54 -05:00
b5feb3fd66 update reseeds list 2016-02-13 17:03:25 -05:00
7785e6ebd2 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-02-12 20:56:46 -05:00
c561d71dc0 count lease expiration threshold 2016-02-12 20:56:29 -05:00
2cfb697867 strip our Referer and replace User-Agent 2016-02-12 15:42:13 -05:00
c680ff006e Merge pull request #378 from PurpleI2P/openssl
recent changes
2016-02-12 11:23:29 -05:00
333103f50e shared RTT 2016-02-11 22:18:44 -05:00
517385fb63 Lease enddate threshold 2016-02-11 22:18:24 -05:00
ee8ab58d64 don't reply to lookup with expired LeaseSet 2016-02-11 22:17:33 -05:00
b967acda58 flood to floodfills that are close than us only 2016-02-11 15:05:46 -05:00
d81ca5f919 local destination leaseset storage verification 2016-02-11 14:45:33 -05:00
07adf64aec Merge pull request #376 from PurpleI2P/openssl
recent changes
2016-02-11 14:37:11 -05:00
fbb98e1aec show actual name of an invalid parameter 2016-02-11 11:18:15 -05:00
2fdf927704 show actual name of an invalid parameter 2016-02-11 10:54:36 -05:00
4b84656133 * i2p::fs migration: drop unused code from util.* (#314) 2016-02-11 13:05:00 +00:00
97c136d043 * i2p::fs migration: Daemon, DaemonLinux, api (#290) 2016-02-11 13:05:00 +00:00
79bf44b3f5 * i2p::fs migration: ClientContext, Destination, HTTPServer, Reseed, RouterContext 2016-02-11 13:05:00 +00:00
ddd8d4aeb2 * i2p::fs migration: AddressBook.* 2016-02-11 13:05:00 +00:00
bfcb6f577f * i2p::fs migration: Profiling.* 2016-02-11 13:05:00 +00:00
2b137b43e6 * i2p::fs migration: I2PControl.* 2016-02-11 13:05:00 +00:00
6d74493491 * i2p::fs migration: NetDb.* 2016-02-11 13:05:00 +00:00
6f4271c054 * update buildsystems 2016-02-11 13:05:00 +00:00
f24054100e * new i2p::fs implementation 2016-02-11 13:05:00 +00:00
6e98649607 * I2PControl: send valid error response, instead closing connection 2016-02-11 13:00:56 +00:00
b2108ff2d0 * fix flags on std::ifstream 2016-02-11 13:00:56 +00:00
8949ebf041 * tune logging 2016-02-11 13:00:56 +00:00
576801cd32 * Addressbook: load addresses at start, not on first request 2016-02-11 13:00:56 +00:00
2f2b12811f * Addressbook: don't save to disk if address map is empty 2016-02-11 13:00:56 +00:00
d8ea3a9035 * make target 'strip' 2016-02-11 13:00:56 +00:00
45c3b3987b reset floodfill 2016-02-11 07:50:29 -05:00
93720fffd4 shared path between streams 2016-02-10 22:51:08 -05:00
61ad6a2b88 set supported transports flag after actual address insertion 2016-02-10 16:09:34 -05:00
c9d5b3c0ff Merge pull request #373 from PurpleI2P/openssl
recent changes
2016-02-10 10:51:21 -05:00
d51bf735c4 * fix mistype 2016-02-10 10:37:30 +00:00
22c388ab18 * fix compilation with gcc 4.7/4.8 2016-02-10 10:37:30 +00:00
d5f831301f * explicit log message when bandwidth set to 'low' 2016-02-10 10:37:30 +00:00
dcab37a148 * update debian/i2pd.{init,upstart} : logging options 2016-02-10 10:37:30 +00:00
60b2da3671 * add --datadir option (not actually works yet) (#290) 2016-02-10 10:37:30 +00:00
5c1b5816d4 * fix segfault when offline (#330) 2016-02-10 10:37:30 +00:00
7a0a45e9d2 * use IsDefault() to check explicitly set values 2016-02-10 10:37:30 +00:00
70f72a78f6 + i2p::config::IsDefault 2016-02-10 10:37:30 +00:00
e056c9c135 drop expired leasesand renew leaseset 2016-02-09 22:42:01 -05:00
c754b5ae18 fixed crash 2016-02-09 17:54:22 -05:00
481fafc11d invalidate excluded leases 2016-02-09 15:27:23 -05:00
7d927b0e28 shared_ptr for Lease 2016-02-09 10:46:27 -05:00
c314b07136 Merge pull request #371 from PurpleI2P/openssl
recent changes
2016-02-09 10:37:46 -05:00
16fe13bf4a Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-02-08 20:30:53 -05:00
d19eda7e08 moved Config.cpp to libi2pd 2016-02-08 20:29:56 -05:00
6f0a136727 some cleanup 2016-02-08 20:29:34 -05:00
e2e101e4fb queue up out of sequence packets 2016-02-08 15:47:39 -05:00
74f03202b7 queue up out of sequence packets 2016-02-08 15:02:17 -05:00
3d19e92059 queue up out of sequence packets 2016-02-08 14:42:20 -05:00
bfff125cc5 Merge pull request #370 from PurpleI2P/openssl
recent changes
2016-02-08 14:41:40 -05:00
e90baf3ca6 correct required base64 buffer size 2016-02-07 21:35:06 -05:00
f3b277aeef doesn't store leases in netdb 2016-02-07 19:45:06 -05:00
76096747b6 cleanup incoming and outgoing tags together 2016-02-07 17:45:11 -05:00
4c6ef32d72 fixed #369 2016-02-06 08:52:02 -05:00
a8e12e624d fixed hanging connection 2016-02-05 21:38:03 -05:00
88a43bfc28 Merge pull request #368 from majestrate/fix_sam_b32_naming
allow resolving of .b32.i2p addresses in SAM name lookup
2016-02-05 16:37:00 -05:00
3b268fe3cc allow resolving of .b32.i2p addresses in SAM name lookup 2016-02-05 16:17:53 -05:00
4c72d43a8a use more efficient XOR over ChipherBlocks for win32 2016-02-05 15:58:14 -05:00
0a5f8527b2 Merge pull request #366 from majestrate/bug_fixes
Squash potential future bugs.
2016-02-05 13:12:08 -05:00
9f1b84d6f2 use const size_t instead of size_t 2016-02-05 12:39:17 -05:00
babcbcbcea use const size_t instead of size_t 2016-02-05 12:32:50 -05:00
823a6017fe Merge pull request #364 from 0niichan/patch-6
Added instructions for a 64-bit OS
2016-02-05 11:12:57 -05:00
f034aef2ae Added instructions for a 64-bit OS 2016-02-05 22:58:04 +07:00
bf38bd5a1d * Fill padding with random in NTCP phase3
* Fill padding with random in NTCPSession::CreateMsgBuffer

* Silence unused variable warnings in NTCPSession.cpp
2016-02-05 10:40:23 -05:00
b922809c9d Merge branch 'openssl' into bug_fixes 2016-02-05 10:20:22 -05:00
05b0bda8bb Merge remote-tracking branch 'purple/openssl' into openssl 2016-02-05 10:16:42 -05:00
0aa3aa1b8d Merge pull request #363 from majestrate/fix_su3_overflow
fix issue #362 , add bounds check to su3 fileNameLength
2016-02-05 10:03:34 -05:00
d4febb4e84 * bounds check on Identity::FromBuffer
* properly indet last commits
2016-02-05 08:52:07 -05:00
21090eaa39 forgot to commit Base.cpp changes 2016-02-05 08:46:08 -05:00
d0ea59c568 add base64 buffer encoding bounds checking 2016-02-05 08:44:09 -05:00
a292bc77ba fix issue #362 , add bounds check to su3 fileNameLength 2016-02-05 07:55:28 -05:00
98d5e0b56d #355. reopen log file by SIGHUP 2016-02-04 13:53:38 -05:00
7ca1cfab1a use shared_ptr for log's stream 2016-02-04 12:36:58 -05:00
2e7ce38552 compatibility with gcc 4.6 2016-02-04 12:36:54 -05:00
0ef3a2472d Merge pull request #361 from PurpleI2P/openssl
rebase master to 2.4.0
2016-02-04 10:08:17 -05:00
b97f095de4 Merge pull request #360 from AMDmi3/build-type
Do not force build type
2016-02-04 10:06:09 -05:00
10e2b35483 Merge pull request #359 from AMDmi3/system-include-dirs
Include system directories as SYSTEM
2016-02-04 10:00:47 -05:00
16920a89f3 Merge pull request #358 from AMDmi3/local-include-dirs-before
Always place local include directories before all others
2016-02-04 10:00:10 -05:00
1a5b9de82e Merge pull request #357 from AMDmi3/conditional-miniupnp
Do not try to use miniupnp if upnp support is disabled
2016-02-04 09:59:18 -05:00
4ef183fee6 Do not force build type 2016-02-04 16:53:24 +03:00
2115ce6606 Do not try to use miniupnp if upnp support is disabled 2016-02-04 16:52:41 +03:00
61d1b733f7 Include system directories as SYSTEM 2016-02-04 16:52:20 +03:00
4978edb8be Always place local include directories before all others 2016-02-04 16:49:07 +03:00
51f7aba807 fixed crash 2016-02-03 16:18:49 -05:00
b9b143e4e7 don't persist proxy keys by defualt 2016-02-03 15:29:15 -05:00
0e7596a205 Update build_notes_windows.md 2016-02-03 15:01:28 -05:00
8c401cf01b check for USE_AESNI=1 2016-02-03 15:00:55 -05:00
6782e6a532 AES-NI 2016-02-03 13:46:26 -05:00
4386bd93c3 handle USE_AESNI for mingw 2016-02-03 12:48:59 -05:00
72b3c10ebd * fix updating address in RI 2016-02-03 14:21:22 +00:00
62cec2a31c * correct shutdown of httpserver & socksproxy 2016-02-03 13:14:54 +00:00
0c442622af * chg default for --host= option : was broken in 900fc1c 2016-02-03 12:28:33 +00:00
bf3c4bc588 * bump version 2016-02-03 11:28:58 +00:00
d98dd83369 * sync actial options and docs (#356) 2016-02-03 11:28:55 +00:00
21ecf309bb * Daemon.cpp : --log option now uses descriptive values: file, stdout (#356) 2016-02-03 11:28:53 +00:00
4bb4012d87 * Daemon.cpp : move logs init to single place 2016-02-03 11:28:52 +00:00
10fd8eb709 * Daemon.cpp : move ParseCmdline() before use of i2p::fs -- allow redefined paths 2016-02-03 11:28:49 +00:00
b1cc1db967 fixed POST for server http tunnel 2016-02-02 22:00:51 -05:00
77d8bae2c2 fixed server http tunnel header 2016-02-02 19:24:49 -05:00
7274d43645 fixed incorrect long fragment size 2016-02-02 18:27:52 -05:00
3eeee1b08d set correct log level for console 2016-02-02 12:16:29 -05:00
64b2a32c9a #343. check for malformed messages 2016-02-02 11:55:38 -05:00
4ced1e5075 proccess loglevel and logfile correctly 2016-02-02 07:24:14 -05:00
8de15c9d0d fixed bandwidth logic 2016-02-01 18:10:45 -05:00
31d716bd0c fixed race condition 2016-02-01 14:19:54 -05:00
3da6b3930b * I2PControl.cpp : fix handling relative paths for cert/key 2016-02-01 15:57:25 +00:00
900fc1cb46 Merge branch 'new-cmdline' into openssl
Conflicts:
	ClientContext.cpp
	Daemon.cpp
	I2PControl.cpp
	I2PControl.h
	docs/configuration.md
2016-02-01 15:08:20 +00:00
deb87f1d4c * for compatibility - leave --log option with arg 2016-02-01 14:42:52 +00:00
ed44d23afb * update docs/ 2016-02-01 14:26:40 +00:00
8baf7f3f6a * temporary remove short options : conflicts with remapping 2016-02-01 14:26:26 +00:00
d2d4fa29e4 * add --logfile option 2016-02-01 10:53:17 +00:00
0c56cd63bd * chg default port for http proxy 2016-02-01 10:53:15 +00:00
c9cf84f2f4 correct SAM datagram size for Windows 2016-01-31 22:37:38 -05:00
0966369723 copy transit message for nedb 2016-01-31 18:27:47 -05:00
4f6c3d52b3 Merge pull request #354 from h0bbyte/openssl
I2PControl add total.sent|received.bytes
2016-01-31 15:55:47 -05:00
97f8ab5c51 Update build_notes_windows.md 2016-01-31 14:58:49 -05:00
8805f1e4d6 I2PControl add total.sent|received.bytes 2016-01-31 22:52:20 +03:00
3ae57e0ca9 Merge pull request #353 from 0niichan/patch-5
correct BOOST_SUFFIX
2016-01-31 14:20:11 -05:00
a8e4301f23 correct BOOST_SUFFIX 2016-01-31 23:59:37 +06:00
68bc78d00b Update README.md 2016-01-30 21:04:02 -05:00
1dc9e74df4 check TunnelBuild message size 2016-01-30 10:35:32 -05:00
a69cee03e5 remove coreVersion and stat_update 2016-01-29 22:35:51 -05:00
bf15ad3bba 0.9.24 2016-01-29 21:53:57 -05:00
bb3f50f967 Merge pull request #352 from 0niichan/patch-4
httpProxyPort 4444
2016-01-28 19:45:30 -05:00
1042e19845 httpProxyPort 4444 2016-01-29 07:18:49 +07:00
85830d5076 fixed race condtion #350 2016-01-27 22:09:35 -05:00
c053bebccd reduced numeber of error messages 2016-01-27 21:54:42 -05:00
d6d6ae8af2 * Config.cpp : add old options remapping (revert this after 2.6.0) 2016-01-27 12:17:41 +00:00
6d8b0e3a5d control logs destination through -log parameter 2016-01-26 22:30:00 -05:00
cfd7f1571b check clock skew 2016-01-26 19:02:06 -05:00
f31c04d92a Merge pull request #347 from evgkrsk/log-subdir
Write service log to separate directory
2016-01-26 09:53:09 -05:00
89b58ec3af Removed confusing accesslist 2016-01-26 09:45:29 -05:00
ab0d66c2ef Write service log to separate directory 2016-01-26 21:12:48 +07:00
9774865d4a * docs/configuration.md 2016-01-26 08:03:44 +00:00
3817a0c2a1 Merge branch 'openssl' into new-cmdline 2016-01-26 08:03:18 +00:00
5215bdc035 clean up remote destinations without outgoing and unconfirmed tags 2016-01-25 22:10:06 -05:00
8061d306dd check tunnel payload size 2016-01-25 14:31:51 -05:00
30f68759ff fixed race condition 2016-01-25 13:34:04 -05:00
3f0b595085 fixed typo 2016-01-24 22:24:39 -05:00
0c9ce6258c sockoutproxy params added 2016-01-24 09:59:02 -05:00
7da17ba21e * tune logs 2016-01-24 12:41:08 +00:00
7b23d79dc2 * util.cpp : update Get*ConfigFile() : autodetect configs 2016-01-24 11:14:19 +00:00
415314a90d * update docs 2016-01-24 11:14:19 +00:00
0f7e2ad11a * Daemon_Singleton::init : rewrite setting bandwidth limit and floodfill mode 2016-01-24 11:14:19 +00:00
26d232c567 * Daemon_Singleton::init : unwrap spagetti-code 2016-01-24 11:14:19 +00:00
efa48a7e39 * tune logs 2016-01-24 11:05:16 +00:00
022642f4d5 * Config.cpp : don't try to parse config, if path is empty 2016-01-24 11:04:41 +00:00
e6e2f04a10 * Config.cpp : set default value for boolean options 2016-01-24 11:04:15 +00:00
f7e21dbe5c show tags for local destinations 2016-01-23 22:53:19 -05:00
f593802a51 I2CP option crypto.tagsToSend added for I2P tunnels 2016-01-23 20:52:21 -05:00
f545e6eb27 Merge pull request #340 from al42and/openssl-boost-asio-check
Better checking if boost::asio::buffer works with std::array
2016-01-23 13:53:12 -05:00
1778d82bc3 Better checking if boost::asio::buffer works with std::array
Otherwise, had troubles with clang 3.4 and boost 1.54
2016-01-23 17:36:06 +03:00
03587d7035 changed data path back to AppData/Roaming 2016-01-22 10:56:25 -05:00
6663788612 fixed some coding style 2016-01-22 07:08:21 -05:00
ac2cb773df * I2PControl.cpp : tune logs 2016-01-22 12:04:14 +00:00
b70b3ec85b * I2PControl : drop I2P_CONTROL_ID* vars : ugly 2016-01-22 12:04:11 +00:00
1e69b8c41d Merge pull request #335 from xcps/http_remove_referer
Http remove referer
2016-01-22 07:00:44 -05:00
d5aa1a4880 * use GetOption instead hardcoded values in header * move cert/key from $DATADIR/i2pcontrol/ to $DATADIR/ 2016-01-22 11:59:15 +00:00
de0658eaab * I2PControlService::CreateCertificate : use function parameters instead direct GetPath calls 2016-01-22 11:59:13 +00:00
939c28b74b removed extra lines 2016-01-22 16:30:24 +05:00
o
c10d628a45 Merge branch 'openssl' into http_remove_referer 2016-01-22 16:13:12 +05:00
o
92830172f9 asdf 2016-01-22 16:08:54 +05:00
431af2c0dd fixed issue #331. reuse existing local detination for tunnels 2016-01-21 15:51:08 -05:00
97ca8b7ada * fix build 2016-01-21 12:59:00 +00:00
f3a7c233b3 * I2PControl.cpp : #329 2016-01-21 12:40:07 +00:00
928abf7094 - I2PControlService::LoadConfig : not used anymore 2016-01-21 07:46:17 +00:00
2cace0008e - I2PControlService::SaveConfig : not used anymore 2016-01-21 07:41:09 +00:00
db9c20f3dd * I2PControl : move boost1.49+gcc4.7 hack 2016-01-21 07:38:11 +00:00
e1a1aef990 * I2PControl : use password option from main config 2016-01-21 07:37:38 +00:00
23cf6ebc89 * add new option 'i2pcontrol.password' 2016-01-21 07:35:26 +00:00
55c279cc7e Rolled back to working Makefile.mingw 2016-01-20 21:51:18 -05:00
4e89f90c4f Merge pull request #328 from 0niichan/patch-3
add "mkdir obj/Win32" in Windows
2016-01-20 16:01:38 -05:00
bd0eb81c1b add "mkdir obj/Win32" in Windows 2016-01-21 03:52:13 +07:00
a77a0d98e0 Merge pull request #327 from 0niichan/patch-2
new default boost' suffix; new paths
2016-01-20 14:16:44 -05:00
e5037fc9f9 new default boost' suffix; new paths 2016-01-21 02:05:16 +07:00
7ac2022159 Merge pull request #326 from 0niichan/patch-2
Update Makefile.mingw
2016-01-20 13:39:53 -05:00
bc41a15eba Update Makefile.mingw
new default boost' suffix; new paths
2016-01-21 01:33:28 +07:00
8aa158c1e0 * update debian/ 2016-01-20 11:32:12 +00:00
1f6f4d9c49 + docs/config_opts_after_2.3.0.md 2016-01-20 11:31:07 +00:00
3686a27c19 * update docs/configuration.md 2016-01-20 11:31:04 +00:00
1bcc311738 - drop i2p::util::config namespace : not used anymore 2016-01-20 11:30:09 +00:00
2335d3879e * migrate to new settings 2016-01-20 11:29:54 +00:00
209934ad67 * update buildsystems to include Config.cpp 2016-01-20 11:29:38 +00:00
35200a1ee5 + new cmdline & config impl 2016-01-20 11:28:57 +00:00
6c4977ee78 * tune log messages 2016-01-20 11:25:43 +00:00
5482a57c45 add clock skew to expiration 2016-01-19 11:16:50 -05:00
18914978d5 pass X-I2P_DestB32 and X-I2P-DestB64 2016-01-19 09:36:56 -05:00
36750ab900 * DaemonWin32 : separate --service (boolean) from --svcctl (string) option 2016-01-19 11:07:25 +00:00
c5f6a690de * Daemon.h : use boolean variables for flags 2016-01-19 11:07:23 +00:00
9611f80a39 check I2NP messages fro expiration 2016-01-18 21:13:43 -05:00
eb2d68fc28 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-01-18 10:29:37 -05:00
937d346676 set clove expiration time interval to 8 seconds 2016-01-18 10:29:07 -05:00
7565843fbe * move ReadConfigFile() : i2p::filesystem -> i2p::config * don't export i2p::config::mapArgs outside namespace 2016-01-18 09:05:03 +00:00
6740ec464c * unwrap i2p::util::config::* calls in Daemon.cpp 2016-01-18 09:04:25 +00:00
314e1e4bfe * unwrap i2p::util::config::* calls in ClientContext.cpp 2016-01-18 09:04:25 +00:00
45d68d89a9 * clean outdated declaration 2016-01-18 09:03:35 +00:00
1d5194a138 * drop mapMultiArgs : it's not used anywhere 2016-01-18 09:03:06 +00:00
05043f30dc * tune logs 2016-01-18 09:02:34 +00:00
cd549937c5 support multiple server tunnels with same destination and different ports 2016-01-17 18:55:09 -05:00
efdea07b7b change message expiration timeout to 8 secs (RTT) 2016-01-17 18:03:40 -05:00
06d4998d87 Merge pull request #323 from zenjy/openssl
Misc fixes
2016-01-17 14:38:27 -05:00
02b566055e * HTTPServer.cpp: add space after "Queue size:" 2016-01-17 18:18:21 +00:00
c312dbaac1 * Daemon.h: replace "#pragma once" with "#define" 2016-01-17 18:13:36 +00:00
b6dcb2f4c0 show streams as table (byt sha-db) 2016-01-17 11:10:56 -05:00
a85d3f2573 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2016-01-16 15:36:58 -05:00
0ca3fb5af0 specify and check netId 2016-01-16 15:36:30 -05:00
2a4d78d9bf wordwrapping (by sha-db) 2016-01-16 15:36:26 -05:00
d9e199092d fixed race condition 2016-01-15 16:23:03 -05:00
02bbb46d2e separate keys and destination creation 2016-01-15 14:46:29 -05:00
13ffdc6dd2 common ReadI2CPOptions 2016-01-15 12:24:40 -05:00
c8c2c4d376 Merge pull request #321 from scrrrapy/fedora-docs
Fedora/Centos docs to build from source
2016-01-15 07:13:38 -05:00
01f7343781 added instructions to build on Fedora/Centos 2016-01-15 03:14:44 +00:00
3acc244692 reordered unix targeted documentation to be more user-friendly
Also fixed wrong build root.
2016-01-15 03:14:40 +00:00
094068e4ff Merge pull request #320 from 0niichan/patch-1
Update util.cpp
2016-01-14 19:46:24 -05:00
ec958697e2 Update util.cpp
change i2pd home data path for Windows
2016-01-15 07:44:26 +07:00
208e8f8247 new webconsole style by sha-db 2016-01-14 19:05:46 -05:00
3d4890a28b handle I2CP keys correctly 2016-01-14 18:45:47 -05:00
fe4362f459 tunnel parameters 2016-01-14 15:57:55 -05:00
81d3ad2d35 Update README.md 2016-01-14 11:06:05 -05:00
ffb8c3e53c Update README.md 2016-01-14 07:47:58 -05:00
2d4d2374e3 Update README.md 2016-01-14 07:47:04 -05:00
09f31a9278 Merge pull request #319 from scrrrapy/travis-ci
Travis-CI integration
2016-01-14 07:19:40 -05:00
80b0a3cdec fixed travis badge branch 2016-01-14 10:16:42 +00:00
c533bfc83d integration with travis-ci 2016-01-14 02:45:06 +00:00
8fa053f7c7 show I2P tunnels at web console 2016-01-13 20:21:53 -05:00
b152bb26e3 more parameters 2016-01-13 09:42:06 -05:00
a0816b04e5 purple links, coloured tunnels 2016-01-12 20:31:25 -05:00
0819517902 * Addressbook : readable http-req assembly 2016-01-12 23:34:59 +00:00
55ea8c82e9 * Addressbook : logging 2016-01-12 23:32:32 +00:00
ffbbf88de4 * DaemonLinux : restore old behaviour: always write pidfile by default, but allow override path 2016-01-12 23:31:01 +00:00
e2ff49825f favicon added 2016-01-12 13:18:01 -05:00
7f325827c4 Merge pull request #317 from l-n-s/openssl
Prepare documentation for Read the docs
2016-01-12 11:30:16 -05:00
cae9ccfda1 version 2.3.0 2016-01-12 10:14:22 -05:00
248ae7d4d5 do nothing upon SIGHUP for now 2016-01-12 10:12:55 -05:00
7f08bbe938 handle -pidfile parameter correctly 2016-01-12 10:00:17 -05:00
81b2f2114d purplei2p webconsole style(by sha-db) 2016-01-12 09:36:01 -05:00
5eee430be3 fixed typo 2016-01-12 09:34:46 -05:00
623edf3bc9 Tuning docs for Sphinx 2016-01-12 07:18:17 +03:00
bd4a224051 Added Sphinx documentation files 2016-01-12 07:03:29 +03:00
870e84a700 new webconsole layout (by nda) 2016-01-11 22:05:10 -05:00
8d4fae24ea fixed misalignment 2016-01-11 19:03:04 -05:00
7a84daf3f7 temporary disable openssl mutexes 2016-01-11 17:37:20 -05:00
7968279bc2 send X-I2P-DestHash 2016-01-11 13:48:18 -05:00
258be40285 notransit parameter added 2016-01-11 11:08:06 -05:00
b2ae30eba1 * fix cmake output library name (#315) 2016-01-11 11:31:55 +00:00
daaba1dbc0 * prevent zero-division exception when running offline 2016-01-11 11:31:02 +00:00
a3c6ed4dd2 * fix warnings from -Wunused-result 2016-01-11 11:31:02 +00:00
e4255ed712 + add --pidfile cmdline option 2016-01-11 11:31:02 +00:00
5d510f1cf4 * DaemonLinux : set umask to 0027 instead 0000 2016-01-11 10:55:50 +00:00
1819bd910a * add log message when fork failed 2016-01-11 10:55:18 +00:00
43eecdbb3f * update default tunnels.cfg 2016-01-11 02:55:21 +00:00
108c1bcac4 * update docs/configuration.md 2016-01-11 02:52:16 +00:00
4b7e5864d4 * cleanup default config file 2016-01-11 02:52:00 +00:00
fb1d2abbfa * cleanup manpage 2016-01-11 02:51:35 +00:00
0c290e65ef removed deprecated parameters 2016-01-10 21:39:29 -05:00
5487fad2ce fixed race conditin 2016-01-10 18:55:00 -05:00
d41f930f69 fixed unintialized reply key 2016-01-10 16:40:28 -05:00
595b2619fd fixed misalignment for timestamp 2016-01-09 19:24:52 -05:00
26d305d866 fixed misalignment of certificate length 2016-01-09 17:26:17 -05:00
c9d95ff161 eliminate one extra multipilication 2016-01-08 10:21:43 -05:00
9cc592b564 correct buffer size for deflate 2016-01-05 14:50:45 -05:00
ff48422ec0 check I2NP message buffer size 2016-01-05 14:29:18 -05:00
a26c5f85c3 ignore LeaseSets coming from transit tunnels 2016-01-04 19:56:46 -05:00
727436e1cf specify signature type for I2P tunnels 2016-01-03 21:43:43 -05:00
d1c57a1872 New bandwidth values 2016-01-03 19:15:12 -05:00
b7c021af8c clear extra bandwidth bit 2016-01-03 09:54:03 -05:00
7149b509d7 extra bandwidth caps 2016-01-02 22:17:04 -05:00
45e7111dda publish stats for floodfill 2016-01-02 17:23:20 -05:00
9fc69db9eb reserve extra 16 bytes for padding 2016-01-01 17:39:12 -05:00
2ba314d9d9 count checksum and padding for buffer size 2016-01-01 15:41:18 -05:00
f35660c8e2 fixed windows build 2016-01-01 08:30:38 -05:00
68b1fe8631 use TUNNEL_DATA_ENCRYPTED_SIZE for tunnel encryption 2015-12-31 19:46:14 -05:00
4242c86d40 check for buffer overflow during flood 2015-12-31 17:09:04 -05:00
ef4dc3cbc9 fixed race condition of openssl calls 2015-12-31 16:02:10 -05:00
8daa7561fa pass ident hash by values to RequestComplete 2015-12-31 11:21:01 -05:00
2cc3dfc2ce fixed windows build 2015-12-28 12:26:10 -05:00
459800568a fixed windows build 2015-12-28 11:55:55 -05:00
3a35b84b03 fixed FreeBSD build 2015-12-28 10:52:02 -05:00
79cfa52bf9 fixed windows build 2015-12-28 08:30:40 -05:00
a0e8fe5848 * implement --loglevel option 2015-12-28 10:54:00 +00:00
2dae5bccb2 * util.cpp : reorder defines 2015-12-28 10:54:00 +00:00
8e867ab0c0 * util.cpp : reorder defines 2015-12-28 10:54:00 +00:00
1b2c88fe38 * drop i2p::util::config::GetCharArg 2015-12-28 10:54:00 +00:00
f3bee5ff3f * log message fix 2015-12-28 10:53:48 +00:00
196d7e8f72 send correct RouterInfo statistics 2015-12-26 09:41:12 -05:00
16596c18fb log max packet size 2015-12-23 20:47:44 -05:00
7ea3a87bfc * missing initializer for member ‘i2p::transport::Peer::delayedMessages‘ 2015-12-24 00:55:53 +00:00
a57905b6cd * merged branch 'sane-log-messages' 2015-12-24 00:46:32 +00:00
f9c592ca22 static link against libgcc, libstdc++ and libwinpthread 2015-12-23 10:24:10 -05:00
aecac0ef85 * bump version in debian/changelog 2015-12-23 01:32:01 +00:00
ca315c51a0 version 2.2.0 2015-12-21 20:49:27 -05:00
45c8858140 persist temporary keys 2015-12-21 10:17:00 -05:00
06e45bff24 removed unused parameter 2015-12-21 09:33:09 -05:00
2635a658d0 Fix missing cached openssl in appveyor 2015-12-20 22:57:55 -06:00
f48a98f691 * disable AESNI by default for .deb package (#312) 2015-12-21 03:48:35 +00:00
3badda95c1 * reseed now https only 2015-12-21 03:46:35 +00:00
364ccc05d5 * Log.h: drop unused template 2015-12-21 03:00:12 +00:00
d09fedf208 * sane log messages: TransitTunnel.cpp 2015-12-21 03:00:12 +00:00
7936f8730f * sane log messages: Reseed.cpp 2015-12-21 03:00:12 +00:00
6c0dfc4356 * sane log messages: Log.cpp 2015-12-21 03:00:12 +00:00
d9af8c31a2 * sane log messages: LeaseSet.cpp 2015-12-21 03:00:12 +00:00
ca375314f0 * sane log messages: Identity.cpp 2015-12-21 03:00:12 +00:00
5266d4d79c * sane log messages: RouterInfo.cpp 2015-12-21 03:00:12 +00:00
1cb0826de0 * sane log messages: SSUData.cpp 2015-12-21 03:00:12 +00:00
89e3178ea3 * sane log messages: HTTPServer.cpp 2015-12-21 03:00:12 +00:00
3b5d9d6cee * sane log messages: RouterContext.cpp 2015-12-21 03:00:12 +00:00
ce4ed19029 * sane log messages: SSU.cpp 2015-12-21 03:00:11 +00:00
01a502339c * sane log messages: api.cpp 2015-12-21 03:00:11 +00:00
642d0e6f74 * sane log messages: Streaming.cpp 2015-12-21 03:00:11 +00:00
d9e659deb0 * sane log messages: Destination.cpp 2015-12-21 03:00:11 +00:00
830fe7f9b8 * sane log messages: Transports.cpp 2015-12-21 03:00:11 +00:00
3e8c247c05 * sane log messages: ClientContext.cpp 2015-12-21 03:00:11 +00:00
16880074fa * sane log messages: DaemonWin32.cpp 2015-12-21 03:00:11 +00:00
19c74ce9fa * sane log messages: DaemonLinux.cpp 2015-12-21 03:00:11 +00:00
56ef0dad9c * sane log messages: Daemon.cpp 2015-12-21 03:00:11 +00:00
8d99808821 * sane log messages: I2PTunnel.cpp 2015-12-21 03:00:11 +00:00
1cb08fdecc * sane log messages: util.cpp 2015-12-21 03:00:11 +00:00
e8952d7e02 * sane log messages: TunnelPool.cpp 2015-12-21 03:00:11 +00:00
18fad9c9d9 * sane log messages: Garlic.cpp 2015-12-21 03:00:11 +00:00
89a0a94f3e * sane log messages: SAM.cpp 2015-12-21 03:00:11 +00:00
0859cf30f8 * sane log messages: UPnP.cpp 2015-12-21 03:00:11 +00:00
a0fe02a560 * sane log messages: BOB.cpp 2015-12-21 03:00:11 +00:00
3156f7dacd * sane log messages: Tunnel.cpp 2015-12-21 03:00:11 +00:00
c3958bf042 * sane log messages: NTCPSession.cpp 2015-12-21 03:00:11 +00:00
facc5f8aa7 * sane log messages: SSUSession.cpp 2015-12-21 03:00:11 +00:00
8170257c26 * sane log messages: AddressBook.cpp 2015-12-21 03:00:11 +00:00
489e37b2a1 * sane log messages: NetDb.cpp 2015-12-21 03:00:11 +00:00
4899e0d2d5 * sane log messages: I2NPProtocol.cpp 2015-12-21 03:00:11 +00:00
762f9c4b23 Merge pull request #308 from mlt/openssl-cmake
Cleaned up appveyor CI along with MSVC & mingw builds
2015-12-20 13:38:12 -06:00
6d3dac0ec1 Windows build status badge update in README.md 2015-12-19 22:19:06 -06:00
f684815272 Build miniupnpc.dll on Appveyor 2015-12-19 22:19:05 -06:00
8e04218c95 Install optional miniupnpc.dll if exist 2015-12-19 22:19:04 -06:00
23cb45454b Set default install folder for CMake based NSIS 2015-12-19 22:19:02 -06:00
7fc9a161b1 Default NSIS template from CMake 2015-12-19 22:19:01 -06:00
95a5473051 Initial CMake based packaging 2015-12-19 22:19:00 -06:00
66ceb573dc Update Windows build docs 2015-12-19 22:18:59 -06:00
5f8223ebb5 Patch for 64-bit zlib build with MSVC assembly 2015-12-19 22:18:58 -06:00
51146d4152 MSVC optimization & hardening 2015-12-19 22:18:57 -06:00
3334281949 Search for patch tool with CMake
This is to enable static build of "bundled" zlib with MSVC
2015-12-19 00:03:32 -06:00
8e85d9ac00 Sync Windows VERSIONINFO resource with version.h 2015-12-19 00:03:31 -06:00
e1c69a6250 Transparency in icon 2015-12-19 00:03:30 -06:00
edd9a18257 Cleanup some CMake msys specifics
* Exclude MSYS from -z relro
* WIN32_LEAN_AND_MEAN
2015-12-19 00:03:28 -06:00
65f993677f Remove unnecessary thread & chrono Boost libs
Prevent boost thread auto-link erroneous attempts with MSVC
2015-12-19 00:03:27 -06:00
bc775140bb appveyor.yml 2015-12-19 00:03:26 -06:00
4b2bd6e18f Include dir for precompiled headers with gcc 2015-12-19 00:03:24 -06:00
c36a810bcb ignore extended options for SessionCreated and SessionConfirmed 2015-12-18 11:52:44 -05:00
a994bbc36b call CryptoConstants from Crypto.cpp only 2015-12-18 10:09:25 -05:00
c3238f4d0b * fix warnings of type mismatch (#298) 2015-12-17 08:10:17 +00:00
632d26e398 * update maintainer scripts 2015-12-17 07:16:26 +00:00
214cc8b810 * install reseed certs 2015-12-17 05:00:03 +00:00
8f218141f4 * add 'i2pd' user (#313) 2015-12-17 04:39:08 +00:00
3676304751 * provide default subscriptions.txt 2015-12-17 04:39:08 +00:00
c605fd57aa * AddressBook.cpp : mistype in log message 2015-12-17 04:39:08 +00:00
4599f6919c shared_ptr for local destination in TunnelPool 2015-12-16 14:52:48 -05:00
8ad20c0db3 * allow parallel builds (#310) 2015-12-16 01:12:14 +00:00
638a69e5f0 * fix comments in default config (#311) 2015-12-16 00:19:52 +00:00
9fa6b1ebe1 keep pending incoming streams if acceptor is not set 2015-12-14 22:36:23 -05:00
5930e2d221 keep pending incoming streams if acceptor is not set 2015-12-14 22:23:28 -05:00
fdd96975fb cancel destination request 2015-12-13 14:40:43 -05:00
de6dd77046 use shared_ptr for LeaseSet request 2015-12-13 10:51:43 -05:00
1b6ad8413e spread addresses between subdirectories 2015-12-11 15:48:33 -05:00
6096d572f3 handle RelayResponse 2015-12-09 22:17:43 -05:00
badcd64b62 print full tunnel path 2015-12-09 19:07:12 -05:00
a7b8b52dbd fixed crash 2015-12-09 18:01:42 -05:00
d89f0f51df show full tunnel path 2015-12-09 10:35:04 -05:00
be358f3f2e enable RI catch for OBEP back 2015-12-09 10:03:51 -05:00
f122da1485 change and save I2PControl password 2015-12-08 10:40:43 -05:00
0dda4728b6 * update README 2015-12-08 12:18:25 +00:00
45fd95e02b * update default/i2pd and traditional init script 2015-12-08 11:38:28 +00:00
91aa2d7f6f + add example config files 2015-12-08 11:38:28 +00:00
a96b7d2a80 * drop patch not needed anymore 2015-12-08 11:38:28 +00:00
8f9cea54c5 * rename main binary 2015-12-08 11:38:28 +00:00
045558bede correct path to openssl 2015-12-06 22:48:08 -05:00
58124ebaab * update debian/docs 2015-12-05 11:55:27 +00:00
0c87dd5624 * added debian/logrotate (thanks to kytv) 2015-12-05 11:55:27 +00:00
b87f986a49 * added manpage (thanks to kytv) 2015-12-05 11:55:27 +00:00
c6a6035bb9 * debian/control : compat level -> 9 2015-12-05 07:56:51 +00:00
1ef12f0645 updated reseeders list 2015-12-04 14:59:31 -05:00
ef3ec33ba3 create all subdirectories for non-case sensitive systems 2015-12-04 14:06:37 -05:00
c82ef1ee8f link against openssl for Mac OS X 2015-12-04 13:19:08 -05:00
23b8a60242 Appveyor status badge 2015-12-03 23:39:09 -06:00
ac9511165e Merge pull request #307 from mlt/openssl-cmake
Better CMake support for MSVC builds
2015-12-03 23:35:14 -06:00
9d70851eb9 Respect static for zlib with CMake 2015-12-03 23:23:26 -06:00
759dfb28ce Increase PCH heap limit for MSVC 2015-12-03 23:07:31 -06:00
ff356b1f21 Use assembly language when building zlib for MSVC++ 2015-12-03 23:07:30 -06:00
b2a6c1bc68 fixup! read Content-Length from http header
MSVC++ complains on ssize_t
2015-12-03 23:07:29 -06:00
76549d0a4a Fix win32 resource compilation with msys
squash! Fix win32 resource

winres.h is missing for mingw
2015-12-03 23:07:27 -06:00
e5c72cae83 Fix CMake stuff for msys2 2015-12-03 23:07:26 -06:00
bf47df46c9 allow DNS names for SSU 2015-12-03 15:45:01 -05:00
0ef42870e5 try SSU if NTCP address is not presented 2015-12-02 12:48:10 -05:00
da8a6a4c2b make sure to use ipv4 introducers only 2015-12-01 09:21:02 -05:00
988007a8c9 pass correct pointer to sessions table 2015-11-30 19:45:57 -05:00
710439e83c * cleanup README
* move all docs to single dir
2015-12-01 00:06:00 +00:00
80a0a3d4fb * BUILD_NOTES.md : add hints for building deb 2015-12-01 00:02:59 +00:00
43299aea10 * BUILD_NOTES.md : update 2015-12-01 00:02:59 +00:00
f5aea766a7 * move 'Requirements' sections to BUILD_NOTES.md 2015-12-01 00:02:59 +00:00
c5308e3f2f separate SSU sessions lists for V4 and V6 2015-11-30 15:53:07 -05:00
2b8e662f81 connect through introducer in v4 thread 2015-11-30 14:59:32 -05:00
0a6d849435 pass shared_ptr to SendRelayIntro 2015-11-30 10:23:05 -05:00
a0106fe5d8 Merge pull request #306 from erlend1/openssl
Configurable addresses from master
2015-11-30 10:20:19 -05:00
cee1b8a64a Configurable addresses from master 2015-11-30 16:44:32 +02:00
4e2ba71d59 more introducers 2015-11-29 17:25:42 -05:00
fb2bdfb9ee create SSU session in SSU thread 2015-11-29 09:10:49 -05:00
72785f6740 eliminate some unnecessary calculations 2015-11-27 22:16:10 -05:00
a94a05fac9 replaced radix-16 to radix-256 2015-11-27 19:02:54 -05:00
430368de97 temporary disable Ed25519 per thread 2015-11-27 15:46:30 -05:00
7bfb499549 reduce number of precalculated points 2015-11-27 13:19:45 -05:00
9bc477e1b6 * use stricter linker options for .deb packages 2015-11-27 14:02:19 +00:00
f84ac18472 * set defaults to *FLAGS instead redefining them 2015-11-27 14:01:15 +00:00
cd515a2e54 * fix Depends: for i2pd-dbg 2015-11-27 14:01:15 +00:00
c73c8fdc47 * fix building of empty -dbg package 2015-11-27 13:35:24 +00:00
e755a32b23 * take some enchancements for debian/ dir from kytv (#1) 2015-11-27 12:09:31 +00:00
d4d1768575 * Makefile.* : fix build with gcc 4.7.2 (#299) 2015-11-27 11:42:44 +00:00
0a5745c559 Update README.md 2015-11-26 21:04:19 -05:00
b24959205b Update README.md 2015-11-26 21:03:58 -05:00
d69f297c05 split between CreateSession and CreateSessionThrough Introducer 2015-11-26 16:20:24 -05:00
3c8e331809 Ed25519 per thread 2015-11-26 14:00:40 -05:00
d169471e8c copy constructor for Ed22519 2015-11-26 13:31:30 -05:00
56453f6b5c moved BN_CTX creation to curve's Verify and Sign 2015-11-26 10:25:51 -05:00
dac2e8c79e use left sift instead multipilication by 2 2015-11-26 09:48:06 -05:00
ccc96bc610 Merge pull request #304 from hagen-i2p/fixes
Misc fixes
2015-11-26 07:05:46 -05:00
654371cb6a fix debian/ directory 2015-11-26 11:24:28 +00:00
1af8d873bb delete build/cmake_modules/FindCryptoPP.cmake (now using openssl) 2015-11-26 11:24:02 +00:00
b7a0e23309 fix BUILD_NOTES: url, md-format, crypto++ reference 2015-11-26 11:23:32 +00:00
4a0f868941 fix Dockerfile : drop crypto++, add openssl 2015-11-26 11:23:30 +00:00
448073cdd6 format '%lu' expects argument of type 'long unsigned int', but argument 5 has type 'size_t {aka unsigned int} 2015-11-26 11:23:27 +00:00
ad79ec7b1f async handshake 2015-11-25 13:11:02 -05:00
e194854c6d replace GetSession to CreateSession 2015-11-25 12:51:35 -05:00
d01d033209 eliminate session creation collision 2015-11-25 11:51:35 -05:00
06c4aca490 always use shared_ptr for I2NPMessage 2015-11-24 13:09:12 -05:00
885d57138a read Content-Length from http header 2015-11-23 19:47:08 -05:00
9e2a770a26 read complete request 2015-11-23 16:40:06 -05:00
942b699bb9 fixed few SSL errors 2015-11-23 14:48:56 -05:00
c9d03a8094 I2PControl through SSL 2015-11-23 13:22:02 -05:00
d015538bb4 create certificate for https 2015-11-23 11:56:00 -05:00
90d6c5c5bb fixed race condition 2015-11-23 09:26:32 -05:00
387ce4b6fa fixed access to eepsites from webconsole 2015-11-22 21:02:02 -05:00
7943b13891 use shared_ptr for sockets 2015-11-22 17:01:37 -05:00
50a7cd19b4 Update README.md 2015-11-22 16:48:38 -05:00
53e9335bb0 Update README.md 2015-11-22 16:47:55 -05:00
e5cb70972e moved status_string to reply structure 2015-11-22 10:58:57 -05:00
0d84871037 backport of 'make http server http/1.1 compliant' 2015-11-21 17:26:12 -05:00
1d37745c0c more separation between api and executable builds 2015-11-21 17:04:40 -05:00
ad9ade7849 reduce number of transient BIGNUM allocations 2015-11-20 21:27:16 -05:00
c1e2ee32b4 fixed mingw build error 2015-11-20 12:34:53 -05:00
1588d2734c use path.string () instead path.c_str () 2015-11-20 12:30:20 -05:00
50dda4263f fixed mingw build error 2015-11-20 11:42:38 -05:00
a8f2239495 backport GetMTU 2015-11-20 10:36:04 -05:00
c42636b0ee check for zero-length 2015-11-20 10:10:13 -05:00
54b2c8bd7e backport fix build for clang 2015-11-20 10:02:54 -05:00
d01a21a867 backport openbsd support 2015-11-20 09:55:34 -05:00
5d43052c05 Merge pull request #296 from edwtjo/make-tunnelscfg-configurable-again
Make tunnels.cfg configurable
2015-11-20 09:08:26 -05:00
4109ab1590 Make tunnels.cfg configurable 2015-11-20 13:59:00 +01:00
f6eabd695b don't store B explicitly 2015-11-19 22:38:18 -05:00
24d9dacfd9 fixed mingw build 2015-11-19 21:02:55 -05:00
430 changed files with 56330 additions and 22535 deletions

2
.dir-locals.el Normal file
View File

@ -0,0 +1,2 @@
((c++-mode . ((indent-tabs-mode . t)))
(c-mode . ((mode . c++))))

38
.gitignore vendored
View File

@ -1,16 +1,21 @@
# i2pd
obj/*.o
*.o
router.info
router.keys
i2p
libi2pd.so
netDb
/i2pd
/libi2pd.a
/libi2pdclient.a
*.exe
# Autotools
autom4te.cache
.deps
stamp-h1
Makefile
#Makefile
config.h
config.h.in~
config.log
@ -230,3 +235,32 @@ pip-log.txt
#Mr Developer
.mr.developer.cfg
# Sphinx
docs/_build
/androidIdea/
# Doxygen
docs/generated
# emacs files
*~
*\#*
# gdb files
.gdb_history
# cmake makefile
build/Makefile
# debian stuff
.pc/
# qt
qt/i2pd_qt/*.ui.autosave
qt/i2pd_qt/*.ui.bk*
qt/i2pd_qt/*.ui_*
#unknown android stuff
android/libs/

54
.travis.yml Normal file
View File

@ -0,0 +1,54 @@
language: cpp
cache:
apt: true
os:
- linux
#- osx
dist: trusty
sudo: required
compiler:
- g++
- clang++
env:
global:
- MAKEFLAGS="-j 2"
matrix:
- BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
- BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
- BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
- BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
matrix:
exclude:
- os: osx
env: BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
- os: osx
env: BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
- os: linux
compiler: clang++
env: BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
- os: linux
compiler: clang++
env: BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
addons:
apt:
packages:
- build-essential
- cmake
- g++
- clang
- libboost-chrono-dev
- libboost-date-time-dev
- libboost-filesystem-dev
- libboost-program-options-dev
- libboost-system-dev
- libboost-thread-dev
- libminiupnpc-dev
- libssl-dev
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libressl miniupnpc ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated boost || brew upgrade boost ; fi
script:
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "cmake" ]]; then cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_UPNP=${UPNP} && make ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "make" ]]; then make USE_UPNP=${MAKE_UPNP} ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then make HOMEBREW=1 USE_UPNP=${MAKE_UPNP} ; fi

View File

@ -1,567 +0,0 @@
#include <string.h>
#include <inttypes.h>
#include <string>
#include <map>
#include <fstream>
#include <chrono>
#include <condition_variable>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include "Base.h"
#include "util.h"
#include "Identity.h"
#include "Log.h"
#include "NetDb.h"
#include "ClientContext.h"
#include "AddressBook.h"
namespace i2p
{
namespace client
{
class AddressBookFilesystemStorage: public AddressBookStorage
{
public:
AddressBookFilesystemStorage ();
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const;
void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address);
void RemoveAddress (const i2p::data::IdentHash& ident);
int Load (std::map<std::string, i2p::data::IdentHash>& addresses);
int Save (const std::map<std::string, i2p::data::IdentHash>& addresses);
private:
boost::filesystem::path GetPath () const { return i2p::util::filesystem::GetDefaultDataDir() / "addressbook"; };
};
AddressBookFilesystemStorage::AddressBookFilesystemStorage ()
{
auto path = GetPath ();
if (!boost::filesystem::exists (path))
{
// Create directory is necessary
if (!boost::filesystem::create_directory (path))
LogPrint (eLogError, "Failed to create addressbook directory");
}
}
std::shared_ptr<const i2p::data::IdentityEx> AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident) const
{
auto filename = GetPath () / (ident.ToBase32() + ".b32");
std::ifstream f(filename.c_str (), std::ifstream::binary);
if (f.is_open ())
{
f.seekg (0,std::ios::end);
size_t len = f.tellg ();
if (len < i2p::data::DEFAULT_IDENTITY_SIZE)
{
LogPrint (eLogError, "File ", filename, " is too short. ", len);
return nullptr;
}
f.seekg(0, std::ios::beg);
uint8_t * buf = new uint8_t[len];
f.read((char *)buf, len);
auto address = std::make_shared<i2p::data::IdentityEx>(buf, len);
delete[] buf;
return address;
}
else
return nullptr;
}
void AddressBookFilesystemStorage::AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address)
{
auto filename = GetPath () / (address->GetIdentHash ().ToBase32() + ".b32");
std::ofstream f (filename.c_str (), std::ofstream::binary | std::ofstream::out);
if (f.is_open ())
{
size_t len = address->GetFullLen ();
uint8_t * buf = new uint8_t[len];
address->ToBuffer (buf, len);
f.write ((char *)buf, len);
delete[] buf;
}
else
LogPrint (eLogError, "Can't open file ", filename);
}
void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident)
{
auto filename = GetPath () / (ident.ToBase32() + ".b32");
if (boost::filesystem::exists (filename))
boost::filesystem::remove (filename);
}
int AddressBookFilesystemStorage::Load (std::map<std::string, i2p::data::IdentHash>& addresses)
{
int num = 0;
auto filename = GetPath () / "addresses.csv";
std::ifstream f (filename.c_str (), std::ofstream::in); // in text mode
if (f.is_open ())
{
addresses.clear ();
while (!f.eof ())
{
std::string s;
getline(f, s);
if (!s.length())
continue; // skip empty line
size_t pos = s.find(',');
if (pos != std::string::npos)
{
std::string name = s.substr(0, pos++);
std::string addr = s.substr(pos);
i2p::data::IdentHash ident;
ident.FromBase32 (addr);
addresses[name] = ident;
num++;
}
}
LogPrint (eLogInfo, num, " addresses loaded");
}
else
LogPrint (eLogWarning, filename, " not found");
return num;
}
int AddressBookFilesystemStorage::Save (const std::map<std::string, i2p::data::IdentHash>& addresses)
{
int num = 0;
auto filename = GetPath () / "addresses.csv";
std::ofstream f (filename.c_str (), std::ofstream::out); // in text mode
if (f.is_open ())
{
for (auto it: addresses)
{
f << it.first << "," << it.second.ToBase32 () << std::endl;
num++;
}
LogPrint (eLogInfo, num, " addresses saved");
}
else
LogPrint (eLogError, "Can't open file ", filename);
return num;
}
//---------------------------------------------------------------------
AddressBook::AddressBook (): m_Storage (nullptr), m_IsLoaded (false), m_IsDownloading (false),
m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
{
}
AddressBook::~AddressBook ()
{
Stop ();
}
void AddressBook::Start ()
{
StartSubscriptions ();
}
void AddressBook::Stop ()
{
StopSubscriptions ();
if (m_SubscriptionsUpdateTimer)
{
delete m_SubscriptionsUpdateTimer;
m_SubscriptionsUpdateTimer = nullptr;
}
if (m_IsDownloading)
{
LogPrint (eLogInfo, "Subscription is downloading. Waiting for temination...");
for (int i = 0; i < 30; i++)
{
if (!m_IsDownloading)
{
LogPrint (eLogInfo, "Subscription download complete");
break;
}
std::this_thread::sleep_for (std::chrono::seconds (1)); // wait for 1 seconds
}
LogPrint (eLogError, "Subscription download hangs");
m_IsDownloading = false;
}
if (m_Storage)
{
m_Storage->Save (m_Addresses);
delete m_Storage;
m_Storage = nullptr;
}
if (m_DefaultSubscription)
{
delete m_DefaultSubscription;
m_DefaultSubscription = nullptr;
}
for (auto it: m_Subscriptions)
delete it;
m_Subscriptions.clear ();
}
AddressBookStorage * AddressBook::CreateStorage ()
{
return new AddressBookFilesystemStorage ();
}
bool AddressBook::GetIdentHash (const std::string& address, i2p::data::IdentHash& ident)
{
auto pos = address.find(".b32.i2p");
if (pos != std::string::npos)
{
Base32ToByteStream (address.c_str(), pos, ident, 32);
return true;
}
else
{
pos = address.find (".i2p");
if (pos != std::string::npos)
{
auto identHash = FindAddress (address);
if (identHash)
{
ident = *identHash;
return true;
}
else
return false;
}
}
// if not .b32 we assume full base64 address
i2p::data::IdentityEx dest;
if (!dest.FromBase64 (address))
return false;
ident = dest.GetIdentHash ();
return true;
}
const i2p::data::IdentHash * AddressBook::FindAddress (const std::string& address)
{
if (!m_IsLoaded)
LoadHosts ();
if (m_IsLoaded)
{
auto it = m_Addresses.find (address);
if (it != m_Addresses.end ())
return &it->second;
}
return nullptr;
}
void AddressBook::InsertAddress (const std::string& address, const std::string& base64)
{
auto ident = std::make_shared<i2p::data::IdentityEx>();
ident->FromBase64 (base64);
if (!m_Storage)
m_Storage = CreateStorage ();
m_Storage->AddAddress (ident);
m_Addresses[address] = ident->GetIdentHash ();
LogPrint (address,"->", ToAddress(ident->GetIdentHash ()), " added");
}
void AddressBook::InsertAddress (std::shared_ptr<const i2p::data::IdentityEx> address)
{
if (!m_Storage)
m_Storage = CreateStorage ();
m_Storage->AddAddress (address);
}
std::shared_ptr<const i2p::data::IdentityEx> AddressBook::GetAddress (const std::string& address)
{
if (!m_Storage)
m_Storage = CreateStorage ();
i2p::data::IdentHash ident;
if (!GetIdentHash (address, ident)) return nullptr;
return m_Storage->GetAddress (ident);
}
void AddressBook::LoadHosts ()
{
if (!m_Storage)
m_Storage = CreateStorage ();
if (m_Storage->Load (m_Addresses) > 0)
{
m_IsLoaded = true;
return;
}
// try hosts.txt first
std::ifstream f (i2p::util::filesystem::GetFullPath ("hosts.txt").c_str (), std::ofstream::in); // in text mode
if (f.is_open ())
{
LoadHostsFromStream (f);
m_IsLoaded = true;
}
else
{
// if not found download it from http://i2p-projekt.i2p/hosts.txt
LogPrint (eLogInfo, "hosts.txt not found. Try to download it from default subscription...");
if (!m_IsDownloading)
{
m_IsDownloading = true;
if (!m_DefaultSubscription)
m_DefaultSubscription = new AddressBookSubscription (*this, DEFAULT_SUBSCRIPTION_ADDRESS);
m_DefaultSubscription->CheckSubscription ();
}
}
}
void AddressBook::LoadHostsFromStream (std::istream& f)
{
std::unique_lock<std::mutex> l(m_AddressBookMutex);
int numAddresses = 0;
std::string s;
while (!f.eof ())
{
getline(f, s);
if (!s.length())
continue; // skip empty line
size_t pos = s.find('=');
if (pos != std::string::npos)
{
std::string name = s.substr(0, pos++);
std::string addr = s.substr(pos);
auto ident = std::make_shared<i2p::data::IdentityEx> ();
if (ident->FromBase64(addr))
{
m_Addresses[name] = ident->GetIdentHash ();
m_Storage->AddAddress (ident);
numAddresses++;
}
else
LogPrint (eLogError, "Malformed address ", addr, " for ", name);
}
}
LogPrint (eLogInfo, numAddresses, " addresses processed");
if (numAddresses > 0)
{
m_IsLoaded = true;
m_Storage->Save (m_Addresses);
}
}
void AddressBook::LoadSubscriptions ()
{
if (!m_Subscriptions.size ())
{
std::ifstream f (i2p::util::filesystem::GetFullPath ("subscriptions.txt").c_str (), std::ofstream::in); // in text mode
if (f.is_open ())
{
std::string s;
while (!f.eof ())
{
getline(f, s);
if (!s.length()) continue; // skip empty line
m_Subscriptions.push_back (new AddressBookSubscription (*this, s));
}
LogPrint (eLogInfo, m_Subscriptions.size (), " subscriptions loaded");
}
else
LogPrint (eLogWarning, "subscriptions.txt not found");
}
else
LogPrint (eLogError, "Subscriptions already loaded");
}
void AddressBook::DownloadComplete (bool success)
{
m_IsDownloading = false;
if (m_SubscriptionsUpdateTimer)
{
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(
success ? CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT : CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT));
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
this, std::placeholders::_1));
}
}
void AddressBook::StartSubscriptions ()
{
LoadSubscriptions ();
if (!m_Subscriptions.size ()) return;
auto dest = i2p::client::context.GetSharedLocalDestination ();
if (dest)
{
m_SubscriptionsUpdateTimer = new boost::asio::deadline_timer (dest->GetService ());
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT));
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
this, std::placeholders::_1));
}
else
LogPrint (eLogError, "Can't start subscriptions: missing shared local destination");
}
void AddressBook::StopSubscriptions ()
{
if (m_SubscriptionsUpdateTimer)
m_SubscriptionsUpdateTimer->cancel ();
}
void AddressBook::HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
auto dest = i2p::client::context.GetSharedLocalDestination ();
if (!dest) return;
if (m_IsLoaded && !m_IsDownloading && dest->IsReady () && !m_Subscriptions.empty ())
{
// pick random subscription
auto ind = rand () % m_Subscriptions.size();
m_IsDownloading = true;
m_Subscriptions[ind]->CheckSubscription ();
}
else
{
if (!m_IsLoaded)
LoadHosts ();
// try it again later
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_RETRY_TIMEOUT));
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
this, std::placeholders::_1));
}
}
}
AddressBookSubscription::AddressBookSubscription (AddressBook& book, const std::string& link):
m_Book (book), m_Link (link)
{
}
void AddressBookSubscription::CheckSubscription ()
{
std::thread load_hosts(&AddressBookSubscription::Request, this);
load_hosts.detach(); // TODO: use join
}
void AddressBookSubscription::Request ()
{
// must be run in separate thread
LogPrint (eLogInfo, "Downloading hosts from ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
bool success = false;
i2p::util::http::url u (m_Link);
i2p::data::IdentHash ident;
if (m_Book.GetIdentHash (u.host_, ident))
{
std::condition_variable newDataReceived;
std::mutex newDataReceivedMutex;
auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (ident);
if (!leaseSet)
{
std::unique_lock<std::mutex> l(newDataReceivedMutex);
i2p::client::context.GetSharedLocalDestination ()->RequestDestination (ident,
[&newDataReceived, &leaseSet](std::shared_ptr<i2p::data::LeaseSet> ls)
{
leaseSet = ls;
newDataReceived.notify_all ();
});
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
LogPrint (eLogError, "Subscription LeseseSet request timeout expired");
}
if (leaseSet)
{
std::stringstream request, response;
// standard header
request << "GET " << u.path_ << " HTTP/1.1\r\nHost: " << u.host_
<< "\r\nAccept: */*\r\n" << "User-Agent: Wget/1.11.4\r\n" << "Connection: close\r\n";
if (m_Etag.length () > 0) // etag
request << i2p::util::http::IF_NONE_MATCH << ": \"" << m_Etag << "\"\r\n";
if (m_LastModified.length () > 0) // if-modfief-since
request << i2p::util::http::IF_MODIFIED_SINCE << ": " << m_LastModified << "\r\n";
request << "\r\n"; // end of header
auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, u.port_);
stream->Send ((uint8_t *)request.str ().c_str (), request.str ().length ());
uint8_t buf[4096];
bool end = false;
while (!end)
{
stream->AsyncReceive (boost::asio::buffer (buf, 4096),
[&](const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (bytes_transferred)
response.write ((char *)buf, bytes_transferred);
if (ecode == boost::asio::error::timed_out || !stream->IsOpen ())
end = true;
newDataReceived.notify_all ();
},
30); // wait for 30 seconds
std::unique_lock<std::mutex> l(newDataReceivedMutex);
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
LogPrint (eLogError, "Subscription timeout expired");
}
// process remaining buffer
while (size_t len = stream->ReadSome (buf, 4096))
response.write ((char *)buf, len);
// parse response
std::string version;
response >> version; // HTTP version
int status = 0;
response >> status; // status
if (status == 200) // OK
{
bool isChunked = false;
std::string header, statusMessage;
std::getline (response, statusMessage);
// read until new line meaning end of header
while (!response.eof () && header != "\r")
{
std::getline (response, header);
auto colon = header.find (':');
if (colon != std::string::npos)
{
std::string field = header.substr (0, colon);
header.resize (header.length () - 1); // delete \r
if (field == i2p::util::http::ETAG)
m_Etag = header.substr (colon + 1);
else if (field == i2p::util::http::LAST_MODIFIED)
m_LastModified = header.substr (colon + 1);
else if (field == i2p::util::http::TRANSFER_ENCODING)
isChunked = !header.compare (colon + 1, std::string::npos, "chunked");
}
}
LogPrint (eLogInfo, m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
if (!response.eof ())
{
success = true;
if (!isChunked)
m_Book.LoadHostsFromStream (response);
else
{
// merge chunks
std::stringstream merged;
i2p::util::http::MergeChunkedResponse (response, merged);
m_Book.LoadHostsFromStream (merged);
}
}
}
else if (status == 304)
{
success = true;
LogPrint (eLogInfo, "No updates from ", m_Link);
}
else
LogPrint (eLogWarning, "Adressbook HTTP response ", status);
}
else
LogPrint (eLogError, "Address ", u.host_, " not found");
}
else
LogPrint (eLogError, "Can't resolve ", u.host_);
LogPrint (eLogInfo, "Download complete ", success ? "Success" : "Failed");
m_Book.DownloadComplete (success);
}
}
}

123
Base.h
View File

@ -1,123 +0,0 @@
#ifndef BASE_H__
#define BASE_H__
#include <inttypes.h>
#include <string.h>
#include <string>
#include <zlib.h>
namespace i2p
{
namespace data
{
size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len);
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
const char * GetBase64SubstitutionTable ();
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
template<int sz>
class Tag
{
public:
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); };
Tag (const Tag<sz>& ) = default;
#ifndef _WIN32 // FIXME!!! msvs 2013 can't compile it
Tag (Tag<sz>&& ) = default;
#endif
Tag () = default;
Tag<sz>& operator= (const Tag<sz>& ) = default;
#ifndef _WIN32
Tag<sz>& operator= (Tag<sz>&& ) = default;
#endif
uint8_t * operator()() { return m_Buf; };
const uint8_t * operator()() const { return m_Buf; };
operator uint8_t * () { return m_Buf; };
operator const uint8_t * () const { return m_Buf; };
const uint64_t * GetLL () const { return ll; };
bool operator== (const Tag<sz>& other) const { return !memcmp (m_Buf, other.m_Buf, sz); };
bool operator< (const Tag<sz>& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; };
bool IsZero () const
{
for (int i = 0; i < sz/8; i++)
if (ll[i]) return false;
return true;
}
std::string ToBase64 () const
{
char str[sz*2];
int l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2);
str[l] = 0;
return std::string (str);
}
std::string ToBase32 () const
{
char str[sz*2];
int l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2);
str[l] = 0;
return std::string (str);
}
void FromBase32 (const std::string& s)
{
i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz);
}
void FromBase64 (const std::string& s)
{
i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
}
private:
union // 8 bytes alignment
{
uint8_t m_Buf[sz];
uint64_t ll[sz/8];
};
};
class GzipInflator
{
public:
GzipInflator ();
~GzipInflator ();
size_t Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
private:
z_stream m_Inflator;
bool m_IsDirty;
};
class GzipDeflator
{
public:
GzipDeflator ();
~GzipDeflator ();
void SetCompressionLevel (int level);
size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
private:
z_stream m_Deflator;
bool m_IsDirty;
};
}
}
#endif

299
ChangeLog Normal file
View File

@ -0,0 +1,299 @@
# for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog
## [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
### Added
- ECIES support for RouterInfo
- HTTP outproxy authorization
- AVX/AESNI runtime detection
- Initial implementation of NTCP2
- I2CP session reconfigure
- I2CP method ClientServicesInfo
- Datagrams to websocks
### Changed
- RouterInfo uses EdDSA signature by default
- Remove stream bans
- Android build system changed to gradle
- Multiple changes in QT GUI
- Dockerfile
### Fixed
- zero tunnelID issue
- tunnels reload
- headers in webconsole
- XSS in webconsole from SAM session name
- build for gcc 8
- cmake build scripts
- systemd service files
- some netbsd issues
## [2.18.0] - 2018-01-30
### Added
- Show tunnel nicknames for I2CP destination in WebUI
- Re-create HTTP and SOCKS proxy by tunnel reload
- Graceful shutdown as soon as no more transit tunnels
### Changed
- Regenerate shared local destination by tunnel reload
- Use transient local destination by default if not specified
- Return correct code if pid file can't be created
- Timing and number of attempts for adressbook requests
- Certificates list
### Fixed
- Malformed addressbook subsctiption request
- Build with boost 1.66
- Few race conditions for SAM
- Check LeaseSet's signature before update
## [2.17.0] - 2017-12-04
### Added
- Reseed through HTTP and SOCKS proxy
- Show status of client services through web console
- Change log level through web connsole
- transient keys for tunnels
- i2p.streaming.initialAckDelay parameter
- CRYPTO_TYPE for SAM destination
- signature and crypto type for newkeys BOB command
### Changed
- Correct publication of ECIES destinations
- Disable RSA signatures completely
### Fixed
- CVE-2017-17066
- Possible buffer overflow for RSA-4096
- Shutdown from web console for Windows
- Web console page layout
## [2.16.0] - 2017-11-13
### Added
- https and "Connect" method for HTTP proxy
- outproxy for HTTP proxy
- initial support of ECIES crypto
- NTCP soft and hard descriptors limits
- Support full timestamps in logs
### Changed
- Faster implementation of GOST R 34.11 hash
- Reject routers with RSA signtures
- Reload config and shudown from Windows GUI
- Update tunnels address(destination) without restart
### Fixed
- BOB crashes if destination is not set
- Correct SAM tunnel name
- QT GUI issues
## [2.15.0] - 2017-08-17
### Added
- QT GUI
- Ability to add and remove I2P tunnels without restart
- Ability to disable SOCKS outproxy option
### Changed
- Strip-out Accept-* hedaers in HTTP proxy
- Don't run peer test if nat=false
- Separate output of NTCP and SSU sessions in Transports tab
### Fixed
- Handle lines with comments in hosts.txt file for address book
- Run router with empty netdb for testnet
- Skip expired introducers by iexp
## [2.14.0] - 2017-06-01
### Added
- Transit traffic bandwidth limitation
- NTCP connections through HTTP and SOCKS proxies
- Ability to disable address helper for HTTP proxy
### Changed
- Reseed servers list
- Minimal required version is 4.0 for Android
### Fixed
- Ignore comments in addressbook feed
## [2.13.0] - 2017-04-06
### Added
- Persist local destination's tags
- GOST signature types 9 and 10
- Exploratory tunnels configuration
### Changed
- Reseed servers list
- Inactive NTCP sockets get closed faster
- Some EdDSA speed up
### Fixed
- Multiple acceptors for SAM
- Follow on data after STREAM CREATE for SAM
- Memory leaks
## [2.12.0] - 2017-02-14
### Added
- Additional HTTP and SOCKS proxy tunnels
- Reseed from ZIP archive
- Some stats in a main window for Windows version
### Changed
- Reseed servers list
- MTU of 1488 for ipv6
- Android and Mac OS X versions use OpenSSL 1.1
- New logo for Android
### Fixed
- Multiple memory leaks
- Incomptibility of some EdDSA private keys with Java
- Clock skew for Windows XP
- Occasional crashes with I2PSnark
## [2.11.0] - 2016-12-18
### Added
- Websockets support
- Reseed through a floodfill
- Tunnel configuration for HTTP and SOCKS proxy
- Zero-hops tunnels for destinations
- Multiple acceptors for SAM
### Changed
- Reseed servers list
- DHT uses AVX if applicable
- New logo
- LeaseSet lookups
### Fixed
- HTTP Proxy connection reset for Windows
- Crash upon SAM session termination
- Can't connect to a destination for a longer time after restart
- Mass packet loss for UDP tunnels
## [2.10.2] - 2016-12-04
### Fixed
- Fixes UPnP discovery bug, producing excessive CPU usage
- Fixes sudden SSU thread stop for Windows.
## [2.10.1] - 2016-11-07
### Fixed
- Fixed some performance issues for Windows and Android
## [2.10.0] - 2016-10-17
### Added
- Datagram i2p tunnels
- Unique local addresses for server tunnels
- Configurable list of reseed servers and initial addressbook
- Configurable netid
- Initial iOS support
### Changed
- Reduced file descriptors usage
- Strict reseed checks enabled by default
## Fixed
- Multiple fixes in I2CP and BOB implementations
## [2.9.0] - 2016-08-12
### Changed
- Proxy refactoring & speedup
- Transmission-I2P support
- Graceful shutdown for Windows
- Android without QT
- Reduced number of timers in SSU
- ipv6 peer test support
- Reseed from SU3 file
## [2.8.0] - 2016-06-20
### Added
- Basic Android support
- I2CP implementation
- 'doxygen' target
### Changed
- I2PControl refactoring & fixes (proper jsonrpc responses on errors)
- boost::regex no more needed
### Fixed
- initscripts: added openrc one, in sysv-ish make I2PD_PORT optional
- properly close NTCP sessions (memleak)
## [2.7.0] - 2016-05-18
### Added
- Precomputed El-Gamal/DH tables
- Configurable limit of transit tunnels
### Changed
- Speed-up of asymmetric crypto for non-x64 platforms
- Refactoring of web-console
## [2.6.0] - 2016-03-31
### Added
- Graceful shutdown on SIGINT
- Numeric bandwidth limits (was: by router class)
- Jumpservices in web-console
- Logging to syslog
- Tray icon for windows application
### Changed
- Logs refactoring
- Improved statistics in web-console
### Deprecated:
- Renamed main/tunnels config files (will use old, if found, but emits warning)
## [2.5.1] - 2016-03-10
### Fixed
- Doesn't create ~/.i2pd dir if missing
## [2.5.0] - 2016-03-04
### Added
- IRC server tunnels
- SOCKS outproxy support
- Support for gzipped addressbook updates
- Support for router families
### Changed
- Shared RTT/RTO between streams
- Filesystem work refactoring
## [2.4.0] - 2016-02-03
### Added
- X-I2P-* headers for server http-tunnels
- I2CP options for I2P tunnels
- Show I2P tunnels in webconsole
### Changed
- Refactoring of cmdline/config parsing
## [2.3.0] - 2016-01-12
### Added
- Support for new router bandwidth class codes (P and X)
- I2PControl supports external webui
- Added --pidfile and --notransit parameters
- Ability to specify signature type for i2p tunnel
### Changed
- Fixed multiple floodfill-related bugs
- New webconsole layout
## [2.2.0] - 2015-12-22
### Added
- Ability to connect to router without ip via introducer
### Changed
- Persist temporary encryption keys for local destinations
- Performance improvements for EdDSA
- New addressbook structure
## [2.1.0] - 2015-11-12
### Added
- Implementation of EdDSA
### Changed
- EdDSA is default signature type for new RouterInfos

View File

@ -1,328 +0,0 @@
#include <fstream>
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "util.h"
#include "Log.h"
#include "Identity.h"
#include "ClientContext.h"
namespace i2p
{
namespace client
{
ClientContext context;
ClientContext::ClientContext (): m_SharedLocalDestination (nullptr),
m_HttpProxy (nullptr), m_SocksProxy (nullptr), m_SamBridge (nullptr),
m_BOBCommandChannel (nullptr)
{
}
ClientContext::~ClientContext ()
{
delete m_HttpProxy;
delete m_SocksProxy;
delete m_SamBridge;
delete m_BOBCommandChannel;
}
void ClientContext::Start ()
{
if (!m_SharedLocalDestination)
{
m_SharedLocalDestination = CreateNewLocalDestination (); // non-public, DSA
m_Destinations[m_SharedLocalDestination->GetIdentity ()->GetIdentHash ()] = m_SharedLocalDestination;
m_SharedLocalDestination->Start ();
}
std::shared_ptr<ClientDestination> localDestination;
// proxies
std::string proxyKeys = i2p::util::config::GetArg("-proxykeys", "");
if (proxyKeys.length () > 0)
localDestination = LoadLocalDestination (proxyKeys, false);
m_HttpProxy = new i2p::proxy::HTTPProxy(i2p::util::config::GetArg("-httpproxyport", 4446), localDestination);
m_HttpProxy->Start();
LogPrint("HTTP Proxy started");
m_SocksProxy = new i2p::proxy::SOCKSProxy(i2p::util::config::GetArg("-socksproxyport", 4447), localDestination);
m_SocksProxy->Start();
LogPrint("SOCKS Proxy Started");
// I2P tunnels
std::string ircDestination = i2p::util::config::GetArg("-ircdest", "");
if (ircDestination.length () > 0) // ircdest is presented
{
localDestination = nullptr;
std::string ircKeys = i2p::util::config::GetArg("-irckeys", "");
if (ircKeys.length () > 0)
localDestination = LoadLocalDestination (ircKeys, false);
auto ircPort = i2p::util::config::GetArg("-ircport", 6668);
auto ircTunnel = new I2PClientTunnel (ircDestination, ircPort, localDestination);
ircTunnel->Start ();
m_ClientTunnels.insert (std::make_pair(ircPort, std::unique_ptr<I2PClientTunnel>(ircTunnel)));
LogPrint("IRC tunnel started");
}
std::string eepKeys = i2p::util::config::GetArg("-eepkeys", "");
if (eepKeys.length () > 0) // eepkeys file is presented
{
localDestination = LoadLocalDestination (eepKeys, true);
auto serverTunnel = new I2PServerTunnel (i2p::util::config::GetArg("-eephost", "127.0.0.1"),
i2p::util::config::GetArg("-eepport", 80), localDestination);
serverTunnel->Start ();
m_ServerTunnels.insert (std::make_pair(localDestination->GetIdentHash (), std::unique_ptr<I2PServerTunnel>(serverTunnel)));
LogPrint("Server tunnel started");
}
ReadTunnels ();
// SAM
int samPort = i2p::util::config::GetArg("-samport", 0);
if (samPort)
{
m_SamBridge = new SAMBridge (samPort);
m_SamBridge->Start ();
LogPrint("SAM bridge started");
}
// BOB
int bobPort = i2p::util::config::GetArg("-bobport", 0);
if (bobPort)
{
m_BOBCommandChannel = new BOBCommandChannel (bobPort);
m_BOBCommandChannel->Start ();
LogPrint("BOB command channel started");
}
m_AddressBook.Start ();
}
void ClientContext::Stop ()
{
m_HttpProxy->Stop();
delete m_HttpProxy;
m_HttpProxy = nullptr;
LogPrint("HTTP Proxy stopped");
m_SocksProxy->Stop();
delete m_SocksProxy;
m_SocksProxy = nullptr;
LogPrint("SOCKS Proxy stopped");
for (auto& it: m_ClientTunnels)
{
it.second->Stop ();
LogPrint("I2P client tunnel on port ", it.first, " stopped");
}
m_ClientTunnels.clear ();
for (auto& it: m_ServerTunnels)
{
it.second->Stop ();
LogPrint("I2P server tunnel stopped");
}
m_ServerTunnels.clear ();
if (m_SamBridge)
{
m_SamBridge->Stop ();
delete m_SamBridge;
m_SamBridge = nullptr;
LogPrint("SAM brdige stopped");
}
if (m_BOBCommandChannel)
{
m_BOBCommandChannel->Stop ();
delete m_BOBCommandChannel;
m_BOBCommandChannel = nullptr;
LogPrint("BOB command channel stopped");
}
m_AddressBook.Stop ();
for (auto it: m_Destinations)
it.second->Stop ();
m_Destinations.clear ();
m_SharedLocalDestination = nullptr;
}
std::shared_ptr<ClientDestination> ClientContext::LoadLocalDestination (const std::string& filename, bool isPublic)
{
i2p::data::PrivateKeys keys;
std::string fullPath = i2p::util::filesystem::GetFullPath (filename);
std::ifstream s(fullPath.c_str (), std::ifstream::binary);
if (s.is_open ())
{
s.seekg (0, std::ios::end);
size_t len = s.tellg();
s.seekg (0, std::ios::beg);
uint8_t * buf = new uint8_t[len];
s.read ((char *)buf, len);
keys.FromBuffer (buf, len);
delete[] buf;
LogPrint ("Local address ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " loaded");
}
else
{
LogPrint ("Can't open file ", fullPath, " Creating new one");
keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out);
size_t len = keys.GetFullLen ();
uint8_t * buf = new uint8_t[len];
len = keys.ToBuffer (buf, len);
f.write ((char *)buf, len);
delete[] buf;
LogPrint ("New private keys file ", fullPath, " for ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " created");
}
std::shared_ptr<ClientDestination> localDestination = nullptr;
std::unique_lock<std::mutex> l(m_DestinationsMutex);
auto it = m_Destinations.find (keys.GetPublic ()->GetIdentHash ());
if (it != m_Destinations.end ())
{
LogPrint (eLogWarning, "Local destination ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " alreday exists");
localDestination = it->second;
}
else
{
localDestination = std::make_shared<ClientDestination> (keys, isPublic);
m_Destinations[localDestination->GetIdentHash ()] = localDestination;
localDestination->Start ();
}
return localDestination;
}
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType,
const std::map<std::string, std::string> * params)
{
i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType);
auto localDestination = std::make_shared<ClientDestination> (keys, isPublic, params);
std::unique_lock<std::mutex> l(m_DestinationsMutex);
m_Destinations[localDestination->GetIdentHash ()] = localDestination;
localDestination->Start ();
return localDestination;
}
void ClientContext::DeleteLocalDestination (std::shared_ptr<ClientDestination> destination)
{
if (!destination) return;
auto it = m_Destinations.find (destination->GetIdentHash ());
if (it != m_Destinations.end ())
{
auto d = it->second;
{
std::unique_lock<std::mutex> l(m_DestinationsMutex);
m_Destinations.erase (it);
}
d->Stop ();
}
}
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic,
const std::map<std::string, std::string> * params)
{
auto it = m_Destinations.find (keys.GetPublic ()->GetIdentHash ());
if (it != m_Destinations.end ())
{
LogPrint ("Local destination ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " exists");
if (!it->second->IsRunning ())
{
it->second->Start ();
return it->second;
}
return nullptr;
}
auto localDestination = std::make_shared<ClientDestination> (keys, isPublic, params);
std::unique_lock<std::mutex> l(m_DestinationsMutex);
m_Destinations[keys.GetPublic ()->GetIdentHash ()] = localDestination;
localDestination->Start ();
return localDestination;
}
std::shared_ptr<ClientDestination> ClientContext::FindLocalDestination (const i2p::data::IdentHash& destination) const
{
auto it = m_Destinations.find (destination);
if (it != m_Destinations.end ())
return it->second;
return nullptr;
}
void ClientContext::ReadTunnels ()
{
boost::property_tree::ptree pt;
try
{
boost::property_tree::read_ini (i2p::util::filesystem::GetFullPath (TUNNELS_CONFIG_FILENAME), pt);
}
catch (std::exception& ex)
{
LogPrint (eLogWarning, "Can't read ", TUNNELS_CONFIG_FILENAME, ": ", ex.what ());
return;
}
int numClientTunnels = 0, numServerTunnels = 0;
for (auto& section: pt)
{
std::string name = section.first;
try
{
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT)
{
// mandatory params
std::string dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
// optional params
std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "");
int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
std::shared_ptr<ClientDestination> localDestination = nullptr;
if (keys.length () > 0)
localDestination = LoadLocalDestination (keys, false);
auto clientTunnel = new I2PClientTunnel (dest, port, localDestination, destinationPort);
if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr<I2PClientTunnel>(clientTunnel))).second)
clientTunnel->Start ();
else
LogPrint (eLogError, "I2P client tunnel with port ", port, " already exists");
numClientTunnels++;
}
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP)
{
// mandatory params
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT);
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS);
// optional params
int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
auto localDestination = LoadLocalDestination (keys, true);
I2PServerTunnel * serverTunnel = (type == I2P_TUNNELS_SECTION_TYPE_HTTP) ? new I2PServerTunnelHTTP (host, port, localDestination, inPort) : new I2PServerTunnel (host, port, localDestination, inPort);
if (accessList.length () > 0)
{
std::set<i2p::data::IdentHash> idents;
size_t pos = 0, comma;
do
{
comma = accessList.find (',', pos);
i2p::data::IdentHash ident;
ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
idents.insert (ident);
pos = comma + 1;
}
while (comma != std::string::npos);
serverTunnel->SetAccessList (idents);
}
if (m_ServerTunnels.insert (std::make_pair (localDestination->GetIdentHash (), std::unique_ptr<I2PServerTunnel>(serverTunnel))).second)
serverTunnel->Start ();
else
LogPrint (eLogError, "I2P server tunnel for destination ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), " already exists");
numServerTunnels++;
}
else
LogPrint (eLogWarning, "Unknown section type=", type, " of ", name, " in ", TUNNELS_CONFIG_FILENAME);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Can't read tunnel ", name, " params: ", ex.what ());
}
}
LogPrint (eLogInfo, numClientTunnels, " I2P client tunnels created");
LogPrint (eLogInfo, numServerTunnels, " I2P server tunnels created");
}
}
}

View File

@ -1,84 +0,0 @@
#ifndef CLIENT_CONTEXT_H__
#define CLIENT_CONTEXT_H__
#include <map>
#include <mutex>
#include <memory>
#include "Destination.h"
#include "HTTPProxy.h"
#include "SOCKS.h"
#include "I2PTunnel.h"
#include "SAM.h"
#include "BOB.h"
#include "AddressBook.h"
namespace i2p
{
namespace client
{
const char I2P_TUNNELS_SECTION_TYPE[] = "type";
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
const char I2P_CLIENT_TUNNEL_PORT[] = "port";
const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination";
const char I2P_CLIENT_TUNNEL_KEYS[] = "keys";
const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport";
const char I2P_SERVER_TUNNEL_HOST[] = "host";
const char I2P_SERVER_TUNNEL_PORT[] = "port";
const char I2P_SERVER_TUNNEL_KEYS[] = "keys";
const char I2P_SERVER_TUNNEL_INPORT[] = "inport";
const char I2P_SERVER_TUNNEL_ACCESS_LIST[] = "accesslist";
const char TUNNELS_CONFIG_FILENAME[] = "tunnels.cfg";
class ClientContext
{
public:
ClientContext ();
~ClientContext ();
void Start ();
void Stop ();
std::shared_ptr<ClientDestination> GetSharedLocalDestination () const { return m_SharedLocalDestination; };
std::shared_ptr<ClientDestination> CreateNewLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1,
const std::map<std::string, std::string> * params = nullptr); // transient
std::shared_ptr<ClientDestination> CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true,
const std::map<std::string, std::string> * params = nullptr);
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
std::shared_ptr<ClientDestination> LoadLocalDestination (const std::string& filename, bool isPublic);
AddressBook& GetAddressBook () { return m_AddressBook; };
const SAMBridge * GetSAMBridge () const { return m_SamBridge; };
private:
void ReadTunnels ();
private:
std::mutex m_DestinationsMutex;
std::map<i2p::data::IdentHash, std::shared_ptr<ClientDestination> > m_Destinations;
std::shared_ptr<ClientDestination> m_SharedLocalDestination;
AddressBook m_AddressBook;
i2p::proxy::HTTPProxy * m_HttpProxy;
i2p::proxy::SOCKSProxy * m_SocksProxy;
std::map<int, std::unique_ptr<I2PClientTunnel> > m_ClientTunnels; // port->tunnel
std::map<i2p::data::IdentHash, std::unique_ptr<I2PServerTunnel> > m_ServerTunnels; // destination->tunnel
SAMBridge * m_SamBridge;
BOBCommandChannel * m_BOBCommandChannel;
public:
// for HTTP
const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; };
};
extern ClientContext context;
}
}
#endif

View File

@ -1,619 +0,0 @@
#include <string.h>
#include <string>
#include <openssl/sha.h>
#include <openssl/dh.h>
#include <openssl/md5.h>
#include <openssl/rand.h>
#include "Log.h"
//#include "TunnelBase.h"
#include "Crypto.h"
namespace i2p
{
namespace crypto
{
const uint8_t elgp_[256]=
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
const int elgg_ = 2;
const uint8_t dsap_[128]=
{
0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c,
0x30, 0x26, 0xe9, 0xb8, 0xed, 0x92, 0xfa, 0xd0, 0xa6, 0x9c, 0xc8, 0x86, 0xd5, 0xbf, 0x80, 0x15,
0xfc, 0xad, 0xae, 0x31, 0xa0, 0xad, 0x18, 0xfa, 0xb3, 0xf0, 0x1b, 0x00, 0xa3, 0x58, 0xde, 0x23,
0x76, 0x55, 0xc4, 0x96, 0x4a, 0xfa, 0xa2, 0xb3, 0x37, 0xe9, 0x6a, 0xd3, 0x16, 0xb9, 0xfb, 0x1c,
0xc5, 0x64, 0xb5, 0xae, 0xc5, 0xb6, 0x9a, 0x9f, 0xf6, 0xc3, 0xe4, 0x54, 0x87, 0x07, 0xfe, 0xf8,
0x50, 0x3d, 0x91, 0xdd, 0x86, 0x02, 0xe8, 0x67, 0xe6, 0xd3, 0x5d, 0x22, 0x35, 0xc1, 0x86, 0x9c,
0xe2, 0x47, 0x9c, 0x3b, 0x9d, 0x54, 0x01, 0xde, 0x04, 0xe0, 0x72, 0x7f, 0xb3, 0x3d, 0x65, 0x11,
0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93
};
const uint8_t dsaq_[20]=
{
0xa5, 0xdf, 0xc2, 0x8f, 0xef, 0x4c, 0xa1, 0xe2, 0x86, 0x74, 0x4c, 0xd8, 0xee, 0xd9, 0xd2, 0x9d,
0x68, 0x40, 0x46, 0xb7
};
const uint8_t dsag_[128]=
{
0x0c, 0x1f, 0x4d, 0x27, 0xd4, 0x00, 0x93, 0xb4, 0x29, 0xe9, 0x62, 0xd7, 0x22, 0x38, 0x24, 0xe0,
0xbb, 0xc4, 0x7e, 0x7c, 0x83, 0x2a, 0x39, 0x23, 0x6f, 0xc6, 0x83, 0xaf, 0x84, 0x88, 0x95, 0x81,
0x07, 0x5f, 0xf9, 0x08, 0x2e, 0xd3, 0x23, 0x53, 0xd4, 0x37, 0x4d, 0x73, 0x01, 0xcd, 0xa1, 0xd2,
0x3c, 0x43, 0x1f, 0x46, 0x98, 0x59, 0x9d, 0xda, 0x02, 0x45, 0x18, 0x24, 0xff, 0x36, 0x97, 0x52,
0x59, 0x36, 0x47, 0xcc, 0x3d, 0xdc, 0x19, 0x7d, 0xe9, 0x85, 0xe4, 0x3d, 0x13, 0x6c, 0xdc, 0xfc,
0x6b, 0xd5, 0x40, 0x9c, 0xd2, 0xf4, 0x50, 0x82, 0x11, 0x42, 0xa5, 0xe6, 0xf8, 0xeb, 0x1c, 0x3a,
0xb5, 0xd0, 0x48, 0x4b, 0x81, 0x29, 0xfc, 0xf1, 0x7b, 0xce, 0x4f, 0x7f, 0x33, 0x32, 0x1c, 0x3c,
0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82
};
const int rsae_ = 65537;
const CryptoConstants& GetCryptoConstants ()
{
static CryptoConstants cryptoConstants (elgp_, elgg_, dsap_, dsaq_, dsag_, rsae_);
return cryptoConstants;
}
bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len)
{
int offset = len - BN_num_bytes (bn);
if (offset < 0) return false;
BN_bn2bin (bn, buf + offset);
memset (buf, 0, offset);
return true;
}
// DH
DHKeys::DHKeys (): m_IsUpdated (true)
{
m_DH = DH_new ();
m_DH->p = BN_dup (elgp);
m_DH->g = BN_dup (elgg);
m_DH->priv_key = NULL;
m_DH->pub_key = NULL;
}
DHKeys::~DHKeys ()
{
DH_free (m_DH);
}
void DHKeys::GenerateKeys (uint8_t * priv, uint8_t * pub)
{
if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; };
if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; };
DH_generate_key (m_DH);
if (priv) bn2buf (m_DH->priv_key, priv, 256);
if (pub) bn2buf (m_DH->pub_key, pub, 256);
m_IsUpdated = true;
}
const uint8_t * DHKeys::GetPublicKey ()
{
if (m_IsUpdated)
{
bn2buf (m_DH->pub_key, m_PublicKey, 256);
BN_free (m_DH->pub_key); m_DH->pub_key = NULL;
m_IsUpdated= false;
}
return m_PublicKey;
}
void DHKeys::Agree (const uint8_t * pub, uint8_t * shared)
{
BIGNUM * pk = BN_bin2bn (pub, 256, NULL);
DH_compute_key (shared, pk, m_DH);
BN_free (pk);
}
// ElGamal
ElGamalEncryption::ElGamalEncryption (const uint8_t * key)
{
ctx = BN_CTX_new ();
// select random k
BIGNUM * k = BN_new ();
BN_rand_range (k, elgp);
if (BN_is_zero (k)) BN_one (k);
// caulculate a
a = BN_new ();
BN_mod_exp (a, elgg, k, elgp, ctx);
BIGNUM * y = BN_new ();
BN_bin2bn (key, 256, y);
// calculate b1
b1 = BN_new ();
BN_mod_exp (b1, y, k, elgp, ctx);
BN_free (y);
BN_free (k);
}
ElGamalEncryption::~ElGamalEncryption ()
{
BN_CTX_free (ctx);
BN_free (a);
BN_free (b1);
}
void ElGamalEncryption::Encrypt (const uint8_t * data, int len, uint8_t * encrypted, bool zeroPadding) const
{
// create m
uint8_t m[255];
m[0] = 0xFF;
memcpy (m+33, data, len);
SHA256 (m+33, 222, m+1);
// calculate b = b1*m mod p
BIGNUM * b = BN_new ();
BN_bin2bn (m, 255, b);
BN_mod_mul (b, b1, b, elgp, ctx);
// copy a and b
if (zeroPadding)
{
encrypted[0] = 0;
bn2buf (a, encrypted + 1, 256);
encrypted[257] = 0;
bn2buf (b, encrypted + 258, 256);
}
else
{
bn2buf (a, encrypted, 256);
bn2buf (b, encrypted + 256, 256);
}
BN_free (b);
}
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted,
uint8_t * data, bool zeroPadding)
{
BN_CTX * ctx = BN_CTX_new ();
BIGNUM * x = BN_new (), * a = BN_new (), * b = BN_new ();
BN_bin2bn (key, 256, x);
BN_sub (x, elgp, x); BN_sub_word (x, 1); // x = elgp - x- 1
BN_bin2bn (zeroPadding ? encrypted + 1 : encrypted, 256, a);
BN_bin2bn (zeroPadding ? encrypted + 258 : encrypted + 256, 256, b);
// m = b*(a^x mod p) mod p
BN_mod_exp (x, a, x, elgp, ctx);
BN_mod_mul (b, b, x, elgp, ctx);
uint8_t m[255];
bn2buf (b, m, 255);
BN_free (x); BN_free (a); BN_free (b);
BN_CTX_free (ctx);
uint8_t hash[32];
SHA256 (m + 33, 222, hash);
if (memcmp (m + 1, hash, 32))
{
LogPrint (eLogError, "ElGamal decrypt hash doesn't match");
return false;
}
memcpy (data, m + 33, 222);
return true;
}
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub)
{
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
RAND_bytes (priv, 256);
BN_CTX * ctx = BN_CTX_new ();
BIGNUM * p = BN_new ();
BN_bin2bn (priv, 256, p);
BN_mod_exp (p, elgg, p, elgp, ctx);
bn2buf (p, pub, 256);
BN_free (p);
BN_CTX_free (ctx);
#else
DHKeys dh;
dh.GenerateKeys (priv, pub);
#endif
}
// HMAC
const uint64_t IPAD = 0x3636363636363636;
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C;
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest)
// key is 32 bytes
// digest is 16 bytes
// block size is 64 bytes
{
uint64_t buf[256];
// 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;
// concatenate with msg
memcpy (buf + 8, msg, len);
// calculate first hash
uint8_t hash[16]; // MD5
MD5((uint8_t *)buf, len + 64, hash);
// okeypad
buf[0] = key.GetLL ()[0] ^ OPAD;
buf[1] = key.GetLL ()[1] ^ OPAD;
buf[2] = key.GetLL ()[2] ^ OPAD;
buf[3] = key.GetLL ()[3] ^ OPAD;
buf[4] = OPAD;
buf[5] = OPAD;
buf[6] = OPAD;
buf[7] = OPAD;
// copy first hash after okeypad
memcpy (buf + 8, hash, 16);
// fill next 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
memset (buf + 10, 0, 16);
// calculate digest
MD5((uint8_t *)buf, 96, digest);
}
// AES
#ifdef AESNI
#define KeyExpansion256(round0,round1) \
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
"movaps %%xmm1, %%xmm4 \n" \
"pslldq $4, %%xmm4 \n" \
"pxor %%xmm4, %%xmm1 \n" \
"pslldq $4, %%xmm4 \n" \
"pxor %%xmm4, %%xmm1 \n" \
"pslldq $4, %%xmm4 \n" \
"pxor %%xmm4, %%xmm1 \n" \
"pxor %%xmm2, %%xmm1 \n" \
"movaps %%xmm1, "#round0"(%[sched]) \n" \
"aeskeygenassist $0, %%xmm1, %%xmm4 \n" \
"pshufd $0xaa, %%xmm4, %%xmm2 \n" \
"movaps %%xmm3, %%xmm4 \n" \
"pslldq $4, %%xmm4 \n" \
"pxor %%xmm4, %%xmm3 \n" \
"pslldq $4, %%xmm4 \n" \
"pxor %%xmm4, %%xmm3 \n" \
"pslldq $4, %%xmm4 \n" \
"pxor %%xmm4, %%xmm3 \n" \
"pxor %%xmm2, %%xmm3 \n" \
"movaps %%xmm3, "#round1"(%[sched]) \n"
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
{
__asm__
(
"movups (%[key]), %%xmm1 \n"
"movups 16(%[key]), %%xmm3 \n"
"movaps %%xmm1, (%[sched]) \n"
"movaps %%xmm3, 16(%[sched]) \n"
"aeskeygenassist $1, %%xmm3, %%xmm2 \n"
KeyExpansion256(32,48)
"aeskeygenassist $2, %%xmm3, %%xmm2 \n"
KeyExpansion256(64,80)
"aeskeygenassist $4, %%xmm3, %%xmm2 \n"
KeyExpansion256(96,112)
"aeskeygenassist $8, %%xmm3, %%xmm2 \n"
KeyExpansion256(128,144)
"aeskeygenassist $16, %%xmm3, %%xmm2 \n"
KeyExpansion256(160,176)
"aeskeygenassist $32, %%xmm3, %%xmm2 \n"
KeyExpansion256(192,208)
"aeskeygenassist $64, %%xmm3, %%xmm2 \n"
// key expansion final
"pshufd $0xff, %%xmm2, %%xmm2 \n"
"movaps %%xmm1, %%xmm4 \n"
"pslldq $4, %%xmm4 \n"
"pxor %%xmm4, %%xmm1 \n"
"pslldq $4, %%xmm4 \n"
"pxor %%xmm4, %%xmm1 \n"
"pslldq $4, %%xmm4 \n"
"pxor %%xmm4, %%xmm1 \n"
"pxor %%xmm2, %%xmm1 \n"
"movups %%xmm1, 224(%[sched]) \n"
: // output
: [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input
: "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged
);
}
#define EncryptAES256(sched) \
"pxor (%["#sched"]), %%xmm0 \n" \
"aesenc 16(%["#sched"]), %%xmm0 \n" \
"aesenc 32(%["#sched"]), %%xmm0 \n" \
"aesenc 48(%["#sched"]), %%xmm0 \n" \
"aesenc 64(%["#sched"]), %%xmm0 \n" \
"aesenc 80(%["#sched"]), %%xmm0 \n" \
"aesenc 96(%["#sched"]), %%xmm0 \n" \
"aesenc 112(%["#sched"]), %%xmm0 \n" \
"aesenc 128(%["#sched"]), %%xmm0 \n" \
"aesenc 144(%["#sched"]), %%xmm0 \n" \
"aesenc 160(%["#sched"]), %%xmm0 \n" \
"aesenc 176(%["#sched"]), %%xmm0 \n" \
"aesenc 192(%["#sched"]), %%xmm0 \n" \
"aesenc 208(%["#sched"]), %%xmm0 \n" \
"aesenclast 224(%["#sched"]), %%xmm0 \n"
void ECBEncryptionAESNI::Encrypt (const ChipherBlock * in, ChipherBlock * out)
{
__asm__
(
"movups (%[in]), %%xmm0 \n"
EncryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
);
}
#define DecryptAES256(sched) \
"pxor 224(%["#sched"]), %%xmm0 \n" \
"aesdec 208(%["#sched"]), %%xmm0 \n" \
"aesdec 192(%["#sched"]), %%xmm0 \n" \
"aesdec 176(%["#sched"]), %%xmm0 \n" \
"aesdec 160(%["#sched"]), %%xmm0 \n" \
"aesdec 144(%["#sched"]), %%xmm0 \n" \
"aesdec 128(%["#sched"]), %%xmm0 \n" \
"aesdec 112(%["#sched"]), %%xmm0 \n" \
"aesdec 96(%["#sched"]), %%xmm0 \n" \
"aesdec 80(%["#sched"]), %%xmm0 \n" \
"aesdec 64(%["#sched"]), %%xmm0 \n" \
"aesdec 48(%["#sched"]), %%xmm0 \n" \
"aesdec 32(%["#sched"]), %%xmm0 \n" \
"aesdec 16(%["#sched"]), %%xmm0 \n" \
"aesdeclast (%["#sched"]), %%xmm0 \n"
void ECBDecryptionAESNI::Decrypt (const ChipherBlock * in, ChipherBlock * out)
{
__asm__
(
"movups (%[in]), %%xmm0 \n"
DecryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
);
}
#define CallAESIMC(offset) \
"movaps "#offset"(%[shed]), %%xmm0 \n" \
"aesimc %%xmm0, %%xmm0 \n" \
"movaps %%xmm0, "#offset"(%[shed]) \n"
void ECBDecryptionAESNI::SetKey (const AESKey& key)
{
ExpandKey (key); // expand encryption key first
// then invert it using aesimc
__asm__
(
CallAESIMC(16)
CallAESIMC(32)
CallAESIMC(48)
CallAESIMC(64)
CallAESIMC(80)
CallAESIMC(96)
CallAESIMC(112)
CallAESIMC(128)
CallAESIMC(144)
CallAESIMC(160)
CallAESIMC(176)
CallAESIMC(192)
CallAESIMC(208)
: : [shed]"r"(GetKeySchedule ()) : "%xmm0", "memory"
);
}
#endif
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
{
#ifdef AESNI
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched)
"movaps %%xmm0, %%xmm1 \n"
"movups %%xmm0, (%[out]) \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"dec %[num] \n"
"jnz 1b \n"
"movups %%xmm1, (%[iv]) \n"
:
: [iv]"r"(&m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
: "%xmm0", "%xmm1", "cc", "memory"
);
#else
for (int i = 0; i < numBlocks; i++)
{
m_LastBlock ^= in[i];
m_ECBEncryption.Encrypt (&m_LastBlock, &m_LastBlock);
out[i] = m_LastBlock;
}
#endif
}
void CBCEncryption::Encrypt (const uint8_t * in, std::size_t len, uint8_t * out)
{
// len/16
int numBlocks = len >> 4;
if (numBlocks > 0)
Encrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
}
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
{
#ifdef AESNI
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched)
"movups %%xmm0, (%[out]) \n"
"movups %%xmm0, (%[iv]) \n"
:
: [iv]"r"(&m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory"
);
#else
Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
#endif
}
void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
{
#ifdef AESNI
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"1: \n"
"movups (%[in]), %%xmm0 \n"
"movaps %%xmm0, %%xmm2 \n"
DecryptAES256(sched)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
"movaps %%xmm2, %%xmm1 \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"dec %[num] \n"
"jnz 1b \n"
"movups %%xmm1, (%[iv]) \n"
:
: [iv]"r"(&m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
: "%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;
m_IV = tmp;
}
#endif
}
void CBCDecryption::Decrypt (const uint8_t * in, std::size_t len, uint8_t * out)
{
int numBlocks = len >> 4;
if (numBlocks > 0)
Decrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
}
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
{
#ifdef AESNI
__asm__
(
"movups (%[iv]), %%xmm1 \n"
"movups (%[in]), %%xmm0 \n"
"movups %%xmm0, (%[iv]) \n"
DecryptAES256(sched)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
:
: [iv]"r"(&m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out)
: "%xmm0", "%xmm1", "memory"
);
#else
Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
#endif
}
void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out)
{
#ifdef AESNI
__asm__
(
// encrypt IV
"movups (%[in]), %%xmm0 \n"
EncryptAES256(sched_iv)
"movaps %%xmm0, %%xmm1 \n"
// double IV encryption
EncryptAES256(sched_iv)
"movups %%xmm0, (%[out]) \n"
// encrypt data, IV is xmm1
"1: \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"movups (%[in]), %%xmm0 \n"
"pxor %%xmm1, %%xmm0 \n"
EncryptAES256(sched_l)
"movaps %%xmm0, %%xmm1 \n"
"movups %%xmm0, (%[out]) \n"
"dec %[num] \n"
"jnz 1b \n"
:
: [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%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*/1008, out + 16); // data
m_IVEncryption.Encrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
#endif
}
void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out)
{
#ifdef AESNI
__asm__
(
// decrypt IV
"movups (%[in]), %%xmm0 \n"
DecryptAES256(sched_iv)
"movaps %%xmm0, %%xmm1 \n"
// double IV encryption
DecryptAES256(sched_iv)
"movups %%xmm0, (%[out]) \n"
// decrypt data, IV is xmm1
"1: \n"
"add $16, %[in] \n"
"add $16, %[out] \n"
"movups (%[in]), %%xmm0 \n"
"movaps %%xmm0, %%xmm2 \n"
DecryptAES256(sched_l)
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[out]) \n"
"movaps %%xmm2, %%xmm1 \n"
"dec %[num] \n"
"jnz 1b \n"
:
: [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.GetKeySchedule ()),
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
: "%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*/1008, out + 16); // data
m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
#endif
}
}
}

322
Crypto.h
View File

@ -1,322 +0,0 @@
#ifndef CRYPTO_H__
#define CRYPTO_H__
#include <inttypes.h>
#include <string>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/aes.h>
#include "Base.h"
namespace i2p
{
namespace crypto
{
struct CryptoConstants
{
// DH/ElGamal
BIGNUM * elgp;
BIGNUM * elgg;
// DSA
BIGNUM * dsap;
BIGNUM * dsaq;
BIGNUM * dsag;
// RSA
BIGNUM * rsae;
CryptoConstants (const uint8_t * elgp_, int elgg_, const uint8_t * dsap_,
const uint8_t * dsaq_, const uint8_t * dsag_, int rsae_)
{
elgp = BN_new ();
BN_bin2bn (elgp_, 256, elgp);
elgg = BN_new ();
BN_set_word (elgg, elgg_);
dsap = BN_new ();
BN_bin2bn (dsap_, 128, dsap);
dsaq = BN_new ();
BN_bin2bn (dsaq_, 20, dsaq);
dsag = BN_new ();
BN_bin2bn (dsag_, 128, dsag);
rsae = BN_new ();
BN_set_word (rsae, rsae_);
}
~CryptoConstants ()
{
BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae);
}
};
const CryptoConstants& GetCryptoConstants ();
// DH/ElGamal
#define elgp GetCryptoConstants ().elgp
#define elgg GetCryptoConstants ().elgg
// DSA
#define dsap GetCryptoConstants ().dsap
#define dsaq GetCryptoConstants ().dsaq
#define dsag GetCryptoConstants ().dsag
// RSA
#define rsae GetCryptoConstants ().rsae
bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len);
// DH
class DHKeys
{
public:
DHKeys ();
~DHKeys ();
void GenerateKeys (uint8_t * priv = nullptr, uint8_t * pub = nullptr);
const uint8_t * GetPublicKey ();
void Agree (const uint8_t * pub, uint8_t * shared);
private:
DH * m_DH;
uint8_t m_PublicKey[256];
bool m_IsUpdated;
};
// ElGamal
class ElGamalEncryption
{
public:
ElGamalEncryption (const uint8_t * key);
~ElGamalEncryption ();
void Encrypt (const uint8_t * data, int len, uint8_t * encrypted, bool zeroPadding = false) const;
private:
BN_CTX * ctx;
BIGNUM * a, * b1;
};
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, bool zeroPadding = false);
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub);
// HMAC
typedef i2p::data::Tag<32> MACKey;
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest);
// AES
struct ChipherBlock
{
uint8_t buf[16];
void operator^=(const ChipherBlock& other) // XOR
{
#if defined(__x86_64__) // for Intel x64
__asm__
(
"movups (%[buf]), %%xmm0 \n"
"movups (%[other]), %%xmm1 \n"
"pxor %%xmm1, %%xmm0 \n"
"movups %%xmm0, (%[buf]) \n"
:
: [buf]"r"(buf), [other]"r"(other.buf)
: "%xmm0", "%xmm1", "memory"
);
#else
// TODO: implement it better
for (int i = 0; i < 16; i++)
buf[i] ^= other.buf[i];
#endif
}
};
typedef i2p::data::Tag<32> AESKey;
template<size_t sz>
class AESAlignedBuffer // 16 bytes alignment
{
public:
AESAlignedBuffer ()
{
m_Buf = m_UnalignedBuffer;
uint8_t rem = ((size_t)m_Buf) & 0x0f;
if (rem)
m_Buf += (16 - rem);
}
operator uint8_t * () { return m_Buf; };
operator const uint8_t * () const { return m_Buf; };
private:
uint8_t m_UnalignedBuffer[sz + 15]; // up to 15 bytes alignment
uint8_t * m_Buf;
};
#ifdef AESNI
class ECBCryptoAESNI
{
public:
uint8_t * GetKeySchedule () { return m_KeySchedule; };
protected:
void ExpandKey (const AESKey& key);
private:
AESAlignedBuffer<240> m_KeySchedule; // 14 rounds for AES-256, 240 bytes
};
class ECBEncryptionAESNI: public ECBCryptoAESNI
{
public:
void SetKey (const AESKey& key) { ExpandKey (key); };
void Encrypt (const ChipherBlock * in, ChipherBlock * out);
};
class ECBDecryptionAESNI: public ECBCryptoAESNI
{
public:
void SetKey (const AESKey& key);
void Decrypt (const ChipherBlock * in, ChipherBlock * out);
};
typedef ECBEncryptionAESNI ECBEncryption;
typedef ECBDecryptionAESNI ECBDecryption;
#else // use openssl
class ECBEncryption
{
public:
void SetKey (const AESKey& key)
{
AES_set_encrypt_key (key, 256, &m_Key);
}
void Encrypt (const ChipherBlock * in, ChipherBlock * out)
{
AES_encrypt (in->buf, out->buf, &m_Key);
}
private:
AES_KEY m_Key;
};
class ECBDecryption
{
public:
void SetKey (const AESKey& key)
{
AES_set_decrypt_key (key, 256, &m_Key);
}
void Decrypt (const ChipherBlock * in, ChipherBlock * out)
{
AES_decrypt (in->buf, out->buf, &m_Key);
}
private:
AES_KEY m_Key;
};
#endif
class CBCEncryption
{
public:
CBCEncryption () { memset (m_LastBlock.buf, 0, 16); };
void SetKey (const AESKey& key) { m_ECBEncryption.SetKey (key); }; // 32 bytes
void SetIV (const uint8_t * iv) { memcpy (m_LastBlock.buf, iv, 16); }; // 16 bytes
void Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out);
void Encrypt (const uint8_t * in, std::size_t len, uint8_t * out);
void Encrypt (const uint8_t * in, uint8_t * out); // one block
private:
ChipherBlock m_LastBlock;
ECBEncryption m_ECBEncryption;
};
class CBCDecryption
{
public:
CBCDecryption () { memset (m_IV.buf, 0, 16); };
void SetKey (const AESKey& key) { m_ECBDecryption.SetKey (key); }; // 32 bytes
void SetIV (const uint8_t * iv) { memcpy (m_IV.buf, iv, 16); }; // 16 bytes
void Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out);
void Decrypt (const uint8_t * in, std::size_t len, uint8_t * out);
void Decrypt (const uint8_t * in, uint8_t * out); // one block
private:
ChipherBlock m_IV;
ECBDecryption m_ECBDecryption;
};
class TunnelEncryption // with double IV encryption
{
public:
void SetKeys (const AESKey& layerKey, const AESKey& ivKey)
{
m_LayerEncryption.SetKey (layerKey);
m_IVEncryption.SetKey (ivKey);
}
void Encrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data)
private:
ECBEncryption m_IVEncryption;
#ifdef AESNI
ECBEncryption m_LayerEncryption;
#else
CBCEncryption m_LayerEncryption;
#endif
};
class TunnelDecryption // with double IV encryption
{
public:
void SetKeys (const AESKey& layerKey, const AESKey& ivKey)
{
m_LayerDecryption.SetKey (layerKey);
m_IVDecryption.SetKey (ivKey);
}
void Decrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data)
private:
ECBDecryption m_IVDecryption;
#ifdef AESNI
ECBDecryption m_LayerDecryption;
#else
CBCDecryption m_LayerDecryption;
#endif
};
}
}
#endif

View File

@ -1,73 +0,0 @@
#include <inttypes.h>
#include "CryptoConst.h"
namespace i2p
{
namespace crypto
{
const uint8_t elgp_[256]=
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
const uint8_t dsap_[128]=
{
0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c,
0x30, 0x26, 0xe9, 0xb8, 0xed, 0x92, 0xfa, 0xd0, 0xa6, 0x9c, 0xc8, 0x86, 0xd5, 0xbf, 0x80, 0x15,
0xfc, 0xad, 0xae, 0x31, 0xa0, 0xad, 0x18, 0xfa, 0xb3, 0xf0, 0x1b, 0x00, 0xa3, 0x58, 0xde, 0x23,
0x76, 0x55, 0xc4, 0x96, 0x4a, 0xfa, 0xa2, 0xb3, 0x37, 0xe9, 0x6a, 0xd3, 0x16, 0xb9, 0xfb, 0x1c,
0xc5, 0x64, 0xb5, 0xae, 0xc5, 0xb6, 0x9a, 0x9f, 0xf6, 0xc3, 0xe4, 0x54, 0x87, 0x07, 0xfe, 0xf8,
0x50, 0x3d, 0x91, 0xdd, 0x86, 0x02, 0xe8, 0x67, 0xe6, 0xd3, 0x5d, 0x22, 0x35, 0xc1, 0x86, 0x9c,
0xe2, 0x47, 0x9c, 0x3b, 0x9d, 0x54, 0x01, 0xde, 0x04, 0xe0, 0x72, 0x7f, 0xb3, 0x3d, 0x65, 0x11,
0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93
};
const uint8_t dsaq_[20]=
{
0xa5, 0xdf, 0xc2, 0x8f, 0xef, 0x4c, 0xa1, 0xe2, 0x86, 0x74, 0x4c, 0xd8, 0xee, 0xd9, 0xd2, 0x9d,
0x68, 0x40, 0x46, 0xb7
};
const uint8_t dsag_[128]=
{
0x0c, 0x1f, 0x4d, 0x27, 0xd4, 0x00, 0x93, 0xb4, 0x29, 0xe9, 0x62, 0xd7, 0x22, 0x38, 0x24, 0xe0,
0xbb, 0xc4, 0x7e, 0x7c, 0x83, 0x2a, 0x39, 0x23, 0x6f, 0xc6, 0x83, 0xaf, 0x84, 0x88, 0x95, 0x81,
0x07, 0x5f, 0xf9, 0x08, 0x2e, 0xd3, 0x23, 0x53, 0xd4, 0x37, 0x4d, 0x73, 0x01, 0xcd, 0xa1, 0xd2,
0x3c, 0x43, 0x1f, 0x46, 0x98, 0x59, 0x9d, 0xda, 0x02, 0x45, 0x18, 0x24, 0xff, 0x36, 0x97, 0x52,
0x59, 0x36, 0x47, 0xcc, 0x3d, 0xdc, 0x19, 0x7d, 0xe9, 0x85, 0xe4, 0x3d, 0x13, 0x6c, 0xdc, 0xfc,
0x6b, 0xd5, 0x40, 0x9c, 0xd2, 0xf4, 0x50, 0x82, 0x11, 0x42, 0xa5, 0xe6, 0xf8, 0xeb, 0x1c, 0x3a,
0xb5, 0xd0, 0x48, 0x4b, 0x81, 0x29, 0xfc, 0xf1, 0x7b, 0xce, 0x4f, 0x7f, 0x33, 0x32, 0x1c, 0x3c,
0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82
};
const CryptoConstants& GetCryptoConstants ()
{
static CryptoConstants cryptoConstants =
{
{elgp_, 256}, // elgp
{2}, // elgg
{dsap_, 128}, // dsap
{dsaq_, 20}, // dsaq
{dsag_, 128} // dsag
};
return cryptoConstants;
}
}
}

View File

@ -1,38 +0,0 @@
#ifndef CRYPTO_CONST_H__
#define CRYPTO_CONST_H__
#include <cryptopp/integer.h>
namespace i2p
{
namespace crypto
{
struct CryptoConstants
{
// DH/ElGamal
const CryptoPP::Integer elgp;
const CryptoPP::Integer elgg;
// DSA
const CryptoPP::Integer dsap;
const CryptoPP::Integer dsaq;
const CryptoPP::Integer dsag;
};
const CryptoConstants& GetCryptoConstants ();
// DH/ElGamal
#define elgp GetCryptoConstants ().elgp
#define elgg GetCryptoConstants ().elgg
// DSA
#define dsap GetCryptoConstants ().dsap
#define dsaq GetCryptoConstants ().dsaq
#define dsag GetCryptoConstants ().dsag
// RSA
const int rsae = 65537;
}
}
#endif

View File

@ -1,174 +0,0 @@
#include <thread>
#include <memory>
#include "Daemon.h"
#include "Log.h"
#include "Base.h"
#include "version.h"
#include "Transports.h"
#include "NTCPSession.h"
#include "RouterInfo.h"
#include "RouterContext.h"
#include "Tunnel.h"
#include "NetDb.h"
#include "Garlic.h"
#include "util.h"
#include "Streaming.h"
#include "Destination.h"
#include "HTTPServer.h"
#include "I2PControl.h"
#include "ClientContext.h"
// ssl.h somehow pulls Windows.h stuff that has to go after asio
#include <openssl/ssl.h>
#ifdef USE_UPNP
#include "UPnP.h"
#endif
namespace i2p
{
namespace util
{
class Daemon_Singleton::Daemon_Singleton_Private
{
public:
Daemon_Singleton_Private() {};
~Daemon_Singleton_Private() {};
std::unique_ptr<i2p::util::HTTPServer> httpServer;
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
#ifdef USE_UPNP
i2p::transport::UPnP m_UPnP;
#endif
};
Daemon_Singleton::Daemon_Singleton() : running(1), d(*new Daemon_Singleton_Private()) {};
Daemon_Singleton::~Daemon_Singleton() {
delete &d;
};
bool Daemon_Singleton::IsService () const
{
#ifndef _WIN32
return i2p::util::config::GetArg("-service", 0);
#else
return false;
#endif
}
bool Daemon_Singleton::init(int argc, char* argv[])
{
SSL_library_init ();
i2p::util::config::OptionParser(argc, argv);
i2p::context.Init ();
LogPrint("\n\n\n\ni2pd starting\n");
LogPrint("Version ", VERSION);
LogPrint("data directory: ", i2p::util::filesystem::GetDataDir().string());
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
isDaemon = i2p::util::config::GetArg("-daemon", 0);
isLogging = i2p::util::config::GetArg("-log", 1);
int port = i2p::util::config::GetArg("-port", 0);
if (port)
i2p::context.UpdatePort (port);
const char * host = i2p::util::config::GetCharArg("-host", "");
if (host && host[0])
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (host));
i2p::context.SetSupportsV6 (i2p::util::config::GetArg("-v6", 0));
i2p::context.SetFloodfill (i2p::util::config::GetArg("-floodfill", 0));
auto bandwidth = i2p::util::config::GetArg("-bandwidth", "");
if (bandwidth.length () > 0)
{
if (bandwidth[0] > 'L')
i2p::context.SetHighBandwidth ();
else
i2p::context.SetLowBandwidth ();
}
LogPrint("CMD parameters:");
for (int i = 0; i < argc; ++i)
LogPrint(i, " ", argv[i]);
return true;
}
bool Daemon_Singleton::start()
{
// initialize log
if (isLogging)
{
if (isDaemon)
{
std::string logfile_path = IsService () ? "/var/log" : i2p::util::filesystem::GetDataDir().string();
#ifndef _WIN32
logfile_path.append("/i2pd.log");
#else
logfile_path.append("\\i2pd.log");
#endif
StartLog (logfile_path);
}
else
StartLog (""); // write to stdout
}
d.httpServer = std::unique_ptr<i2p::util::HTTPServer>(new i2p::util::HTTPServer(i2p::util::config::GetArg("-httpport", 7070)));
d.httpServer->Start();
LogPrint("HTTP Server started");
i2p::data::netdb.Start();
LogPrint("NetDB started");
#ifdef USE_UPNP
d.m_UPnP.Start ();
LogPrint(eLogInfo, "UPnP started");
#endif
i2p::transport::transports.Start();
LogPrint("Transports started");
i2p::tunnel::tunnels.Start();
LogPrint("Tunnels started");
i2p::client::context.Start ();
LogPrint("Client started");
// I2P Control
int i2pcontrolPort = i2p::util::config::GetArg("-i2pcontrolport", 0);
if (i2pcontrolPort)
{
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcontrolPort));
d.m_I2PControlService->Start ();
LogPrint("I2PControl started");
}
return true;
}
bool Daemon_Singleton::stop()
{
LogPrint("Shutdown started.");
i2p::client::context.Stop();
LogPrint("Client stopped");
i2p::tunnel::tunnels.Stop();
LogPrint("Tunnels stopped");
#ifdef USE_UPNP
d.m_UPnP.Stop ();
LogPrint(eLogInfo, "UPnP stopped");
#endif
i2p::transport::transports.Stop();
LogPrint("Transports stopped");
i2p::data::netdb.Stop();
LogPrint("NetDB stopped");
d.httpServer->Stop();
d.httpServer = nullptr;
LogPrint("HTTP Server stopped");
if (d.m_I2PControlService)
{
d.m_I2PControlService->Stop ();
d.m_I2PControlService = nullptr;
LogPrint("I2PControl stopped");
}
StopLog ();
return true;
}
}
}

View File

@ -1,71 +0,0 @@
#pragma once
#include <string>
#ifdef _WIN32
#define Daemon i2p::util::DaemonWin32::Instance()
#else
#define Daemon i2p::util::DaemonLinux::Instance()
#endif
namespace i2p
{
namespace util
{
class Daemon_Singleton_Private;
class Daemon_Singleton
{
public:
virtual bool init(int argc, char* argv[]);
virtual bool start();
virtual bool stop();
int isLogging;
int isDaemon;
int running;
protected:
Daemon_Singleton();
virtual ~Daemon_Singleton();
bool IsService () const;
// d-pointer for httpServer, httpProxy, etc.
class Daemon_Singleton_Private;
Daemon_Singleton_Private &d;
};
#ifdef _WIN32
class DaemonWin32 : public Daemon_Singleton
{
public:
static DaemonWin32& Instance()
{
static DaemonWin32 instance;
return instance;
}
virtual bool init(int argc, char* argv[]);
virtual bool start();
virtual bool stop();
};
#else
class DaemonLinux : public Daemon_Singleton
{
public:
static DaemonLinux& Instance()
{
static DaemonLinux instance;
return instance;
}
virtual bool start();
virtual bool stop();
private:
std::string pidfile;
int pidFilehandle;
};
#endif
}
}

View File

@ -1,119 +0,0 @@
#include "Daemon.h"
#ifndef _WIN32
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "Log.h"
#include "util.h"
void handle_signal(int sig)
{
switch (sig)
{
case SIGHUP:
if (i2p::util::config::GetArg("daemon", 0) == 1)
{
static bool first=true;
if (first)
{
first=false;
return;
}
}
LogPrint("Reloading config.");
i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
break;
case SIGABRT:
case SIGTERM:
case SIGINT:
Daemon.running = 0; // Exit loop
break;
}
}
namespace i2p
{
namespace util
{
bool DaemonLinux::start()
{
if (isDaemon == 1)
{
pid_t pid;
pid = fork();
if (pid > 0) // parent
::exit (EXIT_SUCCESS);
if (pid < 0) // error
return false;
// child
umask(0);
int sid = setsid();
if (sid < 0)
{
LogPrint("Error, could not create process group.");
return false;
}
std::string d(i2p::util::filesystem::GetDataDir().string ()); // make a copy
chdir(d.c_str());
// close stdin/stdout/stderr descriptors
::close (0);
::open ("/dev/null", O_RDWR);
::close (1);
::open ("/dev/null", O_RDWR);
::close (2);
::open ("/dev/null", O_RDWR);
}
// Pidfile
pidfile = IsService () ? "/var/run" : i2p::util::filesystem::GetDataDir().string();
pidfile.append("/i2pd.pid");
pidFilehandle = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
if (pidFilehandle == -1)
{
LogPrint("Error, could not create pid file (", pidfile, ")\nIs an instance already running?");
return false;
}
if (lockf(pidFilehandle, F_TLOCK, 0) == -1)
{
LogPrint("Error, could not lock pid file (", pidfile, ")\nIs an instance already running?");
return false;
}
char pid[10];
sprintf(pid, "%d\n", getpid());
write(pidFilehandle, pid, strlen(pid));
// Signal handler
struct sigaction sa;
sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGHUP, &sa, 0);
sigaction(SIGABRT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
sigaction(SIGINT, &sa, 0);
return Daemon_Singleton::start();
}
bool DaemonLinux::stop()
{
close(pidFilehandle);
unlink(pidfile.c_str());
return Daemon_Singleton::stop();
}
}
}
#endif

View File

@ -1,83 +0,0 @@
#include "Daemon.h"
#include "util.h"
#include "Log.h"
#ifdef _WIN32
#include "./Win32/Win32Service.h"
namespace i2p
{
namespace util
{
bool DaemonWin32::init(int argc, char* argv[])
{
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
if (!Daemon_Singleton::init(argc, argv)) return false;
if (I2PService::isService())
isDaemon = 1;
else
isDaemon = 0;
std::string serviceControl = i2p::util::config::GetArg("-service", "none");
if (serviceControl == "install")
{
InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
);
exit(0);
}
else if (serviceControl == "remove")
{
UninstallService(SERVICE_NAME);
exit(0);
}
else if (serviceControl != "none")
{
printf(" --service=install to install the service.\n");
printf(" --service=remove to remove the service.\n");
}
if (isDaemon == 1)
{
LogPrint("Service session");
I2PService service(SERVICE_NAME);
if (!I2PService::Run(service))
{
LogPrint("Service failed to run w/err 0x%08lx\n", GetLastError());
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
else
LogPrint("User session");
return true;
}
bool DaemonWin32::start()
{
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
return Daemon_Singleton::start();
}
bool DaemonWin32::stop()
{
return Daemon_Singleton::stop();
}
}
}
#endif

View File

@ -1,150 +0,0 @@
#include <string.h>
#include <vector>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include "Log.h"
#include "TunnelBase.h"
#include "RouterContext.h"
#include "Destination.h"
#include "Datagram.h"
namespace i2p
{
namespace datagram
{
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
m_Owner (owner), m_Receiver (nullptr)
{
}
DatagramDestination::~DatagramDestination ()
{
}
void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort, uint16_t toPort)
{
uint8_t buf[MAX_DATAGRAM_SIZE];
auto identityLen = m_Owner->GetIdentity ()->ToBuffer (buf, MAX_DATAGRAM_SIZE);
uint8_t * signature = buf + identityLen;
auto signatureLen = m_Owner->GetIdentity ()->GetSignatureLen ();
uint8_t * buf1 = signature + signatureLen;
size_t headerLen = identityLen + signatureLen;
memcpy (buf1, payload, len);
if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
{
uint8_t hash[32];
SHA256(buf1, len, hash);
m_Owner->Sign (hash, 32, signature);
}
else
m_Owner->Sign (buf1, len, signature);
auto msg = CreateDataMessage (buf, len + headerLen, fromPort, toPort);
auto remote = m_Owner->FindLeaseSet (ident);
if (remote)
m_Owner->GetService ().post (std::bind (&DatagramDestination::SendMsg, this, msg, remote));
else
m_Owner->RequestDestination (ident, std::bind (&DatagramDestination::HandleLeaseSetRequestComplete, this, std::placeholders::_1, msg));
}
void DatagramDestination::HandleLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> remote, I2NPMessage * msg)
{
if (remote)
SendMsg (msg, remote);
else
DeleteI2NPMessage (msg);
}
void DatagramDestination::SendMsg (I2NPMessage * msg, std::shared_ptr<const i2p::data::LeaseSet> remote)
{
auto outboundTunnel = m_Owner->GetTunnelPool ()->GetNextOutboundTunnel ();
auto leases = remote->GetNonExpiredLeases ();
if (!leases.empty () && outboundTunnel)
{
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
uint32_t i = rand () % leases.size ();
auto garlic = m_Owner->WrapMessage (remote, ToSharedI2NPMessage (msg), true);
msgs.push_back (i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeTunnel,
leases[i].tunnelGateway, leases[i].tunnelID,
garlic
});
outboundTunnel->SendTunnelDataMsg (msgs);
}
else
{
if (outboundTunnel)
LogPrint (eLogWarning, "Failed to send datagram. All leases expired");
else
LogPrint (eLogWarning, "Failed to send datagram. No outbound tunnels");
DeleteI2NPMessage (msg);
}
}
void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{
i2p::data::IdentityEx identity;
size_t identityLen = identity.FromBuffer (buf, len);
const uint8_t * signature = buf + identityLen;
size_t headerLen = identityLen + identity.GetSignatureLen ();
bool verified = false;
if (identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
{
uint8_t hash[32];
SHA256(buf + headerLen, len - headerLen, hash);
verified = identity.Verify (hash, 32, signature);
}
else
verified = identity.Verify (buf + headerLen, len - headerLen, signature);
if (verified)
{
auto it = m_ReceiversByPorts.find (toPort);
if (it != m_ReceiversByPorts.end ())
it->second (identity, fromPort, toPort, buf + headerLen, len -headerLen);
else if (m_Receiver != nullptr)
m_Receiver (identity, fromPort, toPort, buf + headerLen, len -headerLen);
else
LogPrint (eLogWarning, "Receiver for datagram is not set");
}
else
LogPrint (eLogWarning, "Datagram signature verification failed");
}
void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{
// unzip it
uint8_t uncompressed[MAX_DATAGRAM_SIZE];
size_t uncompressedLen = m_Inflator.Inflate (buf, len, uncompressed, MAX_DATAGRAM_SIZE);
if (uncompressedLen)
HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen);
}
I2NPMessage * DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
{
I2NPMessage * msg = NewI2NPMessage ();
uint8_t * buf = msg->GetPayload ();
buf += 4; // reserve for length
size_t size = m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len);
if (size)
{
htobe32buf (msg->GetPayload (), size); // length
htobe16buf (buf + 4, fromPort); // source port
htobe16buf (buf + 6, toPort); // destination port
buf[9] = i2p::client::PROTOCOL_TYPE_DATAGRAM; // datagram protocol
msg->len += size + 4;
msg->FillI2NPMessageHeader (eI2NPData);
}
else
{
DeleteI2NPMessage (msg);
msg = nullptr;
}
return msg;
}
}
}

View File

@ -1,61 +0,0 @@
#ifndef DATAGRAM_H__
#define DATAGRAM_H__
#include <inttypes.h>
#include <memory>
#include <functional>
#include <map>
#include "Base.h"
#include "Identity.h"
#include "LeaseSet.h"
#include "I2NPProtocol.h"
namespace i2p
{
namespace client
{
class ClientDestination;
}
namespace datagram
{
const size_t MAX_DATAGRAM_SIZE = 32768;
class DatagramDestination
{
typedef std::function<void (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)> Receiver;
public:
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner);
~DatagramDestination ();
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort = 0, uint16_t toPort = 0);
void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };
void ResetReceiver () { m_Receiver = nullptr; };
void SetReceiver (const Receiver& receiver, uint16_t port) { m_ReceiversByPorts[port] = receiver; };
void ResetReceiver (uint16_t port) { m_ReceiversByPorts.erase (port); };
private:
void HandleLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, I2NPMessage * msg);
I2NPMessage * CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
void SendMsg (I2NPMessage * msg, std::shared_ptr<const i2p::data::LeaseSet> remote);
void HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
private:
std::shared_ptr<i2p::client::ClientDestination> m_Owner;
Receiver m_Receiver; // default
std::map<uint16_t, Receiver> m_ReceiversByPorts;
i2p::data::GzipInflator m_Inflator;
i2p::data::GzipDeflator m_Deflator;
};
}
}
#endif

View File

@ -1,667 +0,0 @@
#include <algorithm>
#include <cassert>
#include <boost/lexical_cast.hpp>
#include <openssl/rand.h>
#include "Log.h"
#include "util.h"
#include "Crypto.h"
#include "Timestamp.h"
#include "NetDb.h"
#include "Destination.h"
namespace i2p
{
namespace client
{
ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic,
const std::map<std::string, std::string> * params):
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
m_Keys (keys), m_IsPublic (isPublic), m_PublishReplyToken (0),
m_DatagramDestination (nullptr), m_PublishConfirmationTimer (m_Service), m_CleanupTimer (m_Service)
{
i2p::crypto::GenerateElGamalKeyPair(m_EncryptionPrivateKey, m_EncryptionPublicKey);
int inboundTunnelLen = DEFAULT_INBOUND_TUNNEL_LENGTH;
int outboundTunnelLen = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
int inboundTunnelsQuantity = DEFAULT_INBOUND_TUNNELS_QUANTITY;
int outboundTunnelsQuantity = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers;
if (params)
{
auto it = params->find (I2CP_PARAM_INBOUND_TUNNEL_LENGTH);
if (it != params->end ())
{
int len = boost::lexical_cast<int>(it->second);
if (len > 0)
{
inboundTunnelLen = len;
LogPrint (eLogInfo, "Inbound tunnel length set to ", len);
}
}
it = params->find (I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH);
if (it != params->end ())
{
int len = boost::lexical_cast<int>(it->second);
if (len > 0)
{
outboundTunnelLen = len;
LogPrint (eLogInfo, "Outbound tunnel length set to ", len);
}
}
it = params->find (I2CP_PARAM_INBOUND_TUNNELS_QUANTITY);
if (it != params->end ())
{
int quantity = boost::lexical_cast<int>(it->second);
if (quantity > 0)
{
inboundTunnelsQuantity = quantity;
LogPrint (eLogInfo, "Inbound tunnels quantity set to ", quantity);
}
}
it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY);
if (it != params->end ())
{
int quantity = boost::lexical_cast<int>(it->second);
if (quantity > 0)
{
outboundTunnelsQuantity = quantity;
LogPrint (eLogInfo, "Outbound tunnels quantity set to ", quantity);
}
}
it = params->find (I2CP_PARAM_EXPLICIT_PEERS);
if (it != params->end ())
{
explicitPeers = std::make_shared<std::vector<i2p::data::IdentHash> >();
std::stringstream ss(it->second);
std::string b64;
while (std::getline (ss, b64, ','))
{
i2p::data::IdentHash ident;
ident.FromBase64 (b64);
explicitPeers->push_back (ident);
}
LogPrint (eLogInfo, "Explicit peers set to ", it->second);
}
}
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this, inboundTunnelLen, outboundTunnelLen, inboundTunnelsQuantity, outboundTunnelsQuantity);
if (explicitPeers)
m_Pool->SetExplicitPeers (explicitPeers);
if (m_IsPublic)
LogPrint (eLogInfo, "Local address ", GetIdentHash().ToBase32 (), " created");
}
ClientDestination::~ClientDestination ()
{
if (m_IsRunning)
Stop ();
for (auto it: m_LeaseSetRequests)
delete it.second;
if (m_Pool)
i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool);
if (m_DatagramDestination)
delete m_DatagramDestination;
}
void ClientDestination::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint ("Destination: ", ex.what ());
}
}
}
void ClientDestination::Start ()
{
if (!m_IsRunning)
{
m_IsRunning = true;
m_Pool->SetLocalDestination (this);
m_Pool->SetActive (true);
m_Thread = new std::thread (std::bind (&ClientDestination::Run, this));
m_StreamingDestination = std::make_shared<i2p::stream::StreamingDestination> (shared_from_this ()); // TODO:
m_StreamingDestination->Start ();
for (auto it: m_StreamingDestinationsByPorts)
it.second->Start ();
m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT));
m_CleanupTimer.async_wait (std::bind (&ClientDestination::HandleCleanupTimer,
this, std::placeholders::_1));
}
}
void ClientDestination::Stop ()
{
if (m_IsRunning)
{
m_CleanupTimer.cancel ();
m_IsRunning = false;
m_StreamingDestination->Stop ();
m_StreamingDestination = nullptr;
for (auto it: m_StreamingDestinationsByPorts)
it.second->Stop ();
if (m_DatagramDestination)
{
auto d = m_DatagramDestination;
m_DatagramDestination = nullptr;
delete d;
}
if (m_Pool)
{
m_Pool->SetLocalDestination (nullptr);
i2p::tunnel::tunnels.StopTunnelPool (m_Pool);
}
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = 0;
}
}
}
std::shared_ptr<const i2p::data::LeaseSet> ClientDestination::FindLeaseSet (const i2p::data::IdentHash& ident)
{
auto it = m_RemoteLeaseSets.find (ident);
if (it != m_RemoteLeaseSets.end ())
{
if (it->second->HasNonExpiredLeases ())
return it->second;
else
LogPrint ("All leases of remote LeaseSet expired");
}
else
{
auto ls = i2p::data::netdb.FindLeaseSet (ident);
if (ls)
{
m_RemoteLeaseSets[ident] = ls;
return ls;
}
}
return nullptr;
}
std::shared_ptr<const i2p::data::LeaseSet> ClientDestination::GetLeaseSet ()
{
if (!m_Pool) return nullptr;
if (!m_LeaseSet)
UpdateLeaseSet ();
return m_LeaseSet;
}
void ClientDestination::UpdateLeaseSet ()
{
m_LeaseSet.reset (new i2p::data::LeaseSet (*m_Pool));
}
bool ClientDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag)
{
struct
{
uint8_t k[32], t[32];
} data;
memcpy (data.k, key, 32);
memcpy (data.t, tag, 32);
m_Service.post ([this,data](void)
{
this->AddSessionKey (data.k, data.t);
});
return true;
}
void ClientDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{
m_Service.post (std::bind (&ClientDestination::HandleGarlicMessage, this, msg));
}
void ClientDestination::ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
{
m_Service.post (std::bind (&ClientDestination::HandleDeliveryStatusMessage, this, msg));
}
void ClientDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
{
uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET];
switch (typeID)
{
case eI2NPData:
HandleDataMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET));
break;
case eI2NPDeliveryStatus:
// we assume tunnel tests non-encrypted
HandleDeliveryStatusMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from));
break;
case eI2NPDatabaseStore:
HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET));
break;
case eI2NPDatabaseSearchReply:
HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET));
break;
default:
i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from));
}
}
void ClientDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len)
{
uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET);
size_t offset = DATABASE_STORE_HEADER_SIZE;
if (replyToken)
{
LogPrint (eLogInfo, "Reply token is ignored for DatabaseStore");
offset += 36;
}
std::shared_ptr<i2p::data::LeaseSet> leaseSet;
if (buf[DATABASE_STORE_TYPE_OFFSET] == 1) // LeaseSet
{
LogPrint (eLogDebug, "Remote LeaseSet");
auto it = m_RemoteLeaseSets.find (buf + DATABASE_STORE_KEY_OFFSET);
if (it != m_RemoteLeaseSets.end ())
{
leaseSet = it->second;
leaseSet->Update (buf + offset, len - offset);
if (leaseSet->IsValid ())
LogPrint (eLogDebug, "Remote LeaseSet updated");
else
{
LogPrint (eLogDebug, "Remote LeaseSet update failed");
m_RemoteLeaseSets.erase (it);
leaseSet = nullptr;
}
}
else
{
leaseSet = std::make_shared<i2p::data::LeaseSet> (buf + offset, len - offset);
if (leaseSet->IsValid ())
{
LogPrint (eLogDebug, "New remote LeaseSet added");
m_RemoteLeaseSets[buf + DATABASE_STORE_KEY_OFFSET] = leaseSet;
}
else
{
LogPrint (eLogError, "New remote LeaseSet verification failed");
leaseSet = nullptr;
}
}
}
else
LogPrint (eLogError, "Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ". Dropped");
auto it1 = m_LeaseSetRequests.find (buf + DATABASE_STORE_KEY_OFFSET);
if (it1 != m_LeaseSetRequests.end ())
{
it1->second->requestTimeoutTimer.cancel ();
if (it1->second->requestComplete) it1->second->requestComplete (leaseSet);
delete it1->second;
m_LeaseSetRequests.erase (it1);
}
}
void ClientDestination::HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len)
{
i2p::data::IdentHash key (buf);
int num = buf[32]; // num
LogPrint ("DatabaseSearchReply for ", key.ToBase64 (), " num=", num);
auto it = m_LeaseSetRequests.find (key);
if (it != m_LeaseSetRequests.end ())
{
LeaseSetRequest * request = it->second;
bool found = false;
if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST)
{
for (int i = 0; i < num; i++)
{
i2p::data::IdentHash peerHash (buf + 33 + i*32);
auto floodfill = i2p::data::netdb.FindRouter (peerHash);
if (floodfill)
{
LogPrint (eLogInfo, "Requesting ", key.ToBase64 (), " at ", peerHash.ToBase64 ());
if (SendLeaseSetRequest (key, floodfill, request))
found = true;
}
else
{
LogPrint (eLogInfo, "Found new floodfill. Request it");
i2p::data::netdb.RequestDestination (peerHash);
}
}
if (!found)
LogPrint (eLogError, "Suggested floodfills are not presented in netDb");
}
else
LogPrint (eLogInfo, key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST," floodfills");
if (!found)
{
if (request->requestComplete) request->requestComplete (nullptr);
delete request;
m_LeaseSetRequests.erase (key);
}
}
else
LogPrint ("Request for ", key.ToBase64 (), " not found");
}
void ClientDestination::HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
{
uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET);
if (msgID == m_PublishReplyToken)
{
LogPrint (eLogDebug, "Publishing confirmed");
m_ExcludedFloodfills.clear ();
m_PublishReplyToken = 0;
}
else
i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msg);
}
void ClientDestination::SetLeaseSetUpdated ()
{
i2p::garlic::GarlicDestination::SetLeaseSetUpdated ();
UpdateLeaseSet ();
if (m_IsPublic)
Publish ();
}
void ClientDestination::Publish ()
{
if (!m_LeaseSet || !m_Pool)
{
LogPrint (eLogError, "Can't publish non-existing LeaseSet");
return;
}
if (m_PublishReplyToken)
{
LogPrint (eLogInfo, "Publishing is pending");
return;
}
auto outbound = m_Pool->GetNextOutboundTunnel ();
if (!outbound)
{
LogPrint ("Can't publish LeaseSet. No outbound tunnels");
return;
}
std::set<i2p::data::IdentHash> excluded;
auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills);
if (!floodfill)
{
LogPrint ("Can't publish LeaseSet. No more floodfills found");
m_ExcludedFloodfills.clear ();
return;
}
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
LogPrint (eLogDebug, "Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken));
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
m_PublishConfirmationTimer.async_wait (std::bind (&ClientDestination::HandlePublishConfirmationTimer,
this, std::placeholders::_1));
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg);
}
void ClientDestination::HandlePublishConfirmationTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
if (m_PublishReplyToken)
{
LogPrint (eLogWarning, "Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, "seconds. Try again");
m_PublishReplyToken = 0;
Publish ();
}
}
}
void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len)
{
uint32_t length = bufbe32toh (buf);
buf += 4;
// we assume I2CP payload
uint16_t fromPort = bufbe16toh (buf + 4), // source
toPort = bufbe16toh (buf + 6); // destination
switch (buf[9])
{
case PROTOCOL_TYPE_STREAMING:
{
// streaming protocol
auto dest = GetStreamingDestination (toPort);
if (dest)
dest->HandleDataMessagePayload (buf, length);
else
LogPrint ("Missing streaming destination");
}
break;
case PROTOCOL_TYPE_DATAGRAM:
// datagram protocol
if (m_DatagramDestination)
m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length);
else
LogPrint ("Missing streaming destination");
break;
default:
LogPrint ("Data: unexpected protocol ", buf[9]);
}
}
void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) {
assert(streamRequestComplete);
auto leaseSet = FindLeaseSet (dest);
if (leaseSet)
streamRequestComplete(CreateStream (leaseSet, port));
else
{
RequestDestination (dest,
[this, streamRequestComplete, port](std::shared_ptr<i2p::data::LeaseSet> ls)
{
if (ls)
streamRequestComplete(CreateStream (ls, port));
else
streamRequestComplete (nullptr);
});
}
}
std::shared_ptr<i2p::stream::Stream> ClientDestination::CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port)
{
if (m_StreamingDestination)
return m_StreamingDestination->CreateNewOutgoingStream (remote, port);
else
return nullptr;
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::GetStreamingDestination (int port) const
{
if (port)
{
auto it = m_StreamingDestinationsByPorts.find (port);
if (it != m_StreamingDestinationsByPorts.end ())
return it->second;
}
// if port is zero or not found, use default destination
return m_StreamingDestination;
}
void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor)
{
if (m_StreamingDestination)
m_StreamingDestination->SetAcceptor (acceptor);
}
void ClientDestination::StopAcceptingStreams ()
{
if (m_StreamingDestination)
m_StreamingDestination->ResetAcceptor ();
}
bool ClientDestination::IsAcceptingStreams () const
{
if (m_StreamingDestination)
return m_StreamingDestination->IsAcceptorSet ();
return false;
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::CreateStreamingDestination (int port)
{
auto dest = std::make_shared<i2p::stream::StreamingDestination> (shared_from_this (), port);
if (port)
m_StreamingDestinationsByPorts[port] = dest;
else // update default
m_StreamingDestination = dest;
return dest;
}
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination ()
{
if (!m_DatagramDestination)
m_DatagramDestination = new i2p::datagram::DatagramDestination (shared_from_this ());
return m_DatagramDestination;
}
bool ClientDestination::RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete)
{
if (!m_Pool || !IsReady ())
{
if (requestComplete) requestComplete (false);
return false;
}
m_Service.post (std::bind (&ClientDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete));
return true;
}
void ClientDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete)
{
std::set<i2p::data::IdentHash> excluded;
auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, excluded);
if (floodfill)
{
LeaseSetRequest * request = new LeaseSetRequest (m_Service);
request->requestComplete = requestComplete;
auto ret = m_LeaseSetRequests.insert (std::pair<i2p::data::IdentHash, LeaseSetRequest *>(dest,request));
if (ret.second) // inserted
{
if (!SendLeaseSetRequest (dest, floodfill, request))
{
// request failed
if (request->requestComplete) request->requestComplete (nullptr);
delete request;
m_LeaseSetRequests.erase (dest);
}
}
else // duplicate
{
LogPrint (eLogError, "Request of ", dest.ToBase64 (), " is pending already");
// TODO: queue up requests
if (request->requestComplete) request->requestComplete (nullptr);
delete request;
}
}
else
LogPrint (eLogError, "No floodfills found");
}
bool ClientDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest,
std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, LeaseSetRequest * request)
{
auto replyTunnel = m_Pool->GetNextInboundTunnel ();
if (!replyTunnel) LogPrint (eLogError, "No inbound tunnels found");
auto outboundTunnel = m_Pool->GetNextOutboundTunnel ();
if (!outboundTunnel) LogPrint (eLogError, "No outbound tunnels found");
if (replyTunnel && outboundTunnel)
{
request->excluded.insert (nextFloodfill->GetIdentHash ());
request->requestTime = i2p::util::GetSecondsSinceEpoch ();
request->requestTimeoutTimer.cancel ();
uint8_t replyKey[32], replyTag[32];
RAND_bytes (replyKey, 32); // random session key
RAND_bytes (replyTag, 32); // random session tag
AddSessionKey (replyKey, replyTag);
auto msg = WrapMessage (nextFloodfill,
CreateLeaseSetDatabaseLookupMsg (dest, request->excluded,
replyTunnel.get (), replyKey, replyTag));
outboundTunnel->SendTunnelDataMsg (
{
i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeRouter,
nextFloodfill->GetIdentHash (), 0, msg
}
});
request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT));
request->requestTimeoutTimer.async_wait (std::bind (&ClientDestination::HandleRequestTimoutTimer,
this, std::placeholders::_1, dest));
}
else
return false;
return true;
}
void ClientDestination::HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest)
{
if (ecode != boost::asio::error::operation_aborted)
{
auto it = m_LeaseSetRequests.find (dest);
if (it != m_LeaseSetRequests.end ())
{
bool done = false;
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
if (ts < it->second->requestTime + MAX_LEASESET_REQUEST_TIMEOUT)
{
auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, it->second->excluded);
if (floodfill)
done = !SendLeaseSetRequest (dest, floodfill, it->second);
else
done = true;
}
else
{
LogPrint (eLogInfo, dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds");
done = true;
}
if (done)
{
if (it->second->requestComplete) it->second->requestComplete (false);
delete it->second;
m_LeaseSetRequests.erase (it);
}
}
}
}
void ClientDestination::HandleCleanupTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
CleanupRoutingSessions ();
CleanupRemoteLeaseSets ();
m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT));
m_CleanupTimer.async_wait (std::bind (&ClientDestination::HandleCleanupTimer,
shared_from_this (), std::placeholders::_1));
}
}
void ClientDestination::CleanupRemoteLeaseSets ()
{
for (auto it = m_RemoteLeaseSets.begin (); it != m_RemoteLeaseSets.end ();)
{
if (!it->second->HasNonExpiredLeases ()) // all leases expired
{
LogPrint ("Remote LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired");
it = m_RemoteLeaseSets.erase (it);
}
else
it++;
}
}
}
}

View File

@ -1,157 +0,0 @@
#ifndef DESTINATION_H__
#define DESTINATION_H__
#include <thread>
#include <mutex>
#include <memory>
#include <map>
#include <set>
#include <string>
#include <functional>
#include <boost/asio.hpp>
#include "Identity.h"
#include "TunnelPool.h"
#include "Crypto.h"
#include "LeaseSet.h"
#include "Garlic.h"
#include "NetDb.h"
#include "Streaming.h"
#include "Datagram.h"
namespace i2p
{
namespace client
{
const uint8_t PROTOCOL_TYPE_STREAMING = 6;
const uint8_t PROTOCOL_TYPE_DATAGRAM = 17;
const uint8_t PROTOCOL_TYPE_RAW = 18;
const int PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds
const int LEASESET_REQUEST_TIMEOUT = 5; // in seconds
const int MAX_LEASESET_REQUEST_TIMEOUT = 40; // in seconds
const int MAX_NUM_FLOODFILLS_PER_REQUEST = 7;
const int DESTINATION_CLEANUP_TIMEOUT = 20; // in minutes
// I2CP
const char I2CP_PARAM_INBOUND_TUNNEL_LENGTH[] = "inbound.length";
const int DEFAULT_INBOUND_TUNNEL_LENGTH = 3;
const char I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH[] = "outbound.length";
const int DEFAULT_OUTBOUND_TUNNEL_LENGTH = 3;
const char I2CP_PARAM_INBOUND_TUNNELS_QUANTITY[] = "inbound.quantity";
const int DEFAULT_INBOUND_TUNNELS_QUANTITY = 5;
const char I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY[] = "outbound.quantity";
const int DEFAULT_OUTBOUND_TUNNELS_QUANTITY = 5;
const char I2CP_PARAM_EXPLICIT_PEERS[] = "explicitPeers";
const int STREAM_REQUEST_TIMEOUT = 60; //in seconds
typedef std::function<void (std::shared_ptr<i2p::stream::Stream> stream)> StreamRequestComplete;
class ClientDestination: public i2p::garlic::GarlicDestination,
public std::enable_shared_from_this<ClientDestination>
{
typedef std::function<void (std::shared_ptr<i2p::data::LeaseSet> leaseSet)> RequestComplete;
// leaseSet = nullptr means not found
struct LeaseSetRequest
{
LeaseSetRequest (boost::asio::io_service& service): requestTime (0), requestTimeoutTimer (service) {};
std::set<i2p::data::IdentHash> excluded;
uint64_t requestTime;
boost::asio::deadline_timer requestTimeoutTimer;
RequestComplete requestComplete;
};
public:
ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map<std::string, std::string> * params = nullptr);
~ClientDestination ();
virtual void Start ();
virtual void Stop ();
bool IsRunning () const { return m_IsRunning; };
boost::asio::io_service& GetService () { return m_Service; };
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () { return m_Pool; };
bool IsReady () const { return m_LeaseSet && m_LeaseSet->HasNonExpiredLeases () && m_Pool->GetOutboundTunnels ().size () > 0; };
std::shared_ptr<const i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
// streaming
std::shared_ptr<i2p::stream::StreamingDestination> CreateStreamingDestination (int port); // additional
std::shared_ptr<i2p::stream::StreamingDestination> GetStreamingDestination (int port = 0) const;
// following methods operate with default streaming destination
void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0);
std::shared_ptr<i2p::stream::Stream> CreateStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port = 0);
void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor);
void StopAcceptingStreams ();
bool IsAcceptingStreams () const;
// datagram
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
i2p::datagram::DatagramDestination * CreateDatagramDestination ();
// implements LocalDestination
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
const uint8_t * GetEncryptionPrivateKey () const { return m_EncryptionPrivateKey; };
const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; };
// implements GarlicDestination
std::shared_ptr<const i2p::data::LeaseSet> GetLeaseSet ();
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const { return m_Pool; }
void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
// override GarlicDestination
bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag);
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
void SetLeaseSetUpdated ();
// I2CP
void HandleDataMessage (const uint8_t * buf, size_t len);
private:
void Run ();
void UpdateLeaseSet ();
void Publish ();
void HandlePublishConfirmationTimer (const boost::system::error_code& ecode);
void HandleDatabaseStoreMessage (const uint8_t * buf, size_t len);
void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len);
void HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete);
bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, LeaseSetRequest * request);
void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest);
void HandleCleanupTimer (const boost::system::error_code& ecode);
void CleanupRemoteLeaseSets ();
private:
volatile bool m_IsRunning;
std::thread * m_Thread;
boost::asio::io_service m_Service;
boost::asio::io_service::work m_Work;
i2p::data::PrivateKeys m_Keys;
uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256];
std::map<i2p::data::IdentHash, std::shared_ptr<i2p::data::LeaseSet> > m_RemoteLeaseSets;
std::map<i2p::data::IdentHash, LeaseSetRequest *> m_LeaseSetRequests;
std::shared_ptr<i2p::tunnel::TunnelPool> m_Pool;
std::shared_ptr<i2p::data::LeaseSet> m_LeaseSet;
bool m_IsPublic;
uint32_t m_PublishReplyToken;
std::set<i2p::data::IdentHash> m_ExcludedFloodfills; // for publishing
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
i2p::datagram::DatagramDestination * m_DatagramDestination;
boost::asio::deadline_timer m_PublishConfirmationTimer, m_CleanupTimer;
public:
// for HTTP only
int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); };
};
}
}
#endif

View File

@ -1,627 +0,0 @@
#include <inttypes.h>
#include "I2PEndian.h"
#include <map>
#include <string>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include "RouterContext.h"
#include "I2NPProtocol.h"
#include "Tunnel.h"
#include "TunnelPool.h"
#include "Timestamp.h"
#include "Log.h"
#include "Garlic.h"
namespace i2p
{
namespace garlic
{
GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner,
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
m_Owner (owner), m_Destination (destination), m_NumTags (numTags),
m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend),
m_ElGamalEncryption (new i2p::crypto::ElGamalEncryption (destination->GetEncryptionPublicKey ()))
{
// create new session tags and session key
RAND_bytes (m_SessionKey, 32);
m_Encryption.SetKey (m_SessionKey);
}
GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag):
m_Owner (nullptr), m_Destination (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend)
{
memcpy (m_SessionKey, sessionKey, 32);
m_Encryption.SetKey (m_SessionKey);
m_SessionTags.push_back (sessionTag);
m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch ();
}
GarlicRoutingSession::~GarlicRoutingSession ()
{
for (auto it: m_UnconfirmedTagsMsgs)
delete it.second;
m_UnconfirmedTagsMsgs.clear ();
}
GarlicRoutingSession::UnconfirmedTags * GarlicRoutingSession::GenerateSessionTags ()
{
auto tags = new UnconfirmedTags (m_NumTags);
tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch ();
for (int i = 0; i < m_NumTags; i++)
{
RAND_bytes (tags->sessionTags[i], 32);
tags->sessionTags[i].creationTime = tags->tagsCreationTime;
}
return tags;
}
void GarlicRoutingSession::MessageConfirmed (uint32_t msgID)
{
TagsConfirmed (msgID);
if (msgID == m_LeaseSetUpdateMsgID)
{
m_LeaseSetUpdateStatus = eLeaseSetUpToDate;
LogPrint (eLogInfo, "LeaseSet update confirmed");
}
else
CleanupExpiredTags ();
}
void GarlicRoutingSession::TagsConfirmed (uint32_t msgID)
{
auto it = m_UnconfirmedTagsMsgs.find (msgID);
if (it != m_UnconfirmedTagsMsgs.end ())
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
UnconfirmedTags * tags = it->second;
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
{
for (int i = 0; i < tags->numTags; i++)
m_SessionTags.push_back (tags->sessionTags[i]);
}
m_UnconfirmedTagsMsgs.erase (it);
delete tags;
}
}
bool GarlicRoutingSession::CleanupExpiredTags ()
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_SessionTags.begin (); it != m_SessionTags.end ();)
{
if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
it = m_SessionTags.erase (it);
else
it++;
}
// delete expired unconfirmed tags
for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();)
{
if (ts >= it->second->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
{
if (m_Owner)
m_Owner->RemoveCreatedSession (it->first);
delete it->second;
it = m_UnconfirmedTagsMsgs.erase (it);
}
else
it++;
}
return !m_SessionTags.empty () || m_UnconfirmedTagsMsgs.empty ();
}
std::shared_ptr<I2NPMessage> GarlicRoutingSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
{
auto m = ToSharedI2NPMessage(NewI2NPMessage ());
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
size_t len = 0;
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
// find non-expired tag
bool tagFound = false;
SessionTag tag;
if (m_NumTags > 0)
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
while (!m_SessionTags.empty ())
{
if (ts < m_SessionTags.front ().creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
{
tag = m_SessionTags.front ();
m_SessionTags.pop_front (); // use same tag only once
tagFound = true;
break;
}
else
m_SessionTags.pop_front (); // remove expired tag
}
}
// create message
if (!tagFound) // new session
{
LogPrint ("No garlic tags available. Use ElGamal");
if (!m_Destination)
{
LogPrint ("Can't use ElGamal for unknown destination");
return nullptr;
}
// create ElGamal block
ElGamalBlock elGamal;
memcpy (elGamal.sessionKey, m_SessionKey, 32);
RAND_bytes (elGamal.preIV, 32); // Pre-IV
uint8_t iv[32]; // IV is first 16 bytes
SHA256(elGamal.preIV, 32, iv);
m_ElGamalEncryption->Encrypt ((uint8_t *)&elGamal, sizeof(elGamal), buf, true);
m_Encryption.SetIV (iv);
buf += 514;
len += 514;
}
else // existing session
{
// session tag
memcpy (buf, tag, 32);
uint8_t iv[32]; // IV is first 16 bytes
SHA256(tag, 32, iv);
m_Encryption.SetIV (iv);
buf += 32;
len += 32;
}
// AES block
len += CreateAESBlock (buf, msg);
htobe32buf (m->GetPayload (), len);
m->len += len + 4;
m->FillI2NPMessageHeader (eI2NPGarlic);
return m;
}
size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg)
{
size_t blockSize = 0;
bool createNewTags = m_Owner && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3);
UnconfirmedTags * newTags = createNewTags ? GenerateSessionTags () : nullptr;
htobuf16 (buf, newTags ? htobe16 (newTags->numTags) : 0); // tag count
blockSize += 2;
if (newTags) // session tags recreated
{
for (int i = 0; i < newTags->numTags; i++)
{
memcpy (buf + blockSize, newTags->sessionTags[i], 32); // tags
blockSize += 32;
}
}
uint32_t * payloadSize = (uint32_t *)(buf + blockSize);
blockSize += 4;
uint8_t * payloadHash = buf + blockSize;
blockSize += 32;
buf[blockSize] = 0; // flag
blockSize++;
size_t len = CreateGarlicPayload (buf + blockSize, msg, newTags);
htobe32buf (payloadSize, len);
SHA256(buf + blockSize, len, payloadHash);
blockSize += len;
size_t rem = blockSize % 16;
if (rem)
blockSize += (16-rem); //padding
m_Encryption.Encrypt(buf, blockSize, buf);
return blockSize;
}
size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, std::shared_ptr<const I2NPMessage> msg, UnconfirmedTags * newTags)
{
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
uint32_t msgID;
RAND_bytes ((uint8_t *)&msgID, 4);
size_t size = 0;
uint8_t * numCloves = payload + size;
*numCloves = 0;
size++;
if (m_Owner)
{
// resubmit non-confirmed LeaseSet
if (m_LeaseSetUpdateStatus == eLeaseSetSubmitted &&
i2p::util::GetMillisecondsSinceEpoch () > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT)
m_LeaseSetUpdateStatus = eLeaseSetUpdated;
// attach DeviveryStatus if necessary
if (newTags || m_LeaseSetUpdateStatus == eLeaseSetUpdated) // new tags created or leaseset updated
{
// clove is DeliveryStatus
auto cloveSize = CreateDeliveryStatusClove (payload + size, msgID);
if (cloveSize > 0) // successive?
{
size += cloveSize;
(*numCloves)++;
if (newTags) // new tags created
m_UnconfirmedTagsMsgs[msgID] = newTags;
m_Owner->DeliveryStatusSent (shared_from_this (), msgID);
}
else
LogPrint ("DeliveryStatus clove was not created");
}
// attach LeaseSet
if (m_LeaseSetUpdateStatus == eLeaseSetUpdated)
{
m_LeaseSetUpdateStatus = eLeaseSetSubmitted;
m_LeaseSetUpdateMsgID = msgID;
m_LeaseSetSubmissionTime = i2p::util::GetMillisecondsSinceEpoch ();
// clove if our leaseSet must be attached
auto leaseSet = CreateDatabaseStoreMsg (m_Owner->GetLeaseSet ());
size += CreateGarlicClove (payload + size, leaseSet, false);
(*numCloves)++;
}
}
if (msg) // clove message ifself if presented
{
size += CreateGarlicClove (payload + size, msg, m_Destination ? m_Destination->IsDestination () : false);
(*numCloves)++;
}
memset (payload + size, 0, 3); // certificate of message
size += 3;
htobe32buf (payload + size, msgID); // MessageID
size += 4;
htobe64buf (payload + size, ts); // Expiration of message
size += 8;
return size;
}
size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg, bool isDestination)
{
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
size_t size = 0;
if (isDestination && m_Destination)
{
buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination
size++;
memcpy (buf + size, m_Destination->GetIdentHash (), 32);
size += 32;
}
else
{
buf[size] = 0;// delivery instructions flag local
size++;
}
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
size += msg->GetLength ();
uint32_t cloveID;
RAND_bytes ((uint8_t *)&cloveID, 4);
htobe32buf (buf + size, cloveID); // CloveID
size += 4;
htobe64buf (buf + size, ts); // Expiration of clove
size += 8;
memset (buf + size, 0, 3); // certificate of clove
size += 3;
return size;
}
size_t GarlicRoutingSession::CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID)
{
size_t size = 0;
if (m_Owner)
{
auto inboundTunnel = m_Owner->GetTunnelPool ()->GetNextInboundTunnel ();
if (inboundTunnel)
{
buf[size] = eGarlicDeliveryTypeTunnel << 5; // delivery instructions flag tunnel
size++;
// hash and tunnelID sequence is reversed for Garlic
memcpy (buf + size, inboundTunnel->GetNextIdentHash (), 32); // To Hash
size += 32;
htobe32buf (buf + size, inboundTunnel->GetNextTunnelID ()); // tunnelID
size += 4;
// create msg
auto msg = CreateDeliveryStatusMsg (msgID);
if (m_Owner)
{
//encrypt
uint8_t key[32], tag[32];
RAND_bytes (key, 32); // random session key
RAND_bytes (tag, 32); // random session tag
m_Owner->SubmitSessionKey (key, tag);
GarlicRoutingSession garlic (key, tag);
msg = garlic.WrapSingleMessage (msg);
}
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
size += msg->GetLength ();
// fill clove
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
uint32_t cloveID;
RAND_bytes ((uint8_t *)&cloveID, 4);
htobe32buf (buf + size, cloveID); // CloveID
size += 4;
htobe64buf (buf + size, ts); // Expiration of clove
size += 8;
memset (buf + size, 0, 3); // certificate of clove
size += 3;
}
else
LogPrint (eLogError, "No inbound tunnels in the pool for DeliveryStatus");
}
else
LogPrint ("Missing local LeaseSet");
return size;
}
GarlicDestination::~GarlicDestination ()
{
}
void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag)
{
if (key)
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
auto decryption = std::make_shared<i2p::crypto::CBCDecryption>();
decryption->SetKey (key);
m_Tags[SessionTag(tag, ts)] = decryption;
}
}
bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag)
{
AddSessionKey (key, tag);
return true;
}
void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{
uint8_t * buf = msg->GetPayload ();
uint32_t length = bufbe32toh (buf);
if (length > msg->GetLength ())
{
LogPrint (eLogError, "Garlic message length ", length, " exceeds I2NP message length ", msg->GetLength ());
return;
}
buf += 4; // length
auto it = m_Tags.find (SessionTag(buf));
if (it != m_Tags.end ())
{
// tag found. Use AES
if (length >= 32)
{
uint8_t iv[32]; // IV is first 16 bytes
SHA256(buf, 32, iv);
it->second->SetIV (iv);
it->second->Decrypt (buf + 32, length - 32, buf + 32);
HandleAESBlock (buf + 32, length - 32, it->second, msg->from);
}
else
LogPrint (eLogError, "Garlic message length ", length, " is less than 32 bytes");
m_Tags.erase (it); // tag might be used only once
}
else
{
// tag not found. Use ElGamal
ElGamalBlock elGamal;
if (length >= 514 && i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, true))
{
auto decryption = std::make_shared<i2p::crypto::CBCDecryption>();
decryption->SetKey (elGamal.sessionKey);
uint8_t iv[32]; // IV is first 16 bytes
SHA256(elGamal.preIV, 32, iv);
decryption->SetIV (iv);
decryption->Decrypt(buf + 514, length - 514, buf + 514);
HandleAESBlock (buf + 514, length - 514, decryption, msg->from);
}
else
LogPrint (eLogError, "Failed to decrypt garlic");
}
// cleanup expired tags
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
if (ts > m_LastTagsCleanupTime + INCOMING_TAGS_EXPIRATION_TIMEOUT)
{
if (m_LastTagsCleanupTime)
{
int numExpiredTags = 0;
for (auto it = m_Tags.begin (); it != m_Tags.end ();)
{
if (ts > it->first.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT)
{
numExpiredTags++;
it = m_Tags.erase (it);
}
else
it++;
}
LogPrint (numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ());
}
m_LastTagsCleanupTime = ts;
}
}
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<i2p::crypto::CBCDecryption> decryption,
std::shared_ptr<i2p::tunnel::InboundTunnel> from)
{
uint16_t tagCount = bufbe16toh (buf);
buf += 2; len -= 2;
if (tagCount > 0)
{
if (tagCount*32 > len)
{
LogPrint (eLogError, "Tag count ", tagCount, " exceeds length ", len);
return ;
}
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
for (int i = 0; i < tagCount; i++)
m_Tags[SessionTag(buf + i*32, ts)] = decryption;
}
buf += tagCount*32;
len -= tagCount*32;
uint32_t payloadSize = bufbe32toh (buf);
if (payloadSize > len)
{
LogPrint (eLogError, "Unexpected payload size ", payloadSize);
return;
}
buf += 4;
uint8_t * payloadHash = buf;
buf += 32;// payload hash.
if (*buf) // session key?
buf += 32; // new session key
buf++; // flag
// payload
uint8_t digest[32];
SHA256 (buf, payloadSize, digest);
if (memcmp (payloadHash, digest, 32)) // payload hash doesn't match
{
LogPrint ("Wrong payload hash");
return;
}
HandleGarlicPayload (buf, payloadSize, from);
}
void GarlicDestination::HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
{
const uint8_t * buf1 = buf;
int numCloves = buf[0];
LogPrint (numCloves," cloves");
buf++;
for (int i = 0; i < numCloves; i++)
{
// delivery instructions
uint8_t flag = buf[0];
buf++; // flag
if (flag & 0x80) // encrypted?
{
// TODO: implement
LogPrint ("Clove encrypted");
buf += 32;
}
GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
switch (deliveryType)
{
case eGarlicDeliveryTypeLocal:
LogPrint ("Garlic type local");
HandleI2NPMessage (buf, len, from);
break;
case eGarlicDeliveryTypeDestination:
LogPrint ("Garlic type destination");
buf += 32; // destination. check it later or for multiple destinations
HandleI2NPMessage (buf, len, from);
break;
case eGarlicDeliveryTypeTunnel:
{
LogPrint ("Garlic type tunnel");
// gwHash and gwTunnel sequence is reverted
uint8_t * gwHash = buf;
buf += 32;
uint32_t gwTunnel = bufbe32toh (buf);
buf += 4;
std::shared_ptr<i2p::tunnel::OutboundTunnel> tunnel;
if (from && from->GetTunnelPool ())
tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
if (tunnel) // we have send it through an outbound tunnel
{
auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from);
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
}
else
LogPrint ("No outbound tunnels available for garlic clove");
break;
}
case eGarlicDeliveryTypeRouter:
LogPrint ("Garlic type router not supported");
buf += 32;
break;
default:
LogPrint ("Unknow garlic delivery type ", (int)deliveryType);
}
buf += GetI2NPMessageLength (buf); // I2NP
buf += 4; // CloveID
buf += 8; // Date
buf += 3; // Certificate
if (buf - buf1 > (int)len)
{
LogPrint (eLogError, "Garlic clove is too long");
break;
}
}
}
std::shared_ptr<I2NPMessage> GarlicDestination::WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet)
{
auto session = GetRoutingSession (destination, attachLeaseSet); // 32 tags by default
return session->WrapSingleMessage (msg);
}
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
{
auto it = m_Sessions.find (destination->GetIdentHash ());
std::shared_ptr<GarlicRoutingSession> session;
if (it != m_Sessions.end ())
session = it->second;
if (!session)
{
session = std::make_shared<GarlicRoutingSession> (this, destination,
attachLeaseSet ? 40 : 4, attachLeaseSet); // 40 tags for connections and 4 for LS requests
std::unique_lock<std::mutex> l(m_SessionsMutex);
m_Sessions[destination->GetIdentHash ()] = session;
}
return session;
}
void GarlicDestination::CleanupRoutingSessions ()
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
for (auto it = m_Sessions.begin (); it != m_Sessions.end ();)
{
if (!it->second->CleanupExpiredTags ())
{
LogPrint (eLogInfo, "Routing session to ", it->first.ToBase32 (), " deleted");
it = m_Sessions.erase (it);
}
else
it++;
}
}
void GarlicDestination::RemoveCreatedSession (uint32_t msgID)
{
m_CreatedSessions.erase (msgID);
}
void GarlicDestination::DeliveryStatusSent (std::shared_ptr<GarlicRoutingSession> session, uint32_t msgID)
{
m_CreatedSessions[msgID] = session;
}
void GarlicDestination::HandleDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
{
uint32_t msgID = bufbe32toh (msg->GetPayload ());
{
auto it = m_CreatedSessions.find (msgID);
if (it != m_CreatedSessions.end ())
{
it->second->MessageConfirmed (msgID);
m_CreatedSessions.erase (it);
LogPrint (eLogInfo, "Garlic message ", msgID, " acknowledged");
}
}
}
void GarlicDestination::SetLeaseSetUpdated ()
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
for (auto it: m_Sessions)
it.second->SetLeaseSetUpdated ();
}
void GarlicDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{
HandleGarlicMessage (msg);
}
void GarlicDestination::ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
{
HandleDeliveryStatusMessage (msg);
}
}
}

View File

@ -1,299 +0,0 @@
#include <cstring>
#include <cassert>
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <string>
#include <atomic>
#include "HTTPProxy.h"
#include "util.h"
#include "Identity.h"
#include "Streaming.h"
#include "Destination.h"
#include "ClientContext.h"
#include "I2PEndian.h"
#include "I2PTunnel.h"
namespace i2p
{
namespace proxy
{
static const size_t http_buffer_size = 8192;
class HTTPProxyHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this<HTTPProxyHandler>
{
private:
enum state
{
GET_METHOD,
GET_HOSTNAME,
GET_HTTPV,
GET_HTTPVNL, //TODO: fallback to finding HOst: header if needed
DONE
};
void EnterState(state nstate);
bool HandleData(uint8_t *http_buff, std::size_t len);
void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
void Terminate();
void AsyncSockRead();
void HTTPRequestFailed(/*std::string message*/);
void ExtractRequest();
bool ValidateHTTPRequest();
void HandleJumpServices();
bool CreateHTTPRequest(uint8_t *http_buff, std::size_t len);
void SentHTTPFailed(const boost::system::error_code & ecode);
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
uint8_t m_http_buff[http_buffer_size];
std::shared_ptr<boost::asio::ip::tcp::socket> m_sock;
std::string m_request; //Data left to be sent
std::string m_url; //URL
std::string m_method; //Method
std::string m_version; //HTTP version
std::string m_address; //Address
std::string m_path; //Path
int m_port; //Port
state m_state;//Parsing state
public:
HTTPProxyHandler(HTTPProxyServer * parent, std::shared_ptr<boost::asio::ip::tcp::socket> sock) :
I2PServiceHandler(parent), m_sock(sock)
{ EnterState(GET_METHOD); }
~HTTPProxyHandler() { Terminate(); }
void Handle () { AsyncSockRead(); }
};
void HTTPProxyHandler::AsyncSockRead()
{
LogPrint(eLogDebug,"--- HTTP Proxy async sock read");
if(m_sock) {
m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size),
std::bind(&HTTPProxyHandler::HandleSockRecv, shared_from_this(),
std::placeholders::_1, std::placeholders::_2));
} else {
LogPrint(eLogError,"--- HTTP Proxy no socket for read");
}
}
void HTTPProxyHandler::Terminate() {
if (Kill()) return;
if (m_sock)
{
LogPrint(eLogDebug,"--- HTTP Proxy close sock");
m_sock->close();
m_sock = nullptr;
}
Done(shared_from_this());
}
/* All hope is lost beyond this point */
//TODO: handle this apropriately
void HTTPProxyHandler::HTTPRequestFailed(/*HTTPProxyHandler::errTypes error*/)
{
static std::string response = "HTTP/1.0 500 Internal Server Error\r\nContent-type: text/html\r\nContent-length: 0\r\n";
boost::asio::async_write(*m_sock, boost::asio::buffer(response,response.size()),
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
}
void HTTPProxyHandler::EnterState(HTTPProxyHandler::state nstate)
{
m_state = nstate;
}
void HTTPProxyHandler::ExtractRequest()
{
LogPrint(eLogDebug,"--- HTTP Proxy method is: ", m_method, "\nRequest is: ", m_url);
std::string server="";
std::string port="80";
boost::regex rHTTP("http://(.*?)(:(\\d+))?(/.*)");
boost::smatch m;
std::string path;
if(boost::regex_search(m_url, m, rHTTP, boost::match_extra))
{
server=m[1].str();
if (m[2].str() != "") port=m[3].str();
path=m[4].str();
}
LogPrint(eLogDebug,"--- HTTP Proxy server is: ",server, " port is: ", port, "\n path is: ",path);
m_address = server;
m_port = boost::lexical_cast<int>(port);
m_path = path;
}
bool HTTPProxyHandler::ValidateHTTPRequest()
{
if ( m_version != "HTTP/1.0" && m_version != "HTTP/1.1" )
{
LogPrint(eLogError,"--- HTTP Proxy unsupported version: ", m_version);
HTTPRequestFailed(); //TODO: send right stuff
return false;
}
return true;
}
void HTTPProxyHandler::HandleJumpServices()
{
static const char * helpermark1 = "?i2paddresshelper=";
static const char * helpermark2 = "&i2paddresshelper=";
size_t addressHelperPos1 = m_path.rfind (helpermark1);
size_t addressHelperPos2 = m_path.rfind (helpermark2);
size_t addressHelperPos;
if (addressHelperPos1 == std::string::npos)
{
if (addressHelperPos2 == std::string::npos)
return; //Not a jump service
else
addressHelperPos = addressHelperPos2;
}
else
{
if (addressHelperPos2 == std::string::npos)
addressHelperPos = addressHelperPos1;
else if ( addressHelperPos1 > addressHelperPos2 )
addressHelperPos = addressHelperPos1;
else
addressHelperPos = addressHelperPos2;
}
auto base64 = m_path.substr (addressHelperPos + strlen(helpermark1));
base64 = i2p::util::http::urlDecode(base64); //Some of the symbols may be urlencoded
LogPrint (eLogDebug,"Jump service for ", m_address, " found at ", base64, ". Inserting to address book");
//TODO: this is very dangerous and broken. We should ask the user before doing anything see http://pastethis.i2p/raw/pn5fL4YNJL7OSWj3Sc6N/
//TODO: we could redirect the user again to avoid dirtiness in the browser
i2p::client::context.GetAddressBook ().InsertAddress (m_address, base64);
m_path.erase(addressHelperPos);
}
bool HTTPProxyHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len)
{
ExtractRequest(); //TODO: parse earlier
if (!ValidateHTTPRequest()) return false;
HandleJumpServices();
m_request = m_method;
m_request.push_back(' ');
m_request += m_path;
m_request.push_back(' ');
m_request += m_version;
m_request.push_back('\r');
m_request.push_back('\n');
m_request.append("Connection: close\r\n");
m_request.append(reinterpret_cast<const char *>(http_buff),len);
return true;
}
bool HTTPProxyHandler::HandleData(uint8_t *http_buff, std::size_t len)
{
assert(len); // This should always be called with a least a byte left to parse
while (len > 0)
{
//TODO: fallback to finding HOst: header if needed
switch (m_state)
{
case GET_METHOD:
switch (*http_buff)
{
case ' ': EnterState(GET_HOSTNAME); break;
default: m_method.push_back(*http_buff); break;
}
break;
case GET_HOSTNAME:
switch (*http_buff)
{
case ' ': EnterState(GET_HTTPV); break;
default: m_url.push_back(*http_buff); break;
}
break;
case GET_HTTPV:
switch (*http_buff)
{
case '\r': EnterState(GET_HTTPVNL); break;
default: m_version.push_back(*http_buff); break;
}
break;
case GET_HTTPVNL:
switch (*http_buff)
{
case '\n': EnterState(DONE); break;
default:
LogPrint(eLogError,"--- HTTP Proxy rejected invalid request ending with: ", ((int)*http_buff));
HTTPRequestFailed(); //TODO: add correct code
return false;
}
break;
default:
LogPrint(eLogError,"--- HTTP Proxy invalid state: ", m_state);
HTTPRequestFailed(); //TODO: add correct code 500
return false;
}
http_buff++;
len--;
if (m_state == DONE)
return CreateHTTPRequest(http_buff,len);
}
return true;
}
void HTTPProxyHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len)
{
LogPrint(eLogDebug,"--- HTTP Proxy sock recv: ", len);
if(ecode)
{
LogPrint(eLogWarning," --- HTTP Proxy sock recv got error: ", ecode);
Terminate();
return;
}
if (HandleData(m_http_buff, len))
{
if (m_state == DONE)
{
LogPrint(eLogInfo,"--- HTTP Proxy requested: ", m_url);
GetOwner()->CreateStream (std::bind (&HTTPProxyHandler::HandleStreamRequestComplete,
shared_from_this(), std::placeholders::_1), m_address, m_port);
}
else
AsyncSockRead();
}
}
void HTTPProxyHandler::SentHTTPFailed(const boost::system::error_code & ecode)
{
if (!ecode)
Terminate();
else
{
LogPrint (eLogError,"--- HTTP Proxy Closing socket after sending failure because: ", ecode.message ());
Terminate();
}
}
void HTTPProxyHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
{
if (stream)
{
if (Kill()) return;
LogPrint (eLogInfo,"--- HTTP Proxy New I2PTunnel connection");
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
GetOwner()->AddHandler (connection);
connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size());
Done(shared_from_this());
}
else
{
LogPrint (eLogError,"--- HTTP Proxy Issue when creating the stream, check the previous warnings for more info.");
HTTPRequestFailed(); // TODO: Send correct error message host unreachable
}
}
HTTPProxyServer::HTTPProxyServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
TCPIPAcceptor(port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())
{
}
std::shared_ptr<i2p::client::I2PServiceHandler> HTTPProxyServer::CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
return std::make_shared<HTTPProxyHandler> (this, socket);
}
}
}

View File

@ -1,32 +0,0 @@
#ifndef HTTP_PROXY_H__
#define HTTP_PROXY_H__
#include <memory>
#include <set>
#include <boost/asio.hpp>
#include <mutex>
#include "I2PService.h"
#include "Destination.h"
namespace i2p
{
namespace proxy
{
class HTTPProxyServer: public i2p::client::TCPIPAcceptor
{
public:
HTTPProxyServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
~HTTPProxyServer() {};
protected:
// Implements TCPIPAcceptor
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
const char* GetName() { return "HTTP Proxy"; }
};
typedef HTTPProxyServer HTTPProxy;
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,139 +0,0 @@
#ifndef HTTP_SERVER_H__
#define HTTP_SERVER_H__
#include <sstream>
#include <thread>
#include <memory>
#include <boost/asio.hpp>
#include <boost/array.hpp>
#include "LeaseSet.h"
#include "Streaming.h"
namespace i2p
{
namespace util
{
const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192;
const int HTTP_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds
class HTTPConnection: public std::enable_shared_from_this<HTTPConnection>
{
protected:
struct header
{
std::string name;
std::string value;
};
struct request
{
std::string method;
std::string uri;
std::string host;
int port;
int http_version_major;
int http_version_minor;
std::vector<header> headers;
};
struct reply
{
std::vector<header> headers;
std::string content;
std::vector<boost::asio::const_buffer> to_buffers (int status);
};
public:
HTTPConnection (boost::asio::ip::tcp::socket * socket):
m_Socket (socket), m_Timer (socket->get_io_service ()),
m_Stream (nullptr), m_BufferLen (0) {};
~HTTPConnection() { delete m_Socket; }
void Receive ();
private:
void Terminate ();
void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void AsyncStreamReceive ();
void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleWriteReply(const boost::system::error_code& ecode);
void HandleWrite (const boost::system::error_code& ecode);
void SendReply (const std::string& content, int status = 200);
void HandleRequest (const std::string& address);
void HandleCommand (const std::string& command, std::stringstream& s);
void ShowTransports (std::stringstream& s);
void ShowTunnels (std::stringstream& s);
void ShowTransitTunnels (std::stringstream& s);
void ShowLocalDestinations (std::stringstream& s);
void ShowLocalDestination (const std::string& b32, std::stringstream& s);
void ShowSAMSessions (std::stringstream& s);
void ShowSAMSession (const std::string& id, std::stringstream& s);
void StartAcceptingTunnels (std::stringstream& s);
void StopAcceptingTunnels (std::stringstream& s);
void RunPeerTest (std::stringstream& s);
void FillContent (std::stringstream& s);
std::string ExtractAddress ();
void ExtractParams (const std::string& str, std::map<std::string, std::string>& params);
protected:
boost::asio::ip::tcp::socket * m_Socket;
boost::asio::deadline_timer m_Timer;
std::shared_ptr<i2p::stream::Stream> m_Stream;
char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1], m_StreamBuffer[HTTP_CONNECTION_BUFFER_SIZE + 1];
size_t m_BufferLen;
request m_Request;
reply m_Reply;
protected:
virtual void RunRequest ();
void HandleDestinationRequest(const std::string& address, const std::string& uri);
void SendToAddress (const std::string& address, int port, const char * buf, size_t len);
void HandleDestinationRequestTimeout (const boost::system::error_code& ecode,
i2p::data::IdentHash destination, int port, const char * buf, size_t len);
void SendToDestination (std::shared_ptr<const i2p::data::LeaseSet> remote, int port, const char * buf, size_t len);
public:
static const std::string itoopieImage;
static const std::string itoopieFavicon;
};
class HTTPServer
{
public:
HTTPServer (int port);
virtual ~HTTPServer ();
void Start ();
void Stop ();
private:
void Run ();
void Accept ();
void HandleAccept(const boost::system::error_code& ecode);
private:
std::thread * m_Thread;
boost::asio::io_service m_Service;
boost::asio::io_service::work m_Work;
boost::asio::ip::tcp::acceptor m_Acceptor;
boost::asio::ip::tcp::socket * m_NewSocket;
protected:
virtual void CreateConnection(boost::asio::ip::tcp::socket * m_NewSocket);
};
}
}
#endif

View File

@ -1,416 +0,0 @@
// There is bug in boost 1.49 with gcc 4.7 coming with Debian Wheezy
#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))
#include "I2PControl.h"
#include <sstream>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#if !GCC47_BOOST149
#include <boost/property_tree/json_parser.hpp>
#endif
#include "Log.h"
#include "NetDb.h"
#include "RouterContext.h"
#include "Daemon.h"
#include "Tunnel.h"
#include "Timestamp.h"
#include "Transports.h"
#include "version.h"
namespace i2p
{
namespace client
{
I2PControlService::I2PControlService (int port):
m_Password (I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning (false), m_Thread (nullptr),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
m_ShutdownTimer (m_Service)
{
m_MethodHandlers[I2P_CONTROL_METHOD_AUTHENTICATE] = &I2PControlService::AuthenticateHandler;
m_MethodHandlers[I2P_CONTROL_METHOD_ECHO] = &I2PControlService::EchoHandler;
m_MethodHandlers[I2P_CONTROL_METHOD_I2PCONTROL] = &I2PControlService::I2PControlHandler;
m_MethodHandlers[I2P_CONTROL_METHOD_ROUTER_INFO] = &I2PControlService::RouterInfoHandler;
m_MethodHandlers[I2P_CONTROL_METHOD_ROUTER_MANAGER] = &I2PControlService::RouterManagerHandler;
m_MethodHandlers[I2P_CONTROL_METHOD_NETWORK_SETTING] = &I2PControlService::NetworkSettingHandler;
// RouterInfo
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_UPTIME] = &I2PControlService::UptimeHandler;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_VERSION] = &I2PControlService::VersionHandler;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_STATUS] = &I2PControlService::StatusHandler;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NETDB_KNOWNPEERS] = &I2PControlService::NetDbKnownPeersHandler;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NETDB_ACTIVEPEERS] = &I2PControlService::NetDbActivePeersHandler;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_NET_STATUS] = &I2PControlService::NetStatusHandler;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_TUNNELS_PARTICIPATING] = &I2PControlService::TunnelsParticipatingHandler;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_BW_IB_1S] = &I2PControlService::InboundBandwidth1S ;
m_RouterInfoHandlers[I2P_CONTROL_ROUTER_INFO_BW_OB_1S] = &I2PControlService::OutboundBandwidth1S ;
// RouterManager
m_RouterManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN] = &I2PControlService::ShutdownHandler;
m_RouterManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN_GRACEFUL] = &I2PControlService::ShutdownGracefulHandler;
m_RouterManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_RESEED] = &I2PControlService::ReseedHandler;
}
I2PControlService::~I2PControlService ()
{
Stop ();
}
void I2PControlService::Start ()
{
if (!m_IsRunning)
{
Accept ();
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&I2PControlService::Run, this));
}
}
void I2PControlService::Stop ()
{
if (m_IsRunning)
{
m_IsRunning = false;
m_Acceptor.cancel ();
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
}
void I2PControlService::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint (eLogError, "I2PControl: ", ex.what ());
}
}
}
void I2PControlService::Accept ()
{
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket> (m_Service);
m_Acceptor.async_accept (*newSocket, std::bind (&I2PControlService::HandleAccept, this,
std::placeholders::_1, newSocket));
}
void I2PControlService::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
if (ecode != boost::asio::error::operation_aborted)
Accept ();
if (!ecode)
{
LogPrint (eLogInfo, "New I2PControl request from ", socket->remote_endpoint ());
std::this_thread::sleep_for (std::chrono::milliseconds(5));
ReadRequest (socket);
}
else
LogPrint (eLogError, "I2PControl accept error: ", ecode.message ());
}
void I2PControlService::ReadRequest (std::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
auto request = std::make_shared<I2PControlBuffer>();
socket->async_read_some (
#if BOOST_VERSION >= 104900
boost::asio::buffer (*request),
#else
boost::asio::buffer (request->data (), request->size ()),
#endif
std::bind(&I2PControlService::HandleRequestReceived, this,
std::placeholders::_1, std::placeholders::_2, socket, request));
}
void I2PControlService::HandleRequestReceived (const boost::system::error_code& ecode,
size_t bytes_transferred, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
std::shared_ptr<I2PControlBuffer> buf)
{
if (ecode)
{
LogPrint (eLogError, "I2PControl read error: ", ecode.message ());
}
else
{
try
{
bool isHtml = !memcmp (buf->data (), "POST", 4);
std::stringstream ss;
ss.write (buf->data (), bytes_transferred);
if (isHtml)
{
std::string header;
while (!ss.eof () && header != "\r")
std::getline(ss, header);
if (ss.eof ())
{
LogPrint (eLogError, "Malformed I2PControl request. HTTP header expected");
return; // TODO:
}
}
#if GCC47_BOOST149
LogPrint (eLogError, "json_read is not supported due bug in boost 1.49 with gcc 4.7");
#else
boost::property_tree::ptree pt;
boost::property_tree::read_json (ss, pt);
std::string method = pt.get<std::string>(I2P_CONTROL_PROPERTY_METHOD);
auto it = m_MethodHandlers.find (method);
if (it != m_MethodHandlers.end ())
{
std::ostringstream response;
response << "{\"id\":" << pt.get<std::string>(I2P_CONTROL_PROPERTY_ID) << ",\"result\":{";
(this->*(it->second))(pt.get_child (I2P_CONTROL_PROPERTY_PARAMS), response);
response << "},\"jsonrpc\":\"2.0\"}";
SendResponse (socket, buf, response, isHtml);
}
else
LogPrint (eLogWarning, "Unknown I2PControl method ", method);
#endif
}
catch (std::exception& ex)
{
LogPrint (eLogError, "I2PControl handle request: ", ex.what ());
}
catch (...)
{
LogPrint (eLogError, "I2PControl handle request unknown exception");
}
}
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, int value) const
{
ss << "\"" << name << "\":" << value;
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, const std::string& value) const
{
ss << "\"" << name << "\":";
if (value.length () > 0)
ss << "\"" << value << "\"";
else
ss << "null";
}
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, double value) const
{
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
}
void I2PControlService::SendResponse (std::shared_ptr<boost::asio::ip::tcp::socket> socket,
std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml)
{
size_t len = response.str ().length (), offset = 0;
if (isHtml)
{
std::ostringstream header;
header << "HTTP/1.1 200 OK\r\n";
header << "Connection: close\r\n";
header << "Content-Length: " << boost::lexical_cast<std::string>(len) << "\r\n";
header << "Content-Type: application/json\r\n";
header << "Date: ";
auto facet = new boost::local_time::local_time_facet ("%a, %d %b %Y %H:%M:%S GMT");
header.imbue(std::locale (header.getloc(), facet));
header << boost::posix_time::second_clock::local_time() << "\r\n";
header << "\r\n";
offset = header.str ().size ();
memcpy (buf->data (), header.str ().c_str (), offset);
}
memcpy (buf->data () + offset, response.str ().c_str (), len);
boost::asio::async_write (*socket, boost::asio::buffer (buf->data (), offset + len),
boost::asio::transfer_all (),
std::bind(&I2PControlService::HandleResponseSent, this,
std::placeholders::_1, std::placeholders::_2, socket, buf));
}
void I2PControlService::HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
std::shared_ptr<boost::asio::ip::tcp::socket> socket, std::shared_ptr<I2PControlBuffer> buf)
{
if (ecode)
LogPrint (eLogError, "I2PControl write error: ", ecode.message ());
socket->close ();
}
// handlers
void I2PControlService::AuthenticateHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
int api = params.get<int> (I2P_CONTROL_PARAM_API);
auto password = params.get<std::string> (I2P_CONTROL_PARAM_PASSWORD);
LogPrint (eLogDebug, "I2PControl Authenticate API=", api, " Password=", password);
if (password != m_Password)
LogPrint (eLogError, "I2PControl Authenticate Invalid password ", password, " expected ", m_Password);
InsertParam (results, I2P_CONTROL_PARAM_API, api);
results << ",";
std::string token = boost::lexical_cast<std::string>(i2p::util::GetSecondsSinceEpoch ());
m_Tokens.insert (token);
InsertParam (results, I2P_CONTROL_PARAM_TOKEN, token);
}
void I2PControlService::EchoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
auto echo = params.get<std::string> (I2P_CONTROL_PARAM_ECHO);
LogPrint (eLogDebug, "I2PControl Echo Echo=", echo);
InsertParam (results, I2P_CONTROL_PARAM_RESULT, echo);
}
// I2PControl
void I2PControlService::I2PControlHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
LogPrint (eLogDebug, "I2PControl I2PControl");
for (auto& it: params)
{
LogPrint (eLogDebug, it.first);
auto it1 = m_I2PControlHandlers.find (it.first);
if (it1 != m_I2PControlHandlers.end ())
(this->*(it1->second))(it.second.data ());
else
LogPrint (eLogError, "I2PControl NetworkSetting unknown request ", it.first);
}
}
// RouterInfo
void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
LogPrint (eLogDebug, "I2PControl RouterInfo");
for (auto it = params.begin (); it != params.end (); it++)
{
if (it != params.begin ()) results << ",";
LogPrint (eLogDebug, it->first);
auto it1 = m_RouterInfoHandlers.find (it->first);
if (it1 != m_RouterInfoHandlers.end ())
(this->*(it1->second))(results);
else
LogPrint (eLogError, "I2PControl RouterInfo unknown request ", it->first);
}
}
void I2PControlService::UptimeHandler (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_UPTIME, (int)i2p::context.GetUptime ()*1000);
}
void I2PControlService::VersionHandler (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_VERSION, VERSION);
}
void I2PControlService::StatusHandler (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_STATUS, "???"); // TODO:
}
void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NETDB_KNOWNPEERS, i2p::data::netdb.GetNumRouters ());
}
void I2PControlService::NetDbActivePeersHandler (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NETDB_ACTIVEPEERS, (int)i2p::transport::transports.GetPeers ().size ());
}
void I2PControlService::NetStatusHandler (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_NET_STATUS, (int)i2p::context.GetStatus ());
}
void I2PControlService::TunnelsParticipatingHandler (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_TUNNELS_PARTICIPATING, (int)i2p::tunnel::tunnels.GetTransitTunnels ().size ());
}
void I2PControlService::InboundBandwidth1S (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_BW_IB_1S, (double)i2p::transport::transports.GetInBandwidth ());
}
void I2PControlService::OutboundBandwidth1S (std::ostringstream& results)
{
InsertParam (results, I2P_CONTROL_ROUTER_INFO_BW_OB_1S, (double)i2p::transport::transports.GetOutBandwidth ());
}
// RouterManager
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
LogPrint (eLogDebug, "I2PControl RouterManager");
for (auto it = params.begin (); it != params.end (); it++)
{
if (it != params.begin ()) results << ",";
LogPrint (eLogDebug, it->first);
auto it1 = m_RouterManagerHandlers.find (it->first);
if (it1 != m_RouterManagerHandlers.end ())
(this->*(it1->second))(results);
else
LogPrint (eLogError, "I2PControl RouterManager unknown request ", it->first);
}
}
void I2PControlService::ShutdownHandler (std::ostringstream& results)
{
LogPrint (eLogInfo, "Shutdown requested");
InsertParam (results, I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN, "");
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
m_ShutdownTimer.async_wait (
[](const boost::system::error_code& ecode)
{
Daemon.running = 0;
});
}
void I2PControlService::ShutdownGracefulHandler (std::ostringstream& results)
{
i2p::context.SetAcceptsTunnels (false);
int timeout = i2p::tunnel::tunnels.GetTransitTunnelsExpirationTimeout ();
LogPrint (eLogInfo, "Graceful shutdown requested. Will shutdown after ", timeout, " seconds");
InsertParam (results, I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN_GRACEFUL, "");
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
m_ShutdownTimer.async_wait (
[](const boost::system::error_code& ecode)
{
Daemon.running = 0;
});
}
void I2PControlService::ReseedHandler (std::ostringstream& results)
{
LogPrint (eLogInfo, "Reseed requested");
InsertParam (results, I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN, "");
i2p::data::netdb.Reseed ();
}
// network setting
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{
LogPrint (eLogDebug, "I2PControl NetworkSetting");
for (auto it = params.begin (); it != params.end (); it++)
{
if (it != params.begin ()) results << ",";
LogPrint (eLogDebug, it->first);
auto it1 = m_NetworkSettingHandlers.find (it->first);
if (it1 != m_NetworkSettingHandlers.end ())
(this->*(it1->second))(it->second.data (), results);
else
LogPrint (eLogError, "I2PControl NetworkSetting unknown request ", it->first);
}
}
}
}

View File

@ -1,79 +0,0 @@
#include "Destination.h"
#include "Identity.h"
#include "ClientContext.h"
#include "I2PService.h"
namespace i2p
{
namespace client
{
static const i2p::data::SigningKeyType I2P_SERVICE_DEFAULT_KEY_TYPE = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
I2PService::I2PService (std::shared_ptr<ClientDestination> localDestination):
m_LocalDestination (localDestination ? localDestination :
i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE))
{
}
I2PService::I2PService (i2p::data::SigningKeyType kt):
m_LocalDestination (i2p::client::context.CreateNewLocalDestination (false, kt))
{
}
void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) {
assert(streamRequestComplete);
i2p::data::IdentHash identHash;
if (i2p::client::context.GetAddressBook ().GetIdentHash (dest, identHash))
m_LocalDestination->CreateStream (streamRequestComplete, identHash, port);
else
{
LogPrint (eLogWarning, "Remote destination ", dest, " not found");
streamRequestComplete (nullptr);
}
}
void TCPIPAcceptor::Start ()
{
m_Acceptor.listen ();
Accept ();
}
void TCPIPAcceptor::Stop ()
{
m_Acceptor.close();
m_Timer.cancel ();
ClearHandlers();
}
void TCPIPAcceptor::Accept ()
{
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket> (GetService ());
m_Acceptor.async_accept (*newSocket, std::bind (&TCPIPAcceptor::HandleAccept, this,
std::placeholders::_1, newSocket));
}
void TCPIPAcceptor::HandleAccept (const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
if (!ecode)
{
LogPrint(eLogDebug,"--- ",GetName()," accepted");
auto handler = CreateHandler(socket);
if (handler)
{
AddHandler(handler);
handler->Handle();
}
else
socket->close();
Accept();
}
else
{
if (ecode != boost::asio::error::operation_aborted)
LogPrint (eLogError,"--- ",GetName()," Closing socket on accept because: ", ecode.message ());
}
}
}
}

View File

@ -1,402 +0,0 @@
#include <cassert>
#include "Base.h"
#include "Log.h"
#include "Destination.h"
#include "ClientContext.h"
#include "I2PTunnel.h"
namespace i2p
{
namespace client
{
I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port):
I2PServiceHandler(owner), m_Socket (socket), m_RemoteEndpoint (socket->remote_endpoint ()),
m_IsQuiet (true)
{
m_Stream = GetOwner()->GetLocalDestination ()->CreateStream (leaseSet, port);
}
I2PTunnelConnection::I2PTunnelConnection (I2PService * owner,
std::shared_ptr<boost::asio::ip::tcp::socket> socket, std::shared_ptr<i2p::stream::Stream> stream):
I2PServiceHandler(owner), m_Socket (socket), m_Stream (stream),
m_RemoteEndpoint (socket->remote_endpoint ()), m_IsQuiet (true)
{
}
I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
std::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::asio::ip::tcp::endpoint& target, bool quiet):
I2PServiceHandler(owner), m_Socket (socket), m_Stream (stream),
m_RemoteEndpoint (target), m_IsQuiet (quiet)
{
}
I2PTunnelConnection::~I2PTunnelConnection ()
{
}
void I2PTunnelConnection::I2PConnect (const uint8_t * msg, size_t len)
{
if (m_Stream)
{
if (msg)
m_Stream->Send (msg, len); // connect and send
else
m_Stream->Send (m_Buffer, 0); // connect
}
StreamReceive ();
Receive ();
}
void I2PTunnelConnection::Connect ()
{
if (m_Socket)
m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect,
shared_from_this (), std::placeholders::_1));
}
void I2PTunnelConnection::Terminate ()
{
if (Kill()) return;
if (m_Stream)
{
m_Stream->Close ();
m_Stream.reset ();
}
m_Socket->close ();
Done(shared_from_this ());
}
void I2PTunnelConnection::Receive ()
{
m_Socket->async_read_some (boost::asio::buffer(m_Buffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE),
std::bind(&I2PTunnelConnection::HandleReceived, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
void I2PTunnelConnection::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("I2PTunnel read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
if (m_Stream)
{
auto s = shared_from_this ();
m_Stream->AsyncSend (m_Buffer, bytes_transferred,
[s](const boost::system::error_code& ecode)
{
if (!ecode)
s->Receive ();
else
s->Terminate ();
});
}
}
}
void I2PTunnelConnection::HandleWrite (const boost::system::error_code& ecode)
{
if (ecode)
{
LogPrint ("I2PTunnel write error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
StreamReceive ();
}
void I2PTunnelConnection::StreamReceive ()
{
if (m_Stream)
m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE),
std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (),
std::placeholders::_1, std::placeholders::_2),
I2P_TUNNEL_CONNECTION_MAX_IDLE);
}
void I2PTunnelConnection::HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("I2PTunnel stream read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
Write (m_StreamBuffer, bytes_transferred);
}
void I2PTunnelConnection::Write (const uint8_t * buf, size_t len)
{
m_Socket->async_send (boost::asio::buffer (buf, len),
std::bind (&I2PTunnelConnection::HandleWrite, shared_from_this (), std::placeholders::_1));
}
void I2PTunnelConnection::HandleConnect (const boost::system::error_code& ecode)
{
if (ecode)
{
LogPrint ("I2PTunnel connect error: ", ecode.message ());
Terminate ();
}
else
{
LogPrint ("I2PTunnel connected");
if (m_IsQuiet)
StreamReceive ();
else
{
// send destination first like received from I2P
std::string dest = m_Stream->GetRemoteIdentity ()->ToBase64 ();
dest += "\n";
memcpy (m_StreamBuffer, dest.c_str (), dest.size ());
HandleStreamReceive (boost::system::error_code (), dest.size ());
}
Receive ();
}
}
I2PTunnelConnectionHTTP::I2PTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
const boost::asio::ip::tcp::endpoint& target, const std::string& host):
I2PTunnelConnection (owner, stream, socket, target), m_Host (host), m_HeaderSent (false)
{
}
void I2PTunnelConnectionHTTP::Write (const uint8_t * buf, size_t len)
{
if (m_HeaderSent)
I2PTunnelConnection::Write (buf, len);
else
{
m_InHeader.clear ();
m_InHeader.write ((const char *)buf, len);
std::string line;
bool endOfHeader = false;
while (!endOfHeader)
{
std::getline(m_InHeader, line);
if (!m_InHeader.fail ())
{
if (line.find ("Host:") != std::string::npos)
m_OutHeader << "Host: " << m_Host << "\r\n";
else
m_OutHeader << line << "\n";
if (line == "\r") endOfHeader = true;
}
else
break;
}
if (endOfHeader)
{
m_OutHeader << m_InHeader.str (); // data right after header
m_HeaderSent = true;
I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ());
}
}
}
/* This handler tries to stablish a connection with the desired server and dies if it fails to do so */
class I2PClientTunnelHandler: public I2PServiceHandler, public std::enable_shared_from_this<I2PClientTunnelHandler>
{
public:
I2PClientTunnelHandler (I2PClientTunnel * parent, i2p::data::IdentHash destination,
int destinationPort, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
I2PServiceHandler(parent), m_DestinationIdentHash(destination),
m_DestinationPort (destinationPort), m_Socket(socket) {};
void Handle();
void Terminate();
private:
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
i2p::data::IdentHash m_DestinationIdentHash;
int m_DestinationPort;
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
};
void I2PClientTunnelHandler::Handle()
{
GetOwner()->GetLocalDestination ()->CreateStream (
std::bind (&I2PClientTunnelHandler::HandleStreamRequestComplete, shared_from_this(), std::placeholders::_1),
m_DestinationIdentHash, m_DestinationPort);
}
void I2PClientTunnelHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
{
if (stream)
{
if (Kill()) return;
LogPrint (eLogInfo,"New I2PTunnel connection");
auto connection = std::make_shared<I2PTunnelConnection>(GetOwner(), m_Socket, stream);
GetOwner()->AddHandler (connection);
connection->I2PConnect ();
Done(shared_from_this());
}
else
{
LogPrint (eLogError,"I2P Client Tunnel Issue when creating the stream, check the previous warnings for more info.");
Terminate();
}
}
void I2PClientTunnelHandler::Terminate()
{
if (Kill()) return;
if (m_Socket)
{
m_Socket->close();
m_Socket = nullptr;
}
Done(shared_from_this());
}
I2PClientTunnel::I2PClientTunnel (const std::string& destination, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort):
TCPIPAcceptor (port,localDestination), m_Destination (destination), m_DestinationIdentHash (nullptr), m_DestinationPort (destinationPort)
{}
void I2PClientTunnel::Start ()
{
TCPIPAcceptor::Start ();
GetIdentHash();
}
void I2PClientTunnel::Stop ()
{
TCPIPAcceptor::Stop();
auto *originalIdentHash = m_DestinationIdentHash;
m_DestinationIdentHash = nullptr;
delete originalIdentHash;
}
/* HACK: maybe we should create a caching IdentHash provider in AddressBook */
const i2p::data::IdentHash * I2PClientTunnel::GetIdentHash ()
{
if (!m_DestinationIdentHash)
{
i2p::data::IdentHash identHash;
if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash))
m_DestinationIdentHash = new i2p::data::IdentHash (identHash);
else
LogPrint (eLogWarning,"Remote destination ", m_Destination, " not found");
}
return m_DestinationIdentHash;
}
std::shared_ptr<I2PServiceHandler> I2PClientTunnel::CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
const i2p::data::IdentHash *identHash = GetIdentHash();
if (identHash)
return std::make_shared<I2PClientTunnelHandler>(this, *identHash, m_DestinationPort, socket);
else
return nullptr;
}
I2PServerTunnel::I2PServerTunnel (const std::string& address, int port,
std::shared_ptr<ClientDestination> localDestination, int inport):
I2PService (localDestination), m_Address (address), m_Port (port), m_IsAccessList (false)
{
m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port);
}
void I2PServerTunnel::Start ()
{
m_Endpoint.port (m_Port);
boost::system::error_code ec;
auto addr = boost::asio::ip::address::from_string (m_Address, ec);
if (!ec)
{
m_Endpoint.address (addr);
Accept ();
}
else
{
auto resolver = std::make_shared<boost::asio::ip::tcp::resolver>(GetService ());
resolver->async_resolve (boost::asio::ip::tcp::resolver::query (m_Address, ""),
std::bind (&I2PServerTunnel::HandleResolve, this,
std::placeholders::_1, std::placeholders::_2, resolver));
}
}
void I2PServerTunnel::Stop ()
{
ClearHandlers ();
}
void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver)
{
if (!ecode)
{
auto addr = (*it).endpoint ().address ();
LogPrint (eLogInfo, "server tunnel ", (*it).host_name (), " has been resolved to ", addr);
m_Endpoint.address (addr);
Accept ();
}
else
LogPrint (eLogError, "Unable to resolve server tunnel address: ", ecode.message ());
}
void I2PServerTunnel::SetAccessList (const std::set<i2p::data::IdentHash>& accessList)
{
m_AccessList = accessList;
m_IsAccessList = true;
}
void I2PServerTunnel::Accept ()
{
if (m_PortDestination)
m_PortDestination->SetAcceptor (std::bind (&I2PServerTunnel::HandleAccept, this, std::placeholders::_1));
auto localDestination = GetLocalDestination ();
if (localDestination)
{
if (!localDestination->IsAcceptingStreams ()) // set it as default if not set yet
localDestination->AcceptStreams (std::bind (&I2PServerTunnel::HandleAccept, this, std::placeholders::_1));
}
else
LogPrint ("Local destination not set for server tunnel");
}
void I2PServerTunnel::HandleAccept (std::shared_ptr<i2p::stream::Stream> stream)
{
if (stream)
{
if (m_IsAccessList)
{
if (!m_AccessList.count (stream->GetRemoteIdentity ()->GetIdentHash ()))
{
LogPrint (eLogWarning, "Address ", stream->GetRemoteIdentity ()->GetIdentHash ().ToBase32 (), " is not in white list. Incoming connection dropped");
stream->Close ();
return;
}
}
CreateI2PConnection (stream);
}
}
void I2PServerTunnel::CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream)
{
auto conn = std::make_shared<I2PTunnelConnection> (this, stream, std::make_shared<boost::asio::ip::tcp::socket> (GetService ()), GetEndpoint ());
AddHandler (conn);
conn->Connect ();
}
I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination, int inport):
I2PServerTunnel (address, port, localDestination, inport)
{
}
void I2PServerTunnelHTTP::CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream)
{
auto conn = std::make_shared<I2PTunnelConnectionHTTP> (this, stream, std::make_shared<boost::asio::ip::tcp::socket> (GetService ()), GetEndpoint (), GetAddress ());
AddHandler (conn);
conn->Connect ();
}
}
}

View File

@ -1,153 +0,0 @@
#ifndef I2PTUNNEL_H__
#define I2PTUNNEL_H__
#include <inttypes.h>
#include <string>
#include <set>
#include <memory>
#include <sstream>
#include <boost/asio.hpp>
#include "Identity.h"
#include "Destination.h"
#include "Streaming.h"
#include "I2PService.h"
namespace i2p
{
namespace client
{
const size_t I2P_TUNNEL_CONNECTION_BUFFER_SIZE = 8192;
const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds
const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds
class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this<I2PTunnelConnection>
{
public:
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port = 0); // to I2P
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
std::shared_ptr<i2p::stream::Stream> stream); // to I2P using simplified API
I2PTunnelConnection (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P
~I2PTunnelConnection ();
void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0);
void Connect ();
protected:
void Terminate ();
void Receive ();
void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
virtual void Write (const uint8_t * buf, size_t len); // can be overloaded
void HandleWrite (const boost::system::error_code& ecode);
void StreamReceive ();
void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleConnect (const boost::system::error_code& ecode);
private:
uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE];
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
std::shared_ptr<i2p::stream::Stream> m_Stream;
boost::asio::ip::tcp::endpoint m_RemoteEndpoint;
bool m_IsQuiet; // don't send destination
};
class I2PTunnelConnectionHTTP: public I2PTunnelConnection
{
public:
I2PTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
const boost::asio::ip::tcp::endpoint& target, const std::string& host);
protected:
void Write (const uint8_t * buf, size_t len);
private:
std::string m_Host;
std::stringstream m_InHeader, m_OutHeader;
bool m_HeaderSent;
};
class I2PClientTunnel: public TCPIPAcceptor
{
protected:
// Implements TCPIPAcceptor
std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
const char* GetName() { return "I2P Client Tunnel"; }
public:
I2PClientTunnel (const std::string& destination, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0);
~I2PClientTunnel () {}
void Start ();
void Stop ();
private:
const i2p::data::IdentHash * GetIdentHash ();
std::string m_Destination;
const i2p::data::IdentHash * m_DestinationIdentHash;
int m_DestinationPort;
};
class I2PServerTunnel: public I2PService
{
public:
I2PServerTunnel (const std::string& address, int port,
std::shared_ptr<ClientDestination> localDestination, int inport = 0);
void Start ();
void Stop ();
void SetAccessList (const std::set<i2p::data::IdentHash>& accessList);
const std::string& GetAddress() const { return m_Address; }
int GetPort () const { return m_Port; };
const boost::asio::ip::tcp::endpoint& GetEndpoint () const { return m_Endpoint; }
private:
void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
void Accept ();
void HandleAccept (std::shared_ptr<i2p::stream::Stream> stream);
virtual void CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
private:
std::string m_Address;
int m_Port;
boost::asio::ip::tcp::endpoint m_Endpoint;
std::shared_ptr<i2p::stream::StreamingDestination> m_PortDestination;
std::set<i2p::data::IdentHash> m_AccessList;
bool m_IsAccessList;
};
class I2PServerTunnelHTTP: public I2PServerTunnel
{
public:
I2PServerTunnelHTTP (const std::string& address, int port,
std::shared_ptr<ClientDestination> localDestination, int inport = 0);
private:
void CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
};
}
}
#endif

View File

@ -1,156 +0,0 @@
#include <string.h>
#include "I2PEndian.h"
#include "Crypto.h"
#include "Log.h"
#include "Timestamp.h"
#include "NetDb.h"
#include "TunnelPool.h"
#include "LeaseSet.h"
namespace i2p
{
namespace data
{
LeaseSet::LeaseSet (const uint8_t * buf, size_t len):
m_IsValid (true)
{
m_Buffer = new uint8_t[len];
memcpy (m_Buffer, buf, len);
m_BufferLen = len;
ReadFromBuffer ();
}
LeaseSet::LeaseSet (const i2p::tunnel::TunnelPool& pool):
m_IsValid (true)
{
// header
const i2p::data::LocalDestination * localDestination = pool.GetLocalDestination ();
if (!localDestination)
{
m_Buffer = nullptr;
m_BufferLen = 0;
m_IsValid = false;
LogPrint (eLogError, "Destination for local LeaseSet doesn't exist");
return;
}
m_Buffer = new uint8_t[MAX_LS_BUFFER_SIZE];
m_BufferLen = localDestination->GetIdentity ()->ToBuffer (m_Buffer, MAX_LS_BUFFER_SIZE);
memcpy (m_Buffer + m_BufferLen, localDestination->GetEncryptionPublicKey (), 256);
m_BufferLen += 256;
auto signingKeyLen = localDestination->GetIdentity ()->GetSigningPublicKeyLen ();
memset (m_Buffer + m_BufferLen, 0, signingKeyLen);
m_BufferLen += signingKeyLen;
auto tunnels = pool.GetInboundTunnels (5); // 5 tunnels maximum
m_Buffer[m_BufferLen] = tunnels.size (); // num leases
m_BufferLen++;
// leases
for (auto it: tunnels)
{
memcpy (m_Buffer + m_BufferLen, it->GetNextIdentHash (), 32);
m_BufferLen += 32; // gateway id
htobe32buf (m_Buffer + m_BufferLen, it->GetNextTunnelID ());
m_BufferLen += 4; // tunnel id
uint64_t ts = it->GetCreationTime () + i2p::tunnel::TUNNEL_EXPIRATION_TIMEOUT - i2p::tunnel::TUNNEL_EXPIRATION_THRESHOLD; // 1 minute before expiration
ts *= 1000; // in milliseconds
ts += rand () % 6; // + random milliseconds 0-5
htobe64buf (m_Buffer + m_BufferLen, ts);
m_BufferLen += 8; // end date
}
// signature
localDestination->Sign (m_Buffer, m_BufferLen, m_Buffer + m_BufferLen);
m_BufferLen += localDestination->GetIdentity ()->GetSignatureLen ();
LogPrint ("Local LeaseSet of ", tunnels.size (), " leases created");
ReadFromBuffer ();
}
void LeaseSet::Update (const uint8_t * buf, size_t len)
{
m_Leases.clear ();
if (len > m_BufferLen)
{
auto oldBuffer = m_Buffer;
m_Buffer = new uint8_t[len];
delete[] oldBuffer;
}
memcpy (m_Buffer, buf, len);
m_BufferLen = len;
ReadFromBuffer (false);
}
void LeaseSet::ReadFromBuffer (bool readIdentity)
{
if (readIdentity || !m_Identity)
m_Identity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
size_t size = m_Identity->GetFullLen ();
memcpy (m_EncryptionKey, m_Buffer + size, 256);
size += 256; // encryption key
size += m_Identity->GetSigningPublicKeyLen (); // unused signing key
uint8_t num = m_Buffer[size];
size++; // num
LogPrint ("LeaseSet num=", (int)num);
if (!num) m_IsValid = false;
// process leases
const uint8_t * leases = m_Buffer + size;
for (int i = 0; i < num; i++)
{
Lease lease;
lease.tunnelGateway = leases;
leases += 32; // gateway
lease.tunnelID = bufbe32toh (leases);
leases += 4; // tunnel ID
lease.endDate = bufbe64toh (leases);
leases += 8; // end date
m_Leases.push_back (lease);
// check if lease's gateway is in our netDb
if (!netdb.FindRouter (lease.tunnelGateway))
{
// if not found request it
LogPrint (eLogInfo, "Lease's tunnel gateway not found. Requested");
netdb.RequestDestination (lease.tunnelGateway);
}
}
// verify
if (!m_Identity->Verify (m_Buffer, leases - m_Buffer, leases))
{
LogPrint (eLogWarning, "LeaseSet verification failed");
m_IsValid = false;
}
}
const std::vector<Lease> LeaseSet::GetNonExpiredLeases (bool withThreshold) const
{
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
std::vector<Lease> leases;
for (auto& it: m_Leases)
{
auto endDate = it.endDate;
if (!withThreshold)
endDate -= i2p::tunnel::TUNNEL_EXPIRATION_THRESHOLD*1000;
if (ts < endDate)
leases.push_back (it);
}
return leases;
}
bool LeaseSet::HasExpiredLeases () const
{
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
for (auto& it: m_Leases)
if (ts >= it.endDate) return true;
return false;
}
bool LeaseSet::HasNonExpiredLeases () const
{
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
for (auto& it: m_Leases)
if (ts < it.endDate) return true;
return false;
}
}
}

View File

@ -1,74 +0,0 @@
#ifndef LEASE_SET_H__
#define LEASE_SET_H__
#include <inttypes.h>
#include <string.h>
#include <vector>
#include "Identity.h"
namespace i2p
{
namespace tunnel
{
class TunnelPool;
}
namespace data
{
struct Lease
{
IdentHash tunnelGateway;
uint32_t tunnelID;
uint64_t endDate;
bool operator< (const Lease& other) const
{
if (endDate != other.endDate)
return endDate > other.endDate;
else
return tunnelID < other.tunnelID;
}
};
const int MAX_LS_BUFFER_SIZE = 3072;
class LeaseSet: public RoutingDestination
{
public:
LeaseSet (const uint8_t * buf, size_t len);
LeaseSet (const i2p::tunnel::TunnelPool& pool);
~LeaseSet () { delete[] m_Buffer; };
void Update (const uint8_t * buf, size_t len);
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_Identity; };
const uint8_t * GetBuffer () const { return m_Buffer; };
size_t GetBufferLen () const { return m_BufferLen; };
bool IsValid () const { return m_IsValid; };
// implements RoutingDestination
const IdentHash& GetIdentHash () const { return m_Identity->GetIdentHash (); };
const std::vector<Lease>& GetLeases () const { return m_Leases; };
const std::vector<Lease> GetNonExpiredLeases (bool withThreshold = true) const;
bool HasExpiredLeases () const;
bool HasNonExpiredLeases () const;
const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionKey; };
bool IsDestination () const { return true; };
private:
void ReadFromBuffer (bool readIdentity = true);
private:
bool m_IsValid;
std::vector<Lease> m_Leases;
std::shared_ptr<const IdentityEx> m_Identity;
uint8_t m_EncryptionKey[256];
uint8_t * m_Buffer;
size_t m_BufferLen;
};
}
}
#endif

62
Log.cpp
View File

@ -1,62 +0,0 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include "Log.h"
Log * g_Log = nullptr;
static const char * g_LogLevelStr[eNumLogLevels] =
{
"error", // eLogError
"warn", // eLogWarning
"info", // eLogInfo
"debug" // eLogDebug
};
void LogMsg::Process()
{
auto& output = (log && log->GetLogStream ()) ? *log->GetLogStream () : std::cerr;
if (log)
output << log->GetTimestamp ();
else
output << boost::posix_time::second_clock::local_time().time_of_day ();
output << "/" << g_LogLevelStr[level] << " - ";
output << s.str();
}
const std::string& Log::GetTimestamp ()
{
#if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 6)
auto ts = std::chrono::monotonic_clock::now ();
#else
auto ts = std::chrono::steady_clock::now ();
#endif
if (ts > m_LastTimestampUpdate + std::chrono::milliseconds (500)) // 0.5 second
{
m_LastTimestampUpdate = ts;
m_Timestamp = boost::posix_time::to_simple_string (boost::posix_time::second_clock::local_time().time_of_day ());
}
return m_Timestamp;
}
void Log::Flush ()
{
if (m_LogStream)
m_LogStream->flush();
}
void Log::SetLogFile (const std::string& fullFilePath)
{
auto logFile = new std::ofstream (fullFilePath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
if (logFile->is_open ())
{
SetLogStream (logFile);
LogPrint("Logging to file ", fullFilePath, " enabled.");
}
else
delete logFile;
}
void Log::SetLogStream (std::ostream * logStream)
{
if (m_LogStream) delete m_LogStream;
m_LogStream = logStream;
}

129
Log.h
View File

@ -1,129 +0,0 @@
#ifndef LOG_H__
#define LOG_H__
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <functional>
#include <chrono>
#include "Queue.h"
enum LogLevel
{
eLogError = 0,
eLogWarning,
eLogInfo,
eLogDebug,
eNumLogLevels
};
class Log;
struct LogMsg
{
std::stringstream s;
Log * log;
LogLevel level;
LogMsg (Log * l = nullptr, LogLevel lv = eLogInfo): log (l), level (lv) {};
void Process();
};
class Log: public i2p::util::MsgQueue<LogMsg>
{
public:
Log (): m_LogStream (nullptr) { SetOnEmpty (std::bind (&Log::Flush, this)); };
~Log () { delete m_LogStream; };
void SetLogFile (const std::string& fullFilePath);
void SetLogStream (std::ostream * logStream);
std::ostream * GetLogStream () const { return m_LogStream; };
const std::string& GetTimestamp ();
private:
void Flush ();
private:
std::ostream * m_LogStream;
std::string m_Timestamp;
#if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 6) // gcc 4.6
std::chrono::monotonic_clock::time_point m_LastTimestampUpdate;
#else
std::chrono::steady_clock::time_point m_LastTimestampUpdate;
#endif
};
extern Log * g_Log;
inline void StartLog (const std::string& fullFilePath)
{
if (!g_Log)
{
auto log = new Log ();
if (fullFilePath.length () > 0)
log->SetLogFile (fullFilePath);
g_Log = log;
}
}
inline void StartLog (std::ostream * s)
{
if (!g_Log)
{
auto log = new Log ();
if (s)
log->SetLogStream (s);
g_Log = log;
}
}
inline void StopLog ()
{
if (g_Log)
{
auto log = g_Log;
g_Log = nullptr;
log->Stop ();
delete log;
}
}
template<typename TValue>
void LogPrint (std::stringstream& s, TValue arg)
{
s << arg;
}
template<typename TValue, typename... TArgs>
void LogPrint (std::stringstream& s, TValue arg, TArgs... args)
{
LogPrint (s, arg);
LogPrint (s, args...);
}
template<typename... TArgs>
void LogPrint (LogLevel level, TArgs... args)
{
LogMsg * msg = new LogMsg (g_Log, level);
LogPrint (msg->s, args...);
msg->s << std::endl;
if (g_Log)
g_Log->Put (msg);
else
{
msg->Process ();
delete msg;
}
}
template<typename... TArgs>
void LogPrint (TArgs... args)
{
LogPrint (eLogInfo, args...);
}
#endif

114
Makefile
View File

@ -1,36 +1,73 @@
UNAME := $(shell uname -s)
SYS := $(shell $(CXX) -dumpmachine)
SHLIB := libi2pd.so
ARLIB := libi2pd.a
SHLIB_CLIENT := libi2pdclient.so
ARLIB_CLIENT := libi2pdclient.a
I2PD := i2p
GREP := fgrep
I2PD := i2pd
GREP := grep
DEPS := obj/make.dep
LIB_SRC_DIR := libi2pd
LIB_CLIENT_SRC_DIR := libi2pd_client
DAEMON_SRC_DIR := daemon
include filelist.mk
USE_AESNI := yes
USE_STATIC := no
USE_AESNI := yes
USE_AVX := yes
USE_STATIC := no
USE_MESHNET := no
USE_UPNP := no
DEBUG := yes
ifeq ($(UNAME),Darwin)
DAEMON_SRC += DaemonLinux.cpp
include Makefile.osx
else ifeq ($(shell echo $(UNAME) | $(GREP) -c FreeBSD),1)
DAEMON_SRC += DaemonLinux.cpp
include Makefile.bsd
else ifeq ($(UNAME),Linux)
DAEMON_SRC += DaemonLinux.cpp
include Makefile.linux
else # win32
DAEMON_SRC += DaemonWin32.cpp
ifeq ($(DEBUG),yes)
CXX_DEBUG = -g
else
CXX_DEBUG = -Os
LD_DEBUG = -s
endif
all: mk_build_dir $(SHLIB) $(SHLIB_CLIENT) $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
ifeq ($(WEBSOCKETS),1)
NEEDED_CXXFLAGS += -DWITH_EVENTS
endif
mk_build_dir:
mkdir -p obj
ifneq (, $(findstring darwin, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
ifeq ($(HOMEBREW),1)
include Makefile.homebrew
else
include Makefile.osx
endif
else ifneq (, $(findstring linux, $(SYS))$(findstring gnu, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
include Makefile.linux
else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS)))
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
include Makefile.bsd
else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS)))
DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
include Makefile.mingw
else # not supported
$(error Not supported platform)
endif
api: $(SHLIB) $(ARLIB)
ifeq ($(USE_MESHNET),yes)
NEEDED_CXXFLAGS += -DMESHNET
endif
NEEDED_CXXFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR)
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
mk_obj_dir:
@mkdir -p obj
@mkdir -p obj/Win32
@mkdir -p obj/$(LIB_SRC_DIR)
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
@mkdir -p obj/$(DAEMON_SRC_DIR)
api: mk_obj_dir $(SHLIB) $(ARLIB)
api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time
## **without** overwriting the CXXFLAGS which we need in order to build.
@ -39,20 +76,19 @@ api: $(SHLIB) $(ARLIB)
## -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.
deps:
@mkdir -p obj
deps: mk_obj_dir
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) -MM *.cpp > $(DEPS)
@sed -i -e '/\.o:/ s/^/obj\//' $(DEPS)
obj/%.o : %.cpp
@mkdir -p obj
obj/%.o: %.cpp
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(CPU_FLAGS) -c -o $@ $<
# '-' is 'ignore if missing' on first run
-include $(DEPS)
$(I2PD): $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) $(ARLIB) $(ARLIB_CLIENT)
$(CXX) -o $@ $^ $(LDLIBS) $(LDFLAGS)
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
$(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS)
$(SHLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
ifneq ($(USE_STATIC),yes)
@ -63,23 +99,39 @@ $(SHLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
$(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^
$(ARLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
ar -r $@ $^
$(AR) -r $@ $^
$(ARLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
ar -r $@ $^
$(AR) -r $@ $^
clean:
rm -rf obj
$(RM) -r obj
$(RM) -r docs/generated
$(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT)
LATEST_TAG=$(shell git describe --tags --abbrev=0 master)
strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB)
strip $^
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
dist:
git archive --format=tar.gz -9 --worktree-attributes \
--prefix=i2pd_$(LATEST_TAG)/ $(LATEST_TAG) -o i2pd_$(LATEST_TAG).tar.gz
last-dist:
git archive --format=tar.gz -9 --worktree-attributes \
--prefix=i2pd_$(LATEST_TAG)/ $(BRANCH) -o ../i2pd_$(LATEST_TAG).orig.tar.gz
doxygen:
doxygen -s docs/Doxyfile
.PHONY: all
.PHONY: clean
.PHONY: deps
.PHONY: doxygen
.PHONY: dist
.PHONY: last-dist
.PHONY: api
.PHONY: mk_build_dir
.PHONY: api_client
.PHONY: mk_obj_dir
.PHONY: install

View File

@ -1,12 +1,12 @@
CXX = g++
CXXFLAGS = -O2
CXX = clang++
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
## **without** overwriting the CXXFLAGS which we need in order to 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
## -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.
NEEDED_CXXFLAGS = -std=c++11
NEEDED_CXXFLAGS = -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
INCFLAGS = -I/usr/include/ -I/usr/local/include/
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
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

54
Makefile.homebrew Normal file
View File

@ -0,0 +1,54 @@
# root directory holding homebrew
BREWROOT = /usr/local
BOOSTROOT = ${BREWROOT}/opt/boost
SSLROOT = ${BREWROOT}/opt/openssl@1.1
UPNPROOT = ${BREWROOT}/opt/miniupnpc
CXXFLAGS = ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
LDFLAGS = ${LD_DEBUG}
ifndef TRAVIS
CXX = clang++
endif
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
else
LDFLAGS += -L${SSLROOT}/lib -L${BOOSTROOT}/lib
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
endif
ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP
INCFLAGS += -I${UPNPROOT}/include
ifeq ($(USE_STATIC),yes)
LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a
else
LDFLAGS += -L${UPNPROOT}/lib
LDLIBS += -lminiupnpc
endif
endif
# OSX Notes
# http://www.hutsby.net/2011/08/macs-with-aes-ni.html
# 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
ifeq ($(USE_AESNI),yes)
CXXFLAGS += -maes
endif
ifeq ($(USE_AVX),1)
CXXFLAGS += -mavx
endif
install: all
install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
install -m 755 ${I2PD} ${PREFIX}/bin/
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
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,12 +1,13 @@
CXXFLAGS = -g -Wall
INCFLAGS =
# set defaults instead redefine
CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
LDFLAGS ?= ${LD_DEBUG}
## 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.
## For example, when adding 'hardening flags' to the build
## (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
## custom FLAGS to work at build-time.
## custom FDLAGS to work at build-time.
# detect proper flag for c++11 support by compilers
CXXVER := $(shell $(CXX) -dumpversion)
@ -15,45 +16,64 @@ ifeq ($(shell expr match $(CXX) 'clang'),5)
else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10
NEEDED_CXXFLAGS += -std=c++11
else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7
NEEDED_CXXFLAGS += -std=c++11
NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6
NEEDED_CXXFLAGS += -std=c++0x
else ifeq ($(shell expr match ${CXXVER} "5\.[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
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "[7-8]"),1) # gcc 7 ubuntu or gcc 8 arch
NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic
else # not supported
$(error Compiler too old)
$(error Compiler too old)
endif
NEEDED_CXXFLAGS += -fPIC
ifeq ($(USE_STATIC),yes)
LIBDIR := /usr/lib
LDLIBS = $(LIBDIR)/libboost_system.a
LDLIBS += $(LIBDIR)/libboost_date_time.a
LDLIBS += $(LIBDIR)/libboost_filesystem.a
LDLIBS += $(LIBDIR)/libboost_regex.a
LDLIBS += $(LIBDIR)/libboost_program_options.a
LDLIBS += $(LIBDIR)/libcrypto.a
LDLIBS += $(LIBDIR)/libssl.a
LDLIBS += $(LIBDIR)/libz.a
LDLIBS += -lpthread -static-libstdc++ -static-libgcc
USE_AESNI := no
# NOTE: on glibc you will get this warning:
# Using 'getaddrinfo' in statically linked applications requires at runtime
# the shared libraries from the glibc version used for linking
LIBDIR := /usr/lib
LDLIBS += $(LIBDIR)/libboost_system.a
LDLIBS += $(LIBDIR)/libboost_date_time.a
LDLIBS += $(LIBDIR)/libboost_filesystem.a
LDLIBS += $(LIBDIR)/libboost_program_options.a
LDLIBS += $(LIBDIR)/libssl.a
LDLIBS += $(LIBDIR)/libcrypto.a
LDLIBS += $(LIBDIR)/libz.a
LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl
USE_AESNI := no
else
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
endif
# UPNP Support (miniupnpc 1.5 or 1.6)
ifeq ($(USE_UPNP),1)
LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP
# UPNP Support (miniupnpc 1.5 and higher)
ifeq ($(USE_UPNP),yes)
CXXFLAGS += -DUSE_UPNP
ifeq ($(USE_STATIC),yes)
LDLIBS += $(LIBDIR)/libminiupnpc.a
else
LDLIBS += -lminiupnpc
endif
endif
IS_64 := $(shell $(CXX) -dumpmachine 2>&1 | $(GREP) -c "64")
ifeq ($(USE_AESNI),yes)
ifeq ($(IS_64),1)
#check if AES-NI is supported by CPU
ifneq ($(shell grep -c aes /proc/cpuinfo),0)
CPU_FLAGS = -maes -DAESNI
ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0)
machine := $(shell uname -m)
ifeq ($(machine), aarch64)
CXXFLAGS += -DARM64AES
else
CPU_FLAGS += -maes
endif
endif
endif
ifeq ($(USE_AVX),yes)
#check if AVX supported by CPU
ifneq ($(shell $(GREP) -c avx /proc/cpuinfo),0)
CPU_FLAGS += -mavx
endif
endif

View File

@ -1,6 +1,54 @@
CXX = g++
CXXFLAGS = -O2 -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
NEEDED_CXXFLAGS = -std=c++11
INCFLAGS = -I/usr/include/ -I/usr/local/include/ -I/c/dev/openssl/include -I/c/dev/boost/include/boost-1_59
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -L/c/dev/openssl -L/c/dev/boost/lib
LDLIBS = -lboost_system-mgw48-mt-1_59 -lboost_date_time-mgw48-mt-1_59 -lboost_filesystem-mgw48-mt-1_59 -lboost_regex-mgw48-mt-1_59 -lboost_program_options-mgw48-mt-1_59 -lssl -lcrypto -lz -lpthread -lwsock32 -lws2_32 -lgdi32
USE_WIN32_APP=yes
CXX = g++
WINDRES = windres
CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
NEEDED_CXXFLAGS = -std=c++11
BOOST_SUFFIX = -mt
INCFLAGS = -Idaemon -I.
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++
# UPNP Support
ifeq ($(USE_UPNP),yes)
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
LDLIBS = -lminiupnpc
endif
LDLIBS += \
-lboost_system$(BOOST_SUFFIX) \
-lboost_date_time$(BOOST_SUFFIX) \
-lboost_filesystem$(BOOST_SUFFIX) \
-lboost_program_options$(BOOST_SUFFIX) \
-lssl \
-lcrypto \
-lz \
-lwsock32 \
-lws2_32 \
-lgdi32 \
-liphlpapi \
-lstdc++ \
-lpthread
ifeq ($(USE_WIN32_APP), yes)
CXXFLAGS += -DWIN32_APP
LDFLAGS += -mwindows
DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif
# don't change following line to ifeq ($(USE_AESNI),yes) !!!
ifeq ($(USE_AESNI),1)
CPU_FLAGS += -maes
else
CPU_FLAGS += -msse
endif
ifeq ($(USE_AVX),1)
CPU_FLAGS += -mavx
endif
ifeq ($(USE_ASLR),yes)
LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols
endif
obj/%.o : %.rc
$(WINDRES) -i $< -o $@

View File

@ -1,25 +1,30 @@
CXX = clang++
CXXFLAGS = -g -Wall -std=c++11 -DCRYPTOPP_DISABLE_ASM -DMAC_OSX
#CXXFLAGS = -g -O2 -Wall -std=c++11 -DCRYPTOPP_DISABLE_ASM
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
INCFLAGS = -I/usr/local/include
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
LDLIBS = -lcryptopp -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
ifeq ($(USE_UPNP),1)
LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP
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
else
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
endif
# OSX Notes
# http://www.hutsby.net/2011/08/macs-with-aes-ni.html
# 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
ifeq ($(USE_AESNI),yes)
CXXFLAGS += -maes -DAESNI
ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP
ifeq ($(USE_STATIC),yes)
LDLIBS += /usr/local/lib/libminiupnpc.a
else
LDLIBS += -lminiupnpc
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}/
ifeq ($(USE_AESNI),1)
CXXFLAGS += -maes
else
CXXFLAGS += -msse
endif
ifeq ($(USE_AVX),1)
CXXFLAGS += -mavx
endif

View File

@ -1,932 +0,0 @@
#include <string.h>
#include <stdlib.h>
#include <openssl/dh.h>
#include <openssl/sha.h>
#include <zlib.h>
#include "I2PEndian.h"
#include "Base.h"
#include "Log.h"
#include "Timestamp.h"
#include "Crypto.h"
#include "I2NPProtocol.h"
#include "RouterContext.h"
#include "Transports.h"
#include "NetDb.h"
#include "NTCPSession.h"
using namespace i2p::crypto;
namespace i2p
{
namespace transport
{
NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
TransportSession (in_RemoteRouter), m_Server (server), m_Socket (m_Server.GetService ()),
m_TerminationTimer (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false),
m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false)
{
m_DHKeysPair = transports.GetNextDHKeysPair ();
m_Establisher = new Establisher;
}
NTCPSession::~NTCPSession ()
{
delete m_Establisher;
}
void NTCPSession::CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key)
{
uint8_t sharedKey[256];
m_DHKeysPair->Agree (pubKey, sharedKey);
uint8_t * aesKey = key;
if (sharedKey[0] & 0x80)
{
aesKey[0] = 0;
memcpy (aesKey + 1, sharedKey, 31);
}
else if (sharedKey[0])
memcpy (aesKey, sharedKey, 32);
else
{
// find first non-zero byte
uint8_t * nonZero = sharedKey + 1;
while (!*nonZero)
{
nonZero++;
if (nonZero - sharedKey > 32)
{
LogPrint (eLogWarning, "First 32 bytes of shared key is all zeros. Ignored");
return;
}
}
memcpy (aesKey, nonZero, 32);
}
}
void NTCPSession::Done ()
{
m_Server.GetService ().post (std::bind (&NTCPSession::Terminate, shared_from_this ()));
}
void NTCPSession::Terminate ()
{
if (!m_IsTerminated)
{
m_IsTerminated = true;
m_IsEstablished = false;
m_Socket.close ();
transports.PeerDisconnected (shared_from_this ());
m_Server.RemoveNTCPSession (shared_from_this ());
m_SendQueue.clear ();
m_NextMessage = nullptr;
m_TerminationTimer.cancel ();
LogPrint (eLogInfo, "NTCP session terminated");
}
}
void NTCPSession::Connected ()
{
m_IsEstablished = true;
delete m_Establisher;
m_Establisher = nullptr;
m_DHKeysPair = nullptr;
SendTimeSyncMessage ();
m_SendQueue.push_back (CreateDatabaseStoreMsg ()); // we tell immediately who we are
transports.PeerConnected (shared_from_this ());
}
void NTCPSession::ClientLogin ()
{
if (!m_DHKeysPair)
m_DHKeysPair = transports.GetNextDHKeysPair ();
// send Phase1
const uint8_t * x = m_DHKeysPair->GetPublicKey ();
memcpy (m_Establisher->phase1.pubKey, x, 256);
SHA256(x, 256, m_Establisher->phase1.HXxorHI);
const uint8_t * ident = m_RemoteIdentity->GetIdentHash ();
for (int i = 0; i < 32; i++)
m_Establisher->phase1.HXxorHI[i] ^= ident[i];
boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase1Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
ScheduleTermination ();
}
void NTCPSession::ServerLogin ()
{
boost::system::error_code ec;
auto ep = m_Socket.remote_endpoint(ec);
if (!ec)
{
m_ConnectedFrom = ep.address ();
// receive Phase1
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
ScheduleTermination ();
}
}
void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint (eLogError, "Couldn't send Phase 1 message: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase2Received, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
}
void NTCPSession::HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint (eLogError, "Phase 1 read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
// verify ident
uint8_t digest[32];
SHA256(m_Establisher->phase1.pubKey, 256, digest);
const uint8_t * ident = i2p::context.GetIdentHash ();
for (int i = 0; i < 32; i++)
{
if ((m_Establisher->phase1.HXxorHI[i] ^ ident[i]) != digest[i])
{
LogPrint (eLogError, "Wrong ident");
Terminate ();
return;
}
}
SendPhase2 ();
}
}
void NTCPSession::SendPhase2 ()
{
if (!m_DHKeysPair)
m_DHKeysPair = transports.GetNextDHKeysPair ();
const uint8_t * y = m_DHKeysPair->GetPublicKey ();
memcpy (m_Establisher->phase2.pubKey, y, 256);
uint8_t xy[512];
memcpy (xy, m_Establisher->phase1.pubKey, 256);
memcpy (xy + 256, y, 256);
SHA256(xy, 512, m_Establisher->phase2.encrypted.hxy);
uint32_t tsB = htobe32 (i2p::util::GetSecondsSinceEpoch ());
m_Establisher->phase2.encrypted.timestamp = tsB;
// TODO: fill filler
i2p::crypto::AESKey aesKey;
CreateAESKey (m_Establisher->phase1.pubKey, aesKey);
m_Encryption.SetKey (aesKey);
m_Encryption.SetIV (y + 240);
m_Decryption.SetKey (aesKey);
m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase2Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsB));
}
void NTCPSession::HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB)
{
if (ecode)
{
LogPrint (eLogError, "Couldn't send Phase 2 message: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase3Received, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, tsB));
}
}
void NTCPSession::HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint (eLogError, "Phase 2 read error: ", ecode.message (), ". Wrong ident assumed");
if (ecode != boost::asio::error::operation_aborted)
{
// this RI is not valid
i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true);
transports.ReuseDHKeysPair (m_DHKeysPair);
m_DHKeysPair = nullptr;
Terminate ();
}
}
else
{
i2p::crypto::AESKey aesKey;
CreateAESKey (m_Establisher->phase2.pubKey, aesKey);
m_Decryption.SetKey (aesKey);
m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240);
m_Encryption.SetKey (aesKey);
m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
// verify
uint8_t xy[512];
memcpy (xy, m_DHKeysPair->GetPublicKey (), 256);
memcpy (xy + 256, m_Establisher->phase2.pubKey, 256);
uint8_t digest[32];
SHA256 (xy, 512, digest);
if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32))
{
LogPrint (eLogError, "Incorrect hash");
transports.ReuseDHKeysPair (m_DHKeysPair);
m_DHKeysPair = nullptr;
Terminate ();
return ;
}
SendPhase3 ();
}
}
void NTCPSession::SendPhase3 ()
{
auto keys = i2p::context.GetPrivateKeys ();
uint8_t * buf = m_ReceiveBuffer;
htobe16buf (buf, keys.GetPublic ()->GetFullLen ());
buf += 2;
buf += i2p::context.GetIdentity ()->ToBuffer (buf, NTCP_BUFFER_SIZE);
uint32_t tsA = htobe32 (i2p::util::GetSecondsSinceEpoch ());
htobuf32(buf,tsA);
buf += 4;
size_t signatureLen = keys.GetPublic ()->GetSignatureLen ();
size_t len = (buf - m_ReceiveBuffer) + signatureLen;
size_t paddingSize = len & 0x0F; // %16
if (paddingSize > 0)
{
paddingSize = 16 - paddingSize;
// TODO: fill padding with random data
buf += paddingSize;
len += paddingSize;
}
SignedData s;
s.Insert (m_Establisher->phase1.pubKey, 256); // x
s.Insert (m_Establisher->phase2.pubKey, 256); // y
s.Insert (m_RemoteIdentity->GetIdentHash (), 32); // ident
s.Insert (tsA); // tsA
s.Insert (m_Establisher->phase2.encrypted.timestamp); // tsB
s.Sign (keys, buf);
m_Encryption.Encrypt(m_ReceiveBuffer, len, m_ReceiveBuffer);
boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, len), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase3Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsA));
}
void NTCPSession::HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA)
{
if (ecode)
{
LogPrint (eLogError, "Couldn't send Phase 3 message: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
// wait for phase4
auto signatureLen = m_RemoteIdentity->GetSignatureLen ();
size_t paddingSize = signatureLen & 0x0F; // %16
if (paddingSize > 0) signatureLen += (16 - paddingSize);
boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase4Received, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, tsA));
}
}
void NTCPSession::HandlePhase3Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB)
{
if (ecode)
{
LogPrint (eLogError, "Phase 3 read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
m_Decryption.Decrypt (m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer);
uint8_t * buf = m_ReceiveBuffer;
uint16_t size = bufbe16toh (buf);
SetRemoteIdentity (std::make_shared<i2p::data::IdentityEx> (buf + 2, size));
if (m_Server.FindNTCPSession (m_RemoteIdentity->GetIdentHash ()))
{
LogPrint (eLogError, "NTCP session already exists");
Terminate ();
}
size_t expectedSize = size + 2/*size*/ + 4/*timestamp*/ + m_RemoteIdentity->GetSignatureLen ();
size_t paddingLen = expectedSize & 0x0F;
if (paddingLen) paddingLen = (16 - paddingLen);
if (expectedSize > NTCP_DEFAULT_PHASE3_SIZE)
{
// we need more bytes for Phase3
expectedSize += paddingLen;
boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, expectedSize - NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase3ExtraReceived, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, tsB, paddingLen));
}
else
HandlePhase3 (tsB, paddingLen);
}
}
void NTCPSession::HandlePhase3ExtraReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB, size_t paddingLen)
{
if (ecode)
{
LogPrint (eLogError, "Phase 3 extra read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
m_Decryption.Decrypt (m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, bytes_transferred, m_ReceiveBuffer+ NTCP_DEFAULT_PHASE3_SIZE);
HandlePhase3 (tsB, paddingLen);
}
}
void NTCPSession::HandlePhase3 (uint32_t tsB, size_t paddingLen)
{
uint8_t * buf = m_ReceiveBuffer + m_RemoteIdentity->GetFullLen () + 2 /*size*/;
uint32_t tsA = buf32toh(buf);
buf += 4;
buf += paddingLen;
SignedData s;
s.Insert (m_Establisher->phase1.pubKey, 256); // x
s.Insert (m_Establisher->phase2.pubKey, 256); // y
s.Insert (i2p::context.GetRouterInfo ().GetIdentHash (), 32); // ident
s.Insert (tsA); // tsA
s.Insert (tsB); // tsB
if (!s.Verify (m_RemoteIdentity, buf))
{
LogPrint (eLogError, "signature verification failed");
Terminate ();
return;
}
SendPhase4 (tsA, tsB);
}
void NTCPSession::SendPhase4 (uint32_t tsA, uint32_t tsB)
{
SignedData s;
s.Insert (m_Establisher->phase1.pubKey, 256); // x
s.Insert (m_Establisher->phase2.pubKey, 256); // y
s.Insert (m_RemoteIdentity->GetIdentHash (), 32); // ident
s.Insert (tsA); // tsA
s.Insert (tsB); // tsB
auto keys = i2p::context.GetPrivateKeys ();
auto signatureLen = keys.GetPublic ()->GetSignatureLen ();
s.Sign (keys, m_ReceiveBuffer);
size_t paddingSize = signatureLen & 0x0F; // %16
if (paddingSize > 0) signatureLen += (16 - paddingSize);
m_Encryption.Encrypt (m_ReceiveBuffer, signatureLen, m_ReceiveBuffer);
boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase4Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
void NTCPSession::HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint (eLogWarning, "Couldn't send Phase 4 message: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
LogPrint (eLogInfo, "NTCP server session from ", m_Socket.remote_endpoint (), " connected");
m_Server.AddNTCPSession (shared_from_this ());
Connected ();
m_ReceiveBufferOffset = 0;
m_NextMessage = nullptr;
Receive ();
}
}
void NTCPSession::HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA)
{
if (ecode)
{
LogPrint (eLogError, "Phase 4 read error: ", ecode.message (), ". Check your clock");
if (ecode != boost::asio::error::operation_aborted)
{
// this router doesn't like us
i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true);
Terminate ();
}
}
else
{
m_Decryption.Decrypt(m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer);
// verify signature
SignedData s;
s.Insert (m_Establisher->phase1.pubKey, 256); // x
s.Insert (m_Establisher->phase2.pubKey, 256); // y
s.Insert (i2p::context.GetIdentHash (), 32); // ident
s.Insert (tsA); // tsA
s.Insert (m_Establisher->phase2.encrypted.timestamp); // tsB
if (!s.Verify (m_RemoteIdentity, m_ReceiveBuffer))
{
LogPrint (eLogError, "signature verification failed");
Terminate ();
return;
}
LogPrint (eLogInfo, "NTCP session to ", m_Socket.remote_endpoint (), " connected");
Connected ();
m_ReceiveBufferOffset = 0;
m_NextMessage = nullptr;
Receive ();
}
}
void NTCPSession::Receive ()
{
m_Socket.async_read_some (boost::asio::buffer(m_ReceiveBuffer + m_ReceiveBufferOffset, NTCP_BUFFER_SIZE - m_ReceiveBufferOffset),
std::bind(&NTCPSession::HandleReceived, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
void NTCPSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint (eLogError, "Read error: ", ecode.message ());
if (!m_NumReceivedBytes) m_Server.Ban (m_ConnectedFrom);
//if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
m_NumReceivedBytes += bytes_transferred;
i2p::transport::transports.UpdateReceivedBytes (bytes_transferred);
m_ReceiveBufferOffset += bytes_transferred;
if (m_ReceiveBufferOffset >= 16)
{
int numReloads = 0;
do
{
uint8_t * nextBlock = m_ReceiveBuffer;
while (m_ReceiveBufferOffset >= 16)
{
if (!DecryptNextBlock (nextBlock)) // 16 bytes
{
Terminate ();
return;
}
nextBlock += 16;
m_ReceiveBufferOffset -= 16;
}
if (m_ReceiveBufferOffset > 0)
memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset);
// try to read more
if (numReloads < 5)
{
boost::system::error_code ec;
size_t moreBytes = m_Socket.available(ec);
if (moreBytes)
{
if (moreBytes > NTCP_BUFFER_SIZE - m_ReceiveBufferOffset)
moreBytes = NTCP_BUFFER_SIZE - m_ReceiveBufferOffset;
moreBytes = m_Socket.read_some (boost::asio::buffer (m_ReceiveBuffer + m_ReceiveBufferOffset, moreBytes));
if (ec)
{
LogPrint (eLogError, "Read more bytes error: ", ec.message ());
Terminate ();
return;
}
m_NumReceivedBytes += moreBytes;
m_ReceiveBufferOffset += moreBytes;
numReloads++;
}
}
}
while (m_ReceiveBufferOffset >= 16);
m_Handler.Flush ();
}
ScheduleTermination (); // reset termination timer
Receive ();
}
}
bool NTCPSession::DecryptNextBlock (const uint8_t * encrypted) // 16 bytes
{
if (!m_NextMessage) // new message, header expected
{
// descrypt header and extract length
uint8_t buf[16];
m_Decryption.Decrypt (encrypted, buf);
uint16_t dataSize = bufbe16toh (buf);
if (dataSize)
{
// new message
if (dataSize > NTCP_MAX_MESSAGE_SIZE)
{
LogPrint (eLogError, "NTCP data size ", dataSize, " exceeds max size");
return false;
}
auto msg = dataSize <= I2NP_MAX_SHORT_MESSAGE_SIZE - 2 ? NewI2NPShortMessage () : NewI2NPMessage ();
m_NextMessage = ToSharedI2NPMessage (msg);
memcpy (m_NextMessage->buf, buf, 16);
m_NextMessageOffset = 16;
m_NextMessage->offset = 2; // size field
m_NextMessage->len = dataSize + 2;
}
else
{
// timestamp
LogPrint ("Timestamp");
return true;
}
}
else // message continues
{
m_Decryption.Decrypt (encrypted, m_NextMessage->buf + m_NextMessageOffset);
m_NextMessageOffset += 16;
}
if (m_NextMessageOffset >= m_NextMessage->len + 4) // +checksum
{
// we have a complete I2NP message
uint8_t checksum[4];
htobe32buf (checksum, adler32 (adler32 (0, Z_NULL, 0), m_NextMessage->buf, m_NextMessageOffset - 4));
if (!memcmp (m_NextMessage->buf + m_NextMessageOffset - 4, checksum, 4))
m_Handler.PutNextMessage (m_NextMessage);
else
LogPrint (eLogWarning, "Incorrect adler checksum of NTCP message. Dropped");
m_NextMessage = nullptr;
}
return true;
}
void NTCPSession::Send (std::shared_ptr<i2p::I2NPMessage> msg)
{
m_IsSending = true;
boost::asio::async_write (m_Socket, CreateMsgBuffer (msg), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::vector<std::shared_ptr<I2NPMessage> >{ msg }));
}
boost::asio::const_buffers_1 NTCPSession::CreateMsgBuffer (std::shared_ptr<I2NPMessage> msg)
{
uint8_t * sendBuffer;
int len;
if (msg)
{
// regular I2NP
if (msg->offset < 2)
LogPrint (eLogError, "Malformed I2NP message"); // TODO:
sendBuffer = msg->GetBuffer () - 2;
len = msg->GetLength ();
htobe16buf (sendBuffer, len);
}
else
{
// prepare timestamp
sendBuffer = m_TimeSyncBuffer;
len = 4;
htobuf16(sendBuffer, 0);
htobe32buf (sendBuffer + 2, time (0));
}
int rem = (len + 6) & 0x0F; // %16
int padding = 0;
if (rem > 0) padding = 16 - rem;
// TODO: fill padding
htobe32buf (sendBuffer + len + 2 + padding, adler32 (adler32 (0, Z_NULL, 0), sendBuffer, len + 2+ padding));
int l = len + padding + 6;
m_Encryption.Encrypt(sendBuffer, l, sendBuffer);
return boost::asio::buffer ((const uint8_t *)sendBuffer, l);
}
void NTCPSession::Send (const std::vector<std::shared_ptr<I2NPMessage> >& msgs)
{
m_IsSending = true;
std::vector<boost::asio::const_buffer> bufs;
for (auto it: msgs)
bufs.push_back (CreateMsgBuffer (it));
boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (),
std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs));
}
void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector<std::shared_ptr<I2NPMessage> > msgs)
{
m_IsSending = false;
if (ecode)
{
LogPrint (eLogWarning, "Couldn't send msgs: ", ecode.message ());
// we shouldn't call Terminate () here, because HandleReceive takes care
// TODO: 'delete this' statement in Terminate () must be eliminated later
// Terminate ();
}
else
{
m_NumSentBytes += bytes_transferred;
i2p::transport::transports.UpdateSentBytes (bytes_transferred);
if (!m_SendQueue.empty())
{
Send (m_SendQueue);
m_SendQueue.clear ();
}
else
ScheduleTermination (); // reset termination timer
}
}
void NTCPSession::SendTimeSyncMessage ()
{
Send (nullptr);
}
void NTCPSession::SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs)
{
m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs));
}
void NTCPSession::PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs)
{
if (m_IsTerminated) return;
if (m_IsSending)
{
for (auto it: msgs)
m_SendQueue.push_back (it);
}
else
Send (msgs);
}
void NTCPSession::ScheduleTermination ()
{
m_TerminationTimer.cancel ();
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_TIMEOUT));
m_TerminationTimer.async_wait (std::bind (&NTCPSession::HandleTerminationTimer,
shared_from_this (), std::placeholders::_1));
}
void NTCPSession::HandleTerminationTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
LogPrint ("No activity fo ", NTCP_TERMINATION_TIMEOUT, " seconds");
//Terminate ();
m_Socket.close ();// invoke Terminate () from HandleReceive
}
}
//-----------------------------------------
NTCPServer::NTCPServer (int port):
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr)
{
}
NTCPServer::~NTCPServer ()
{
Stop ();
}
void NTCPServer::Start ()
{
if (!m_IsRunning)
{
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&NTCPServer::Run, this));
// create acceptors
auto addresses = context.GetRouterInfo ().GetAddresses ();
for (auto& address : addresses)
{
if (address.transportStyle == i2p::data::RouterInfo::eTransportNTCP && address.host.is_v4 ())
{
m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address.port));
LogPrint (eLogInfo, "Start listening TCP port ", address.port);
auto conn = std::make_shared<NTCPSession>(*this);
m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this,
conn, std::placeholders::_1));
if (context.SupportsV6 ())
{
m_NTCPV6Acceptor = new boost::asio::ip::tcp::acceptor (m_Service);
m_NTCPV6Acceptor->open (boost::asio::ip::tcp::v6());
m_NTCPV6Acceptor->set_option (boost::asio::ip::v6_only (true));
m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address.port));
m_NTCPV6Acceptor->listen ();
LogPrint (eLogInfo, "Start listening V6 TCP port ", address.port);
auto conn = std::make_shared<NTCPSession> (*this);
m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6,
this, conn, std::placeholders::_1));
}
}
}
}
}
void NTCPServer::Stop ()
{
m_NTCPSessions.clear ();
if (m_IsRunning)
{
m_IsRunning = false;
delete m_NTCPAcceptor;
m_NTCPAcceptor = nullptr;
delete m_NTCPV6Acceptor;
m_NTCPV6Acceptor = nullptr;
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
}
void NTCPServer::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint ("NTCP server: ", ex.what ());
}
}
}
void NTCPServer::AddNTCPSession (std::shared_ptr<NTCPSession> session)
{
if (session && session->GetRemoteIdentity ())
{
std::unique_lock<std::mutex> l(m_NTCPSessionsMutex);
m_NTCPSessions[session->GetRemoteIdentity ()->GetIdentHash ()] = session;
}
}
void NTCPServer::RemoveNTCPSession (std::shared_ptr<NTCPSession> session)
{
if (session && session->GetRemoteIdentity ())
{
std::unique_lock<std::mutex> l(m_NTCPSessionsMutex);
m_NTCPSessions.erase (session->GetRemoteIdentity ()->GetIdentHash ());
}
}
std::shared_ptr<NTCPSession> NTCPServer::FindNTCPSession (const i2p::data::IdentHash& ident)
{
std::unique_lock<std::mutex> l(m_NTCPSessionsMutex);
auto it = m_NTCPSessions.find (ident);
if (it != m_NTCPSessions.end ())
return it->second;
return nullptr;
}
void NTCPServer::HandleAccept (std::shared_ptr<NTCPSession> conn, const boost::system::error_code& error)
{
if (!error)
{
boost::system::error_code ec;
auto ep = conn->GetSocket ().remote_endpoint(ec);
if (!ec)
{
LogPrint (eLogInfo, "Connected from ", ep);
auto it = m_BanList.find (ep.address ());
if (it != m_BanList.end ())
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
if (ts < it->second)
{
LogPrint (eLogInfo, ep.address (), " is banned for ", it->second - ts, " more seconds");
conn = nullptr;
}
else
m_BanList.erase (it);
}
if (conn)
conn->ServerLogin ();
}
else
LogPrint (eLogError, "Connected from error ", ec.message ());
}
if (error != boost::asio::error::operation_aborted)
{
conn = std::make_shared<NTCPSession> (*this);
m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this,
conn, std::placeholders::_1));
}
}
void NTCPServer::HandleAcceptV6 (std::shared_ptr<NTCPSession> conn, const boost::system::error_code& error)
{
if (!error)
{
boost::system::error_code ec;
auto ep = conn->GetSocket ().remote_endpoint(ec);
if (!ec)
{
LogPrint (eLogInfo, "Connected from ", ep);
auto it = m_BanList.find (ep.address ());
if (it != m_BanList.end ())
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
if (ts < it->second)
{
LogPrint (eLogInfo, ep.address (), " is banned for ", it->second - ts, " more seconds");
conn = nullptr;
}
else
m_BanList.erase (it);
}
if (conn)
conn->ServerLogin ();
}
else
LogPrint (eLogError, "Connected from error ", ec.message ());
}
if (error != boost::asio::error::operation_aborted)
{
conn = std::make_shared<NTCPSession> (*this);
m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this,
conn, std::placeholders::_1));
}
}
void NTCPServer::Connect (const boost::asio::ip::address& address, int port, std::shared_ptr<NTCPSession> conn)
{
LogPrint (eLogInfo, "Connecting to ", address ,":", port);
m_Service.post([conn, this]()
{
this->AddNTCPSession (conn);
});
conn->GetSocket ().async_connect (boost::asio::ip::tcp::endpoint (address, port),
std::bind (&NTCPServer::HandleConnect, this, std::placeholders::_1, conn));
}
void NTCPServer::HandleConnect (const boost::system::error_code& ecode, std::shared_ptr<NTCPSession> conn)
{
if (ecode)
{
LogPrint (eLogError, "Connect error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true);
conn->Terminate ();
}
else
{
LogPrint (eLogInfo, "Connected to ", conn->GetSocket ().remote_endpoint ());
if (conn->GetSocket ().local_endpoint ().protocol () == boost::asio::ip::tcp::v6()) // ipv6
context.UpdateNTCPV6Address (conn->GetSocket ().local_endpoint ().address ());
conn->ClientLogin ();
}
}
void NTCPServer::Ban (const boost::asio::ip::address& addr)
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
m_BanList[addr] = ts + NTCP_BAN_EXPIRATION_TIMEOUT;
LogPrint (eLogInfo, addr, " has been banned for ", NTCP_BAN_EXPIRATION_TIMEOUT, " seconds");
}
}
}

984
NetDb.cpp
View File

@ -1,984 +0,0 @@
#include <string.h>
#include "I2PEndian.h"
#include <fstream>
#include <vector>
#include <boost/asio.hpp>
#include <openssl/rand.h>
#include <zlib.h>
#include "Base.h"
#include "Log.h"
#include "Timestamp.h"
#include "I2NPProtocol.h"
#include "Tunnel.h"
#include "Transports.h"
#include "RouterContext.h"
#include "Garlic.h"
#include "NetDb.h"
#include "util.h"
using namespace i2p::transport;
namespace i2p
{
namespace data
{
const char NetDb::m_NetDbPath[] = "netDb";
NetDb netdb;
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr)
{
}
NetDb::~NetDb ()
{
Stop ();
delete m_Reseeder;
}
void NetDb::Start ()
{
Load ();
if (m_RouterInfos.size () < 25) // reseed if # of router less than 50
Reseed ();
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&NetDb::Run, this));
}
void NetDb::Stop ()
{
if (m_IsRunning)
{
for (auto it: m_RouterInfos)
it.second->SaveProfile ();
DeleteObsoleteProfiles ();
m_RouterInfos.clear ();
m_Floodfills.clear ();
if (m_Thread)
{
m_IsRunning = false;
m_Queue.WakeUp ();
m_Thread->join ();
delete m_Thread;
m_Thread = 0;
}
m_LeaseSets.clear();
m_Requests.Stop ();
}
}
void NetDb::Run ()
{
uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0;
while (m_IsRunning)
{
try
{
auto msg = m_Queue.GetNextWithTimeout (15000); // 15 sec
if (msg)
{
int numMsgs = 0;
while (msg)
{
switch (msg->GetTypeID ())
{
case eI2NPDatabaseStore:
LogPrint ("DatabaseStore");
HandleDatabaseStoreMsg (msg);
break;
case eI2NPDatabaseSearchReply:
LogPrint ("DatabaseSearchReply");
HandleDatabaseSearchReplyMsg (msg);
break;
case eI2NPDatabaseLookup:
LogPrint ("DatabaseLookup");
HandleDatabaseLookupMsg (msg);
break;
default: // WTF?
LogPrint (eLogError, "NetDb: unexpected message type ", msg->GetTypeID ());
//i2p::HandleI2NPMessage (msg);
}
if (numMsgs > 100) break;
msg = m_Queue.Get ();
numMsgs++;
}
}
if (!m_IsRunning) break;
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
if (ts - lastManageRequest >= 15) // manage requests every 15 seconds
{
m_Requests.ManageRequests ();
lastManageRequest = ts;
}
if (ts - lastSave >= 60) // save routers, manage leasesets and validate subscriptions every minute
{
if (lastSave)
{
SaveUpdated ();
ManageLeaseSets ();
}
lastSave = ts;
}
if (ts - lastPublish >= 2400) // publish every 40 minutes
{
Publish ();
lastPublish = ts;
}
if (ts - lastExploratory >= 30) // exploratory every 30 seconds
{
auto numRouters = m_RouterInfos.size ();
if (numRouters < 2500 || ts - lastExploratory >= 90)
{
numRouters = 800/numRouters;
if (numRouters < 1) numRouters = 1;
if (numRouters > 9) numRouters = 9;
m_Requests.ManageRequests ();
Explore (numRouters);
lastExploratory = ts;
}
}
}
catch (std::exception& ex)
{
LogPrint ("NetDb: ", ex.what ());
}
}
}
void NetDb::AddRouterInfo (const uint8_t * buf, int len)
{
IdentityEx identity;
if (identity.FromBuffer (buf, len))
AddRouterInfo (identity.GetIdentHash (), buf, len);
}
void NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len)
{
auto r = FindRouter (ident);
if (r)
{
auto ts = r->GetTimestamp ();
r->Update (buf, len);
if (r->GetTimestamp () > ts)
LogPrint ("RouterInfo updated");
}
else
{
LogPrint ("New RouterInfo added");
r = std::make_shared<RouterInfo> (buf, len);
{
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
m_RouterInfos[r->GetIdentHash ()] = r;
}
if (r->IsFloodfill ())
{
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
m_Floodfills.push_back (r);
}
}
// take care about requested destination
m_Requests.RequestComplete (ident, r);
}
void NetDb::AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len,
std::shared_ptr<i2p::tunnel::InboundTunnel> from)
{
if (!from) // unsolicited LS must be received directly
{
auto it = m_LeaseSets.find(ident);
if (it != m_LeaseSets.end ())
{
it->second->Update (buf, len);
if (it->second->IsValid ())
LogPrint (eLogInfo, "LeaseSet updated");
else
{
LogPrint (eLogInfo, "LeaseSet update failed");
m_LeaseSets.erase (it);
}
}
else
{
auto leaseSet = std::make_shared<LeaseSet> (buf, len);
if (leaseSet->IsValid ())
{
LogPrint (eLogInfo, "New LeaseSet added");
m_LeaseSets[ident] = leaseSet;
}
else
LogPrint (eLogError, "New LeaseSet validation failed");
}
}
}
std::shared_ptr<RouterInfo> NetDb::FindRouter (const IdentHash& ident) const
{
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
auto it = m_RouterInfos.find (ident);
if (it != m_RouterInfos.end ())
return it->second;
else
return nullptr;
}
std::shared_ptr<LeaseSet> NetDb::FindLeaseSet (const IdentHash& destination) const
{
auto it = m_LeaseSets.find (destination);
if (it != m_LeaseSets.end ())
return it->second;
else
return nullptr;
}
std::shared_ptr<RouterProfile> NetDb::FindRouterProfile (const IdentHash& ident) const
{
auto router = FindRouter (ident);
return router ? router->GetProfile () : nullptr;
}
void NetDb::SetUnreachable (const IdentHash& ident, bool unreachable)
{
auto it = m_RouterInfos.find (ident);
if (it != m_RouterInfos.end ())
return it->second->SetUnreachable (unreachable);
}
// TODO: Move to reseed and/or scheduled tasks. (In java version, scheduler fix this as well as sort RIs.)
bool NetDb::CreateNetDb(boost::filesystem::path directory)
{
LogPrint (directory.string(), " doesn't exist, trying to create it.");
if (!boost::filesystem::create_directory (directory))
{
LogPrint("Failed to create directory ", directory.string());
return false;
}
// list of chars might appear in base64 string
const char * chars = GetBase64SubstitutionTable (); // 64 bytes
boost::filesystem::path suffix;
for (int i = 0; i < 64; i++)
{
#ifndef _WIN32
suffix = std::string ("/r") + chars[i];
#else
suffix = std::string ("\\r") + chars[i];
#endif
if (!boost::filesystem::create_directory( boost::filesystem::path (directory / suffix) )) return false;
}
return true;
}
void NetDb::Reseed ()
{
if (!m_Reseeder)
{
m_Reseeder = new Reseeder ();
m_Reseeder->LoadCertificates (); // we need certificates for SU3 verification
}
int reseedRetries = 0;
while (reseedRetries < 10 && !m_Reseeder->ReseedNowSU3 ())
reseedRetries++;
if (reseedRetries >= 10)
LogPrint (eLogWarning, "Failed to reseed after 10 attempts");
}
void NetDb::Load ()
{
boost::filesystem::path p(i2p::util::filesystem::GetDataDir() / m_NetDbPath);
if (!boost::filesystem::exists (p))
{
// seems netDb doesn't exist yet
if (!CreateNetDb(p)) return;
}
// make sure we cleanup netDb from previous attempts
m_RouterInfos.clear ();
m_Floodfills.clear ();
// load routers now
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
int numRouters = 0;
boost::filesystem::directory_iterator end;
for (boost::filesystem::directory_iterator it (p); it != end; ++it)
{
if (boost::filesystem::is_directory (it->status()))
{
for (boost::filesystem::directory_iterator it1 (it->path ()); it1 != end; ++it1)
{
#if BOOST_VERSION > 10500
const std::string& fullPath = it1->path().string();
#else
const std::string& fullPath = it1->path();
#endif
auto r = std::make_shared<RouterInfo>(fullPath);
if (!r->IsUnreachable () && (!r->UsesIntroducer () || ts < r->GetTimestamp () + 3600*1000LL)) // 1 hour
{
r->DeleteBuffer ();
r->ClearProperties (); // properties are not used for regular routers
m_RouterInfos[r->GetIdentHash ()] = r;
if (r->IsFloodfill ())
m_Floodfills.push_back (r);
numRouters++;
}
else
{
if (boost::filesystem::exists (fullPath))
boost::filesystem::remove (fullPath);
}
}
}
}
LogPrint (numRouters, " routers loaded");
LogPrint (m_Floodfills.size (), " floodfills loaded");
}
void NetDb::SaveUpdated ()
{
auto GetFilePath = [](const boost::filesystem::path& directory, const RouterInfo * routerInfo)
{
std::string s(routerInfo->GetIdentHashBase64());
return directory / (std::string("r") + s[0]) / ("routerInfo-" + s + ".dat");
};
boost::filesystem::path fullDirectory (i2p::util::filesystem::GetDataDir() / m_NetDbPath);
int count = 0, deletedCount = 0;
auto total = m_RouterInfos.size ();
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
for (auto it: m_RouterInfos)
{
if (it.second->IsUpdated ())
{
std::string f = GetFilePath(fullDirectory, it.second.get()).string();
it.second->SaveToFile (f);
it.second->SetUpdated (false);
it.second->SetUnreachable (false);
it.second->DeleteBuffer ();
count++;
}
else
{
// RouterInfo expires after 1 hour if uses introducer
if (it.second->UsesIntroducer () && ts > it.second->GetTimestamp () + 3600*1000LL) // 1 hour
it.second->SetUnreachable (true);
else if (total > 75 && ts > (i2p::context.GetStartupTime () + 600)*1000LL) // routers don't expire if less than 25 or uptime is less than 10 minutes
{
if (i2p::context.IsFloodfill ())
{
if (ts > it.second->GetTimestamp () + 3600*1000LL) // 1 hours
{
it.second->SetUnreachable (true);
total--;
}
}
else if (total > 300)
{
if (ts > it.second->GetTimestamp () + 30*3600*1000LL) // 30 hours
{
it.second->SetUnreachable (true);
total--;
}
}
else if (total > 120)
{
if (ts > it.second->GetTimestamp () + 72*3600*1000LL) // 72 hours
{
it.second->SetUnreachable (true);
total--;
}
}
}
if (it.second->IsUnreachable ())
{
total--;
// delete RI file
if (boost::filesystem::exists (GetFilePath (fullDirectory, it.second.get ())))
{
boost::filesystem::remove (GetFilePath (fullDirectory, it.second.get ()));
deletedCount++;
}
// delete from floodfills list
if (it.second->IsFloodfill ())
{
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
m_Floodfills.remove (it.second);
}
}
}
}
if (count > 0)
LogPrint (count," new/updated routers saved");
if (deletedCount > 0)
{
LogPrint (deletedCount," routers deleted");
// clean up RouterInfos table
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();)
{
if (it->second->IsUnreachable ())
{
it->second->SaveProfile ();
it = m_RouterInfos.erase (it);
}
else
it++;
}
}
}
void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete)
{
auto dest = m_Requests.CreateRequest (destination, false, requestComplete); // non-exploratory
if (!dest)
{
LogPrint (eLogWarning, "Destination ", destination.ToBase64(), " is requested already");
return;
}
auto floodfill = GetClosestFloodfill (destination, dest->GetExcludedPeers ());
if (floodfill)
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
else
{
LogPrint (eLogError, "No floodfills found");
m_Requests.RequestComplete (destination, nullptr);
}
}
void NetDb::HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> m)
{
const uint8_t * buf = m->GetPayload ();
size_t len = m->GetSize ();
IdentHash ident (buf + DATABASE_STORE_KEY_OFFSET);
if (ident.IsZero ())
{
LogPrint (eLogError, "Database store with zero ident. Dropped");
return;
}
uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET);
size_t offset = DATABASE_STORE_HEADER_SIZE;
if (replyToken)
{
auto deliveryStatus = CreateDeliveryStatusMsg (replyToken);
uint32_t tunnelID = bufbe32toh (buf + offset);
offset += 4;
if (!tunnelID) // send response directly
transports.SendMessage (buf + offset, deliveryStatus);
else
{
auto pool = i2p::tunnel::tunnels.GetExploratoryPool ();
auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr;
if (outbound)
outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus);
else
LogPrint (eLogError, "No outbound tunnels for DatabaseStore reply found");
}
offset += 32;
if (context.IsFloodfill ())
{
// flood it
auto floodMsg = ToSharedI2NPMessage (NewI2NPShortMessage ());
uint8_t * payload = floodMsg->GetPayload ();
memcpy (payload, buf, 33); // key + type
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); // zero reply token
memcpy (payload + DATABASE_STORE_HEADER_SIZE, buf + offset, len - offset);
floodMsg->len += DATABASE_STORE_HEADER_SIZE + len -offset;
floodMsg->FillI2NPMessageHeader (eI2NPDatabaseStore);
std::set<IdentHash> excluded;
for (int i = 0; i < 3; i++)
{
auto floodfill = GetClosestFloodfill (ident, excluded);
if (floodfill)
transports.SendMessage (floodfill->GetIdentHash (), floodMsg);
}
}
}
if (buf[DATABASE_STORE_TYPE_OFFSET]) // type
{
LogPrint ("LeaseSet");
AddLeaseSet (ident, buf + offset, len - offset, m->from);
}
else
{
LogPrint ("RouterInfo");
size_t size = bufbe16toh (buf + offset);
offset += 2;
if (size > 2048 || size > len - offset)
{
LogPrint ("Invalid RouterInfo length ", (int)size);
return;
}
uint8_t uncompressed[2048];
size_t uncompressedSize = m_Inflator.Inflate (buf + offset, size, uncompressed, 2048);
if (uncompressedSize)
AddRouterInfo (ident, uncompressed, uncompressedSize);
}
}
void NetDb::HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg)
{
const uint8_t * buf = msg->GetPayload ();
char key[48];
int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48);
key[l] = 0;
int num = buf[32]; // num
LogPrint ("DatabaseSearchReply for ", key, " num=", num);
IdentHash ident (buf);
auto dest = m_Requests.FindRequest (ident);
if (dest)
{
bool deleteDest = true;
if (num > 0)
{
auto pool = i2p::tunnel::tunnels.GetExploratoryPool ();
auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr;
auto inbound = pool ? pool->GetNextInboundTunnel () : nullptr;
if (!dest->IsExploratory ())
{
// reply to our destination. Try other floodfills
if (outbound && inbound )
{
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
auto count = dest->GetExcludedPeers ().size ();
if (count < 7)
{
auto nextFloodfill = GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ());
if (nextFloodfill)
{
// tell floodfill about us
msgs.push_back (i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeRouter,
nextFloodfill->GetIdentHash (), 0,
CreateDatabaseStoreMsg ()
});
// request destination
LogPrint ("Try ", key, " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ());
auto msg = dest->CreateRequestMessage (nextFloodfill, inbound);
msgs.push_back (i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeRouter,
nextFloodfill->GetIdentHash (), 0, msg
});
deleteDest = false;
}
}
else
LogPrint (key, " was not found on 7 floodfills");
if (msgs.size () > 0)
outbound->SendTunnelDataMsg (msgs);
}
}
if (deleteDest)
// no more requests for the destinationation. delete it
m_Requests.RequestComplete (ident, nullptr);
}
else
// no more requests for detination possible. delete it
m_Requests.RequestComplete (ident, nullptr);
}
else
LogPrint ("Requested destination for ", key, " not found");
// try responses
for (int i = 0; i < num; i++)
{
const uint8_t * router = buf + 33 + i*32;
char peerHash[48];
int l1 = i2p::data::ByteStreamToBase64 (router, 32, peerHash, 48);
peerHash[l1] = 0;
LogPrint (i,": ", peerHash);
auto r = FindRouter (router);
if (!r || i2p::util::GetMillisecondsSinceEpoch () > r->GetTimestamp () + 3600*1000LL)
{
// router with ident not found or too old (1 hour)
LogPrint ("Found new/outdated router. Requesting RouterInfo ...");
RequestDestination (router);
}
else
LogPrint ("Bayan");
}
}
void NetDb::HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg)
{
const uint8_t * buf = msg->GetPayload ();
IdentHash ident (buf);
if (ident.IsZero ())
{
LogPrint (eLogError, "DatabaseLookup for zero ident. Ignored");
return;
}
char key[48];
int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48);
key[l] = 0;
uint8_t flag = buf[64];
LogPrint ("DatabaseLookup for ", key, " recieved flags=", (int)flag);
uint8_t lookupType = flag & DATABASE_LOOKUP_TYPE_FLAGS_MASK;
const uint8_t * excluded = buf + 65;
uint32_t replyTunnelID = 0;
if (flag & DATABASE_LOOKUP_DELIVERY_FLAG) //reply to tunnel
{
replyTunnelID = bufbe32toh (buf + 64);
excluded += 4;
}
uint16_t numExcluded = bufbe16toh (excluded);
excluded += 2;
if (numExcluded > 512)
{
LogPrint ("Number of excluded peers", numExcluded, " exceeds 512");
numExcluded = 0; // TODO:
}
std::shared_ptr<I2NPMessage> replyMsg;
if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP)
{
LogPrint ("Exploratory close to ", key, " ", numExcluded, " excluded");
std::set<IdentHash> excludedRouters;
for (int i = 0; i < numExcluded; i++)
{
excludedRouters.insert (excluded);
excluded += 32;
}
std::vector<IdentHash> routers;
for (int i = 0; i < 3; i++)
{
auto r = GetClosestNonFloodfill (ident, excludedRouters);
if (r)
{
routers.push_back (r->GetIdentHash ());
excludedRouters.insert (r->GetIdentHash ());
}
}
replyMsg = CreateDatabaseSearchReply (ident, routers);
}
else
{
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
{
auto router = FindRouter (ident);
if (router)
{
LogPrint ("Requested RouterInfo ", key, " found");
router->LoadBuffer ();
if (router->GetBuffer ())
replyMsg = CreateDatabaseStoreMsg (router);
}
}
if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP ||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP))
{
auto leaseSet = FindLeaseSet (ident);
if (leaseSet) // we don't send back our LeaseSets
{
LogPrint ("Requested LeaseSet ", key, " found");
replyMsg = CreateDatabaseStoreMsg (leaseSet);
}
}
if (!replyMsg)
{
LogPrint ("Requested ", key, " not found. ", numExcluded, " excluded");
std::set<IdentHash> excludedRouters;
for (int i = 0; i < numExcluded; i++)
{
excludedRouters.insert (excluded);
excluded += 32;
}
replyMsg = CreateDatabaseSearchReply (ident, GetClosestFloodfills (ident, 3, excludedRouters));
}
}
if (replyMsg)
{
if (replyTunnelID)
{
// encryption might be used though tunnel only
if (flag & DATABASE_LOOKUP_ENCYPTION_FLAG) // encrypted reply requested
{
const uint8_t * sessionKey = excluded;
uint8_t numTags = sessionKey[32];
if (numTags > 0)
{
const uint8_t * sessionTag = sessionKey + 33; // take first tag
i2p::garlic::GarlicRoutingSession garlic (sessionKey, sessionTag);
replyMsg = garlic.WrapSingleMessage (replyMsg);
}
}
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr;
if (outbound)
outbound->SendTunnelDataMsg (buf+32, replyTunnelID, replyMsg);
else
transports.SendMessage (buf+32, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg));
}
else
transports.SendMessage (buf+32, replyMsg);
}
}
void NetDb::Explore (int numDestinations)
{
// new requests
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr;
auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr;
bool throughTunnels = outbound && inbound;
uint8_t randomHash[32];
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
std::set<const RouterInfo *> floodfills;
LogPrint ("Exploring new ", numDestinations, " routers ...");
for (int i = 0; i < numDestinations; i++)
{
RAND_bytes (randomHash, 32);
auto dest = m_Requests.CreateRequest (randomHash, true); // exploratory
if (!dest)
{
LogPrint (eLogWarning, "Exploratory destination is requested already");
return;
}
auto floodfill = GetClosestFloodfill (randomHash, dest->GetExcludedPeers ());
if (floodfill && !floodfills.count (floodfill.get ())) // request floodfill only once
{
floodfills.insert (floodfill.get ());
if (i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
throughTunnels = false;
if (throughTunnels)
{
msgs.push_back (i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeRouter,
floodfill->GetIdentHash (), 0,
CreateDatabaseStoreMsg () // tell floodfill about us
});
msgs.push_back (i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeRouter,
floodfill->GetIdentHash (), 0,
dest->CreateRequestMessage (floodfill, inbound) // explore
});
}
else
i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
}
else
m_Requests.RequestComplete (randomHash, nullptr);
}
if (throughTunnels && msgs.size () > 0)
outbound->SendTunnelDataMsg (msgs);
}
void NetDb::Publish ()
{
std::set<IdentHash> excluded; // TODO: fill up later
for (int i = 0; i < 2; i++)
{
auto floodfill = GetClosestFloodfill (i2p::context.GetRouterInfo ().GetIdentHash (), excluded);
if (floodfill)
{
uint32_t replyToken;
RAND_bytes ((uint8_t *)&replyToken, 4);
LogPrint ("Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken);
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
excluded.insert (floodfill->GetIdentHash ());
}
}
}
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter () const
{
return GetRandomRouter (
[](std::shared_ptr<const RouterInfo> router)->bool
{
return !router->IsHidden ();
});
}
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const
{
return GetRandomRouter (
[compatibleWith](std::shared_ptr<const RouterInfo> router)->bool
{
return !router->IsHidden () && router != compatibleWith &&
router->IsCompatible (*compatibleWith);
});
}
std::shared_ptr<const RouterInfo> NetDb::GetRandomPeerTestRouter () const
{
return GetRandomRouter (
[](std::shared_ptr<const RouterInfo> router)->bool
{
return !router->IsHidden () && router->IsPeerTesting ();
});
}
std::shared_ptr<const RouterInfo> NetDb::GetRandomIntroducer () const
{
return GetRandomRouter (
[](std::shared_ptr<const RouterInfo> router)->bool
{
return !router->IsHidden () && router->IsIntroducer ();
});
}
std::shared_ptr<const RouterInfo> NetDb::GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const
{
return GetRandomRouter (
[compatibleWith](std::shared_ptr<const RouterInfo> router)->bool
{
return !router->IsHidden () && router != compatibleWith &&
router->IsCompatible (*compatibleWith) &&
(router->GetCaps () & RouterInfo::eHighBandwidth);
});
}
template<typename Filter>
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter (Filter filter) const
{
if (!m_RouterInfos.size ()) return 0;
uint32_t ind = rand () % m_RouterInfos.size ();
for (int j = 0; j < 2; j++)
{
uint32_t i = 0;
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
for (auto it: m_RouterInfos)
{
if (i >= ind)
{
if (!it.second->IsUnreachable () && filter (it.second))
return it.second;
}
else
i++;
}
// we couldn't find anything, try second pass
ind = 0;
}
return nullptr; // seems we have too few routers
}
void NetDb::PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg)
{
if (msg) m_Queue.Put (msg);
}
std::shared_ptr<const RouterInfo> NetDb::GetClosestFloodfill (const IdentHash& destination,
const std::set<IdentHash>& excluded) const
{
std::shared_ptr<const RouterInfo> r;
XORMetric minMetric;
IdentHash destKey = CreateRoutingKey (destination);
minMetric.SetMax ();
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
for (auto it: m_Floodfills)
{
if (!it->IsUnreachable ())
{
XORMetric m = destKey ^ it->GetIdentHash ();
if (m < minMetric && !excluded.count (it->GetIdentHash ()))
{
minMetric = m;
r = it;
}
}
}
return r;
}
std::vector<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num,
std::set<IdentHash>& excluded) const
{
struct Sorted
{
std::shared_ptr<const RouterInfo> r;
XORMetric metric;
bool operator< (const Sorted& other) const { return metric < other.metric; };
};
std::set<Sorted> sorted;
IdentHash destKey = CreateRoutingKey (destination);
{
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
for (auto it: m_Floodfills)
{
if (!it->IsUnreachable ())
{
XORMetric m = destKey ^ it->GetIdentHash ();
if (sorted.size () < num)
sorted.insert ({it, m});
else if (m < sorted.rbegin ()->metric)
{
sorted.insert ({it, m});
sorted.erase (std::prev (sorted.end ()));
}
}
}
}
std::vector<IdentHash> res;
size_t i = 0;
for (auto it: sorted)
{
if (i < num)
{
auto& ident = it.r->GetIdentHash ();
if (!excluded.count (ident))
{
res.push_back (ident);
i++;
}
}
else
break;
}
return res;
}
std::shared_ptr<const RouterInfo> NetDb::GetClosestNonFloodfill (const IdentHash& destination,
const std::set<IdentHash>& excluded) const
{
std::shared_ptr<const RouterInfo> r;
XORMetric minMetric;
IdentHash destKey = CreateRoutingKey (destination);
minMetric.SetMax ();
// must be called from NetDb thread only
for (auto it: m_RouterInfos)
{
if (!it.second->IsFloodfill ())
{
XORMetric m = destKey ^ it.first;
if (m < minMetric && !excluded.count (it.first))
{
minMetric = m;
r = it.second;
}
}
}
return r;
}
void NetDb::ManageLeaseSets ()
{
for (auto it = m_LeaseSets.begin (); it != m_LeaseSets.end ();)
{
if (!it->second->HasNonExpiredLeases ()) // all leases expired
{
LogPrint ("LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired");
it = m_LeaseSets.erase (it);
}
else
it++;
}
}
}
}

109
NetDb.h
View File

@ -1,109 +0,0 @@
#ifndef NETDB_H__
#define NETDB_H__
#include <inttypes.h>
#include <set>
#include <map>
#include <list>
#include <string>
#include <thread>
#include <mutex>
#include <boost/filesystem.hpp>
#include "Base.h"
#include "Queue.h"
#include "I2NPProtocol.h"
#include "RouterInfo.h"
#include "LeaseSet.h"
#include "Tunnel.h"
#include "TunnelPool.h"
#include "Reseed.h"
#include "NetDbRequests.h"
namespace i2p
{
namespace data
{
class NetDb
{
public:
NetDb ();
~NetDb ();
void Start ();
void Stop ();
void AddRouterInfo (const uint8_t * buf, int len);
void AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len);
void AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
std::shared_ptr<RouterInfo> FindRouter (const IdentHash& ident) const;
std::shared_ptr<LeaseSet> FindLeaseSet (const IdentHash& destination) const;
std::shared_ptr<RouterProfile> FindRouterProfile (const IdentHash& ident) const;
void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr);
void HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> msg);
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
void HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg);
std::shared_ptr<const RouterInfo> GetRandomRouter () const;
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter () const;
std::shared_ptr<const RouterInfo> GetRandomIntroducer () const;
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
std::set<IdentHash>& excluded) const;
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
void SetUnreachable (const IdentHash& ident, bool unreachable);
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
void Reseed ();
// for web interface
int GetNumRouters () const { return m_RouterInfos.size (); };
int GetNumFloodfills () const { return m_Floodfills.size (); };
int GetNumLeaseSets () const { return m_LeaseSets.size (); };
private:
bool CreateNetDb(boost::filesystem::path directory);
void Load ();
void SaveUpdated ();
void Run (); // exploratory thread
void Explore (int numDestinations);
void Publish ();
void ManageLeaseSets ();
void ManageRequests ();
template<typename Filter>
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
private:
std::map<IdentHash, std::shared_ptr<LeaseSet> > m_LeaseSets;
mutable std::mutex m_RouterInfosMutex;
std::map<IdentHash, std::shared_ptr<RouterInfo> > m_RouterInfos;
mutable std::mutex m_FloodfillsMutex;
std::list<std::shared_ptr<RouterInfo> > m_Floodfills;
bool m_IsRunning;
std::thread * m_Thread;
i2p::util::Queue<std::shared_ptr<const I2NPMessage> > m_Queue; // of I2NPDatabaseStoreMsg
GzipInflator m_Inflator;
Reseeder * m_Reseeder;
friend class NetDbRequests;
NetDbRequests m_Requests;
static const char m_NetDbPath[];
};
extern NetDb netdb;
}
}
#endif

View File

@ -1,214 +0,0 @@
#include <boost/filesystem.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "Base.h"
#include "util.h"
#include "Log.h"
#include "Profiling.h"
namespace i2p
{
namespace data
{
RouterProfile::RouterProfile (const IdentHash& identHash):
m_IdentHash (identHash), m_LastUpdateTime (boost::posix_time::second_clock::local_time()),
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
m_NumTimesTaken (0), m_NumTimesRejected (0)
{
}
boost::posix_time::ptime RouterProfile::GetTime () const
{
return boost::posix_time::second_clock::local_time();
}
void RouterProfile::UpdateTime ()
{
m_LastUpdateTime = GetTime ();
}
void RouterProfile::Save ()
{
// fill sections
boost::property_tree::ptree participation;
participation.put (PEER_PROFILE_PARTICIPATION_AGREED, m_NumTunnelsAgreed);
participation.put (PEER_PROFILE_PARTICIPATION_DECLINED, m_NumTunnelsDeclined);
participation.put (PEER_PROFILE_PARTICIPATION_NON_REPLIED, m_NumTunnelsNonReplied);
boost::property_tree::ptree usage;
usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken);
usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected);
// fill property tree
boost::property_tree::ptree pt;
pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime));
pt.put_child (PEER_PROFILE_SECTION_PARTICIPATION, participation);
pt.put_child (PEER_PROFILE_SECTION_USAGE, usage);
// save to file
auto path = i2p::util::filesystem::GetDefaultDataDir() / PEER_PROFILES_DIRECTORY;
if (!boost::filesystem::exists (path))
{
// Create directory is necessary
if (!boost::filesystem::create_directory (path))
{
LogPrint (eLogError, "Failed to create directory ", path);
return;
}
const char * chars = GetBase64SubstitutionTable (); // 64 bytes
for (int i = 0; i < 64; i++)
{
auto path1 = path / (std::string ("p") + chars[i]);
if (!boost::filesystem::create_directory (path1))
{
LogPrint (eLogError, "Failed to create directory ", path1);
return;
}
}
}
std::string base64 = m_IdentHash.ToBase64 ();
path = path / (std::string ("p") + base64[0]);
auto filename = path / (std::string (PEER_PROFILE_PREFIX) + base64 + ".txt");
try
{
boost::property_tree::write_ini (filename.string (), pt);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Can't write ", filename, ": ", ex.what ());
}
}
void RouterProfile::Load ()
{
std::string base64 = m_IdentHash.ToBase64 ();
auto path = i2p::util::filesystem::GetDefaultDataDir() / PEER_PROFILES_DIRECTORY;
path /= std::string ("p") + base64[0];
auto filename = path / (std::string (PEER_PROFILE_PREFIX) + base64 + ".txt");
if (boost::filesystem::exists (filename))
{
boost::property_tree::ptree pt;
try
{
boost::property_tree::read_ini (filename.string (), pt);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Can't read ", filename, ": ", ex.what ());
return;
}
try
{
auto t = pt.get (PEER_PROFILE_LAST_UPDATE_TIME, "");
if (t.length () > 0)
m_LastUpdateTime = boost::posix_time::time_from_string (t);
if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT)
{
try
{
// read participations
auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION);
m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0);
m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0);
m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0);
}
catch (boost::property_tree::ptree_bad_path& ex)
{
LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_PARTICIPATION);
}
try
{
// read usage
auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE);
m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0);
m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0);
}
catch (boost::property_tree::ptree_bad_path& ex)
{
LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE);
}
}
else
*this = RouterProfile (m_IdentHash);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Can't read profile ", base64, " :", ex.what ());
}
}
}
void RouterProfile::TunnelBuildResponse (uint8_t ret)
{
UpdateTime ();
if (ret > 0)
m_NumTunnelsDeclined++;
else
m_NumTunnelsAgreed++;
}
void RouterProfile::TunnelNonReplied ()
{
m_NumTunnelsNonReplied++;
UpdateTime ();
}
bool RouterProfile::IsLowPartcipationRate () const
{
return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate
}
bool RouterProfile::IsLowReplyRate () const
{
auto total = m_NumTunnelsAgreed + m_NumTunnelsDeclined;
return m_NumTunnelsNonReplied > 10*(total + 1);
}
bool RouterProfile::IsBad ()
{
auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/;
if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1))
{
// reset profile
m_NumTunnelsAgreed = 0;
m_NumTunnelsDeclined = 0;
m_NumTunnelsNonReplied = 0;
isBad = false;
}
if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++;
return isBad;
}
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
{
auto profile = std::make_shared<RouterProfile> (identHash);
profile->Load (); // if possible
return profile;
}
void DeleteObsoleteProfiles ()
{
int num = 0;
auto ts = boost::posix_time::second_clock::local_time();
boost::filesystem::path p (i2p::util::filesystem::GetDataDir()/PEER_PROFILES_DIRECTORY);
if (boost::filesystem::exists (p))
{
boost::filesystem::directory_iterator end;
for (boost::filesystem::directory_iterator it (p); it != end; ++it)
{
if (boost::filesystem::is_directory (it->status()))
{
for (boost::filesystem::directory_iterator it1 (it->path ()); it1 != end; ++it1)
{
auto lastModified = boost::posix_time::from_time_t (boost::filesystem::last_write_time (it1->path ()));
if ((ts - lastModified).hours () >= PEER_PROFILE_EXPIRATION_TIMEOUT)
{
boost::filesystem::remove (it1->path ());
num++;
}
}
}
}
}
LogPrint (eLogInfo, num, " obsolete profiles deleted");
}
}
}

215
README.md
View File

@ -1,145 +1,86 @@
i2pd
====
I2P router written in C++
Contains all ongoing changes from https://bitbucket.org/orignal/i2pd/src
[Русская версия](https://github.com/PurpleI2P/i2pd_docs_ru/blob/master/README.md)
i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.
I2P (Invisible Internet Protocol) is a universal anonymous network layer.
All communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses.
I2P client is a software used for building and using anonymous I2P
networks. Such networks are commonly used for anonymous peer-to-peer
applications (filesharing, cryptocurrencies) and anonymous client-server
applications (websites, instant messengers, chat-servers).
I2P allows people from all around the world to communicate and share information
without restrictions.
Features
--------
* Distributed anonymous networking framework
* End-to-end encrypted communications
* Small footprint, simple dependencies, fast performance
* Rich set of APIs for developers of secure applications
Resources
---------
* [Website](http://i2pd.website)
* [Documentation](https://i2pd.readthedocs.io/en/latest/)
* [Wiki](https://github.com/PurpleI2P/i2pd/wiki)
* [Tickets/Issues](https://github.com/PurpleI2P/i2pd/issues)
* [Specifications](https://geti2p.net/spec)
* [Twitter](https://twitter.com/hashtag/i2pd)
Installing
----------
The easiest way to install i2pd is by using
[precompiled binaries](https://github.com/PurpleI2P/i2pd/releases/latest).
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
i2pd from source on your OS.
Build instructions:
* [unix](https://i2pd.readthedocs.io/en/latest/devs/building/unix/)
* [windows](https://i2pd.readthedocs.io/en/latest/devs/building/windows/)
* [iOS](https://i2pd.readthedocs.io/en/latest/devs/building/ios/)
* [android](https://i2pd.readthedocs.io/en/latest/devs/building/android/)
**Supported systems:**
* GNU/Linux x86/x64 - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd)
* Windows - [![Build status](https://ci.appveyor.com/api/projects/status/1908qe4p48ff1x23?svg=true)](https://ci.appveyor.com/project/PurpleI2P/i2pd)
* Mac OS X - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd)
* CentOS / Fedora - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/)
* Docker image - [![Build Status](https://dockerbuildbadges.quelltext.eu/status.svg?organization=meeh&repository=i2pd)](https://hub.docker.com/r/meeh/i2pd/builds/)
* FreeBSD
* Android
* iOS
Using i2pd
----------
See [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/run/) and
[example config file](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf).
Donations
---------
BTC: 3MDoGJW9TLMTCDGrR9bLgWXfm6sjmgy86f
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d
DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF
ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ
GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG
License
-------
This project is licensed under the BSD 3-clause license, which can be found in the file
LICENSE in the root of the project source code.
Donations
---------
BTC: 1K7Ds6KUeR8ya287UC4rYTjvC96vXyZbDY
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
ANC: AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z
Requirements for Linux/FreeBSD/OSX
----------------------------------
GCC 4.6 or newer, Boost 1.46 or newer, openssl, zlib. Clang can be used instead of
GCC.
Requirements for Windows
------------------------
VS2013 (known to work with 12.0.21005.1 or newer), Boost 1.46 or newer,
crypto++ 5.62. See Win32/README-Build.txt for instructions on how to build i2pd
and its dependencies.
Downloads
------------
Official binary releases could be found at:
http://download.i2p.io/purplei2p/i2pd/releases/
Build Statuses
---------------
- Linux x64 - [![Build Status](https://jenkins.greyhat.no/buildStatus/icon?job=i2pd-linux)](https://jenkins.nordcloud.no/job/i2pd-linux/)
- Linux ARM - To be added
- Mac OS X - Got it working, but not well tested. (Only works with clang, not GCC.)
- Microsoft VC13 - To be added
Testing
-------
First, build it.
On Ubuntu/Debian based
* sudo apt-get install libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-regex-dev libboost-date-time-dev libssl-dev zlib1g-dev
* $ cd i2pd
* $ make
Then, run it:
$ ./i2p
The client should now reseed by itself.
To visit an I2P page, you need to find the b32 address of your destination.
After that, go to the webconsole and add it behind the url. (Remove http:// from the address)
This should resulting in for example:
http://localhost:7070/4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa.b32.i2p
Cmdline options
---------------
* --host= - The external IP (deprecated).
* --port= - The port to listen on
* --httpport= - The http port to listen on
* --log= - Enable or disable logging to file. 1 for yes, 0 for no.
* --daemon= - Enable or disable daemon mode. 1 for yes, 0 for no.
* --service= - 1 if uses system folders (/var/run/i2pd.pid, /var/log/i2pd.log, /var/lib/i2pd).
* --v6= - 1 if supports communication through ipv6, off by default
* --floodfill= - 1 if router is floodfill, off by default
* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O if not. Always O if floodfill, otherwise L by default.
* --httpproxyport= - The port to listen on (HTTP Proxy)
* --socksproxyport= - The port to listen on (SOCKS Proxy)
* --proxykeys= - optional keys file for proxy's local destination
* --ircport= - The local port of IRC tunnel to listen on. 6668 by default
* --ircdest= - I2P destination address of IRC server. For example irc.postman.i2p
* --irckeys= - optional keys file for tunnel's local destination
* --eepkeys= - File name containing destination keys, for example privKeys.dat.
The file will be created if it does not already exist (issue #110).
* --eephost= - Address incoming trafic forward to. 127.0.0.1 by default
* --eepport= - Port incoming trafic forward to. 80 by default
* --samport= - Port of SAM bridge. Usually 7656. SAM is off if not specified
* --bobport= - Port of BOB command channel. Usually 2827. BOB is off if not specified
* --i2pcontrolport= - Port of I2P control service. Usually 7650. I2PControl is off if not specified
* --conf= - Config file (default: ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf)
This parameter will be silently ignored if the specified config file does not exist.
Options specified on the command line take precedence over those in the config file.
Config files
------------
INI-like, syntax is the following : <key> = <value>.
All command-line parameters are allowed as keys, for example:
i2p.conf:
log = 1
v6 = 0
ircdest = irc.postman.i2p
tunnels.cfg (filename of this config is subject of change):
; outgoing tunnel sample, to remote service
; mandatory parameters:
; * type -- always "client"
; * port -- local port to listen to
; * destination -- i2p hostname
; optional parameters (may be omitted)
; * keys -- our identity, if unset, will be generated on every startup,
; if set and file missing, keys will be generated and placed to this file
[IRC]
type = client
port = 6668
destination = irc.echelon.i2p
keys = irc-keys.dat
; incoming tunnel sample, for local service
; mandatory parameters:
; * type -- always "server"
; * host -- ip address of our service
; * port -- port of our service
; * keys -- file with LeaseSet of address in i2p
; optional parameters (may be omitted)
; * inport -- optional, i2p service port, if unset - the same as 'port'
; * accesslist -- comma-separated list of i2p addresses, allowed to connect
; every address is b32 without '.b32.i2p' part
[LOCALSITE]
type = server
host = 127.0.0.1
port = 80
keys = site-keys.dat
inport = 81
accesslist = <b32>[,<b32>]
LICENSE in the root of the project source code.

View File

@ -1,414 +0,0 @@
#include <string.h>
#include <fstream>
#include <sstream>
#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <openssl/bn.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <zlib.h>
#include "I2PEndian.h"
#include "Reseed.h"
#include "Log.h"
#include "Identity.h"
#include "Crypto.h"
#include "NetDb.h"
#include "util.h"
namespace i2p
{
namespace data
{
static std::vector<std::string> httpsReseedHostList =
{
"https://reseed.i2p-projekt.de/", // Only HTTPS
"https://i2pseed.zarrenspry.info/", // Only HTTPS and SU3 (v3) support
"https://i2p.mooo.com/netDb/",
"https://netdb.i2p2.no/", // Only SU3 (v3) support, SNI required
"https://us.reseed.i2p2.no:444/",
"https://uk.reseed.i2p2.no:444/",
"https://reseed.i2p.vzaws.com:8443/", // Only SU3 (v3) support
"https://user.mx24.eu/", // Only HTTPS and SU3 (v3) support
"https://ieb9oopo.mooo.com/" // Only HTTPS and SU3 (v3) support
};
Reseeder::Reseeder()
{
}
Reseeder::~Reseeder()
{
}
int Reseeder::ReseedNowSU3 ()
{
auto ind = rand () % httpsReseedHostList.size ();
std::string& reseedHost = httpsReseedHostList[ind];
return ReseedFromSU3 (reseedHost, true);
}
int Reseeder::ReseedFromSU3 (const std::string& host, bool https)
{
std::string url = host + "i2pseeds.su3";
LogPrint (eLogInfo, "Dowloading SU3 from ", host);
std::string su3 = https ? HttpsRequest (url) : i2p::util::http::httpRequest (url);
if (su3.length () > 0)
{
std::stringstream s(su3);
return ProcessSU3Stream (s);
}
else
{
LogPrint (eLogWarning, "SU3 download failed");
return 0;
}
}
int Reseeder::ProcessSU3File (const char * filename)
{
std::ifstream s(filename, std::ifstream::binary);
if (s.is_open ())
return ProcessSU3Stream (s);
else
{
LogPrint (eLogError, "Can't open file ", filename);
return 0;
}
}
const char SU3_MAGIC_NUMBER[]="I2Psu3";
const uint32_t ZIP_HEADER_SIGNATURE = 0x04034B50;
const uint32_t ZIP_CENTRAL_DIRECTORY_HEADER_SIGNATURE = 0x02014B50;
const uint16_t ZIP_BIT_FLAG_DATA_DESCRIPTOR = 0x0008;
int Reseeder::ProcessSU3Stream (std::istream& s)
{
char magicNumber[7];
s.read (magicNumber, 7); // magic number and zero byte 6
if (strcmp (magicNumber, SU3_MAGIC_NUMBER))
{
LogPrint (eLogError, "Unexpected SU3 magic number");
return 0;
}
s.seekg (1, std::ios::cur); // su3 file format version
SigningKeyType signatureType;
s.read ((char *)&signatureType, 2); // signature type
signatureType = be16toh (signatureType);
uint16_t signatureLength;
s.read ((char *)&signatureLength, 2); // signature length
signatureLength = be16toh (signatureLength);
s.seekg (1, std::ios::cur); // unused
uint8_t versionLength;
s.read ((char *)&versionLength, 1); // version length
s.seekg (1, std::ios::cur); // unused
uint8_t signerIDLength;
s.read ((char *)&signerIDLength, 1); // signer ID length
uint64_t contentLength;
s.read ((char *)&contentLength, 8); // content length
contentLength = be64toh (contentLength);
s.seekg (1, std::ios::cur); // unused
uint8_t fileType;
s.read ((char *)&fileType, 1); // file type
if (fileType != 0x00) // zip file
{
LogPrint (eLogError, "Can't handle file type ", (int)fileType);
return 0;
}
s.seekg (1, std::ios::cur); // unused
uint8_t contentType;
s.read ((char *)&contentType, 1); // content type
if (contentType != 0x03) // reseed data
{
LogPrint (eLogError, "Unexpected content type ", (int)contentType);
return 0;
}
s.seekg (12, std::ios::cur); // unused
s.seekg (versionLength, std::ios::cur); // skip version
char signerID[256];
s.read (signerID, signerIDLength); // signerID
signerID[signerIDLength] = 0;
//try to verify signature
auto it = m_SigningKeys.find (signerID);
if (it != m_SigningKeys.end ())
{
// TODO: implement all signature types
if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096)
{
size_t pos = s.tellg ();
size_t tbsLen = pos + contentLength;
uint8_t * tbs = new uint8_t[tbsLen];
s.seekg (0, std::ios::beg);
s.read ((char *)tbs, tbsLen);
uint8_t * signature = new uint8_t[signatureLength];
s.read ((char *)signature, signatureLength);
// RSA-raw
{
// calculate digest
uint8_t digest[64];
SHA512 (tbs, tbsLen, digest);
// encrypt signature
BN_CTX * bnctx = BN_CTX_new ();
BIGNUM * s = BN_new (), * n = BN_new ();
BN_bin2bn (signature, signatureLength, s);
BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n);
BN_mod_exp (s, s, i2p::crypto::rsae, n, bnctx); // s = s^e mod n
uint8_t * enSigBuf = new uint8_t[signatureLength];
i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
// digest is right aligned
// we can't use RSA_verify due wrong padding in SU3
if (memcmp (enSigBuf + (signatureLength - 64), digest, 64))
LogPrint (eLogWarning, "SU3 signature verification failed");
delete[] enSigBuf;
BN_free (s); BN_free (n);
BN_CTX_free (bnctx);
}
delete[] signature;
delete[] tbs;
s.seekg (pos, std::ios::beg);
}
else
LogPrint (eLogWarning, "Signature type ", signatureType, " is not supported");
}
else
LogPrint (eLogWarning, "Certificate for ", signerID, " not loaded");
// handle content
int numFiles = 0;
size_t contentPos = s.tellg ();
while (!s.eof ())
{
uint32_t signature;
s.read ((char *)&signature, 4);
signature = le32toh (signature);
if (signature == ZIP_HEADER_SIGNATURE)
{
// next local file
s.seekg (2, std::ios::cur); // version
uint16_t bitFlag;
s.read ((char *)&bitFlag, 2);
bitFlag = le16toh (bitFlag);
uint16_t compressionMethod;
s.read ((char *)&compressionMethod, 2);
compressionMethod = le16toh (compressionMethod);
s.seekg (4, std::ios::cur); // skip fields we don't care about
uint32_t compressedSize, uncompressedSize;
uint32_t crc_32;
s.read ((char *)&crc_32, 4);
crc_32 = le32toh (crc_32);
s.read ((char *)&compressedSize, 4);
compressedSize = le32toh (compressedSize);
s.read ((char *)&uncompressedSize, 4);
uncompressedSize = le32toh (uncompressedSize);
uint16_t fileNameLength, extraFieldLength;
s.read ((char *)&fileNameLength, 2);
fileNameLength = le16toh (fileNameLength);
s.read ((char *)&extraFieldLength, 2);
extraFieldLength = le16toh (extraFieldLength);
char localFileName[255];
s.read (localFileName, fileNameLength);
localFileName[fileNameLength] = 0;
s.seekg (extraFieldLength, std::ios::cur);
// take care about data desriptor if presented
if (bitFlag & ZIP_BIT_FLAG_DATA_DESCRIPTOR)
{
size_t pos = s.tellg ();
if (!FindZipDataDescriptor (s))
{
LogPrint (eLogError, "SU3 archive data descriptor not found");
return numFiles;
}
s.read ((char *)&crc_32, 4);
crc_32 = le32toh (crc_32);
s.read ((char *)&compressedSize, 4);
compressedSize = le32toh (compressedSize) + 4; // ??? we must consider signature as part of compressed data
s.read ((char *)&uncompressedSize, 4);
uncompressedSize = le32toh (uncompressedSize);
// now we know compressed and uncompressed size
s.seekg (pos, std::ios::beg); // back to compressed data
}
LogPrint (eLogDebug, "Proccessing file ", localFileName, " ", compressedSize, " bytes");
if (!compressedSize)
{
LogPrint (eLogWarning, "Unexpected size 0. Skipped");
continue;
}
uint8_t * compressed = new uint8_t[compressedSize];
s.read ((char *)compressed, compressedSize);
if (compressionMethod) // we assume Deflate
{
z_stream inflator;
memset (&inflator, 0, sizeof (inflator));
inflateInit2 (&inflator, -MAX_WBITS); // no zlib header
uint8_t * uncompressed = new uint8_t[uncompressedSize];
inflator.next_in = compressed;
inflator.avail_in = compressedSize;
inflator.next_out = uncompressed;
inflator.avail_out = uncompressedSize;
int err;
if ((err = inflate (&inflator, Z_SYNC_FLUSH)) >= 0)
{
uncompressedSize -= inflator.avail_out;
if (crc32 (0, uncompressed, uncompressedSize) == crc_32)
{
i2p::data::netdb.AddRouterInfo (uncompressed, uncompressedSize);
numFiles++;
}
else
LogPrint (eLogError, "CRC32 verification failed");
}
else
LogPrint (eLogError, "decompression error ", err);
delete[] uncompressed;
inflateEnd (&inflator);
}
else // no compression
{
i2p::data::netdb.AddRouterInfo (compressed, compressedSize);
numFiles++;
}
delete[] compressed;
if (bitFlag & ZIP_BIT_FLAG_DATA_DESCRIPTOR)
s.seekg (12, std::ios::cur); // skip data descriptor section if presented (12 = 16 - 4)
}
else
{
if (signature != ZIP_CENTRAL_DIRECTORY_HEADER_SIGNATURE)
LogPrint (eLogWarning, "Missing zip central directory header");
break; // no more files
}
size_t end = s.tellg ();
if (end - contentPos >= contentLength)
break; // we are beyond contentLength
}
return numFiles;
}
const uint8_t ZIP_DATA_DESCRIPTOR_SIGNATURE[] = { 0x50, 0x4B, 0x07, 0x08 };
bool Reseeder::FindZipDataDescriptor (std::istream& s)
{
size_t nextInd = 0;
while (!s.eof ())
{
uint8_t nextByte;
s.read ((char *)&nextByte, 1);
if (nextByte == ZIP_DATA_DESCRIPTOR_SIGNATURE[nextInd])
{
nextInd++;
if (nextInd >= sizeof (ZIP_DATA_DESCRIPTOR_SIGNATURE))
return true;
}
else
nextInd = 0;
}
return false;
}
void Reseeder::LoadCertificate (const std::string& filename)
{
SSL_CTX * ctx = SSL_CTX_new (TLSv1_method ());
int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
if (ret)
{
SSL * ssl = SSL_new (ctx);
X509 * cert = SSL_get_certificate (ssl);
// verify
if (cert)
{
// extract issuer name
char name[100];
X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
// extract RSA key (we need n only, e = 65537)
RSA * key = X509_get_pubkey (cert)->pkey.rsa;
PublicKey value;
i2p::crypto::bn2buf (key->n, value, 512);
m_SigningKeys[name] = value;
}
SSL_free (ssl);
}
else
LogPrint (eLogError, "Can't open certificate file ", filename);
SSL_CTX_free (ctx);
}
void Reseeder::LoadCertificates ()
{
boost::filesystem::path reseedDir = i2p::util::filesystem::GetCertificatesDir() / "reseed";
if (!boost::filesystem::exists (reseedDir))
{
LogPrint (eLogWarning, "Reseed certificates not loaded. ", reseedDir, " doesn't exist");
return;
}
int numCertificates = 0;
boost::filesystem::directory_iterator end; // empty
for (boost::filesystem::directory_iterator it (reseedDir); it != end; ++it)
{
if (boost::filesystem::is_regular_file (it->status()) && it->path ().extension () == ".crt")
{
LoadCertificate (it->path ().string ());
numCertificates++;
}
}
LogPrint (eLogInfo, numCertificates, " certificates loaded");
}
std::string Reseeder::HttpsRequest (const std::string& address)
{
i2p::util::http::url u(address);
if (u.port_ == 80) u.port_ = 443;
boost::asio::io_service service;
boost::system::error_code ecode;
auto it = boost::asio::ip::tcp::resolver(service).resolve (
boost::asio::ip::tcp::resolver::query (u.host_, std::to_string (u.port_)), ecode);
if (!ecode)
{
boost::asio::ssl::context ctx(service, boost::asio::ssl::context::sslv23);
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);
s.lowest_layer().connect (*it, ecode);
if (!ecode)
{
s.handshake (boost::asio::ssl::stream_base::client, ecode);
if (!ecode)
{
LogPrint (eLogInfo, "Connected to ", u.host_, ":", u.port_);
// send request
std::stringstream ss;
ss << "GET " << u.path_ << " HTTP/1.1\r\nHost: " << u.host_
<< "\r\nAccept: */*\r\n" << "User-Agent: Wget/1.11.4\r\n" << "Connection: close\r\n\r\n";
s.write_some (boost::asio::buffer (ss.str ()));
// read response
std::stringstream rs;
char response[1024]; size_t l = 0;
do
{
l = s.read_some (boost::asio::buffer (response, 1024), ecode);
if (l) rs.write (response, l);
}
while (!ecode && l);
// process response
return i2p::util::http::GetHttpContent (rs);
}
else
LogPrint (eLogError, "SSL handshake failed: ", ecode.message ());
}
else
LogPrint (eLogError, "Couldn't connect to ", u.host_, ": ", ecode.message ());
}
else
LogPrint (eLogError, "Couldn't resolve address ", u.host_, ": ", ecode.message ());
return "";
}
}
}

View File

@ -1,350 +0,0 @@
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "Crypto.h"
#include "Timestamp.h"
#include "I2NPProtocol.h"
#include "NetDb.h"
#include "util.h"
#include "version.h"
#include "Log.h"
#include "RouterContext.h"
namespace i2p
{
RouterContext context;
RouterContext::RouterContext ():
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
m_StartupTime (0), m_Status (eRouterStatusOK )
{
}
void RouterContext::Init ()
{
srand (i2p::util::GetMillisecondsSinceEpoch () % 1000);
m_StartupTime = i2p::util::GetSecondsSinceEpoch ();
if (!Load ())
CreateNewRouter ();
UpdateRouterInfo ();
}
void RouterContext::CreateNewRouter ()
{
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
#else
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_DSA_SHA1);
#endif
SaveKeys ();
NewRouterInfo ();
}
void RouterContext::NewRouterInfo ()
{
i2p::data::RouterInfo routerInfo;
routerInfo.SetRouterIdentity (GetIdentity ());
int port = i2p::util::config::GetArg("-port", 0);
if (!port)
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
routerInfo.AddSSUAddress (i2p::util::config::GetCharArg("-host", "127.0.0.1"), port, routerInfo.GetIdentHash ());
routerInfo.AddNTCPAddress (i2p::util::config::GetCharArg("-host", "127.0.0.1"), port);
routerInfo.SetCaps (i2p::data::RouterInfo::eReachable |
i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC
routerInfo.SetProperty ("coreVersion", I2P_VERSION);
routerInfo.SetProperty ("netId", "2");
routerInfo.SetProperty ("router.version", I2P_VERSION);
routerInfo.SetProperty ("stat_uptime", "90m");
routerInfo.CreateBuffer (m_Keys);
m_RouterInfo.SetRouterIdentity (GetIdentity ());
m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ());
}
void RouterContext::UpdateRouterInfo ()
{
m_RouterInfo.CreateBuffer (m_Keys);
m_RouterInfo.SaveToFile (i2p::util::filesystem::GetFullPath (ROUTER_INFO));
m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch ();
}
void RouterContext::SetStatus (RouterStatus status)
{
if (status != m_Status)
{
m_Status = status;
switch (m_Status)
{
case eRouterStatusOK:
SetReachable ();
break;
case eRouterStatusFirewalled:
SetUnreachable ();
break;
default:
;
}
}
}
void RouterContext::UpdatePort (int port)
{
bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ())
{
if (address.port != port)
{
address.port = port;
updated = true;
}
}
if (updated)
UpdateRouterInfo ();
}
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
{
bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ())
{
if (address.host != host && address.IsCompatible (host))
{
address.host = host;
updated = true;
}
}
auto ts = i2p::util::GetSecondsSinceEpoch ();
if (updated || ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL)
UpdateRouterInfo ();
}
bool RouterContext::AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer)
{
bool ret = m_RouterInfo.AddIntroducer (introducer);
if (ret)
UpdateRouterInfo ();
return ret;
}
void RouterContext::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
{
if (m_RouterInfo.RemoveIntroducer (e))
UpdateRouterInfo ();
}
void RouterContext::SetFloodfill (bool floodfill)
{
m_IsFloodfill = floodfill;
if (floodfill)
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eFloodfill);
else
{
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eFloodfill);
// we don't publish number of routers and leaseset for non-floodfill
m_RouterInfo.DeleteProperty (ROUTER_INFO_PROPERTY_LEASESETS);
m_RouterInfo.DeleteProperty (ROUTER_INFO_PROPERTY_ROUTERS);
}
UpdateRouterInfo ();
}
void RouterContext::SetHighBandwidth ()
{
if (!m_RouterInfo.IsHighBandwidth ())
{
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eHighBandwidth);
UpdateRouterInfo ();
}
}
void RouterContext::SetLowBandwidth ()
{
if (m_RouterInfo.IsHighBandwidth ())
{
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eHighBandwidth);
UpdateRouterInfo ();
}
}
bool RouterContext::IsUnreachable () const
{
return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable;
}
void RouterContext::SetUnreachable ()
{
// set caps
m_RouterInfo.SetCaps (i2p::data::RouterInfo::eUnreachable | i2p::data::RouterInfo::eSSUTesting); // LU, B
// remove NTCP address
auto& addresses = m_RouterInfo.GetAddresses ();
for (size_t i = 0; i < addresses.size (); i++)
{
if (addresses[i].transportStyle == i2p::data::RouterInfo::eTransportNTCP)
{
addresses.erase (addresses.begin () + i);
break;
}
}
// delete previous introducers
for (auto& addr : addresses)
addr.introducers.clear ();
// update
UpdateRouterInfo ();
}
void RouterContext::SetReachable ()
{
// update caps
uint8_t caps = m_RouterInfo.GetCaps ();
caps &= ~i2p::data::RouterInfo::eUnreachable;
caps |= i2p::data::RouterInfo::eReachable;
caps |= i2p::data::RouterInfo::eSSUIntroducer;
if (m_IsFloodfill)
caps |= i2p::data::RouterInfo::eFloodfill;
m_RouterInfo.SetCaps (caps);
// insert NTCP back
auto& addresses = m_RouterInfo.GetAddresses ();
for (size_t i = 0; i < addresses.size (); i++)
{
if (addresses[i].transportStyle == i2p::data::RouterInfo::eTransportSSU)
{
// insert NTCP address with host/port from SSU
m_RouterInfo.AddNTCPAddress (addresses[i].host.to_string ().c_str (), addresses[i].port);
break;
}
}
// delete previous introducers
for (auto& addr : addresses)
addr.introducers.clear ();
// update
UpdateRouterInfo ();
}
void RouterContext::SetSupportsV6 (bool supportsV6)
{
if (supportsV6)
m_RouterInfo.EnableV6 ();
else
m_RouterInfo.DisableV6 ();
UpdateRouterInfo ();
}
void RouterContext::UpdateNTCPV6Address (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.host.is_v6 () && addr.transportStyle == i2p::data::RouterInfo::eTransportNTCP)
{
if (addr.host != host)
{
addr.host = host;
updated = true;
}
found = true;
}
else
port = addr.port;
}
if (!found)
{
// create new address
m_RouterInfo.AddNTCPAddress (host.to_string ().c_str (), port);
auto mtu = i2p::util::net::GetMTU (host);
if (mtu)
{
LogPrint ("Our v6 MTU=", mtu);
if (mtu > 1472) mtu = 1472;
}
m_RouterInfo.AddSSUAddress (host.to_string ().c_str (), port, GetIdentHash (), mtu ? mtu : 1472); // TODO
updated = true;
}
if (updated)
UpdateRouterInfo ();
}
void RouterContext::UpdateStats ()
{
if (m_IsFloodfill)
{
// update routers and leasesets
m_RouterInfo.SetProperty (ROUTER_INFO_PROPERTY_LEASESETS, boost::lexical_cast<std::string>(i2p::data::netdb.GetNumLeaseSets ()));
m_RouterInfo.SetProperty (ROUTER_INFO_PROPERTY_ROUTERS, boost::lexical_cast<std::string>(i2p::data::netdb.GetNumRouters ()));
UpdateRouterInfo ();
}
}
bool RouterContext::Load ()
{
std::ifstream fk (i2p::util::filesystem::GetFullPath (ROUTER_KEYS).c_str (), std::ifstream::binary | std::ofstream::in);
if (!fk.is_open ()) return false;
fk.seekg (0, std::ios::end);
size_t len = fk.tellg();
fk.seekg (0, std::ios::beg);
if (len == sizeof (i2p::data::Keys)) // old keys file format
{
i2p::data::Keys keys;
fk.read ((char *)&keys, sizeof (keys));
m_Keys = keys;
}
else // new keys file format
{
uint8_t * buf = new uint8_t[len];
fk.read ((char *)buf, len);
m_Keys.FromBuffer (buf, len);
delete[] buf;
}
i2p::data::RouterInfo routerInfo(i2p::util::filesystem::GetFullPath (ROUTER_INFO)); // TODO
m_RouterInfo.SetRouterIdentity (GetIdentity ());
m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ());
m_RouterInfo.SetProperty ("coreVersion", I2P_VERSION);
m_RouterInfo.SetProperty ("router.version", I2P_VERSION);
if (IsUnreachable ())
SetReachable (); // we assume reachable until we discover firewall through peer tests
return true;
}
void RouterContext::SaveKeys ()
{
// save in the same format as .dat files
std::ofstream fk (i2p::util::filesystem::GetFullPath (ROUTER_KEYS).c_str (), std::ofstream::binary | std::ofstream::out);
size_t len = m_Keys.GetFullLen ();
uint8_t * buf = new uint8_t[len];
m_Keys.ToBuffer (buf, len);
fk.write ((char *)buf, len);
delete[] buf;
}
std::shared_ptr<i2p::tunnel::TunnelPool> RouterContext::GetTunnelPool () const
{
return i2p::tunnel::tunnels.GetExploratoryPool ();
}
void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
{
i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from));
}
void RouterContext::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{
std::unique_lock<std::mutex> l(m_GarlicMutex);
i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg);
}
void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
{
std::unique_lock<std::mutex> l(m_GarlicMutex);
i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg);
}
uint32_t RouterContext::GetUptime () const
{
return i2p::util::GetSecondsSinceEpoch () - m_StartupTime;
}
}

View File

@ -1,103 +0,0 @@
#ifndef ROUTER_CONTEXT_H__
#define ROUTER_CONTEXT_H__
#include <inttypes.h>
#include <string>
#include <memory>
#include <mutex>
#include <boost/asio.hpp>
#include "Identity.h"
#include "RouterInfo.h"
#include "Garlic.h"
namespace i2p
{
const char ROUTER_INFO[] = "router.info";
const char ROUTER_KEYS[] = "router.keys";
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
enum RouterStatus
{
eRouterStatusOK = 0,
eRouterStatusTesting = 1,
eRouterStatusFirewalled = 2
};
class RouterContext: public i2p::garlic::GarlicDestination
{
public:
RouterContext ();
void Init ();
i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; };
std::shared_ptr<const i2p::data::RouterInfo> GetSharedRouterInfo () const
{
return std::shared_ptr<const i2p::data::RouterInfo> (&m_RouterInfo,
[](const i2p::data::RouterInfo *) {});
}
uint32_t GetUptime () const;
uint32_t GetStartupTime () const { return m_StartupTime; };
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
RouterStatus GetStatus () const { return m_Status; };
void SetStatus (RouterStatus status);
void UpdatePort (int port); // called from Daemon
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
bool IsUnreachable () const;
void SetUnreachable ();
void SetReachable ();
bool IsFloodfill () const { return m_IsFloodfill; };
void SetFloodfill (bool floodfill);
void SetHighBandwidth ();
void SetLowBandwidth ();
bool AcceptsTunnels () const { return m_AcceptsTunnels; };
void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; };
bool SupportsV6 () const { return m_RouterInfo.IsV6 (); };
void SetSupportsV6 (bool supportsV6);
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
void UpdateStats ();
// implements LocalDestination
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
const uint8_t * GetEncryptionPrivateKey () const { return m_Keys.GetPrivateKey (); };
const uint8_t * GetEncryptionPublicKey () const { return GetIdentity ()->GetStandardIdentity ().publicKey; };
void SetLeaseSetUpdated () {};
// implements GarlicDestination
std::shared_ptr<const i2p::data::LeaseSet> GetLeaseSet () { return nullptr; };
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const;
void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from);
// override GarlicDestination
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
private:
void CreateNewRouter ();
void NewRouterInfo ();
void UpdateRouterInfo ();
bool Load ();
void SaveKeys ();
private:
i2p::data::RouterInfo m_RouterInfo;
i2p::data::PrivateKeys m_Keys;
uint64_t m_LastUpdateTime;
bool m_AcceptsTunnels, m_IsFloodfill;
uint64_t m_StartupTime; // in seconds since epoch
RouterStatus m_Status;
std::mutex m_GarlicMutex;
};
extern RouterContext context;
}
#endif

View File

@ -1,679 +0,0 @@
#include <stdio.h>
#include <string.h>
#include "I2PEndian.h"
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "Crypto.h"
#include "Base.h"
#include "Timestamp.h"
#include "Log.h"
#include "RouterInfo.h"
namespace i2p
{
namespace data
{
RouterInfo::RouterInfo (const std::string& fullPath):
m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false),
m_SupportedTransports (0), m_Caps (0)
{
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
ReadFromFile ();
}
RouterInfo::RouterInfo (const uint8_t * buf, int len):
m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
{
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
memcpy (m_Buffer, buf, len);
m_BufferLen = len;
ReadFromBuffer (true);
}
RouterInfo::~RouterInfo ()
{
delete[] m_Buffer;
}
void RouterInfo::Update (const uint8_t * buf, int len)
{
// verify signature since we have indentity already
int l = len - m_RouterIdentity->GetSignatureLen ();
if (m_RouterIdentity->Verify (buf, l, buf + l))
{
// clean up
m_IsUpdated = true;
m_IsUnreachable = false;
m_SupportedTransports = 0;
m_Caps = 0;
m_Addresses.clear ();
m_Properties.clear ();
// copy buffer
if (!m_Buffer)
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
memcpy (m_Buffer, buf, len);
m_BufferLen = len;
// skip identity
size_t identityLen = m_RouterIdentity->GetFullLen ();
// read new RI
std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen));
ReadFromStream (str);
// don't delete buffer until saved to the file
}
else
{
LogPrint (eLogError, "RouterInfo signature verification failed");
m_IsUnreachable = true;
}
m_RouterIdentity->DropVerifier ();
}
void RouterInfo::SetRouterIdentity (std::shared_ptr<const IdentityEx> identity)
{
m_RouterIdentity = identity;
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
}
bool RouterInfo::LoadFile ()
{
std::ifstream s(m_FullPath.c_str (), std::ifstream::binary);
if (s.is_open ())
{
s.seekg (0,std::ios::end);
m_BufferLen = s.tellg ();
if (m_BufferLen < 40)
{
LogPrint(eLogError, "File", m_FullPath, " is malformed");
return false;
}
s.seekg(0, std::ios::beg);
if (!m_Buffer)
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
s.read((char *)m_Buffer, m_BufferLen);
}
else
{
LogPrint (eLogError, "Can't open file ", m_FullPath);
return false;
}
return true;
}
void RouterInfo::ReadFromFile ()
{
if (LoadFile ())
ReadFromBuffer (false);
}
void RouterInfo::ReadFromBuffer (bool verifySignature)
{
m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
size_t identityLen = m_RouterIdentity->GetFullLen ();
std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen));
ReadFromStream (str);
if (verifySignature)
{
// verify signature
int l = m_BufferLen - m_RouterIdentity->GetSignatureLen ();
if (!m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
{
LogPrint (eLogError, "RouterInfo signature verification failed");
m_IsUnreachable = true;
}
m_RouterIdentity->DropVerifier ();
}
}
void RouterInfo::ReadFromStream (std::istream& s)
{
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
m_Timestamp = be64toh (m_Timestamp);
// read addresses
uint8_t numAddresses;
s.read ((char *)&numAddresses, sizeof (numAddresses));
bool introducers = false;
for (int i = 0; i < numAddresses; i++)
{
bool isValidAddress = true;
Address address;
s.read ((char *)&address.cost, sizeof (address.cost));
s.read ((char *)&address.date, sizeof (address.date));
char transportStyle[5];
ReadString (transportStyle, s);
if (!strcmp (transportStyle, "NTCP"))
address.transportStyle = eTransportNTCP;
else if (!strcmp (transportStyle, "SSU"))
address.transportStyle = eTransportSSU;
else
address.transportStyle = eTransportUnknown;
address.port = 0;
address.mtu = 0;
uint16_t size, r = 0;
s.read ((char *)&size, sizeof (size));
size = be16toh (size);
while (r < size)
{
char key[500], value[500];
r += ReadString (key, s);
s.seekg (1, std::ios_base::cur); r++; // =
r += ReadString (value, s);
s.seekg (1, std::ios_base::cur); r++; // ;
if (!strcmp (key, "host"))
{
boost::system::error_code ecode;
address.host = boost::asio::ip::address::from_string (value, ecode);
if (ecode)
{
if (address.transportStyle == eTransportNTCP)
{
m_SupportedTransports |= eNTCPV4; // TODO:
address.addressString = value;
}
else
{
// TODO: resolve address for SSU
LogPrint (eLogWarning, "Unexpected SSU address ", value);
isValidAddress = false;
}
}
else
{
// add supported protocol
if (address.host.is_v4 ())
m_SupportedTransports |= (address.transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4;
else
m_SupportedTransports |= (address.transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6;
}
}
else if (!strcmp (key, "port"))
address.port = boost::lexical_cast<int>(value);
else if (!strcmp (key, "mtu"))
address.mtu = boost::lexical_cast<int>(value);
else if (!strcmp (key, "key"))
Base64ToByteStream (value, strlen (value), address.key, 32);
else if (!strcmp (key, "caps"))
ExtractCaps (value);
else if (key[0] == 'i')
{
// introducers
introducers = true;
size_t l = strlen(key);
unsigned char index = key[l-1] - '0'; // TODO:
key[l-1] = 0;
if (index >= address.introducers.size ())
address.introducers.resize (index + 1);
Introducer& introducer = address.introducers.at (index);
if (!strcmp (key, "ihost"))
{
boost::system::error_code ecode;
introducer.iHost = boost::asio::ip::address::from_string (value, ecode);
}
else if (!strcmp (key, "iport"))
introducer.iPort = boost::lexical_cast<int>(value);
else if (!strcmp (key, "itag"))
introducer.iTag = boost::lexical_cast<uint32_t>(value);
else if (!strcmp (key, "ikey"))
Base64ToByteStream (value, strlen (value), introducer.iKey, 32);
}
}
if (isValidAddress)
m_Addresses.push_back(address);
}
// read peers
uint8_t numPeers;
s.read ((char *)&numPeers, sizeof (numPeers));
s.seekg (numPeers*32, std::ios_base::cur); // TODO: read peers
// read properties
uint16_t size, r = 0;
s.read ((char *)&size, sizeof (size));
size = be16toh (size);
while (r < size)
{
#ifdef _WIN32
char key[500], value[500];
// TODO: investigate why properties get read as one long string under Windows
// length should not be more than 44
#else
char key[50], value[50];
#endif
r += ReadString (key, s);
s.seekg (1, std::ios_base::cur); r++; // =
r += ReadString (value, s);
s.seekg (1, std::ios_base::cur); r++; // ;
m_Properties[key] = value;
// extract caps
if (!strcmp (key, "caps"))
ExtractCaps (value);
}
if (!m_SupportedTransports || !m_Addresses.size() || (UsesIntroducer () && !introducers))
SetUnreachable (true);
}
void RouterInfo::ExtractCaps (const char * value)
{
const char * cap = value;
while (*cap)
{
switch (*cap)
{
case CAPS_FLAG_FLOODFILL:
m_Caps |= Caps::eFloodfill;
break;
case CAPS_FLAG_HIGH_BANDWIDTH1:
case CAPS_FLAG_HIGH_BANDWIDTH2:
case CAPS_FLAG_HIGH_BANDWIDTH3:
m_Caps |= Caps::eHighBandwidth;
break;
case CAPS_FLAG_HIDDEN:
m_Caps |= Caps::eHidden;
break;
case CAPS_FLAG_REACHABLE:
m_Caps |= Caps::eReachable;
break;
case CAPS_FLAG_UNREACHABLE:
m_Caps |= Caps::eUnreachable;
break;
case CAPS_FLAG_SSU_TESTING:
m_Caps |= Caps::eSSUTesting;
break;
case CAPS_FLAG_SSU_INTRODUCER:
m_Caps |= Caps::eSSUIntroducer;
break;
default: ;
}
cap++;
}
}
void RouterInfo::UpdateCapsProperty ()
{
std::string caps;
if (m_Caps & eFloodfill)
{
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // highest bandwidth
caps += CAPS_FLAG_FLOODFILL; // floodfill
}
else
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 : CAPS_FLAG_LOW_BANDWIDTH2; // bandwidth
if (m_Caps & eHidden) caps += CAPS_FLAG_HIDDEN; // hidden
if (m_Caps & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable
if (m_Caps & eUnreachable) caps += CAPS_FLAG_UNREACHABLE; // unreachable
SetProperty ("caps", caps.c_str ());
}
void RouterInfo::WriteToStream (std::ostream& s)
{
uint64_t ts = htobe64 (m_Timestamp);
s.write ((char *)&ts, sizeof (ts));
// addresses
uint8_t numAddresses = m_Addresses.size ();
s.write ((char *)&numAddresses, sizeof (numAddresses));
for (auto& address : m_Addresses)
{
s.write ((char *)&address.cost, sizeof (address.cost));
s.write ((char *)&address.date, sizeof (address.date));
std::stringstream properties;
if (address.transportStyle == eTransportNTCP)
WriteString ("NTCP", s);
else if (address.transportStyle == eTransportSSU)
{
WriteString ("SSU", s);
// caps
WriteString ("caps", properties);
properties << '=';
std::string caps;
if (IsPeerTesting ()) caps += CAPS_FLAG_SSU_TESTING;
if (IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
WriteString (caps, properties);
properties << ';';
}
else
WriteString ("", s);
WriteString ("host", properties);
properties << '=';
WriteString (address.host.to_string (), properties);
properties << ';';
if (address.transportStyle == eTransportSSU)
{
// write introducers if any
if (address.introducers.size () > 0)
{
int i = 0;
for (auto introducer: address.introducers)
{
WriteString ("ihost" + boost::lexical_cast<std::string>(i), properties);
properties << '=';
WriteString (introducer.iHost.to_string (), properties);
properties << ';';
i++;
}
i = 0;
for (auto introducer: address.introducers)
{
WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
properties << '=';
char value[64];
size_t l = ByteStreamToBase64 (introducer.iKey, 32, value, 64);
value[l] = 0;
WriteString (value, properties);
properties << ';';
i++;
}
i = 0;
for (auto introducer: address.introducers)
{
WriteString ("iport" + boost::lexical_cast<std::string>(i), properties);
properties << '=';
WriteString (boost::lexical_cast<std::string>(introducer.iPort), properties);
properties << ';';
i++;
}
i = 0;
for (auto introducer: address.introducers)
{
WriteString ("itag" + boost::lexical_cast<std::string>(i), properties);
properties << '=';
WriteString (boost::lexical_cast<std::string>(introducer.iTag), properties);
properties << ';';
i++;
}
}
// write intro key
WriteString ("key", properties);
properties << '=';
char value[64];
size_t l = ByteStreamToBase64 (address.key, 32, value, 64);
value[l] = 0;
WriteString (value, properties);
properties << ';';
// write mtu
if (address.mtu)
{
WriteString ("mtu", properties);
properties << '=';
WriteString (boost::lexical_cast<std::string>(address.mtu), properties);
properties << ';';
}
}
WriteString ("port", properties);
properties << '=';
WriteString (boost::lexical_cast<std::string>(address.port), properties);
properties << ';';
uint16_t size = htobe16 (properties.str ().size ());
s.write ((char *)&size, sizeof (size));
s.write (properties.str ().c_str (), properties.str ().size ());
}
// peers
uint8_t numPeers = 0;
s.write ((char *)&numPeers, sizeof (numPeers));
// properties
std::stringstream properties;
for (auto& p : m_Properties)
{
WriteString (p.first, properties);
properties << '=';
WriteString (p.second, properties);
properties << ';';
}
uint16_t size = htobe16 (properties.str ().size ());
s.write ((char *)&size, sizeof (size));
s.write (properties.str ().c_str (), properties.str ().size ());
}
const uint8_t * RouterInfo::LoadBuffer ()
{
if (!m_Buffer)
{
if (LoadFile ())
LogPrint ("Buffer for ", GetIdentHashAbbreviation (GetIdentHash ()), " loaded from file");
}
return m_Buffer;
}
void RouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
{
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); // refresh timstamp
std::stringstream s;
uint8_t ident[1024];
auto identLen = privateKeys.GetPublic ()->ToBuffer (ident, 1024);
s.write ((char *)ident, identLen);
WriteToStream (s);
m_BufferLen = s.str ().size ();
if (!m_Buffer)
m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
memcpy (m_Buffer, s.str ().c_str (), m_BufferLen);
// signature
privateKeys.Sign ((uint8_t *)m_Buffer, m_BufferLen, (uint8_t *)m_Buffer + m_BufferLen);
m_BufferLen += privateKeys.GetPublic ()->GetSignatureLen ();
}
void RouterInfo::SaveToFile (const std::string& fullPath)
{
m_FullPath = fullPath;
if (m_Buffer)
{
std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out);
if (f.is_open ())
f.write ((char *)m_Buffer, m_BufferLen);
else
LogPrint(eLogError, "Can't save RouterInfo to ", fullPath);
}
else
LogPrint (eLogError, "Can't save RouterInfo m_Buffer==NULL");
}
size_t RouterInfo::ReadString (char * str, std::istream& s)
{
uint8_t len;
s.read ((char *)&len, 1);
s.read (str, len);
str[len] = 0;
return len+1;
}
void RouterInfo::WriteString (const std::string& str, std::ostream& s)
{
uint8_t len = str.size ();
s.write ((char *)&len, 1);
s.write (str.c_str (), len);
}
void RouterInfo::AddNTCPAddress (const char * host, int port)
{
Address addr;
addr.host = boost::asio::ip::address::from_string (host);
addr.port = port;
addr.transportStyle = eTransportNTCP;
addr.cost = 2;
addr.date = 0;
addr.mtu = 0;
for (auto it: m_Addresses) // don't insert same address twice
if (it == addr) return;
m_Addresses.push_back(addr);
m_SupportedTransports |= addr.host.is_v6 () ? eNTCPV6 : eNTCPV4;
}
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
{
Address addr;
addr.host = boost::asio::ip::address::from_string (host);
addr.port = port;
addr.transportStyle = eTransportSSU;
addr.cost = 10; // NTCP should have priority over SSU
addr.date = 0;
addr.mtu = mtu;
memcpy (addr.key, key, 32);
for (auto it: m_Addresses) // don't insert same address twice
if (it == addr) return;
m_Addresses.push_back(addr);
m_SupportedTransports |= addr.host.is_v6 () ? eNTCPV6 : eSSUV4;
m_Caps |= eSSUTesting;
m_Caps |= eSSUIntroducer;
}
bool RouterInfo::AddIntroducer (const Introducer& introducer)
{
for (auto& addr : m_Addresses)
{
if (addr.transportStyle == eTransportSSU && addr.host.is_v4 ())
{
for (auto intro: addr.introducers)
if (intro.iTag == introducer.iTag) return false; // already presented
addr.introducers.push_back (introducer);
return true;
}
}
return false;
}
bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
{
for (auto& addr : m_Addresses)
{
if (addr.transportStyle == eTransportSSU && addr.host.is_v4 ())
{
for (std::vector<Introducer>::iterator it = addr.introducers.begin (); it != addr.introducers.end (); it++)
if ( boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
{
addr.introducers.erase (it);
return true;
}
}
}
return false;
}
void RouterInfo::SetCaps (uint8_t caps)
{
m_Caps = caps;
UpdateCapsProperty ();
}
void RouterInfo::SetCaps (const char * caps)
{
SetProperty ("caps", caps);
m_Caps = 0;
ExtractCaps (caps);
}
void RouterInfo::SetProperty (const std::string& key, const std::string& value)
{
m_Properties[key] = value;
}
void RouterInfo::DeleteProperty (const std::string& key)
{
m_Properties.erase (key);
}
bool RouterInfo::IsFloodfill () const
{
return m_Caps & Caps::eFloodfill;
}
bool RouterInfo::IsNTCP (bool v4only) const
{
if (v4only)
return m_SupportedTransports & eNTCPV4;
else
return m_SupportedTransports & (eNTCPV4 | eNTCPV6);
}
bool RouterInfo::IsSSU (bool v4only) const
{
if (v4only)
return m_SupportedTransports & eSSUV4;
else
return m_SupportedTransports & (eSSUV4 | eSSUV6);
}
bool RouterInfo::IsV6 () const
{
return m_SupportedTransports & (eNTCPV6 | eSSUV6);
}
void RouterInfo::EnableV6 ()
{
if (!IsV6 ())
m_SupportedTransports |= eNTCPV6 | eSSUV6;
}
void RouterInfo::DisableV6 ()
{
if (IsV6 ())
{
// NTCP
m_SupportedTransports &= ~eNTCPV6;
for (size_t i = 0; i < m_Addresses.size (); i++)
{
if (m_Addresses[i].transportStyle == i2p::data::RouterInfo::eTransportNTCP &&
m_Addresses[i].host.is_v6 ())
{
m_Addresses.erase (m_Addresses.begin () + i);
break;
}
}
// SSU
m_SupportedTransports &= ~eSSUV6;
for (size_t i = 0; i < m_Addresses.size (); i++)
{
if (m_Addresses[i].transportStyle == i2p::data::RouterInfo::eTransportSSU &&
m_Addresses[i].host.is_v6 ())
{
m_Addresses.erase (m_Addresses.begin () + i);
break;
}
}
}
}
bool RouterInfo::UsesIntroducer () const
{
return m_Caps & Caps::eUnreachable; // non-reachable
}
const RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only) const
{
return GetAddress (eTransportNTCP, v4only);
}
const RouterInfo::Address * RouterInfo::GetSSUAddress (bool v4only) const
{
return GetAddress (eTransportSSU, v4only);
}
const RouterInfo::Address * RouterInfo::GetSSUV6Address () const
{
return GetAddress (eTransportSSU, false, true);
}
const RouterInfo::Address * RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
{
for (auto& address : m_Addresses)
{
if (address.transportStyle == s)
{
if ((!v4only || address.host.is_v4 ()) && (!v6only || address.host.is_v6 ()))
return &address;
}
}
return nullptr;
}
std::shared_ptr<RouterProfile> RouterInfo::GetProfile () const
{
if (!m_Profile)
m_Profile = GetRouterProfile (GetIdentHash ());
return m_Profile;
}
}
}

873
SAM.cpp
View File

@ -1,873 +0,0 @@
#include <string.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <stdlib.h>
#endif
#include <boost/lexical_cast.hpp>
#include "Base.h"
#include "Identity.h"
#include "Log.h"
#include "Destination.h"
#include "ClientContext.h"
#include "SAM.h"
namespace i2p
{
namespace client
{
SAMSocket::SAMSocket (SAMBridge& owner):
m_Owner (owner), m_Socket (m_Owner.GetService ()), m_Timer (m_Owner.GetService ()),
m_BufferOffset (0), m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false),
m_Stream (nullptr), m_Session (nullptr)
{
}
SAMSocket::~SAMSocket ()
{
Terminate ();
}
void SAMSocket::CloseStream ()
{
if (m_Stream)
{
m_Stream->Close ();
m_Stream.reset ();
}
}
void SAMSocket::Terminate ()
{
CloseStream ();
switch (m_SocketType)
{
case eSAMSocketTypeSession:
m_Owner.CloseSession (m_ID);
break;
case eSAMSocketTypeStream:
{
if (m_Session)
m_Session->sockets.remove (shared_from_this ());
break;
}
case eSAMSocketTypeAcceptor:
{
if (m_Session)
{
m_Session->sockets.remove (shared_from_this ());
m_Session->localDestination->StopAcceptingStreams ();
}
break;
}
default:
;
}
m_SocketType = eSAMSocketTypeTerminated;
m_Socket.close ();
}
void SAMSocket::ReceiveHandshake ()
{
m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
void SAMSocket::HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("SAM handshake read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
m_Buffer[bytes_transferred] = 0;
char * eol = (char *)memchr (m_Buffer, '\n', bytes_transferred);
if (eol)
*eol = 0;
LogPrint ("SAM handshake ", m_Buffer);
char * separator = strchr (m_Buffer, ' ');
if (separator)
{
separator = strchr (separator + 1, ' ');
if (separator)
*separator = 0;
}
if (!strcmp (m_Buffer, SAM_HANDSHAKE))
{
std::string version("3.0");
// try to find MIN and MAX, 3.0 if not found
if (separator)
{
separator++;
std::map<std::string, std::string> params;
ExtractParams (separator, params);
auto it = params.find (SAM_PARAM_MAX);
// TODO: check MIN as well
if (it != params.end ())
version = it->second;
}
if (version[0] == '3') // we support v3 (3.0 and 3.1) only
{
#ifdef _MSC_VER
size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
#else
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
#endif
boost::asio::async_write (m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
else
SendMessageReply (SAM_HANDSHAKE_I2P_ERROR, strlen (SAM_HANDSHAKE_I2P_ERROR), true);
}
else
{
LogPrint ("SAM handshake mismatch");
Terminate ();
}
}
}
void SAMSocket::HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("SAM handshake reply send error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
std::bind(&SAMSocket::HandleMessage, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
}
void SAMSocket::SendMessageReply (const char * msg, size_t len, bool close)
{
if (!m_IsSilent)
boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, close));
else
{
if (close)
Terminate ();
else
Receive ();
}
}
void SAMSocket::HandleMessageReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred, bool close)
{
if (ecode)
{
LogPrint ("SAM reply send error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
if (close)
Terminate ();
else
Receive ();
}
}
void SAMSocket::HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("SAM read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else if (m_SocketType == eSAMSocketTypeStream)
HandleReceived (ecode, bytes_transferred);
else
{
bytes_transferred += m_BufferOffset;
m_BufferOffset = 0;
m_Buffer[bytes_transferred] = 0;
char * eol = (char *)memchr (m_Buffer, '\n', bytes_transferred);
if (eol)
{
*eol = 0;
char * separator = strchr (m_Buffer, ' ');
if (separator)
{
separator = strchr (separator + 1, ' ');
if (separator)
*separator = 0;
else
separator = eol;
if (!strcmp (m_Buffer, SAM_SESSION_CREATE))
ProcessSessionCreate (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
else if (!strcmp (m_Buffer, SAM_STREAM_CONNECT))
ProcessStreamConnect (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
else if (!strcmp (m_Buffer, SAM_STREAM_ACCEPT))
ProcessStreamAccept (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
else if (!strcmp (m_Buffer, SAM_DEST_GENERATE))
ProcessDestGenerate ();
else if (!strcmp (m_Buffer, SAM_NAMING_LOOKUP))
ProcessNamingLookup (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
else if (!strcmp (m_Buffer, SAM_DATAGRAM_SEND))
{
size_t len = bytes_transferred - (separator - m_Buffer) - 1;
size_t processed = ProcessDatagramSend (separator + 1, len, eol + 1);
if (processed < len)
{
m_BufferOffset = len - processed;
if (processed > 0)
memmove (m_Buffer, separator + 1 + processed, m_BufferOffset);
else
{
// restore string back
*separator = ' ';
*eol = '\n';
}
}
// since it's SAM v1 reply is not expected
Receive ();
}
else
{
LogPrint (eLogError, "SAM unexpected message ", m_Buffer);
Terminate ();
}
}
else
{
LogPrint (eLogError, "SAM malformed message ", m_Buffer);
Terminate ();
}
}
else
{
LogPrint (eLogWarning, "SAM incomplete message ", bytes_transferred);
m_BufferOffset = bytes_transferred;
// try to receive remaining message
Receive ();
}
}
}
void SAMSocket::ProcessSessionCreate (char * buf, size_t len)
{
LogPrint ("SAM session create: ", buf);
std::map<std::string, std::string> params;
ExtractParams (buf, params);
std::string& style = params[SAM_PARAM_STYLE];
std::string& id = params[SAM_PARAM_ID];
std::string& destination = params[SAM_PARAM_DESTINATION];
m_ID = id;
if (m_Owner.FindSession (id))
{
// session exists
SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), true);
return;
}
// create destination
m_Session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, &params);
if (m_Session)
{
m_SocketType = eSAMSocketTypeSession;
if (style == SAM_VALUE_DATAGRAM)
{
auto dest = m_Session->localDestination->CreateDatagramDestination ();
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
}
if (m_Session->localDestination->IsReady ())
SendSessionCreateReplyOk ();
else
{
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL));
m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer,
shared_from_this (), std::placeholders::_1));
}
}
else
SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_DEST, strlen(SAM_SESSION_CREATE_DUPLICATED_DEST), true);
}
void SAMSocket::HandleSessionReadinessCheckTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
if (m_Session->localDestination->IsReady ())
SendSessionCreateReplyOk ();
else
{
m_Timer.expires_from_now (boost::posix_time::seconds(SAM_SESSION_READINESS_CHECK_INTERVAL));
m_Timer.async_wait (std::bind (&SAMSocket::HandleSessionReadinessCheckTimer,
shared_from_this (), std::placeholders::_1));
}
}
}
void SAMSocket::SendSessionCreateReplyOk ()
{
uint8_t buf[1024];
char priv[1024];
size_t l = m_Session->localDestination->GetPrivateKeys ().ToBuffer (buf, 1024);
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, priv, 1024);
priv[l1] = 0;
#ifdef _MSC_VER
size_t l2 = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_CREATE_REPLY_OK, priv);
#else
size_t l2 = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_CREATE_REPLY_OK, priv);
#endif
SendMessageReply (m_Buffer, l2, false);
}
void SAMSocket::ProcessStreamConnect (char * buf, size_t len)
{
LogPrint (eLogDebug, "SAM stream connect: ", buf);
std::map<std::string, std::string> params;
ExtractParams (buf, params);
std::string& id = params[SAM_PARAM_ID];
std::string& destination = params[SAM_PARAM_DESTINATION];
std::string& silent = params[SAM_PARAM_SILENT];
if (silent == SAM_VALUE_TRUE) m_IsSilent = true;
m_ID = id;
m_Session = m_Owner.FindSession (id);
if (m_Session)
{
auto dest = std::make_shared<i2p::data::IdentityEx> ();
size_t len = dest->FromBase64(destination);
if (len > 0)
{
context.GetAddressBook().InsertAddress(dest);
auto leaseSet = m_Session->localDestination->FindLeaseSet(dest->GetIdentHash());
if (leaseSet)
Connect(leaseSet);
else
{
m_Session->localDestination->RequestDestination(dest->GetIdentHash(),
std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete,
shared_from_this(), std::placeholders::_1));
}
}
else
SendMessageReply(SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), true);
}
else
SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true);
}
void SAMSocket::Connect (std::shared_ptr<const i2p::data::LeaseSet> remote)
{
m_SocketType = eSAMSocketTypeStream;
m_Session->sockets.push_back (shared_from_this ());
m_Stream = m_Session->localDestination->CreateStream (remote);
m_Stream->Send ((uint8_t *)m_Buffer, 0); // connect
I2PReceive ();
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
}
void SAMSocket::HandleConnectLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet)
{
if (leaseSet)
Connect (leaseSet);
else
{
LogPrint ("SAM destination to connect not found");
SendMessageReply (SAM_STREAM_STATUS_CANT_REACH_PEER, strlen(SAM_STREAM_STATUS_CANT_REACH_PEER), true);
}
}
void SAMSocket::ProcessStreamAccept (char * buf, size_t len)
{
LogPrint (eLogDebug, "SAM stream accept: ", buf);
std::map<std::string, std::string> params;
ExtractParams (buf, params);
std::string& id = params[SAM_PARAM_ID];
std::string& silent = params[SAM_PARAM_SILENT];
if (silent == SAM_VALUE_TRUE) m_IsSilent = true;
m_ID = id;
m_Session = m_Owner.FindSession (id);
if (m_Session)
{
if (!m_Session->localDestination->IsAcceptingStreams ())
{
m_SocketType = eSAMSocketTypeAcceptor;
m_Session->sockets.push_back (shared_from_this ());
m_Session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1));
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
}
else
SendMessageReply (SAM_STREAM_STATUS_I2P_ERROR, strlen(SAM_STREAM_STATUS_I2P_ERROR), true);
}
else
SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true);
}
size_t SAMSocket::ProcessDatagramSend (char * buf, size_t len, const char * data)
{
LogPrint (eLogDebug, "SAM datagram send: ", buf, " ", len);
std::map<std::string, std::string> params;
ExtractParams (buf, params);
size_t size = boost::lexical_cast<int>(params[SAM_PARAM_SIZE]), offset = data - buf;
if (offset + size <= len)
{
if (m_Session)
{
auto d = m_Session->localDestination->GetDatagramDestination ();
if (d)
{
i2p::data::IdentityEx dest;
dest.FromBase64 (params[SAM_PARAM_DESTINATION]);
d->SendDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ());
}
else
LogPrint (eLogError, "SAM missing datagram destination");
}
else
LogPrint (eLogError, "SAM session is not created from DATAGRAM SEND");
}
else
{
LogPrint (eLogWarning, "SAM sent datagram size ", size, " exceeds buffer ", len - offset);
return 0; // try to receive more
}
return offset + size;
}
void SAMSocket::ProcessDestGenerate ()
{
LogPrint (eLogDebug, "SAM dest generate");
auto keys = i2p::data::PrivateKeys::CreateRandomKeys ();
#ifdef _MSC_VER
size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY,
keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
#else
size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY,
keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
#endif
SendMessageReply (m_Buffer, len, false);
}
void SAMSocket::ProcessNamingLookup (char * buf, size_t len)
{
LogPrint (eLogDebug, "SAM naming lookup: ", buf);
std::map<std::string, std::string> params;
ExtractParams (buf, params);
std::string& name = params[SAM_PARAM_NAME];
std::shared_ptr<const i2p::data::IdentityEx> identity;
i2p::data::IdentHash ident;
if (name == "ME")
SendNamingLookupReply (m_Session->localDestination->GetIdentity ());
else if ((identity = context.GetAddressBook ().GetAddress (name)) != nullptr)
SendNamingLookupReply (identity);
else if (m_Session && m_Session->localDestination &&
context.GetAddressBook ().GetIdentHash (name, ident))
{
auto leaseSet = m_Session->localDestination->FindLeaseSet (ident);
if (leaseSet)
SendNamingLookupReply (leaseSet->GetIdentity ());
else
m_Session->localDestination->RequestDestination (ident,
std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete,
shared_from_this (), std::placeholders::_1, ident));
}
else
{
LogPrint ("SAM naming failed. Unknown address ", name);
#ifdef _MSC_VER
size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY_INVALID_KEY, name.c_str());
#else
size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY_INVALID_KEY, name.c_str());
#endif
SendMessageReply (m_Buffer, len, false);
}
}
void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, i2p::data::IdentHash ident)
{
if (leaseSet)
{
context.GetAddressBook ().InsertAddress (leaseSet->GetIdentity ());
SendNamingLookupReply (leaseSet->GetIdentity ());
}
else
{
LogPrint (eLogInfo, "SAM naming lookup failed. LeaseSet for ", ident.ToBase32 (), " not found");
#ifdef _MSC_VER
size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY_INVALID_KEY,
context.GetAddressBook ().ToAddress (ident).c_str());
#else
size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY_INVALID_KEY,
context.GetAddressBook ().ToAddress (ident).c_str());
#endif
SendMessageReply (m_Buffer, len, false);
}
}
void SAMSocket::SendNamingLookupReply (std::shared_ptr<const i2p::data::IdentityEx> identity)
{
auto base64 = identity->ToBase64 ();
#ifdef _MSC_VER
size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, base64.c_str ());
#else
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, base64.c_str ());
#endif
SendMessageReply (m_Buffer, l, false);
}
void SAMSocket::ExtractParams (char * buf, std::map<std::string, std::string>& params)
{
char * separator;
do
{
separator = strchr (buf, ' ');
if (separator) *separator = 0;
char * value = strchr (buf, '=');
if (value)
{
*value = 0;
value++;
params[buf] = value;
}
buf = separator + 1;
}
while (separator);
}
void SAMSocket::Receive ()
{
if (m_BufferOffset >= SAM_SOCKET_BUFFER_SIZE)
{
LogPrint (eLogError, "Buffer is full. Terminate");
Terminate ();
return;
}
m_Socket.async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset),
std::bind((m_SocketType == eSAMSocketTypeStream) ? &SAMSocket::HandleReceived : &SAMSocket::HandleMessage,
shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
void SAMSocket::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("SAM read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
if (m_Stream)
{
auto s = shared_from_this ();
m_Stream->AsyncSend ((uint8_t *)m_Buffer, bytes_transferred,
[s](const boost::system::error_code& ecode)
{
if (!ecode)
s->Receive ();
else
s->Terminate ();
});
}
}
}
void SAMSocket::I2PReceive ()
{
if (m_Stream)
m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE),
std::bind (&SAMSocket::HandleI2PReceive, shared_from_this (),
std::placeholders::_1, std::placeholders::_2),
SAM_SOCKET_CONNECTION_MAX_IDLE);
}
void SAMSocket::HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("SAM stream read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred),
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1));
}
}
void SAMSocket::HandleWriteI2PData (const boost::system::error_code& ecode)
{
if (ecode)
{
LogPrint ("SAM socket write error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
I2PReceive ();
}
void SAMSocket::HandleI2PAccept (std::shared_ptr<i2p::stream::Stream> stream)
{
if (stream)
{
LogPrint ("SAM incoming I2P connection for session ", m_ID);
m_Stream = stream;
context.GetAddressBook ().InsertAddress (stream->GetRemoteIdentity ());
auto session = m_Owner.FindSession (m_ID);
if (session)
session->localDestination->StopAcceptingStreams ();
m_SocketType = eSAMSocketTypeStream;
if (!m_IsSilent)
{
// send remote peer address
uint8_t ident[1024];
size_t l = stream->GetRemoteIdentity ()->ToBuffer (ident, 1024);
size_t l1 = i2p::data::ByteStreamToBase64 (ident, l, (char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE);
m_StreamBuffer[l1] = '\n';
HandleI2PReceive (boost::system::error_code (), l1 +1); // we send identity like it has been received from stream
}
else
I2PReceive ();
}
else
LogPrint (eLogInfo, "SAM I2P acceptor has been reset");
}
void SAMSocket::HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{
LogPrint (eLogDebug, "SAM datagram received ", len);
auto base64 = from.ToBase64 ();
#ifdef _MSC_VER
size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), len);
#else
size_t l = snprintf ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), len);
#endif
if (len < SAM_SOCKET_BUFFER_SIZE - l)
{
memcpy (m_StreamBuffer + l, buf, len);
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, len + l),
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1));
}
else
LogPrint (eLogWarning, "SAM received datagram size ", len," exceeds buffer");
}
SAMSession::SAMSession (std::shared_ptr<ClientDestination> dest):
localDestination (dest)
{
}
SAMSession::~SAMSession ()
{
for (auto it: sockets)
it->SetSocketType (eSAMSocketTypeTerminated);
i2p::client::context.DeleteLocalDestination (localDestination);
}
void SAMSession::CloseStreams ()
{
for (auto it: sockets)
{
it->CloseStream ();
it->SetSocketType (eSAMSocketTypeTerminated);
}
sockets.clear ();
}
SAMBridge::SAMBridge (int port):
m_IsRunning (false), m_Thread (nullptr),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
m_DatagramEndpoint (boost::asio::ip::udp::v4 (), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint)
{
}
SAMBridge::~SAMBridge ()
{
if (m_IsRunning)
Stop ();
}
void SAMBridge::Start ()
{
Accept ();
ReceiveDatagram ();
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&SAMBridge::Run, this));
}
void SAMBridge::Stop ()
{
m_IsRunning = false;
m_Acceptor.cancel ();
for (auto it: m_Sessions)
delete it.second;
m_Sessions.clear ();
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
void SAMBridge::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint ("SAM: ", ex.what ());
}
}
}
void SAMBridge::Accept ()
{
auto newSocket = std::make_shared<SAMSocket> (*this);
m_Acceptor.async_accept (newSocket->GetSocket (), std::bind (&SAMBridge::HandleAccept, this,
std::placeholders::_1, newSocket));
}
void SAMBridge::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<SAMSocket> socket)
{
if (!ecode)
{
boost::system::error_code ec;
auto ep = socket->GetSocket ().remote_endpoint (ec);
if (!ec)
{
LogPrint ("New SAM connection from ", ep);
socket->ReceiveHandshake ();
}
else
LogPrint (eLogError, "SAM connection from error ", ec.message ());
}
else
LogPrint ("SAM accept error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Accept ();
}
SAMSession * SAMBridge::CreateSession (const std::string& id, const std::string& destination,
const std::map<std::string, std::string> * params)
{
std::shared_ptr<ClientDestination> localDestination = nullptr;
if (destination != "")
{
i2p::data::PrivateKeys keys;
keys.FromBase64 (destination);
localDestination = i2p::client::context.CreateNewLocalDestination (keys, true, params);
}
else // transient
{
// extract signature type
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
if (params)
{
auto it = params->find (SAM_PARAM_SIGNATURE_TYPE);
if (it != params->end ())
// TODO: extract string values
signatureType = boost::lexical_cast<int> (it->second);
}
localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, params);
}
if (localDestination)
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
auto ret = m_Sessions.insert (std::pair<std::string, SAMSession *>(id, new SAMSession (localDestination)));
if (!ret.second)
LogPrint ("Session ", id, " already exists");
return ret.first->second;
}
return nullptr;
}
void SAMBridge::CloseSession (const std::string& id)
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
auto it = m_Sessions.find (id);
if (it != m_Sessions.end ())
{
auto session = it->second;
session->localDestination->StopAcceptingStreams ();
session->CloseStreams ();
m_Sessions.erase (it);
delete session;
}
}
SAMSession * SAMBridge::FindSession (const std::string& id) const
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
auto it = m_Sessions.find (id);
if (it != m_Sessions.end ())
return it->second;
return nullptr;
}
void SAMBridge::ReceiveDatagram ()
{
m_DatagramSocket.async_receive_from (
boost::asio::buffer (m_DatagramReceiveBuffer, i2p::datagram::MAX_DATAGRAM_SIZE),
m_SenderEndpoint,
std::bind (&SAMBridge::HandleReceivedDatagram, this, std::placeholders::_1, std::placeholders::_2));
}
void SAMBridge::HandleReceivedDatagram (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (!ecode)
{
m_DatagramReceiveBuffer[bytes_transferred] = 0;
char * eol = strchr ((char *)m_DatagramReceiveBuffer, '\n');
*eol = 0; eol++;
size_t payloadLen = bytes_transferred - ((uint8_t *)eol - m_DatagramReceiveBuffer);
LogPrint ("SAM datagram received ", m_DatagramReceiveBuffer," size=", payloadLen);
char * sessionID = strchr ((char *)m_DatagramReceiveBuffer, ' ');
if (sessionID)
{
sessionID++;
char * destination = strchr (sessionID, ' ');
if (destination)
{
*destination = 0; destination++;
auto session = FindSession (sessionID);
if (session)
{
i2p::data::IdentityEx dest;
dest.FromBase64 (destination);
session->localDestination->GetDatagramDestination ()->
SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ());
}
else
LogPrint ("Session ", sessionID, " not found");
}
else
LogPrint ("Missing destination key");
}
else
LogPrint ("Missing sessionID");
ReceiveDatagram ();
}
else
LogPrint ("SAM datagram receive error: ", ecode.message ());
}
}
}

574
SOCKS.cpp
View File

@ -1,574 +0,0 @@
#include <cstring>
#include <cassert>
#include <string>
#include <atomic>
#include "SOCKS.h"
#include "Identity.h"
#include "Streaming.h"
#include "Destination.h"
#include "ClientContext.h"
#include "I2PEndian.h"
#include "I2PTunnel.h"
namespace i2p
{
namespace proxy
{
static const size_t socks_buffer_size = 8192;
static const size_t max_socks_hostname_size = 255; // Limit for socks5 and bad idea to traverse
struct SOCKSDnsAddress
{
uint8_t size;
char value[max_socks_hostname_size];
void FromString (std::string str)
{
size = str.length();
if (str.length() > max_socks_hostname_size) size = max_socks_hostname_size;
memcpy(value,str.c_str(),size);
}
std::string ToString() { return std::string(value, size); }
void push_back (char c) { value[size++] = c; }
};
class SOCKSServer;
class SOCKSHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this<SOCKSHandler>
{
private:
enum state
{
GET_SOCKSV,
GET_COMMAND,
GET_PORT,
GET_IPV4,
GET4_IDENT,
GET4A_HOST,
GET5_AUTHNUM,
GET5_AUTH,
GET5_REQUESTV,
GET5_GETRSV,
GET5_GETADDRTYPE,
GET5_IPV6,
GET5_HOST_SIZE,
GET5_HOST,
DONE
};
enum authMethods
{
AUTH_NONE = 0, //No authentication, skip to next step
AUTH_GSSAPI = 1, //GSSAPI authentication
AUTH_USERPASSWD = 2, //Username and password
AUTH_UNACCEPTABLE = 0xff //No acceptable method found
};
enum addrTypes
{
ADDR_IPV4 = 1, //IPv4 address (4 octets)
ADDR_DNS = 3, // DNS name (up to 255 octets)
ADDR_IPV6 = 4 //IPV6 address (16 octets)
};
enum errTypes
{
SOCKS5_OK = 0, // No error for SOCKS5
SOCKS5_GEN_FAIL = 1, // General server failure
SOCKS5_RULE_DENIED = 2, // Connection disallowed by ruleset
SOCKS5_NET_UNREACH = 3, // Network unreachable
SOCKS5_HOST_UNREACH = 4, // Host unreachable
SOCKS5_CONN_REFUSED = 5, // Connection refused by the peer
SOCKS5_TTL_EXPIRED = 6, // TTL Expired
SOCKS5_CMD_UNSUP = 7, // Command unsuported
SOCKS5_ADDR_UNSUP = 8, // Address type unsuported
SOCKS4_OK = 90, // No error for SOCKS4
SOCKS4_FAIL = 91, // Failed establishing connecting or not allowed
SOCKS4_IDENTD_MISSING = 92, // Couldn't connect to the identd server
SOCKS4_IDENTD_DIFFER = 93 // The ID reported by the application and by identd differ
};
enum cmdTypes
{
CMD_CONNECT = 1, // TCP Connect
CMD_BIND = 2, // TCP Bind
CMD_UDP = 3 // UDP associate
};
enum socksVersions
{
SOCKS4 = 4, // SOCKS4
SOCKS5 = 5 // SOCKS5
};
union address
{
uint32_t ip;
SOCKSDnsAddress dns;
uint8_t ipv6[16];
};
void EnterState(state nstate, uint8_t parseleft = 1);
bool HandleData(uint8_t *sock_buff, std::size_t len);
bool ValidateSOCKSRequest();
void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
void Terminate();
void AsyncSockRead();
boost::asio::const_buffers_1 GenerateSOCKS5SelectAuth(authMethods method);
boost::asio::const_buffers_1 GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port);
boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port);
bool Socks5ChooseAuth();
void SocksRequestFailed(errTypes error);
void SocksRequestSuccess();
void SentSocksFailed(const boost::system::error_code & ecode);
void SentSocksDone(const boost::system::error_code & ecode);
void SentSocksResponse(const boost::system::error_code & ecode);
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
uint8_t m_sock_buff[socks_buffer_size];
std::shared_ptr<boost::asio::ip::tcp::socket> m_sock;
std::shared_ptr<i2p::stream::Stream> m_stream;
uint8_t *m_remaining_data; //Data left to be sent
uint8_t m_response[7+max_socks_hostname_size];
address m_address; //Address
std::size_t m_remaining_data_len; //Size of the data left to be sent
uint32_t m_4aip; //Used in 4a requests
uint16_t m_port;
uint8_t m_command;
uint8_t m_parseleft; //Octets left to parse
authMethods m_authchosen; //Authentication chosen
addrTypes m_addrtype; //Address type chosen
socksVersions m_socksv; //Socks version
cmdTypes m_cmd; // Command requested
state m_state;
public:
SOCKSHandler(SOCKSServer * parent, std::shared_ptr<boost::asio::ip::tcp::socket> sock) :
I2PServiceHandler(parent), m_sock(sock), m_stream(nullptr),
m_authchosen(AUTH_UNACCEPTABLE), m_addrtype(ADDR_IPV4)
{ m_address.ip = 0; EnterState(GET_SOCKSV); }
~SOCKSHandler() { Terminate(); }
void Handle() { AsyncSockRead(); }
};
void SOCKSHandler::AsyncSockRead()
{
LogPrint(eLogDebug,"--- SOCKS async sock read");
if(m_sock)
m_sock->async_receive(boost::asio::buffer(m_sock_buff, socks_buffer_size),
std::bind(&SOCKSHandler::HandleSockRecv, shared_from_this(),
std::placeholders::_1, std::placeholders::_2));
else
LogPrint(eLogError,"--- SOCKS no socket for read");
}
void SOCKSHandler::Terminate()
{
if (Kill()) return;
if (m_sock)
{
LogPrint(eLogDebug,"--- SOCKS close sock");
m_sock->close();
m_sock = nullptr;
}
if (m_stream)
{
LogPrint(eLogDebug,"--- SOCKS close stream");
m_stream.reset ();
}
Done(shared_from_this());
}
boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS4Response(SOCKSHandler::errTypes error, uint32_t ip, uint16_t port)
{
assert(error >= SOCKS4_OK);
m_response[0] = '\x00'; //Version
m_response[1] = error; //Response code
htobe16buf(m_response+2,port); //Port
htobe32buf(m_response+4,ip); //IP
return boost::asio::const_buffers_1(m_response,8);
}
boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port)
{
size_t size = 6;
assert(error <= SOCKS5_ADDR_UNSUP);
m_response[0] = '\x05'; //Version
m_response[1] = error; //Response code
m_response[2] = '\x00'; //RSV
m_response[3] = type; //Address type
switch (type)
{
case ADDR_IPV4:
size = 10;
htobe32buf(m_response+4,addr.ip);
break;
case ADDR_IPV6:
size = 22;
memcpy(m_response+4,addr.ipv6, 16);
break;
case ADDR_DNS:
size = 7+addr.dns.size;
m_response[4] = addr.dns.size;
memcpy(m_response+5,addr.dns.value, addr.dns.size);
break;
}
htobe16buf(m_response+size-2,port); //Port
return boost::asio::const_buffers_1(m_response,size);
}
bool SOCKSHandler::Socks5ChooseAuth()
{
m_response[0] = '\x05'; //Version
m_response[1] = m_authchosen; //Response code
boost::asio::const_buffers_1 response(m_response,2);
if (m_authchosen == AUTH_UNACCEPTABLE)
{
LogPrint(eLogWarning,"--- SOCKS5 authentication negotiation failed");
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed,
shared_from_this(), std::placeholders::_1));
return false;
}
else
{
LogPrint(eLogDebug,"--- SOCKS5 choosing authentication method: ", m_authchosen);
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksResponse,
shared_from_this(), std::placeholders::_1));
return true;
}
}
/* All hope is lost beyond this point */
void SOCKSHandler::SocksRequestFailed(SOCKSHandler::errTypes error)
{
boost::asio::const_buffers_1 response(nullptr,0);
assert(error != SOCKS4_OK && error != SOCKS5_OK);
switch (m_socksv)
{
case SOCKS4:
LogPrint(eLogWarning,"--- SOCKS4 failed: ", error);
if (error < SOCKS4_OK) error = SOCKS4_FAIL; //Transparently map SOCKS5 errors
response = GenerateSOCKS4Response(error, m_4aip, m_port);
break;
case SOCKS5:
LogPrint(eLogWarning,"--- SOCKS5 failed: ", error);
response = GenerateSOCKS5Response(error, m_addrtype, m_address, m_port);
break;
}
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed,
shared_from_this(), std::placeholders::_1));
}
void SOCKSHandler::SocksRequestSuccess()
{
boost::asio::const_buffers_1 response(nullptr,0);
//TODO: this should depend on things like the command type and callbacks may change
switch (m_socksv)
{
case SOCKS4:
LogPrint(eLogInfo,"--- SOCKS4 connection success");
response = GenerateSOCKS4Response(SOCKS4_OK, m_4aip, m_port);
break;
case SOCKS5:
LogPrint(eLogInfo,"--- SOCKS5 connection success");
auto s = i2p::client::context.GetAddressBook().ToAddress(GetOwner()->GetLocalDestination()->GetIdentHash());
address ad; ad.dns.FromString(s);
//HACK only 16 bits passed in port as SOCKS5 doesn't allow for more
response = GenerateSOCKS5Response(SOCKS5_OK, ADDR_DNS, ad, m_stream->GetRecvStreamID());
break;
}
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksDone,
shared_from_this(), std::placeholders::_1));
}
void SOCKSHandler::EnterState(SOCKSHandler::state nstate, uint8_t parseleft) {
switch (nstate)
{
case GET_PORT: parseleft = 2; break;
case GET_IPV4: m_addrtype = ADDR_IPV4; m_address.ip = 0; parseleft = 4; break;
case GET4_IDENT: m_4aip = m_address.ip; break;
case GET4A_HOST:
case GET5_HOST: m_addrtype = ADDR_DNS; m_address.dns.size = 0; break;
case GET5_IPV6: m_addrtype = ADDR_IPV6; parseleft = 16; break;
default:;
}
m_parseleft = parseleft;
m_state = nstate;
}
bool SOCKSHandler::ValidateSOCKSRequest()
{
if ( m_cmd != CMD_CONNECT )
{
//TODO: we need to support binds and other shit!
LogPrint(eLogError,"--- SOCKS unsupported command: ", m_cmd);
SocksRequestFailed(SOCKS5_CMD_UNSUP);
return false;
}
//TODO: we may want to support other address types!
if ( m_addrtype != ADDR_DNS )
{
switch (m_socksv)
{
case SOCKS5:
LogPrint(eLogError,"--- SOCKS5 unsupported address type: ", m_addrtype);
break;
case SOCKS4:
LogPrint(eLogError,"--- SOCKS4a rejected because it's actually SOCKS4");
break;
}
SocksRequestFailed(SOCKS5_ADDR_UNSUP);
return false;
}
//TODO: we may want to support other domains
if(m_addrtype == ADDR_DNS && m_address.dns.ToString().find(".i2p") == std::string::npos)
{
LogPrint(eLogError,"--- SOCKS invalid hostname: ", m_address.dns.ToString());
SocksRequestFailed(SOCKS5_ADDR_UNSUP);
return false;
}
return true;
}
bool SOCKSHandler::HandleData(uint8_t *sock_buff, std::size_t len)
{
assert(len); // This should always be called with a least a byte left to parse
while (len > 0)
{
switch (m_state)
{
case GET_SOCKSV:
m_socksv = (SOCKSHandler::socksVersions) *sock_buff;
switch (*sock_buff)
{
case SOCKS4:
EnterState(GET_COMMAND); //Initialize the parser at the right position
break;
case SOCKS5:
EnterState(GET5_AUTHNUM); //Initialize the parser at the right position
break;
default:
LogPrint(eLogError,"--- SOCKS rejected invalid version: ", ((int)*sock_buff));
Terminate();
return false;
}
break;
case GET5_AUTHNUM:
EnterState(GET5_AUTH, *sock_buff);
break;
case GET5_AUTH:
m_parseleft --;
if (*sock_buff == AUTH_NONE)
m_authchosen = AUTH_NONE;
if ( m_parseleft == 0 )
{
if (!Socks5ChooseAuth()) return false;
EnterState(GET5_REQUESTV);
}
break;
case GET_COMMAND:
switch (*sock_buff)
{
case CMD_CONNECT:
case CMD_BIND:
break;
case CMD_UDP:
if (m_socksv == SOCKS5) break;
default:
LogPrint(eLogError,"--- SOCKS invalid command: ", ((int)*sock_buff));
SocksRequestFailed(SOCKS5_GEN_FAIL);
return false;
}
m_cmd = (SOCKSHandler::cmdTypes)*sock_buff;
switch (m_socksv)
{
case SOCKS5: EnterState(GET5_GETRSV); break;
case SOCKS4: EnterState(GET_PORT); break;
}
break;
case GET_PORT:
m_port = (m_port << 8)|((uint16_t)*sock_buff);
m_parseleft--;
if (m_parseleft == 0)
{
switch (m_socksv)
{
case SOCKS5: EnterState(DONE); break;
case SOCKS4: EnterState(GET_IPV4); break;
}
}
break;
case GET_IPV4:
m_address.ip = (m_address.ip << 8)|((uint32_t)*sock_buff);
m_parseleft--;
if (m_parseleft == 0)
{
switch (m_socksv)
{
case SOCKS5: EnterState(GET_PORT); break;
case SOCKS4: EnterState(GET4_IDENT); m_4aip = m_address.ip; break;
}
}
break;
case GET4_IDENT:
if (!*sock_buff)
{
if( m_4aip == 0 || m_4aip > 255 )
EnterState(DONE);
else
EnterState(GET4A_HOST);
}
break;
case GET4A_HOST:
if (!*sock_buff)
{
EnterState(DONE);
break;
}
if (m_address.dns.size >= max_socks_hostname_size)
{
LogPrint(eLogError,"--- SOCKS4a destination is too large");
SocksRequestFailed(SOCKS4_FAIL);
return false;
}
m_address.dns.push_back(*sock_buff);
break;
case GET5_REQUESTV:
if (*sock_buff != SOCKS5)
{
LogPrint(eLogError,"--- SOCKS5 rejected unknown request version: ", ((int)*sock_buff));
SocksRequestFailed(SOCKS5_GEN_FAIL);
return false;
}
EnterState(GET_COMMAND);
break;
case GET5_GETRSV:
if ( *sock_buff != 0 )
{
LogPrint(eLogError,"--- SOCKS5 unknown reserved field: ", ((int)*sock_buff));
SocksRequestFailed(SOCKS5_GEN_FAIL);
return false;
}
EnterState(GET5_GETADDRTYPE);
break;
case GET5_GETADDRTYPE:
switch (*sock_buff)
{
case ADDR_IPV4: EnterState(GET_IPV4); break;
case ADDR_IPV6: EnterState(GET5_IPV6); break;
case ADDR_DNS : EnterState(GET5_HOST_SIZE); break;
default:
LogPrint(eLogError,"--- SOCKS5 unknown address type: ", ((int)*sock_buff));
SocksRequestFailed(SOCKS5_GEN_FAIL);
return false;
}
break;
case GET5_IPV6:
m_address.ipv6[16-m_parseleft] = *sock_buff;
m_parseleft--;
if (m_parseleft == 0) EnterState(GET_PORT);
break;
case GET5_HOST_SIZE:
EnterState(GET5_HOST, *sock_buff);
break;
case GET5_HOST:
m_address.dns.push_back(*sock_buff);
m_parseleft--;
if (m_parseleft == 0) EnterState(GET_PORT);
break;
default:
LogPrint(eLogError,"--- SOCKS parse state?? ", m_state);
Terminate();
return false;
}
sock_buff++;
len--;
if (m_state == DONE)
{
m_remaining_data_len = len;
m_remaining_data = sock_buff;
return ValidateSOCKSRequest();
}
}
return true;
}
void SOCKSHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len)
{
LogPrint(eLogDebug,"--- SOCKS sock recv: ", len);
if(ecode)
{
LogPrint(eLogWarning," --- SOCKS sock recv got error: ", ecode);
Terminate();
return;
}
if (HandleData(m_sock_buff, len))
{
if (m_state == DONE)
{
LogPrint(eLogInfo,"--- SOCKS requested ", m_address.dns.ToString(), ":" , m_port);
GetOwner()->CreateStream ( std::bind (&SOCKSHandler::HandleStreamRequestComplete,
shared_from_this(), std::placeholders::_1), m_address.dns.ToString(), m_port);
}
else
AsyncSockRead();
}
}
void SOCKSHandler::SentSocksFailed(const boost::system::error_code & ecode)
{
if (!ecode)
Terminate();
else
{
LogPrint (eLogError,"--- SOCKS Closing socket after sending failure because: ", ecode.message ());
Terminate();
}
}
void SOCKSHandler::SentSocksDone(const boost::system::error_code & ecode)
{
if (!ecode)
{
if (Kill()) return;
LogPrint (eLogInfo,"--- SOCKS New I2PTunnel connection");
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, m_stream);
GetOwner()->AddHandler (connection);
connection->I2PConnect (m_remaining_data,m_remaining_data_len);
Done(shared_from_this());
}
else
{
LogPrint (eLogError,"--- SOCKS Closing socket after completion reply because: ", ecode.message ());
Terminate();
}
}
void SOCKSHandler::SentSocksResponse(const boost::system::error_code & ecode)
{
if (ecode)
{
LogPrint (eLogError,"--- SOCKS Closing socket after sending reply because: ", ecode.message ());
Terminate();
}
}
void SOCKSHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
{
if (stream)
{
m_stream = stream;
SocksRequestSuccess();
}
else
{
LogPrint (eLogError,"--- SOCKS Issue when creating the stream, check the previous warnings for more info.");
SocksRequestFailed(SOCKS5_HOST_UNREACH);
}
}
SOCKSServer::SOCKSServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination) :
TCPIPAcceptor (port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())
{
}
std::shared_ptr<i2p::client::I2PServiceHandler> SOCKSServer::CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
return std::make_shared<SOCKSHandler> (this, socket);
}
}
}

32
SOCKS.h
View File

@ -1,32 +0,0 @@
#ifndef SOCKS_H__
#define SOCKS_H__
#include <memory>
#include <set>
#include <boost/asio.hpp>
#include <mutex>
#include "I2PService.h"
namespace i2p
{
namespace proxy
{
class SOCKSServer: public i2p::client::TCPIPAcceptor
{
public:
SOCKSServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
~SOCKSServer() {};
protected:
// Implements TCPIPAcceptor
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
const char* GetName() { return "SOCKS"; }
};
typedef SOCKSServer SOCKSProxy;
}
}
#endif

565
SSU.cpp
View File

@ -1,565 +0,0 @@
#include <string.h>
#include <boost/bind.hpp>
#include "Log.h"
#include "Timestamp.h"
#include "RouterContext.h"
#include "NetDb.h"
#include "SSU.h"
namespace i2p
{
namespace transport
{
SSUServer::SSUServer (int port): m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr),
m_Work (m_Service), m_WorkV6 (m_ServiceV6), m_ReceiversWork (m_ReceiversService),
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
m_Socket (m_ReceiversService, m_Endpoint), m_SocketV6 (m_ReceiversService),
m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service)
{
m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (65535));
m_Socket.set_option (boost::asio::socket_base::send_buffer_size (65535));
if (context.SupportsV6 ())
{
m_SocketV6.open (boost::asio::ip::udp::v6());
m_SocketV6.set_option (boost::asio::ip::v6_only (true));
m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (65535));
m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (65535));
m_SocketV6.bind (m_EndpointV6);
}
}
SSUServer::~SSUServer ()
{
}
void SSUServer::Start ()
{
m_IsRunning = true;
m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this));
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
m_ReceiversService.post (std::bind (&SSUServer::Receive, this));
if (context.SupportsV6 ())
{
m_ThreadV6 = new std::thread (std::bind (&SSUServer::RunV6, this));
m_ReceiversService.post (std::bind (&SSUServer::ReceiveV6, this));
}
SchedulePeerTestsCleanupTimer ();
ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers
}
void SSUServer::Stop ()
{
DeleteAllSessions ();
m_IsRunning = false;
m_Service.stop ();
m_Socket.close ();
m_ServiceV6.stop ();
m_SocketV6.close ();
m_ReceiversService.stop ();
if (m_ReceiversThread)
{
m_ReceiversThread->join ();
delete m_ReceiversThread;
m_ReceiversThread = nullptr;
}
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
if (m_ThreadV6)
{
m_ThreadV6->join ();
delete m_ThreadV6;
m_ThreadV6 = nullptr;
}
}
void SSUServer::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint (eLogError, "SSU server: ", ex.what ());
}
}
}
void SSUServer::RunV6 ()
{
while (m_IsRunning)
{
try
{
m_ServiceV6.run ();
}
catch (std::exception& ex)
{
LogPrint (eLogError, "SSU V6 server: ", ex.what ());
}
}
}
void SSUServer::RunReceivers ()
{
while (m_IsRunning)
{
try
{
m_ReceiversService.run ();
}
catch (std::exception& ex)
{
LogPrint (eLogError, "SSU receivers: ", ex.what ());
}
}
}
void SSUServer::AddRelay (uint32_t tag, const boost::asio::ip::udp::endpoint& relay)
{
m_Relays[tag] = relay;
}
std::shared_ptr<SSUSession> SSUServer::FindRelaySession (uint32_t tag)
{
auto it = m_Relays.find (tag);
if (it != m_Relays.end ())
return FindSession (it->second);
return nullptr;
}
void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to)
{
if (to.protocol () == boost::asio::ip::udp::v4())
m_Socket.send_to (boost::asio::buffer (buf, len), to);
else
m_SocketV6.send_to (boost::asio::buffer (buf, len), to);
}
void SSUServer::Receive ()
{
SSUPacket * packet = new SSUPacket ();
m_Socket.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from,
std::bind (&SSUServer::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet));
}
void SSUServer::ReceiveV6 ()
{
SSUPacket * packet = new SSUPacket ();
m_SocketV6.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from,
std::bind (&SSUServer::HandleReceivedFromV6, this, std::placeholders::_1, std::placeholders::_2, packet));
}
void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{
if (!ecode)
{
packet->len = bytes_transferred;
std::vector<SSUPacket *> packets;
packets.push_back (packet);
boost::system::error_code ec;
size_t moreBytes = m_Socket.available(ec);
while (moreBytes && packets.size () < 25)
{
packet = new SSUPacket ();
packet->len = m_Socket.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from);
packets.push_back (packet);
moreBytes = m_Socket.available();
}
m_Service.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets));
Receive ();
}
else
{
LogPrint ("SSU receive error: ", ecode.message ());
delete packet;
}
}
void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{
if (!ecode)
{
packet->len = bytes_transferred;
std::vector<SSUPacket *> packets;
packets.push_back (packet);
size_t moreBytes = m_SocketV6.available ();
while (moreBytes && packets.size () < 25)
{
packet = new SSUPacket ();
packet->len = m_SocketV6.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from);
packets.push_back (packet);
moreBytes = m_SocketV6.available();
}
m_ServiceV6.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets));
ReceiveV6 ();
}
else
{
LogPrint ("SSU V6 receive error: ", ecode.message ());
delete packet;
}
}
void SSUServer::HandleReceivedPackets (std::vector<SSUPacket *> packets)
{
std::shared_ptr<SSUSession> session;
for (auto it1: packets)
{
auto packet = it1;
try
{
if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous
{
if (session) session->FlushData ();
auto it = m_Sessions.find (packet->from);
if (it != m_Sessions.end ())
session = it->second;
if (!session)
{
session = std::make_shared<SSUSession> (*this, packet->from);
session->WaitForConnect ();
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
m_Sessions[packet->from] = session;
}
LogPrint (eLogInfo, "New SSU session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created");
}
}
session->ProcessNextMessage (packet->buf, packet->len, packet->from);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "SSU: HandleReceivedPackets ", ex.what ());
if (session) session->FlushData ();
session = nullptr;
}
delete packet;
}
if (session) session->FlushData ();
}
std::shared_ptr<SSUSession> SSUServer::FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const
{
if (!router) return nullptr;
auto address = router->GetSSUAddress (true); // v4 only
if (!address) return nullptr;
auto session = FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
if (session || !context.SupportsV6 ())
return session;
// try v6
address = router->GetSSUV6Address ();
if (!address) return nullptr;
return FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
}
std::shared_ptr<SSUSession> SSUServer::FindSession (const boost::asio::ip::udp::endpoint& e) const
{
auto it = m_Sessions.find (e);
if (it != m_Sessions.end ())
return it->second;
else
return nullptr;
}
std::shared_ptr<SSUSession> SSUServer::GetSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest)
{
std::shared_ptr<SSUSession> session;
if (router)
{
auto address = router->GetSSUAddress (!context.SupportsV6 ());
if (address)
{
boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port);
auto it = m_Sessions.find (remoteEndpoint);
if (it != m_Sessions.end ())
{
session = it->second;
if (peerTest && session->GetState () == eSessionStateEstablished)
session->SendPeerTest ();
}
else
{
// otherwise create new session
session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
m_Sessions[remoteEndpoint] = session;
}
if (!router->UsesIntroducer ())
{
// connect directly
LogPrint ("Creating new SSU session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
session->Connect ();
}
else
{
// connect through introducer
int numIntroducers = address->introducers.size ();
if (numIntroducers > 0)
{
std::shared_ptr<SSUSession> introducerSession;
const i2p::data::RouterInfo::Introducer * introducer = nullptr;
// we might have a session to introducer already
for (int i = 0; i < numIntroducers; i++)
{
introducer = &(address->introducers[i]);
it = m_Sessions.find (boost::asio::ip::udp::endpoint (introducer->iHost, introducer->iPort));
if (it != m_Sessions.end ())
{
introducerSession = it->second;
break;
}
}
if (introducerSession) // session found
LogPrint ("Session to introducer already exists");
else // create new
{
LogPrint ("Creating new session to introducer");
introducer = &(address->introducers[0]); // TODO:
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
std::unique_lock<std::mutex> l(m_SessionsMutex);
m_Sessions[introducerEndpoint] = introducerSession;
}
// introduce
LogPrint ("Introduce new SSU session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()),
"] through introducer ", introducer->iHost, ":", introducer->iPort);
session->WaitForIntroduction ();
if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable
{
uint8_t buf[1];
Send (buf, 0, remoteEndpoint); // send HolePunch
}
introducerSession->Introduce (*introducer);
}
else
{
LogPrint (eLogWarning, "Can't connect to unreachable router. No introducers presented");
std::unique_lock<std::mutex> l(m_SessionsMutex);
m_Sessions.erase (remoteEndpoint);
session.reset ();
}
}
}
}
else
LogPrint (eLogWarning, "Router ", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), " doesn't have SSU address");
}
return session;
}
void SSUServer::DeleteSession (std::shared_ptr<SSUSession> session)
{
if (session)
{
session->Close ();
std::unique_lock<std::mutex> l(m_SessionsMutex);
m_Sessions.erase (session->GetRemoteEndpoint ());
}
}
void SSUServer::DeleteAllSessions ()
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
for (auto it: m_Sessions)
it.second->Close ();
m_Sessions.clear ();
}
template<typename Filter>
std::shared_ptr<SSUSession> SSUServer::GetRandomSession (Filter filter)
{
std::vector<std::shared_ptr<SSUSession> > filteredSessions;
for (auto s :m_Sessions)
if (filter (s.second)) filteredSessions.push_back (s.second);
if (filteredSessions.size () > 0)
{
auto ind = rand () % filteredSessions.size ();
return filteredSessions[ind];
}
return nullptr;
}
std::shared_ptr<SSUSession> SSUServer::GetRandomEstablishedSession (std::shared_ptr<const SSUSession> excluded)
{
return GetRandomSession (
[excluded](std::shared_ptr<SSUSession> session)->bool
{
return session->GetState () == eSessionStateEstablished && !session->IsV6 () &&
session != excluded;
}
);
}
std::set<SSUSession *> SSUServer::FindIntroducers (int maxNumIntroducers)
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
std::set<SSUSession *> ret;
for (int i = 0; i < maxNumIntroducers; i++)
{
auto session = GetRandomSession (
[&ret, ts](std::shared_ptr<SSUSession> session)->bool
{
return session->GetRelayTag () && !ret.count (session.get ()) &&
session->GetState () == eSessionStateEstablished &&
ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION;
}
);
if (session)
{
ret.insert (session.get ());
break;
}
}
return ret;
}
void SSUServer::ScheduleIntroducersUpdateTimer ()
{
m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL));
m_IntroducersUpdateTimer.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer,
this, std::placeholders::_1));
}
void SSUServer::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
// timeout expired
if (i2p::context.GetStatus () == eRouterStatusTesting)
{
// we still don't know if we need introducers
ScheduleIntroducersUpdateTimer ();
return;
}
if (i2p::context.GetStatus () == eRouterStatusOK) return; // we don't need introducers anymore
// we are firewalled
if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable ();
std::list<boost::asio::ip::udp::endpoint> newList;
size_t numIntroducers = 0;
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it :m_Introducers)
{
auto session = FindSession (it);
if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION)
{
session->SendKeepAlive ();
newList.push_back (it);
numIntroducers++;
}
else
i2p::context.RemoveIntroducer (it);
}
if (numIntroducers < SSU_MAX_NUM_INTRODUCERS)
{
// create new
auto introducers = FindIntroducers (SSU_MAX_NUM_INTRODUCERS);
if (introducers.size () > 0)
{
for (auto it1: introducers)
{
auto& ep = it1->GetRemoteEndpoint ();
i2p::data::RouterInfo::Introducer introducer;
introducer.iHost = ep.address ();
introducer.iPort = ep.port ();
introducer.iTag = it1->GetRelayTag ();
introducer.iKey = it1->GetIntroKey ();
if (i2p::context.AddIntroducer (introducer))
{
newList.push_back (ep);
if (newList.size () >= SSU_MAX_NUM_INTRODUCERS) break;
}
}
}
}
m_Introducers = newList;
if (m_Introducers.empty ())
{
auto introducer = i2p::data::netdb.GetRandomIntroducer ();
if (introducer)
GetSession (introducer);
}
ScheduleIntroducersUpdateTimer ();
}
}
void SSUServer::NewPeerTest (uint32_t nonce, PeerTestParticipant role, std::shared_ptr<SSUSession> session)
{
m_PeerTests[nonce] = { i2p::util::GetMillisecondsSinceEpoch (), role, session };
}
PeerTestParticipant SSUServer::GetPeerTestParticipant (uint32_t nonce)
{
auto it = m_PeerTests.find (nonce);
if (it != m_PeerTests.end ())
return it->second.role;
else
return ePeerTestParticipantUnknown;
}
std::shared_ptr<SSUSession> SSUServer::GetPeerTestSession (uint32_t nonce)
{
auto it = m_PeerTests.find (nonce);
if (it != m_PeerTests.end ())
return it->second.session;
else
return nullptr;
}
void SSUServer::UpdatePeerTest (uint32_t nonce, PeerTestParticipant role)
{
auto it = m_PeerTests.find (nonce);
if (it != m_PeerTests.end ())
it->second.role = role;
}
void SSUServer::RemovePeerTest (uint32_t nonce)
{
m_PeerTests.erase (nonce);
}
void SSUServer::SchedulePeerTestsCleanupTimer ()
{
m_PeerTestsCleanupTimer.expires_from_now (boost::posix_time::seconds(SSU_PEER_TEST_TIMEOUT));
m_PeerTestsCleanupTimer.async_wait (std::bind (&SSUServer::HandlePeerTestsCleanupTimer,
this, std::placeholders::_1));
}
void SSUServer::HandlePeerTestsCleanupTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
int numDeleted = 0;
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
for (auto it = m_PeerTests.begin (); it != m_PeerTests.end ();)
{
if (ts > it->second.creationTime + SSU_PEER_TEST_TIMEOUT*1000LL)
{
numDeleted++;
it = m_PeerTests.erase (it);
}
else
it++;
}
if (numDeleted > 0)
LogPrint (eLogInfo, numDeleted, " peer tests have been expired");
SchedulePeerTestsCleanupTimer ();
}
}
}
}

View File

@ -1,441 +0,0 @@
#include <memory>
#include "Log.h"
#include "Signature.h"
namespace i2p
{
namespace crypto
{
class Ed25519
{
public:
Ed25519 ()
{
BN_CTX * ctx = BN_CTX_new ();
BIGNUM * two = BN_new (), * tmp = BN_new ();
BN_set_word (two, 2);
q = BN_new ();
// 2^255-19
BN_set_word (tmp, 255);
BN_exp (q, two, tmp, ctx);
BN_sub_word (q, 19);
l = BN_new ();
// 2^252 + 27742317777372353535851937790883648493
BN_set_word (tmp, 252);
BN_exp (l, two, tmp, ctx);
two_252_2 = BN_dup (l);
BN_dec2bn (&tmp, "27742317777372353535851937790883648493");
BN_add (l, l, tmp);
BN_sub_word (two_252_2, 2); // 2^252 - 2
// -121665*inv(121666)
d = BN_new ();
BN_set_word (tmp, 121666);
BN_mod_inverse (tmp, tmp, q, ctx);
BN_set_word (d, 121665);
BN_set_negative (d, 1);
BN_mul (d, d, tmp, ctx);
// 2^((q-1)/4)
I = BN_new ();
BN_free (tmp);
tmp = BN_dup (q);
BN_sub_word (tmp, 1);
BN_div_word (tmp, 4);
BN_mod_exp (I, two, tmp, q, ctx);
// 4*inv(5)
BIGNUM * By = BN_new ();
BN_set_word (By, 5);
BN_mod_inverse (By, By, q, ctx);
BN_mul_word (By, 4);
BIGNUM * Bx = RecoverX (By, ctx);
BN_mod (Bx, Bx, q, ctx); // % q
BN_mod (By, By, q, ctx); // % q
B = {Bx, By};
BN_free (two);
BN_free (tmp);
// precalculate Bi16 table
Bi16[0][0] = { BN_dup (Bx), BN_dup (By) };
for (int i = 0; i < 64; i++)
{
if (i) Bi16[i][0] = Sum (Bi16[i-1][14], Bi16[i-1][0], ctx);
for (int j = 1; j < 15; j++)
Bi16[i][j] = Sum (Bi16[i][j-1], Bi16[i][0], ctx); // (16+j+1)^i*B
}
BN_CTX_free (ctx);
}
~Ed25519 ()
{
BN_free (q);
BN_free (l);
BN_free (d);
BN_free (I);
BN_free (two_252_2);
}
EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const
{
return MulB (expandedPrivateKey, ctx); // left half of expanded key, considered as Little Endian
}
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const
{
return DecodePoint (buf, ctx);
}
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const
{
EncodePoint (Normalize (publicKey, ctx), buf);
}
bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature, BN_CTX * ctx) const
{
BIGNUM * h = DecodeBN<64> (digest);
// signature 0..31 - R, 32..63 - S
// B*S = R + PK*h => R = B*S - PK*h
// we don't decode R, but encode (B*S - PK*h)
auto Bs = MulB (signature + EDDSA25519_SIGNATURE_LENGTH/2, ctx); // B*S;
BN_mod (h, h, l, ctx); // public key is multiple of B, but B%l = 0
auto PKh = Mul (publicKey, h, ctx); // PK*h
uint8_t diff[32];
EncodePoint (Normalize (Sum (Bs, -PKh, ctx), ctx), diff); // Bs - PKh encoded
bool passed = !memcmp (signature, diff, 32); // R
BN_free (h);
if (!passed)
LogPrint (eLogError, "25519 signature verification failed");
return passed;
}
void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len,
uint8_t * signature, BN_CTX * bnCtx) const
{
// calculate r
SHA512_CTX ctx;
SHA512_Init (&ctx);
SHA512_Update (&ctx, expandedPrivateKey + EDDSA25519_PRIVATE_KEY_LENGTH, EDDSA25519_PRIVATE_KEY_LENGTH); // right half of expanded key
SHA512_Update (&ctx, buf, len); // data
uint8_t digest[64];
SHA512_Final (digest, &ctx);
BIGNUM * r = DecodeBN<32> (digest); // DecodeBN<64> (digest); // for test vectors
// calculate R
uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf
EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R); // EncodePoint (Mul (B, r, bnCtx), R); // for test vectors
// calculate S
SHA512_Init (&ctx);
SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
SHA512_Update (&ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
SHA512_Update (&ctx, buf, len); // data
SHA512_Final (digest, &ctx);
BIGNUM * h = DecodeBN<64> (digest);
// S = (r + h*a) % l
BIGNUM * a = DecodeBN<EDDSA25519_PRIVATE_KEY_LENGTH> (expandedPrivateKey); // left half of expanded key
BN_mod_mul (h, h, a, l, bnCtx); // %l
BN_mod_add (h, h, r, l, bnCtx); // %l
memcpy (signature, R, EDDSA25519_SIGNATURE_LENGTH/2);
EncodeBN (h, signature + EDDSA25519_SIGNATURE_LENGTH/2, EDDSA25519_SIGNATURE_LENGTH/2); // S
BN_free (r); BN_free (h); BN_free (a);
}
private:
EDDSAPoint Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const
{
// x3 = (x1*y2+y1*x2)*(z1*z2-d*t1*t2)
// y3 = (y1*y2+x1*x2)*(z1*z2+d*t1*t2)
// z3 = (z1*z2-d*t1*t2)*(z1*z2+d*t1*t2)
// t3 = (y1*y2+x1*x2)*(x1*y2+y1*x2)
BIGNUM * x3 = BN_new (), * y3 = BN_new (), * z3 = BN_new (), * t3 = BN_new ();
BIGNUM * z1 = p1.z, * t1 = p1.t;
if (!z1) { z1 = BN_new (); BN_one (z1); }
if (!t1) { t1 = BN_new (); BN_mul (t1, p1.x, p1.y, ctx); }
BIGNUM * z2 = p2.z, * t2 = p2.t;
if (!z2) { z2 = BN_new (); BN_one (z2); }
if (!t2) { t2 = BN_new (); BN_mul (t2, p2.x, p2.y, ctx); }
BIGNUM * A = BN_new (), * B = BN_new (), * C = BN_new (), * D = BN_new ();
BN_mul (A, p1.x, p2.x, ctx); // A = x1*x2
BN_mul (B, p1.y, p2.y, ctx); // B = y1*y2
BN_mul (C, t1, t2, ctx);
BN_mul (C, C, d, ctx); // C = d*t1*t2
BN_mul (D, z1, z2, ctx); // D = z1*z2
BIGNUM * E = BN_new (), * F = BN_new (), * G = BN_new (), * H = BN_new ();
BN_add (x3, p1.x, p1.y);
BN_add (y3, p2.x, p2.y);
BN_mul (E, x3, y3, ctx); // (x1 + y1)*(x2 + y2)
BN_sub (E, E, A);
BN_sub (E, E, B); // E = (x1 + y1)*(x2 + y2) - A - B
BN_sub (F, D, C); // F = D - C
BN_add (G, D, C); // G = D + C
BN_add (H, B, A); // H = B + A
BN_free (A); BN_free (B); BN_free (C); BN_free (D);
if (!p1.z) BN_free (z1);
if (!p1.t) BN_free (t1);
if (!p2.z) BN_free (z2);
if (!p2.t) BN_free (t2);
BN_mod_mul (x3, E, F, q, ctx); // x3 = E*F
BN_mod_mul (y3, G, H, q, ctx); // y3 = G*H
BN_mod_mul (z3, F, G, q, ctx); // z3 = F*G
BN_mod_mul (t3, E, H, q, ctx); // t3 = E*H
BN_free (E); BN_free (F); BN_free (G); BN_free (H);
return EDDSAPoint {x3, y3, z3, t3};
}
EDDSAPoint Double (const EDDSAPoint& p, BN_CTX * ctx) const
{
BIGNUM * x2 = BN_new (), * y2 = BN_new (), * z2 = BN_new (), * t2 = BN_new ();
BIGNUM * z = p.z, * t = p.t;
if (!z) { z = BN_new (); BN_one (z); }
if (!t) { t = BN_new (); BN_mul (t, p.x, p.y, ctx); }
BN_sqr (x2, p.x, ctx); // x2 = A = x^2
BN_sqr (y2, p.y, ctx); // y2 = B = y^2
BN_sqr (t2, t, ctx);
BN_mul (t2, t2, d, ctx); // t2 = C = d*t^2
BN_sqr (z2, z, ctx); // z2 = D = z^2
BIGNUM * E = BN_new (), * F = BN_new (), * G = BN_new (), * H = BN_new ();
// E = (x+y)*(x+y)-A-B = x^2+y^2+2xy-A-B = 2xy
BN_mul (E, p.x, p.y, ctx);
BN_mul_word (E, 2); // E =2*x*y
BN_sub (F, z2, t2); // F = D - C
BN_add (G, z2, t2); // G = D + C
BN_add (H, y2, x2); // H = B + A
if (!p.z) BN_free (z);
if (!p.t) BN_free (t);
BN_mod_mul (x2, E, F, q, ctx); // x2 = E*F
BN_mod_mul (y2, G, H, q, ctx); // y2 = G*H
BN_mod_mul (z2, F, G, q, ctx); // z2 = F*G
BN_mod_mul (t2, E, H, q, ctx); // t2 = E*H
BN_free (E); BN_free (F); BN_free (G); BN_free (H);
return EDDSAPoint {x2, y2, z2, t2};
}
EDDSAPoint Mul (const EDDSAPoint& p, const BIGNUM * e, BN_CTX * ctx) const
{
BIGNUM * zero = BN_new (), * one = BN_new ();
BN_zero (zero); BN_one (one);
EDDSAPoint res {zero, one};
if (!BN_is_zero (e))
{
int bitCount = BN_num_bits (e);
for (int i = bitCount - 1; i >= 0; i--)
{
res = Double (res, ctx);
if (BN_is_bit_set (e, i)) res = Sum (res, p, ctx);
}
}
return res;
}
EDDSAPoint MulB (const uint8_t * e, BN_CTX * ctx) const // B*e. e is 32 bytes Little Endian
{
BIGNUM * zero = BN_new (), * one = BN_new ();
BN_zero (zero); BN_one (one);
EDDSAPoint res {zero, one};
for (int i = 0; i < 32; i++)
{
uint8_t x = e[i] & 0x0F; // 4 low bits
if (x > 0)
res = Sum (res, Bi16[i*2][x-1], ctx);
x = e[i] >> 4; // 4 high bits
if (x > 0)
res = Sum (res, Bi16[i*2+1][x-1], ctx);
}
return res;
}
EDDSAPoint Normalize (const EDDSAPoint& p, BN_CTX * ctx) const
{
if (p.z)
{
BIGNUM * x = BN_new (), * y = BN_new ();
BN_mod_inverse (y, p.z, q, ctx);
BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
return EDDSAPoint{x, y};
}
else
return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
}
bool IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const
{
BIGNUM * x2 = BN_new ();
BN_sqr (x2, p.x, ctx); // x^2
BIGNUM * y2 = BN_new ();
BN_sqr (y2, p.y, ctx); // y^2
// y^2 - x^2 - 1 - d*x^2*y^2
BIGNUM * tmp = BN_new ();
BN_mul (tmp, d, x2, ctx);
BN_mul (tmp, tmp, y2, ctx);
BN_sub (tmp, y2, tmp);
BN_sub (tmp, tmp, x2);
BN_sub_word (tmp, 1);
BN_mod (tmp, tmp, q, ctx); // % q
bool ret = BN_is_zero (tmp);
BN_free (x2);
BN_free (y2);
BN_free (tmp);
return ret;
}
BIGNUM * RecoverX (const BIGNUM * y, BN_CTX * ctx) const
{
BIGNUM * y2 = BN_new ();
BN_sqr (y2, y, ctx); // y^2
// xx = (y^2 -1)*inv(d*y^2 +1)
BIGNUM * xx = BN_new ();
BN_mul (xx, d, y2, ctx);
BN_add_word (xx, 1);
BN_mod_inverse (xx, xx, q, ctx);
BN_sub_word (y2, 1);
BN_mul (xx, y2, xx, ctx);
// x = srqt(xx) = xx^(2^252-2)
BIGNUM * x = BN_new ();
BN_mod_exp (x, xx, two_252_2, q, ctx);
// check (x^2 -xx) % q
BN_sqr (y2, x, ctx);
BN_mod_sub (y2, y2, xx, q, ctx);
if (!BN_is_zero (y2))
BN_mod_mul (x, x, I, q, ctx);
if (BN_is_odd (x))
BN_sub (x, q, x);
BN_free (y2);
BN_free (xx);
return x;
}
EDDSAPoint DecodePoint (const uint8_t * buf, BN_CTX * ctx) const
{
// buf is 32 bytes Little Endian, convert it to Big Endian
uint8_t buf1[EDDSA25519_PUBLIC_KEY_LENGTH];
for (size_t i = 0; i < EDDSA25519_PUBLIC_KEY_LENGTH/2; i++) // invert bytes
{
buf1[i] = buf[EDDSA25519_PUBLIC_KEY_LENGTH -1 - i];
buf1[EDDSA25519_PUBLIC_KEY_LENGTH -1 - i] = buf[i];
}
bool isHighestBitSet = buf1[0] & 0x80;
if (isHighestBitSet)
buf1[0] &= 0x7f; // clear highest bit
BIGNUM * y = BN_new ();
BN_bin2bn (buf1, EDDSA25519_PUBLIC_KEY_LENGTH, y);
auto x = RecoverX (y, ctx);
if (BN_is_bit_set (x, 0) != isHighestBitSet)
BN_sub (x, q, x); // x = q - x
EDDSAPoint p {x, y};
if (!IsOnCurve (p, ctx))
LogPrint (eLogError, "Decoded point is not on 25519");
return p;
}
void EncodePoint (const EDDSAPoint& p, uint8_t * buf) const
{
EncodeBN (p.y, buf,EDDSA25519_PUBLIC_KEY_LENGTH);
if (BN_is_bit_set (p.x, 0)) // highest bit
buf[EDDSA25519_PUBLIC_KEY_LENGTH - 1] |= 0x80; // set highest bit
}
template<int len>
BIGNUM * DecodeBN (const uint8_t * buf) const
{
// buf is Little Endian convert it to Big Endian
uint8_t buf1[len];
for (size_t i = 0; i < len/2; i++) // invert bytes
{
buf1[i] = buf[len -1 - i];
buf1[len -1 - i] = buf[i];
}
BIGNUM * res = BN_new ();
BN_bin2bn (buf1, len, res);
return res;
}
void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const
{
bn2buf (bn, buf, len);
// To Little Endian
for (size_t i = 0; i < len/2; i++) // invert bytes
{
uint8_t tmp = buf[i];
buf[i] = buf[len -1 - i];
buf[len -1 - i] = tmp;
}
}
private:
BIGNUM * q, * l, * d, * I;
EDDSAPoint B; // base point
// transient values
BIGNUM * two_252_2; // 2^252-2
EDDSAPoint Bi16[64][15]; // per 4-bits, Bi16[i][j] = (16+j+1)^i*B, we don't store zeroes
};
static std::unique_ptr<Ed25519> g_Ed25519;
std::unique_ptr<Ed25519>& GetEd25519 ()
{
if (!g_Ed25519)
g_Ed25519.reset (new Ed25519 ());
return g_Ed25519;
}
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey):
m_Ctx (BN_CTX_new ()),
m_PublicKey (GetEd25519 ()->DecodePublicKey (signingKey, m_Ctx))
{
memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH);
}
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
SHA512_CTX ctx;
SHA512_Init (&ctx);
SHA512_Update (&ctx, signature, EDDSA25519_SIGNATURE_LENGTH/2); // R
SHA512_Update (&ctx, m_PublicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
SHA512_Update (&ctx, buf, len); // data
uint8_t digest[64];
SHA512_Final (digest, &ctx);
return GetEd25519 ()->Verify (m_PublicKey, digest, signature, m_Ctx);
}
EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey):
m_Ctx (BN_CTX_new ())
{
// expand key
SHA512 (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH, m_ExpandedPrivateKey);
m_ExpandedPrivateKey[0] &= 0xF8; // drop last 3 bits
m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0x1F; // drop first 3 bits
m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] |= 0x40; // set second bit
// generate and encode public key
auto publicKey = GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, m_Ctx);
GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, m_Ctx);
}
void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature, m_Ctx);
}
}
}

View File

@ -1,895 +0,0 @@
#include <openssl/rand.h>
#include "Log.h"
#include "RouterInfo.h"
#include "RouterContext.h"
#include "Tunnel.h"
#include "Timestamp.h"
#include "Destination.h"
#include "Streaming.h"
namespace i2p
{
namespace stream
{
Stream::Stream (boost::asio::io_service& service, StreamingDestination& local,
std::shared_ptr<const i2p::data::LeaseSet> remote, int port): m_Service (service),
m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1),
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service),
m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port),
m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO),
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0)
{
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
m_RemoteIdentity = remote->GetIdentity ();
m_CurrentRemoteLease.endDate = 0;
}
Stream::Stream (boost::asio::io_service& service, StreamingDestination& local):
m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1),
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service),
m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE),
m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0)
{
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
}
Stream::~Stream ()
{
Terminate ();
while (!m_ReceiveQueue.empty ())
{
auto packet = m_ReceiveQueue.front ();
m_ReceiveQueue.pop ();
delete packet;
}
for (auto it: m_SentPackets)
delete it;
m_SentPackets.clear ();
for (auto it: m_SavedPackets)
delete it;
m_SavedPackets.clear ();
LogPrint (eLogDebug, "Stream deleted");
}
void Stream::Terminate ()
{
m_AckSendTimer.cancel ();
m_ReceiveTimer.cancel ();
m_ResendTimer.cancel ();
if (m_SendHandler)
{
auto handler = m_SendHandler;
m_SendHandler = nullptr;
handler (boost::asio::error::make_error_code (boost::asio::error::operation_aborted));
}
}
void Stream::HandleNextPacket (Packet * packet)
{
m_NumReceivedBytes += packet->GetLength ();
if (!m_SendStreamID)
m_SendStreamID = packet->GetReceiveStreamID ();
if (!packet->IsNoAck ()) // ack received
ProcessAck (packet);
int32_t receivedSeqn = packet->GetSeqn ();
bool isSyn = packet->IsSYN ();
if (!receivedSeqn && !isSyn)
{
// plain ack
LogPrint (eLogDebug, "Plain ACK received");
delete packet;
return;
}
LogPrint (eLogDebug, "Received seqn=", receivedSeqn);
if (isSyn || receivedSeqn == m_LastReceivedSequenceNumber + 1)
{
// we have received next in sequence message
ProcessPacket (packet);
// we should also try stored messages if any
for (auto it = m_SavedPackets.begin (); it != m_SavedPackets.end ();)
{
if ((*it)->GetSeqn () == (uint32_t)(m_LastReceivedSequenceNumber + 1))
{
Packet * savedPacket = *it;
m_SavedPackets.erase (it++);
ProcessPacket (savedPacket);
}
else
break;
}
// schedule ack for last message
if (m_Status == eStreamStatusOpen)
{
if (!m_IsAckSendScheduled)
{
m_IsAckSendScheduled = true;
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ACK_SEND_TIMEOUT));
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
shared_from_this (), std::placeholders::_1));
}
}
else if (isSyn)
// we have to send SYN back to incoming connection
SendBuffer (); // also sets m_IsOpen
}
else
{
if (receivedSeqn <= m_LastReceivedSequenceNumber)
{
// we have received duplicate
LogPrint (eLogWarning, "Duplicate message ", receivedSeqn, " received");
SendQuickAck (); // resend ack for previous message again
delete packet; // packet dropped
}
else
{
LogPrint (eLogWarning, "Missing messages from ", m_LastReceivedSequenceNumber + 1, " to ", receivedSeqn - 1);
// save message and wait for missing message again
SavePacket (packet);
if (m_LastReceivedSequenceNumber >= 0)
{
// send NACKs for missing messages ASAP
if (m_IsAckSendScheduled)
{
m_IsAckSendScheduled = false;
m_AckSendTimer.cancel ();
}
SendQuickAck ();
}
else
{
// wait for SYN
m_IsAckSendScheduled = true;
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ACK_SEND_TIMEOUT));
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
shared_from_this (), std::placeholders::_1));
}
}
}
}
void Stream::SavePacket (Packet * packet)
{
m_SavedPackets.insert (packet);
}
void Stream::ProcessPacket (Packet * packet)
{
// process flags
uint32_t receivedSeqn = packet->GetSeqn ();
uint16_t flags = packet->GetFlags ();
LogPrint (eLogDebug, "Process seqn=", receivedSeqn, ", flags=", flags);
const uint8_t * optionData = packet->GetOptionData ();
if (flags & PACKET_FLAG_SYNCHRONIZE)
LogPrint (eLogDebug, "Synchronize");
if (flags & PACKET_FLAG_DELAY_REQUESTED)
{
optionData += 2;
}
if (flags & PACKET_FLAG_FROM_INCLUDED)
{
m_RemoteIdentity = std::make_shared<i2p::data::IdentityEx>(optionData, packet->GetOptionSize ());
optionData += m_RemoteIdentity->GetFullLen ();
LogPrint (eLogInfo, "From identity ", m_RemoteIdentity->GetIdentHash ().ToBase64 ());
if (!m_RemoteLeaseSet)
LogPrint (eLogDebug, "Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase64 ());
}
if (flags & PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED)
{
uint16_t maxPacketSize = bufbe16toh (optionData);
LogPrint (eLogDebug, "Max packet size ", maxPacketSize);
optionData += 2;
}
if (flags & PACKET_FLAG_SIGNATURE_INCLUDED)
{
LogPrint (eLogDebug, "Signature");
uint8_t signature[256];
auto signatureLen = m_RemoteIdentity->GetSignatureLen ();
memcpy (signature, optionData, signatureLen);
memset (const_cast<uint8_t *>(optionData), 0, signatureLen);
if (!m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature))
{
LogPrint (eLogError, "Signature verification failed");
Close ();
flags |= PACKET_FLAG_CLOSE;
}
memcpy (const_cast<uint8_t *>(optionData), signature, signatureLen);
optionData += signatureLen;
}
packet->offset = packet->GetPayload () - packet->buf;
if (packet->GetLength () > 0)
{
m_ReceiveQueue.push (packet);
m_ReceiveTimer.cancel ();
}
else
delete packet;
m_LastReceivedSequenceNumber = receivedSeqn;
if (flags & (PACKET_FLAG_CLOSE | PACKET_FLAG_RESET))
{
LogPrint (eLogInfo, (flags & PACKET_FLAG_RESET) ? "Reset" : "Closed");
m_Status = eStreamStatusReset;
Close ();
}
}
void Stream::ProcessAck (Packet * packet)
{
bool acknowledged = false;
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
uint32_t ackThrough = packet->GetAckThrough ();
int nackCount = packet->GetNACKCount ();
for (auto it = m_SentPackets.begin (); it != m_SentPackets.end ();)
{
auto seqn = (*it)->GetSeqn ();
if (seqn <= ackThrough)
{
if (nackCount > 0)
{
bool nacked = false;
for (int i = 0; i < nackCount; i++)
if (seqn == packet->GetNACK (i))
{
nacked = true;
break;
}
if (nacked)
{
LogPrint (eLogDebug, "Packet ", seqn, " NACK");
it++;
continue;
}
}
auto sentPacket = *it;
uint64_t rtt = ts - sentPacket->sendTime;
m_RTT = (m_RTT*seqn + rtt)/(seqn + 1);
m_RTO = m_RTT*1.5; // TODO: implement it better
LogPrint (eLogDebug, "Packet ", seqn, " acknowledged rtt=", rtt);
m_SentPackets.erase (it++);
delete sentPacket;
acknowledged = true;
if (m_WindowSize < WINDOW_SIZE)
m_WindowSize++; // slow start
else
{
// linear growth
if (ts > m_LastWindowSizeIncreaseTime + m_RTT)
{
m_WindowSize++;
if (m_WindowSize > MAX_WINDOW_SIZE) m_WindowSize = MAX_WINDOW_SIZE;
m_LastWindowSizeIncreaseTime = ts;
}
}
}
else
break;
}
if (m_SentPackets.empty ())
m_ResendTimer.cancel ();
if (acknowledged)
{
m_NumResendAttempts = 0;
SendBuffer ();
}
if (m_Status == eStreamStatusClosing)
Close (); // all outgoing messages have been sent
}
size_t Stream::Send (const uint8_t * buf, size_t len)
{
if (len > 0 && buf)
{
std::unique_lock<std::mutex> l(m_SendBufferMutex);
m_SendBuffer.clear ();
m_SendBuffer.write ((const char *)buf, len);
}
m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ()));
return len;
}
void Stream::AsyncSend (const uint8_t * buf, size_t len, SendHandler handler)
{
if (m_SendHandler)
handler (boost::asio::error::make_error_code (boost::asio::error::in_progress));
else
m_SendHandler = handler;
Send (buf, len);
}
void Stream::SendBuffer ()
{
int numMsgs = m_WindowSize - m_SentPackets.size ();
if (numMsgs <= 0) return; // window is full
bool isNoAck = m_LastReceivedSequenceNumber < 0; // first packet
std::vector<Packet *> packets;
{
std::unique_lock<std::mutex> l(m_SendBufferMutex);
while ((m_Status == eStreamStatusNew) || (IsEstablished () && !m_SendBuffer.eof () && numMsgs > 0))
{
Packet * p = new Packet ();
uint8_t * packet = p->GetBuffer ();
// TODO: implement setters
size_t size = 0;
htobe32buf (packet + size, m_SendStreamID);
size += 4; // sendStreamID
htobe32buf (packet + size, m_RecvStreamID);
size += 4; // receiveStreamID
htobe32buf (packet + size, m_SequenceNumber++);
size += 4; // sequenceNum
if (isNoAck)
htobe32buf (packet + size, m_LastReceivedSequenceNumber);
else
htobuf32 (packet + size, 0);
size += 4; // ack Through
packet[size] = 0;
size++; // NACK count
packet[size] = m_RTO/1000;
size++; // resend delay
if (m_Status == eStreamStatusNew)
{
// initial packet
m_Status = eStreamStatusOpen;
uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED |
PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED;
if (isNoAck) flags |= PACKET_FLAG_NO_ACK;
htobe16buf (packet + size, flags);
size += 2; // flags
size_t identityLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetFullLen ();
size_t signatureLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetSignatureLen ();
htobe16buf (packet + size, identityLen + signatureLen + 2); // identity + signature + packet size
size += 2; // options size
m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen);
size += identityLen; // from
htobe16buf (packet + size, STREAMING_MTU);
size += 2; // max packet size
uint8_t * signature = packet + size; // set it later
memset (signature, 0, signatureLen); // zeroes for now
size += signatureLen; // signature
m_SendBuffer.read ((char *)(packet + size), STREAMING_MTU - size);
size += m_SendBuffer.gcount (); // payload
m_LocalDestination.GetOwner ()->Sign (packet, size, signature);
}
else
{
// follow on packet
htobuf16 (packet + size, 0);
size += 2; // flags
htobuf16 (packet + size, 0); // no options
size += 2; // options size
m_SendBuffer.read((char *)(packet + size), STREAMING_MTU - size);
size += m_SendBuffer.gcount (); // payload
}
p->len = size;
packets.push_back (p);
numMsgs--;
}
if (m_SendBuffer.eof () && m_SendHandler)
{
m_SendHandler (boost::system::error_code ());
m_SendHandler = nullptr;
}
}
if (packets.size () > 0)
{
m_IsAckSendScheduled = false;
m_AckSendTimer.cancel ();
bool isEmpty = m_SentPackets.empty ();
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
for (auto it: packets)
{
it->sendTime = ts;
m_SentPackets.insert (it);
}
SendPackets (packets);
if (m_Status == eStreamStatusClosing && m_SendBuffer.eof ())
SendClose ();
if (isEmpty)
ScheduleResend ();
}
}
void Stream::SendQuickAck ()
{
int32_t lastReceivedSeqn = m_LastReceivedSequenceNumber;
if (!m_SavedPackets.empty ())
{
int32_t seqn = (*m_SavedPackets.rbegin ())->GetSeqn ();
if (seqn > lastReceivedSeqn) lastReceivedSeqn = seqn;
}
if (lastReceivedSeqn < 0)
{
LogPrint (eLogError, "No packets have been received yet");
return;
}
Packet p;
uint8_t * packet = p.GetBuffer ();
size_t size = 0;
htobe32buf (packet + size, m_SendStreamID);
size += 4; // sendStreamID
htobe32buf (packet + size, m_RecvStreamID);
size += 4; // receiveStreamID
htobuf32 (packet + size, 0); // this is plain Ack message
size += 4; // sequenceNum
htobe32buf (packet + size, lastReceivedSeqn);
size += 4; // ack Through
uint8_t numNacks = 0;
if (lastReceivedSeqn > m_LastReceivedSequenceNumber)
{
// fill NACKs
uint8_t * nacks = packet + size + 1;
auto nextSeqn = m_LastReceivedSequenceNumber + 1;
for (auto it: m_SavedPackets)
{
auto seqn = it->GetSeqn ();
if (numNacks + (seqn - nextSeqn) >= 256)
{
LogPrint (eLogError, "Number of NACKs exceeds 256. seqn=", seqn, " nextSeqn=", nextSeqn);
htobe32buf (packet + 12, nextSeqn); // change ack Through
break;
}
for (uint32_t i = nextSeqn; i < seqn; i++)
{
htobe32buf (nacks, i);
nacks += 4;
numNacks++;
}
nextSeqn = seqn + 1;
}
packet[size] = numNacks;
size++; // NACK count
size += numNacks*4; // NACKs
}
else
{
// No NACKs
packet[size] = 0;
size++; // NACK count
}
size++; // resend delay
htobuf16 (packet + size, 0); // nof flags set
size += 2; // flags
htobuf16 (packet + size, 0); // no options
size += 2; // options size
p.len = size;
SendPackets (std::vector<Packet *> { &p });
LogPrint ("Quick Ack sent. ", (int)numNacks, " NACKs");
}
void Stream::Close ()
{
switch (m_Status)
{
case eStreamStatusOpen:
m_Status = eStreamStatusClosing;
Close (); // recursion
if (m_Status == eStreamStatusClosing) //still closing
LogPrint (eLogInfo, "Trying to send stream data before closing");
break;
case eStreamStatusReset:
SendClose ();
Terminate ();
m_LocalDestination.DeleteStream (shared_from_this ());
break;
case eStreamStatusClosing:
if (m_SentPackets.empty () && m_SendBuffer.eof ()) // nothing to send
{
m_Status = eStreamStatusClosed;
SendClose ();
Terminate ();
m_LocalDestination.DeleteStream (shared_from_this ());
}
break;
case eStreamStatusClosed:
// already closed
Terminate ();
m_LocalDestination.DeleteStream (shared_from_this ());
break;
default:
LogPrint (eLogWarning, "Unexpected stream status ", (int)m_Status);
};
}
void Stream::SendClose ()
{
Packet * p = new Packet ();
uint8_t * packet = p->GetBuffer ();
size_t size = 0;
htobe32buf (packet + size, m_SendStreamID);
size += 4; // sendStreamID
htobe32buf (packet + size, m_RecvStreamID);
size += 4; // receiveStreamID
htobe32buf (packet + size, m_SequenceNumber++);
size += 4; // sequenceNum
htobe32buf (packet + size, m_LastReceivedSequenceNumber);
size += 4; // ack Through
packet[size] = 0;
size++; // NACK count
size++; // resend delay
htobe16buf (packet + size, PACKET_FLAG_CLOSE | PACKET_FLAG_SIGNATURE_INCLUDED);
size += 2; // flags
size_t signatureLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetSignatureLen ();
htobe16buf (packet + size, signatureLen); // signature only
size += 2; // options size
uint8_t * signature = packet + size;
memset (packet + size, 0, signatureLen);
size += signatureLen; // signature
m_LocalDestination.GetOwner ()->Sign (packet, size, signature);
p->len = size;
m_Service.post (std::bind (&Stream::SendPacket, shared_from_this (), p));
LogPrint ("FIN sent");
}
size_t Stream::ConcatenatePackets (uint8_t * buf, size_t len)
{
size_t pos = 0;
while (pos < len && !m_ReceiveQueue.empty ())
{
Packet * packet = m_ReceiveQueue.front ();
size_t l = std::min (packet->GetLength (), len - pos);
memcpy (buf + pos, packet->GetBuffer (), l);
pos += l;
packet->offset += l;
if (!packet->GetLength ())
{
m_ReceiveQueue.pop ();
delete packet;
}
}
return pos;
}
bool Stream::SendPacket (Packet * packet)
{
if (packet)
{
if (m_IsAckSendScheduled)
{
m_IsAckSendScheduled = false;
m_AckSendTimer.cancel ();
}
SendPackets (std::vector<Packet *> { packet });
if (m_Status == eStreamStatusOpen)
{
bool isEmpty = m_SentPackets.empty ();
m_SentPackets.insert (packet);
if (isEmpty)
ScheduleResend ();
}
else
delete packet;
return true;
}
else
return false;
}
void Stream::SendPackets (const std::vector<Packet *>& packets)
{
if (!m_RemoteLeaseSet)
{
UpdateCurrentRemoteLease ();
if (!m_RemoteLeaseSet)
{
LogPrint (eLogError, "Can't send packets. Missing remote LeaseSet");
return;
}
}
if (!m_CurrentOutboundTunnel || !m_CurrentOutboundTunnel->IsEstablished ())
m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNewOutboundTunnel (m_CurrentOutboundTunnel);
if (!m_CurrentOutboundTunnel)
{
LogPrint (eLogError, "No outbound tunnels in the pool");
return;
}
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
if (!m_CurrentRemoteLease.endDate || ts >= m_CurrentRemoteLease.endDate - i2p::tunnel::TUNNEL_EXPIRATION_THRESHOLD*1000)
UpdateCurrentRemoteLease (true);
if (ts < m_CurrentRemoteLease.endDate)
{
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
for (auto it: packets)
{
auto msg = m_RoutingSession->WrapSingleMessage (CreateDataMessage (it->GetBuffer (), it->GetLength ()));
msgs.push_back (i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeTunnel,
m_CurrentRemoteLease.tunnelGateway, m_CurrentRemoteLease.tunnelID,
msg
});
m_NumSentBytes += it->GetLength ();
}
m_CurrentOutboundTunnel->SendTunnelDataMsg (msgs);
}
else
LogPrint (eLogWarning, "All leases are expired");
}
void Stream::ScheduleResend ()
{
m_ResendTimer.cancel ();
m_ResendTimer.expires_from_now (boost::posix_time::milliseconds(m_RTO));
m_ResendTimer.async_wait (std::bind (&Stream::HandleResendTimer,
shared_from_this (), std::placeholders::_1));
}
void Stream::HandleResendTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
// check for resend attempts
if (m_NumResendAttempts >= MAX_NUM_RESEND_ATTEMPTS)
{
LogPrint (eLogWarning, "Stream packet was not ACKed after ", MAX_NUM_RESEND_ATTEMPTS, " attempts. Terminate");
m_Status = eStreamStatusReset;
Close ();
return;
}
// collect packets to resend
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
std::vector<Packet *> packets;
for (auto it : m_SentPackets)
{
if (ts >= it->sendTime + m_RTO)
{
it->sendTime = ts;
packets.push_back (it);
}
}
// select tunnels if necessary and send
if (packets.size () > 0)
{
m_NumResendAttempts++;
m_RTO *= 2;
switch (m_NumResendAttempts)
{
case 1: // congesion avoidance
m_WindowSize /= 2;
if (m_WindowSize < MIN_WINDOW_SIZE) m_WindowSize = MIN_WINDOW_SIZE;
break;
case 2:
m_RTO = INITIAL_RTO; // drop RTO to initial upon tunnels pair change first time
// no break here
case 4:
UpdateCurrentRemoteLease (); // pick another lease
LogPrint (eLogWarning, "Another remote lease has been selected for stream");
break;
case 3:
// pick another outbound tunnel
m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNextOutboundTunnel (m_CurrentOutboundTunnel);
LogPrint (eLogWarning, "Another outbound tunnel has been selected for stream");
break;
default: ;
}
SendPackets (packets);
}
ScheduleResend ();
}
}
void Stream::HandleAckSendTimer (const boost::system::error_code& ecode)
{
if (m_IsAckSendScheduled)
{
if (m_LastReceivedSequenceNumber < 0)
{
LogPrint (eLogWarning, "SYN has not been recived after ", ACK_SEND_TIMEOUT, " milliseconds after follow on. Terminate");
m_Status = eStreamStatusReset;
Close ();
return;
}
if (m_Status == eStreamStatusOpen)
SendQuickAck ();
m_IsAckSendScheduled = false;
}
}
void Stream::UpdateCurrentRemoteLease (bool expired)
{
if (!m_RemoteLeaseSet)
{
m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());
if (!m_RemoteLeaseSet)
LogPrint ("LeaseSet ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " not found");
}
if (m_RemoteLeaseSet)
{
if (!m_RoutingSession)
m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, 32);
auto leases = m_RemoteLeaseSet->GetNonExpiredLeases (false); // try without threshold first
if (leases.empty ())
{
expired = false;
m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); // time to re-request
leases = m_RemoteLeaseSet->GetNonExpiredLeases (true); // then with threshold
}
if (!leases.empty ())
{
bool updated = false;
if (expired)
{
for (auto it: leases)
if ((it.tunnelGateway == m_CurrentRemoteLease.tunnelGateway) && (it.tunnelID != m_CurrentRemoteLease.tunnelID))
{
m_CurrentRemoteLease = it;
updated = true;
break;
}
}
if (!updated)
{
uint32_t i = rand () % leases.size ();
if (m_CurrentRemoteLease.endDate && leases[i].tunnelID == m_CurrentRemoteLease.tunnelID)
// make sure we don't select previous
i = (i + 1) % leases.size (); // if so, pick next
m_CurrentRemoteLease = leases[i];
}
}
else
{
m_RemoteLeaseSet = nullptr;
m_CurrentRemoteLease.endDate = 0;
// re-request expired
}
}
else
m_CurrentRemoteLease.endDate = 0;
}
std::shared_ptr<I2NPMessage> Stream::CreateDataMessage (const uint8_t * payload, size_t len)
{
auto msg = ToSharedI2NPMessage (NewI2NPShortMessage ());
if (len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE)
m_LocalDestination.m_Deflator.SetCompressionLevel (Z_NO_COMPRESSION);
else
m_LocalDestination.m_Deflator.SetCompressionLevel (Z_DEFAULT_COMPRESSION);
uint8_t * buf = msg->GetPayload ();
buf += 4; // reserve for lengthlength
size_t size = m_LocalDestination.m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len);
if (size)
{
htobe32buf (msg->GetPayload (), size); // length
htobe16buf (buf + 4, m_LocalDestination.GetLocalPort ()); // source port
htobe16buf (buf + 6, m_Port); // destination port
buf[9] = i2p::client::PROTOCOL_TYPE_STREAMING; // streaming protocol
msg->len += size + 4;
msg->FillI2NPMessageHeader (eI2NPData);
}
else
msg = nullptr;
return msg;
}
StreamingDestination::StreamingDestination (std::shared_ptr<i2p::client::ClientDestination> owner, uint16_t localPort):
m_Owner (owner), m_LocalPort (localPort)
{
}
StreamingDestination::~StreamingDestination ()
{
}
void StreamingDestination::Start ()
{
}
void StreamingDestination::Stop ()
{
ResetAcceptor ();
{
std::unique_lock<std::mutex> l(m_StreamsMutex);
m_Streams.clear ();
}
}
void StreamingDestination::HandleNextPacket (Packet * packet)
{
uint32_t sendStreamID = packet->GetSendStreamID ();
if (sendStreamID)
{
auto it = m_Streams.find (sendStreamID);
if (it != m_Streams.end ())
it->second->HandleNextPacket (packet);
else
{
LogPrint ("Unknown stream sendStreamID=", sendStreamID);
delete packet;
}
}
else
{
if (packet->IsSYN () && !packet->GetSeqn ()) // new incoming stream
{
auto incomingStream = CreateNewIncomingStream ();
incomingStream->HandleNextPacket (packet);
if (m_Acceptor != nullptr)
m_Acceptor (incomingStream);
else
{
LogPrint ("Acceptor for incoming stream is not set");
DeleteStream (incomingStream);
}
}
else // follow on packet without SYN
{
uint32_t receiveStreamID = packet->GetReceiveStreamID ();
for (auto it: m_Streams)
if (it.second->GetSendStreamID () == receiveStreamID)
{
// found
it.second->HandleNextPacket (packet);
return;
}
// TODO: should queue it up
LogPrint ("Unknown stream receiveStreamID=", receiveStreamID);
delete packet;
}
}
}
std::shared_ptr<Stream> StreamingDestination::CreateNewOutgoingStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port)
{
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, port);
std::unique_lock<std::mutex> l(m_StreamsMutex);
m_Streams[s->GetRecvStreamID ()] = s;
return s;
}
std::shared_ptr<Stream> StreamingDestination::CreateNewIncomingStream ()
{
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this);
std::unique_lock<std::mutex> l(m_StreamsMutex);
m_Streams[s->GetRecvStreamID ()] = s;
return s;
}
void StreamingDestination::DeleteStream (std::shared_ptr<Stream> stream)
{
if (stream)
{
std::unique_lock<std::mutex> l(m_StreamsMutex);
auto it = m_Streams.find (stream->GetRecvStreamID ());
if (it != m_Streams.end ())
m_Streams.erase (it);
}
}
void StreamingDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len)
{
// unzip it
Packet * uncompressed = new Packet;
uncompressed->offset = 0;
uncompressed->len = m_Inflator.Inflate (buf, len, uncompressed->buf, MAX_PACKET_SIZE);
if (uncompressed->len)
HandleNextPacket (uncompressed);
else
delete uncompressed;
}
}
}

View File

@ -1,515 +0,0 @@
#include <openssl/dh.h>
#include "Log.h"
#include "Crypto.h"
#include "RouterContext.h"
#include "I2NPProtocol.h"
#include "NetDb.h"
#include "Transports.h"
using namespace i2p::data;
namespace i2p
{
namespace transport
{
DHKeysPairSupplier::DHKeysPairSupplier (int size):
m_QueueSize (size), m_IsRunning (false), m_Thread (nullptr)
{
}
DHKeysPairSupplier::~DHKeysPairSupplier ()
{
Stop ();
}
void DHKeysPairSupplier::Start ()
{
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&DHKeysPairSupplier::Run, this));
}
void DHKeysPairSupplier::Stop ()
{
m_IsRunning = false;
m_Acquired.notify_one ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = 0;
}
}
void DHKeysPairSupplier::Run ()
{
while (m_IsRunning)
{
int num;
while ((num = m_QueueSize - m_Queue.size ()) > 0)
CreateDHKeysPairs (num);
std::unique_lock<std::mutex> l(m_AcquiredMutex);
m_Acquired.wait (l); // wait for element gets aquired
}
}
void DHKeysPairSupplier::CreateDHKeysPairs (int num)
{
if (num > 0)
{
i2p::crypto::DHKeys dh;
for (int i = 0; i < num; i++)
{
auto pair = std::make_shared<i2p::crypto::DHKeys> ();
pair->GenerateKeys ();
std::unique_lock<std::mutex> l(m_AcquiredMutex);
m_Queue.push (pair);
}
}
}
std::shared_ptr<i2p::crypto::DHKeys> DHKeysPairSupplier::Acquire ()
{
if (!m_Queue.empty ())
{
std::unique_lock<std::mutex> l(m_AcquiredMutex);
auto pair = m_Queue.front ();
m_Queue.pop ();
m_Acquired.notify_one ();
return pair;
}
else // queue is empty, create new
{
auto pair = std::make_shared<i2p::crypto::DHKeys> ();
pair->GenerateKeys ();
return pair;
}
}
void DHKeysPairSupplier::Return (std::shared_ptr<i2p::crypto::DHKeys> pair)
{
std::unique_lock<std::mutex> l(m_AcquiredMutex);
m_Queue.push (pair);
}
Transports transports;
Transports::Transports ():
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), m_PeerCleanupTimer (m_Service),
m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_InBandwidth (0), m_OutBandwidth (0),
m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0)
{
}
Transports::~Transports ()
{
Stop ();
}
void Transports::Start ()
{
m_DHKeysPairSupplier.Start ();
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Transports::Run, this));
// create acceptors
auto addresses = context.GetRouterInfo ().GetAddresses ();
for (auto& address : addresses)
{
if (!m_NTCPServer)
{
m_NTCPServer = new NTCPServer (address.port);
m_NTCPServer->Start ();
}
if (address.transportStyle == RouterInfo::eTransportSSU && address.host.is_v4 ())
{
if (!m_SSUServer)
{
m_SSUServer = new SSUServer (address.port);
LogPrint ("Start listening UDP port ", address.port);
m_SSUServer->Start ();
DetectExternalIP ();
}
else
LogPrint ("SSU server already exists");
}
}
m_PeerCleanupTimer.expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
m_PeerCleanupTimer.async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
}
void Transports::Stop ()
{
m_PeerCleanupTimer.cancel ();
m_Peers.clear ();
if (m_SSUServer)
{
m_SSUServer->Stop ();
delete m_SSUServer;
m_SSUServer = nullptr;
}
if (m_NTCPServer)
{
m_NTCPServer->Stop ();
delete m_NTCPServer;
m_NTCPServer = nullptr;
}
m_DHKeysPairSupplier.Stop ();
m_IsRunning = false;
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
void Transports::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint ("Transports: ", ex.what ());
}
}
}
void Transports::UpdateBandwidth ()
{
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
if (m_LastBandwidthUpdateTime > 0)
{
auto delta = ts - m_LastBandwidthUpdateTime;
if (delta > 0)
{
m_InBandwidth = (m_TotalReceivedBytes - m_LastInBandwidthUpdateBytes)*1000/delta; // per second
m_OutBandwidth = (m_TotalSentBytes - m_LastOutBandwidthUpdateBytes)*1000/delta; // per second
}
}
m_LastBandwidthUpdateTime = ts;
m_LastInBandwidthUpdateBytes = m_TotalReceivedBytes;
m_LastOutBandwidthUpdateBytes = m_TotalSentBytes;
}
bool Transports::IsBandwidthExceeded () const
{
if (i2p::context.GetRouterInfo ().IsHighBandwidth ()) return false;
return std::max (m_InBandwidth, m_OutBandwidth) > LOW_BANDWIDTH_LIMIT;
}
void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr<i2p::I2NPMessage> msg)
{
SendMessages (ident, std::vector<std::shared_ptr<i2p::I2NPMessage> > {msg });
}
void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector<std::shared_ptr<i2p::I2NPMessage> >& msgs)
{
m_Service.post (std::bind (&Transports::PostMessages, this, ident, msgs));
}
void Transports::PostMessages (i2p::data::IdentHash ident, std::vector<std::shared_ptr<i2p::I2NPMessage> > msgs)
{
if (ident == i2p::context.GetRouterInfo ().GetIdentHash ())
{
// we send it to ourself
for (auto it: msgs)
i2p::HandleI2NPMessage (it);
return;
}
auto it = m_Peers.find (ident);
if (it == m_Peers.end ())
{
bool connected = false;
try
{
auto r = netdb.FindRouter (ident);
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
i2p::util::GetSecondsSinceEpoch () })).first;
connected = ConnectToPeer (ident, it->second);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Transports::PostMessages ", ex.what ());
}
if (!connected) return;
}
if (!it->second.sessions.empty ())
it->second.sessions.front ()->SendI2NPMessages (msgs);
else
{
for (auto it1: msgs)
it->second.delayedMessages.push_back (it1);
}
}
bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer)
{
if (peer.router) // we have RI already
{
if (!peer.numAttempts) // NTCP
{
peer.numAttempts++;
auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ());
if (address)
{
#if BOOST_VERSION >= 104900
if (!address->host.is_unspecified ()) // we have address now
#else
boost::system::error_code ecode;
address->host.to_string (ecode);
if (!ecode)
#endif
{
if (!peer.router->UsesIntroducer () && !peer.router->IsUnreachable ())
{
auto s = std::make_shared<NTCPSession> (*m_NTCPServer, peer.router);
m_NTCPServer->Connect (address->host, address->port, s);
return true;
}
}
else // we don't have address
{
if (address->addressString.length () > 0) // trying to resolve
{
LogPrint (eLogInfo, "Resolving ", address->addressString);
NTCPResolve (address->addressString, ident);
return true;
}
}
}
}
else if (peer.numAttempts == 1)// SSU
{
peer.numAttempts++;
if (m_SSUServer)
{
if (m_SSUServer->GetSession (peer.router))
return true;
}
}
LogPrint (eLogError, "No NTCP and SSU addresses available");
peer.Done ();
m_Peers.erase (ident);
return false;
}
else // otherwise request RI
{
LogPrint ("Router not found. Requested");
i2p::data::netdb.RequestDestination (ident, std::bind (
&Transports::RequestComplete, this, std::placeholders::_1, ident));
}
return true;
}
void Transports::RequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, const i2p::data::IdentHash& ident)
{
m_Service.post (std::bind (&Transports::HandleRequestComplete, this, r, ident));
}
void Transports::HandleRequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, const i2p::data::IdentHash& ident)
{
auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
{
if (r)
{
LogPrint ("Router found. Trying to connect");
it->second.router = r;
ConnectToPeer (ident, it->second);
}
else
{
LogPrint ("Router not found. Failed to send messages");
m_Peers.erase (it);
}
}
}
void Transports::NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident)
{
auto resolver = std::make_shared<boost::asio::ip::tcp::resolver>(m_Service);
resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""),
std::bind (&Transports::HandleNTCPResolve, this,
std::placeholders::_1, std::placeholders::_2, ident, resolver));
}
void Transports::HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
i2p::data::IdentHash ident, std::shared_ptr<boost::asio::ip::tcp::resolver> resolver)
{
auto it1 = m_Peers.find (ident);
if (it1 != m_Peers.end ())
{
auto& peer = it1->second;
if (!ecode && peer.router)
{
auto address = (*it).endpoint ().address ();
LogPrint (eLogInfo, (*it).host_name (), " has been resolved to ", address);
auto addr = peer.router->GetNTCPAddress ();
if (addr)
{
auto s = std::make_shared<NTCPSession> (*m_NTCPServer, peer.router);
m_NTCPServer->Connect (address, addr->port, s);
return;
}
}
LogPrint (eLogError, "Unable to resolve NTCP address: ", ecode.message ());
m_Peers.erase (it1);
}
}
void Transports::CloseSession (std::shared_ptr<const i2p::data::RouterInfo> router)
{
if (!router) return;
m_Service.post (std::bind (&Transports::PostCloseSession, this, router));
}
void Transports::PostCloseSession (std::shared_ptr<const i2p::data::RouterInfo> router)
{
auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (router) : nullptr;
if (ssuSession) // try SSU first
{
m_SSUServer->DeleteSession (ssuSession);
LogPrint ("SSU session closed");
}
// TODO: delete NTCP
}
void Transports::DetectExternalIP ()
{
if (m_SSUServer)
{
i2p::context.SetStatus (eRouterStatusTesting);
for (int i = 0; i < 5; i++)
{
auto router = i2p::data::netdb.GetRandomPeerTestRouter ();
if (router && router->IsSSU ())
m_SSUServer->GetSession (router, true); // peer test
else
{
// if not peer test capable routers found pick any
router = i2p::data::netdb.GetRandomRouter ();
if (router && router->IsSSU ())
m_SSUServer->GetSession (router); // no peer test
}
}
}
else
LogPrint (eLogError, "Can't detect external IP. SSU is not available");
}
void Transports::PeerTest ()
{
if (m_SSUServer)
{
bool statusChanged = false;
for (int i = 0; i < 5; i++)
{
auto router = i2p::data::netdb.GetRandomPeerTestRouter ();
if (router && router->IsSSU ())
{
if (!statusChanged)
{
statusChanged = true;
i2p::context.SetStatus (eRouterStatusTesting); // first time only
}
m_SSUServer->GetSession (router, true); // peer test
}
}
}
}
std::shared_ptr<i2p::crypto::DHKeys> Transports::GetNextDHKeysPair ()
{
return m_DHKeysPairSupplier.Acquire ();
}
void Transports::ReuseDHKeysPair (std::shared_ptr<i2p::crypto::DHKeys> pair)
{
m_DHKeysPairSupplier.Return (pair);
}
void Transports::PeerConnected (std::shared_ptr<TransportSession> session)
{
m_Service.post([session, this]()
{
if (!session->GetRemoteIdentity ()) return;
auto ident = session->GetRemoteIdentity ()->GetIdentHash ();
auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
{
it->second.sessions.push_back (session);
session->SendI2NPMessages (it->second.delayedMessages);
it->second.delayedMessages.clear ();
}
else // incoming connection
m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch () }));
});
}
void Transports::PeerDisconnected (std::shared_ptr<TransportSession> session)
{
m_Service.post([session, this]()
{
if (!session->GetRemoteIdentity ()) return;
auto ident = session->GetRemoteIdentity ()->GetIdentHash ();
auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
{
it->second.sessions.remove (session);
if (it->second.sessions.empty ()) // TODO: why?
{
if (it->second.delayedMessages.size () > 0)
ConnectToPeer (ident, it->second);
else
m_Peers.erase (it);
}
}
});
}
bool Transports::IsConnected (const i2p::data::IdentHash& ident) const
{
auto it = m_Peers.find (ident);
return it != m_Peers.end ();
}
void Transports::HandlePeerCleanupTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
auto ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_Peers.begin (); it != m_Peers.end (); )
{
if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT)
{
LogPrint (eLogError, "Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds");
it = m_Peers.erase (it);
}
else
it++;
}
UpdateBandwidth (); // TODO: use separate timer(s) for it
if (i2p::context.GetStatus () == eRouterStatusTesting) // if still testing, repeat peer test
DetectExternalIP ();
m_PeerCleanupTimer.expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
m_PeerCleanupTimer.async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
}
}
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const
{
if (!m_Peers.size ()) return nullptr;
auto it = m_Peers.begin ();
std::advance (it, rand () % m_Peers.size ());
return it != m_Peers.end () ? it->second.router : nullptr;
}
}
}

View File

@ -1,260 +0,0 @@
#include "I2PEndian.h"
#include <string.h>
#include <openssl/sha.h>
#include "Log.h"
#include "NetDb.h"
#include "I2NPProtocol.h"
#include "Transports.h"
#include "RouterContext.h"
#include "TunnelEndpoint.h"
namespace i2p
{
namespace tunnel
{
TunnelEndpoint::~TunnelEndpoint ()
{
}
void TunnelEndpoint::HandleDecryptedTunnelDataMsg (std::shared_ptr<I2NPMessage> msg)
{
m_NumReceivedBytes += TUNNEL_DATA_MSG_SIZE;
uint8_t * decrypted = msg->GetPayload () + 20; // 4 + 16
uint8_t * zero = (uint8_t *)memchr (decrypted + 4, 0, TUNNEL_DATA_ENCRYPTED_SIZE - 4); // witout 4-byte checksum
if (zero)
{
uint8_t * fragment = zero + 1;
// verify checksum
memcpy (msg->GetPayload () + TUNNEL_DATA_MSG_SIZE, msg->GetPayload () + 4, 16); // copy iv to the end
uint8_t hash[32];
SHA256(fragment, TUNNEL_DATA_MSG_SIZE -(fragment - msg->GetPayload ()) + 16, hash); // payload + iv
if (memcmp (hash, decrypted, 4))
{
LogPrint (eLogError, "TunnelMessage: checksum verification failed");
return;
}
// process fragments
while (fragment < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE)
{
uint8_t flag = fragment[0];
fragment++;
bool isFollowOnFragment = flag & 0x80, isLastFragment = true;
uint32_t msgID = 0;
int fragmentNum = 0;
TunnelMessageBlockEx m;
if (!isFollowOnFragment)
{
// first fragment
m.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03);
switch (m.deliveryType)
{
case eDeliveryTypeLocal: // 0
break;
case eDeliveryTypeTunnel: // 1
m.tunnelID = bufbe32toh (fragment);
fragment += 4; // tunnelID
m.hash = i2p::data::IdentHash (fragment);
fragment += 32; // hash
break;
case eDeliveryTypeRouter: // 2
m.hash = i2p::data::IdentHash (fragment);
fragment += 32; // to hash
break;
default:
;
}
bool isFragmented = flag & 0x08;
if (isFragmented)
{
// Message ID
msgID = bufbe32toh (fragment);
fragment += 4;
isLastFragment = false;
}
}
else
{
// follow on
msgID = bufbe32toh (fragment); // MessageID
fragment += 4;
fragmentNum = (flag >> 1) & 0x3F; // 6 bits
isLastFragment = flag & 0x01;
}
uint16_t size = bufbe16toh (fragment);
fragment += 2;
msg->offset = fragment - msg->buf;
msg->len = msg->offset + size;
if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE)
{
// this is not last message. we have to copy it
m.data = ToSharedI2NPMessage (NewI2NPShortMessage ());
m.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header
m.data->len += TUNNEL_GATEWAY_HEADER_SIZE;
*(m.data) = *msg;
}
else
m.data = msg;
if (!isFollowOnFragment && isLastFragment)
HandleNextMessage (m);
else
{
if (msgID) // msgID is presented, assume message is fragmented
{
if (!isFollowOnFragment) // create new incomlete message
{
m.nextFragmentNum = 1;
auto ret = m_IncompleteMessages.insert (std::pair<uint32_t, TunnelMessageBlockEx>(msgID, m));
if (ret.second)
HandleOutOfSequenceFragment (msgID, ret.first->second);
else
LogPrint (eLogError, "Incomplete message ", msgID, "already exists");
}
else
{
m.nextFragmentNum = fragmentNum;
HandleFollowOnFragment (msgID, isLastFragment, m);
}
}
else
LogPrint (eLogError, "Message is fragmented, but msgID is not presented");
}
fragment += size;
}
}
else
LogPrint (eLogError, "TunnelMessage: zero not found");
}
void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m)
{
auto fragment = m.data->GetBuffer ();
auto size = m.data->GetLength ();
auto it = m_IncompleteMessages.find (msgID);
if (it != m_IncompleteMessages.end())
{
auto& msg = it->second;
if (m.nextFragmentNum == msg.nextFragmentNum)
{
if (msg.data->len + size < I2NP_MAX_MESSAGE_SIZE) // check if message is not too long
{
if (msg.data->len + size > msg.data->maxLen)
{
LogPrint (eLogInfo, "Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough");
auto newMsg = ToSharedI2NPMessage (NewI2NPMessage ());
*newMsg = *(msg.data);
msg.data = newMsg;
}
memcpy (msg.data->buf + msg.data->len, fragment, size); // concatenate fragment
msg.data->len += size;
if (isLastFragment)
{
// message complete
HandleNextMessage (msg);
m_IncompleteMessages.erase (it);
}
else
{
msg.nextFragmentNum++;
HandleOutOfSequenceFragment (msgID, msg);
}
}
else
{
LogPrint (eLogError, "Fragment ", m.nextFragmentNum, " of message ", msgID, "exceeds max I2NP message size. Message dropped");
m_IncompleteMessages.erase (it);
}
}
else
{
LogPrint (eLogInfo, "Unexpected fragment ", (int)m.nextFragmentNum, " instead ", (int)msg.nextFragmentNum, " of message ", msgID, ". Saved");
AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data);
}
}
else
{
LogPrint (eLogInfo, "First fragment of message ", msgID, " not found. Saved");
AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data);
}
}
void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data)
{
auto it = m_OutOfSequenceFragments.find (msgID);
if (it == m_OutOfSequenceFragments.end ())
m_OutOfSequenceFragments.insert (std::pair<uint32_t, Fragment> (msgID, {fragmentNum, isLastFragment, data}));
}
void TunnelEndpoint::HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
{
auto it = m_OutOfSequenceFragments.find (msgID);
if (it != m_OutOfSequenceFragments.end ())
{
if (it->second.fragmentNum == msg.nextFragmentNum)
{
LogPrint (eLogInfo, "Out-of-sequence fragment ", (int)it->second.fragmentNum, " of message ", msgID, " found");
auto size = it->second.data->GetLength ();
if (msg.data->len + size > msg.data->maxLen)
{
LogPrint (eLogInfo, "Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough");
auto newMsg = ToSharedI2NPMessage (NewI2NPMessage ());
*newMsg = *(msg.data);
msg.data = newMsg;
}
memcpy (msg.data->buf + msg.data->len, it->second.data->GetBuffer (), size); // concatenate out-of-sync fragment
msg.data->len += size;
if (it->second.isLastFragment)
{
// message complete
HandleNextMessage (msg);
m_IncompleteMessages.erase (msgID);
}
else
msg.nextFragmentNum++;
m_OutOfSequenceFragments.erase (it);
}
}
}
void TunnelEndpoint::HandleNextMessage (const TunnelMessageBlock& msg)
{
LogPrint (eLogInfo, "TunnelMessage: handle fragment of ", msg.data->GetLength ()," bytes. Msg type ", (int)msg.data->GetTypeID ());
switch (msg.deliveryType)
{
case eDeliveryTypeLocal:
i2p::HandleI2NPMessage (msg.data);
break;
case eDeliveryTypeTunnel:
i2p::transport::transports.SendMessage (msg.hash, i2p::CreateTunnelGatewayMsg (msg.tunnelID, msg.data));
break;
case eDeliveryTypeRouter:
if (msg.hash == i2p::context.GetRouterInfo ().GetIdentHash ()) // check if message is sent to us
i2p::HandleI2NPMessage (msg.data);
else
{
// to somebody else
if (!m_IsInbound) // outbound transit tunnel
{
/* auto typeID = msg.data->GetTypeID ();
if (typeID == eI2NPDatabaseStore || typeID == eI2NPDatabaseSearchReply )
// catch RI or reply with new list of routers
i2p::data::netdb.PostI2NPMsg (msg.data);*/
i2p::transport::transports.SendMessage (msg.hash, msg.data);
}
else // we shouldn't send this message. possible leakage
LogPrint (eLogError, "Message to another router arrived from an inbound tunnel. Dropped");
}
break;
default:
LogPrint (eLogError, "TunnelMessage: Unknown delivery type ", (int)msg.deliveryType);
};
}
}
}

View File

@ -1,437 +0,0 @@
#include <algorithm>
#include <openssl/rand.h>
#include "I2PEndian.h"
#include "Crypto.h"
#include "Tunnel.h"
#include "NetDb.h"
#include "Timestamp.h"
#include "Garlic.h"
#include "Transports.h"
#include "Log.h"
#include "TunnelPool.h"
namespace i2p
{
namespace tunnel
{
TunnelPool::TunnelPool (i2p::garlic::GarlicDestination * localDestination, int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
m_LocalDestination (localDestination), m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true)
{
}
TunnelPool::~TunnelPool ()
{
DetachTunnels ();
}
void TunnelPool::SetExplicitPeers (std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers)
{
m_ExplicitPeers = explicitPeers;
if (m_ExplicitPeers)
{
int size = m_ExplicitPeers->size ();
if (m_NumInboundHops > size)
{
m_NumInboundHops = size;
LogPrint (eLogInfo, "Inbound tunnel length has beed adjusted to ", size, " for explicit peers");
}
if (m_NumOutboundHops > size)
{
m_NumOutboundHops = size;
LogPrint (eLogInfo, "Outbound tunnel length has beed adjusted to ", size, " for explicit peers");
}
m_NumInboundTunnels = 1;
m_NumOutboundTunnels = 1;
}
}
void TunnelPool::DetachTunnels ()
{
{
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
for (auto it: m_InboundTunnels)
it->SetTunnelPool (nullptr);
m_InboundTunnels.clear ();
}
{
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
for (auto it: m_OutboundTunnels)
it->SetTunnelPool (nullptr);
m_OutboundTunnels.clear ();
}
m_Tests.clear ();
}
void TunnelPool::TunnelCreated (std::shared_ptr<InboundTunnel> createdTunnel)
{
if (!m_IsActive) return;
{
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
m_InboundTunnels.insert (createdTunnel);
}
if (m_LocalDestination)
m_LocalDestination->SetLeaseSetUpdated ();
}
void TunnelPool::TunnelExpired (std::shared_ptr<InboundTunnel> expiredTunnel)
{
if (expiredTunnel)
{
expiredTunnel->SetTunnelPool (nullptr);
for (auto it: m_Tests)
if (it.second.second == expiredTunnel) it.second.second = nullptr;
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
m_InboundTunnels.erase (expiredTunnel);
}
}
void TunnelPool::TunnelCreated (std::shared_ptr<OutboundTunnel> createdTunnel)
{
if (!m_IsActive) return;
{
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
m_OutboundTunnels.insert (createdTunnel);
}
//CreatePairedInboundTunnel (createdTunnel);
}
void TunnelPool::TunnelExpired (std::shared_ptr<OutboundTunnel> expiredTunnel)
{
if (expiredTunnel)
{
expiredTunnel->SetTunnelPool (nullptr);
for (auto it: m_Tests)
if (it.second.first == expiredTunnel) it.second.first = nullptr;
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
m_OutboundTunnels.erase (expiredTunnel);
}
}
std::vector<std::shared_ptr<InboundTunnel> > TunnelPool::GetInboundTunnels (int num) const
{
std::vector<std::shared_ptr<InboundTunnel> > v;
int i = 0;
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
for (auto it : m_InboundTunnels)
{
if (i >= num) break;
if (it->IsEstablished ())
{
v.push_back (it);
i++;
}
}
return v;
}
std::shared_ptr<OutboundTunnel> TunnelPool::GetNextOutboundTunnel (std::shared_ptr<OutboundTunnel> excluded) const
{
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
return GetNextTunnel (m_OutboundTunnels, excluded);
}
std::shared_ptr<InboundTunnel> TunnelPool::GetNextInboundTunnel (std::shared_ptr<InboundTunnel> excluded) const
{
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
return GetNextTunnel (m_InboundTunnels, excluded);
}
template<class TTunnels>
typename TTunnels::value_type TunnelPool::GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const
{
if (tunnels.empty ()) return nullptr;
uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0;
typename TTunnels::value_type tunnel = nullptr;
for (auto it: tunnels)
{
if (it->IsEstablished () && it != excluded)
{
tunnel = it;
i++;
}
if (i > ind && tunnel) break;
}
if (!tunnel && excluded && excluded->IsEstablished ()) tunnel = excluded;
return tunnel;
}
std::shared_ptr<OutboundTunnel> TunnelPool::GetNewOutboundTunnel (std::shared_ptr<OutboundTunnel> old) const
{
if (old && old->IsEstablished ()) return old;
std::shared_ptr<OutboundTunnel> tunnel;
if (old)
{
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
for (auto it: m_OutboundTunnels)
if (it->IsEstablished () && old->GetEndpointIdentHash () == it->GetEndpointIdentHash ())
{
tunnel = it;
break;
}
}
if (!tunnel)
tunnel = GetNextOutboundTunnel ();
return tunnel;
}
void TunnelPool::CreateTunnels ()
{
int num = 0;
{
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
for (auto it : m_InboundTunnels)
if (it->IsEstablished ()) num++;
}
for (int i = num; i < m_NumInboundTunnels; i++)
CreateInboundTunnel ();
num = 0;
{
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
for (auto it : m_OutboundTunnels)
if (it->IsEstablished ()) num++;
}
for (int i = num; i < m_NumOutboundTunnels; i++)
CreateOutboundTunnel ();
}
void TunnelPool::TestTunnels ()
{
for (auto it: m_Tests)
{
LogPrint ("Tunnel test ", (int)it.first, " failed");
// if test failed again with another tunnel we consider it failed
if (it.second.first)
{
if (it.second.first->GetState () == eTunnelStateTestFailed)
{
it.second.first->SetState (eTunnelStateFailed);
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
m_OutboundTunnels.erase (it.second.first);
}
else
it.second.first->SetState (eTunnelStateTestFailed);
}
if (it.second.second)
{
if (it.second.second->GetState () == eTunnelStateTestFailed)
{
it.second.second->SetState (eTunnelStateFailed);
{
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
m_InboundTunnels.erase (it.second.second);
}
if (m_LocalDestination)
m_LocalDestination->SetLeaseSetUpdated ();
}
else
it.second.second->SetState (eTunnelStateTestFailed);
}
}
m_Tests.clear ();
// new tests
auto it1 = m_OutboundTunnels.begin ();
auto it2 = m_InboundTunnels.begin ();
while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ())
{
bool failed = false;
if ((*it1)->IsFailed ())
{
failed = true;
it1++;
}
if ((*it2)->IsFailed ())
{
failed = true;
it2++;
}
if (!failed)
{
uint32_t msgID;
RAND_bytes ((uint8_t *)&msgID, 4);
m_Tests[msgID] = std::make_pair (*it1, *it2);
(*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
CreateDeliveryStatusMsg (msgID));
it1++; it2++;
}
}
}
void TunnelPool::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{
if (m_LocalDestination)
m_LocalDestination->ProcessGarlicMessage (msg);
else
LogPrint (eLogWarning, "Local destination doesn't exist. Dropped");
}
void TunnelPool::ProcessDeliveryStatus (std::shared_ptr<I2NPMessage> msg)
{
const uint8_t * buf = msg->GetPayload ();
uint32_t msgID = bufbe32toh (buf);
buf += 4;
uint64_t timestamp = bufbe64toh (buf);
auto it = m_Tests.find (msgID);
if (it != m_Tests.end ())
{
// restore from test failed state if any
if (it->second.first->GetState () == eTunnelStateTestFailed)
it->second.first->SetState (eTunnelStateEstablished);
if (it->second.second->GetState () == eTunnelStateTestFailed)
it->second.second->SetState (eTunnelStateEstablished);
LogPrint ("Tunnel test ", it->first, " successive. ", i2p::util::GetMillisecondsSinceEpoch () - timestamp, " milliseconds");
m_Tests.erase (it);
}
else
{
if (m_LocalDestination)
m_LocalDestination->ProcessDeliveryStatusMessage (msg);
else
LogPrint (eLogWarning, "Local destination doesn't exist. Dropped");
}
}
std::shared_ptr<const i2p::data::RouterInfo> TunnelPool::SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const
{
bool isExploratory = (m_LocalDestination == &i2p::context); // TODO: implement it better
auto hop = isExploratory ? i2p::data::netdb.GetRandomRouter (prevHop):
i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop);
if (!hop || hop->GetProfile ()->IsBad ())
hop = i2p::data::netdb.GetRandomRouter ();
return hop;
}
bool TunnelPool::SelectPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers, bool isInbound)
{
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
auto prevHop = i2p::context.GetSharedRouterInfo ();
int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops;
if (i2p::transport::transports.GetNumPeers () > 25)
{
auto r = i2p::transport::transports.GetRandomPeer ();
if (r && !r->GetProfile ()->IsBad ())
{
prevHop = r;
peers.push_back (r->GetRouterIdentity ());
numHops--;
}
}
for (int i = 0; i < numHops; i++)
{
auto hop = SelectNextHop (prevHop);
if (!hop)
{
LogPrint (eLogError, "Can't select next hop");
return false;
}
prevHop = hop;
peers.push_back (hop->GetRouterIdentity ());
}
return true;
}
bool TunnelPool::SelectExplicitPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers, bool isInbound)
{
int size = m_ExplicitPeers->size ();
std::vector<int> peerIndicies;
for (int i = 0; i < size; i++) peerIndicies.push_back(i);
std::random_shuffle (peerIndicies.begin(), peerIndicies.end());
int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops;
for (int i = 0; i < numHops; i++)
{
auto& ident = (*m_ExplicitPeers)[peerIndicies[i]];
auto r = i2p::data::netdb.FindRouter (ident);
if (r)
peers.push_back (r->GetRouterIdentity ());
else
{
LogPrint (eLogInfo, "Can't find router for ", ident.ToBase64 ());
i2p::data::netdb.RequestDestination (ident);
return false;
}
}
return true;
}
void TunnelPool::CreateInboundTunnel ()
{
auto outboundTunnel = GetNextOutboundTunnel ();
if (!outboundTunnel)
outboundTunnel = tunnels.GetNextOutboundTunnel ();
LogPrint ("Creating destination inbound tunnel...");
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > peers;
if (SelectPeers (peers, true))
{
std::reverse (peers.begin (), peers.end ());
auto tunnel = tunnels.CreateTunnel<InboundTunnel> (std::make_shared<TunnelConfig> (peers), outboundTunnel);
tunnel->SetTunnelPool (shared_from_this ());
}
else
LogPrint (eLogError, "Can't create inbound tunnel. No peers available");
}
void TunnelPool::RecreateInboundTunnel (std::shared_ptr<InboundTunnel> tunnel)
{
auto outboundTunnel = GetNextOutboundTunnel ();
if (!outboundTunnel)
outboundTunnel = tunnels.GetNextOutboundTunnel ();
LogPrint ("Re-creating destination inbound tunnel...");
auto newTunnel = tunnels.CreateTunnel<InboundTunnel> (std::make_shared<TunnelConfig>(tunnel->GetPeers ()), outboundTunnel);
newTunnel->SetTunnelPool (shared_from_this());
}
void TunnelPool::CreateOutboundTunnel ()
{
auto inboundTunnel = GetNextInboundTunnel ();
if (!inboundTunnel)
inboundTunnel = tunnels.GetNextInboundTunnel ();
if (inboundTunnel)
{
LogPrint ("Creating destination outbound tunnel...");
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > peers;
if (SelectPeers (peers, false))
{
auto tunnel = tunnels.CreateTunnel<OutboundTunnel> (
std::make_shared<TunnelConfig> (peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()));
tunnel->SetTunnelPool (shared_from_this ());
}
else
LogPrint (eLogError, "Can't create outbound tunnel. No peers available");
}
else
LogPrint (eLogError, "Can't create outbound tunnel. No inbound tunnels found");
}
void TunnelPool::RecreateOutboundTunnel (std::shared_ptr<OutboundTunnel> tunnel)
{
auto inboundTunnel = GetNextInboundTunnel ();
if (!inboundTunnel)
inboundTunnel = tunnels.GetNextInboundTunnel ();
if (inboundTunnel)
{
LogPrint ("Re-creating destination outbound tunnel...");
auto newTunnel = tunnels.CreateTunnel<OutboundTunnel> (
std::make_shared<TunnelConfig> (tunnel->GetPeers (),
inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()));
newTunnel->SetTunnelPool (shared_from_this ());
}
else
LogPrint ("Can't re-create outbound tunnel. No inbound tunnels found");
}
void TunnelPool::CreatePairedInboundTunnel (std::shared_ptr<OutboundTunnel> outboundTunnel)
{
LogPrint (eLogInfo, "Creating paired inbound tunnel...");
auto tunnel = tunnels.CreateTunnel<InboundTunnel> (std::make_shared<TunnelConfig>(outboundTunnel->GetInvertedPeers ()), outboundTunnel);
tunnel->SetTunnelPool (shared_from_this ());
}
}
}

View File

@ -1,91 +0,0 @@
#ifndef TUNNEL_POOL__
#define TUNNEL_POOL__
#include <inttypes.h>
#include <set>
#include <vector>
#include <utility>
#include <mutex>
#include <memory>
#include "Identity.h"
#include "LeaseSet.h"
#include "RouterInfo.h"
#include "I2NPProtocol.h"
#include "TunnelBase.h"
#include "RouterContext.h"
#include "Garlic.h"
namespace i2p
{
namespace tunnel
{
class Tunnel;
class InboundTunnel;
class OutboundTunnel;
class TunnelPool: public std::enable_shared_from_this<TunnelPool> // per local destination
{
public:
TunnelPool (i2p::garlic::GarlicDestination * localDestination, int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels);
~TunnelPool ();
i2p::garlic::GarlicDestination * GetLocalDestination () const { return m_LocalDestination; };
void SetLocalDestination (i2p::garlic::GarlicDestination * destination) { m_LocalDestination = destination; };
void SetExplicitPeers (std::shared_ptr<std::vector<i2p::data::IdentHash> > explicitPeers);
void CreateTunnels ();
void TunnelCreated (std::shared_ptr<InboundTunnel> createdTunnel);
void TunnelExpired (std::shared_ptr<InboundTunnel> expiredTunnel);
void TunnelCreated (std::shared_ptr<OutboundTunnel> createdTunnel);
void TunnelExpired (std::shared_ptr<OutboundTunnel> expiredTunnel);
void RecreateInboundTunnel (std::shared_ptr<InboundTunnel> tunnel);
void RecreateOutboundTunnel (std::shared_ptr<OutboundTunnel> tunnel);
std::vector<std::shared_ptr<InboundTunnel> > GetInboundTunnels (int num) const;
std::shared_ptr<OutboundTunnel> GetNextOutboundTunnel (std::shared_ptr<OutboundTunnel> excluded = nullptr) const;
std::shared_ptr<InboundTunnel> GetNextInboundTunnel (std::shared_ptr<InboundTunnel> excluded = nullptr) const;
std::shared_ptr<OutboundTunnel> GetNewOutboundTunnel (std::shared_ptr<OutboundTunnel> old) const;
void TestTunnels ();
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
void ProcessDeliveryStatus (std::shared_ptr<I2NPMessage> msg);
bool IsActive () const { return m_IsActive; };
void SetActive (bool isActive) { m_IsActive = isActive; };
void DetachTunnels ();
private:
void CreateInboundTunnel ();
void CreateOutboundTunnel ();
void CreatePairedInboundTunnel (std::shared_ptr<OutboundTunnel> outboundTunnel);
template<class TTunnels>
typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const;
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const;
bool SelectPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& hops, bool isInbound);
bool SelectExplicitPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& hops, bool isInbound);
private:
i2p::garlic::GarlicDestination * m_LocalDestination;
int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels;
std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers;
mutable std::mutex m_InboundTunnelsMutex;
std::set<std::shared_ptr<InboundTunnel>, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first
mutable std::mutex m_OutboundTunnelsMutex;
std::set<std::shared_ptr<OutboundTunnel>, TunnelCreationTimeCmp> m_OutboundTunnels;
std::map<uint32_t, std::pair<std::shared_ptr<OutboundTunnel>, std::shared_ptr<InboundTunnel> > > m_Tests;
bool m_IsActive;
public:
// for HTTP only
const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; };
const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; };
};
}
}
#endif

247
UPnP.cpp
View File

@ -1,247 +0,0 @@
#ifdef USE_UPNP
#include <string>
#include <thread>
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#ifdef _WIN32
#include <windows.h>
#define dlsym GetProcAddress
#else
#include <dlfcn.h>
#endif
#include "Log.h"
#include "RouterContext.h"
#include "UPnP.h"
#include "NetDb.h"
#include "util.h"
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnpcommands.h>
// These are per-process and are safe to reuse for all threads
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int);
int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *,
const char *, const char *, const char *, const char *);
#else
/* miniupnpc 1.6 */
UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int, int, int *);
int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *,
const char *, const char *, const char *, const char *, const char *);
#endif
int (*UPNP_GetValidIGDFunc) (struct UPNPDev *, struct UPNPUrls *, struct IGDdatas *, char *, int);
int (*UPNP_GetExternalIPAddressFunc) (const char *, const char *, char *);
int (*UPNP_DeletePortMappingFunc) (const char *, const char *, const char *, const char *, const char *);
void (*freeUPNPDevlistFunc) (struct UPNPDev *);
void (*FreeUPNPUrlsFunc) (struct UPNPUrls *);
// Nice approach http://stackoverflow.com/a/21517513/673826
template<class M, typename F>
F GetKnownProcAddressImpl(M hmod, const char *name, F) {
auto proc = reinterpret_cast<F>(dlsym(hmod, name));
if (!proc) {
LogPrint("Error resolving ", name, " from UPNP library. This often happens if there is version mismatch!");
}
return proc;
}
#define GetKnownProcAddress(hmod, func) GetKnownProcAddressImpl(hmod, #func, func##Func);
namespace i2p
{
namespace transport
{
UPnP::UPnP () : m_Thread (nullptr) , m_IsModuleLoaded (false)
{
}
void UPnP::Stop ()
{
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
void UPnP::Start()
{
if (!m_IsModuleLoaded) {
#ifdef MAC_OSX
m_Module = dlopen ("libminiupnpc.dylib", RTLD_LAZY);
#elif _WIN32
m_Module = LoadLibrary ("miniupnpc.dll"); // official prebuilt binary, e.g., in upnpc-exe-win32-20140422.zip
#else
m_Module = dlopen ("libminiupnpc.so", RTLD_LAZY);
#endif
if (m_Module == NULL)
{
LogPrint ("Error loading UPNP library. This often happens if there is version mismatch!");
return;
}
else
{
upnpDiscoverFunc = GetKnownProcAddress (m_Module, upnpDiscover);
UPNP_GetValidIGDFunc = GetKnownProcAddress (m_Module, UPNP_GetValidIGD);
UPNP_GetExternalIPAddressFunc = GetKnownProcAddress (m_Module, UPNP_GetExternalIPAddress);
UPNP_AddPortMappingFunc = GetKnownProcAddress (m_Module, UPNP_AddPortMapping);
UPNP_DeletePortMappingFunc = GetKnownProcAddress (m_Module, UPNP_DeletePortMapping);
freeUPNPDevlistFunc = GetKnownProcAddress (m_Module, freeUPNPDevlist);
FreeUPNPUrlsFunc = GetKnownProcAddress (m_Module, FreeUPNPUrls);
if (upnpDiscoverFunc && UPNP_GetValidIGDFunc && UPNP_GetExternalIPAddressFunc && UPNP_AddPortMappingFunc &&
UPNP_DeletePortMappingFunc && freeUPNPDevlistFunc && FreeUPNPUrlsFunc)
m_IsModuleLoaded = true;
}
}
m_Thread = new std::thread (std::bind (&UPnP::Run, this));
}
UPnP::~UPnP ()
{
}
void UPnP::Run ()
{
for (auto& address : context.GetRouterInfo ().GetAddresses ())
{
if (!address.host.is_v6 ())
{
Discover ();
if (address.transportStyle == data::RouterInfo::eTransportSSU )
{
TryPortMapping (I2P_UPNP_UDP, address.port);
}
else if (address.transportStyle == data::RouterInfo::eTransportNTCP )
{
TryPortMapping (I2P_UPNP_TCP, address.port);
}
}
}
}
void UPnP::Discover ()
{
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0);
#else
/* miniupnpc 1.6 */
int nerror = 0;
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
#endif
int r;
r = UPNP_GetValidIGDFunc (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
if (r == 1)
{
r = UPNP_GetExternalIPAddressFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS)
{
LogPrint ("UPnP: UPNP_GetExternalIPAddress () returned ", r);
return;
}
else
{
if (m_externalIPAddress[0])
{
LogPrint ("UPnP: ExternalIPAddress = ", m_externalIPAddress);
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (m_externalIPAddress));
return;
}
else
{
LogPrint ("UPnP: GetExternalIPAddress failed.");
return;
}
}
}
}
void UPnP::TryPortMapping (int type, int port)
{
std::string strType, strPort (std::to_string (port));
switch (type)
{
case I2P_UPNP_TCP:
strType = "TCP";
break;
case I2P_UPNP_UDP:
default:
strType = "UDP";
}
int r;
std::string strDesc = "I2Pd";
try {
for (;;) {
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0);
#else
/* miniupnpc 1.6 */
r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0");
#endif
if (r!=UPNPCOMMAND_SUCCESS)
{
LogPrint ("AddPortMapping (", strPort.c_str () ,", ", strPort.c_str () ,", ", m_NetworkAddr, ") failed with code ", r);
return;
}
else
{
LogPrint ("UPnP Port Mapping successful. (", m_NetworkAddr ,":", strPort.c_str(), " type ", strType.c_str () ," -> ", m_externalIPAddress ,":", strPort.c_str() ,")");
return;
}
std::this_thread::sleep_for(std::chrono::minutes(20)); // c++11
//boost::this_thread::sleep_for(); // pre c++11
//sleep(20*60); // non-portable
}
}
catch (boost::thread_interrupted)
{
CloseMapping(type, port);
Close();
throw;
}
}
void UPnP::CloseMapping (int type, int port)
{
std::string strType, strPort (std::to_string (port));
switch (type)
{
case I2P_UPNP_TCP:
strType = "TCP";
break;
case I2P_UPNP_UDP:
default:
strType = "UDP";
}
int r = 0;
r = UPNP_DeletePortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0);
LogPrint ("UPNP_DeletePortMapping() returned : ", r, "\n");
}
void UPnP::Close ()
{
freeUPNPDevlistFunc (m_Devlist);
m_Devlist = 0;
FreeUPNPUrlsFunc (&m_upnpUrls);
#ifndef _WIN32
dlclose (m_Module);
#else
FreeLibrary (m_Module);
#endif
}
}
}
#endif

63
UPnP.h
View File

@ -1,63 +0,0 @@
#ifndef __UPNP_H__
#define __UPNP_H__
#ifdef USE_UPNP
#include <string>
#include <thread>
#include <miniupnpc/miniwget.h>
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
#include <boost/asio.hpp>
#include "util.h"
#define I2P_UPNP_TCP 1
#define I2P_UPNP_UDP 2
namespace i2p
{
namespace transport
{
class UPnP
{
public:
UPnP ();
~UPnP ();
void Close ();
void Start ();
void Stop ();
void Discover ();
void TryPortMapping (int type, int port);
void CloseMapping (int type, int port);
private:
void Run ();
std::thread * m_Thread;
struct UPNPUrls m_upnpUrls;
struct IGDdatas m_upnpData;
// For miniupnpc
char * m_MulticastIf = 0;
char * m_Minissdpdpath = 0;
struct UPNPDev * m_Devlist = 0;
char m_NetworkAddr[64];
char m_externalIPAddress[40];
bool m_IsModuleLoaded;
#ifndef _WIN32
void *m_Module;
#else
HINSTANCE m_Module;
#endif
};
}
}
#endif
#endif

14
Win32/.gitignore vendored
View File

@ -1,14 +0,0 @@
*
!*/
!*.h
!*.cpp
!*.bat
!*.sln
!*.vcproj
!*.vcxproj
!*.vcxproj.filters
!*.iss
!.gitignore

113
Win32/DaemonWin32.cpp Normal file
View File

@ -0,0 +1,113 @@
#include <thread>
#include <clocale>
#include "Config.h"
#include "Daemon.h"
#include "util.h"
#include "Log.h"
#ifdef _WIN32
#include "Win32/Win32Service.h"
#ifdef WIN32_APP
#include "Win32/Win32App.h"
#endif
namespace i2p
{
namespace util
{
bool DaemonWin32::init(int argc, char* argv[])
{
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
if (!Daemon_Singleton::init(argc, argv))
return false;
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
if (serviceControl == "install")
{
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
);
return false;
}
else if (serviceControl == "remove")
{
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
UninstallService(SERVICE_NAME);
return false;
}
if (isDaemon)
{
LogPrint(eLogDebug, "Daemon: running as service");
I2PService service(SERVICE_NAME);
if (!I2PService::Run(service))
{
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
return false;
}
return false;
}
else
LogPrint(eLogDebug, "Daemon: running as user");
return true;
}
bool DaemonWin32::start()
{
setlocale(LC_CTYPE, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
setlocale(LC_TIME, "C");
#ifdef WIN32_APP
if (!i2p::win32::StartWin32App ()) return false;
// override log
i2p::config::SetOption("log", std::string ("file"));
#endif
bool ret = Daemon_Singleton::start();
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
{
// TODO: find out where this garbage to console comes from
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
}
bool insomnia; i2p::config::GetOption("insomnia", insomnia);
if (insomnia)
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
return ret;
}
bool DaemonWin32::stop()
{
#ifdef WIN32_APP
i2p::win32::StopWin32App ();
#endif
return Daemon_Singleton::stop();
}
void DaemonWin32::run ()
{
#ifdef WIN32_APP
i2p::win32::RunWin32App ();
#else
while (running)
{
std::this_thread::sleep_for (std::chrono::seconds(1));
}
#endif
}
}
}
#endif //_WIN32

View File

@ -1,282 +0,0 @@
# NSIS Installer script. (Tested with NSIS 2.64 on Windows 7)
# Author: Mikal Villa (Meeh)
# Version: 1.1
Name PurpleI2P
RequestExecutionLevel highest
SetCompressor /SOLID lzma
ShowInstDetails show
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
!define VERSION 0.3.0.0
!define COMPANY "The Privacy Solutions Project"
!define URL "https://i2p.io"
# MUI Symbol Definitions
!define MUI_ICON "ictoopie.ico"
#!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_RIGHT
#!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp"
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup
!define MUI_STARTMENUPAGE_DEFAULTFOLDER PurpleI2P
!define MUI_FINISHPAGE_RUN $INSTDIR\i2pd.exe
!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\Readme.txt
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
# Included files
!include Sections.nsh
!include MUI2.nsh
!include nsDialogs.nsh
!include winmessages.nsh
!include logiclib.nsh
# Local included files
!include nsi\helper_readme.nsh
;!include nsi\servicelib.nsh
# Variables
Var StartMenuGroup
# Installer pages
# Execution flow of installer windows
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_README "../Readme.md"
!insertmacro MUI_PAGE_DIRECTORY
# Disabled for now. Use the bat
;Page custom mode_selection # Meeh's hack for installing and starting service.
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
# Uninstall pages
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
# Installer languages
!insertmacro MUI_LANGUAGE English
# Installer attributes
OutFile PurpleI2P-0.3.0.0-win32-setup.exe
InstallDir $PROGRAMFILES\PurpleI2P
CRCCheck on
XPStyle on
BrandingText " "
ShowInstDetails show
VIProductVersion 0.3.0.0
VIAddVersionKey ProductName PurpleI2P
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
VIAddVersionKey CompanyWebsite "${URL}"
VIAddVersionKey FileVersion "${VERSION}"
VIAddVersionKey FileDescription ""
VIAddVersionKey LegalCopyright ""
InstallDirRegKey HKCU "${REGKEY}" Path
ShowUninstDetails show
# Readme definitions
;--------------------------------
;Languages
;Set up install lang strings for 1st lang
${ReadmeLanguage} "${LANG_ENGLISH}" \
"Read Me" \
"Please review the following important information." \
"About $(^name):" \
"$\n Click on scrollbar arrows or press Page Down to review the entire text."
;Add 2nd language
!insertmacro MUI_LANGUAGE "Norwegian"
;set up install lang strings for second lang
${ReadmeLanguage} "${LANG_NORWEGIAN}" \
"Les meg!" \
"Vennligst les informasjonen om hvordan du skal bruke PurpleI2P." \
"Om $(^name):" \
"$\n Klikk på scrollbaren til høyre for å se hele innholdet."
;--------------------------------
# Installer sections
Section -Main SEC0000
SetOutPath $INSTDIR
SetOverwrite on
File /oname=i2pd.exe Release\i2pd.exe
File /oname=install_service.bat install_service.bat
File /oname=uninstall_service.bat uninstall_service.bat
File /oname=LICENSE.txt ..\LICENSE
File /oname=Readme.txt ..\README.md
SetOutPath $INSTDIR\src
File /r /x *.nsi /x *.rc /x *.exe /x *.obj /x *.nsh /x *.sln /x *.vcxproj /x *.tlog /x *.log /x *.res /x *.pdb /x *.suo /x *.opensdf /x *.filters /x *.sdf /x *.iss /x *.aps /x .gitignore /x *.o ../\*.*
SetOutPath $INSTDIR
RMDir /r /REBOOTOK $INSTDIR\src\.git # Remove git directory
RMDir /r /REBOOTOK $INSTDIR\src\Win32\Release # Removing release directory
RMDir /r /REBOOTOK $INSTDIR\src\Win32\nsi
WriteRegStr HKCU "${REGKEY}\Components" Main 1
SectionEnd
Section -post SEC0001
WriteRegStr HKCU "${REGKEY}" Path $INSTDIR
SetOutPath $INSTDIR
WriteUninstaller $INSTDIR\uninstall.exe
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
CreateDirectory $SMPROGRAMS\$StartMenuGroup
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk" $INSTDIR\i2pd.exe
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk" $INSTDIR\install_service.bat
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P Service.lnk" $INSTDIR\uninstall_service.bat
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk" $INSTDIR\uninstall.exe
!insertmacro MUI_STARTMENU_WRITE_END
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)"
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}"
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}"
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}"
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
WriteRegStr HKCR "i2pd" "URL Protocol" ""
WriteRegStr HKCR "i2pd" "" "URL:i2pd" # TODO: if a instance of own is found, relaunch with a proxyfied browser to open webage. (e.g i2pd://meeh.i2p)
WriteRegStr HKCR "i2pd\DefaultIcon" "" $INSTDIR\i2pd.exe
WriteRegStr HKCR "i2pd\shell\open\command" "" '"$INSTDIR\i2pd.exe" "%1"'
SectionEnd
# Macro for selecting uninstaller sections
!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID
Push $R0
ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}"
StrCmp $R0 1 0 next${UNSECTION_ID}
!insertmacro SelectSection "${UNSECTION_ID}"
GoTo done${UNSECTION_ID}
next${UNSECTION_ID}:
!insertmacro UnselectSection "${UNSECTION_ID}"
done${UNSECTION_ID}:
Pop $R0
!macroend
# Uninstaller sections
Section /o -un.Main UNSEC0000
Delete /REBOOTOK $INSTDIR\i2pd.exe
Delete /REBOOTOK $INSTDIR\LICENSE.txt
Delete /REBOOTOK $INSTDIR\Readme.txt
Delete /REBOOTOK $INSTDIR\install_service.bat
Delete /REBOOTOK $INSTDIR\uninstall_service.bat
RMDir /r /REBOOTOK $INSTDIR\src
DeleteRegValue HKCU "${REGKEY}\Components" Main
SectionEnd
Section -un.post UNSEC0001
DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)"
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk"
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk"
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk"
Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\UnInstall PurpleI2P Service.lnk"
Delete /REBOOTOK "$SMSTARTUP\PurpleI2P.lnk"
Delete /REBOOTOK $INSTDIR\uninstall.exe
Delete /REBOOTOK $INSTDIR\debug.log
DeleteRegValue HKCU "${REGKEY}" StartMenuGroup
DeleteRegValue HKCU "${REGKEY}" Path
DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components"
DeleteRegKey /IfEmpty HKCU "${REGKEY}"
DeleteRegKey HKCR "i2pd"
RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup
RmDir /REBOOTOK $INSTDIR
Push $R0
StrCpy $R0 $StartMenuGroup 1
StrCmp $R0 ">" no_smgroup
no_smgroup:
Pop $R0
SectionEnd
; var hwndExecModeRadio
; var hwndRunServiceNowRadio
; Function mode_selection
; nsDialogs::Create 1018
; Pop $0
; ${NSD_CreateLabel} 0 10 75% 20u "How would you like PurpleI2P (i2pd) to run?"
; Pop $0
; ${NSD_CreateRadioButton} 20 60 80% 25u "Service Mode"
; Pop $hwndExecModeRadio
; ${NSD_AddStyle} $hwndExecModeRadio ${WS_GROUP}
; ${NSD_CreateRadioButton} 20 90 80% 25u "Command line Mode"
; Pop $0
; ${NSD_CreateButton} 20 150 -40 14u "Do it!"
; Pop $0
; ${NSD_OnClick} $0 perform_mode
; nsDialogs::Show
; FunctionEnd
; Function start_now_selection
; nsDialogs::Create 1018
; Pop $0
; ${NSD_CreateLabel} 0 10 75% 20u "Enable the service now?"
; Pop $0
; ${NSD_CreateRadioButton} 20 60 80% 25u "Yes"
; Pop $hwndRunServiceNowRadio
; ${NSD_AddStyle} $hwndRunServiceNowRadio ${WS_GROUP}
; ${NSD_CreateRadioButton} 20 90 80% 25u "No"
; Pop $0
; ${NSD_CreateButton} 20 150 -40 14u "Do it!"
; Pop $0
; ${NSD_OnClick} $0 perform_mode
; nsDialogs::Show
; FunctionEnd
; Function perform_mode
; ${NSD_GetState} $hwndExecModeRadio $0
; ${If} $0 = ${BST_CHECKED}
; Call service_mode
; ${EndIF}
; FunctionEnd
; Function start_now
; ${NSD_GetState} $hwndRunServiceNowRadio $0
; ${If} $0 = ${BST_CHECKED}
; Call start_now_selection
; ${EndIF}
; FunctionEnd
; Function service_mode
; Push "create"
; Push "PurpleI2P Service"
; Push "$INSTDIR\i2pd.exe;autostart=1;display=PurpleI2P"
; Call Service
; Pop $0 ; Actually more to write than !insertmacro, but much more fun :D
; Push "start"
; Push "PurpleI2P Service"
; Call Service
; Pop $0
; Call start_now
; !define MUI_FINISHPAGE_RUN_NOTCHECKED
; !define MUI_FINISHPAGE_RUN_TEXT "No need to run now since we already installed and launched it as a Windows service!"
; FunctionEnd
# Installer functions
Function .onInit
InitPluginsDir
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
# Uninstaller functions
Function un.onInit
ReadRegStr $INSTDIR HKCU "${REGKEY}" Path
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
!insertmacro SELECT_UNSECTION Main ${UNSEC0000}
!insertmacro MUI_UNGETLANGUAGE
FunctionEnd

View File

@ -1,84 +0,0 @@
Building i2pd for Windows
=========================
Requirements for building:
* Visual Studio 2013 (tested with VS2013 Update 1, Update 3, and Update 4)
* Boost (tested with 1.56, 1.57, and 1.58)
* Crypto++ (tested with 5.6.2)
Building Boost (32-bit)
-----------------------
Open a Visual Studio x86 command prompt and run the following:
cd C:\path\to\boost\sources
bootstrap
b2 toolset=msvc-12.0 --build-type=complete --libdir=C:\Boost\lib\Win32 install --with-filesystem --with-program_options --with-regex --with-date_time
Building Boost (64-bit)
-----------------------
Open a Visual Studio x64 command prompt and run the following:
cd C:\path\to\boost\sources
bootstrap
b2 toolset=msvc-12.0 --build-type=complete --libdir=C:\Boost\lib\x64 architecture=x86 address-model=64 install --with-filesystem --with-program_options --with-regex --with-date_time
After Boost is compiled, set the environment variable `BOOST` to the directory
Boost was installed to. If you followed the instructions outlined here, you
should set it to `C:\Boost`. Additionally, set the BOOSTVER variable to the
version of Boost that you're using, but instead of a '.' use a '_'. For
example, I have `BOOSTVER` set to `1_58`.
Building Crypto++
-----------------
* Open the crypttest Solution in VS2013
* Visual Studio will ask to update the Solution/Project. Allow it.
* Build the `cryptopp` project, both the Debug and Release targets and for both
Win32 and x64.
* Create a folder called `cryptopp` in the crypto++ source directory, then copy
the header files to this new directory.
* Set the `CRYPTOPP` environment variable pointing to the Crypto++ source directory.
Building i2pd
-------------
## Prep work ##
I strongly advise setting up your own `INCLUDES` and `LIBS` instead of relying
on the settings in the i2pd project file. By using your own settings, if the
i2pd devs change the paths in the project file, your builds will still work.
To do this, create or edit the file
`%localappdata%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user`.
For comparison, my file is reproduced below:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<LibraryPath>$(CRYPTOPP)\$(Platform)\Output\$(Configuration);$(BOOST)\lib\$(Platform);$(LibraryPath)</LibraryPath>
<IncludePath>$(CRYPTOPP);$(BOOST)\include\boost-$(BOOSTVER);$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup />
<ItemGroup />
</Project>
If you want to build x64 binaries as well, you'll want to edit or create the
file `%localappdata%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.x64.user`. If you
followed the steps outlined earlier you can copy (or link) the win32 file to
the x64 one.
## Anti-Climatic End ##
After following the above instructions, you'll be able to build Debug Win32,
Debug x64, Release Win32, and Release x64 i2pd binaries.

Binary file not shown.

38
Win32/Resource.rc2 Normal file
View File

@ -0,0 +1,38 @@
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
#include "../libi2pd/version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Purple I2P"
VALUE "FileDescription", "C++ I2P daemon"
VALUE "FileVersion", I2PD_VERSION
VALUE "InternalName", CODENAME
VALUE "LegalCopyright", "Copyright (C) 2013-2017, The PurpleI2P Project"
VALUE "OriginalFilename", "i2pd"
VALUE "ProductName", "Purple I2P"
VALUE "ProductVersion", I2P_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

394
Win32/Win32App.cpp Normal file
View File

@ -0,0 +1,394 @@
#include <string.h>
#include <windows.h>
#include <shellapi.h>
#include "ClientContext.h"
#include "Config.h"
#include "NetDb.hpp"
#include "RouterContext.h"
#include "Transports.h"
#include "Tunnel.h"
#include "version.h"
#include "resource.h"
#include "Daemon.h"
#include "Win32App.h"
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define ID_ABOUT 2000
#define ID_EXIT 2001
#define ID_CONSOLE 2002
#define ID_APP 2003
#define ID_GRACEFUL_SHUTDOWN 2004
#define ID_STOP_GRACEFUL_SHUTDOWN 2005
#define ID_RELOAD 2006
#define ID_TRAY_ICON 2050
#define WM_TRAYICON (WM_USER + 1)
#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100
#define FRAME_UPDATE_TIMER 2101
namespace i2p
{
namespace win32
{
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
{
HMENU hPopup = CreatePopupMenu();
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload configs");
if (!i2p::util::DaemonWin32::Instance ().isGraceful)
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
else
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "&Stop graceful shutdown");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
POINT p;
if (!curpos)
{
GetCursorPos (&p);
curpos = &p;
}
WORD cmd = TrackPopupMenu (hPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, curpos->x, curpos->y, 0, hWnd, NULL);
SendMessage (hWnd, WM_COMMAND, cmd, 0);
DestroyMenu(hPopup);
}
static void AddTrayIcon (HWND hWnd)
{
NOTIFYICONDATA nid;
memset(&nid, 0, sizeof(nid));
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uID = ID_TRAY_ICON;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
nid.uCallbackMessage = WM_TRAYICON;
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON));
strcpy (nid.szTip, "i2pd");
strcpy (nid.szInfo, "i2pd is starting");
Shell_NotifyIcon(NIM_ADD, &nid );
}
static void RemoveTrayIcon (HWND hWnd)
{
NOTIFYICONDATA nid;
nid.hWnd = hWnd;
nid.uID = ID_TRAY_ICON;
Shell_NotifyIcon (NIM_DELETE, &nid);
}
static void ShowUptime (std::stringstream& s, int seconds)
{
int num;
if ((num = seconds / 86400) > 0) {
s << num << " days, ";
seconds -= num * 86400;
}
if ((num = seconds / 3600) > 0) {
s << num << " hours, ";
seconds -= num * 3600;
}
if ((num = seconds / 60) > 0) {
s << num << " min, ";
seconds -= num * 60;
}
s << seconds << " seconds\n";
}
template <typename size> static void ShowTransfered (std::stringstream& s, size transfer)
{
auto bytes = transfer & 0x03ff;
transfer >>= 10;
auto kbytes = transfer & 0x03ff;
transfer >>= 10;
auto mbytes = transfer & 0x03ff;
transfer >>= 10;
auto gbytes = transfer & 0x03ff;
if (gbytes)
s << gbytes << " GB, ";
if (mbytes)
s << mbytes << " MB, ";
if (kbytes)
s << kbytes << " KB, ";
s << bytes << " Bytes\n";
}
static void PrintMainWindowText (std::stringstream& s)
{
s << "\n";
s << "Status: ";
switch (i2p::context.GetStatus())
{
case eRouterStatusOK: s << "OK"; break;
case eRouterStatusTesting: s << "Testing"; break;
case eRouterStatusFirewalled: s << "Firewalled"; break;
case eRouterStatusError:
{
switch (i2p::context.GetError())
{
case eRouterErrorClockSkew: s << "Clock skew"; break;
default: s << "Error";
}
break;
}
default: s << "Unknown";
}
s << "; ";
s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n";
s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ());
s << "\n";
s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; ";
s << "Outbound: " << i2p::transport::transports.GetOutBandwidth() / 1024 << " KiB/s\n";
s << "Received: "; ShowTransfered (s, i2p::transport::transports.GetTotalReceivedBytes());
s << "Sent: "; ShowTransfered (s, i2p::transport::transports.GetTotalSentBytes());
s << "\n";
s << "Routers: " << i2p::data::netdb.GetNumRouters () << "; ";
s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << "; ";
s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "\n";
s << "Tunnels: ";
s << "In: " << i2p::tunnel::tunnels.CountInboundTunnels() << "; ";
s << "Out: " << i2p::tunnel::tunnels.CountOutboundTunnels() << "; ";
s << "Transit: " << i2p::tunnel::tunnels.CountTransitTunnels() << "\n";
s << "\n";
}
static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
AddTrayIcon (hWnd);
break;
}
case WM_CLOSE:
{
RemoveTrayIcon (hWnd);
KillTimer (hWnd, FRAME_UPDATE_TIMER);
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
PostQuitMessage (0);
break;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case ID_ABOUT:
{
std::stringstream text;
text << "Version: " << I2PD_VERSION << " " << CODENAME;
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
return 0;
}
case ID_EXIT:
{
PostMessage (hWnd, WM_CLOSE, 0, 0);
return 0;
}
case ID_GRACEFUL_SHUTDOWN:
{
i2p::context.SetAcceptsTunnels (false);
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
i2p::util::DaemonWin32::Instance ().isGraceful = true;
return 0;
}
case ID_STOP_GRACEFUL_SHUTDOWN:
{
i2p::context.SetAcceptsTunnels (true);
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
i2p::util::DaemonWin32::Instance ().isGraceful = false;
return 0;
}
case ID_RELOAD:
{
i2p::client::context.ReloadConfig();
std::stringstream text;
text << "I2Pd reloading configs...";
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
return 0;
}
case ID_CONSOLE:
{
char buf[30];
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort);
ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL);
return 0;
}
case ID_APP:
{
ShowWindow(hWnd, SW_SHOW);
SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL);
return 0;
}
}
break;
}
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_MINIMIZE:
{
ShowWindow(hWnd, SW_HIDE);
KillTimer (hWnd, FRAME_UPDATE_TIMER);
return 0;
}
case SC_CLOSE:
{
std::string close; i2p::config::GetOption("close", close);
if (0 == close.compare("ask"))
switch(::MessageBox(hWnd, "Would you like to minimize instead of exiting?"
" You can add 'close' configuration option. Valid values are: ask, minimize, exit.",
"Minimize instead of exiting?", MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON1))
{
case IDYES: close = "minimize"; break;
case IDNO: close = "exit"; break;
default: return 0;
}
if (0 == close.compare("minimize"))
{
ShowWindow(hWnd, SW_HIDE);
KillTimer (hWnd, FRAME_UPDATE_TIMER);
return 0;
}
if (0 != close.compare("exit"))
{
::MessageBox(hWnd, close.c_str(), "Unknown close action in config", MB_OK | MB_ICONWARNING);
return 0;
}
}
}
}
case WM_TRAYICON:
{
switch (lParam)
{
case WM_LBUTTONUP:
case WM_RBUTTONUP:
{
SetForegroundWindow (hWnd);
ShowPopupMenu(hWnd, NULL, -1);
PostMessage (hWnd, WM_APP + 1, 0, 0);
break;
}
}
break;
}
case WM_TIMER:
{
if (wParam == IDT_GRACEFUL_SHUTDOWN_TIMER)
{
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
return 0;
}
if (wParam == FRAME_UPDATE_TIMER)
{
InvalidateRect(hWnd, NULL, TRUE);
}
break;
}
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
RECT rp;
HFONT hFont;
std::stringstream s; PrintMainWindowText (s);
hDC = BeginPaint (hWnd, &ps);
GetClientRect(hWnd, &rp);
SetTextColor(hDC, 0x00D43B69);
hFont = CreateFont(18,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0,TEXT("Times New Roman"));
SelectObject(hDC,hFont);
DrawText(hDC, TEXT(s.str().c_str()), s.str().length(), &rp, DT_CENTER|DT_VCENTER);
DeleteObject(hFont);
EndPaint(hWnd, &ps);
break;
}
}
return DefWindowProc( hWnd, uMsg, wParam, lParam);
}
bool StartWin32App ()
{
if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")))
{
MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK);
return false;
}
// register main window
auto hInst = GetModuleHandle(NULL);
WNDCLASSEX wclx;
memset (&wclx, 0, sizeof(wclx));
wclx.cbSize = sizeof(wclx);
wclx.style = 0;
wclx.lpfnWndProc = WndProc;
//wclx.cbClsExtra = 0;
//wclx.cbWndExtra = 0;
wclx.hInstance = hInst;
wclx.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(MAINICON));
wclx.hCursor = LoadCursor (NULL, IDC_ARROW);
//wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wclx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wclx.lpszMenuName = NULL;
wclx.lpszClassName = I2PD_WIN32_CLASSNAME;
RegisterClassEx (&wclx);
// create new window
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 210, NULL, NULL, hInst, NULL))
{
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
return false;
}
return true;
}
int RunWin32App ()
{
MSG msg;
while (GetMessage (&msg, NULL, 0, 0 ))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
void StopWin32App ()
{
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
if (hWnd)
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0);
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
}
bool GracefulShutdown ()
{
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
if (hWnd)
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0);
return hWnd;
}
bool StopGracefulShutdown ()
{
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
if (hWnd)
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0);
return hWnd;
}
}
}

17
Win32/Win32App.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef WIN32APP_H__
#define WIN32APP_H__
#define I2PD_WIN32_CLASSNAME "i2pd main window"
namespace i2p
{
namespace win32
{
bool StartWin32App ();
void StopWin32App ();
int RunWin32App ();
bool GracefulShutdown ();
bool StopGracefulShutdown ();
}
}
#endif // WIN32APP_H__

View File

@ -7,15 +7,14 @@
#include <strsafe.h>
#include <windows.h>
#include "../Daemon.h"
#include "../Log.h"
#include "Daemon.h"
#include "Log.h"
I2PService *I2PService::s_service = NULL;
BOOL I2PService::isService()
{
BOOL bIsService = FALSE;
HWINSTA hWinStation = GetProcessWindowStation();
if (hWinStation != NULL)
{
@ -31,28 +30,23 @@ BOOL I2PService::isService()
BOOL I2PService::Run(I2PService &service)
{
s_service = &service;
SERVICE_TABLE_ENTRY serviceTable[] =
{
{ service.m_name, ServiceMain },
{ NULL, NULL }
};
return StartServiceCtrlDispatcher(serviceTable);
}
void WINAPI I2PService::ServiceMain(DWORD dwArgc, PSTR *pszArgv)
{
assert(s_service != NULL);
s_service->m_statusHandle = RegisterServiceCtrlHandler(
s_service->m_name, ServiceCtrlHandler);
if (s_service->m_statusHandle == NULL)
{
throw GetLastError();
}
s_service->Start(dwArgc, pszArgv);
}
@ -61,27 +55,23 @@ void WINAPI I2PService::ServiceCtrlHandler(DWORD dwCtrl)
{
switch (dwCtrl)
{
case SERVICE_CONTROL_STOP: s_service->Stop(); break;
case SERVICE_CONTROL_PAUSE: s_service->Pause(); break;
case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break;
case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break;
case SERVICE_CONTROL_INTERROGATE: break;
default: break;
case SERVICE_CONTROL_STOP: s_service->Stop(); break;
case SERVICE_CONTROL_PAUSE: s_service->Pause(); break;
case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break;
case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break;
case SERVICE_CONTROL_INTERROGATE: break;
default: break;
}
}
I2PService::I2PService(PSTR pszServiceName,
BOOL fCanStop,
BOOL fCanShutdown,
BOOL fCanPauseContinue)
{
m_name = (pszServiceName == NULL) ? "" : pszServiceName;
m_name = (pszServiceName == NULL) ? (PSTR)"" : pszServiceName;
m_statusHandle = NULL;
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
m_status.dwCurrentState = SERVICE_START_PENDING;
DWORD dwControlsAccepted = 0;
@ -91,16 +81,14 @@ I2PService::I2PService(PSTR pszServiceName,
dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
if (fCanPauseContinue)
dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
m_status.dwControlsAccepted = dwControlsAccepted;
m_status.dwControlsAccepted = dwControlsAccepted;
m_status.dwWin32ExitCode = NO_ERROR;
m_status.dwServiceSpecificExitCode = 0;
m_status.dwCheckPoint = 0;
m_status.dwWaitHint = 0;
m_fStopping = FALSE;
// Create a manual-reset event that is not signaled at first to indicate
// Create a manual-reset event that is not signaled at first to indicate
// the stopped signal of the service.
m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hStoppedEvent == NULL)
@ -109,7 +97,6 @@ I2PService::I2PService(PSTR pszServiceName,
}
}
I2PService::~I2PService(void)
{
if (m_hStoppedEvent)
@ -119,93 +106,73 @@ I2PService::~I2PService(void)
}
}
void I2PService::Start(DWORD dwArgc, PSTR *pszArgv)
{
try
{
SetServiceStatus(SERVICE_START_PENDING);
OnStart(dwArgc, pszArgv);
SetServiceStatus(SERVICE_RUNNING);
}
catch (DWORD dwError)
{
LogPrint("Win32Service Start", dwError);
LogPrint(eLogError, "Win32Service Start", dwError);
SetServiceStatus(SERVICE_STOPPED, dwError);
}
catch (...)
{
LogPrint("Win32Service failed to start.", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service failed to start.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_STOPPED);
}
}
void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv)
{
LogPrint("Win32Service in OnStart",
EVENTLOG_INFORMATION_TYPE);
LogPrint(eLogInfo, "Win32Service in OnStart", EVENTLOG_INFORMATION_TYPE);
Daemon.start();
//i2p::util::config::OptionParser(dwArgc, pszArgv);
//i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs);
//i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"),
// i2p::util::config::GetArg("-port", 17070));
_worker = new std::thread(std::bind(&I2PService::WorkerThread, this));
}
void I2PService::WorkerThread()
{
while (!m_fStopping)
{
::Sleep(1000); // Simulate some lengthy operations.
::Sleep(1000); // Simulate some lengthy operations.
}
// Signal the stopped event.
SetEvent(m_hStoppedEvent);
}
void I2PService::Stop()
{
DWORD dwOriginalState = m_status.dwCurrentState;
try
{
SetServiceStatus(SERVICE_STOP_PENDING);
OnStop();
SetServiceStatus(SERVICE_STOPPED);
}
catch (DWORD dwError)
{
LogPrint("Win32Service Stop", dwError);
LogPrint(eLogInfo, "Win32Service Stop", dwError);
SetServiceStatus(dwOriginalState);
}
catch (...)
{
LogPrint("Win32Service failed to stop.", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service failed to stop.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(dwOriginalState);
}
}
void I2PService::OnStop()
{
// Log a service stop message to the Application log.
LogPrint("Win32Service in OnStop", EVENTLOG_INFORMATION_TYPE);
LogPrint(eLogInfo, "Win32Service in OnStop", EVENTLOG_INFORMATION_TYPE);
Daemon.stop();
m_fStopping = TRUE;
if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
{
@ -215,102 +182,83 @@ void I2PService::OnStop()
delete _worker;
}
void I2PService::Pause()
{
try
{
SetServiceStatus(SERVICE_PAUSE_PENDING);
OnPause();
SetServiceStatus(SERVICE_PAUSED);
}
catch (DWORD dwError)
{
LogPrint("Win32Service Pause", dwError);
LogPrint(eLogError, "Win32Service Pause", dwError);
SetServiceStatus(SERVICE_RUNNING);
}
catch (...)
{
LogPrint("Win32Service failed to pause.", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service failed to pause.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_RUNNING);
}
}
void I2PService::OnPause()
{
}
void I2PService::Continue()
{
try
{
SetServiceStatus(SERVICE_CONTINUE_PENDING);
OnContinue();
SetServiceStatus(SERVICE_RUNNING);
}
catch (DWORD dwError)
{
LogPrint("Win32Service Continue", dwError);
LogPrint(eLogError, "Win32Service Continue", dwError);
SetServiceStatus(SERVICE_PAUSED);
}
catch (...)
{
LogPrint("Win32Service failed to resume.", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service failed to resume.", EVENTLOG_ERROR_TYPE);
SetServiceStatus(SERVICE_PAUSED);
}
}
void I2PService::OnContinue()
{
}
void I2PService::Shutdown()
{
try
{
OnShutdown();
SetServiceStatus(SERVICE_STOPPED);
}
catch (DWORD dwError)
{
LogPrint("Win32Service Shutdown", dwError);
LogPrint(eLogError, "Win32Service Shutdown", dwError);
}
catch (...)
{
LogPrint("Win32Service failed to shut down.", EVENTLOG_ERROR_TYPE);
LogPrint(eLogError, "Win32Service failed to shut down.", EVENTLOG_ERROR_TYPE);
}
}
void I2PService::OnShutdown()
{
}
void I2PService::SetServiceStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
m_status.dwCurrentState = dwCurrentState;
m_status.dwWin32ExitCode = dwWin32ExitCode;
m_status.dwWaitHint = dwWaitHint;
m_status.dwCheckPoint =
((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED)) ?
@ -335,12 +283,7 @@ void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService)
}
}
void InstallService(PSTR pszServiceName,
PSTR pszDisplayName,
DWORD dwStartType,
PSTR pszDependencies,
PSTR pszAccount,
PSTR pszPassword)
void InstallService(PCSTR pszServiceName, PCSTR pszDisplayName, DWORD dwStartType, PCSTR pszDependencies, PCSTR pszAccount, PCSTR pszPassword)
{
printf("Try to install Win32Service (%s).\n", pszServiceName);
@ -354,10 +297,10 @@ void InstallService(PSTR pszServiceName,
FreeHandles(schSCManager, schService);
return;
}
strncat(szPath, " --daemon", MAX_PATH);
// Open the local default service control manager database
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT |
SC_MANAGER_CREATE_SERVICE);
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
if (schSCManager == NULL)
{
printf("OpenSCManager failed w/err 0x%08lx\n", GetLastError());
@ -381,6 +324,7 @@ void InstallService(PSTR pszServiceName,
pszAccount, // Service running account
pszPassword // Password of the account
);
if (schService == NULL)
{
printf("CreateService failed w/err 0x%08lx\n", GetLastError());
@ -394,7 +338,7 @@ void InstallService(PSTR pszServiceName,
FreeHandles(schSCManager, schService);
}
void UninstallService(PSTR pszServiceName)
void UninstallService(PCSTR pszServiceName)
{
printf("Try to uninstall Win32Service (%s).\n", pszServiceName);
@ -412,8 +356,7 @@ void UninstallService(PSTR pszServiceName)
}
// Open the service with delete, stop, and query status permissions
schService = OpenService(schSCManager, pszServiceName, SERVICE_STOP |
SERVICE_QUERY_STATUS | DELETE);
schService = OpenService(schSCManager, pszServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE);
if (schService == NULL)
{
printf("OpenService failed w/err 0x%08lx\n", GetLastError());

View File

@ -4,13 +4,12 @@
#include <thread>
#include <windows.h>
#ifdef _WIN32
// Internal name of the service
#define SERVICE_NAME "i2pService"
#define SERVICE_NAME "i2pdService"
// Displayed name of the service
#define SERVICE_DISPLAY_NAME "i2p router service"
#define SERVICE_DISPLAY_NAME "i2pd router service"
// Service start options.
#define SERVICE_START_TYPE SERVICE_DEMAND_START
@ -25,7 +24,6 @@
#define SERVICE_PASSWORD NULL
#endif
class I2PService
{
public:
@ -72,13 +70,15 @@ private:
std::thread* _worker;
};
void InstallService(PSTR pszServiceName,
PSTR pszDisplayName,
void InstallService(
PCSTR pszServiceName,
PCSTR pszDisplayName,
DWORD dwStartType,
PSTR pszDependencies,
PSTR pszAccount,
PSTR pszPassword);
PCSTR pszDependencies,
PCSTR pszAccount,
PCSTR pszPassword
);
void UninstallService(PSTR pszServiceName);
void UninstallService(PCSTR pszServiceName);
#endif // WIN_32_SERVICE_H__

View File

@ -1,30 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "i2pd", "i2pd.vcxproj", "{930568EC-31C9-406A-AD1C-9636DF5D8FAA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.ActiveCfg = Debug|Win32
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Build.0 = Debug|Win32
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Deploy.0 = Debug|Win32
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.ActiveCfg = Debug|x64
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.Build.0 = Debug|x64
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.ActiveCfg = Release|Win32
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Build.0 = Release|Win32
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Deploy.0 = Release|Win32
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.ActiveCfg = Release|x64
{930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,292 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\AddressBook.cpp" />
<ClCompile Include="..\aes.cpp" />
<ClCompile Include="..\base64.cpp" />
<ClCompile Include="..\BOB.cpp" />
<ClCompile Include="..\CryptoConst.cpp" />
<ClCompile Include="..\Daemon.cpp" />
<ClCompile Include="..\DaemonWin32.cpp" />
<ClCompile Include="..\Garlic.cpp" />
<ClCompile Include="..\HTTPProxy.cpp" />
<ClCompile Include="..\HTTPServer.cpp" />
<ClCompile Include="..\I2NPProtocol.cpp" />
<ClCompile Include="..\i2p.cpp" />
<ClCompile Include="..\I2PEndian.cpp" />
<ClCompile Include="..\I2PService.cpp" />
<ClCompile Include="..\Identity.cpp" />
<ClCompile Include="..\LeaseSet.cpp" />
<ClCompile Include="..\Log.cpp" />
<ClCompile Include="..\NetDb.cpp" />
<ClCompile Include="..\NetDbRequests.cpp" />
<ClCompile Include="..\NTCPSession.cpp" />
<ClCompile Include="..\Profiling.cpp" />
<ClCompile Include="..\Reseed.cpp" />
<ClCompile Include="..\RouterContext.cpp" />
<ClCompile Include="..\RouterInfo.cpp" />
<ClCompile Include="..\Signature.cpp" />
<ClCompile Include="..\SAM.cpp" />
<ClCompile Include="..\SSU.cpp" />
<ClCompile Include="..\SSUData.cpp" />
<ClCompile Include="..\SSUSession.cpp" />
<ClCompile Include="..\Streaming.cpp" />
<ClCompile Include="..\Datagram.cpp" />
<ClCompile Include="..\Destination.cpp" />
<ClCompile Include="..\TransitTunnel.cpp" />
<ClCompile Include="..\Transports.cpp" />
<ClCompile Include="..\Tunnel.cpp" />
<ClCompile Include="..\TunnelEndpoint.cpp" />
<ClCompile Include="..\TunnelGateway.cpp" />
<ClCompile Include="..\TunnelPool.cpp" />
<ClCompile Include="..\UPnP.cpp" />
<ClCompile Include="..\util.cpp" />
<ClCompile Include="..\SOCKS.cpp" />
<ClCompile Include="..\I2PTunnel.cpp" />
<ClCompile Include="..\I2PControl.cpp" />
<ClCompile Include="..\ClientContext.cpp" />
<ClCompile Include="Win32Service.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\AddressBook.h" />
<ClInclude Include="..\base64.h" />
<ClInclude Include="..\BOB.h" />
<ClInclude Include="..\CryptoConst.h" />
<ClInclude Include="..\Daemon.h" />
<ClInclude Include="..\ElGamal.h" />
<ClInclude Include="..\Garlic.h" />
<ClInclude Include="..\HTTPProxy.h" />
<ClInclude Include="..\HTTPServer.h" />
<ClInclude Include="..\I2NPProtocol.h" />
<ClInclude Include="..\I2PEndian.h" />
<ClInclude Include="..\I2PService.h" />
<ClInclude Include="..\Identity.h" />
<ClInclude Include="..\LeaseSet.h" />
<ClInclude Include="..\LittleBigEndian.h" />
<ClInclude Include="..\Log.h" />
<ClInclude Include="..\NetDbRequests.h" />
<ClInclude Include="..\NetDb.h" />
<ClInclude Include="..\NTCPSession.h" />
<ClInclude Include="..\Queue.h" />
<ClInclude Include="..\Profiling.h" />
<ClInclude Include="..\Reseed.h" />
<ClInclude Include="..\RouterContext.h" />
<ClInclude Include="..\RouterInfo.h" />
<ClInclude Include="..\SAM.h" />
<ClInclude Include="..\SSU.h" />
<ClInclude Include="..\SSUData.h" />
<ClInclude Include="..\SSUSession.h" />
<ClInclude Include="..\Streaming.h" />
<ClInclude Include="..\Datagram.h" />
<ClInclude Include="..\Destination.h" />
<ClInclude Include="..\Timestamp.h" />
<ClInclude Include="..\TransitTunnel.h" />
<ClInclude Include="..\Transports.h" />
<ClInclude Include="..\Tunnel.h" />
<ClInclude Include="..\TunnelBase.h" />
<ClInclude Include="..\TunnelConfig.h" />
<ClInclude Include="..\TunnelEndpoint.h" />
<ClInclude Include="..\TunnelGateway.h" />
<ClInclude Include="..\TunnelPool.h" />
<ClInclude Include="..\UPnP.h" />
<ClInclude Include="..\util.h" />
<ClInclude Include="..\SOCKS.h" />
<ClInclude Include="..\I2PTunnel.h" />
<ClInclude Include="..\I2PControl.h" />
<ClInclude Include="..\version.h" />
<ClInclude Include="..\Signature.h" />
<ClInclude Include="..\ClientContext.h" />
<ClInclude Include="..\TransportSession.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Win32Service.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{930568EC-31C9-406A-AD1C-9636DF5D8FAA}</ProjectGuid>
<RootNamespace>i2pd</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>./..;$(IncludePath);$(BOOST);$(CRYPTOPP);C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\</IncludePath>
<LibraryPath>$(BOOST)\stage\lib;C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
<TargetName>$(ProjectName)_d</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>./..;$(IncludePath);$(BOOST);$(CRYPTOPP)</IncludePath>
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
<TargetName>$(ProjectName)_d</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>./..;$(IncludePath);$(BOOST);C:\build-lib\boost_1_57_0\;C:\build-lib</IncludePath>
<LibraryPath>C:\build-lib\boost_1_57_0\stage\lib;C:\build-lib\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>./..;$(IncludePath);$(BOOST);$(CRYPTOPP)</IncludePath>
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath)</LibraryPath>
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>_MBCS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
<Version>0.2</Version>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>_MBCS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
<Version>0.2</Version>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level2</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PreprocessorDefinitions>_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences>
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
<Version>
</Version>
<SubSystem>Console</SubSystem>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
</Link>
<Manifest>
<AssemblyIdentity>
</AssemblyIdentity>
<ComponentFileName>
</ComponentFileName>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PreprocessorDefinitions>_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences>
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
<Version>
</Version>
<SubSystem>Console</SubSystem>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
</Link>
<Manifest>
<AssemblyIdentity>
</AssemblyIdentity>
<ComponentFileName>
</ComponentFileName>
</Manifest>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,302 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Win32">
<UniqueIdentifier>{a880a08c-16b8-4243-82ea-6bfc63bb7dab}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\Identity.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\LeaseSet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Log.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\NetDb.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\NTCPSession.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\RouterContext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\RouterInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Streaming.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TransitTunnel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Transports.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Tunnel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TunnelEndpoint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TunnelGateway.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\base64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Garlic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\HTTPServer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\I2NPProtocol.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\i2p.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\I2PEndian.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SOCKS.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SSU.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Reseed.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\UPnP.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\HTTPProxy.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TunnelPool.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\AddressBook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Win32Service.cpp">
<Filter>Win32</Filter>
</ClCompile>
<ClCompile Include="..\Daemon.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\DaemonWin32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SSUData.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\CryptoConst.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\aes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\I2PTunnel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SAM.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SSUSession.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Datagram.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Destination.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ClientContext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\BOB.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\I2PControl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\I2PService.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Identity.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\LeaseSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\LittleBigEndian.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Log.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\NetDb.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\NTCPSession.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Queue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\RouterContext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\RouterInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Streaming.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Timestamp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TransitTunnel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Transports.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Tunnel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TunnelBase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TunnelConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TunnelEndpoint.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TunnelGateway.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\base64.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\CryptoConst.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ElGamal.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Garlic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\HTTPServer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\I2NPProtocol.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\I2PEndian.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SOCKS.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SSU.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Reseed.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\UPnP.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\HTTPProxy.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TunnelPool.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\AddressBook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Win32Service.h">
<Filter>Win32</Filter>
</ClInclude>
<ClInclude Include="..\Daemon.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SSUData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\I2PTunnel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Signature.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SAM.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\SSUSession.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Datagram.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Destination.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ClientContext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TransportSession.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\BOB.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\I2PControl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\I2PService.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resource.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

View File

@ -1,149 +0,0 @@
#define I2Pd_AppName "i2pd"
#define I2Pd_ver "0.2"
[Setup]
AppName={#I2Pd_AppName}
AppVersion={#I2Pd_ver}
DefaultDirName={pf}\I2Pd
DefaultGroupName=I2Pd
UninstallDisplayIcon={app}\I2Pd.exe
Compression=lzma2
SolidCompression=yes
OutputDir=.
LicenseFile=.\..\LICENSE
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
ArchitecturesInstallIn64BitMode=x64
[Files]
Source: "x64\Release\i2pd.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Check: Is64BitInstallMode
Source: "Release\i2pd.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode
Source: "..\README.md"; DestDir: "{app}"; DestName: "Readme.txt"; AfterInstall: ConvertLineEndings
[Icons]
Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe"
Name: "{group}\Readme"; Filename: "{app}\Readme.txt"
[Registry]
Root: HKCU; Subkey: "Environment"; ValueName: "Path"; ValueType: "string"; ValueData: "{app};{olddata}"; Check: NotOnPathAlready(); Flags: preservestringtype;
[Code]
var
DefaultTop,
DefaultLeft,
DefaultHeight,
DefaultBackTop,
DefaultNextTop,
DefaultCancelTop,
DefaultBevelTop,
DefaultOuterHeight: Integer;
const
LicenseHeight = 400;
LF = #10;
CR = #13;
CRLF = CR + LF;
procedure ConvertLineEndings();
var
FilePath : String;
FileContents : String;
begin
FilePath := ExpandConstant(CurrentFileName)
LoadStringFromFile(FilePath, FileContents);
StringChangeEx(FileContents, LF, CRLF, False);
SaveStringToFile(FilePath, FileContents, False);
end;
procedure InitializeWizard();
begin
DefaultTop := WizardForm.Top;
DefaultLeft := WizardForm.Left;
DefaultHeight := WizardForm.Height;
DefaultBackTop := WizardForm.BackButton.Top;
DefaultNextTop := WizardForm.NextButton.Top;
DefaultCancelTop := WizardForm.CancelButton.Top;
DefaultBevelTop := WizardForm.Bevel.Top;
DefaultOuterHeight := WizardForm.OuterNotebook.Height;
WizardForm.InnerPage.Height := WizardForm.InnerPage.Height + (LicenseHeight - DefaultHeight);
WizardForm.InnerNotebook.Height := WizardForm.InnerNotebook.Height + (LicenseHeight - DefaultHeight);
WizardForm.LicensePage.Height := WizardForm.LicensePage.Height + (LicenseHeight - DefaultHeight);
WizardForm.LicenseMemo.Height := WizardForm.LicenseMemo.Height + (LicenseHeight - DefaultHeight);
WizardForm.LicenseNotAcceptedRadio.Top := WizardForm.LicenseNotAcceptedRadio.Top + (LicenseHeight - DefaultHeight);
WizardForm.LicenseAcceptedRadio.Top := WizardForm.LicenseAcceptedRadio.Top + (LicenseHeight - DefaultHeight);
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpLicense then
begin
WizardForm.Top := DefaultTop - (LicenseHeight - DefaultHeight) div 2;
WizardForm.Height := LicenseHeight;
WizardForm.OuterNotebook.Height := WizardForm.OuterNotebook.Height + (LicenseHeight - DefaultHeight);
WizardForm.CancelButton.Top := DefaultCancelTop + (LicenseHeight - DefaultHeight);
WizardForm.NextButton.Top := DefaultNextTop + (LicenseHeight - DefaultHeight);
WizardForm.BackButton.Top := DefaultBackTop + (LicenseHeight - DefaultHeight);
WizardForm.Bevel.Top := DefaultBevelTop + (LicenseHeight - DefaultHeight);
end
else
begin
WizardForm.Top := DefaultTop;
WizardForm.Left := DefaultLeft;
WizardForm.Height := DefaultHeight;
WizardForm.OuterNotebook.Height := DefaultOuterHeight;
WizardForm.CancelButton.Top := DefaultCancelTop;
WizardForm.NextButton.Top := DefaultNextTop;
WizardForm.BackButton.Top := DefaultBackTop;
WizardForm.Bevel.Top := DefaultBevelTop;
end;
end;
function NotOnPathAlready(): Boolean;
var
BinDir, Path: String;
begin
Log('Checking if i2pd dir is already in the %PATH%');
if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path) then
begin // Successfully read the value
Log('HKCUEnvironmentPATH = ' + Path);
BinDir := ExpandConstant('{app}');
Log('Looking for i2pd dir in %PATH%: ' + BinDir + ' in ' + Path);
if Pos(LowerCase(BinDir), Lowercase(Path)) = 0 then
begin
Log('Did not find i2pd dir in %PATH% so I will add it');
Result := True;
end
else
begin
Log('Found i2pd dir in %PATH% so will not add it again');
Result := False;
end
end
else // The key probably doesn't exist
begin
Log('Could not access HKCUEnvironmentPATH so I assume that it is OK to add it');
Result := True;
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
BinDir, Path: String;
begin
if (CurUninstallStep = usPostUninstall)
and (RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path)) then
begin
BinDir := ExpandConstant('{app}');
if Pos(LowerCase(BinDir) + ';', Lowercase(Path)) <> 0 then
begin
StringChange(Path, BinDir + ';', '');
RegWriteStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path);
end;
end;
end;

View File

@ -1 +0,0 @@
i2pd --service=install

41
Win32/installer.iss Normal file
View File

@ -0,0 +1,41 @@
#define I2Pd_AppName "i2pd"
#define I2Pd_ver "2.21.0"
#define I2Pd_Publisher "PurpleI2P"
[Setup]
AppName={#I2Pd_AppName}
AppVersion={#I2Pd_ver}
AppPublisher={#I2Pd_Publisher}
DefaultDirName={pf}\I2Pd
DefaultGroupName=I2Pd
UninstallDisplayIcon={app}\I2Pd.exe
OutputDir=.
LicenseFile=../LICENSE
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
SetupIconFile=mask.ico
InternalCompressLevel=ultra64
Compression=lzma/ultra64
SolidCompression=true
ArchitecturesInstallIn64BitMode=x64
AppVerName={#I2Pd_AppName}
ExtraDiskSpaceRequired=15
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
AppPublisherURL=http://i2pd.website/
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
[Files]
Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64
Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64
Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist
Source: ..\contrib\i2pd.conf; 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\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
[Icons]
Name: {group}\I2Pd; Filename: {app}\i2pd.exe
Name: {group}\Readme; Filename: {app}\Readme.txt
[UninstallDelete]
Type: filesandordirs; Name: {app}

BIN
Win32/mask.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
Win32/mask.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

View File

@ -1,57 +0,0 @@
!verbose push
!verbose 3
!ifndef _MUI_EXTRAPAGES_NSH
!define _MUI_EXTRAPAGES_NSH
!ifmacrondef MUI_EXTRAPAGE_README & MUI_PAGE_README & MUI_UNPAGE_README & ReadmeLangStrings
!macro MUI_EXTRAPAGE_README UN ReadmeFile
!verbose push
!verbose 3
!define MUI_PAGE_HEADER_TEXT "$(${UN}ReadmeHeader)"
!define MUI_PAGE_HEADER_SUBTEXT "$(${UN}ReadmeSubHeader)"
!define MUI_LICENSEPAGE_TEXT_TOP "$(${UN}ReadmeTextTop)"
!define MUI_LICENSEPAGE_TEXT_BOTTOM "$(${UN}ReadmeTextBottom)"
!define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)"
!insertmacro MUI_${UN}PAGE_LICENSE "${ReadmeFile}"
!verbose pop
!macroend
!define ReadmeRun "!insertmacro MUI_EXTRAPAGE_README"
!macro MUI_PAGE_README ReadmeFile
!verbose push
!verbose 3
${ReadmeRun} "" "${ReadmeFile}"
!verbose pop
!macroend
!macro MUI_UNPAGE_README ReadmeFile
!verbose push
!verbose 3
${ReadmeRun} "UN" "${ReadmeFile}"
!verbose pop
!macroend
!macro ReadmeLangStrings UN MUI_LANG ReadmeHeader ReadmeSubHeader ReadmeTextTop ReadmeTextBottom
!verbose push
!verbose 3
LangString ${UN}ReadmeHeader ${MUI_LANG} "${ReadmeHeader}"
LangString ${UN}ReadmeSubHeader ${MUI_LANG} "${ReadmeSubHeader}"
LangString ${UN}ReadmeTextTop ${MUI_LANG} "${ReadmeTextTop}"
LangString ${UN}ReadmeTextBottom ${MUI_LANG} "${ReadmeTextBottom}"
!verbose pop
!macroend
!define ReadmeLanguage `!insertmacro ReadmeLangStrings ""`
!define Un.ReadmeLanguage `!insertmacro ReadmeLangStrings "UN"`
!endif
!endif
!verbose pop

View File

@ -1,419 +0,0 @@
; NSIS SERVICE LIBRARY - servicelib.nsh
; Version 1.8.1 - Jun 21th, 2013
; Questions/Comments - dselkirk@hotmail.com
;
; Description:
; Provides an interface to window services
;
; Inputs:
; action - systemlib action ie. create, delete, start, stop, pause,
; continue, installed, running, status
; name - name of service to manipulate
; param - action parameters; usage: var1=value1;var2=value2;...etc.
; (don't forget to add a ';' after the last value!)
;
; Actions:
; create - creates a new windows service
; Parameters:
; path - path to service executable
; autostart - automatically start with system ie. 1|0
; interact - interact with the desktop ie. 1|0
; depend - service dependencies
; user - user that runs the service
; password - password of the above user
; display - display name in service's console
; description - Description of service
; starttype - start type (supersedes autostart)
; servicetype - service type (supersedes interact)
;
; delete - deletes a windows service
; start - start a stopped windows service
; stop - stops a running windows service
; pause - pauses a running windows service
; continue - continues a paused windows service
; installed - is the provided service installed
; Parameters:
; action - if true then invokes the specified action
; running - is the provided service running
; Parameters:
; action - if true then invokes the specified action
; status - check the status of the provided service
;
; Usage:
; Method 1:
; Push "action"
; Push "name"
; Push "param"
; Call Service
; Pop $0 ;response
;
; Method 2:
; !insertmacro SERVICE "action" "name" "param"
;
; History:
; 1.0 - 09/15/2003 - Initial release
; 1.1 - 09/16/2003 - Changed &l to i, thx brainsucker
; 1.2 - 02/29/2004 - Fixed documentation.
; 1.3 - 01/05/2006 - Fixed interactive flag and pop order (Kichik)
; 1.4 - 12/07/2006 - Added display and depend, fixed datatypes (Vitoco)
; 1.5 - 06/25/2008 - Added description of service.(DeSafe.com/liuqixing#gmail.com)
; 1.5.1 - 06/12/2009 - Added use of __UNINSTALL__
; 1.6 - 08/02/2010 - Fixed description implementation (Anders)
; 1.7 - 04/11/2010 - Added get running service process id (Nico)
; 1.8 - 24/03/2011 - Added starttype and servicetype (Sergius)
; 1.8.1 - 21/06/2013 - Added dynamic ASCII & Unicode support (Zinthose)
!ifndef SERVICELIB
!define SERVICELIB
!define SC_MANAGER_ALL_ACCESS 0x3F
!define SC_STATUS_PROCESS_INFO 0x0
!define SERVICE_ALL_ACCESS 0xF01FF
!define SERVICE_CONTROL_STOP 1
!define SERVICE_CONTROL_PAUSE 2
!define SERVICE_CONTROL_CONTINUE 3
!define SERVICE_STOPPED 0x1
!define SERVICE_START_PENDING 0x2
!define SERVICE_STOP_PENDING 0x3
!define SERVICE_RUNNING 0x4
!define SERVICE_CONTINUE_PENDING 0x5
!define SERVICE_PAUSE_PENDING 0x6
!define SERVICE_PAUSED 0x7
!define SERVICE_KERNEL_DRIVER 0x00000001
!define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
!define SERVICE_WIN32_OWN_PROCESS 0x00000010
!define SERVICE_WIN32_SHARE_PROCESS 0x00000020
!define SERVICE_INTERACTIVE_PROCESS 0x00000100
!define SERVICE_BOOT_START 0x00000000
!define SERVICE_SYSTEM_START 0x00000001
!define SERVICE_AUTO_START 0x00000002
!define SERVICE_DEMAND_START 0x00000003
!define SERVICE_DISABLED 0x00000004
## Added by Zinthose for Native Unicode Support
!ifdef NSIS_UNICODE
!define APITAG "W"
!else
!define APITAG "A"
!endif
!macro SERVICE ACTION NAME PARAM
Push '${ACTION}'
Push '${NAME}'
Push '${PARAM}'
!ifdef __UNINSTALL__
Call un.Service
!else
Call Service
!endif
!macroend
!macro FUNC_GETPARAM
Push $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
Push $7
Exch 8
Pop $1 ;name
Exch 8
Pop $2 ;source
StrCpy $0 ""
StrLen $7 $2
StrCpy $3 0
lbl_loop:
IntCmp $3 $7 0 0 lbl_done
StrLen $4 "$1="
StrCpy $5 $2 $4 $3
StrCmp $5 "$1=" 0 lbl_next
IntOp $5 $3 + $4
StrCpy $3 $5
lbl_loop2:
IntCmp $3 $7 0 0 lbl_done
StrCpy $6 $2 1 $3
StrCmp $6 ";" 0 lbl_next2
IntOp $6 $3 - $5
StrCpy $0 $2 $6 $5
Goto lbl_done
lbl_next2:
IntOp $3 $3 + 1
Goto lbl_loop2
lbl_next:
IntOp $3 $3 + 1
Goto lbl_loop
lbl_done:
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Exch 2
Pop $6
Pop $7
Exch $0
!macroend
!macro CALL_GETPARAM VAR NAME DEFAULT LABEL
Push $1
Push ${NAME}
Call ${UN}GETPARAM
Pop $6
StrCpy ${VAR} "${DEFAULT}"
StrCmp $6 "" "${LABEL}" 0
StrCpy ${VAR} $6
!macroend
!macro FUNC_SERVICE UN
Push $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
Push $7
Exch 8
Pop $1 ;param
Exch 8
Pop $2 ;name
Exch 8
Pop $3 ;action
;$0 return
;$4 OpenSCManager
;$5 OpenService
StrCpy $0 "false"
System::Call 'advapi32::OpenSCManager${APITAG}(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.r4'
IntCmp $4 0 lbl_done
StrCmp $3 "create" lbl_create
System::Call 'advapi32::OpenService${APITAG}(i r4, t r2, i ${SERVICE_ALL_ACCESS}) i.r5'
IntCmp $5 0 lbl_done
lbl_select:
StrCmp $3 "delete" lbl_delete
StrCmp $3 "start" lbl_start
StrCmp $3 "stop" lbl_stop
StrCmp $3 "pause" lbl_pause
StrCmp $3 "continue" lbl_continue
StrCmp $3 "installed" lbl_installed
StrCmp $3 "running" lbl_running
StrCmp $3 "status" lbl_status
StrCmp $3 "processid" lbl_processid
Goto lbl_done
; create service
lbl_create:
Push $R1 ;depend
Push $R2 ;user
Push $R3 ;password
Push $R4 ;servicetype/interact
Push $R5 ;starttype/autostart
Push $R6 ;path
Push $R7 ;display
Push $R8 ;description
!insertmacro CALL_GETPARAM $R1 "depend" "n" "lbl_depend"
StrCpy $R1 't "$R1"'
lbl_depend:
StrCmp $R1 "n" 0 lbl_machine ;old name of depend param
!insertmacro CALL_GETPARAM $R1 "machine" "n" "lbl_machine"
StrCpy $R1 't "$R1"'
lbl_machine:
!insertmacro CALL_GETPARAM $R2 "user" "n" "lbl_user"
StrCpy $R2 't "$R2"'
lbl_user:
!insertmacro CALL_GETPARAM $R3 "password" "n" "lbl_password"
StrCpy $R3 't "$R3"'
lbl_password:
!insertmacro CALL_GETPARAM $R4 "interact" "${SERVICE_WIN32_OWN_PROCESS}" "lbl_interact"
StrCpy $6 ${SERVICE_WIN32_OWN_PROCESS}
IntCmp $R4 0 +2
IntOp $6 $6 | ${SERVICE_INTERACTIVE_PROCESS}
StrCpy $R4 $6
lbl_interact:
!insertmacro CALL_GETPARAM $R4 "servicetype" "$R4" "lbl_servicetype"
lbl_servicetype:
!insertmacro CALL_GETPARAM $R5 "autostart" "${SERVICE_DEMAND_START}" "lbl_autostart"
StrCpy $6 ${SERVICE_DEMAND_START}
IntCmp $R5 0 +2
StrCpy $6 ${SERVICE_AUTO_START}
StrCpy $R5 $6
lbl_autostart:
!insertmacro CALL_GETPARAM $R5 "starttype" "$R5" "lbl_starttype"
lbl_starttype:
!insertmacro CALL_GETPARAM $R6 "path" "n" "lbl_path"
lbl_path:
!insertmacro CALL_GETPARAM $R7 "display" "$2" "lbl_display"
lbl_display:
!insertmacro CALL_GETPARAM $R8 "description" "$2" "lbl_description"
lbl_description:
System::Call 'advapi32::CreateService${APITAG}(i r4, t r2, t R7, i ${SERVICE_ALL_ACCESS}, \
i R4, i R5, i 0, t R6, n, n, $R1, $R2, $R3) i.r6'
; write description of service (SERVICE_CONFIG_DESCRIPTION)
System::Call 'advapi32::ChangeServiceConfig2${APITAG}(ir6,i1,*t "$R8")i.R7'
strcmp $R7 "error" 0 lbl_descriptioncomplete
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\$2" "Description" $R8
lbl_descriptioncomplete:
Pop $R8
Pop $R7
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
StrCmp $6 0 lbl_done lbl_good
; delete service
lbl_delete:
System::Call 'advapi32::DeleteService(i r5) i.r6'
StrCmp $6 0 lbl_done lbl_good
; start service
lbl_start:
System::Call 'advapi32::StartService${APITAG}(i r5, i 0, i 0) i.r6'
StrCmp $6 0 lbl_done lbl_good
; stop service
lbl_stop:
Push $R1
System::Call '*(i,i,i,i,i,i,i) i.R1'
System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_STOP}, i $R1) i'
System::Free $R1
Pop $R1
StrCmp $6 0 lbl_done lbl_good
; pause service
lbl_pause:
Push $R1
System::Call '*(i,i,i,i,i,i,i) i.R1'
System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_PAUSE}, i $R1) i'
System::Free $R1
Pop $R1
StrCmp $6 0 lbl_done lbl_good
; continue service
lbl_continue:
Push $R1
System::Call '*(i,i,i,i,i,i,i) i.R1'
System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_CONTINUE}, i $R1) i'
System::Free $R1
Pop $R1
StrCmp $6 0 lbl_done lbl_good
; is installed
lbl_installed:
!insertmacro CALL_GETPARAM $7 "action" "" "lbl_good"
StrCpy $3 $7
Goto lbl_select
; is service running
lbl_running:
Push $R1
System::Call '*(i,i,i,i,i,i,i) i.R1'
System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i'
System::Call '*$R1(i, i.r6)'
System::Free $R1
Pop $R1
IntFmt $6 "0x%X" $6
StrCmp $6 ${SERVICE_RUNNING} 0 lbl_done
!insertmacro CALL_GETPARAM $7 "action" "" "lbl_good"
StrCpy $3 $7
Goto lbl_select
lbl_status:
Push $R1
System::Call '*(i,i,i,i,i,i,i) i.R1'
System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i'
System::Call '*$R1(i, i .r6)'
System::Free $R1
Pop $R1
IntFmt $6 "0x%X" $6
StrCpy $0 "running"
IntCmp $6 ${SERVICE_RUNNING} lbl_done
StrCpy $0 "stopped"
IntCmp $6 ${SERVICE_STOPPED} lbl_done
StrCpy $0 "start_pending"
IntCmp $6 ${SERVICE_START_PENDING} lbl_done
StrCpy $0 "stop_pending"
IntCmp $6 ${SERVICE_STOP_PENDING} lbl_done
StrCpy $0 "running"
IntCmp $6 ${SERVICE_RUNNING} lbl_done
StrCpy $0 "continue_pending"
IntCmp $6 ${SERVICE_CONTINUE_PENDING} lbl_done
StrCpy $0 "pause_pending"
IntCmp $6 ${SERVICE_PAUSE_PENDING} lbl_done
StrCpy $0 "paused"
IntCmp $6 ${SERVICE_PAUSED} lbl_done
StrCpy $0 "unknown"
Goto lbl_done
lbl_processid:
Push $R1
Push $R2
System::Call '*(i,i,i,i,i,i,i,i,i) i.R1'
System::Call '*(i 0) i.R2'
System::Call "advapi32::QueryServiceStatusEx(i r5, i ${SC_STATUS_PROCESS_INFO}, i $R1, i 36, i $R2) i"
System::Call "*$R1(i,i,i,i,i,i,i, i .r0)"
System::Free $R2
System::Free $R1
Pop $R2
Pop $R1
Goto lbl_done
lbl_good:
StrCpy $0 "true"
lbl_done:
IntCmp $5 0 +2
System::Call 'advapi32::CloseServiceHandle(i r5) n'
IntCmp $4 0 +2
System::Call 'advapi32::CloseServiceHandle(i r4) n'
Pop $4
Pop $3
Pop $2
Pop $1
Exch 3
Pop $5
Pop $7
Pop $6
Exch $0
!macroend
Function Service
!insertmacro FUNC_SERVICE ""
FunctionEnd
Function un.Service
!insertmacro FUNC_SERVICE "un."
FunctionEnd
Function GetParam
!insertmacro FUNC_GETPARAM
FunctionEnd
Function un.GetParam
!insertmacro FUNC_GETPARAM
FunctionEnd
!undef APITAG
!endif

Binary file not shown.

View File

@ -1 +0,0 @@
i2pd --service=remove

6
Win32/winres.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef WINRES_H__
#define WINRES_H__
#include <winresrc.h>
#endif

18
android/.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

57
android/AndroidManifest.xml Executable file
View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.purplei2p.i2pd"
android:installLocation="auto"
android:versionCode="1"
android:versionName="2.21.0">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="28" />
<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.ACCESS_NETWORK_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.FOREGROUND_SERVICE" /> <!-- required in API 26+ -->
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
>
<receiver android:name=".NetworkStateChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<activity
android:name=".I2PDPermsAskerActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".I2PDActivity"
android:label="@string/app_name" />
<service
android:name=".ForegroundService"
android:enabled="true" />
<activity
android:name=".I2PDPermsExplanationActivity"
android:label="@string/title_activity_i2_pdperms_asker_prompt"
android:parentActivityName=".I2PDPermsAskerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.purplei2p.i2pd.I2PDPermsAskerActivity" />
</activity>
</application>
</manifest>

1
android/assets/certificates Symbolic link
View File

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

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

@ -0,0 +1,81 @@
## 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
# 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/

74
android/build.gradle Normal file
View File

@ -0,0 +1,74 @@
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
}
apply plugin: 'com.android.application'
repositories {
jcenter()
maven {
url 'https://maven.google.com'
}
}
dependencies {
compile 'com.android.support:support-compat:28.0.0'
}
android {
compileSdkVersion 28
buildToolsVersion "28.0.1"
defaultConfig {
applicationId "org.purplei2p.i2pd"
targetSdkVersion 28
minSdkVersion 14
versionCode 1
versionName "2.21.0"
ndk {
abiFilters 'armeabi-v7a'
abiFilters 'x86'
}
externalNativeBuild {
ndkBuild {
arguments "-j4"
}
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
jniLibs.srcDirs = ['libs']
assets.srcDirs = ['assets']
}
}
signingConfigs {
orignal {
storeFile file("i2pdapk.jks")
storePassword "android"
keyAlias "i2pdapk"
keyPassword "android"
}
}
buildTypes {
release {
minifyEnabled true
signingConfig signingConfigs.orignal
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
externalNativeBuild {
ndkBuild {
path './jni/Android.mk'
}
}
}

96
android/build.xml Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="i2pd" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Insert sdk.dir=... into './local.properties'. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<fail
message="ndk.dir is missing. Insert ndk.dir=... into './local.properties'."
unless="ndk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

View File

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

73
android/jni/Android.mk Executable file
View File

@ -0,0 +1,73 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := i2pd
LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH)
LOCAL_STATIC_LIBRARIES := \
boost_system \
boost_date_time \
boost_filesystem \
boost_program_options \
crypto ssl \
miniupnpc
LOCAL_LDLIBS := -lz
LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
$(DAEMON_SRC_PATH)/Daemon.cpp \
$(DAEMON_SRC_PATH)/UPnP.cpp \
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
$(DAEMON_SRC_PATH)/I2PControl.cpp
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_system
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_64_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_64_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_date_time
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_64_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_filesystem
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_64_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_64_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_program_options
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_64_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1/$(TARGET_ARCH_ABI)/lib/libcrypto.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1/$(TARGET_ARCH_ABI)/lib/libssl.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1/include
LOCAL_STATIC_LIBRARIES := crypto
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := miniupnpc
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
include $(PREBUILT_STATIC_LIBRARY)

41
android/jni/Application.mk Executable file
View File

@ -0,0 +1,41 @@
#APP_ABI := all
APP_ABI := armeabi-v7a x86
#APP_ABI := x86
#APP_ABI := x86_64
#APP_ABI := armeabi-v7a
#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there.
APP_PLATFORM := android-14
# http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse
NDK_TOOLCHAIN_VERSION := 4.9
# APP_STL := stlport_shared --> does not seem to contain C++11 features
APP_STL := gnustl_shared
# Enable c++11 extensions in source code
APP_CPPFLAGS += -std=c++11
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
APP_CPPFLAGS += -DANDROID_ARM7A
endif
# Forcing debug optimization. Use `ndk-build NDK_DEBUG=1` instead.
#APP_OPTIM := debug
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
# change to your own
I2PD_LIBS_PATH = /path/to/libraries
BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt
OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt
MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
# don't change me
I2PD_SRC_PATH = $(PWD)/..
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon

View File

@ -0,0 +1,207 @@
#include <iostream>
#include <chrono>
#include <thread>
#include <exception>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception_ptr.hpp>
//#include "mainwindow.h"
#include "FS.h"
#include "DaemonAndroid.h"
#include "Daemon.h"
namespace i2p
{
namespace android
{
/* Worker::Worker (DaemonAndroidImpl& daemon):
m_Daemon (daemon)
{
}
void Worker::startDaemon()
{
Log.d(TAG"Performing daemon start...");
m_Daemon.start();
Log.d(TAG"Daemon started.");
emit resultReady();
}
void Worker::restartDaemon()
{
Log.d(TAG"Performing daemon restart...");
m_Daemon.restart();
Log.d(TAG"Daemon restarted.");
emit resultReady();
}
void Worker::stopDaemon() {
Log.d(TAG"Performing daemon stop...");
m_Daemon.stop();
Log.d(TAG"Daemon stopped.");
emit resultReady();
}
Controller::Controller(DaemonAndroidImpl& daemon):
m_Daemon (daemon)
{
Worker *worker = new Worker (m_Daemon);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon);
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon);
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
Controller::~Controller()
{
Log.d(TAG"Closing and waiting for daemon worker thread...");
workerThread.quit();
workerThread.wait();
Log.d(TAG"Waiting for daemon worker thread finished.");
if(m_Daemon.isRunning())
{
Log.d(TAG"Stopping the daemon...");
m_Daemon.stop();
Log.d(TAG"Stopped the daemon.");
}
}
*/
DaemonAndroidImpl::DaemonAndroidImpl ()
//:
/*mutex(nullptr), */
//m_IsRunning(false),
//m_RunningChangedCallback(nullptr)
{
}
DaemonAndroidImpl::~DaemonAndroidImpl ()
{
//delete mutex;
}
bool DaemonAndroidImpl::init(int argc, char* argv[])
{
//mutex=new QMutex(QMutex::Recursive);
//setRunningCallback(0);
//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);
}
void DaemonAndroidImpl::start()
{
//QMutexLocker locker(mutex);
//setRunning(true);
Daemon.start();
}
void DaemonAndroidImpl::stop()
{
//QMutexLocker locker(mutex);
Daemon.stop();
//setRunning(false);
}
void DaemonAndroidImpl::restart()
{
//QMutexLocker locker(mutex);
stop();
start();
}
/*
void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb)
{
m_RunningChangedCallback = cb;
}
bool DaemonAndroidImpl::isRunning()
{
return m_IsRunning;
}
void DaemonAndroidImpl::setRunning(bool newValue)
{
bool oldValue = m_IsRunning;
if(oldValue!=newValue)
{
m_IsRunning = newValue;
if(m_RunningChangedCallback)
m_RunningChangedCallback();
}
}
*/
static DaemonAndroidImpl daemon;
static char* argv[1]={strdup("tmp")};
/**
* returns error details if failed
* returns "ok" if daemon initialized and started okay
*/
std::string start(/*int argc, char* argv[]*/)
{
try
{
//int result;
{
//Log.d(TAG"Initialising the daemon...");
bool daemonInitSuccess = daemon.init(1,argv);
if(!daemonInitSuccess)
{
//QMessageBox::critical(0, "Error", "Daemon init failed");
return "Daemon init failed";
}
//Log.d(TAG"Initialised, creating the main window...");
//MainWindow w;
//Log.d(TAG"Before main window.show()...");
//w.show ();
{
//i2p::qt::Controller daemonQtController(daemon);
//Log.d(TAG"Starting the daemon...");
//emit daemonQtController.startDaemon();
//daemon.start ();
//Log.d(TAG"Starting GUI event loop...");
//result = app.exec();
//daemon.stop ();
daemon.start();
}
}
//QMessageBox::information(&w, "Debug", "demon stopped");
//Log.d(TAG"Exiting the application");
//return result;
}
catch (boost::exception& ex)
{
std::stringstream ss;
ss << boost::diagnostic_information(ex);
return ss.str();
}
catch (std::exception& ex)
{
std::stringstream ss;
ss << ex.what();
return ss.str();
}
catch(...)
{
return "unknown exception";
}
return "ok";
}
void stop()
{
daemon.stop();
}
}
}

View File

@ -0,0 +1,87 @@
#ifndef DAEMON_ANDROID_H
#define DAEMON_ANDROID_H
#include <string>
namespace i2p
{
namespace android
{
class DaemonAndroidImpl
{
public:
DaemonAndroidImpl ();
~DaemonAndroidImpl ();
//typedef void (*runningChangedCallback)();
/**
* @return success
*/
bool init(int argc, char* argv[]);
void start();
void stop();
void restart();
//void setRunningCallback(runningChangedCallback cb);
//bool isRunning();
private:
//void setRunning(bool running);
private:
//QMutex* mutex;
//bool m_IsRunning;
//runningChangedCallback m_RunningChangedCallback;
};
/**
* returns "ok" if daemon init failed
* returns errinfo if daemon initialized and started okay
*/
std::string start();
// stops the daemon
void stop();
/*
class Worker : public QObject
{
Q_OBJECT
public:
Worker (DaemonAndroidImpl& daemon);
private:
DaemonAndroidImpl& m_Daemon;
public slots:
void startDaemon();
void restartDaemon();
void stopDaemon();
signals:
void resultReady();
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller(DaemonAndroidImpl& daemon);
~Controller();
private:
DaemonAndroidImpl& m_Daemon;
public slots:
void handleResults(){}
signals:
void startDaemon();
void stopDaemon();
void restartDaemon();
};
*/
}
}
#endif // DAEMON_ANDROID_H

66
android/jni/i2pd_android.cpp Executable file
View File

@ -0,0 +1,66 @@
//#include <string.h>
#include <jni.h>
#include "org_purplei2p_i2pd_I2PD_JNI.h"
#include "DaemonAndroid.h"
#include "RouterContext.h"
#include "Transports.h"
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
(JNIEnv * env, jclass clazz) {
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a/NEON (hard-float)"
#else
#define ABI "armeabi-v7a/NEON"
#endif
#else
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a (hard-float)"
#else
#define ABI "armeabi-v7a"
#endif
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__x86_64__)
#define ABI "x86_64"
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
#define ABI "mips64"
#elif defined(__mips__)
#define ABI "mips"
#elif defined(__aarch64__)
#define ABI "arm64-v8a"
#else
#define ABI "unknown"
#endif
return env->NewStringUTF(ABI);
}
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
(JNIEnv * env, jclass clazz) {
return env->NewStringUTF(i2p::android::start().c_str());
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
(JNIEnv * env, jclass clazz) {
i2p::android::stop();
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
(JNIEnv * env, jclass clazz) {
i2p::context.SetAcceptsTunnels (false);
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
(JNIEnv * env, jclass clazz, jboolean isConnected)
{
bool isConnectedBool = (bool) isConnected;
i2p::transport::transports.SetOnline (isConnectedBool);
}

View File

@ -0,0 +1,33 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_purplei2p_i2pd_I2PD_JNI */
#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI
#define _Included_org_purplei2p_i2pd_I2PD_JNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_purplei2p_i2pd_I2PD_JNI
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
(JNIEnv *, jclass);
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
(JNIEnv * env, jclass clazz, jboolean isConnected);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

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