Compare commits

...

3494 Commits

Author SHA1 Message Date
90a5d02bf6 2.28.0 2019-08-27 10:17:32 -04:00
44a2549b81 2.28.0 2019-08-27 09:46:54 -04:00
a2b8d468bc Merge pull request #1412 from nonlinear-chaos-order-etc/openssl
qt: disabled broken UPnP + small qt debugging tweaks
2019-08-27 08:53:44 -04:00
d523f0cadd gitignored autosave files by qtcreator 2019-08-27 19:31:57 +08:00
99116ff097 qt: disabled upnp for now - until upnp fixed 2019-08-27 19:31:28 +08:00
3939ca9eb4 enabled default logging debug option for qt debug builds 2019-08-27 17:51:55 +08:00
b5aa67b491 tweaked debug logging in i2pd_qt 2019-08-27 17:10:53 +08:00
e42efec220 correct outet plain text length in case of authKeys 2019-08-26 07:35:11 -04:00
9d06aa2f6a pass authSalt or epk 2019-08-25 20:51:15 -04:00
80765a797b correct outer cipher text len 2019-08-25 19:14:53 -04:00
0b5509a1ed correct authClients offset 2019-08-25 14:54:43 -04:00
478d7b4a83 Merge pull request #1410 from nonlinear-chaos-order-etc/openssl
android various fixes and improvements
2019-08-24 07:31:12 -04:00
9d3b38141a android various fixes and improv 2019-08-24 19:13:10 +08:00
ab3a4d902e Merge pull request #1409 from nonlinear-chaos-order-etc/openssl
android - show battery optimiz. os dialog menu item added; translated all battery stuff into Russian
2019-08-24 07:03:15 -04:00
5eab5f2437 show battery optimiz. menu item now hidden if not supported by os 2019-08-24 18:00:11 +08:00
80f632c19a show battery optimiz. menu item added; translated all battery stuff into Russian 2019-08-24 17:50:30 +08:00
6e4f18543d added *.local to android/.gitignore 2019-08-24 17:04:04 +08:00
54586c9076 Merge pull request #1408 from docker-and-co/fix-dockerfile-non-existend-deps
fix dockerfile: remove unmet dependencies
2019-08-23 11:02:00 -04:00
351c899807 cleanup incoming streams on stop 2019-08-23 10:00:49 -04:00
fe45d431d7 fix dockerfile: remove unmet dependencies 2019-08-23 16:20:09 +03:00
488c2f6d05 bump SDK version 2019-08-22 09:45:49 -04:00
75ab0909b3 Merge pull request #1405 from nonlinear-chaos-order-etc/openssl
various Android stuff. Fixed #1400
2019-08-22 07:15:36 -04:00
8f82d563c1 various Android stuff. Fixed #1400 2019-08-22 10:00:50 +08:00
9bbce5dba6 fixed typo 2019-08-21 20:26:19 -04:00
099adab9ed Update README.md
update head badges links, add snapcraft badge
2019-08-16 21:45:44 +03:00
c8cbf425ac check and send netid for NTCP2 and SSU 2019-08-13 14:55:18 -04:00
ad9c11cd92 correct parsing of addreses containing # 2019-08-10 22:16:26 -04:00
3872c2a3f5 use published encrypted instead orig type 2019-08-07 16:18:00 -04:00
e6a09b49c9 published encrypted flag 2019-08-07 15:43:03 -04:00
db107602bd handle messages with \r\n 2019-08-02 13:48:39 -04:00
a6558a61a7 Recognize RedDSA_SHA512_Ed25519 signature type 2019-08-02 12:54:24 -04:00
254d2b82b3 fixed #1393. store streams by recvStreamID 2019-07-26 14:23:21 -04:00
97d9795fc9 pass encrepted LeaseSet auth keys 2019-07-16 16:31:17 -04:00
54071b0e5d set and handle unpublished LeaseSet flag 2019-07-16 11:48:30 -04:00
925e8316c7 read i2cp.leaseSetAuthType, i2cp.leaseSetClient.dh.nnn and i2cp.leaseSetClient.psk.nnn from tunnel config 2019-07-12 20:58:17 -04:00
99e1b74023 create encrypted LeaseSet2 with authentication 2019-07-12 15:40:59 -04:00
7d68ccca53 create encrypted LeaseSet2 with authentication 2019-07-12 15:37:32 -04:00
a090114066 send data message wih raw type fpr raw datagrams 2019-07-10 13:31:49 -04:00
a204841abb handle RAW SEND 2019-07-10 13:30:31 -04:00
cc451809cc send/receive raw datagrams through the SAM 2019-07-10 11:32:56 -04:00
a605e4bab6 send and recieve raw datagrams 2019-07-09 21:33:55 -04:00
3f0534134d check for malformed b33 2019-07-04 13:05:39 -04:00
3acfb129cd 2.27.0 2019-07-03 12:38:55 -04:00
6ccef66920 call shutdown before close 2019-06-26 10:47:16 -04:00
e9fa4e94a6 Merge pull request #1374 from rszibele/openssl
BOB: fix status command.
2019-06-25 18:28:43 -04:00
fecc0c4640 don't call destructor twice 2019-06-25 16:37:06 -04:00
b759294975 BOB: fix status command. 2019-06-25 19:18:40 +02:00
a23e845c03 BOB: improve comment and remove error log in list command 2019-06-25 19:04:27 +02:00
cb8373e487 BOB: status response now correctly starts with "OK DATA". 2019-06-25 17:59:44 +02:00
8e919ddc8e use monotonic clock for uptime 2019-06-19 11:43:04 -04:00
832a9ab6b5 don't set random NTCP2 port if already set 2019-06-18 15:47:58 -04:00
13732ac333 fix #1363 try connect in SSU's thread 2019-06-14 15:43:03 -04:00
3e932a55f4 fixed typo 2019-06-11 15:09:10 -04:00
74e8610ec9 DH auth for encrypted LeaseSet2 2019-06-11 10:40:53 -04:00
089a60ded6 Merge pull request #1367 from rszibele/openssl
fix build on BSDs, as "isset" is a defined macro.
2019-06-10 19:10:34 -04:00
c8eeefe194 fix build on BSDs, as "isset" is a defined macro. 2019-06-10 23:04:59 +02:00
85eeba14c1 Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2019-06-08 21:24:16 -04:00
f6f45eab39 flood encrypted LeaseSet2 with store hash 2019-06-08 21:23:25 -04:00
a74065f775 [qt] dont build UnixDaemon.cpp 2019-06-09 01:04:43 +03:00
48d02f7e09 [qt] update headers, fix ChaCha source name, remove duplicates 2019-06-08 22:24:11 +03:00
e60549f8df [qt] fix build 2019-06-08 21:16:20 +03:00
41f4f4713e handle i2cp.leaseSetPrivKey 2019-06-07 14:51:08 -04:00
213a292fd5 correct offsets for auth data 2019-06-07 11:59:48 -04:00
79630e844b 2.26.0 2019-06-07 17:25:55 +03:00
1c9e46dbb3 2.26.0 2019-06-07 10:04:57 -04:00
0a299284f8 correct check for PSK auth 2019-06-06 13:58:31 -04:00
347a5f7346 pass secret to encrypted LeaseSet2 2019-06-06 12:33:33 -04:00
c6a903572c [HTTP] add PROFIND support 2019-06-06 18:07:17 +03:00
14f0d6d26b extract client auth data 2019-06-05 15:57:20 -04:00
485f105555 fixed typo 2019-06-04 15:12:19 -04:00
686c0b776f common blinding code for public and private keys 2019-06-04 14:47:40 -04:00
828862ea49 store hash for ECDSA blidning 2019-06-03 12:51:57 -04:00
c4dffa4dc8 remove obsolete reseeds 2019-06-01 09:37:02 -04:00
3c1906e3d4 Merge pull request #1360 from khumarahn/openssl
link libi2pd to boost and zlib
2019-06-01 09:28:54 -04:00
7147a3694c link libi2pd to boost and zlib 2019-06-01 12:57:09 +01:00
64707dbb22 key blinding test 2019-05-31 11:57:16 -04:00
554e8eeef3 [appveyor] remove gcc-ada and gcc-objc packages
https://github.com/msys2/MINGW-packages/issues/5434#issuecomment-496706950
2019-05-31 16:32:32 +03:00
5e10549543 disable NTCP by default 2019-05-30 19:18:56 -04:00
685f45bd76 publish/unpublish NTCP2 address depending on network status 2019-05-30 17:52:44 -04:00
61d84dd4c1 publish/unpublish NTCP2 address depending on network status 2019-05-30 17:48:49 -04:00
4d10593bb1 publish/unpublish NTCP2 address depending on network status 2019-05-30 16:11:35 -04:00
fbb8903774 correct buffer size for ECDSA blinding 2019-05-30 13:57:43 -04:00
e8cac91bb7 blind ECDSA public key 2019-05-29 15:48:35 -04:00
7328ffa036 Merge pull request #1359 from rszibele/openssl
BOB modifications.
2019-05-29 14:07:30 -04:00
a03e828317 BOB: status: forgot to pass destination for current tunnel. 2019-05-29 18:47:35 +02:00
93d4dc70cf BOB fixes. 2019-05-29 18:05:03 +02:00
8e3d16e9fb update ipv6 addresses from SSU rather than NTCP or NTCP2 2019-05-29 11:36:58 -04:00
07405e57b9 fixed typo 2019-05-25 14:58:10 -04:00
354c9187db detect our ipv6 address 2019-05-23 15:59:44 -04:00
af33df3004 common buffer size 2019-05-23 11:49:54 -04:00
78bfde237f allocate actual RouterInfo's buffer size 2019-05-23 09:34:04 -04:00
7b9033d678 allocate actual RouterInfo's buffer size 2019-05-23 09:32:07 -04:00
f784cfad46 correct RouterInfo buffer size 2019-05-23 06:56:41 -04:00
e40c139ff1 blind ECDSA private key 2019-05-22 16:15:11 -04:00
edf4f7695d fix #1352. correct response for 'list' command 2019-05-22 12:45:50 -04:00
60ec03237e blidning for ECDSA 2019-05-16 15:49:07 -04:00
a91641e427 fix #823, reindent code 2019-05-16 09:39:22 +03:00
5c3992018f fixed #1350 use GetAddress insted GetIdentHash 2019-05-15 14:22:19 -04:00
f5b682619f [webconsole] move b33 to spoiler, fix typo 2019-05-15 14:15:10 +03:00
743fa745b7 show b33 address for encrypted LeaseSet2 2019-05-14 14:42:10 -04:00
39400fd381 move key blinding code from LeaseSet.cpp to Blinding.cpp 2019-05-14 11:42:25 -04:00
5299ac35a6 create NTCP2 ipv6 address 2019-05-13 11:40:08 -04:00
ef76ed394c publish SSU ipv6 address if NTCP if disabled 2019-05-12 13:36:26 -04:00
1472637de7 skip introducers for non-SSU address 2019-05-11 07:27:34 -04:00
3b8baa85a3 2.25.0 2019-05-09 10:21:11 -04:00
73921b1024 fix ipv6 fallback address 2019-05-08 00:45:52 +03:00
ece140f18c [httpproxy] make addresshelper support configurable for every httpproxy 2019-04-25 23:06:14 +03:00
5e42947fbd always lookup SSU session if peer's endpoint doesn't match 2019-04-25 12:54:44 -04:00
1bfb9b02f5 make sure remote endpoint matches stored with 2019-04-24 11:40:58 -04:00
16a14c2b76 [android] set datadir path from system environment 2019-04-20 19:47:06 +00:00
f6199c6c17 print store hash for encrypted LeaseSet 2019-04-20 09:44:16 -04:00
d7e7f06e88 re-request encrypted LeaseSet 2019-04-17 15:53:07 -04:00
4c4e856a1a ntcp2.addressv6 parameter 2019-04-17 14:40:00 -04:00
07bbbbaf61 fixed gcc 4.7 build 2019-04-17 12:42:43 -04:00
3236827781 add/removed NTCP addresses 2019-04-16 21:04:04 -04:00
0be664cc3d publish NTCP2 address instead NTCP if NTCP is disabled 2019-04-15 16:32:16 -04:00
6cc6849ccc use published timestamp for blinding 2019-04-12 14:05:07 -04:00
5d5cd71714 limit expiration by next midnight for encrypted LS2 2019-04-12 11:13:46 -04:00
d248343517 Handle CreateLeaseSet2 I2CP message for encrypted leasesets 2019-04-11 14:06:53 -04:00
64d800427f allow HTTP headers without value 2019-04-10 15:25:09 -04:00
c4c896a833 publish encrypted LS2 2019-04-10 12:04:19 -04:00
b6b5bb3f75 publish LeaseSet with store hash 2019-04-09 15:36:10 -04:00
5d69bb7383 correct ecrypted LS2 layout 2019-04-09 10:34:05 -04:00
76e222079a Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2019-04-09 09:21:47 -04:00
73abb9278d correct ecrypted LS2 size 2019-04-09 09:21:38 -04:00
8fd843e7ce Merge pull request #1334 from rex4539/fix-typos
Fix typos
2019-04-08 17:36:55 -04:00
6a497a23d9 Fix typos 2019-04-08 22:22:42 +03:00
3ac74e1091 create encrypted LS2 2019-04-08 13:27:21 -04:00
ef0fb48f1f blind private keys 2019-04-05 16:03:58 -04:00
414ef2bc3d fixed gcc 4.7 build 2019-04-04 16:18:52 -04:00
ea791309ad moved credential and blinding to BlindedPublicKey 2019-04-02 16:32:18 -04:00
706da6e431 allow .b32.i2p in jump links 2019-04-02 13:11:49 -04:00
ed116e7cea add gcc 9 support 2019-03-30 13:05:32 +03:00
5b56f4007b counter is always in Little Endian 2019-03-29 18:45:31 -04:00
e2071542bf use 16 bytes iv for chacha20 2019-03-29 16:18:51 -04:00
cdb217b774 always initialize m_Pkey 2019-03-29 13:15:32 -04:00
079798940b lookup for b33 address 2019-03-29 11:59:59 -04:00
f1c24689bf fixed #1319. send correct response 2019-03-29 09:29:28 -04:00
1f9cf6ed7c show lookup keys 2019-03-28 19:00:56 -04:00
43f218410f correct b33 address length threshold 2019-03-28 18:48:38 -04:00
3fd9d5f641 save b33 addresses 2019-03-28 16:06:53 -04:00
f5ab8f2062 replaced GetIdentHash by GetAddress 2019-03-28 12:19:19 -04:00
8774a8fbc2 handle b33 addresses in I2P tunnels 2019-03-28 10:17:03 -04:00
6f4f0f03d2 handle b33 addresses in I2P tunnels 2019-03-28 09:57:34 -04:00
00b5fdce03 create stream to blinded dest 2019-03-27 16:04:46 -04:00
baee6a0d91 generic address for AdressBook 2019-03-27 15:19:10 -04:00
ff44bcc489 complete implementation of RedDSA 2019-03-24 18:42:52 -04:00
c797ac4268 Update README.md 2019-03-23 03:25:10 +03:00
d22a76d4d1 remove incorrect line 2019-03-22 23:40:59 +00:00
a6642e0ebc add script for packaging archive with android binaries 2019-03-22 23:37:20 +00:00
3d4d260a34 extract b33 address 2019-03-22 16:04:47 -04:00
8e4b9da97d pass blinded key instead identity for encrypted LS2 2019-03-22 15:32:13 -04:00
2be80ba30f Fix Docker build 2019-03-22 13:14:02 -04:00
2e44c88d6c [2.24.0][android] update addressbook 2019-03-21 18:34:39 +03:00
21eb1ce6c9 2.24.0 2019-03-21 11:30:12 -04:00
cdfd411df7 2.24.0 2019-03-21 10:58:59 -04:00
a6149ca90c [android] upload gradlew script 2019-03-21 00:09:49 +03:00
642435486c [android] add gradle wrapper, update buildtools version, fixes in code. 2019-03-20 23:49:54 +03:00
fc84d6c4b7 remove unused timer 2019-03-17 21:37:42 -04:00
aa4bddd6ec common HKDF 2019-03-15 12:25:20 -04:00
8ec12a1b65 fixed race condition for publishing 2019-03-10 09:22:42 -04:00
0fbf552e95 lookup and handle encrypted LeaseSet2 2019-03-07 14:52:59 -05:00
09b1b120d7 update LeaseSet2 if store type changed 2019-03-07 14:51:05 -05:00
557244bc3f verify blinding key for encrypted LS2 2019-03-07 11:55:47 -05:00
24c5ed1cff calculate store hash for encrypted LeaseSet2 2019-03-06 16:08:04 -05:00
32e55ebd0c blind public key for encrypted LeaseSet2 2019-03-05 15:51:24 -05:00
ea3070d02b derivation of subcredentials for LeaseSet2 2019-03-05 12:41:01 -05:00
9aaba49a9f decrypt and handle Layer 2 of encrypted LeaseSet 2 2019-03-04 15:47:35 -05:00
9b64be07a9 set chacha20 counter to 1 2019-03-04 15:08:03 -05:00
42c3c28ea7 [addressbook] reset eTags if addressbook can't be loaded 2019-03-04 18:29:29 +00:00
9e9236badb don't check TRANSIENT destination 2019-03-04 07:35:48 -05:00
560ebcec8d persist.addressbook parameter added 2019-03-01 14:42:20 -05:00
9b1fe4338b reuse_address for ipv6 acceptor 2019-02-28 16:00:26 -05:00
9188e3ad3f ChaCha20 decrypt 2019-02-28 13:31:51 -05:00
af65af5be9 H and HKDF for encrypted LeaseSet2 2019-02-27 15:52:47 -05:00
2f0115c300 handle RedDSA as EdDSA 2019-02-27 13:18:09 -05:00
0646461342 check published timestamp for LeaseSet2 2019-02-26 16:20:24 -05:00
ec30ec0996 Merge pull request #1304 from lifecoder-phoenix/openssl
Fix #1257
2019-02-25 07:01:33 -05:00
cdecb7a43c Fix #1257 2019-02-25 10:10:09 +01:00
aa9c1b66a0 Fix #1257 2019-02-25 09:57:18 +01:00
846eac29dc filter out unspecified addresses. Check floodfill status change 2019-02-24 18:26:58 -05:00
0f9e3c5b33 fix crash if public key is null 2019-02-22 13:17:43 -05:00
aa27746982 remove address string 2019-02-22 11:03:31 -05:00
d8a4954bf1 [NetDb] check PersistProfiles on load
* tabulation fixes
2019-02-22 18:37:32 +03:00
d40a029dae eliminate extra copy 2019-02-20 12:36:05 -05:00
96d961c393 correct public key for EdDSA trasient key 2019-02-15 15:03:58 -05:00
7b6814e32d correct flags 2019-02-14 21:22:49 -05:00
6fee2d3536 correct options szie 2019-02-14 17:49:23 -05:00
636fc633d4 send offline signature in streaming 2019-02-14 12:11:25 -05:00
72a239838e publish offline signature 2019-02-12 14:56:39 -05:00
a463dbc5fb Merge pull request #1295 from l-n-s/websocket_support
Support websocket connections over HTTP proxy
2019-02-12 12:30:44 -05:00
016ae3b9e9 rewrite for efficiency 2019-02-12 11:20:54 -05:00
7d0d421724 [windows] handle unexpected conditions (#1185) 2019-02-12 04:27:09 +03:00
83b5856a19 fix overflow warning, fix little typos 2019-02-12 03:09:29 +03:00
f617b27110 Support websocket connections over HTTP proxy 2019-02-11 17:18:01 -05:00
a91a0263cf update outproxy user-agent header rewrite 2019-02-12 00:51:47 +03:00
80ffe13f3e correct offline signature layout 2019-02-08 15:12:51 -05:00
1eb726c9bb create offline keys 2019-02-08 12:19:51 -05:00
1fa3ba8b42 read offline info 2019-02-07 16:04:31 -05:00
b6bfd66a49 use identity from LeaseSet 2019-02-06 21:19:44 -05:00
1be0e7ddaa [windows] add functional
* check tunnels count on graceful shutdown
* add tray menu item for accept/decline transit tunnels
2019-02-07 02:02:28 +03:00
2cac9b03ff common code for offline signatures 2019-02-06 13:36:03 -05:00
f5f4190803 catch error 10045 on stopping SAM acceptor (#1233), fix warning in util 2019-02-06 03:03:37 +03:00
a14d554947 fix tray icon disappearing, var type warning, code tabulation 2019-02-06 00:24:01 +03:00
6d9e5147b5 handle offline signature 2019-02-05 15:32:18 -05:00
841452cb9e Merge pull request #1292 from PurpleI2P/inet_pton_xp
inet_pton for winxp
2019-02-05 17:36:36 +03:00
9c76368dbc inet_pton for winxp 2019-02-05 14:13:23 +03:00
bd5122c6ea fixed build error 2019-02-01 17:41:12 -05:00
6643258618 implement Update for LeaseSet2 2019-02-01 12:55:13 -05:00
bc3f02cb6b fix #1290. copy correct size if message didn't fit previous 2019-01-31 16:03:10 -05:00
d848ae332a encryption keys priority 2019-01-30 14:10:40 -05:00
08ddc98303 initial LeaseSet2 support in I2CP 2019-01-29 11:30:31 -05:00
a3344c4290 resolve SIGNATURE_TYPE string values 2019-01-23 10:52:17 -05:00
22c1ce3ea5 don't pick port 9150 (Tor browser) 2019-01-23 09:53:30 -05:00
afb14e6782 [fedora] fix build in release on fc30+
fixes #1284
2019-01-22 04:57:53 +03:00
e177363377 [fedora] specify srcdir only if building at 30+ 2019-01-22 04:08:52 +03:00
ce213934c9 try fix build in fedora rawhide 2019-01-22 02:33:44 +03:00
af286ec52e try fix build in fedora rawhide 2019-01-22 02:32:51 +03:00
f7f2b7607b 2.23.0 2019-01-21 18:51:04 +03:00
60a282826c 2.23.0 2019-01-21 10:33:22 -05:00
3eba599aec [android] add addressbook in assets
Sources:
http://inr.i2p/export/alive-hosts.txt
http://stats.i2p/cgi-bin/newhosts.txt
http://i2p-projekt.i2p/hosts.txt
http://identiguy.i2p/hosts.txt

Updated: January ‎18, ‎2019, ‏‎12:00:01 PM
2019-01-18 23:59:22 +03:00
74d876f145 [android] update russian strings, add tunnels.d to assets list 2019-01-18 18:43:48 +03:00
d7609f119c [android] build libi2pd staticly, add update strings, fix messages 2019-01-18 15:44:30 +03:00
65c2c7d80b re-create LeaseSet if store type has changed 2019-01-16 19:00:17 -05:00
468a32a819 check LS2 transient key expires time 2019-01-15 18:56:26 -05:00
b89cf73ae2 correct encryption key type for LS2 2019-01-15 18:41:00 -05:00
9cf43dea1a handle i2cp.leaseSetEncType 2019-01-15 15:43:21 -05:00
670ffe2078 show LS2 in Leasets' list 2019-01-14 18:39:02 -05:00
884cf756ed remove invalid leasesets 2019-01-14 18:37:17 -05:00
e44ba54857 show correct LeaseSet's store type 2019-01-14 16:34:43 -05:00
3712749a94 extract timestamp for LS2 2019-01-14 13:49:27 -05:00
6569c4aa03 actual key size for LS2 2019-01-13 19:17:02 -05:00
d6b2b3c996 take key type for LS2 from identity 2019-01-13 08:34:34 -05:00
06c7900ece show LeaseSet type in destination 2019-01-12 18:26:31 -05:00
52a6a12a9a correct LS2 creation 2019-01-12 18:25:10 -05:00
e647603dce handle i2cp.leaseSetType parameter 2019-01-11 13:58:02 -05:00
dadf6174ba create standard LS2 2019-01-10 11:52:34 -05:00
84de7675c4 don't copy LS2 for signature verification 2019-01-10 10:57:57 -05:00
6311a80d0e use clang for android binary build 2019-01-10 09:47:11 -05:00
9504e69598 LocalLeaseSet2 added 2019-01-09 14:51:47 -05:00
5398b651f7 handle LS2 in destinations 2019-01-09 12:47:47 -05:00
b5596c4596 handle encrypted LS2 2019-01-08 11:26:50 -05:00
fdcea5537c show LeaseSet's store type 2019-01-08 09:35:15 -05:00
8ca8bc810d take elgamal percomputation from config 2019-01-08 09:23:14 -05:00
8f909b051f Merge pull request #1281 from neheb/b
Fix compilation without deprecated OpenSSL APIs
2019-01-06 20:12:51 -05:00
90f2b2d249 Fix compilation without deprecated OpenSSL APIs 2019-01-06 15:39:24 -08:00
f74b27c58c check if chacha20 and poly1305 is presented in openssl build 2019-01-06 17:43:05 -05:00
3f091f4748 remove i2pd-qt android project (closes #1279) 2019-01-06 19:46:17 +03:00
d84c9ad611 Merge pull request #1277 from l-n-s/update_zlib_version
CMake: bump version of ZLib
2019-01-04 23:48:44 +03:00
e55e15693d update LS2 leases 2019-01-02 15:40:48 -05:00
c54e6bafdb process meta LS2 2019-01-02 14:19:10 -05:00
2e56c4895d transient key signature verification 2019-01-02 09:43:18 -05:00
bce4224d6e extract and verify LS2 transient key 2019-01-01 17:00:37 -05:00
812e2814bc read flags from LS2 header 2018-12-31 14:23:48 -05:00
7cd17f8e1f build android app with llvm 2018-12-27 03:16:38 +03:00
6193b06708 LS2 signature verification and store type 2018-12-26 15:27:32 -05:00
12af68bdb5 initial support of LeaseSet2 2018-12-21 15:00:03 -05:00
881f7e9062 correct Authorization header 2018-12-21 10:50:23 -05:00
1db4076bbd CMake: bump version of ZLib 2018-12-19 12:19:30 -05:00
1933e44719 reseeds update 2018-12-17 20:14:12 -05:00
25441cb650 revert mingw makefile
ref: https://github.com/Alexpux/MINGW-packages/issues/4773
2018-12-14 21:44:38 +03:00
bc755ac32f [MSYS2] add boost version detection via pacman 2018-12-14 15:43:52 +03:00
1fa34be52a update mingw makefile 2018-12-14 09:29:41 +03:00
f7a6d57855 fixed bug with loval destination shared between http and socks proxy 2018-12-13 09:53:16 -05:00
8a987af244 initialize m_Pkey 2018-12-11 15:14:51 -05:00
65cbb06080 create ephemeral keys after getting connected 2018-12-07 19:24:46 -05:00
979ea9c252 removed address resolvers as discontinued 2018-12-07 12:27:06 -05:00
aa1f4ee72a fixed possible race condition 2018-12-07 12:25:26 -05:00
74ce485b73 EdDSA signatures by default 2018-12-06 13:13:20 -05:00
165e6508f8 EdDSA signatures by default 2018-12-05 14:58:50 -05:00
c7af2889fa removed dummy initializer 2018-12-05 14:56:40 -05:00
5ab3390434 don't create dummy initializer for android 2018-12-05 11:39:48 -05:00
67f60f1889 set openssl no_config before boost::asio:ssl 2018-12-04 21:20:12 -05:00
985a468d0f don't read openssl config file 2018-12-04 18:39:49 -05:00
34dc6fbdc1 check if session is terminated before sending 2018-12-04 16:10:52 -05:00
b57152cc25 common code for padding and sending termination and RouterInfo messages 2018-12-04 15:56:55 -05:00
dc9562e430 padding for termination message 2018-12-04 15:23:43 -05:00
05689fe183 padding for short messages 2018-12-04 15:00:10 -05:00
8f6f95211e eliminate extra copy of RouterInfo 2018-12-04 12:56:49 -05:00
f30b6c9e6e const reference to vector of buffers 2018-12-04 12:54:48 -05:00
12ac7d6a00 enable sending I2NP messages 2018-12-03 18:47:20 -05:00
10251a6447 fixed typo 2018-12-03 15:54:35 -05:00
089cbbc20a rollback 2018-12-03 14:51:27 -05:00
95ab68acd1 don't copy I2NP messages to NTCP2 frame 2018-12-03 14:14:36 -05:00
abc4f6c70b fixed bug with chacha20 encryption of short messages 2018-12-03 13:36:17 -05:00
8fc3a1f9c9 correct frame size for I2NP msgs 2018-12-03 12:29:24 -05:00
5c3d0fc02c create I2NP blocks 2018-12-02 17:24:31 -05:00
7efb47fed4 send NTCP2 frame from I2NP messages 2018-12-02 14:24:39 -05:00
7692332f0e don't inialize Chacha20 state twice 2018-11-30 21:31:06 -05:00
ef6db64e9f correct chacha20 for multiple messages 2018-11-30 16:21:11 -05:00
e68f1dbc99 AEAD/Chacha20/Poly1305 encrypt multiple buffers 2018-11-30 14:41:14 -05:00
0c9ebc36d4 remove AVX and SSE for CipherBlock XOR 2018-11-27 14:33:31 -05:00
fcd6eb7801 overwrite user-agent for outproxy requests 2018-11-27 19:57:40 +03:00
328c2182c2 alignment for tunnel message AES decryption 2018-11-27 10:35:17 -05:00
08706f5dfb fixed typo 2018-11-25 18:49:59 -05:00
d49f165f0d fixed build warning 2018-11-25 15:59:00 -05:00
cf0fc3a4a9 some performance improvements 2018-11-25 10:33:48 -05:00
72c8fd257c eliminate extra buffer for Poly1305 2018-11-24 15:39:37 -05:00
fa620e41a4 correct alignment for polyKey 2018-11-24 14:41:17 -05:00
b07f851ce7 Merge pull request #1272 from majestrate/openssl
expose poly1305 digest struct in poly1305.h
2018-11-24 14:24:09 -05:00
16b3108719 Merge remote-tracking branch 'purple/openssl' into openssl 2018-11-24 10:08:12 -05:00
f385c624c7 expose poly1305 digester 2018-11-24 10:07:17 -05:00
f7e9975192 restore BlockCipher XOR using SSE 2018-11-24 09:43:30 -05:00
cde989b59d don't compile compatibility code if openssl 1.1.1 2018-11-22 12:13:16 -05:00
c0e263abd3 default value for m_PersistProfiles 2018-11-22 11:30:44 -05:00
79c0c11e80 configure persist of peer profiles
* If persist.profiles = false, peer profiles not stored on disk
* remove inet_pton for windows
* update configs
2018-11-22 00:13:23 +03:00
ca671551c8 flood NTCP2 RouterInfo if requested 2018-11-21 13:24:54 -05:00
42ed312384 handle NTCP2 RouterInfo flag 2018-11-21 11:23:48 -05:00
0e9074aaba reduce start and stop time 2018-11-20 13:57:51 -05:00
7c1961d4ef Cancel Graceful Stop 2018-11-20 12:36:10 -05:00
71e57717c2 request memory permisssion for android >= 6 2018-11-19 15:53:16 -05:00
8a549b83a2 NTP sync in separate thread 2018-11-16 12:49:04 -05:00
d7081c5f23 handle RouterInfo from NTCP2 in netdb's thread 2018-11-14 20:52:54 -05:00
588d64a30b more NTP logging 2018-11-14 12:27:11 -05:00
8335bdf3d4 correct ntp servers 2018-11-14 11:47:50 -05:00
85394f2438 NTP time sync 2018-11-14 11:06:53 -05:00
42b556574f add fedora copr mageia support 2018-11-11 22:28:34 +03:00
f34e65ad9e Merge pull request #1268 from sokolas/webroot
Added configurable web console URL path
2018-11-10 15:08:40 -05:00
51352a6819 update debian/rpm tunnels.d storing
+ testing rpm changes: manpage and configs store
2018-11-10 03:28:24 +00:00
d9887ec370 bump i2pd version in appdata manifest 2018-11-09 14:05:10 -05:00
c994950aaf default webroot in config, webroot in automatic redirect instead of request path 2018-11-09 17:42:04 +03:00
a26ed6fe6c Merge remote-tracking branch 'upstream/openssl' into webroot 2018-11-09 16:30:54 +03:00
a12a7e73f9 redirect with webroot 2018-11-09 16:13:56 +03:00
779228857e 2.22.0 2018-11-09 02:22:55 +00:00
8d0b696d33 packages - tunnels.conf.d fix configs place, links 2018-11-07 18:41:04 +03:00
23ae220aa7 add webroot setting 2018-11-07 18:07:05 +03:00
b7940e0002 add tunnels.d to packages 2018-11-06 20:04:26 +03:00
b3fd8bd0ae check if keys are available before sending termination message 2018-11-04 18:51:25 -05:00
bffeb237de termination might be send for non-established session 2018-11-04 15:32:31 -05:00
23e3602ea1 common MixHash 2018-11-01 16:06:39 -04:00
34cfd205f6 create new static keys by X25519Keys 2018-11-01 10:43:31 -04:00
df3da8be7a Merge pull request #1264 from l-n-s/desktop
fix appdata manifest
2018-10-31 17:24:39 +00:00
940243f45e fix appdata manifest 2018-10-31 13:23:13 -04:00
75d6599143 Update desktop files (#1263)
* Rename files to freedesktop standarts

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

* More metadata in appstream file
2018-10-30 07:48:02 +00:00
82ddee2104 Merge pull request #1260 from l-n-s/version_display
Add --version flag to display i2pd and system libraries versions
2018-10-28 11:01:46 -04:00
a141678119 Add --version flag to display i2pd and system libraries versions 2018-10-28 10:52:22 -04:00
96d109af81 fixed typo 2018-10-27 19:55:23 -04:00
a309eb9f3c faster CipherBlock XOR implementation for non-AVX 2018-10-27 18:41:05 -04:00
d034dab265 fill m3p2 with SessionRequest 2018-10-26 09:58:18 -04:00
883a035e5c Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl 2018-10-22 12:26:49 -04:00
08603091c5 2.21.1 2018-10-22 14:21:52 +00:00
a2e84e5a1e 2.21.1 2018-10-22 09:19:39 -04:00
d148898ad7 Merge remote-tracking branch 'purple/openssl' into openssl 2018-10-22 07:35:34 -04:00
9439621849 fixed #1259. read extra tunnels from tunnels.d 2018-10-19 15:23:46 -04:00
36cf622979 Merge pull request #1258 from PurpleI2P/openssl
long I2NP messages
2018-10-15 09:30:56 -04:00
15ded89618 set cost=14 for unpublished NTCP2 addresses 2018-10-11 13:00:37 -04:00
b84f74c167 limit SSU message size to 32K 2018-10-11 11:17:14 -04:00
a97300f8be fixed #1256 I2NP messages up to 64K 2018-10-10 11:31:55 -04:00
9e12cff317 fix #1253 handle incorrect values of SIGNATURE_TYPE and CRYPTO_TYPE 2018-10-08 15:03:41 -04:00
ecdf1f4ddc updated debian patches, add patch disabling few settings in service file, fix name in control file 2018-10-05 13:44:18 +00:00
2fa7a48163 2.21.0 2018-10-04 10:17:33 -04:00
5e31e533e2 Merge pull request #1249 from PurpleI2P/openssl
2.21.0
2018-10-04 09:47:29 -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
5ecd04dd4f Merge pull request #1240 from PurpleI2P/openssl
eddsa from 1.1.1
2018-09-08 16:22:12 -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
fb26e78ecc Merge branch 'openssl' of https://github.com/purplei2p/i2pd into openssl 2018-08-25 14:03:21 -04:00
4c687036c4 enable socks outproxy 2018-08-25 14:01:57 -04:00
062d8d0f4f fixed potential race condition 2018-08-25 13:27:03 -04:00
73b6338f62 Merge pull request #1229 from PurpleI2P/openssl
2.20
2018-08-23 11:21:49 -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
8490e7ca7c Merge pull request #1223 from PurpleI2P/openssl
recent changes
2018-08-14 13:50:44 -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
fb229d4064 Merge pull request #1203 from PurpleI2P/openssl
2.19
2018-06-26 13:58:07 -04: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
427 changed files with 60010 additions and 23903 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);
}
}
}

View File

@ -1,106 +0,0 @@
#ifndef ADDRESS_BOOK_H__
#define ADDRESS_BOOK_H__
#include <string.h>
#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <mutex>
#include <memory>
#include <boost/asio.hpp>
#include "Base.h"
#include "util.h"
#include "Identity.h"
#include "Log.h"
namespace i2p
{
namespace client
{
const char DEFAULT_SUBSCRIPTION_ADDRESS[] = "http://udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p/hosts.txt";
const int INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT = 3; // in minutes
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
const int SUBSCRIPTION_REQUEST_TIMEOUT = 60; //in second
inline std::string GetB32Address(const i2p::data::IdentHash& ident) { return ident.ToBase32().append(".b32.i2p"); }
class AddressBookStorage // interface for storage
{
public:
virtual ~AddressBookStorage () {};
virtual std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const = 0;
virtual void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) = 0;
virtual void RemoveAddress (const i2p::data::IdentHash& ident) = 0;
virtual int Load (std::map<std::string, i2p::data::IdentHash>& addresses) = 0;
virtual int Save (const std::map<std::string, i2p::data::IdentHash>& addresses) = 0;
};
class AddressBookSubscription;
class AddressBook
{
public:
AddressBook ();
~AddressBook ();
void Start ();
void Stop ();
bool GetIdentHash (const std::string& address, i2p::data::IdentHash& ident);
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const std::string& address);
const i2p::data::IdentHash * FindAddress (const std::string& address);
void InsertAddress (const std::string& address, const std::string& base64); // for jump service
void InsertAddress (std::shared_ptr<const i2p::data::IdentityEx> address);
void LoadHostsFromStream (std::istream& f);
void DownloadComplete (bool success);
//This method returns the ".b32.i2p" address
std::string ToAddress(const i2p::data::IdentHash& ident) { return GetB32Address(ident); }
std::string ToAddress(std::shared_ptr<const i2p::data::IdentityEx> ident) { return ToAddress(ident->GetIdentHash ()); }
private:
void StartSubscriptions ();
void StopSubscriptions ();
AddressBookStorage * CreateStorage ();
void LoadHosts ();
void LoadSubscriptions ();
void HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode);
private:
std::mutex m_AddressBookMutex;
std::map<std::string, i2p::data::IdentHash> m_Addresses;
AddressBookStorage * m_Storage;
volatile bool m_IsLoaded, m_IsDownloading;
std::vector<AddressBookSubscription *> m_Subscriptions;
AddressBookSubscription * m_DefaultSubscription; // in case if we don't know any addresses yet
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
};
class AddressBookSubscription
{
public:
AddressBookSubscription (AddressBook& book, const std::string& link);
void CheckSubscription ();
private:
void Request ();
private:
AddressBook& m_Book;
std::string m_Link, m_Etag, m_LastModified;
};
}
}
#endif

643
BOB.cpp
View File

@ -1,643 +0,0 @@
#include <string.h>
#include <boost/lexical_cast.hpp>
#include "Log.h"
#include "ClientContext.h"
#include "BOB.h"
namespace i2p
{
namespace client
{
BOBI2PInboundTunnel::BOBI2PInboundTunnel (int port, std::shared_ptr<ClientDestination> localDestination):
BOBI2PTunnel (localDestination),
m_Acceptor (localDestination->GetService (), boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4(), port))
{
}
BOBI2PInboundTunnel::~BOBI2PInboundTunnel ()
{
Stop ();
}
void BOBI2PInboundTunnel::Start ()
{
m_Acceptor.listen ();
Accept ();
}
void BOBI2PInboundTunnel::Stop ()
{
m_Acceptor.close();
ClearHandlers ();
}
void BOBI2PInboundTunnel::Accept ()
{
auto receiver = std::make_shared<AddressReceiver> ();
receiver->socket = std::make_shared<boost::asio::ip::tcp::socket> (GetService ());
m_Acceptor.async_accept (*receiver->socket, std::bind (&BOBI2PInboundTunnel::HandleAccept, this,
std::placeholders::_1, receiver));
}
void BOBI2PInboundTunnel::HandleAccept (const boost::system::error_code& ecode, std::shared_ptr<AddressReceiver> receiver)
{
if (!ecode)
{
Accept ();
ReceiveAddress (receiver);
}
}
void BOBI2PInboundTunnel::ReceiveAddress (std::shared_ptr<AddressReceiver> receiver)
{
receiver->socket->async_read_some (boost::asio::buffer(
receiver->buffer + receiver->bufferOffset,
BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset),
std::bind(&BOBI2PInboundTunnel::HandleReceivedAddress, this,
std::placeholders::_1, std::placeholders::_2, receiver));
}
void BOBI2PInboundTunnel::HandleReceivedAddress (const boost::system::error_code& ecode, std::size_t bytes_transferred,
std::shared_ptr<AddressReceiver> receiver)
{
if (ecode)
LogPrint ("BOB inbound tunnel read error: ", ecode.message ());
else
{
receiver->bufferOffset += bytes_transferred;
receiver->buffer[receiver->bufferOffset] = 0;
char * eol = strchr (receiver->buffer, '\n');
if (eol)
{
*eol = 0;
receiver->data = (uint8_t *)eol + 1;
receiver->dataLen = receiver->bufferOffset - (eol - receiver->buffer + 1);
i2p::data::IdentHash ident;
if (!context.GetAddressBook ().GetIdentHash (receiver->buffer, ident))
{
LogPrint (eLogError, "BOB address ", receiver->buffer, " not found");
return;
}
auto leaseSet = GetLocalDestination ()->FindLeaseSet (ident);
if (leaseSet)
CreateConnection (receiver, leaseSet);
else
GetLocalDestination ()->RequestDestination (ident,
std::bind (&BOBI2PInboundTunnel::HandleDestinationRequestComplete,
this, std::placeholders::_1, receiver));
}
else
{
if (receiver->bufferOffset < BOB_COMMAND_BUFFER_SIZE)
ReceiveAddress (receiver);
else
LogPrint ("BOB missing inbound address ");
}
}
}
void BOBI2PInboundTunnel::HandleDestinationRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, std::shared_ptr<AddressReceiver> receiver)
{
if (leaseSet)
CreateConnection (receiver, leaseSet);
else
LogPrint ("LeaseSet for BOB inbound destination not found");
}
void BOBI2PInboundTunnel::CreateConnection (std::shared_ptr<AddressReceiver> receiver, std::shared_ptr<const i2p::data::LeaseSet> leaseSet)
{
LogPrint ("New BOB inbound connection");
auto connection = std::make_shared<I2PTunnelConnection>(this, receiver->socket, leaseSet);
AddHandler (connection);
connection->I2PConnect (receiver->data, receiver->dataLen);
}
BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& address, int port,
std::shared_ptr<ClientDestination> localDestination, bool quiet): BOBI2PTunnel (localDestination),
m_Endpoint (boost::asio::ip::address::from_string (address), port), m_IsQuiet (quiet)
{
}
void BOBI2POutboundTunnel::Start ()
{
Accept ();
}
void BOBI2POutboundTunnel::Stop ()
{
ClearHandlers ();
}
void BOBI2POutboundTunnel::Accept ()
{
auto localDestination = GetLocalDestination ();
if (localDestination)
localDestination->AcceptStreams (std::bind (&BOBI2POutboundTunnel::HandleAccept, this, std::placeholders::_1));
else
LogPrint ("Local destination not set for server tunnel");
}
void BOBI2POutboundTunnel::HandleAccept (std::shared_ptr<i2p::stream::Stream> stream)
{
if (stream)
{
auto conn = std::make_shared<I2PTunnelConnection> (this, stream, std::make_shared<boost::asio::ip::tcp::socket> (GetService ()), m_Endpoint, m_IsQuiet);
AddHandler (conn);
conn->Connect ();
}
}
BOBDestination::BOBDestination (std::shared_ptr<ClientDestination> localDestination):
m_LocalDestination (localDestination),
m_OutboundTunnel (nullptr), m_InboundTunnel (nullptr)
{
}
BOBDestination::~BOBDestination ()
{
delete m_OutboundTunnel;
delete m_InboundTunnel;
i2p::client::context.DeleteLocalDestination (m_LocalDestination);
}
void BOBDestination::Start ()
{
if (m_OutboundTunnel) m_OutboundTunnel->Start ();
if (m_InboundTunnel) m_InboundTunnel->Start ();
}
void BOBDestination::Stop ()
{
StopTunnels ();
m_LocalDestination->Stop ();
}
void BOBDestination::StopTunnels ()
{
if (m_OutboundTunnel)
{
m_OutboundTunnel->Stop ();
delete m_OutboundTunnel;
m_OutboundTunnel = nullptr;
}
if (m_InboundTunnel)
{
m_InboundTunnel->Stop ();
delete m_InboundTunnel;
m_InboundTunnel = nullptr;
}
}
void BOBDestination::CreateInboundTunnel (int port)
{
if (!m_InboundTunnel)
m_InboundTunnel = new BOBI2PInboundTunnel (port, m_LocalDestination);
}
void BOBDestination::CreateOutboundTunnel (const std::string& address, int port, bool quiet)
{
if (!m_OutboundTunnel)
m_OutboundTunnel = new BOBI2POutboundTunnel (address, port, m_LocalDestination, quiet);
}
BOBCommandSession::BOBCommandSession (BOBCommandChannel& owner):
m_Owner (owner), m_Socket (m_Owner.GetService ()), m_ReceiveBufferOffset (0),
m_IsOpen (true), m_IsQuiet (false), m_InPort (0), m_OutPort (0),
m_CurrentDestination (nullptr)
{
}
BOBCommandSession::~BOBCommandSession ()
{
}
void BOBCommandSession::Terminate ()
{
m_Socket.close ();
m_IsOpen = false;
}
void BOBCommandSession::Receive ()
{
m_Socket.async_read_some (boost::asio::buffer(m_ReceiveBuffer + m_ReceiveBufferOffset, BOB_COMMAND_BUFFER_SIZE - m_ReceiveBufferOffset),
std::bind(&BOBCommandSession::HandleReceived, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
void BOBCommandSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("BOB command channel read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
size_t size = m_ReceiveBufferOffset + bytes_transferred;
m_ReceiveBuffer[size] = 0;
char * eol = strchr (m_ReceiveBuffer, '\n');
if (eol)
{
*eol = 0;
char * operand = strchr (m_ReceiveBuffer, ' ');
if (operand)
{
*operand = 0;
operand++;
}
else
operand = eol;
// process command
auto& handlers = m_Owner.GetCommandHandlers ();
auto it = handlers.find (m_ReceiveBuffer);
if (it != handlers.end ())
(this->*(it->second))(operand, eol - operand);
else
{
LogPrint (eLogError, "BOB unknown command ", m_ReceiveBuffer);
SendReplyError ("unknown command");
}
m_ReceiveBufferOffset = size - (eol - m_ReceiveBuffer) - 1;
memmove (m_ReceiveBuffer, eol + 1, m_ReceiveBufferOffset);
}
else
{
if (size < BOB_COMMAND_BUFFER_SIZE)
m_ReceiveBufferOffset = size;
else
{
LogPrint (eLogError, "Malformed input of the BOB command channel");
Terminate ();
}
}
}
}
void BOBCommandSession::Send (size_t len)
{
boost::asio::async_write (m_Socket, boost::asio::buffer (m_SendBuffer, len),
boost::asio::transfer_all (),
std::bind(&BOBCommandSession::HandleSent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
void BOBCommandSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
{
LogPrint ("BOB command channel send error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ();
}
else
{
if (m_IsOpen)
Receive ();
else
Terminate ();
}
}
void BOBCommandSession::SendReplyOK (const char * msg)
{
#ifdef _MSC_VER
size_t len = sprintf_s (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_OK, msg);
#else
size_t len = snprintf (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_OK, msg);
#endif
Send (len);
}
void BOBCommandSession::SendReplyError (const char * msg)
{
#ifdef _MSC_VER
size_t len = sprintf_s (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_ERROR, msg);
#else
size_t len = snprintf (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_ERROR, msg);
#endif
Send (len);
}
void BOBCommandSession::SendVersion ()
{
size_t len = strlen (BOB_VERSION);
memcpy (m_SendBuffer, BOB_VERSION, len);
Send (len);
}
void BOBCommandSession::SendData (const char * nickname)
{
#ifdef _MSC_VER
size_t len = sprintf_s (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_DATA, nickname);
#else
size_t len = snprintf (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_DATA, nickname);
#endif
Send (len);
}
void BOBCommandSession::ZapCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: zap");
Terminate ();
}
void BOBCommandSession::QuitCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: quit");
m_IsOpen = false;
SendReplyOK ("Bye!");
}
void BOBCommandSession::StartCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: start ", m_Nickname);
if (!m_CurrentDestination)
{
m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options));
m_Owner.AddDestination (m_Nickname, m_CurrentDestination);
}
if (m_InPort)
m_CurrentDestination->CreateInboundTunnel (m_InPort);
if (m_OutPort && !m_Address.empty ())
m_CurrentDestination->CreateOutboundTunnel (m_Address, m_OutPort, m_IsQuiet);
m_CurrentDestination->Start ();
SendReplyOK ("tunnel starting");
}
void BOBCommandSession::StopCommandHandler (const char * operand, size_t len)
{
auto dest = m_Owner.FindDestination (m_Nickname);
if (dest)
{
dest->StopTunnels ();
SendReplyOK ("tunnel stopping");
}
else
SendReplyError ("tunnel not found");
}
void BOBCommandSession::SetNickCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: setnick ", operand);
m_Nickname = operand;
std::string msg ("Nickname set to ");
msg += operand;
SendReplyOK (msg.c_str ());
}
void BOBCommandSession::GetNickCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: getnick ", operand);
m_CurrentDestination = m_Owner.FindDestination (operand);
if (m_CurrentDestination)
{
m_Keys = m_CurrentDestination->GetKeys ();
m_Nickname = operand;
std::string msg ("Nickname set to ");
msg += operand;
SendReplyOK (msg.c_str ());
}
else
SendReplyError ("tunnel not found");
}
void BOBCommandSession::NewkeysCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: newkeys");
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys ();
SendReplyOK (m_Keys.GetPublic ()->ToBase64 ().c_str ());
}
void BOBCommandSession::SetkeysCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: setkeys ", operand);
m_Keys.FromBase64 (operand);
SendReplyOK (m_Keys.GetPublic ()->ToBase64 ().c_str ());
}
void BOBCommandSession::GetkeysCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: getkeys");
SendReplyOK (m_Keys.ToBase64 ().c_str ());
}
void BOBCommandSession::GetdestCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: getdest");
SendReplyOK (m_Keys.GetPublic ()->ToBase64 ().c_str ());
}
void BOBCommandSession::OuthostCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: outhost ", operand);
m_Address = operand;
SendReplyOK ("outhost set");
}
void BOBCommandSession::OutportCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: outport ", operand);
m_OutPort = boost::lexical_cast<int>(operand);
SendReplyOK ("outbound port set");
}
void BOBCommandSession::InhostCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: inhost ", operand);
m_Address = operand;
SendReplyOK ("inhost set");
}
void BOBCommandSession::InportCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: inport ", operand);
m_InPort = boost::lexical_cast<int>(operand);
SendReplyOK ("inbound port set");
}
void BOBCommandSession::QuietCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: quiet");
m_IsQuiet = true;
SendReplyOK ("quiet");
}
void BOBCommandSession::LookupCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: lookup ", operand);
i2p::data::IdentHash ident;
if (!context.GetAddressBook ().GetIdentHash (operand, ident) || !m_CurrentDestination)
{
SendReplyError ("Address Not found");
return;
}
auto localDestination = m_CurrentDestination->GetLocalDestination ();
auto leaseSet = localDestination->FindLeaseSet (ident);
if (leaseSet)
SendReplyOK (leaseSet->GetIdentity ()->ToBase64 ().c_str ());
else
{
auto s = shared_from_this ();
localDestination->RequestDestination (ident,
[s](std::shared_ptr<i2p::data::LeaseSet> ls)
{
if (ls)
s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ());
else
s->SendReplyError ("LeaseSet Not found");
}
);
}
}
void BOBCommandSession::ClearCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: clear");
m_Owner.DeleteDestination (m_Nickname);
SendReplyOK ("cleared");
}
void BOBCommandSession::ListCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: list");
auto& destinations = m_Owner.GetDestinations ();
for (auto it: destinations)
SendData (it.first.c_str ());
SendReplyOK ("Listing done");
}
void BOBCommandSession::OptionCommandHandler (const char * operand, size_t len)
{
LogPrint (eLogDebug, "BOB: option ", operand);
const char * value = strchr (operand, '=');
if (value)
{
*(const_cast<char *>(value)) = 0;
m_Options[operand] = value + 1;
*(const_cast<char *>(value)) = '=';
SendReplyOK ("option");
}
else
SendReplyError ("malformed");
}
BOBCommandChannel::BOBCommandChannel (int port):
m_IsRunning (false), m_Thread (nullptr),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
{
// command -> handler
m_CommandHandlers[BOB_COMMAND_ZAP] = &BOBCommandSession::ZapCommandHandler;
m_CommandHandlers[BOB_COMMAND_QUIT] = &BOBCommandSession::QuitCommandHandler;
m_CommandHandlers[BOB_COMMAND_START] = &BOBCommandSession::StartCommandHandler;
m_CommandHandlers[BOB_COMMAND_STOP] = &BOBCommandSession::StopCommandHandler;
m_CommandHandlers[BOB_COMMAND_SETNICK] = &BOBCommandSession::SetNickCommandHandler;
m_CommandHandlers[BOB_COMMAND_GETNICK] = &BOBCommandSession::GetNickCommandHandler;
m_CommandHandlers[BOB_COMMAND_NEWKEYS] = &BOBCommandSession::NewkeysCommandHandler;
m_CommandHandlers[BOB_COMMAND_GETKEYS] = &BOBCommandSession::GetkeysCommandHandler;
m_CommandHandlers[BOB_COMMAND_SETKEYS] = &BOBCommandSession::SetkeysCommandHandler;
m_CommandHandlers[BOB_COMMAND_GETDEST] = &BOBCommandSession::GetdestCommandHandler;
m_CommandHandlers[BOB_COMMAND_OUTHOST] = &BOBCommandSession::OuthostCommandHandler;
m_CommandHandlers[BOB_COMMAND_OUTPORT] = &BOBCommandSession::OutportCommandHandler;
m_CommandHandlers[BOB_COMMAND_INHOST] = &BOBCommandSession::InhostCommandHandler;
m_CommandHandlers[BOB_COMMAND_INPORT] = &BOBCommandSession::InportCommandHandler;
m_CommandHandlers[BOB_COMMAND_QUIET] = &BOBCommandSession::QuietCommandHandler;
m_CommandHandlers[BOB_COMMAND_LOOKUP] = &BOBCommandSession::LookupCommandHandler;
m_CommandHandlers[BOB_COMMAND_CLEAR] = &BOBCommandSession::ClearCommandHandler;
m_CommandHandlers[BOB_COMMAND_LIST] = &BOBCommandSession::ListCommandHandler;
m_CommandHandlers[BOB_COMMAND_OPTION] = &BOBCommandSession::OptionCommandHandler;
}
BOBCommandChannel::~BOBCommandChannel ()
{
Stop ();
for (auto it: m_Destinations)
delete it.second;
}
void BOBCommandChannel::Start ()
{
Accept ();
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&BOBCommandChannel::Run, this));
}
void BOBCommandChannel::Stop ()
{
m_IsRunning = false;
for (auto it: m_Destinations)
it.second->Stop ();
m_Acceptor.cancel ();
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
void BOBCommandChannel::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint (eLogError, "BOB: ", ex.what ());
}
}
}
void BOBCommandChannel::AddDestination (const std::string& name, BOBDestination * dest)
{
m_Destinations[name] = dest;
}
void BOBCommandChannel::DeleteDestination (const std::string& name)
{
auto it = m_Destinations.find (name);
if (it != m_Destinations.end ())
{
it->second->Stop ();
delete it->second;
m_Destinations.erase (it);
}
}
BOBDestination * BOBCommandChannel::FindDestination (const std::string& name)
{
auto it = m_Destinations.find (name);
if (it != m_Destinations.end ())
return it->second;
return nullptr;
}
void BOBCommandChannel::Accept ()
{
auto newSession = std::make_shared<BOBCommandSession> (*this);
m_Acceptor.async_accept (newSession->GetSocket (), std::bind (&BOBCommandChannel::HandleAccept, this,
std::placeholders::_1, newSession));
}
void BOBCommandChannel::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<BOBCommandSession> session)
{
if (ecode != boost::asio::error::operation_aborted)
Accept ();
if (!ecode)
{
LogPrint (eLogInfo, "New BOB command connection from ", session->GetSocket ().remote_endpoint ());
session->SendVersion ();
}
else
LogPrint (eLogError, "BOB accept error: ", ecode.message ());
}
}
}

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

409
ChangeLog Normal file
View File

@ -0,0 +1,409 @@
# for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog
## [2.28.0] - 2019-08-27
### Added
- RAW datagrams in SAM
- Publishing encrypted LeaseSet2 with DH or PSH authentication
- Ability to disable battery optimization for Android
- Transport Network ID Check
### Changed
- Set and handle published encrypted flag for LeaseSet2
### Fixed
- ReceiveID changes in the same stream
- "\r\n" command terminator in SAM
- Addressbook lines with signatures
## [2.27.0] - 2019-07-03
### Added
- Support of PSK and DH authentication for encrypted LeaseSet2
### Changed
- Uptime is based on monotonic timer
### Fixed
- BOB status command response
- Correct NTCP2 port if NTCP is disabled
- Flood encrypted LeaseSet2 with store hash
## [2.26.0] - 2019-06-07
### Added
- HTTP method "PROPFIND"
- Detection of external ipv6 address through the SSU
- NTCP2 publishing depends on network status
### Changed
- ntcp is disabled by default, ntcp2 is published by default
- Response to BOB's "list" command
- ipv6 address is not longer NTCP's local endpoint's address
- Reseeds list
- HTTP_REFERER stripping in httpproxy (#823)
### Fixed
- Check and handle incorrect BOB input
- Ignore introducers for NTCP or NTCP2 addresses
- RouterInfo check from NTCP2
## [2.25.0] - 2019-05-09
### Added
- Create, publish and handle encrypted LeaseSet2
- Support of b33 addresses
- RedDSA key blinding
- .b32.i2p addresses in jump links
- ntcp2.addressv6 parameter
### Changed
- Allow HTTP headers without value
- Set data directory from external storage path for Android
- addresshelper support is configurable per tunnel
- gradlew script for android build
### Fixed
- Deletion of expired encrypted LeaseSet2 on floodfills
- ipv6 fallback address
- SSU incoming packets routing
## [2.24.0] - 2019-03-21
### Added
- Support of transient keys for LeaseSet2
- Support of encrypted LeaseSet2
- Recognize signature type 11 (RedDSA)
- Support websocket connections over HTTP proxy
- Ability to disable full addressbook persist
### Changed
- Don't load peer profiles if non-persistant
- REUSE_ADDR for ipv6 acceptors
- Reset eTags if addressbook can't be loaded
### Fixed
- Build with boost 1.70
- Filter out unspecified addresses from RouterInfo
- Check floodfill status change
- Correct SAM response for invalid key
- SAM crash on termination for Windows
- Race condition for publishing
## [2.23.0] - 2019-01-21
### Added
- Standard LeaseSet2 support
- Ability to adjust timestamps through the NTP
- Ability to disable peer profile persist
- Request permission for android >= 6
- Initial addressbook to android assets
- Cancel graceful shutdown for android
- Russian translation for android
### Changed
- Chacha20 and Poly1305 implementation
- Eliminate extra copy of NTCP2 send buffers
- Extract content of tunnel.d from assets on android
- Removed name resolvers from transports
- Update reseed certificates
### Fixed
- LeaseSet published content verification
- Exclude invalid LeaseSets from the list on a floodfill
- Build for OpenWrt with openssl 1.1.1
## [2.22.0] - 2018-11-09
### Added
- Multiple tunnel config files from tunnels.d folder
### Changed
- Fetch own RouterInfo upon SessionRequest for NTCP2
- Faster XOR between AES blocks for non AVX capable CPUs
### Fixed
- Fixed NTCP2 termination send
## [2.21.1] - 2018-10-22
### Changed
- cost=13 for unpublished NTCP2 address
### Fixed
- Handle I2NP messages longer than 32K
## [2.21.0] - 2018-10-04
### Added
- EdDSA, x25519 and SipHash from openssl 1.1.1
- NTCP2 ipv6 incoming connections
- Show total number of destination's outgoing tags in the web console
### Changed
- Android build with openssl 1.1.1/boost 1.64
- Bandwidth classes 'P' and 'X' don't add 'O' anymore
### Fixed
- Update own RouterInfo if no SSU
- Recognize 'P' and 'X' routers as high bandwidth without 'O'
- NTCP address doesn't disappear if NTCP2 enabled
- Android with api 26+
## [2.20.0] - 2018-08-23
### Added
- Full implementation of NTCP2
- Assets for android
### Changed
- armeabi-v7a and x86 in one apk for android
- NTCP2 is enabled by default
- Show lease's expiration time in readable format in the web console
### Fixed
- Correct names for transports in the web console
## [2.19.0] - 2018-06-26
### 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,562 +0,0 @@
#include <time.h>
#include <stdio.h>
#include <openssl/sha.h>
#include <openssl/dh.h>
#include <openssl/rand.h>
#include "Crypto.h"
#include "I2PEndian.h"
#include "Log.h"
#include "Identity.h"
namespace i2p
{
namespace data
{
Identity& Identity::operator=(const Keys& keys)
{
// copy public and signing keys together
memcpy (publicKey, keys.publicKey, sizeof (publicKey) + sizeof (signingKey));
memset (&certificate, 0, sizeof (certificate));
return *this;
}
size_t Identity::FromBuffer (const uint8_t * buf, size_t len)
{
memcpy (publicKey, buf, DEFAULT_IDENTITY_SIZE);
return DEFAULT_IDENTITY_SIZE;
}
IdentHash Identity::Hash () const
{
IdentHash hash;
SHA256(publicKey, DEFAULT_IDENTITY_SIZE, hash);
return hash;
}
IdentityEx::IdentityEx ():
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
}
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type)
{
memcpy (m_StandardIdentity.publicKey, publicKey, sizeof (m_StandardIdentity.publicKey));
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
{
size_t excessLen = 0;
uint8_t * excessBuf = nullptr;
switch (type)
{
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
{
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
RAND_bytes (m_StandardIdentity.signingKey, padding);
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH);
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
{
size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96
RAND_bytes (m_StandardIdentity.signingKey, padding);
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP384_KEY_LENGTH);
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
{
memcpy (m_StandardIdentity.signingKey, signingKey, 128);
excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132 - 128
excessBuf = new uint8_t[excessLen];
memcpy (excessBuf, signingKey + 128, excessLen);
break;
}
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
{
memcpy (m_StandardIdentity.signingKey, signingKey, 128);
excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256 - 128
excessBuf = new uint8_t[excessLen];
memcpy (excessBuf, signingKey + 128, excessLen);
break;
}
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
{
memcpy (m_StandardIdentity.signingKey, signingKey, 128);
excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384 - 128
excessBuf = new uint8_t[excessLen];
memcpy (excessBuf, signingKey + 128, excessLen);
break;
}
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
{
memcpy (m_StandardIdentity.signingKey, signingKey, 128);
excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512 - 128
excessBuf = new uint8_t[excessLen];
memcpy (excessBuf, signingKey + 128, excessLen);
break;
}
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
{
size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32
RAND_bytes (m_StandardIdentity.signingKey, padding);
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH);
break;
}
default:
LogPrint ("Signing key type ", (int)type, " is not supported");
}
m_ExtendedLen = 4 + excessLen; // 4 bytes extra + excess length
// fill certificate
m_StandardIdentity.certificate.type = CERTIFICATE_TYPE_KEY;
m_StandardIdentity.certificate.length = htobe16 (m_ExtendedLen);
// fill extended buffer
m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
htobe16buf (m_ExtendedBuffer, type);
htobe16buf (m_ExtendedBuffer + 2, CRYPTO_KEY_TYPE_ELGAMAL);
if (excessLen && excessBuf)
{
memcpy (m_ExtendedBuffer + 4, excessBuf, excessLen);
delete[] excessBuf;
}
// calculate ident hash
uint8_t * buf = new uint8_t[GetFullLen ()];
ToBuffer (buf, GetFullLen ());
SHA256(buf, GetFullLen (), m_IdentHash);
delete[] buf;
}
else // DSA-SHA1
{
memcpy (m_StandardIdentity.signingKey, signingKey, sizeof (m_StandardIdentity.signingKey));
memset (&m_StandardIdentity.certificate, 0, sizeof (m_StandardIdentity.certificate));
m_IdentHash = m_StandardIdentity.Hash ();
m_ExtendedLen = 0;
m_ExtendedBuffer = nullptr;
}
CreateVerifier ();
}
IdentityEx::IdentityEx (const uint8_t * buf, size_t len):
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
FromBuffer (buf, len);
}
IdentityEx::IdentityEx (const IdentityEx& other):
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
*this = other;
}
IdentityEx::IdentityEx (const Identity& standard):
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
*this = standard;
}
IdentityEx::~IdentityEx ()
{
delete[] m_ExtendedBuffer;
}
IdentityEx& IdentityEx::operator=(const IdentityEx& other)
{
memcpy (&m_StandardIdentity, &other.m_StandardIdentity, DEFAULT_IDENTITY_SIZE);
m_IdentHash = other.m_IdentHash;
delete[] m_ExtendedBuffer;
m_ExtendedLen = other.m_ExtendedLen;
if (m_ExtendedLen > 0)
{
m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen);
}
else
m_ExtendedBuffer = nullptr;
m_Verifier = nullptr;
return *this;
}
IdentityEx& IdentityEx::operator=(const Identity& standard)
{
m_StandardIdentity = standard;
m_IdentHash = m_StandardIdentity.Hash ();
delete[] m_ExtendedBuffer;
m_ExtendedBuffer = nullptr;
m_ExtendedLen = 0;
m_Verifier = nullptr;
return *this;
}
size_t IdentityEx::FromBuffer (const uint8_t * buf, size_t len)
{
if (len < DEFAULT_IDENTITY_SIZE)
{
LogPrint (eLogError, "Identity buffer length ", len, " is too small");
return 0;
}
memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE);
delete[] m_ExtendedBuffer;
if (m_StandardIdentity.certificate.length)
{
m_ExtendedLen = be16toh (m_StandardIdentity.certificate.length);
if (m_ExtendedLen + DEFAULT_IDENTITY_SIZE <= len)
{
m_ExtendedBuffer = new uint8_t[m_ExtendedLen];
memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen);
}
else
{
LogPrint (eLogError, "Certificate length ", m_ExtendedLen, " exceeds buffer length ", len - DEFAULT_IDENTITY_SIZE);
return 0;
}
}
else
{
m_ExtendedLen = 0;
m_ExtendedBuffer = nullptr;
}
SHA256(buf, GetFullLen (), m_IdentHash);
m_Verifier = nullptr;
return GetFullLen ();
}
size_t IdentityEx::ToBuffer (uint8_t * buf, size_t len) const
{
memcpy (buf, &m_StandardIdentity, DEFAULT_IDENTITY_SIZE);
if (m_ExtendedLen > 0 && m_ExtendedBuffer)
memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBuffer, m_ExtendedLen);
return GetFullLen ();
}
size_t IdentityEx::FromBase64(const std::string& s)
{
uint8_t buf[1024];
auto len = Base64ToByteStream (s.c_str(), s.length(), buf, 1024);
return FromBuffer (buf, len);
}
std::string IdentityEx::ToBase64 () const
{
uint8_t buf[1024];
char str[1536];
size_t l = ToBuffer (buf, 1024);
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, str, 1536);
str[l1] = 0;
return std::string (str);
}
size_t IdentityEx::GetSigningPublicKeyLen () const
{
if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->GetPublicKeyLen ();
return 128;
}
size_t IdentityEx::GetSigningPrivateKeyLen () const
{
if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->GetPrivateKeyLen ();
return GetSignatureLen ()/2;
}
size_t IdentityEx::GetSignatureLen () const
{
if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->GetSignatureLen ();
return 40;
}
bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
if (!m_Verifier) CreateVerifier ();
if (m_Verifier)
return m_Verifier->Verify (buf, len, signature);
return false;
}
SigningKeyType IdentityEx::GetSigningKeyType () const
{
if (m_StandardIdentity.certificate.type == CERTIFICATE_TYPE_KEY && m_ExtendedBuffer)
return bufbe16toh (m_ExtendedBuffer); // signing key
return SIGNING_KEY_TYPE_DSA_SHA1;
}
CryptoKeyType IdentityEx::GetCryptoKeyType () const
{
if (m_StandardIdentity.certificate.type == CERTIFICATE_TYPE_KEY && m_ExtendedBuffer)
return bufbe16toh (m_ExtendedBuffer + 2); // crypto key
return CRYPTO_KEY_TYPE_ELGAMAL;
}
void IdentityEx::CreateVerifier () const
{
auto keyType = GetSigningKeyType ();
switch (keyType)
{
case SIGNING_KEY_TYPE_DSA_SHA1:
m_Verifier.reset (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey));
break;
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
{
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
m_Verifier.reset (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding));
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
{
size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96
m_Verifier.reset (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding));
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
{
uint8_t signingKey[i2p::crypto::ECDSAP521_KEY_LENGTH];
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
m_Verifier.reset (new i2p::crypto::ECDSAP521Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
{
uint8_t signingKey[i2p::crypto::RSASHA2562048_KEY_LENGTH];
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
m_Verifier.reset (new i2p::crypto:: RSASHA2562048Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
{
uint8_t signingKey[i2p::crypto::RSASHA3843072_KEY_LENGTH];
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
m_Verifier.reset (new i2p::crypto:: RSASHA3843072Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
{
uint8_t signingKey[i2p::crypto::RSASHA5124096_KEY_LENGTH];
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
m_Verifier.reset (new i2p::crypto:: RSASHA5124096Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
{
size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32
m_Verifier.reset (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding));
break;
}
default:
LogPrint ("Signing key type ", (int)keyType, " is not supported");
}
}
void IdentityEx::DropVerifier () const
{
m_Verifier = nullptr;
}
PrivateKeys& PrivateKeys::operator=(const Keys& keys)
{
m_Public = std::make_shared<IdentityEx>(Identity (keys));
memcpy (m_PrivateKey, keys.privateKey, 256); // 256
memcpy (m_SigningPrivateKey, keys.signingPrivateKey, m_Public->GetSigningPrivateKeyLen ());
m_Signer = nullptr;
CreateSigner ();
return *this;
}
PrivateKeys& PrivateKeys::operator=(const PrivateKeys& other)
{
m_Public = std::make_shared<IdentityEx>(*other.m_Public);
memcpy (m_PrivateKey, other.m_PrivateKey, 256); // 256
memcpy (m_SigningPrivateKey, other.m_SigningPrivateKey, m_Public->GetSigningPrivateKeyLen ());
m_Signer = nullptr;
CreateSigner ();
return *this;
}
size_t PrivateKeys::FromBuffer (const uint8_t * buf, size_t len)
{
m_Public = std::make_shared<IdentityEx>(buf, len);
size_t ret = m_Public->GetFullLen ();
memcpy (m_PrivateKey, buf + ret, 256); // private key always 256
ret += 256;
size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen ();
memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize);
ret += signingPrivateKeySize;
m_Signer = nullptr;
CreateSigner ();
return ret;
}
size_t PrivateKeys::ToBuffer (uint8_t * buf, size_t len) const
{
size_t ret = m_Public->ToBuffer (buf, len);
memcpy (buf + ret, m_PrivateKey, 256); // private key always 256
ret += 256;
size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen ();
memcpy (buf + ret, m_SigningPrivateKey, signingPrivateKeySize);
ret += signingPrivateKeySize;
return ret;
}
size_t PrivateKeys::FromBase64(const std::string& s)
{
uint8_t * buf = new uint8_t[s.length ()];
size_t l = i2p::data::Base64ToByteStream (s.c_str (), s.length (), buf, s.length ());
size_t ret = FromBuffer (buf, l);
delete[] buf;
return ret;
}
std::string PrivateKeys::ToBase64 () const
{
uint8_t * buf = new uint8_t[GetFullLen ()];
char * str = new char[GetFullLen ()*2];
size_t l = ToBuffer (buf, GetFullLen ());
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, str, GetFullLen ()*2);
str[l1] = 0;
delete[] buf;
std::string ret(str);
delete[] str;
return ret;
}
void PrivateKeys::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
if (m_Signer)
m_Signer->Sign (buf, len, signature);
}
void PrivateKeys::CreateSigner ()
{
switch (m_Public->GetSigningKeyType ())
{
case SIGNING_KEY_TYPE_DSA_SHA1:
m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
m_Signer.reset (new i2p::crypto::ECDSAP256Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
m_Signer.reset (new i2p::crypto::ECDSAP384Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
m_Signer.reset (new i2p::crypto::ECDSAP521Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
m_Signer.reset (new i2p::crypto::RSASHA2562048Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
m_Signer.reset (new i2p::crypto::RSASHA3843072Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
m_Signer.reset (new i2p::crypto::RSASHA5124096Signer (m_SigningPrivateKey));
break;
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey));
break;
default:
LogPrint ("Signing key type ", (int)m_Public->GetSigningKeyType (), " is not supported");
}
}
PrivateKeys PrivateKeys::CreateRandomKeys (SigningKeyType type)
{
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
{
PrivateKeys keys;
// signature
uint8_t signingPublicKey[512]; // signing public key is 512 bytes max
switch (type)
{
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
i2p::crypto::CreateECDSAP256RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
break;
case SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
i2p::crypto::CreateECDSAP384RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
break;
case SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
i2p::crypto::CreateECDSAP521RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
break;
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
i2p::crypto::CreateRSARandomKeys (i2p::crypto::RSASHA2562048_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey);
break;
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
i2p::crypto::CreateRSARandomKeys (i2p::crypto::RSASHA3843072_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey);
break;
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
i2p::crypto::CreateRSARandomKeys (i2p::crypto::RSASHA5124096_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey);
break;
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
break;
default:
LogPrint ("Signing key type ", (int)type, " is not supported. Create DSA-SHA1");
return PrivateKeys (i2p::data::CreateRandomKeys ()); // DSA-SHA1
}
// encryption
uint8_t publicKey[256];
i2p::crypto::GenerateElGamalKeyPair (keys.m_PrivateKey, publicKey);
// identity
keys.m_Public = std::make_shared<IdentityEx> (publicKey, signingPublicKey, type);
keys.CreateSigner ();
return keys;
}
return PrivateKeys (i2p::data::CreateRandomKeys ()); // DSA-SHA1
}
Keys CreateRandomKeys ()
{
Keys keys;
// encryption
i2p::crypto::GenerateElGamalKeyPair(keys.privateKey, keys.publicKey);
// signing
i2p::crypto::CreateDSARandomKeys (keys.signingPrivateKey, keys.signingKey);
return keys;
}
IdentHash CreateRoutingKey (const IdentHash& ident)
{
uint8_t buf[41]; // ident + yyyymmdd
memcpy (buf, (const uint8_t *)ident, 32);
time_t t = time (nullptr);
struct tm tm;
#ifdef _WIN32
gmtime_s(&tm, &t);
sprintf_s((char *)(buf + 32), 9, "%04i%02i%02i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
#else
gmtime_r(&t, &tm);
sprintf((char *)(buf + 32), "%04i%02i%02i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
#endif
IdentHash key;
SHA256(buf, 40, key);
return key;
}
XORMetric operator^(const IdentHash& key1, const IdentHash& key2)
{
XORMetric m;
const uint64_t * hash1 = key1.GetLL (), * hash2 = key2.GetLL ();
m.metric_ll[0] = hash1[0] ^ hash2[0];
m.metric_ll[1] = hash1[1] ^ hash2[1];
m.metric_ll[2] = hash1[2] ^ hash2[2];
m.metric_ll[3] = hash1[3] ^ hash2[3];
return m;
}
}
}

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,61 @@ 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-9]"),1) # gcc >= 5
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,56 @@
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
INCFLAGS = -Idaemon -I.
LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++
# Boost libraries suffix
BOOST_SUFFIX = -mt
# 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");
}
}
}

224
README.md
View File

@ -1,145 +1,95 @@
[![GitHub release](https://img.shields.io/github/release/PurpleI2P/i2pd.svg?label=latest%20release)](https://github.com/PurpleI2P/i2pd/releases/latest)
[![Snapcraft release](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd)
[![License](https://img.shields.io/github/license/PurpleI2P/i2pd.svg)](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE)
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 packages and binaries.
You can fetch most of them on [release](https://github.com/PurpleI2P/i2pd/releases/latest) page.
Please see [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/install/) for more info.
Building
--------
See [documentation](https://i2pd.readthedocs.io/en/latest/) for how to build
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 - [![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 / Mageia - [![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/)
* Snap - [![Snap Status](https://build.snapcraft.io/badge/PurpleI2P/i2pd-snap.svg)](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap)
* 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;
}
}
}

View File

@ -1,192 +0,0 @@
#ifndef ROUTER_INFO_H__
#define ROUTER_INFO_H__
#include <inttypes.h>
#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <boost/asio.hpp>
#include "Identity.h"
#include "Profiling.h"
namespace i2p
{
namespace data
{
const char CAPS_FLAG_FLOODFILL = 'f';
const char CAPS_FLAG_HIDDEN = 'H';
const char CAPS_FLAG_REACHABLE = 'R';
const char CAPS_FLAG_UNREACHABLE = 'U';
const char CAPS_FLAG_LOW_BANDWIDTH1 = 'K';
const char CAPS_FLAG_LOW_BANDWIDTH2 = 'L';
const char CAPS_FLAG_HIGH_BANDWIDTH1 = 'M';
const char CAPS_FLAG_HIGH_BANDWIDTH2 = 'N';
const char CAPS_FLAG_HIGH_BANDWIDTH3 = 'O';
const char CAPS_FLAG_SSU_TESTING = 'B';
const char CAPS_FLAG_SSU_INTRODUCER = 'C';
const int MAX_RI_BUFFER_SIZE = 2048;
class RouterInfo: public RoutingDestination
{
public:
enum SupportedTranports
{
eNTCPV4 = 0x01,
eNTCPV6 = 0x02,
eSSUV4 = 0x04,
eSSUV6 = 0x08
};
enum Caps
{
eFloodfill = 0x01,
eHighBandwidth = 0x02,
eReachable = 0x04,
eSSUTesting = 0x08,
eSSUIntroducer = 0x10,
eHidden = 0x20,
eUnreachable = 0x40
};
enum TransportStyle
{
eTransportUnknown = 0,
eTransportNTCP,
eTransportSSU
};
typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
struct Introducer
{
boost::asio::ip::address iHost;
int iPort;
IntroKey iKey;
uint32_t iTag;
};
struct Address
{
TransportStyle transportStyle;
boost::asio::ip::address host;
std::string addressString;
int port, mtu;
uint64_t date;
uint8_t cost;
// SSU only
IntroKey key; // intro key for SSU
std::vector<Introducer> introducers;
bool IsCompatible (const boost::asio::ip::address& other) const
{
return (host.is_v4 () && other.is_v4 ()) ||
(host.is_v6 () && other.is_v6 ());
}
bool operator==(const Address& other) const
{
return transportStyle == other.transportStyle && host == other.host && port == other.port;
}
bool operator!=(const Address& other) const
{
return !(*this == other);
}
};
RouterInfo (const std::string& fullPath);
RouterInfo (): m_Buffer (nullptr) { };
RouterInfo (const RouterInfo& ) = default;
RouterInfo& operator=(const RouterInfo& ) = default;
RouterInfo (const uint8_t * buf, int len);
~RouterInfo ();
std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
uint64_t GetTimestamp () const { return m_Timestamp; };
std::vector<Address>& GetAddresses () { return m_Addresses; };
const Address * GetNTCPAddress (bool v4only = true) const;
const Address * GetSSUAddress (bool v4only = true) const;
const Address * GetSSUV6Address () const;
void AddNTCPAddress (const char * host, int port);
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
bool AddIntroducer (const Introducer& introducer);
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only
void DeleteProperty (const std::string& key); // called from RouterContext only
void ClearProperties () { m_Properties.clear (); };
bool IsFloodfill () const;
bool IsNTCP (bool v4only = true) const;
bool IsSSU (bool v4only = true) const;
bool IsV6 () const;
void EnableV6 ();
void DisableV6 ();
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
bool UsesIntroducer () const;
bool IsIntroducer () const { return m_Caps & eSSUIntroducer; };
bool IsPeerTesting () const { return m_Caps & eSSUTesting; };
bool IsHidden () const { return m_Caps & eHidden; };
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };
uint8_t GetCaps () const { return m_Caps; };
void SetCaps (uint8_t caps);
void SetCaps (const char * caps);
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
bool IsUnreachable () const { return m_IsUnreachable; };
const uint8_t * GetBuffer () const { return m_Buffer; };
const uint8_t * LoadBuffer (); // load if necessary
int GetBufferLen () const { return m_BufferLen; };
void CreateBuffer (const PrivateKeys& privateKeys);
bool IsUpdated () const { return m_IsUpdated; };
void SetUpdated (bool updated) { m_IsUpdated = updated; };
void SaveToFile (const std::string& fullPath);
std::shared_ptr<RouterProfile> GetProfile () const;
void SaveProfile () { if (m_Profile) m_Profile->Save (); };
void Update (const uint8_t * buf, int len);
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
// implements RoutingDestination
const IdentHash& GetIdentHash () const { return m_RouterIdentity->GetIdentHash (); };
const uint8_t * GetEncryptionPublicKey () const { return m_RouterIdentity->GetStandardIdentity ().publicKey; };
bool IsDestination () const { return false; };
private:
bool LoadFile ();
void ReadFromFile ();
void ReadFromStream (std::istream& s);
void ReadFromBuffer (bool verifySignature);
void WriteToStream (std::ostream& s);
size_t ReadString (char * str, std::istream& s);
void WriteString (const std::string& str, std::ostream& s);
void ExtractCaps (const char * value);
const Address * GetAddress (TransportStyle s, bool v4only, bool v6only = false) const;
void UpdateCapsProperty ();
private:
std::string m_FullPath;
std::shared_ptr<const IdentityEx> m_RouterIdentity;
uint8_t * m_Buffer;
int m_BufferLen;
uint64_t m_Timestamp;
std::vector<Address> m_Addresses;
std::map<std::string, std::string> m_Properties;
bool m_IsUpdated, m_IsUnreachable;
uint8_t m_SupportedTransports, m_Caps;
mutable std::shared_ptr<RouterProfile> m_Profile;
};
}
}
#endif

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,452 +0,0 @@
#ifndef SIGNATURE_H__
#define SIGNATURE_H__
#include <inttypes.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/rsa.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include "Crypto.h"
namespace i2p
{
namespace crypto
{
class Verifier
{
public:
virtual ~Verifier () {};
virtual bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const = 0;
virtual size_t GetPublicKeyLen () const = 0;
virtual size_t GetSignatureLen () const = 0;
virtual size_t GetPrivateKeyLen () const { return GetSignatureLen ()/2; };
};
class Signer
{
public:
virtual ~Signer () {};
virtual void Sign (const uint8_t * buf, int len, uint8_t * signature) const = 0;
};
const size_t DSA_PUBLIC_KEY_LENGTH = 128;
const size_t DSA_SIGNATURE_LENGTH = 40;
const size_t DSA_PRIVATE_KEY_LENGTH = DSA_SIGNATURE_LENGTH/2;
class DSAVerifier: public Verifier
{
public:
DSAVerifier (const uint8_t * signingKey)
{
m_PublicKey = DSA_new ();
m_PublicKey->p = BN_dup (dsap);
m_PublicKey->q = BN_dup (dsaq);
m_PublicKey->g = BN_dup (dsag);
m_PublicKey->priv_key = NULL;
m_PublicKey->pub_key = BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL);
}
~DSAVerifier ()
{
DSA_free (m_PublicKey);
}
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
// calculate SHA1 digest
uint8_t digest[20];
SHA1 (buf, len, digest);
// signature
DSA_SIG * sig = DSA_SIG_new();
sig->r = BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL);
sig->s = BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL);
// DSA verification
int ret = DSA_do_verify (digest, 20, sig, m_PublicKey);
DSA_SIG_free(sig);
return ret;
}
size_t GetPublicKeyLen () const { return DSA_PUBLIC_KEY_LENGTH; };
size_t GetSignatureLen () const { return DSA_SIGNATURE_LENGTH; };
private:
DSA * m_PublicKey;
};
class DSASigner: public Signer
{
public:
DSASigner (const uint8_t * signingPrivateKey)
{
m_PrivateKey = DSA_new ();
m_PrivateKey->p = BN_dup (dsap);
m_PrivateKey->q = BN_dup (dsaq);
m_PrivateKey->g = BN_dup (dsag);
m_PrivateKey->priv_key = BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL);
m_PrivateKey->pub_key = NULL;
}
~DSASigner ()
{
DSA_free (m_PrivateKey);
}
void Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
uint8_t digest[20];
SHA1 (buf, len, digest);
DSA_SIG * sig = DSA_do_sign (digest, 20, m_PrivateKey);
bn2buf (sig->r, signature, DSA_SIGNATURE_LENGTH/2);
bn2buf (sig->s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2);
DSA_SIG_free(sig);
}
private:
DSA * m_PrivateKey;
};
inline void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
DSA * dsa = DSA_new ();
dsa->p = BN_dup (dsap);
dsa->q = BN_dup (dsaq);
dsa->g = BN_dup (dsag);
dsa->priv_key = NULL;
dsa->pub_key = NULL;
DSA_generate_key (dsa);
bn2buf (dsa->priv_key, signingPrivateKey, DSA_PRIVATE_KEY_LENGTH);
bn2buf (dsa->pub_key, signingPublicKey, DSA_PUBLIC_KEY_LENGTH);
DSA_free (dsa);
}
struct SHA256Hash
{
static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
{
SHA256 (buf, len, digest);
}
enum { hashLen = 32 };
};
struct SHA384Hash
{
static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
{
SHA384 (buf, len, digest);
}
enum { hashLen = 48 };
};
struct SHA512Hash
{
static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
{
SHA512 (buf, len, digest);
}
enum { hashLen = 64 };
};
template<typename Hash, int curve, size_t keyLen>
class ECDSAVerifier: public Verifier
{
public:
ECDSAVerifier (const uint8_t * signingKey)
{
m_PublicKey = EC_KEY_new_by_curve_name (curve);
EC_KEY_set_public_key_affine_coordinates (m_PublicKey,
BN_bin2bn (signingKey, keyLen/2, NULL),
BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL));
}
~ECDSAVerifier ()
{
EC_KEY_free (m_PublicKey);
}
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
uint8_t digest[Hash::hashLen];
Hash::CalculateHash (buf, len, digest);
ECDSA_SIG * sig = ECDSA_SIG_new();
sig->r = BN_bin2bn (signature, GetSignatureLen ()/2, NULL);
sig->s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL);
// ECDSA verification
int ret = ECDSA_do_verify (digest, Hash::hashLen, sig, m_PublicKey);
ECDSA_SIG_free(sig);
return ret;
}
size_t GetPublicKeyLen () const { return keyLen; };
size_t GetSignatureLen () const { return keyLen; }; // signature length = key length
private:
EC_KEY * m_PublicKey;
};
template<typename Hash, int curve, size_t keyLen>
class ECDSASigner: public Signer
{
public:
ECDSASigner (const uint8_t * signingPrivateKey)
{
m_PrivateKey = EC_KEY_new_by_curve_name (curve);
EC_KEY_set_private_key (m_PrivateKey, BN_bin2bn (signingPrivateKey, keyLen/2, NULL));
}
~ECDSASigner ()
{
EC_KEY_free (m_PrivateKey);
}
void Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
uint8_t digest[Hash::hashLen];
Hash::CalculateHash (buf, len, digest);
ECDSA_SIG * sig = ECDSA_do_sign (digest, Hash::hashLen, m_PrivateKey);
// signatureLen = keyLen
bn2buf (sig->r, signature, keyLen/2);
bn2buf (sig->s, signature + keyLen/2, keyLen/2);
ECDSA_SIG_free(sig);
}
private:
EC_KEY * m_PrivateKey;
};
inline void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
EC_KEY * signingKey = EC_KEY_new_by_curve_name (curve);
EC_KEY_generate_key (signingKey);
bn2buf (EC_KEY_get0_private_key (signingKey), signingPrivateKey, keyLen/2);
BIGNUM * x = BN_new(), * y = BN_new();
EC_POINT_get_affine_coordinates_GFp (EC_KEY_get0_group(signingKey),
EC_KEY_get0_public_key (signingKey), x, y, NULL);
bn2buf (x, signingPublicKey, keyLen/2);
bn2buf (y, signingPublicKey + keyLen/2, keyLen/2);
BN_free (x); BN_free (y);
EC_KEY_free (signingKey);
}
// ECDSA_SHA256_P256
const size_t ECDSAP256_KEY_LENGTH = 64;
typedef ECDSAVerifier<SHA256Hash, NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH> ECDSAP256Verifier;
typedef ECDSASigner<SHA256Hash, NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH> ECDSAP256Signer;
inline void CreateECDSAP256RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// ECDSA_SHA384_P384
const size_t ECDSAP384_KEY_LENGTH = 96;
typedef ECDSAVerifier<SHA384Hash, NID_secp384r1, ECDSAP384_KEY_LENGTH> ECDSAP384Verifier;
typedef ECDSASigner<SHA384Hash, NID_secp384r1, ECDSAP384_KEY_LENGTH> ECDSAP384Signer;
inline void CreateECDSAP384RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys (NID_secp384r1, ECDSAP384_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// ECDSA_SHA512_P521
const size_t ECDSAP521_KEY_LENGTH = 132;
typedef ECDSAVerifier<SHA512Hash, NID_secp521r1, ECDSAP521_KEY_LENGTH> ECDSAP521Verifier;
typedef ECDSASigner<SHA512Hash, NID_secp521r1, ECDSAP521_KEY_LENGTH> ECDSAP521Signer;
inline void CreateECDSAP521RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// RSA
template<typename Hash, int type, size_t keyLen>
class RSAVerifier: public Verifier
{
public:
RSAVerifier (const uint8_t * signingKey)
{
m_PublicKey = RSA_new ();
memset (m_PublicKey, 0, sizeof (RSA));
m_PublicKey->e = BN_dup (rsae);
m_PublicKey->n = BN_bin2bn (signingKey, keyLen, NULL);
}
~RSAVerifier ()
{
RSA_free (m_PublicKey);
}
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
uint8_t digest[Hash::hashLen];
Hash::CalculateHash (buf, len, digest);
return RSA_verify (type, digest, Hash::hashLen, signature, GetSignatureLen (), m_PublicKey);
}
size_t GetPublicKeyLen () const { return keyLen; }
size_t GetSignatureLen () const { return keyLen; }
size_t GetPrivateKeyLen () const { return GetSignatureLen ()*2; };
private:
RSA * m_PublicKey;
};
template<typename Hash, int type, size_t keyLen>
class RSASigner: public Signer
{
public:
RSASigner (const uint8_t * signingPrivateKey)
{
m_PrivateKey = RSA_new ();
memset (m_PrivateKey, 0, sizeof (RSA));
m_PrivateKey->e = BN_dup (rsae);
m_PrivateKey->n = BN_bin2bn (signingPrivateKey, keyLen, NULL);
m_PrivateKey->d = BN_bin2bn (signingPrivateKey + keyLen, keyLen, NULL);
}
~RSASigner ()
{
RSA_free (m_PrivateKey);
}
void Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
uint8_t digest[Hash::hashLen];
Hash::CalculateHash (buf, len, digest);
unsigned int signatureLen = keyLen;
RSA_sign (type, digest, Hash::hashLen, signature, &signatureLen, m_PrivateKey);
}
private:
RSA * m_PrivateKey;
};
inline void CreateRSARandomKeys (size_t publicKeyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
RSA * rsa = RSA_new ();
RSA_generate_key_ex (rsa, publicKeyLen*8, rsae, NULL);
bn2buf (rsa->n, signingPrivateKey, publicKeyLen);
bn2buf (rsa->d, signingPrivateKey + publicKeyLen, publicKeyLen);
bn2buf (rsa->n, signingPublicKey, publicKeyLen);
RSA_free (rsa);
}
// RSA_SHA256_2048
const size_t RSASHA2562048_KEY_LENGTH = 256;
typedef RSAVerifier<SHA256Hash, NID_sha256, RSASHA2562048_KEY_LENGTH> RSASHA2562048Verifier;
typedef RSASigner<SHA256Hash, NID_sha256, RSASHA2562048_KEY_LENGTH> RSASHA2562048Signer;
// RSA_SHA384_3072
const size_t RSASHA3843072_KEY_LENGTH = 384;
typedef RSAVerifier<SHA384Hash, NID_sha384, RSASHA3843072_KEY_LENGTH> RSASHA3843072Verifier;
typedef RSASigner<SHA384Hash, NID_sha384, RSASHA3843072_KEY_LENGTH> RSASHA3843072Signer;
// RSA_SHA512_4096
const size_t RSASHA5124096_KEY_LENGTH = 512;
typedef RSAVerifier<SHA512Hash, NID_sha512, RSASHA5124096_KEY_LENGTH> RSASHA5124096Verifier;
typedef RSASigner<SHA512Hash, NID_sha512, RSASHA5124096_KEY_LENGTH> RSASHA5124096Signer;
// EdDSA
struct EDDSAPoint
{
BIGNUM * x, * y;
BIGNUM * z, * t; // projective coordinates
EDDSAPoint (): x(nullptr), y(nullptr), z(nullptr), t(nullptr) {};
EDDSAPoint (EDDSAPoint&& other): x(nullptr), y(nullptr), z(nullptr), t(nullptr)
{ *this = std::move (other); };
EDDSAPoint (BIGNUM * x1, BIGNUM * y1, BIGNUM * z1 = nullptr, BIGNUM * t1 = nullptr): x(x1), y(y1), z(z1), t(t1) {};
~EDDSAPoint () { BN_free (x); BN_free (y); BN_free(z); BN_free(t); };
EDDSAPoint& operator=(EDDSAPoint&& other)
{
if (x) BN_free (x);
if (y) BN_free (y);
if (z) BN_free (z);
if (t) BN_free (t);
x = other.x; other.x = nullptr;
y = other.y; other.y = nullptr;
z = other.z; other.z = nullptr;
t = other.t; other.t = nullptr;
return *this;
}
EDDSAPoint operator-() const
{
BIGNUM * x1 = NULL, * y1 = NULL, * z1 = NULL, * t1 = NULL;
if (x) { x1 = BN_dup (x); BN_set_negative (x1, !BN_is_negative (x)); };
if (y) y1 = BN_dup (y);
if (z) z1 = BN_dup (z);
if (t) { t1 = BN_dup (t); BN_set_negative (t1, !BN_is_negative (t)); };
return EDDSAPoint {x1, y1, z1, t1};
}
};
const size_t EDDSA25519_PUBLIC_KEY_LENGTH = 32;
const size_t EDDSA25519_SIGNATURE_LENGTH = 64;
const size_t EDDSA25519_PRIVATE_KEY_LENGTH = 32;
class EDDSA25519Verifier: public Verifier
{
public:
EDDSA25519Verifier (const uint8_t * signingKey);
~EDDSA25519Verifier () { BN_CTX_free (m_Ctx); };
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; };
size_t GetSignatureLen () const { return EDDSA25519_SIGNATURE_LENGTH; };
private:
BN_CTX * m_Ctx;
EDDSAPoint m_PublicKey;
uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
};
class EDDSA25519Signer: public Signer
{
public:
EDDSA25519Signer (const uint8_t * signingPrivateKey);
~EDDSA25519Signer () { BN_CTX_free (m_Ctx); };
void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; };
private:
BN_CTX * m_Ctx;
uint8_t m_ExpandedPrivateKey[64];
uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
};
inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
EDDSA25519Signer signer (signingPrivateKey);
memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH);
}
}
}
#endif

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,32 +0,0 @@
#ifndef TIMESTAMP_H__
#define TIMESTAMP_H__
#include <inttypes.h>
#include <chrono>
namespace i2p
{
namespace util
{
inline uint64_t GetMillisecondsSinceEpoch ()
{
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count ();
}
inline uint32_t GetHoursSinceEpoch ()
{
return std::chrono::duration_cast<std::chrono::hours>(
std::chrono::system_clock::now().time_since_epoch()).count ();
}
inline uint64_t GetSecondsSinceEpoch ()
{
return std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()).count ();
}
}
}
#endif

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((PSTR)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

454
Win32/Win32App.cpp Normal file
View File

@ -0,0 +1,454 @@
#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_ACCEPT_TRANSIT 2007
#define ID_DECLINE_TRANSIT 2008
#define ID_TRAY_ICON 2050
#define WM_TRAYICON (WM_USER + 1)
#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100
#define FRAME_UPDATE_TIMER 2101
#define IDT_GRACEFUL_TUNNELCHECK_TIMER 2102
namespace i2p
{
namespace win32
{
static DWORD GracefulShutdownEndtime = 0;
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);
if(!i2p::context.AcceptsTunnels())
InsertMenu (hPopup, -1,
i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING,
ID_ACCEPT_TRANSIT, "Accept &transit");
else
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit");
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload configs");
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 ());
if (GracefulShutdownEndtime != 0)
{
DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCount()) / 1000;
s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft);
}
else
s << "\n";
s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; ";
s << "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)
{
static UINT s_uTaskbarRestart;
switch (uMsg)
{
case WM_CREATE:
{
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
AddTrayIcon (hWnd);
break;
}
case WM_CLOSE:
{
RemoveTrayIcon (hWnd);
KillTimer (hWnd, FRAME_UPDATE_TIMER);
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_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_ACCEPT_TRANSIT:
{
i2p::context.SetAcceptsTunnels (true);
std::stringstream text;
text << "I2Pd now accept transit tunnels";
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
return 0;
}
case ID_DECLINE_TRANSIT:
{
i2p::context.SetAcceptsTunnels (false);
std::stringstream text;
text << "I2Pd now decline new transit tunnels";
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
return 0;
}
case ID_GRACEFUL_SHUTDOWN:
{
i2p::context.SetAcceptsTunnels (false);
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second
GracefulShutdownEndtime = GetTickCount() + 10*60*1000;
i2p::util::DaemonWin32::Instance ().isGraceful = true;
return 0;
}
case ID_STOP_GRACEFUL_SHUTDOWN:
{
i2p::context.SetAcceptsTunnels (true);
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER);
GracefulShutdownEndtime = 0;
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:
{
switch(wParam)
{
case IDT_GRACEFUL_SHUTDOWN_TIMER:
{
GracefulShutdownEndtime = 0;
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
return 0;
}
case FRAME_UPDATE_TIMER:
{
InvalidateRect(hWnd, NULL, TRUE);
return 0;
}
case IDT_GRACEFUL_TUNNELCHECK_TIMER:
{
if (i2p::tunnel::tunnels.CountTransitTunnels() == 0)
PostMessage (hWnd, WM_CLOSE, 0, 0);
else
SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr);
return 0;
}
}
break;
}
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;
}
default:
{
if (uMsg == s_uTaskbarRestart)
AddTrayIcon (hWnd);
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,11 @@ void InstallService(PSTR pszServiceName,
FreeHandles(schSCManager, schService);
return;
}
char SvcOpt[] = " --daemon";
strncat(szPath, SvcOpt, strlen(SvcOpt));
// 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 +325,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 +339,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 +357,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

42
Win32/installer.iss Normal file
View File

@ -0,0 +1,42 @@
#define I2Pd_AppName "i2pd"
#define I2Pd_ver "2.28.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
Source: ..\contrib\tunnels.d\*; DestDir: {userappdata}\i2pd\tunnels.d; 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

16
android/.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
gen
tests
bin
libs
log*
obj
.gradle
.idea
.externalNativeBuild
ant.properties
local.properties
build.sh
android.iml
build
*.iml
*.local

52
android/AndroidManifest.xml Executable file
View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.purplei2p.i2pd"
android:installLocation="auto">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<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" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<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>

View File

@ -0,0 +1,693 @@
00.i2p,zmzpltxslembpaupg3srh4bbhv5txgh5jmms6sfj4hzsvlv3xugq
0ipfs.i2p,cdii3ou5mve5sfxyirs6kogt4tbvivk2d6o25awbcbazjrlhjeza
0xcc.i2p,gawouxh2sg32cluwlqsnpy3dwedvoqtfroi4evvdvm2pfv7tdadq
1.fcp.freenet.i2p,cuxbeputgxn75ak4nr7ltp7fjktnzl5sul3wstwnsoytbbpb4ixq
102chan.i2p,xxu3lso4h2rh6wmrxiou3ax7r7la7x6dhoepnku3jvrlwp35pefq
1st.i2p,rduua7bhest6rwsmmyttzssfdw3p4eu6bgl3mb4hin32qo3x5zfq
2.fcp.freenet.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
333.i2p,ctvfe2fimcsdfxmzmd42brnbf7ceenwrbroyjx3wzah5eudjyyza
55cancri.i2p,b4iqenefh2fr4xtuq6civfc6nhnia6e2yo36pf7vcgdvrwmh7xua
adab.i2p,pxjr6f2cig6v7v7ekam3smdnkqgmgseyy5cdwrozdyejm7jknkha
alice.i2p,iq26r2ls2qlkhbn62cvgb6a4iib7m5lkoulohdua5z6uvzlovjtq
always.i2p,wp43sdtuxum6gxbjvyeor35r5yvgtkp3dcu7dv47lx22zeb3relq
amazone.i2p,e6kq73lsxaeyiwpmykdbdo3uy4ppj64bl7y3viegp6mqrilqybqa
amiga.i2p,edy2xappzjjh7bxqounevji4wd2binqkv7gft4usrkan45xhbk5q
amobius.i2p,rj6432agdprun5baai2hj62xfhb4l75uvzl55dhj6z5zzoxv3htq
anarchistfaq.i2p,xosberjz2geveh5dcstztq5kwew6xx2brrqaorkjf2323bjzcd3q
animal.i2p,5iedafy32swqq4t2wcmjb4fvg3onscng7ct7wb237jkvrclaftla
anodex.i2p,25cb5kixhxm6i6c6wequrhi65mez4duc4l5qk6ictbik3tnxlu6a
anoncoin.i2p,nmi3loretkk4zbili32t2e5wyznwoxcsgzmd2z4ll3msgndyqpfa
anongw.i2p,owrnciwubb3f3dctvlmnaknb6tjdxtlzvv7klocb45mmhievdjhq
anonsfw.i2p,ir6hzi66izmvqx3usjl6br3nndkpazonlckrzt3gtltqcy5ralyq
anonymnet.i2p,77ouyl2ane7ffgydosd4ye42g67aomtc4jrusmi76lds5qonlffa
anonynanny.i2p,l2lnhq2dynnmf3m46tcbpcmbbn4kifjgt26go6n2hlapy4drhyja
anonyradio.i2p,cbobsax3rhoyjbk7ii2nd2fnl5bxh3x7bbearokyxgvmudn7o5bq
antipiracyagency.i2p,by4kcmklz7xnkai6ndfio47kts3rndm6wwleegtxghllimikdapq
antipiratbyran.i2p,y2qbhrvuciifbszaqqwxd5t75bomp7kzdqx4yxsrkaq542t75k3a
aosp.i2p,ly7raldsh2na2cgw5yvueyvqqjgx3vbqinecjrqdldgya76i2p2q
arc2.i2p,rnmosuwvtftfcrk5sk7zoyhyadh2g4dhe2mif5ml7qjisgkyw2na
archaicbinarybbs.i2p,t7o2tw36cffedgfr6kahewpkrntofnliuapji2e4rucl3os55epa
archiv.tutorials.i2p,lldr2miowq6353fxy44pnxfk37d6yn2f6kaivzecbmvvnnf5exyq
archive.i2p,x54d5st3dl6mwgfxj6raiekqkypo5pdvuex3n62szwju7hgefiyq
archive.syndie.i2p,abbyu5n3mh3nj7pe3b6byldrxswvva5ttxcafsnnseidanurq3kq
ardor-wallet.i2p,tm23k5ny3umhf6vf3kghnnwacli5zywq5wrr3xcqowbcofuyr4gq
ardvark.i2p,jcmw2sol3hruwc6rfinonx4e23pjkukkg7lg7xt7xb2gpiyyraiq
arf.i2p,o46lsq4u7udxg3qqlidrmpj4lb4nr7ldxmbb2x53nftndaeyxqeq
arkan.i2p,7o5y2lyyrjx5tf6l4fyumywui7msjv5azaaheatvw5sqj7mxbuvq
asciiwhite.i2p,itbzny5ktuenhjwjfqx3jravolhlj5wullhhr2m4qr6k2emnm5dq
aspnet.i2p,tsb7zqru57p4q2a7cto2lko4w5cg4lieglwm6t27c44fkphqmf2a
asylum.i2p,p45ejjw4p2q6nq3mzi6cm6ep35grtzshboidj2lojmrmic22noha
auchan.i2p,6vxz4yp3vhjwbkmxajj7wiikxafwujig63gkhjknbq6xh4rqpm5a
aum.i2p,ohdfneqxapfd3fwfbum4tut7z6k3rnr7rrguoxdrrfe2tln2kpbq
awup.i2p,v6g32duzrkacnrezfbll3pza5u37h7lnukr2wbsk6rqen6prhbga
b.i2p,272kt3gcx6wjurunzaiiwld7s5p4mpjewfubzmlcvw2vie62ckpq
bacardi.i2p,hivhnx2v47vh234c7coi2urj5cyvbl4bu3ypjr7snklortyqeljq
backup.i2p,kepphem42whle3rkfv26wcksmnegdbg6rdp6t3oobdkc2fmzrdkq
badfish.i2p,f6v26gyr4eipy3a7pi2voulw5qvob6dg7zij6xpo2ywbi5tvbu6a
badtoyz.i2p,3qz6ubtwlt2c4iasofjirkckq43u5fgkzyg7mlutcsym5gzhijna
barry.i2p,4kyahq53ol52n23l44tefgeaxqpp3cbb632t5k3umdvqcooevdzq
bash.i2p,s3wouoilbl3mrefxjhp4qoyujgok34e7y6vmpbu6hx4342ivqo4q
bdl.i2p,kp6fnuulenbjm7r26pfbmjcq3u7c7kvxeajodvgr5flcnskdgi5a
bdsm.i2p,pa7fxql5jljegg7j5tglhnnaod2sptq3gxvdn3ji6muqyhgn3poq
betaguru.i2p,d7cduwwhrcc2voameqfkvd66u3advu4jw2p6pysgax35vq6ovriq
beyond.i2p,uaicfqlrpjtitqbqkpfujanj5dollzfzee5glsuls67ekw6hlpoa
bible.i2p,pypz7ca24n3lyp4tm3kvncg3ltp3gd5pgnacc6zltoeffiyyegda
bible4u.i2p,xs6lr2g5jiaajtb3nkno2zmy34eipitrggooxb7wtey7uko7bqmq
bigbrother.i2p,tnxiifs6uticzyg6ac4lhv2l5luwi6xra7yngocro56ive5e4jsq
bitlox.i2p,lqw5khxcdntlv3u4vhn53upcqirplvnc4etjlmoytrzs66ytettq
bittorrent.i2p,pgax2vz572i4zsp6u6paox5xubmjrkqohq6g4hvlp6ruzzy56l5q
bk1k.i2p,nlyegmtyfffo5jfgg5h4dxxnlmqko2g36gpaye5a7vd3is35xxfq
bl.i2p,e73d6uhnfbylza6wqkhxejmqeyfb7thkzw35gn5ojmna64jzyk2a
black.i2p,sjwueu62qpe6dtv5b322k3f23fl4uz3w6qe6wcrwauiwpnymypfq
blackbox.i2p,7josyf7zjieoib3ovmr5a4dh5w64kmfh45lv5h436eljtgfegtqa
blackexchange.i2p,ztgr5kghkyn43fhhkuycroxgfti6cojo3vg4wdd3usqonyvrla5q
blog.curiosity.i2p,yiz6jec5k7ccxdgnh7msqa4ze52bqqmf6rpq6bqdyojra2erd4ta
blog.polecat.i2p,orlccceubewvxo3fbdyydq6e4uuidbs4xd5u2gyqbculnowo3ehq
blog.tinlans.i2p,ylkch2nkrwehakx4z6wiyjbeqwlgasknukdkex6r6yq4xusrjnda
bluebeam.i2p,lvxp3cbcfwtol57d5pmrsck32t7ndutlxubjb4smaf32bynhlk6a
blueheron.i2p,anfb5jrhixjmvkyxctqwkezqer7dbob22wge2bh6wsewbhgnftfa
bnc.i2p,fr4zbcygmx2vdct6nrabakfys4b4derm6jqu2ovppkgqillvlqxa
bob.i2p,i76m7dwm5hnapljendbie6fc5y3mjlkdlduo3tvbwiwmvhxbpyaa
bobcat.i2p,ftuukjtcquuvppt726w37boit7gp5hf2yxwfop35prx3grzzzxlq
bobthebuilder.i2p,qlahgthqhr4uojkkwahnper2cl3ro5f5gtzy5t4lzapbzo4osy6q
boerse.i2p,7633w56hd53sesr6b532r5qlbdnvyl5bnvama6ign6xryaxol4rq
bofh.i2p,auvuinzogu6gc4pwsgbjijuszxgcjygciu2wy53pfz7mo5nfpc5a
boing.i2p,bgsq33bh74j66hn4oh7oovlvuhhdyw22lq2qi2fnv3jyh2ryap3a
books.manveru.i2p,eb2tisc2vr5jvjqrixrozcujiucwxg4m722stxwho5666ipl67zq
bote.i2p,bhjhc3lsdqzoyhxwzyrd63kvyg4br6n2337d74blyintae66mr2a
bozo.i2p,7a2d23h6htprhzrol36vgwgklsbqrnuya4tbaaaspmaeaodt57iq
brittanyworld.i2p,e76umhhic3474sdxiuax25ixyfg7y3z7oojj4fmxvhgv3ruet6aa
bt.i2p,uhkuu54pg47zey76h45tnvsdtpkf5bthbtrjgnaloi5m54h4hlaq
bugfuzz.i2p,ubszn4gsf22vga67rvzzlg4qj2bfcq6o52fmxz46xruawqm6z7rq
burntout.i2p,lkep3fd7tjvxrs25crr2c3jy7xm4s7bqiua5r327zgpw37sgyerq
bytepay.i2p,7amc4ztwkzu3cgsaaaw3223ohuihn5hlsqc6gpf2rxdyptdkyugq
ca.i2pd.i2p,u5safmawcxj5vlrdtqrsqbsndkr5cfenpicgg5euu4xqm73yicba
cases.i2p,kmpmk2fmineaiwublteqlifg4fkmewnhmxqlcgg7qwecz6daj43a
cathugger.i2p,vq43xjjcnejqpzfprws5qzrea2siieshu4tglpdepql2w3w3bpba
cbs.i2p,u3lp7wazvq6opodzwjg5sc5w5kwxehmxd4wcdpt4s4j2k4dx4apq
cerapadus.i2p,zroed2cxga5zeuu6rcvmp2yfi77nzduw7yhdplbeuqkuyxwbrzaq
cerebrum.i2p,u5gtsfn267udwfh2uq35jiabkufifvcbgv456zz34cydutsiw2eq
cgan.i2p,43z65gdr52xe3fxmkumwp3dzhedu4tu4rdtzr24hz5b4awcpfbqa
chat.i2p,ollpwnp6yidc3obbb3famgt6rw5jg5w3k3a6z7hhaegj6gcohiuq
chess.fillament.i2p,tv6wbanei647yf5bie4dhg2wmybkjurezlpdfwftc5ajqlfswwya
chess.i2p,sbnoqznp5yzxals3vs6nzyqaj2fetvonys4e3b3x4ktmfeus54sa
china.i2p,wit6f2zx6dtuqqze6nhbykrds3idppfirxvhf2f7ydqoqf4xdzeq
chitanka.i2p,u4s3jneepk3akoez46kqiwikoezi6zyj2ibjkjyi4uuvsbcojzba
ciaran.i2p,2r3645eete6xwbfu62ogonudcrcgqq25sbnij5v4geru74yrscna
ciphercraft.i2p,7s5pkqbpbfdkxtwuu2e2iwstbikyewvvscy76lij4x5pfbygbjca
closedshop.i2p,6fg67mbw2okopzyonsck4bsy3cy7l2fame56uiysr2cezhjhzdbq
cneal.i2p,g4za73ffigv3ht4jnhzy4dae52djjq7lqcguqsfg3w5cxzqm7nba
co.i2p,3mvo5eifcwplcsoubtvqkzdahwo2sdhfygfdde7lj2glybk4q22q
codevoid.i2p,2mukrqwtinsw27uoejtrz74zxtilyhnnfdyso7j3yo6vaa6nzlaa
colombo-bt.i2p,cyr75zgiu2uuzap5zeosforbgvpfbqos2g6spe4qfulvzpyhnzxa
complication.i2p,x2av6rwj5e5tp64yhdmifdyleo4wblw4ncrrcrabxwscuevpdv7a
comwiz.i2p,6p7zqfotzbd66etl5xqy3p6xvr5ijucru3am2xqa7wmnj6vf3djq
confessions.i2p,lh5vitshufxpmyr44zgyymebo5elc42eda7pxvn5lmtes47c7rxa
connelly.i2p,5yrris3nigb3fapvzrlrcaew6cdmzdknzvgrc7y2jpn3ntqurweq
costeira.i2p,abhty5xlmnyab2kqdxcd56352kcescxoux3p6dbqdrghggyygnxa
cowsay.i2p,q4ghzfpah4ffvm3bhc6fdkrznk5f6jxfjm2daytlparznai5d54q
crstrack.i2p,mm3zx3besctrx6peq5wzzueil237jdgscuvn5ugwilxrwzyuajja
crypthost.i2p,zywhrxtnkjc3rxxvxbocom7ml4hnutomgtuvqrwyf3rhuupnq5ca
crypto.i2p,vffax5jzewwv6pfim55hvhqyynafkygdalvzoqd74lkib3hla3ta
cryptostorm.i2p,mlu7mswyirjf53usqq7gyamvqc6rqihezgdbevov3dkxmkfo57aq
curiosity.i2p,eomeif4xrykxlzhawc3icdilje5iammijos6tyizwhrfh3j7qdvq
cvs.i2p,yd6k7dzpsa2tnlzx4q7xqkmd4qsjk5xk5hbiqpiarwbeyvxaxgba
danwin1210.i2p,eoqdf4no5dxn4tw5n256kkd4lzz3uk4p47np4mepsykpsdzrnvba
darknetnow.i2p,gkx3o5fy7mv7l4psqqnhp35d5iun7rt3soci6ylf3rgb7a5a655q
darknut.i2p,2mk37gtvpk2i63o6vl7vna4dr46rqexxetupgn5efuuins7x3qya
darkrealm.i2p,gbh4eerxdsph7etxsxznfhvmuiz54trlkenakqep343u4xcoekzq
darrob.i2p,hz2xhtpeo6btgiwi6od4qj2575ml5o2246rd5orarruyjhd63zja
dashninja.i2p,dzjzoefy7fx57h5xkdknikvfv3ckbxu2bx5wryn6taud343g2jma
davidkra.i2p,nq7ca2egm563nir3xegfv52ocgmxstpz56droji4jgnzfoosk45a
dcherukhin.i2p,qa4boq364ndjdgow4kadycr5vvch7hofzblcqangh3nobzvyew7a
de-ebook-archiv.i2p,6mhurvyn6b6j6xa4a3wpuz7ovpsejbuncvyl6rnhepasfgdgmn7q
de-ebooks.i2p,epqdyuuhtydkg5muwwq47n7jvr66pq4jheve7ky5euls6klzwuyq
dead.i2p,7ko27dxvicr2sezvykkrfiktlghx5y5onup3f2bas5ipocy6ibvq
deadgod.i2p,63bveyh7wefb44hlia7wtxxb3jal3r67thd6jekmwrtq4ulaaksa
debian-multimedia.i2p,cylxxz2y35x6cvyrl57wu3brckurtexatyi2i5awz3eeamqwjspq
decadence.i2p,pw5ys7k2grjb5myydpv6ohikm6nna7y6u2dro44i4rucgulu3ikq
deepwebradio.i2p,2nait2gdeozkgf6gyhzjfij6mwldwkxxwcvtxobb4b5q5cvtm5la
def2.i2p,cepsrw27kdegwo7ihzouwvgcvw2obswwjs23ollgj7hk2yrce3da
def3.i2p,xbf3ots2purqun7orn72ypkpjmrzbfrkj3u654zfe77hbrbow6la
def4.i2p,yyzdq4fwwmnlojp23drfpfqujln2vcjozjrfzfeuriuqzdq7g4mq
deploy.i2p,ujzspsqkbz5z272eozsrdv4ukl434h3fuliwrfxxnab74jmd7e6a
det.i2p,y6d4fs3rpqrctuv77ltfajf5m4tl4kzcu7rtwhxgiohylfxxow4q
detonate.i2p,nykapdsjjswdkjov7x3jzslhg4ig3cpkhmshxqzijuhbisx25jja
dev.i2p,cfscxpnm3w3qxnlv3oikewxm4qrot4u6dwp52ec2iuo6m7xb5mna
di.i2p,3irnooyt5spqiem66upksabez4f3yyrvvjwkmwyzlbealg64mgxa
diasporg.i2p,edvccoobtjukjgw2os5eetywanbb2mpag5aknkrpia5qx2koksua
diftracker.i2p,m4mer767ipj7mq6l7gdrmrq37yzvsj3kzezd7n7nsfuctntjseka
dm.i2p,heysbdivyeugdbggpscco5wje3dsvwgcpp5ot4sopooebnmiqvtq
docs.i2p,ato242wckzs4eaawlr5matzxudt6t5enw73e4p6r3wajwkxsm3za
docs.i2p2.i2p,las5l45ulwwf5i72nht6vk33sfkidcpr2okpf5b6mvgbk3a2ujna
downloads.legion.i2p,xpmxdpuuptlekyhs7mmdwkvry7h2jbvpqpzsijqe3a5ctxgodesq
dox.i2p,vk27cjdrtegfdnrjqutebgxkpyrfj42trdfbsupl5zn2kp34wb3a
dropbox.i2p,omax2s5n4mzvymidpuxp2yqknf23asvu54uon6cxl6gdrlblnuiq
duck.i2p,3u2mqm3mvcyc27yliky3xnr4khpgfd4eeadhwwjneaqhj25a65ua
dumpteam.i2p,2fwlpuouwxlk2nj4xklvm43m52tqyhqnu2fcfiuv7clvf3wd5nwa
dust.i2p,u6xgh6zhhhvdvefbqksfljfs3nyjvqcrmyamp5bryz5f4injmniq
dvdr-core.i2p,fg6l2ej6qrk5rkyfzdptxx5xkcm4kvdla4gg2tun7z7fm5cxxw5q
dyad.i2p,7n2ljphvp2dep7imoujvydxp4myuxfld3axwfgcny5xc5x6jj6ka
e-reading.i2p,z54dnry6rxtmzcg7e6y3qtsig5yf5fmehuvakcg5wnuahx3iafuq
easygpg2.i2p,bwxry5alzx5ihgrd3glah4eotddblzhalvpheppnw4zcajzqoora
eboochka.i2p,ou7g64d5in4sugv5fgmmzwnunuw5hloixio7puthmrvrkwrp6egq
ebooks.i2p,bvpy6xf6ivyws6mshhqmdmr36pruh2hvoceznzeag52mpu647nzq
echelon.i2p,afvtspvugtd32rsalxircjglh3fhcjzk7gxrm3gw4s2yrpvzk6wq
echo.baffled.i2p,bfr3lyicr72psxvt2umqfb562rtex66w6q3hi3tktzkoyane2iha
eco.i2p,2dq2o5h6c6a674qaduipp55mid5iktumjbswuwmpsrcqaeowdvwa
eddysblog.i2p,ieac3ub4g5sy3wuhsbqfembnpp7f3a37xgcx537ytzsmgfzexnbq
edge.i2p,aknsl5wmzjmwyc4wxutfdwy2w5vgd3vcx52mqx647hcgvyurmqta
eepdot.i2p,t6edyotbxmxvy56fofdvmragvsj65te2gkhvzv5qnblicutyvgoa
eepshare-project.i2p,sn26kom4qyuzouppv4lwnk6bqabdydcegtrilybviibwiq2s4nfq
eepsites.i2p,isskhl4ak3g7qevrarlmblddgr4ugnn3ckalwpjcvxafk5rjgypq
elf.i2p,duz6ey27ohpcp3llylklzdb63lylolzcixad6bh7rt5tkq42qqpa
elgoog.i2p,z6hrgkg2ajmuzlrddjlffrgctx7x7fkipm6c4hdzmohyn5wkr4ya
ems.i2p,734zw4jsegdf55zl3z6s22tqkbxcghu4qvk6q2wevjfmx7xhbn6q
epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
es.hiddenanswers.i2p,cw7ge5ey4ekp5iep2kaw6j54boebtqytpcbnvio2bfpccd5ejzfa
eschaton.i2p,xe75f5hzmrq6rkhsef2geslmi2v2yfngdiysmlmxvh7b4pyyjk4q
esuwiki.i2p,cwxuiwcpymb72vm5vluba66ofhugyf5qeevvwo7e2fqrxl243coa
evil.i2p,ljfl7cujtmxfffcydq77pgkqfxhgbikbc6qxjgkvcpn4wzd73a4a
evilchat.i2p,s5b7l3hzs3ea535vqc5qe2ufnutyxzd63ke5hdvnhz24ltp3pjla
evilgit.i2p,mx5vyoqhg77yuhthwznsxrepjsemq4uwitx4lxdzetk36ryl5rla
exch.i2p,vsyjsbbf2pyggtilpqwqnhgcc7mymjxblamarmxe5hmbxaxvcndq
exchange.gostcoin.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
exchanged.i2p,ylmulgfskl6uiwac4hw4ecwqdzd3oxtwaemzj25zc6k5q4rkexra
exitpoint.i2p,5zmjurq3enudcenegnxu5hqmfmayz4lxvnik6ulch4xssa2ithta
exotrack.i2p,blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva
explorer.gostcoin.i2p,ktoacmumifddtqdw6ewns3szxths2hq2fat2o7xnwq4y3auga3za
fa.i2p,6n6p3aj6xqhevfojj36dixwbl4reopkhymxmatz7ai5sroh75rka
falafel.i2p,djpn5cbcgmpumwcriuzqistbae66txca2j4apjd2xesfgb7r5zmq
false.i2p,77mpz4z6s4eenjexleclqb36uxvqjtztqikjfqa4sovojh6gwwha
false2.i2p,j5i2tfumh3ti5sdtafwzzbpupmlcbg5drysfay2kxbdpsaljrosa
fantasy-worlds.i2p,62a4xcyyhvfrcq2bkckb7ia37fmrssrgx467tlkxp32fjpq577wq
fcp.entropy.i2p,de6h6ti5z3mcbdcwucu45vplikqyoeddsu3rqy7s2zy5i47j3peq
fcp.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
fedo.i2p,zoamh7e3k2vf2g6pfy46ho4taujk2f4mxqqsv3gbg554fxbvyfqq
feedspace.i2p,kvtnpx4jylgeyojfhix4x462sqn5uork3roml4sfzotkxx62i4wa
ferret.i2p,kkqie5qmja7bkf3iad4zxhrdarwj7kbrx2m3etn5kmba3shgwj4q
fido.r4sas.i2p,i522xmu63hfbaw2k54cthffcoqmeao6urjyq3jg4hddf6wf57p3q
fifi4all.i2p,v2stz6bsot7sbjzix5tky5dm5ej7gidmjnkvzqjju5xvz5sz6fwa
files.hypercubus.i2p,qfglq25jwieszgyt7muz6dambzqsrmjhhszygzzx2ttubc77sffa
files.i2p,w2sy74xe6oqnuz6sfh5fhkzu7boholgzd5f3anhj47srxwpj2vaa
files.nickster.i2p,yil7dp2hg5pbqyovsiwb2ig6zjsq4tize3fnwemmqdrr6j5itdtq
fillament.i2p,udj2kiino4cylstsj4edpz2jsls77e32jvffn2a4knjn4222s2oq
firerabbit.i2p,awqh7n3wskzl3epyvkdwgarmfybsncm7vye6psg4tpkmplh3mj2q
flibs.i2p,ocdm33e3h5tdml3yyholj4objdwsrhlugfqjnqgdkslmgdzb6b3a
flibusta.i2p,zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq
flipkick.i2p,aso5rzc4ym6g2bcbxjy2n573bmbenkjawva2jg7fhyqhwtwgu6lq
flock.i2p,hflpi33ko5bi2655lx6bpzstdnjqgzrz23inovqjx5zpntyzyb3q
floureszination.i2p,vitpvfb25sikuk3crgcvtcdi7hajxnnq2t6weay3no7ulur2wwwq
forum.fr.i2p,onvelkowkbuwrglhw2cnocggvbdudi75sll5mfirde3cbopjqivq
forum.i2p,33pebl3dijgihcdxxuxm27m3m4rgldi5didiqmjqjtg4q6fla6ya
forum.rus.i2p,zd37rfivydhkiyvau27qxwzmerlzbqtthsa5ohtcww62zrygjaga
forums.i2p,tmlxlzag7lmkgwf6g2msygby3qttxvm6ixlfkq6s6cpgwubp33ya
fproxy.i2p,keknios3gm6kh6onez6x2bm2t7stv54oanvltuagphgdfjdw5e2a
fproxy.tino.i2p,fpaituvuvyxp6xdjnv3i27alnj2ifzcvqdweqb6yj5uybotzvyha
fproxy2.i2p,r4lgw4wmza25g7j5fjocjbwzwthfg4ymcbm52ref3hh2hogskcza
fr.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
freeciv.nightblade.i2p,rluupsgxbvw5t7jno3apyzlrdirjkljft4gdoy4mxxh4fmd4xzta
freedomarchives.i2p,4ck6oliqfjz3sccpya2q4rh5xkj5xdxkqs76ieml37537nfhwd2q
freedomforum.i2p,abzmusjcm3p3llj4z7b5kkkexpsxcnsylikokouk5txfim3evqua
freefallheavens.i2p,giqnkltyugfmsb4ot5ywpvf3ievuswfurk6bjie4hxi2hh2axajq
freenet.eco.i2p,2kf7ovb35ztqkrurkm76y34jfpwi6go25xj7peznnmxrl7aieo7a
freshcoffee.i2p,sscuukigp6alcb3ylhkcugoejjfw5jqgtqbsbafw4hyku42lgc3q
frooze.i2p,m6ofa5dmyse4b4jg7kfmluuuc4pw5jqu6zh4qnboin4vropxepja
frosk.i2p,63naq7zb3hvbcppj2ng7qwf6ztusp4kwpyrzbt4ptafcdbu4pfjq
frostmirror.i2p,ycz3imuz6yte2zhlapmsm3bsvc46senvc2jxzwsbfdct5c72qulq
fs.i2p,ah4r4vzunzfa67atljlbrdgtg3zak5esh7ablpm6xno6fhqij35q
fsoc.i2p,vaqc4jm2trq7lx2kkglve7rkzxhhaptcwwl32uicx4ehf5k3hx6q
galen.i2p,4weo7zkxscxbcouiqx4mlnb35uwl2lromikzk33er3fljktyvi2q
gaming.i2p,rfxberwod6st2zc6gblqswxjl57nucgc3xrbwss43pe3dvqqzj4q
garden.i2p,qkk2dqx6nocycgt3vinsoc76cxkb4jreybcpgz3fcps2dbe4rowq
gaytorrents.i2p,fnggbr2t2aulr6rvlo4aehotx6wecfob7u3k2nxsnvtm4xex424q
general.i2p,5fklrsztdqpl3hkkwwrrw2rdowrq7wwhwb6h7avvk4fhansp4vvq
gernika.i2p,wpzqv3lxpecdsvcaadvbmrhhwlc7kp4n2mijdv2qjw3zr3ye232a
ginnegappen.i2p,kbhfkzx5jeqhfgss4xixnf4cb3jpuo432l3hxc32feelcmnr3yja
git-ssh.crypthost.i2p,llcp7jvz3hgtt3yzkdgjolwobisgvhv4xqa5a4oddejllyozur5a
git.crypthost.i2p,7frihhdcisdcyrzdbax6jzvx5gvtgwsm7m6kcem2tlaw4jtahbqa
git.psi.i2p,em763732l4b7b7zhaolctpt6wewwr7zw3nsxfchr6qmceizzmgpa
git.repo.i2p,vsd2vtgtuua2vwqsal2mpmxm2b2cpn3qzmqjoeumrrw2p4aot7uq
git.volatile.i2p,gwqdodo2stgwgwusekxpkh3hbtph5jjc3kovmov2e2fbfdxg3woq
glog.i2p,ciaqmqmd2wnws3hcpyboqymauyz4dbwmkb3gm2eckklgvdca4rgq
gloinsblog.i2p,zqazjq6ttjtbf2psrtmmjthjeuxaubi742ujrk2eptcsaoam4k7a
go.i2p,ll6q4lsirhwkln4dqxwqkh2xu4mu3jiy546b4uhe4fypyb4vvx2q
gonzo2000.i2p,nogsv7okydhbvrewv6hb4xdojncvhkusnyib4lglluc4uw67a37a
google.i2p,4p3ajq4cotnflmuv7fhef3ptop5qpm3uzzgp5bahxif3nc4w3ffq
gostcoin.i2p,4gzcllfxktrqzv3uys5k4vgkzbth4gqednwhfpt755yivm3davuq
gott.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
greenflog.i2p,zny5ftmhzxulxzyczmeat53qjnue2xtqv2clisc7dg76lwfceecq
gstbtc.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
gusion.i2p,4qyfdhizjixe2psu7wcvqufix5wlijocehpb2futurcmlhlktrta
guttersnipe.i2p,kizkhzes2bzp45widihremo6geepfk7dl6juourkvzuvlc6y3spq
hack8.i2p,un63fgjgi3auvi7zscznwqfol7ka4johgthvqf635mg3fefsjgpq
hagen.i2p,e2t6rqd2ysbvs53t5nnaf7drllkgk6kfriq3lfuz6mip6xfg644q
heisenberg.i2p,jz4quyw7zt63tmw65jfp76fblwadjss4iyi4puqdg3dye7oaqlvq
heligoland.i2p,gzrjm62ektpqjfsem3r3kwvg6zpjvvhvpjvwfxkm2ay4zu7sp6oq
hidden.i2p,iqodhhqo473qv5gwhjcs2bsrbhlqtpzgpnuumpastfiyhuwb2kyq
hiddenanswers.i2p,kj2kbzt27naifij4ki6bklsa2qfewxnkzbkgvximr4ecm7y4ojdq
hiddenbooru.i2p,zma5du344hy2ip5xcu6xmt4c7dgibnlv5jm4c2fre5nxv44sln3q
hiddenchan.i2p,6y4tltjdgqwfdcz6tqwc7dxhhuradop2vejatisu64nwjzh5tuwa
hiddengate.i2p,rvblcu54jvkkfffp3fobhunsvpgfc6546crcgzielzwe2s5m5hbq
home.duck.i2p,jsh7yfvm2t5urdcnmfzdy4n6vegqskdtlwem53chgxli4ipfmuma
hopekiller.i2p,kcaelbgsvrkiwpx36b4wxofebrl3njx7rgm5amzfmqwbomt44cxa
hotline.i2p,6cczi27iuxkm3aivazaemzltdqgh42ljzurqp43uclbz2lid2uqq
hq.postman.i2p,27ivgyi2xhbwjyqmnx3ufjvc2slg6mv7767hxct74cfwzksjemaq
http.entropy.i2p,ytu7kz5bdoc26nkpw2hajwt3q7n5rcbg2eokyefhmkxmmslimbdq
human.i2p,nrtcelq3humyfvoxmzmngpka6tmyifweouku5mbi5av4lc43hzaa
i2host.i2p,awdf3nnmxxup5q2i6dobhozgcbir7fxpccejwruqcde2ptld443q
i2jump.i2p,633kqgmwzzu6vhkevwvbf2pfyejt3gkes34i6upa4og57fgdfcxa
i2p-bt.postman.i2p,jeudwnx7mekjcowpqo6xpkwn7263c57y5piurrjrdzinjziu4fla
i2p-epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
i2p-javadocs.i2p,icgmr6hhjudl4yxhtuq4pxvss2pzypwddzowajgs5rdz6f55novq
i2p-projekt.i2p,udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna
i2pbote.i2p,tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a
i2pbuggenie.i2p,bioq5jbcnfopqwvk7qssaxcl7avzeta6mu72jmxjeowflpcrhf6q
i2pchan.i2p,tduxyvfs7fzi26znvph3mu2d2ewaess7emomfci22wvownajphuq
i2pd.i2p,4bpcp4fmvyr46vb4kqjvtxlst6puz4r3dld24umooiy5mesxzspa
i2pdocs.str4d.i2p,yfvbtrhjac3jutdsqzugog6mbz3jtyhpwovrt2mqc5mzv534y7cq
i2peek-a-boo.i2p,qgv64klyy4tgk4ranaznet5sjgi7ccsrawtjx3j5tvekvvfl67aa
i2pforum.i2p,tmipbl5d7ctnz3cib4yd2yivlrssrtpmuuzyqdpqkelzmnqllhda
i2pjump.i2p,2mwcgdjvfvd3xwumzqzqntual3l57h3zo7lwdmkjboeraudpkyka
i2plugins.i2p,bb63kmnmbpitsdu45ez54kmogvvljn3yudksurcxiyq7dn5abt7a
i2pmetrics.i2p,v65p4czypwxrn35zlrfkar2w77vr42acd7gbszegsrqq4u7sip5a
i2pnews.i2p,tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq
i2podisy.i2p,3c2jzypzjpxuq2ncr3wn3swn5d4isxlulqgccb6oq5f6zylcrvcq
i2push.i2p,mabdiml4busx53hjh4el5wlyn4go5mgji2dxsfyelagi4v5mzjxq
i2pwiki.i2p,nrbnshsndzb6homcipymkkngngw4s6twediqottzqdfyvrvjw3pq
iamevil.i2p,au7jhslyt4cxkjp365bvqvend3hhykrrhbohtjqlgoqrlijbezja
icu812.i2p,bxgqwfsnr3bgnr6adn62anjcin5nuthqglotb3wn3dgynsfofeva
id3nt.i2p,ufuqdzsxltiz224vq5gnuslt3a3t72dhy5kq6i2xway53m6pzv6q
identiguy.i2p,3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva
ilcosmista.i2p,6u2rfuq3cyeb7ytjzjxgbfa73ipzpzen5wx3tihyast2f2oeo24q
ilita.i2p,isxls447iuumsb35pq5r3di6xrxr2igugvshqwhi5hj5gvhwvqba
illuminati.i2p,syi6jakreatlm2z22u76izyqvbm4yi4yj7hr7jb63lgru5yhwwla
imhotep.i2p,qegmmhy52bdes2wqot4kfyqyg7xnxm5jzbafdb42rfoafadj2q7a
in.i2p,r5vbv2akbp6txy5amkftia757klgdy44s6cglqhmstpg65xycyjq
infosecurity.i2p,v3gkh5kqzawn2l3uzhw6xnszsh6w3nztjmlwil7p4kyrwrsm2dba
infoserver.i2p,jd3agbakybnhfvkeoxrx7t33iln6suzomv3kxkxf77j7rkonch6q
inproxy.tino.i2p,ex5yf6eqqmjkrzxnkn6cgvefgne24qxsskqnpmarmajoit43pgma
inr.i2p,joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq
instantexchange.i2p,5wiyndm44bysev22kxvczxt37p6o6qroiqykytrvn2yzi55aqfxq
investigaciones.i2p,n7hqd4asxrdwf3zwo7rzv27y2qkcfmakmz6mjar6aw6hlc4c7mha
invisible-internet.i2p,jnpykdpp46zenz4p64eb3opadl5g42dls3rurk2cvq6a3g3rvbvq
io.i2p,tx22i6crnorzuti3x6va4mijsbhoqswy2cfdxjbvprgsq4eerg7q
irc.00.i2p,bvcja52pppgfspp2ueuipoysjnvvoyblz2h6smpxcmanjquogirq
irc.arcturus.i2p,5nywlbn35p2nwsymwpfmicu6fxono6g64vwusxbsvmm2qwz6vupq
irc.baffled.i2p,5zmtoopscym6qagkvpgyn7jnkp6dwnfai745xevkxlou77c2fsjq
irc.carambar.i2p,hxzbpivxqxy6nuae4t6fnkhcgnhs4c72vt6mmsqfmfhrkn2ca6gq
irc.cerapadus.i2p,e4ckznxcxvgyikzjmjsu72i2dbj2d76ogexyukklbjvpcnhp6zzq
irc.dg.i2p,fvp3pkcw4uvijqabwtekcdilklp73gyasuek67wdcs2mucep4caq
irc.duck.i2p,chdpmm4gxffyn24xx5dhxvfd5httu42i5gtoe6cctjlsf4mbofeq
irc.echelon.i2p,ez2czsvej5p3z5bquue5q3thujcodfze7ptybctqhnqc7hms5uzq
irc.freshcoffee.i2p,ubiu2ehtfnrleemgpzsqkahwnvzuaifqa3u4wmaz5maaisd5ycfa
irc.i2p,l3ohmm4ccxvyuxuajeaddiptci5lsrnxtvtyq7iohphrt3oj2evq
irc.ilita.i2p,5xeoyfvtddmo5k3kxzv7b3d5risil6333ntqrr3yvx3yubz5tk3a
irc.ircbnc.i2p,4rqcsqd7xif6r4v55blqvmqu5er6due4eyene3mjorfkts4o3rxa
irc.killyourtv.i2p,wre4majmg2vnbi6id27et7yw6lnpf56wkbm6ftnlwpvxnktq73hq
irc.nickster.i2p,dhq3fhd5scw3jqhj5ge7kqfpprfolcgxfjbaw24obohaiqjtdu7a
irc.orz.i2p,7gifacog4aoons3syybojbbnyqqaaqijhngrehn2xlq3eucuyjcq
irc.postman.i2p,mpvr7qmek2yz2ekegp5rur573z7e77vp3xqt2lfbco5i6nkfppcq
irc.r4sas.i2p,hodhusp73gltozgrnianlbploon3rrvhrzfn5mf2g46o7aaau5la
ircssl.cerapadus.i2p,4x2i745i4w52ss3he2kse6tzwt64pr62yvrcb72lgvrb63fup6ea
irongeeks.i2p,ecduxoion5uc5hnvzjxff6iiwhdwph6gse3dknyvlo7e6gaeho7a
iscofsi.i2p,enjgdxs4um2dmhdb2ajff2egrdijkjji3g47m6unb74swbrqsddq
isotoxin.i2p,wue3ycaccf4texikza3fh6p5yrmtgnooisuypnepo5mo67lmpcqq
itemname.i2p,o35ut7hgywy35okvgkjkv3ufzv2ejv4luap4oytwbyy2jqy6u4vq
ivorytower.i2p,fpwrfvidfexsz7dspofkwtkmmizm7lyralfz5kvykffk7gubvxsq
j.i2p,kjxvohlsf5sdrzxzfcrmvquccnoevi6ytbl63mstsru5wt2dx3ea
jabber-2.i2p,pvnmzgemetkwcuvt45omgowmeznwk5xw3nc3ygeoz7yekqxy57na
jabber.duck.i2p,rhdzvvzraqzzm67zpyegb7knpfrjeffitixqzeyymdoz56uh2rtq
jake.i2p,v2axvy6pqefnla7gun5fmqs4lqe4xfyqovgzcundhxrpcdvfd7cq
jar.i2p,2fthkmujup3xiiu3yple24n6g4emzdiiimbuqwvpdddtsr3c4nrq
jazzy.i2p,ha5c3zafwkt6mwqwjcf4oqwvbwz473652ljjadiwrj4gfkfkjofa
jdot.i2p,kw4jr5qw4bhnj33avkwankjdh3zi7wtahlmgkjwvsv2isskkzgpq
jhor.i2p,c6rnm7oemydhuwzmhwwwxphkzanez5rnn7fkcs3lpgu6gkgtssoa
jikx.i2p,aazr55itvyns4lwppvx5njyx5tjdwemw4w6jbmpegdunznod2ieq
jisko.i2p,jxgfvr663uhr6m65hrgkscshysfshkq32ywdubc4ed7zda3e2pca
jmg.i2p,oglpnq7zungdukmk6gk5fzj5jp6wibuoihqgks453wztrwos4ggq
jnymo.i2p,nbfplxgykyfutyadlfko2rmizdsxox2pee2ahboj5mju4s3putda
jrandom.dev.i2p,htynimemonyzqmn76gworxyfkmqtsa7zcprbrd3i5cxqqm75tuzq
jrandom.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
jrrecology.i2p,qxi24gpbum3w3kesuxvheyu3p5u5o6tuvoypaolub2gnvbld57xq
jwebcache.i2p,xdffxnxtjd6ji2zig3cgva7igvl2tiapyjoc7ylbzwqhxudbmvfa
k1773r.i2p,zam7u6vslhemddz347uusuzjdk5wma4h5hcmcqlng4ybbpdbjhnq
kaji.i2p,z5ic7gvm2k4doczphtrnrspl2w5sfbss2de4z3ihjijhtjw67ydq
kaji2.i2p,4lscgc6napekfx7ay5fdcjofeja4fnl7tqcd3fek63t4saavur2a
keys.echelon.i2p,mwfpkdmjur5ytq4og36ym3ychinv36b2a57f4rmgqmtrwepq3fva
keys.i2p,6qv4x7ltaxckd4vbay5s4ntqqflq4efk6oke2d5yzicqrmk443ba
keyserver.sigterm.i2p,isoxvnflrdn7cm76yjlfg5tbcugoito2hur7eidbqmo33xmwz5ga
killyourtv.i2p,aululz24ugumppq56jsaw3d7mkbmcgo7dl2lgeanvpniyk2cbrda
knijka.i2p,knjkodsakcxihwk5w5new76hibywia5zqcgoqgjttzsausnd22oa
knotwork.i2p,2yocdbcjiyfaqgxb4l6oenrrrrie6nydgmbnbfulqg7cik6bozxq
kohaar.i2p,qchpjehbhqjbxdo7w3m55jbkrtsneb7oqoxcr24qttiq6j5g3z5q
krabs.i2p,3yamyk5bgfgovg6zpvtvpdjk37ivjj2wog2w7wha5agzgxxkqaca
kuroneko.i2p,wbit2huhhwlyqp2j4undccuyrodh6qcmzdeyuaoy5o4ym7g5gdgq
kycklingar.i2p,gctswdhp4447yibxfbqg3uq2bvx63qjeqnaoaux75zw73leakyva
lazyguy.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
legion.i2p,5oirascyhwfy2tr2horw6mixozsre7z6s7jfq7qbnj523q3bkebq
legwork.i2p,cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a
lenta.i2p,nevfjzoo3eeef3lbj2nqsuwj5qh3veiztiw6gzeu2eokcowns3ra
libertor.i2p,7gajvk4dnnob6wlkoo2zcws7nor3gunvoi7ofalcps5lc76wruuq
library.i2p,brqqaq44vbeagesj5o3sxcnkc5yivkwouafyxa77ciu7l644ei2a
lifebox.i2p,pyqjnycm55cuxow22voqj62qysrjdnb6nbyladaiaiirqi7vp2yq
linuxagent.i2p,ap5riaikrjq2uv5qvy7klzhhqywvqi7wqscyipsewcun7w2eynlq
lists.i2p2.i2p,vmfwbic2brek2ez223j6fc6bl5mmouzqvbsch45msvyyzih3iqua
lm.i2p,yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q
lodikon.i2p,u3f67staiwhqxpacya3clmvurdwd2kp7qcthzhstqnhrmlwc2g4a
lolicatgirls.i2p,a4lzmjyba7aq7hl6okqpds7znnwymolqnr7xhvno2wraqb7uhfla
lolifox.i2p,7fd2clkiotjnaoeigdtxlkkb24eik675ovezjf67x26ysham4zca
longhorn.i2p,pohcihzxzttjclrazhs3p76wt3ih737egb5bovqb6ym3du6z3o7a
lp.i2p,jiklbujn3cbfikf4pca526jgmorx6mxhil3twqmfoteaplx6ddwq
lucky.i2p,wx36m3wnpt2y6bngdpg3ifrarvtkpwnluarx377bllpgvkuhybaa
luckypunk.i2p,y4t6cujjxnnrtln3rgmfbgbh46hic7wkef57krd7opitbgngohka
lunokhod.i2p,3yc6sp7xic4grmpfecbwuij6z3dp5kdgoo362pszaco7io42mnwa
m16.i2p,ucsr3eveuc4mx5y6gxnoaywd4ojvbel5q3ynns6s5yfw3vusmfva
mac7.i2p,3yjowssqzydciwa5zx55kazgf7q7w6g7rkocr7bngy35ii44t34q
madman2003.i2p,a2sam2xbhxbzmeyobphbxrkdwlppoerewq5qvibbyk3ftsr643qq
magix.i2p,cgfnyxv62msfynsfbv3kju22j2mt6tfnopshhmrcmpcrxyts6xwq
magnets.i2p,snz46nez6hrrpg6336neinflw56l3vwatk6bzzytwu77xmsfsoca
manas.i2p,6qolj62ikkoq6wdn3hbvcbdmlvf2rcyv432kgi5uy7mvrczmjtba
manveru.i2p,pbmbofs76wpjnxi55eqtwg4y6ltyij72o4fm4sxfjol3y57ze5sq
marcos.i2p,vpo36bsil2voqaou53zshuegssqaroa5mbrzxfmhjywlbojckalq
marshmallow.i2p,svdqd6j3y3gwryufcl4fkzpmcujgvrvphvk2oy4r7m75xs327e2q
marxists.i2p,lepah55qyp2fhuwxlz7bwrhzckn4gkuofivnofoeuyfpmke5x2hq
mattermost.i2p,x5oovnhnuli5fnwtgkbd5z5jvrvdvprqyuofywx6uoxkk4bie6ya
me.i2p,dbpegthe42sx2yendpesxgispuohjixm4bds7ts5gjxzni5nu6na
meeh.i2p,4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa
mesh.firerabbit.i2p,3x5wokr4bjy5z3ynji4fyhvwzv4fvgry3xafi5df5h75doezjytq
messageinabottle.i2p,avfhe3kvrrv7utxn2vre65lg7damxzzsewq3vukwie4llitd254a
metrics.i2p,z45ieamhex2ihqv7oowk5fz4qq47rbvxhhhbaaiinpajbhuevtpq
mhatta.i2p,o4rsxdeepfrnncsnjq675xogp5v5qkbfgbt6ooqeyfvlifobrjxq
microbleu.i2p,mtapervgibruizniems2yyr47pin2wpysyh7m632rigl26vjc6qa
microsoft.i2p,hvaqr5idszdyrjph34amb4mjosqd3ynggoxlnj7ciqhnx7q6plza
mindisl0st.i2p,u7rnqhvsuyxd3fabm4kyzn7brgz3i3cporj2emk2jmbpcmltyf7a
mindspore.i2p,uuh5dd3y2rqa7x2jpggm4p2pg6znarm5uanwsvybe4tk36ymwr4q
modulus.i2p,ctz3o6hdefrzwt3hlg6rjhdcbjk6irppbndq32u6jnn4lz72f62a
monerotools.i2p,5bal7dngxde2ddmhuzbtfken6w5nmxmixtjlrlmxt3wbhnemv73q
monerujo.i2p,puri6y5dtwh6zr4u77ep6ozatun6iz7v4wai2dzxppz7654corlq
morph.i2p,iovyp2dao5rta6g5v6hke2s4ugx2btkpcljddak2yhxfrx3l4dqa
mosbot.i2p,5bhmrp43mjwlzf4x64xgdrkwmw4luvng6eq5waa663a7vnkp732a
mosfet.i2p,s5ynkgagndmpxpf2kmnenv4x72io664gzd2x3qef54ilammnte3q
moxonom.i2p,gcjdrvnlobgexh7ebv276pwmnoj3yoyaqm3w4vmmdha4lgxfinqq
mp3.aum.i2p,n7bmu5dwux7f6gedmdik6zrm77bnls4lkzo2vo3bf4bwegk7vkjq
mp3.tc.i2p,w3ied5s7ldjcvnhxu2gyofe3oogzbplkyxshzfkhspiy2526snsa
mpaa.i2p,m6cqnglo7xlytwxkdsmwf3d23d6lq5r446c3tktb2tdmuah36zya
mrbamboo.i2p,tmpmkx6wlbbrgsnexrqlrib7laoegpbfeop7bnyezegii7hecpxa
mrflibble.i2p,u7k2qcmkrril6yvudvwxjqz7k3dzgp3jdejjjeapej7liselj3eq
mrplod.i2p,fjn5hxtybxyfyvdf6u5v5seg2sjd47hb5by6sa6ais4w3xnrxwyq
mtn.i2p,xisk3h6sku3iqj52uriogaajmnku7pwjux7wa4omx2zloamuw6eq
mtn.i2p-projekt.i2p,f52x5fp6uhq53f5zle5d6rq5un34xgmxgazvilvmzcby37xcmsfa
mtn.i2p2.i2p,l6kuhtmgvbp57d7jwalj5nksi6nr4gfzbz4oit62lxgipb3llt5a
mtn.meeh.i2p,h7ylrsuzzynrxp3jql7anoozyqblavj7eqces6o3wngvuuxhs2la
mudgaard.i2p,yz32lk42gtoesknesfolq3tt4erxxcejcote5pontaeqev3bj2kq
mush.zeit.i2p,dk3sg23kljawxqp3cb6xz5mnzjlyckzvq5jhqs5gnvdsv7wqn6ha
music.i2p,akamh76yi6p7xxbvl3qv3yhaockne57yfuh77acogbgpjmwypvia
mysterious.i2p,p66g2a4nzfkvidd3l7nwphcnfa3ttyu5kiolcb4czec2rn2kvwsq
mywastedlife.i2p,ceumy3puvvsrru5bmfmtgsajsx5qyehqac7l7a23xpwtfs2bvcgq
nacl.i2p,bm2fib3tumer72lopjh4nmqomwvqu2sdfyb2hmr6lnk7jbw3vvia
nano.i2p,ex5ssv7s3hj6jp7hvadxfw3wvbjbvnczxr4pbk7qw26ihiorjmba
nassai.i2p,v653cocvn3i6bgjdm3ciwbdnu32supglv6gn4fh23bohemsp545q
neodome.i2p,5hkhjehj3ct2pvcah7dcylwef2oti3xij5myxbv3pd7rocio5vkq
news-i2pn.i2p,wwcqkwfo5yhe6uribv5tzylk25j5hkdk6gdnyftzd3k7dawlzwca
news.neodome.i2p,trhwcnygfkeqjj6g4xhmrdp4gsjqsye47lsxshbmwbten4ywt5oq
news.underscore.i2p,rl7t3kspoktuatjcu7gf7xleu7y6biibs4fspzo24kll6n7hbq4q
newsbyte.i2p,gsk3rgsejxxrfabjxu5w5plplxsu47aoeoke22vvhlwwllzosnxq
nibble.i2p,jmdxcpdzqafedn3clc4y7u6o56qocfiffrzbzncmtggqtio5qjpa
nic.i2p,vzu5ymab6klevpcdudv4ypisjqaznmt44e6lcg7dwiuza4saibxq
nickster.i2p,zkwsa6kvq2wdhovw5g5wqakpb7rlaylyhfriwmurots5pvwbqauq
nickster2.i2p,eofzi7npzpk4p5gb4qper4hmwgxo6kepo3dheeblakewedxj2bwq
nickyb.i2p,gmpxk4tje7mnud32kg2kjmf36f6cpwqakzc2dxuzjnnz4qr5w4sa
nightblade.i2p,p4gkon7ytswxrbwkl7vruw6mg7kfw5aofovqjgt4c7tnqmbq6lha
ninja.i2p,q6dg6hlb3egzdqz352ri5rc4fx4gcrdeu3tpiyfxlv73yfjgrhya
nm.i2p,3itdpqzyn3ii7sivppo4sxxwhvgtpskzkbokrdibim6gqpvlw5ya
nntp.baffled.i2p,kc6muo2tih5mttbpzecteegvtonuysjidk3emcy4cm4yifzild2a
nntp.duck.i2p,gvzzor4utsqxswvf6jaglfks7yxudlz2s326ftrk56i4lpd2s47q
nntp.fr.i2p,npoztnqadfnu4vrokoh6rusoi3yne47s6jurc3lzhcrzzia5eqva
nntp.i2p,wwdzmeyler4djegvyt2bxmkwrckfgg3epkkwowyb75s47he6df6q
no.i2p,lpsg4x4gdrf7antxcdy47cl6abcqei5ommgzt55retq7go5ku3ba
noname56.i2p,oiyoslismzyxuw7ehxoigmtkdj35idim6flmlplddxuiiif6msfa
nop.i2p,ssag45lathm4gqp46si7c4w4tioyvjpcza5uvz5x2zuljnplylca
normal.i2p,j5fex634r2altzb3kjvu35qekt2r3hgsqzg5qxoy7dp53heu5pma
normanabcd.i2p,si2vh43gvxjnw2shwr24j76xyanow4oa6gbu4idookbraoxl3s3a
nothingburger.i2p,tesfpn757ysc7nih7mxher2b3jstkc3l5fhfcyb5kxhzhvv52trq
nothingspecial.i2p,wzrwqrp52bilqijrlboclynuev4kzpjzfzlvzl5aqxqt5fdnpbga
novospice.i2p,ukqap24nwac4gns77s4zy7j5cagt7l7syb5zo7eukfg3zn5gg5qq
nsa.i2p,nsetvbclpomqxfcit4mghn6z7vdhnza6jdzczby4crnto32uykga
nvspc.i2p,anlncoi2fzbsadbujidqmtji7hshfw3nrkqvbgdleepbxx3d5xra
nxt-wallet.i2p,33pp74k4ivy67z332qpyl3qlcqmi6gxqumrow4bldkblxxlxqq5a
obmen.i2p,vodkv54jaetjw7q2t2iethc4cbi4gjdrmw2ovfmr43mcybt7ekxa
obscuratus.i2p,i4j37hcmfssokfb6w3npup77v6v4awdxzxa65ranu34urjs4cota
ogg.aum.i2p,wchgsx6d6p3czloeqvna2db5jr7odw4v4kqrn4gr4qiipfyrbh5q
ogg.baffled.i2p,tfbvj2xal6lcuxv3hzuw7cw4g3whguombcv2zuotzvul4qtrimgq
ol.i2p,bnb46culzbssz6aipcjkuytanflz6dtndyhmlaxn3pfiv6zqrohq
onboard.i2p,qwlgxrmv62mhdu6bgkh4ufnxowxsatfb6tbs2zr666qyunwqnecq
onelon.i2p,irkvgdnlc6tidoqomre4qr7q4w4qcjfyvbovatgyolk6d4uvcyha
onhere.i2p,vwjowg5exhxxsmt4uhjeumuecf5tvticndq2qilfnhzrdumcnuva
oniichan.i2p,nnkikjorplul4dlytwfovkne66lwo7ln26xzuq33isvixw3wu3yq
onionforum.i2p,yadam2bp6hccgy7uvcigf5cabknovj5hrplcqxnufcu4ey33pu5q
ooo.i2p,iqp5wt326fyai5jajsa3vkkk5uk56ofn4anocgpe5iwlpisq6l7a
opal.i2p,li5kue3hfaqhhvaoxiw2ollhhkw765myhwcijgock5rs4erdqdaa
open4you.i2p,ice6ax5qrzwfwzsy64bctffj6zlzpuzdr5np65zsxlbt7hztyc6a
opendiftracker.i2p,bikpeyxci4zuyy36eau5ycw665dplun4yxamn7vmsastejdqtfoq
openforums.i2p,lho7cvuuzddql24utu7x6mzfsdmxqq7virxp5bcqsxzry2vmwj5q
opentracker.dg2.i2p,w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa
orion.i2p,5vntdqqckjex274sma3uqckwqep2czxs5zew25zlntwoofxk3sga
orz.i2p,oxomqkekybmyk6befjlouesit5mhstonzvzd2xnvsk7i6uyrqsfq
os3.i2p,s7x4ww5osrrfein3xgwyq67wnk6lgliw4mzt7shtu66wrb2zdojq
osiristomb.i2p,t3slf77axkv3qm7c3gzpv3jgmkraoqqe2bojr6h66eipibofsyzq
ot.knotwork.i2p,cxhvvfkbp2qbv5qojph7zb46molpe2ffanghnerjag3xdmy6ltxq
outproxy-tor.meeh.i2p,77igjr2pbg73ox5ngqy5ohzvrnur3ezqcogtl4vpuqtrcl3irsqq
outproxy.h2ik.i2p,nwgvfpfarpnyjjl4pwsxr2zdsppcx5we3kos2vlwicbiukopgaza
outproxyng.h2ik.i2p,v32zse2zczzgegelwxbx7n5i2lm2xhh2avltg76h6fz5tb53sfxq
overchan.oniichan.i2p,g7c54d4b7yva4ktpbaabqeu2yx6axalh4gevb44afpbwm23xuuya
p4bl0.i2p,lkgdfm4w6e2kkjhcdzr4ahhz26s3aunhrn6t2or436o73qh4z7ga
pants.i2p,xez3clscjfafkqwk6f473ccp3yvac4kh6rdp6dptwxa2lhixizgq
papel.i2p,mxskjqntn2d34q4ovsnd5mud7cgde734tdjldd3lt4hczh2645zq
pasta-nojs.i2p,dkkl3ab6iovxfqnp44wsjgqaabznvu7u3hugpzyagbeqlxgvx3la
paste.crypthost.i2p,2zaj4u4s4l3lgas2h5p6c6pvzr2dckylkrh5ngabursj4oh25ozq
paste.i2p2.i2p,b2gizskfea4sjxlw6ru2tb6kdrj47dsjc77cijsf5mzh4ogbmfvq
paste.r4sas.i2p,csen43keji3qiw6uobsgzysxyjd225g6446ylq5uuz6ur2glkzaa
pastebin.i2p,mnicncxrg2qqi55qftigiitaheugnj4rpysbk7zabdrirgktelqa
pastethis.i2p,erkqiwnjl7vtysqd3wvddv6tfvnhswarqkbn4blhdlhfxn7cf2ha
pdforge.i2p,wzeg3ehf6d2mqjqji3sd3rns776thvhe2vam2r6gjlmsqis2dctq
perv.i2p,f3k3wm4ae7t7ottfjd4hu6is7zsls73izl2gm2qynzficxcdsiwq
pgp.duck.i2p,wujajyxj3cgsfsbtr3g7g7npv5ft3de6pcstxlav26zq6cxdjmha
pharos.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
pharoz.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
phonebooth.i2p,noxia7rv6uvamoy2fkcgyj4ssjpdt4io6lzgx6jl6wujpufxedrq
photo.i2p,fqhuy77ugd5htnubzkyy5guvwboqn6goahtmn2g7feewvdj7k3iq
piespy.i2p,vzusfjzcu5ntnvobcvyzc4dcu4j6ommtnpmba2puk3kexgdzrl7a
pisekot.i2p,7yzdwhy723fodqz4onp6k3nyvixra2sa6dl45tcblhmyoa7i36nq
pizdabol.i2p,5vik2232yfwyltuwzq7ht2yocla46q76ioacin2bfofgy63hz6wa
planet.i2p,y45f23mb2apgywmftrjmfg35oynzfwjed7rxs2mh76pbdeh4fatq
plugins.i2p,wwgtflbaa7od2fxbw4u7q7uugmdclxf56alddvizugwcz5edjgia
polecat.i2p,het5jrdn35nhkanxmom5mjyggyvmn2wdj2agyqlrv4mhzhtmavwq
politguy.i2p,6dkkh3wnlwlr6k7wnlp4dbtf7pebjrph5afra2vqgfjnbihdglkq
pomoyka.i2p,omt56v4jxa4hurbwk44vqbbcwn3eavuynyc24c25cy7grucjh24q
pool.gostcoin.i2p,m4f4k3eeaj7otbc254ccj7d5hivguqgnohwelkibr4ddk43qhywa
pop.mail.i2p,bup6pmac7adgzkb5r6eknk2juczkxigolkwqkbmenawkes5s5qfq
pop.postman.i2p,ipkiowj7x4yjj7jc35yay3c6gauynkkl64gzzyxra3wmyhtfxlya
pravtor.i2p,2sr27o5x2v2pyqro7wl5nl6krrsbizwrzsky5y7pkohwh24gn6xq
pris.i2p,ahiwycgzuutdxvfqu3wseqffdnhy675nes57s4it2uysy5pxmz6a
project-future.i2p,ivqynpfwxzl746gxf376lxqvgktql2lqshzwnwjk2twut6xq7xta
projectmayhem2012-086.i2p,ehkjj4ptsagxlo27wpv4a5dk4zxqf4kg4p6fh35xrlz4y6mhe4eq
protokol.i2p,f4xre35ehc5l6ianjvt3zcktxkjlyp2iwdje65qnu2j6vurhy6nq
proxynet.i2p,7gar5a3n4hzvsgi73iizo65mjza4kujf7feopfxuwu5p6wtwog5a
psi.i2p,avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a
psy.i2p,s3elzoj3wo6v6wqu5ehd56vevpz2vrhhjc5m6mxoazicrl43y62q
psyco.i2p,eoilbrgyaiikxzdtmk2zeoalteupjrvcu3ui23p4wvfqo25bb73q
pt.hiddenanswers.i2p,o5jlxbbnx3byzgmihqye3kysop5jgl3unsrkmurbtr2nrnl2y74a
ptm.i2p,7dna5745ynxgogpjermnq26hwrqyjdlsibpjfmjxlwig247bjisa
ptt.i2p,q7r32j7lc3xgrcw2ym33wv4lfgqbez7vtm4lts7n34qfe3iygeha
pull.git.repo.i2p,3so7htzxzz6h46qvjm3fbd735zl3lrblerlj2xxybhobublcv67q
push.git.repo.i2p,jef4g5vxnqybm4zpouum3lzbl6ti6456q57nbyj5kfyldkempm3a
pycache.awup.i2p,w45lkxdnqhil4sgzanmxce62sv3q4szeowcjb2e72a5y5vbhm4ra
r4sas.i2p,2gafixvoztrndawkmhfxamci5lgd3urwnilxqmlo6ittu552cndq
radio.r4sas.i2p,cv72xsje5ihg6e24atitmhyk2cbml6eggi6b6fjfh2vgw62gdpla
ragnarok.i2p,jpzw6kbuzz3ll2mfi3emcaan4gidyt7ysdhu62r5k5xawrva7kca
ransack.i2p,mqamk4cfykdvhw5kjez2gnvse56gmnqxn7vkvvbuor4k4j2lbbnq
rasputin-sucks.i2p,fdozdbyak4rul4jwpqfisbkcx4xbrkuvf2o5r6fd3xryyrjgvjiq
rebel.i2p,nch2arl45crkyk6bklyk2hrdwjf5nztyxdtoshy6llhwqgxho5jq
red.i2p,fzbdltgsg7jrpz7gmjfvhpcdnw5yrglwspnxqp4zoym3bglntzfa
redpanda.i2p,3wcnp6afz4cikqzdu2ktb5wfz7hb3ejdbpn7ocpy7fmeqyzbaiea
redzara.i2p,ty7bt62rw5ryvk44dd3v5sua6c7wnbpxxqb6v4dohajmwmezi7va
reefer.i2p,4cde25mrrnt5n4nvp5tl62gej33nekfvq2viubmx4xdakhm5pfaa
relatelist.i2p,utrer5zgnou72hs4eztmk37pmzdtfw3d6s23wwl7nk3lkqpzbdiq
repo.i2p,uxe3lqueuuyklel23sf5h25zwgqgjwsofrqchhnptd5y6pedzbxa
repo.r4sas.i2p,ymzx5zgt6qzdg6nhxnecdgbqjd34ery6mpqolnbyo5kcwxadnodq
reseed.i2p,j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq
retrobbs-nntp.i2p,fkyzl24oxcxvjzkx74t3533x7qjketzmvzk6bwn3d6hj5t7hlw6q
retrobbs.i2p,mnn77stihntxdoade3ca2vcf456w6vhhvdsfepdvq5qggikvprxq
retrobbs2.i2p,ejff7jtyaus37slkwgeqrrcmyhpj26carp7n27f5h6s5vlbeiy6q
revo-ua.i2p,hpojpumki22xjwhmhe6zkiy44oanyn7u4ctcfe3in2ibwm5l32hq
riaa.i2p,lfbezn7amkzhswnx7lb4lxihyggl2kuqo5c7vwkcv6bwqmr4cuoa
rideronthestorm.i2p,xrdc2qc7quhumhglpbcuiqxr42nuffv4xj4a73jbr4ygepitibqq
romster.i2p,eaf2stdqdbepylt53egvixdi34g2usvgi7a4oixsja6atkran43a
rootd.i2p,mzbe5wofwn7eaqq4yefrmxizqaxoslwqxrv5qcv2opx5lnhg64dq
rospravosudie.i2p,z55khrnlj6bzhs5zielutm6ae6t2bbhfuiujwlrp3teubqyc4w7q
rotten.i2p,j4bm3rvezlejnb44elniagi5v2gazh7jaqrzhbod2pbxmgeb2frq
rpi.i2p,56p5qxsrvo5ereibevetw2qbj5bronmos7wxunku27g2s4kpbnlq
rslight.i2p,bitag46q3465nylvzuikfwjcj7ewi4gjkjtvuxhn73f6vsxffyiq
rsync.thetower.i2p,w4brpcdod7wnfqhwqrxyt4sbf2acouqfk5wyosfpq4mxq4s35kqa
ru.hiddenanswers.i2p,o6rmndvggfwnuvxwyq54y667fmmurgveerlzufyrhub6w3vkagva
ru.i2p,m7fqktjgtmsb3x7bvfrdx4tf7htnhytnz5qi2ujjcnph33u3hnja
rufurus.i2p,7msryymfdta3ssyz34qur6gi4jyfkvca5iyfmnceviipwu7g2wca
rus.i2p,gh6655arkncnbrzq5tmq4xpn36734d4tdza6flbw5xppye2dt6ga
ruslibgen.i2p,kk566cv37hivbjafiij5ryoui2ebxnm7b25gb3troniixopaj6nq
rutor.i2p,tro5tvvtd2qg34naxhvqp4236it36jjaipbda5vnjmggp55navdq
salt.i2p,6aflphlze6btsbez5cm4x53ydrmwhqrkxsud535d3qjh4wq62rxq
sasquotch.i2p,p6535uyfk2y6etc3t47vd3oqxydznqior5jxcvq5bdxe5kw5th6q
schwarzwald.i2p,4gokilzy73mmudufy3pohgatm42fcstx7uzg5hjvnfyphxpnphuq
sciencebooks.i2p,ypftjpgck75swz3bnsu4nw7rmrlr2vqsn4mwivwt3zcc3rxln5cq
scp.duck.i2p,ghbpsolpnveizxu4wbs7jbs2vj3kntnsexfcdleyhpqdhfpxleda
search.i2p,nz4qj6xaw5fda3rsmsax6yjthqy4c7uak2j3dzcehtkgyso4q46q
secretchat.i2p,cl3j2zxhpw6u6jevny45i557ojhwfxn4g375nnuqhy6lp27mry2q
secure.thetinhat.i2p,4q3qyzgz3ub5npbmt3vqqege5lg4zy62rhbgage4lpvnujwfpala
seeker.i2p,ipll7sit24oyhnwawpvokz5u7dabq6klveuqpx3sbi6o5qemy2bq
seomon.i2p,5mvpsy4h45w4fx7upen7ay3vkrs5klphz5nptmtcqvc3fsajsm4q
septu.i2p,5lqvih7yzbqacfi63hwnmih57dxopu5g2o5o4e2aorq7bt4ooyra
serien.i2p,3z5k3anbbk32thinvwcy4g5al7dmb75fagcm3zgh4rzrt3maphda
ses.i2p,5qfoz6qfgbo7z5sdi26naxstpi2xiltamkcdbhmj6y6q2bo4inja
shiftfox.i2p,wpvnuzslu7hjy4gujvnphtyckchdoxccrlhbyomsmjizykczyseq
shoieq3.i2p,3fjk4nfk3mccch4hdreghnyijcvovsi3yucjz3qzj5sxngqk5j6q
shoronil.i2p,7shqzgmb6tabiwrnwlasruq7pswy2d3emvfhaitehkqgod7i62sa
short.i2p,z5mt5rvnanlex6r3x3jnjhzzfqpv36r4ylesynigytegjmebauba
sion.i2p,lcbmmw2tvplvqh2dq5lmpxl3vnd5o4j3bdul5moa23deakjrso5q
sirup.i2p,aohdp4yajnkitrtw7v2mo3sp7swuqhjfwlsi5xwd7dudzftumsma
site.games.i2p,zeuczucfxeev3k7tvqlfcdpfbnqggheiknyyb5r2q4utn3d2auja
skank.i2p,qiii4iqrj3fwv4ucaji2oykcvsob75jviycv3ghw7dhzxg2kq53q
slack.i2p,gfcsh2yrb2tx7hyvmobriv52skz7qoobn7n7y7n6xaehhh4rpbja
slacker.i2p,wq7m2wdguzweleb666ygv3bmfhha63zj74rub76vfesbyhsyk6iq
smeghead.i2p,ojf4czveeuekxqkjvkszvv7eiop5dg7x2p6rgfzl4ng4xrjk6lja
smtp.mail.i2p,kdn7zx7fgoe4bn5abaaj5cb3e4ql22fklb5veui5yajpj4cxapya
smtp.postman.i2p,jj7pt6chsziz6oxxnzpqj7mzhxm2xfhcrbh7dl3tegifb577vx5q
socks1.tor.i2p,sifawcdexgdmoc3krv46pvvz74nzd6fkju2vzykjxsx3egqsb6wq
sonax.i2p,jmuxdhlok5ggojehesfjlit2e2q3fhzwwfxjndts7vzdshucbjjq
sponge.i2p,o5hu7phy7udffuhts6w5wn5mw3sepwe3hyvw6kthti33wa2xn5tq
squid.i2p,r4ll5zkbokgxlttqc2lrojvvey5yar4xr5prnndvnmggnqzjaeoq
squid2.i2p,hum4wlwizbsckbudcklflei66qxhpxsdkyo4l2rn256smmjleila
sqz.i2p,3jvbwc7sy4lnhj25nj7yepx7omli4ulqirnawv3mz6qlhgokjgzq
ssh.i2p,xpvdadaouc4qr75pteymyozc7mcsynjfkuqqkkla542lpcsqionq
stasher.i2p,6ilgpudnba4kroleunc2weh5txgoxys5yucij5gla6pjyki4oewa
stats.i2p,7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq
status.str4d.i2p,ycyyjo3psqbo45nuz243xvgvwnmzlanzqbzxv3kh6gyjztv7425q
sto-man.i2p,rg4eilfpe24ws6nctix63qw2dlvd2tqgwdcgdxzji6l5bc4dc7aa
str4d.i2p,wrrwzdgsppwl2g2bdohhajz3dh45ui6u3y7yuop5ivvfzxtwnipa
stream.i2p,prmbv3xm63ksoetnhbzqg4nzu2lhqdnqytgsydb7u3quxfrg7rna
streams.darkrealm.i2p,ud3gcmvysjch4lbjr2khmhqpf7r2x5if4q43xkqdptl4k7lc4muq
striker.i2p,4gswsrfpbd44hwjoj33jbqfbwzxfkwpuplb3ydq5zm7nfu2pxvdq
subrosa.i2p,g3lnglrnoual7wyabnwwv37uwhadgbxiqz36pf3f5cwfuxsx4mxq
subterra.i2p,vdmhe4u26unzgd7ysq6w36ubjncms5wzbhzr2gq576sq4xut5zwq
sugadude.i2p,yzjn76iyqard64wgggfrnywkxi7tbfkw7mjhpviqz3p2dguey4yq
suicidal.i2p,yfamynllow5xiqbbca7eh5xn733wtnuti5bi4ovc7dwycntqmiuq
sungo.i2p,h67s3jw56rwfyoxqxj3fngrluybsgxc2meendngkehzqowxnpj3q
surrender.adab.i2p,jgz7xglgfgnjfklrytyn427np2ubipztlm5bxrtbiucayglukrta
susi.i2p,qc6g2qfi2ccw7vjwpst6rwuofgzbeoewsb2usv7rubutf4gzqveq
syncline.i2p,5kcqmhislu3lmr7llgmdl72yu3efhyriljdc6wp774ftpwlcs5ra
syndie-project.i2p,xa63tpfoaqt3zru2ehxjjfbpadwj4ha6qsdvtcqtyr3b7hmt4iaq
syndie.echelon.i2p,vwrl2qmcif722fdkn3ldxcgz76df5cq4qypbndzthxwgmykyewta
syndie.i2p,7lm3yzpuejhpl4tt4l7o4ndqlu7hgijohofh7oaydx7q7kelenbq
syndiemedia.i2p,4lrbbblclodhobn3jadt5bf2yab2pxzoz4ey4a2cvrl44tdv3jma
tabak.i2p,y5o2vwb6kart7ivpnbpk4yte3i7kf2dsx7fy3i6w7htqtxhmbzia
tahoeserve.i2p,yhs7tsjeznxdenmdho5gjmk755wtredfzipb5t272oi5otipfkoa
tc.i2p,qkv2yk6rof3rh7n3eelg5niujae6cmdzcpqbv3wsttedxtqqqj7a
telegram.i2p,i6jow7hymogz2s42xq62gqgej2zdm4xtnmpc6vjcwktdxpdoupja
templar.i2p,zxeralsujowfpyi2ynyjooxy222pzz4apc2qcwrfx5ikhf64et7q
terror.i2p,wsijm6aqz4qtuyn2jedpx6imar5uq4yuhjdgtfqumxbqww47vbnq
thebland.i2p,oiviukgwapzxsrwxsoucpqa47s3wt6nfuhfjxvgbqsyrze2mwrda
thebreton.i2p,woutbsflcrlgppx4y7ag2kawlqijyenvlwrhbbvbkoaksuhf2hkq
thedarkside.i2p,fxt3z33nzkrg5kjrk7bp5vvmu7w2vsn4i6jo6cily3hsm6u664ca
theland.i2p,26ppxbseda6xmim37ksarccdb4q5ctdagfmt2u5aba6xjh452zsa
thetower.i2p,3xqa5nype64y6fxgqjq6r5w2qpiqftoraj2niebumseat4cj654a
thornworld.i2p,vinz4ygmodxarocntyjlfwk2wjpvzndlf4hxss2w2t3fk52oplva
tino.i2p,e4bfnhvaofu4s67ztcgiskos2mqyhskid64dvlqexxs2c2bno3iq
tinyurl.i2p,mc4oxv3v7dnyzpvok7v5qxkwtgjprgyz6w7x3tag4fipsen6rdwa
tome.i2p,qktkxwawgixrm5lzofnj5n24zspbnzxy4pvjm7uvaxvmgwrsuvgq
tor-gw.meeh.i2p,ounrqi7cfemnt66yhnhigt2u27fkctbvct527cp2522ozy3btjza
tor-www-proxy.i2p,xov45rvjks5fe4ofmpblkj23bnwxgslbypbgvchbr7yul2ujej2q
torapa.i2p,eejqjtpko6mdd4opvntbpsuandstrebxpbymfhix7avp5obrw5ta
torrentfinder.i2p,mpc73okj7wq2xl6clofl64cn6v7vrvhpmi6d524nrsvbeuvjxalq
torrfreedom.i2p,nfrjvknwcw47itotkzmk6mdlxmxfxsxhbhlr5ozhlsuavcogv4hq
trac.i2p,kyioa2lgdi2za2fwfwajnb3ljz6zwlx7yzjdpnxnch5uw3iqn6ca
trac.i2p2.i2p,i43xzkihpdq34f2jlmtgiyyay5quafg5rebog7tk7xil2c6kbyoa
tracker-fr.i2p,qfrvqrfoqkistgzo2oxpfduz4ktkhtqopleozs3emblmm36fepea
tracker.awup.i2p,dl47cno335ltvqm6noi5zcij5hpvbj7vjkzuofu262efvu6yp6cq
tracker.crypthost.i2p,ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq
tracker.fr.i2p,rzwqr7pfibq5wlcq4a7akm6ohfyhz7hchmy4wz5t55lhd7dwao5q
tracker.i2p,lsjcplya2b4hhmezz2jy5gqh6zlk3nskisjkhhwapy3jjly4ds5q
tracker.lodikon.i2p,q2a7tqlyddbyhxhtuia4bmtqpohpp266wsnrkm6cgoahdqrjo3ra
tracker.mastertracker.i2p,tiwurhqvaaguwpz2shdahqmcfze5ejre52ed2rmoadnjkkilskda
tracker.postman.i2p,jfcylf4j3gfmqogkltwy7v5m47wp4h7ffrnfsva6grfdavdn7ueq
tracker.psi.i2p,vmow3h54yljn7zvzbqepdddt5fmygijujycod2q6yznpy2rrzuwa
tracker.thebland.i2p,s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq
tracker.welterde.i2p,cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa
tracker2.postman.i2p,ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna
traditio.i2p,wkpjjloylf6jopu2itgpktr45t2xvpjijxilxd5tq4i7wkqgwhhq
trevorreznik.i2p,wc2z6o5fxm2saqzpfcawr63lejwccvzkysmgtfudkrigqopzfdma
true.i2p,pdilhl5vmefyzrrnmak5bnmxqxk2pmw7rpy4f7wbaeppqu2vvugq
trwcln.i2p,evml6jiiujhulsgxkdu3wcmkwbokxlv4is6w5qj46tp3ajz3hqzq
trypanom.i2p,tgv5acj4khwvr6t44cmryohybd2e5o2kndysnzae6qwcr4hzda3q
ts.i2p,nebcjgfx3f7q4wzihqmguwcdeopaf7f6wyk2dojw4bcuku472zxq
ttc.i2p,wb4tsfyvfv4idgrultsq6o7inza4fxkc7dijsfpncbx7zko4cdlq
ttp.i2p,uuczclxejmetohwf2vqewovx3qcumdfh5zecjb3xkcdmk6e5j72a
tumbach.i2p,u6pciacxnpbsq7nwc3tgutywochfd6aysgayijr7jxzoysgxklvq
tutorials.i2p,zy37tq6ynucp3ufoyeegswqjaeofmj57cpm5ecd7nbanh2h6f2ja
ugha.i2p,z3f3owc72awbywk4p6qb5l2mxgitvs6ejztggbpn2a3ddmymfjda
uk.i2p,vydbychnep3mzkzhg43ptewp242issy47whamfbxodc4ma6wc63a
underground.i2p,dlnuthb6tpw3kchlb7xoztyspy4ehlggjhl44l64vbcrulrfeica
underscore.i2p,3gmezyig6gvsjbpkq2kihoskpuqpkfrajmhhm7hpyrjuvtasgepa
unqueued.i2p,3gvn4kwd7z74jxc2sn4ucx52dpvpscxbzjluux3ul4t3eu5g64xq
up.i2p,25it5olgdo7pht25z6buzd32sw7jvc65oziqeuocfozfhgua655q
update.dg.i2p,iqj6ysfh3wl26m4buvyna73yhduifv523l7bwuexxak4mgldexja
update.killyourtv.i2p,gqdfg25jlqtm35qnmt4b7r53d6u2vep4ob23fwd42iyy4j6cvdqq
update.postman.i2p,u5rbu6yohfafplp6lgbbmmcuip34s7g3zqdd63cp27dl3nbd7gtq
utansans.i2p,u2oyre7ygqv4qs5xjjijfg3x7ddwtod6nqwgbomuuzljzvnq4rda
v2mail.i2p,4gg7fykcqe7oaqt4w5fmlarnia7vtmwkv3h45zzgoj6o6crryg5a
vadino.i2p,aalttzlt3z25ktokesceweabm5yyhhvml2z3rfotndgpfyh6myra
visibility.i2p,pwgma3snbsgkddxgb54mrxxkt3l4jzchrtp52vxmw7rbkjygylxq
volatile.i2p,q6rve733tvhgyys57jfw4fymqf3xsnza6dqailcdjcq7w4fa5m3a
vpnbest.i2p,ov5f74ndsy5rfkuyps56waf42vxncufqu5rzm3vsnxkdtogccaea
vudu.i2p,3zlwci7pvgep2igygzyjej24ue7mjsktlhaff6crpsr75yquak2q
w.i2p,j2xorlcb3qxubnthzqu7lt4fvxqn63it4ikwmze55yjkzeeampuq
wa11ed.city.i2p,7mxwtmala3ycg2sybjwwfil7s6dqck2fbemeutghhwu73rznmqoa
wahoo.i2p,vqe5vkpe5wbda7lwekcd2jaj44ar3rawgv54u5rcolezbg5f5vwa
wallet.gostcoin.i2p,reuvum7lgetglafn72chypesvto773oy53zumagrpigkckybrwda
wallsgetbombed.i2p,tzhea5d65fllm4263wztghgw4ijdgibsca5xsecp6lk4xlsbdeuq
web.telegram.i2p,re6cgwg2yrkgaixlqvt5ufajbb3w42fsldlq7k5brpvnd5gp6x5a
wiht.i2p,yojmpj3sh76g3i6ogzgsf7eouipdgdij5o2blcpdgmu5oyjk5xca
wiki.fr.i2p,lrqa7hw52uxjb5q3pedmjs6hzos5zrod4y6a4e25hu7vcjhohvxq
wiki.ilita.i2p,r233yskmowqe4od4he4b37wydr5fqzvj3z77v5fdei2etp2kg34a
wintermute.i2p,4gvlfrdy2rkmem33c342tjntpvqik65wekcvm4275qbkuwotoila
wspucktracker.i2p,ubd2txda3kllumx7ftg4unzgqy536cn6dd2ax6mlhodczfas7rgq
www.aum.i2p,3xolizygkzkqrldncjqsb734szznw2u36lliceuacqnbs2n65aeq
www.baffled.i2p,lqrsfslwu4xnubkk2hofhmuvvr4dia2zevxefinbzdsjurvehtqq
www.fr.i2p,rmkgvlfwo3vkb3xrr6epoypxasdzzuilv3sckcqbo6c4os5jo2ea
www.i2p,ojxyenivrrqvycgbxbm3phgisu5abspzq4g2us4fjlwz4tx222va
www.i2p2.i2p,rjxwbsw4zjhv4zsplma6jmf5nr24e4ymvvbycd3swgiinbvg7oga
www.imule.i2p,657xcllunctawyjtar5kgh3wpt6z4l7ba6mmam5rf7hev5w2lsvq
www.infoserver.i2p,fq7xhxkdcauhwn4loufcadiiy24zbei25elnup33a3gfrdzrtlyq
www.janonymous.i2p,vosqx5qw22hwrzcgsm4ib7hymf5ryovsbtaexqrzmnzshy5bhakq
www.mail.i2p,nctas6ioo7aaekfstv3o45yh6ywzwa3vznrdae52ouupzke5pyba
www.nntp.i2p,kly3o7zmetuwyz7xonnhttw4lj2244pkbibjz26uflyfte3b3dka
www.postman.i2p,rb3srw2gaooyw63q62cp4udrxxa6molr2irbkgrloveylpkkblhq
www.syndie.i2p,vojgy5ep4wffmtpjmpnbpa4gq64bgn4yicuw6qmhbm6nqa2ysrva
www1.squid.i2p,vbh3bltd2duwbukafgj6f6vfi6aigwso7snucp5zohnf66a2hkpa
xc.i2p,mt45a2z3sb2iyy2mwauj4rwa2lwu4peanfy6gx6ybidwnbasusyq
xeha.i2p,oartgetziabrdemxctowp7bbeggc7ktmj7tr4qgk5y5jcz4prbtq
xilog.i2p,eoc5i5q52hutnmsmq56edvooulutaxfikddgdz27otmgtsxmiloq
xmpp.crypthost.i2p,ittkqpjuliwsdewdugkhvgzstejr2jp5tzou7p332lxx4xw7srba
xmpp.rpi.i2p,3yv65pfwiwfuv4ciwtx34clqps6o2mc3vtyltcbqdkcki6untbca
xn--l2bl5aw.i2p,d2epikjh5crt2l5xjmtceqw2ho44hzp6x3u7hgjrd4mi4wywikwa
xolotl.i2p,rwr6rrlmrotxfkxt22mah42cycliy2g5k7hgxyxkpcyyxkd2bgwq
xotc.i2p,gqgvzum3xdgtaahkjfw3layb33vjrucmw5btyhrppm463cz3c5oq
z-lab.i2p,s6g2pz3mrwzsl4ts65ox3scqawfj7mzvd7hn2ekiiycawopkriba
zab.i2p,n4xen5sohufgjhv327ex4qra77f4tpqohlcyoa3atoboknzqazeq
zcash.i2p,zcashmliuw3yd2ptfyd5sadatcpyxj4ldiqahtjzg73cgoevxp4q
zener.i2p,mcbyglflte3dhwhqyafsfpnqtcapqkv2sepqd62wzd7fo2dzz4ca
zerobin.i2p,3564erslxzaoucqasxsjerk4jz2xril7j2cbzd4p7flpb4ut67hq
zeroman.i2p,gq77fmto535koofcd53f6yzcc5y57ccrxg3pb6twhcodc7v5dutq
zeronet.i2p,fe6pk5sibhkr64veqxkfochdfptehyxrrbs3edwjs5ckjbjn4bna
znc.i2p,uw2yt6njjl676fupd72hiezwmd4ouuywowrph6fvhkzhlnvp7jwa
znc.str4d.i2p,ufkajv3stxpxlwgwwb2ae6oixdjircnbwog77qxpxv7nt67rpcxq
zzz.i2p,ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq
1 00.i2p zmzpltxslembpaupg3srh4bbhv5txgh5jmms6sfj4hzsvlv3xugq
2 0ipfs.i2p cdii3ou5mve5sfxyirs6kogt4tbvivk2d6o25awbcbazjrlhjeza
3 0xcc.i2p gawouxh2sg32cluwlqsnpy3dwedvoqtfroi4evvdvm2pfv7tdadq
4 1.fcp.freenet.i2p cuxbeputgxn75ak4nr7ltp7fjktnzl5sul3wstwnsoytbbpb4ixq
5 102chan.i2p xxu3lso4h2rh6wmrxiou3ax7r7la7x6dhoepnku3jvrlwp35pefq
6 1st.i2p rduua7bhest6rwsmmyttzssfdw3p4eu6bgl3mb4hin32qo3x5zfq
7 2.fcp.freenet.i2p ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
8 333.i2p ctvfe2fimcsdfxmzmd42brnbf7ceenwrbroyjx3wzah5eudjyyza
9 55cancri.i2p b4iqenefh2fr4xtuq6civfc6nhnia6e2yo36pf7vcgdvrwmh7xua
10 adab.i2p pxjr6f2cig6v7v7ekam3smdnkqgmgseyy5cdwrozdyejm7jknkha
11 alice.i2p iq26r2ls2qlkhbn62cvgb6a4iib7m5lkoulohdua5z6uvzlovjtq
12 always.i2p wp43sdtuxum6gxbjvyeor35r5yvgtkp3dcu7dv47lx22zeb3relq
13 amazone.i2p e6kq73lsxaeyiwpmykdbdo3uy4ppj64bl7y3viegp6mqrilqybqa
14 amiga.i2p edy2xappzjjh7bxqounevji4wd2binqkv7gft4usrkan45xhbk5q
15 amobius.i2p rj6432agdprun5baai2hj62xfhb4l75uvzl55dhj6z5zzoxv3htq
16 anarchistfaq.i2p xosberjz2geveh5dcstztq5kwew6xx2brrqaorkjf2323bjzcd3q
17 animal.i2p 5iedafy32swqq4t2wcmjb4fvg3onscng7ct7wb237jkvrclaftla
18 anodex.i2p 25cb5kixhxm6i6c6wequrhi65mez4duc4l5qk6ictbik3tnxlu6a
19 anoncoin.i2p nmi3loretkk4zbili32t2e5wyznwoxcsgzmd2z4ll3msgndyqpfa
20 anongw.i2p owrnciwubb3f3dctvlmnaknb6tjdxtlzvv7klocb45mmhievdjhq
21 anonsfw.i2p ir6hzi66izmvqx3usjl6br3nndkpazonlckrzt3gtltqcy5ralyq
22 anonymnet.i2p 77ouyl2ane7ffgydosd4ye42g67aomtc4jrusmi76lds5qonlffa
23 anonynanny.i2p l2lnhq2dynnmf3m46tcbpcmbbn4kifjgt26go6n2hlapy4drhyja
24 anonyradio.i2p cbobsax3rhoyjbk7ii2nd2fnl5bxh3x7bbearokyxgvmudn7o5bq
25 antipiracyagency.i2p by4kcmklz7xnkai6ndfio47kts3rndm6wwleegtxghllimikdapq
26 antipiratbyran.i2p y2qbhrvuciifbszaqqwxd5t75bomp7kzdqx4yxsrkaq542t75k3a
27 aosp.i2p ly7raldsh2na2cgw5yvueyvqqjgx3vbqinecjrqdldgya76i2p2q
28 arc2.i2p rnmosuwvtftfcrk5sk7zoyhyadh2g4dhe2mif5ml7qjisgkyw2na
29 archaicbinarybbs.i2p t7o2tw36cffedgfr6kahewpkrntofnliuapji2e4rucl3os55epa
30 archiv.tutorials.i2p lldr2miowq6353fxy44pnxfk37d6yn2f6kaivzecbmvvnnf5exyq
31 archive.i2p x54d5st3dl6mwgfxj6raiekqkypo5pdvuex3n62szwju7hgefiyq
32 archive.syndie.i2p abbyu5n3mh3nj7pe3b6byldrxswvva5ttxcafsnnseidanurq3kq
33 ardor-wallet.i2p tm23k5ny3umhf6vf3kghnnwacli5zywq5wrr3xcqowbcofuyr4gq
34 ardvark.i2p jcmw2sol3hruwc6rfinonx4e23pjkukkg7lg7xt7xb2gpiyyraiq
35 arf.i2p o46lsq4u7udxg3qqlidrmpj4lb4nr7ldxmbb2x53nftndaeyxqeq
36 arkan.i2p 7o5y2lyyrjx5tf6l4fyumywui7msjv5azaaheatvw5sqj7mxbuvq
37 asciiwhite.i2p itbzny5ktuenhjwjfqx3jravolhlj5wullhhr2m4qr6k2emnm5dq
38 aspnet.i2p tsb7zqru57p4q2a7cto2lko4w5cg4lieglwm6t27c44fkphqmf2a
39 asylum.i2p p45ejjw4p2q6nq3mzi6cm6ep35grtzshboidj2lojmrmic22noha
40 auchan.i2p 6vxz4yp3vhjwbkmxajj7wiikxafwujig63gkhjknbq6xh4rqpm5a
41 aum.i2p ohdfneqxapfd3fwfbum4tut7z6k3rnr7rrguoxdrrfe2tln2kpbq
42 awup.i2p v6g32duzrkacnrezfbll3pza5u37h7lnukr2wbsk6rqen6prhbga
43 b.i2p 272kt3gcx6wjurunzaiiwld7s5p4mpjewfubzmlcvw2vie62ckpq
44 bacardi.i2p hivhnx2v47vh234c7coi2urj5cyvbl4bu3ypjr7snklortyqeljq
45 backup.i2p kepphem42whle3rkfv26wcksmnegdbg6rdp6t3oobdkc2fmzrdkq
46 badfish.i2p f6v26gyr4eipy3a7pi2voulw5qvob6dg7zij6xpo2ywbi5tvbu6a
47 badtoyz.i2p 3qz6ubtwlt2c4iasofjirkckq43u5fgkzyg7mlutcsym5gzhijna
48 barry.i2p 4kyahq53ol52n23l44tefgeaxqpp3cbb632t5k3umdvqcooevdzq
49 bash.i2p s3wouoilbl3mrefxjhp4qoyujgok34e7y6vmpbu6hx4342ivqo4q
50 bdl.i2p kp6fnuulenbjm7r26pfbmjcq3u7c7kvxeajodvgr5flcnskdgi5a
51 bdsm.i2p pa7fxql5jljegg7j5tglhnnaod2sptq3gxvdn3ji6muqyhgn3poq
52 betaguru.i2p d7cduwwhrcc2voameqfkvd66u3advu4jw2p6pysgax35vq6ovriq
53 beyond.i2p uaicfqlrpjtitqbqkpfujanj5dollzfzee5glsuls67ekw6hlpoa
54 bible.i2p pypz7ca24n3lyp4tm3kvncg3ltp3gd5pgnacc6zltoeffiyyegda
55 bible4u.i2p xs6lr2g5jiaajtb3nkno2zmy34eipitrggooxb7wtey7uko7bqmq
56 bigbrother.i2p tnxiifs6uticzyg6ac4lhv2l5luwi6xra7yngocro56ive5e4jsq
57 bitlox.i2p lqw5khxcdntlv3u4vhn53upcqirplvnc4etjlmoytrzs66ytettq
58 bittorrent.i2p pgax2vz572i4zsp6u6paox5xubmjrkqohq6g4hvlp6ruzzy56l5q
59 bk1k.i2p nlyegmtyfffo5jfgg5h4dxxnlmqko2g36gpaye5a7vd3is35xxfq
60 bl.i2p e73d6uhnfbylza6wqkhxejmqeyfb7thkzw35gn5ojmna64jzyk2a
61 black.i2p sjwueu62qpe6dtv5b322k3f23fl4uz3w6qe6wcrwauiwpnymypfq
62 blackbox.i2p 7josyf7zjieoib3ovmr5a4dh5w64kmfh45lv5h436eljtgfegtqa
63 blackexchange.i2p ztgr5kghkyn43fhhkuycroxgfti6cojo3vg4wdd3usqonyvrla5q
64 blog.curiosity.i2p yiz6jec5k7ccxdgnh7msqa4ze52bqqmf6rpq6bqdyojra2erd4ta
65 blog.polecat.i2p orlccceubewvxo3fbdyydq6e4uuidbs4xd5u2gyqbculnowo3ehq
66 blog.tinlans.i2p ylkch2nkrwehakx4z6wiyjbeqwlgasknukdkex6r6yq4xusrjnda
67 bluebeam.i2p lvxp3cbcfwtol57d5pmrsck32t7ndutlxubjb4smaf32bynhlk6a
68 blueheron.i2p anfb5jrhixjmvkyxctqwkezqer7dbob22wge2bh6wsewbhgnftfa
69 bnc.i2p fr4zbcygmx2vdct6nrabakfys4b4derm6jqu2ovppkgqillvlqxa
70 bob.i2p i76m7dwm5hnapljendbie6fc5y3mjlkdlduo3tvbwiwmvhxbpyaa
71 bobcat.i2p ftuukjtcquuvppt726w37boit7gp5hf2yxwfop35prx3grzzzxlq
72 bobthebuilder.i2p qlahgthqhr4uojkkwahnper2cl3ro5f5gtzy5t4lzapbzo4osy6q
73 boerse.i2p 7633w56hd53sesr6b532r5qlbdnvyl5bnvama6ign6xryaxol4rq
74 bofh.i2p auvuinzogu6gc4pwsgbjijuszxgcjygciu2wy53pfz7mo5nfpc5a
75 boing.i2p bgsq33bh74j66hn4oh7oovlvuhhdyw22lq2qi2fnv3jyh2ryap3a
76 books.manveru.i2p eb2tisc2vr5jvjqrixrozcujiucwxg4m722stxwho5666ipl67zq
77 bote.i2p bhjhc3lsdqzoyhxwzyrd63kvyg4br6n2337d74blyintae66mr2a
78 bozo.i2p 7a2d23h6htprhzrol36vgwgklsbqrnuya4tbaaaspmaeaodt57iq
79 brittanyworld.i2p e76umhhic3474sdxiuax25ixyfg7y3z7oojj4fmxvhgv3ruet6aa
80 bt.i2p uhkuu54pg47zey76h45tnvsdtpkf5bthbtrjgnaloi5m54h4hlaq
81 bugfuzz.i2p ubszn4gsf22vga67rvzzlg4qj2bfcq6o52fmxz46xruawqm6z7rq
82 burntout.i2p lkep3fd7tjvxrs25crr2c3jy7xm4s7bqiua5r327zgpw37sgyerq
83 bytepay.i2p 7amc4ztwkzu3cgsaaaw3223ohuihn5hlsqc6gpf2rxdyptdkyugq
84 ca.i2pd.i2p u5safmawcxj5vlrdtqrsqbsndkr5cfenpicgg5euu4xqm73yicba
85 cases.i2p kmpmk2fmineaiwublteqlifg4fkmewnhmxqlcgg7qwecz6daj43a
86 cathugger.i2p vq43xjjcnejqpzfprws5qzrea2siieshu4tglpdepql2w3w3bpba
87 cbs.i2p u3lp7wazvq6opodzwjg5sc5w5kwxehmxd4wcdpt4s4j2k4dx4apq
88 cerapadus.i2p zroed2cxga5zeuu6rcvmp2yfi77nzduw7yhdplbeuqkuyxwbrzaq
89 cerebrum.i2p u5gtsfn267udwfh2uq35jiabkufifvcbgv456zz34cydutsiw2eq
90 cgan.i2p 43z65gdr52xe3fxmkumwp3dzhedu4tu4rdtzr24hz5b4awcpfbqa
91 chat.i2p ollpwnp6yidc3obbb3famgt6rw5jg5w3k3a6z7hhaegj6gcohiuq
92 chess.fillament.i2p tv6wbanei647yf5bie4dhg2wmybkjurezlpdfwftc5ajqlfswwya
93 chess.i2p sbnoqznp5yzxals3vs6nzyqaj2fetvonys4e3b3x4ktmfeus54sa
94 china.i2p wit6f2zx6dtuqqze6nhbykrds3idppfirxvhf2f7ydqoqf4xdzeq
95 chitanka.i2p u4s3jneepk3akoez46kqiwikoezi6zyj2ibjkjyi4uuvsbcojzba
96 ciaran.i2p 2r3645eete6xwbfu62ogonudcrcgqq25sbnij5v4geru74yrscna
97 ciphercraft.i2p 7s5pkqbpbfdkxtwuu2e2iwstbikyewvvscy76lij4x5pfbygbjca
98 closedshop.i2p 6fg67mbw2okopzyonsck4bsy3cy7l2fame56uiysr2cezhjhzdbq
99 cneal.i2p g4za73ffigv3ht4jnhzy4dae52djjq7lqcguqsfg3w5cxzqm7nba
100 co.i2p 3mvo5eifcwplcsoubtvqkzdahwo2sdhfygfdde7lj2glybk4q22q
101 codevoid.i2p 2mukrqwtinsw27uoejtrz74zxtilyhnnfdyso7j3yo6vaa6nzlaa
102 colombo-bt.i2p cyr75zgiu2uuzap5zeosforbgvpfbqos2g6spe4qfulvzpyhnzxa
103 complication.i2p x2av6rwj5e5tp64yhdmifdyleo4wblw4ncrrcrabxwscuevpdv7a
104 comwiz.i2p 6p7zqfotzbd66etl5xqy3p6xvr5ijucru3am2xqa7wmnj6vf3djq
105 confessions.i2p lh5vitshufxpmyr44zgyymebo5elc42eda7pxvn5lmtes47c7rxa
106 connelly.i2p 5yrris3nigb3fapvzrlrcaew6cdmzdknzvgrc7y2jpn3ntqurweq
107 costeira.i2p abhty5xlmnyab2kqdxcd56352kcescxoux3p6dbqdrghggyygnxa
108 cowsay.i2p q4ghzfpah4ffvm3bhc6fdkrznk5f6jxfjm2daytlparznai5d54q
109 crstrack.i2p mm3zx3besctrx6peq5wzzueil237jdgscuvn5ugwilxrwzyuajja
110 crypthost.i2p zywhrxtnkjc3rxxvxbocom7ml4hnutomgtuvqrwyf3rhuupnq5ca
111 crypto.i2p vffax5jzewwv6pfim55hvhqyynafkygdalvzoqd74lkib3hla3ta
112 cryptostorm.i2p mlu7mswyirjf53usqq7gyamvqc6rqihezgdbevov3dkxmkfo57aq
113 curiosity.i2p eomeif4xrykxlzhawc3icdilje5iammijos6tyizwhrfh3j7qdvq
114 cvs.i2p yd6k7dzpsa2tnlzx4q7xqkmd4qsjk5xk5hbiqpiarwbeyvxaxgba
115 danwin1210.i2p eoqdf4no5dxn4tw5n256kkd4lzz3uk4p47np4mepsykpsdzrnvba
116 darknetnow.i2p gkx3o5fy7mv7l4psqqnhp35d5iun7rt3soci6ylf3rgb7a5a655q
117 darknut.i2p 2mk37gtvpk2i63o6vl7vna4dr46rqexxetupgn5efuuins7x3qya
118 darkrealm.i2p gbh4eerxdsph7etxsxznfhvmuiz54trlkenakqep343u4xcoekzq
119 darrob.i2p hz2xhtpeo6btgiwi6od4qj2575ml5o2246rd5orarruyjhd63zja
120 dashninja.i2p dzjzoefy7fx57h5xkdknikvfv3ckbxu2bx5wryn6taud343g2jma
121 davidkra.i2p nq7ca2egm563nir3xegfv52ocgmxstpz56droji4jgnzfoosk45a
122 dcherukhin.i2p qa4boq364ndjdgow4kadycr5vvch7hofzblcqangh3nobzvyew7a
123 de-ebook-archiv.i2p 6mhurvyn6b6j6xa4a3wpuz7ovpsejbuncvyl6rnhepasfgdgmn7q
124 de-ebooks.i2p epqdyuuhtydkg5muwwq47n7jvr66pq4jheve7ky5euls6klzwuyq
125 dead.i2p 7ko27dxvicr2sezvykkrfiktlghx5y5onup3f2bas5ipocy6ibvq
126 deadgod.i2p 63bveyh7wefb44hlia7wtxxb3jal3r67thd6jekmwrtq4ulaaksa
127 debian-multimedia.i2p cylxxz2y35x6cvyrl57wu3brckurtexatyi2i5awz3eeamqwjspq
128 decadence.i2p pw5ys7k2grjb5myydpv6ohikm6nna7y6u2dro44i4rucgulu3ikq
129 deepwebradio.i2p 2nait2gdeozkgf6gyhzjfij6mwldwkxxwcvtxobb4b5q5cvtm5la
130 def2.i2p cepsrw27kdegwo7ihzouwvgcvw2obswwjs23ollgj7hk2yrce3da
131 def3.i2p xbf3ots2purqun7orn72ypkpjmrzbfrkj3u654zfe77hbrbow6la
132 def4.i2p yyzdq4fwwmnlojp23drfpfqujln2vcjozjrfzfeuriuqzdq7g4mq
133 deploy.i2p ujzspsqkbz5z272eozsrdv4ukl434h3fuliwrfxxnab74jmd7e6a
134 det.i2p y6d4fs3rpqrctuv77ltfajf5m4tl4kzcu7rtwhxgiohylfxxow4q
135 detonate.i2p nykapdsjjswdkjov7x3jzslhg4ig3cpkhmshxqzijuhbisx25jja
136 dev.i2p cfscxpnm3w3qxnlv3oikewxm4qrot4u6dwp52ec2iuo6m7xb5mna
137 di.i2p 3irnooyt5spqiem66upksabez4f3yyrvvjwkmwyzlbealg64mgxa
138 diasporg.i2p edvccoobtjukjgw2os5eetywanbb2mpag5aknkrpia5qx2koksua
139 diftracker.i2p m4mer767ipj7mq6l7gdrmrq37yzvsj3kzezd7n7nsfuctntjseka
140 dm.i2p heysbdivyeugdbggpscco5wje3dsvwgcpp5ot4sopooebnmiqvtq
141 docs.i2p ato242wckzs4eaawlr5matzxudt6t5enw73e4p6r3wajwkxsm3za
142 docs.i2p2.i2p las5l45ulwwf5i72nht6vk33sfkidcpr2okpf5b6mvgbk3a2ujna
143 downloads.legion.i2p xpmxdpuuptlekyhs7mmdwkvry7h2jbvpqpzsijqe3a5ctxgodesq
144 dox.i2p vk27cjdrtegfdnrjqutebgxkpyrfj42trdfbsupl5zn2kp34wb3a
145 dropbox.i2p omax2s5n4mzvymidpuxp2yqknf23asvu54uon6cxl6gdrlblnuiq
146 duck.i2p 3u2mqm3mvcyc27yliky3xnr4khpgfd4eeadhwwjneaqhj25a65ua
147 dumpteam.i2p 2fwlpuouwxlk2nj4xklvm43m52tqyhqnu2fcfiuv7clvf3wd5nwa
148 dust.i2p u6xgh6zhhhvdvefbqksfljfs3nyjvqcrmyamp5bryz5f4injmniq
149 dvdr-core.i2p fg6l2ej6qrk5rkyfzdptxx5xkcm4kvdla4gg2tun7z7fm5cxxw5q
150 dyad.i2p 7n2ljphvp2dep7imoujvydxp4myuxfld3axwfgcny5xc5x6jj6ka
151 e-reading.i2p z54dnry6rxtmzcg7e6y3qtsig5yf5fmehuvakcg5wnuahx3iafuq
152 easygpg2.i2p bwxry5alzx5ihgrd3glah4eotddblzhalvpheppnw4zcajzqoora
153 eboochka.i2p ou7g64d5in4sugv5fgmmzwnunuw5hloixio7puthmrvrkwrp6egq
154 ebooks.i2p bvpy6xf6ivyws6mshhqmdmr36pruh2hvoceznzeag52mpu647nzq
155 echelon.i2p afvtspvugtd32rsalxircjglh3fhcjzk7gxrm3gw4s2yrpvzk6wq
156 echo.baffled.i2p bfr3lyicr72psxvt2umqfb562rtex66w6q3hi3tktzkoyane2iha
157 eco.i2p 2dq2o5h6c6a674qaduipp55mid5iktumjbswuwmpsrcqaeowdvwa
158 eddysblog.i2p ieac3ub4g5sy3wuhsbqfembnpp7f3a37xgcx537ytzsmgfzexnbq
159 edge.i2p aknsl5wmzjmwyc4wxutfdwy2w5vgd3vcx52mqx647hcgvyurmqta
160 eepdot.i2p t6edyotbxmxvy56fofdvmragvsj65te2gkhvzv5qnblicutyvgoa
161 eepshare-project.i2p sn26kom4qyuzouppv4lwnk6bqabdydcegtrilybviibwiq2s4nfq
162 eepsites.i2p isskhl4ak3g7qevrarlmblddgr4ugnn3ckalwpjcvxafk5rjgypq
163 elf.i2p duz6ey27ohpcp3llylklzdb63lylolzcixad6bh7rt5tkq42qqpa
164 elgoog.i2p z6hrgkg2ajmuzlrddjlffrgctx7x7fkipm6c4hdzmohyn5wkr4ya
165 ems.i2p 734zw4jsegdf55zl3z6s22tqkbxcghu4qvk6q2wevjfmx7xhbn6q
166 epub-eepsite.i2p yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
167 es.hiddenanswers.i2p cw7ge5ey4ekp5iep2kaw6j54boebtqytpcbnvio2bfpccd5ejzfa
168 eschaton.i2p xe75f5hzmrq6rkhsef2geslmi2v2yfngdiysmlmxvh7b4pyyjk4q
169 esuwiki.i2p cwxuiwcpymb72vm5vluba66ofhugyf5qeevvwo7e2fqrxl243coa
170 evil.i2p ljfl7cujtmxfffcydq77pgkqfxhgbikbc6qxjgkvcpn4wzd73a4a
171 evilchat.i2p s5b7l3hzs3ea535vqc5qe2ufnutyxzd63ke5hdvnhz24ltp3pjla
172 evilgit.i2p mx5vyoqhg77yuhthwznsxrepjsemq4uwitx4lxdzetk36ryl5rla
173 exch.i2p vsyjsbbf2pyggtilpqwqnhgcc7mymjxblamarmxe5hmbxaxvcndq
174 exchange.gostcoin.i2p n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
175 exchanged.i2p ylmulgfskl6uiwac4hw4ecwqdzd3oxtwaemzj25zc6k5q4rkexra
176 exitpoint.i2p 5zmjurq3enudcenegnxu5hqmfmayz4lxvnik6ulch4xssa2ithta
177 exotrack.i2p blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva
178 explorer.gostcoin.i2p ktoacmumifddtqdw6ewns3szxths2hq2fat2o7xnwq4y3auga3za
179 fa.i2p 6n6p3aj6xqhevfojj36dixwbl4reopkhymxmatz7ai5sroh75rka
180 falafel.i2p djpn5cbcgmpumwcriuzqistbae66txca2j4apjd2xesfgb7r5zmq
181 false.i2p 77mpz4z6s4eenjexleclqb36uxvqjtztqikjfqa4sovojh6gwwha
182 false2.i2p j5i2tfumh3ti5sdtafwzzbpupmlcbg5drysfay2kxbdpsaljrosa
183 fantasy-worlds.i2p 62a4xcyyhvfrcq2bkckb7ia37fmrssrgx467tlkxp32fjpq577wq
184 fcp.entropy.i2p de6h6ti5z3mcbdcwucu45vplikqyoeddsu3rqy7s2zy5i47j3peq
185 fcp.i2p ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
186 fedo.i2p zoamh7e3k2vf2g6pfy46ho4taujk2f4mxqqsv3gbg554fxbvyfqq
187 feedspace.i2p kvtnpx4jylgeyojfhix4x462sqn5uork3roml4sfzotkxx62i4wa
188 ferret.i2p kkqie5qmja7bkf3iad4zxhrdarwj7kbrx2m3etn5kmba3shgwj4q
189 fido.r4sas.i2p i522xmu63hfbaw2k54cthffcoqmeao6urjyq3jg4hddf6wf57p3q
190 fifi4all.i2p v2stz6bsot7sbjzix5tky5dm5ej7gidmjnkvzqjju5xvz5sz6fwa
191 files.hypercubus.i2p qfglq25jwieszgyt7muz6dambzqsrmjhhszygzzx2ttubc77sffa
192 files.i2p w2sy74xe6oqnuz6sfh5fhkzu7boholgzd5f3anhj47srxwpj2vaa
193 files.nickster.i2p yil7dp2hg5pbqyovsiwb2ig6zjsq4tize3fnwemmqdrr6j5itdtq
194 fillament.i2p udj2kiino4cylstsj4edpz2jsls77e32jvffn2a4knjn4222s2oq
195 firerabbit.i2p awqh7n3wskzl3epyvkdwgarmfybsncm7vye6psg4tpkmplh3mj2q
196 flibs.i2p ocdm33e3h5tdml3yyholj4objdwsrhlugfqjnqgdkslmgdzb6b3a
197 flibusta.i2p zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq
198 flipkick.i2p aso5rzc4ym6g2bcbxjy2n573bmbenkjawva2jg7fhyqhwtwgu6lq
199 flock.i2p hflpi33ko5bi2655lx6bpzstdnjqgzrz23inovqjx5zpntyzyb3q
200 floureszination.i2p vitpvfb25sikuk3crgcvtcdi7hajxnnq2t6weay3no7ulur2wwwq
201 forum.fr.i2p onvelkowkbuwrglhw2cnocggvbdudi75sll5mfirde3cbopjqivq
202 forum.i2p 33pebl3dijgihcdxxuxm27m3m4rgldi5didiqmjqjtg4q6fla6ya
203 forum.rus.i2p zd37rfivydhkiyvau27qxwzmerlzbqtthsa5ohtcww62zrygjaga
204 forums.i2p tmlxlzag7lmkgwf6g2msygby3qttxvm6ixlfkq6s6cpgwubp33ya
205 fproxy.i2p keknios3gm6kh6onez6x2bm2t7stv54oanvltuagphgdfjdw5e2a
206 fproxy.tino.i2p fpaituvuvyxp6xdjnv3i27alnj2ifzcvqdweqb6yj5uybotzvyha
207 fproxy2.i2p r4lgw4wmza25g7j5fjocjbwzwthfg4ymcbm52ref3hh2hogskcza
208 fr.i2p ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
209 freeciv.nightblade.i2p rluupsgxbvw5t7jno3apyzlrdirjkljft4gdoy4mxxh4fmd4xzta
210 freedomarchives.i2p 4ck6oliqfjz3sccpya2q4rh5xkj5xdxkqs76ieml37537nfhwd2q
211 freedomforum.i2p abzmusjcm3p3llj4z7b5kkkexpsxcnsylikokouk5txfim3evqua
212 freefallheavens.i2p giqnkltyugfmsb4ot5ywpvf3ievuswfurk6bjie4hxi2hh2axajq
213 freenet.eco.i2p 2kf7ovb35ztqkrurkm76y34jfpwi6go25xj7peznnmxrl7aieo7a
214 freshcoffee.i2p sscuukigp6alcb3ylhkcugoejjfw5jqgtqbsbafw4hyku42lgc3q
215 frooze.i2p m6ofa5dmyse4b4jg7kfmluuuc4pw5jqu6zh4qnboin4vropxepja
216 frosk.i2p 63naq7zb3hvbcppj2ng7qwf6ztusp4kwpyrzbt4ptafcdbu4pfjq
217 frostmirror.i2p ycz3imuz6yte2zhlapmsm3bsvc46senvc2jxzwsbfdct5c72qulq
218 fs.i2p ah4r4vzunzfa67atljlbrdgtg3zak5esh7ablpm6xno6fhqij35q
219 fsoc.i2p vaqc4jm2trq7lx2kkglve7rkzxhhaptcwwl32uicx4ehf5k3hx6q
220 galen.i2p 4weo7zkxscxbcouiqx4mlnb35uwl2lromikzk33er3fljktyvi2q
221 gaming.i2p rfxberwod6st2zc6gblqswxjl57nucgc3xrbwss43pe3dvqqzj4q
222 garden.i2p qkk2dqx6nocycgt3vinsoc76cxkb4jreybcpgz3fcps2dbe4rowq
223 gaytorrents.i2p fnggbr2t2aulr6rvlo4aehotx6wecfob7u3k2nxsnvtm4xex424q
224 general.i2p 5fklrsztdqpl3hkkwwrrw2rdowrq7wwhwb6h7avvk4fhansp4vvq
225 gernika.i2p wpzqv3lxpecdsvcaadvbmrhhwlc7kp4n2mijdv2qjw3zr3ye232a
226 ginnegappen.i2p kbhfkzx5jeqhfgss4xixnf4cb3jpuo432l3hxc32feelcmnr3yja
227 git-ssh.crypthost.i2p llcp7jvz3hgtt3yzkdgjolwobisgvhv4xqa5a4oddejllyozur5a
228 git.crypthost.i2p 7frihhdcisdcyrzdbax6jzvx5gvtgwsm7m6kcem2tlaw4jtahbqa
229 git.psi.i2p em763732l4b7b7zhaolctpt6wewwr7zw3nsxfchr6qmceizzmgpa
230 git.repo.i2p vsd2vtgtuua2vwqsal2mpmxm2b2cpn3qzmqjoeumrrw2p4aot7uq
231 git.volatile.i2p gwqdodo2stgwgwusekxpkh3hbtph5jjc3kovmov2e2fbfdxg3woq
232 glog.i2p ciaqmqmd2wnws3hcpyboqymauyz4dbwmkb3gm2eckklgvdca4rgq
233 gloinsblog.i2p zqazjq6ttjtbf2psrtmmjthjeuxaubi742ujrk2eptcsaoam4k7a
234 go.i2p ll6q4lsirhwkln4dqxwqkh2xu4mu3jiy546b4uhe4fypyb4vvx2q
235 gonzo2000.i2p nogsv7okydhbvrewv6hb4xdojncvhkusnyib4lglluc4uw67a37a
236 google.i2p 4p3ajq4cotnflmuv7fhef3ptop5qpm3uzzgp5bahxif3nc4w3ffq
237 gostcoin.i2p 4gzcllfxktrqzv3uys5k4vgkzbth4gqednwhfpt755yivm3davuq
238 gott.i2p dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
239 greenflog.i2p zny5ftmhzxulxzyczmeat53qjnue2xtqv2clisc7dg76lwfceecq
240 gstbtc.i2p n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
241 gusion.i2p 4qyfdhizjixe2psu7wcvqufix5wlijocehpb2futurcmlhlktrta
242 guttersnipe.i2p kizkhzes2bzp45widihremo6geepfk7dl6juourkvzuvlc6y3spq
243 hack8.i2p un63fgjgi3auvi7zscznwqfol7ka4johgthvqf635mg3fefsjgpq
244 hagen.i2p e2t6rqd2ysbvs53t5nnaf7drllkgk6kfriq3lfuz6mip6xfg644q
245 heisenberg.i2p jz4quyw7zt63tmw65jfp76fblwadjss4iyi4puqdg3dye7oaqlvq
246 heligoland.i2p gzrjm62ektpqjfsem3r3kwvg6zpjvvhvpjvwfxkm2ay4zu7sp6oq
247 hidden.i2p iqodhhqo473qv5gwhjcs2bsrbhlqtpzgpnuumpastfiyhuwb2kyq
248 hiddenanswers.i2p kj2kbzt27naifij4ki6bklsa2qfewxnkzbkgvximr4ecm7y4ojdq
249 hiddenbooru.i2p zma5du344hy2ip5xcu6xmt4c7dgibnlv5jm4c2fre5nxv44sln3q
250 hiddenchan.i2p 6y4tltjdgqwfdcz6tqwc7dxhhuradop2vejatisu64nwjzh5tuwa
251 hiddengate.i2p rvblcu54jvkkfffp3fobhunsvpgfc6546crcgzielzwe2s5m5hbq
252 home.duck.i2p jsh7yfvm2t5urdcnmfzdy4n6vegqskdtlwem53chgxli4ipfmuma
253 hopekiller.i2p kcaelbgsvrkiwpx36b4wxofebrl3njx7rgm5amzfmqwbomt44cxa
254 hotline.i2p 6cczi27iuxkm3aivazaemzltdqgh42ljzurqp43uclbz2lid2uqq
255 hq.postman.i2p 27ivgyi2xhbwjyqmnx3ufjvc2slg6mv7767hxct74cfwzksjemaq
256 http.entropy.i2p ytu7kz5bdoc26nkpw2hajwt3q7n5rcbg2eokyefhmkxmmslimbdq
257 human.i2p nrtcelq3humyfvoxmzmngpka6tmyifweouku5mbi5av4lc43hzaa
258 i2host.i2p awdf3nnmxxup5q2i6dobhozgcbir7fxpccejwruqcde2ptld443q
259 i2jump.i2p 633kqgmwzzu6vhkevwvbf2pfyejt3gkes34i6upa4og57fgdfcxa
260 i2p-bt.postman.i2p jeudwnx7mekjcowpqo6xpkwn7263c57y5piurrjrdzinjziu4fla
261 i2p-epub-eepsite.i2p yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
262 i2p-javadocs.i2p icgmr6hhjudl4yxhtuq4pxvss2pzypwddzowajgs5rdz6f55novq
263 i2p-projekt.i2p udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna
264 i2pbote.i2p tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a
265 i2pbuggenie.i2p bioq5jbcnfopqwvk7qssaxcl7avzeta6mu72jmxjeowflpcrhf6q
266 i2pchan.i2p tduxyvfs7fzi26znvph3mu2d2ewaess7emomfci22wvownajphuq
267 i2pd.i2p 4bpcp4fmvyr46vb4kqjvtxlst6puz4r3dld24umooiy5mesxzspa
268 i2pdocs.str4d.i2p yfvbtrhjac3jutdsqzugog6mbz3jtyhpwovrt2mqc5mzv534y7cq
269 i2peek-a-boo.i2p qgv64klyy4tgk4ranaznet5sjgi7ccsrawtjx3j5tvekvvfl67aa
270 i2pforum.i2p tmipbl5d7ctnz3cib4yd2yivlrssrtpmuuzyqdpqkelzmnqllhda
271 i2pjump.i2p 2mwcgdjvfvd3xwumzqzqntual3l57h3zo7lwdmkjboeraudpkyka
272 i2plugins.i2p bb63kmnmbpitsdu45ez54kmogvvljn3yudksurcxiyq7dn5abt7a
273 i2pmetrics.i2p v65p4czypwxrn35zlrfkar2w77vr42acd7gbszegsrqq4u7sip5a
274 i2pnews.i2p tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq
275 i2podisy.i2p 3c2jzypzjpxuq2ncr3wn3swn5d4isxlulqgccb6oq5f6zylcrvcq
276 i2push.i2p mabdiml4busx53hjh4el5wlyn4go5mgji2dxsfyelagi4v5mzjxq
277 i2pwiki.i2p nrbnshsndzb6homcipymkkngngw4s6twediqottzqdfyvrvjw3pq
278 iamevil.i2p au7jhslyt4cxkjp365bvqvend3hhykrrhbohtjqlgoqrlijbezja
279 icu812.i2p bxgqwfsnr3bgnr6adn62anjcin5nuthqglotb3wn3dgynsfofeva
280 id3nt.i2p ufuqdzsxltiz224vq5gnuslt3a3t72dhy5kq6i2xway53m6pzv6q
281 identiguy.i2p 3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva
282 ilcosmista.i2p 6u2rfuq3cyeb7ytjzjxgbfa73ipzpzen5wx3tihyast2f2oeo24q
283 ilita.i2p isxls447iuumsb35pq5r3di6xrxr2igugvshqwhi5hj5gvhwvqba
284 illuminati.i2p syi6jakreatlm2z22u76izyqvbm4yi4yj7hr7jb63lgru5yhwwla
285 imhotep.i2p qegmmhy52bdes2wqot4kfyqyg7xnxm5jzbafdb42rfoafadj2q7a
286 in.i2p r5vbv2akbp6txy5amkftia757klgdy44s6cglqhmstpg65xycyjq
287 infosecurity.i2p v3gkh5kqzawn2l3uzhw6xnszsh6w3nztjmlwil7p4kyrwrsm2dba
288 infoserver.i2p jd3agbakybnhfvkeoxrx7t33iln6suzomv3kxkxf77j7rkonch6q
289 inproxy.tino.i2p ex5yf6eqqmjkrzxnkn6cgvefgne24qxsskqnpmarmajoit43pgma
290 inr.i2p joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq
291 instantexchange.i2p 5wiyndm44bysev22kxvczxt37p6o6qroiqykytrvn2yzi55aqfxq
292 investigaciones.i2p n7hqd4asxrdwf3zwo7rzv27y2qkcfmakmz6mjar6aw6hlc4c7mha
293 invisible-internet.i2p jnpykdpp46zenz4p64eb3opadl5g42dls3rurk2cvq6a3g3rvbvq
294 io.i2p tx22i6crnorzuti3x6va4mijsbhoqswy2cfdxjbvprgsq4eerg7q
295 irc.00.i2p bvcja52pppgfspp2ueuipoysjnvvoyblz2h6smpxcmanjquogirq
296 irc.arcturus.i2p 5nywlbn35p2nwsymwpfmicu6fxono6g64vwusxbsvmm2qwz6vupq
297 irc.baffled.i2p 5zmtoopscym6qagkvpgyn7jnkp6dwnfai745xevkxlou77c2fsjq
298 irc.carambar.i2p hxzbpivxqxy6nuae4t6fnkhcgnhs4c72vt6mmsqfmfhrkn2ca6gq
299 irc.cerapadus.i2p e4ckznxcxvgyikzjmjsu72i2dbj2d76ogexyukklbjvpcnhp6zzq
300 irc.dg.i2p fvp3pkcw4uvijqabwtekcdilklp73gyasuek67wdcs2mucep4caq
301 irc.duck.i2p chdpmm4gxffyn24xx5dhxvfd5httu42i5gtoe6cctjlsf4mbofeq
302 irc.echelon.i2p ez2czsvej5p3z5bquue5q3thujcodfze7ptybctqhnqc7hms5uzq
303 irc.freshcoffee.i2p ubiu2ehtfnrleemgpzsqkahwnvzuaifqa3u4wmaz5maaisd5ycfa
304 irc.i2p l3ohmm4ccxvyuxuajeaddiptci5lsrnxtvtyq7iohphrt3oj2evq
305 irc.ilita.i2p 5xeoyfvtddmo5k3kxzv7b3d5risil6333ntqrr3yvx3yubz5tk3a
306 irc.ircbnc.i2p 4rqcsqd7xif6r4v55blqvmqu5er6due4eyene3mjorfkts4o3rxa
307 irc.killyourtv.i2p wre4majmg2vnbi6id27et7yw6lnpf56wkbm6ftnlwpvxnktq73hq
308 irc.nickster.i2p dhq3fhd5scw3jqhj5ge7kqfpprfolcgxfjbaw24obohaiqjtdu7a
309 irc.orz.i2p 7gifacog4aoons3syybojbbnyqqaaqijhngrehn2xlq3eucuyjcq
310 irc.postman.i2p mpvr7qmek2yz2ekegp5rur573z7e77vp3xqt2lfbco5i6nkfppcq
311 irc.r4sas.i2p hodhusp73gltozgrnianlbploon3rrvhrzfn5mf2g46o7aaau5la
312 ircssl.cerapadus.i2p 4x2i745i4w52ss3he2kse6tzwt64pr62yvrcb72lgvrb63fup6ea
313 irongeeks.i2p ecduxoion5uc5hnvzjxff6iiwhdwph6gse3dknyvlo7e6gaeho7a
314 iscofsi.i2p enjgdxs4um2dmhdb2ajff2egrdijkjji3g47m6unb74swbrqsddq
315 isotoxin.i2p wue3ycaccf4texikza3fh6p5yrmtgnooisuypnepo5mo67lmpcqq
316 itemname.i2p o35ut7hgywy35okvgkjkv3ufzv2ejv4luap4oytwbyy2jqy6u4vq
317 ivorytower.i2p fpwrfvidfexsz7dspofkwtkmmizm7lyralfz5kvykffk7gubvxsq
318 j.i2p kjxvohlsf5sdrzxzfcrmvquccnoevi6ytbl63mstsru5wt2dx3ea
319 jabber-2.i2p pvnmzgemetkwcuvt45omgowmeznwk5xw3nc3ygeoz7yekqxy57na
320 jabber.duck.i2p rhdzvvzraqzzm67zpyegb7knpfrjeffitixqzeyymdoz56uh2rtq
321 jake.i2p v2axvy6pqefnla7gun5fmqs4lqe4xfyqovgzcundhxrpcdvfd7cq
322 jar.i2p 2fthkmujup3xiiu3yple24n6g4emzdiiimbuqwvpdddtsr3c4nrq
323 jazzy.i2p ha5c3zafwkt6mwqwjcf4oqwvbwz473652ljjadiwrj4gfkfkjofa
324 jdot.i2p kw4jr5qw4bhnj33avkwankjdh3zi7wtahlmgkjwvsv2isskkzgpq
325 jhor.i2p c6rnm7oemydhuwzmhwwwxphkzanez5rnn7fkcs3lpgu6gkgtssoa
326 jikx.i2p aazr55itvyns4lwppvx5njyx5tjdwemw4w6jbmpegdunznod2ieq
327 jisko.i2p jxgfvr663uhr6m65hrgkscshysfshkq32ywdubc4ed7zda3e2pca
328 jmg.i2p oglpnq7zungdukmk6gk5fzj5jp6wibuoihqgks453wztrwos4ggq
329 jnymo.i2p nbfplxgykyfutyadlfko2rmizdsxox2pee2ahboj5mju4s3putda
330 jrandom.dev.i2p htynimemonyzqmn76gworxyfkmqtsa7zcprbrd3i5cxqqm75tuzq
331 jrandom.i2p dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
332 jrrecology.i2p qxi24gpbum3w3kesuxvheyu3p5u5o6tuvoypaolub2gnvbld57xq
333 jwebcache.i2p xdffxnxtjd6ji2zig3cgva7igvl2tiapyjoc7ylbzwqhxudbmvfa
334 k1773r.i2p zam7u6vslhemddz347uusuzjdk5wma4h5hcmcqlng4ybbpdbjhnq
335 kaji.i2p z5ic7gvm2k4doczphtrnrspl2w5sfbss2de4z3ihjijhtjw67ydq
336 kaji2.i2p 4lscgc6napekfx7ay5fdcjofeja4fnl7tqcd3fek63t4saavur2a
337 keys.echelon.i2p mwfpkdmjur5ytq4og36ym3ychinv36b2a57f4rmgqmtrwepq3fva
338 keys.i2p 6qv4x7ltaxckd4vbay5s4ntqqflq4efk6oke2d5yzicqrmk443ba
339 keyserver.sigterm.i2p isoxvnflrdn7cm76yjlfg5tbcugoito2hur7eidbqmo33xmwz5ga
340 killyourtv.i2p aululz24ugumppq56jsaw3d7mkbmcgo7dl2lgeanvpniyk2cbrda
341 knijka.i2p knjkodsakcxihwk5w5new76hibywia5zqcgoqgjttzsausnd22oa
342 knotwork.i2p 2yocdbcjiyfaqgxb4l6oenrrrrie6nydgmbnbfulqg7cik6bozxq
343 kohaar.i2p qchpjehbhqjbxdo7w3m55jbkrtsneb7oqoxcr24qttiq6j5g3z5q
344 krabs.i2p 3yamyk5bgfgovg6zpvtvpdjk37ivjj2wog2w7wha5agzgxxkqaca
345 kuroneko.i2p wbit2huhhwlyqp2j4undccuyrodh6qcmzdeyuaoy5o4ym7g5gdgq
346 kycklingar.i2p gctswdhp4447yibxfbqg3uq2bvx63qjeqnaoaux75zw73leakyva
347 lazyguy.i2p ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
348 legion.i2p 5oirascyhwfy2tr2horw6mixozsre7z6s7jfq7qbnj523q3bkebq
349 legwork.i2p cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a
350 lenta.i2p nevfjzoo3eeef3lbj2nqsuwj5qh3veiztiw6gzeu2eokcowns3ra
351 libertor.i2p 7gajvk4dnnob6wlkoo2zcws7nor3gunvoi7ofalcps5lc76wruuq
352 library.i2p brqqaq44vbeagesj5o3sxcnkc5yivkwouafyxa77ciu7l644ei2a
353 lifebox.i2p pyqjnycm55cuxow22voqj62qysrjdnb6nbyladaiaiirqi7vp2yq
354 linuxagent.i2p ap5riaikrjq2uv5qvy7klzhhqywvqi7wqscyipsewcun7w2eynlq
355 lists.i2p2.i2p vmfwbic2brek2ez223j6fc6bl5mmouzqvbsch45msvyyzih3iqua
356 lm.i2p yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q
357 lodikon.i2p u3f67staiwhqxpacya3clmvurdwd2kp7qcthzhstqnhrmlwc2g4a
358 lolicatgirls.i2p a4lzmjyba7aq7hl6okqpds7znnwymolqnr7xhvno2wraqb7uhfla
359 lolifox.i2p 7fd2clkiotjnaoeigdtxlkkb24eik675ovezjf67x26ysham4zca
360 longhorn.i2p pohcihzxzttjclrazhs3p76wt3ih737egb5bovqb6ym3du6z3o7a
361 lp.i2p jiklbujn3cbfikf4pca526jgmorx6mxhil3twqmfoteaplx6ddwq
362 lucky.i2p wx36m3wnpt2y6bngdpg3ifrarvtkpwnluarx377bllpgvkuhybaa
363 luckypunk.i2p y4t6cujjxnnrtln3rgmfbgbh46hic7wkef57krd7opitbgngohka
364 lunokhod.i2p 3yc6sp7xic4grmpfecbwuij6z3dp5kdgoo362pszaco7io42mnwa
365 m16.i2p ucsr3eveuc4mx5y6gxnoaywd4ojvbel5q3ynns6s5yfw3vusmfva
366 mac7.i2p 3yjowssqzydciwa5zx55kazgf7q7w6g7rkocr7bngy35ii44t34q
367 madman2003.i2p a2sam2xbhxbzmeyobphbxrkdwlppoerewq5qvibbyk3ftsr643qq
368 magix.i2p cgfnyxv62msfynsfbv3kju22j2mt6tfnopshhmrcmpcrxyts6xwq
369 magnets.i2p snz46nez6hrrpg6336neinflw56l3vwatk6bzzytwu77xmsfsoca
370 manas.i2p 6qolj62ikkoq6wdn3hbvcbdmlvf2rcyv432kgi5uy7mvrczmjtba
371 manveru.i2p pbmbofs76wpjnxi55eqtwg4y6ltyij72o4fm4sxfjol3y57ze5sq
372 marcos.i2p vpo36bsil2voqaou53zshuegssqaroa5mbrzxfmhjywlbojckalq
373 marshmallow.i2p svdqd6j3y3gwryufcl4fkzpmcujgvrvphvk2oy4r7m75xs327e2q
374 marxists.i2p lepah55qyp2fhuwxlz7bwrhzckn4gkuofivnofoeuyfpmke5x2hq
375 mattermost.i2p x5oovnhnuli5fnwtgkbd5z5jvrvdvprqyuofywx6uoxkk4bie6ya
376 me.i2p dbpegthe42sx2yendpesxgispuohjixm4bds7ts5gjxzni5nu6na
377 meeh.i2p 4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa
378 mesh.firerabbit.i2p 3x5wokr4bjy5z3ynji4fyhvwzv4fvgry3xafi5df5h75doezjytq
379 messageinabottle.i2p avfhe3kvrrv7utxn2vre65lg7damxzzsewq3vukwie4llitd254a
380 metrics.i2p z45ieamhex2ihqv7oowk5fz4qq47rbvxhhhbaaiinpajbhuevtpq
381 mhatta.i2p o4rsxdeepfrnncsnjq675xogp5v5qkbfgbt6ooqeyfvlifobrjxq
382 microbleu.i2p mtapervgibruizniems2yyr47pin2wpysyh7m632rigl26vjc6qa
383 microsoft.i2p hvaqr5idszdyrjph34amb4mjosqd3ynggoxlnj7ciqhnx7q6plza
384 mindisl0st.i2p u7rnqhvsuyxd3fabm4kyzn7brgz3i3cporj2emk2jmbpcmltyf7a
385 mindspore.i2p uuh5dd3y2rqa7x2jpggm4p2pg6znarm5uanwsvybe4tk36ymwr4q
386 modulus.i2p ctz3o6hdefrzwt3hlg6rjhdcbjk6irppbndq32u6jnn4lz72f62a
387 monerotools.i2p 5bal7dngxde2ddmhuzbtfken6w5nmxmixtjlrlmxt3wbhnemv73q
388 monerujo.i2p puri6y5dtwh6zr4u77ep6ozatun6iz7v4wai2dzxppz7654corlq
389 morph.i2p iovyp2dao5rta6g5v6hke2s4ugx2btkpcljddak2yhxfrx3l4dqa
390 mosbot.i2p 5bhmrp43mjwlzf4x64xgdrkwmw4luvng6eq5waa663a7vnkp732a
391 mosfet.i2p s5ynkgagndmpxpf2kmnenv4x72io664gzd2x3qef54ilammnte3q
392 moxonom.i2p gcjdrvnlobgexh7ebv276pwmnoj3yoyaqm3w4vmmdha4lgxfinqq
393 mp3.aum.i2p n7bmu5dwux7f6gedmdik6zrm77bnls4lkzo2vo3bf4bwegk7vkjq
394 mp3.tc.i2p w3ied5s7ldjcvnhxu2gyofe3oogzbplkyxshzfkhspiy2526snsa
395 mpaa.i2p m6cqnglo7xlytwxkdsmwf3d23d6lq5r446c3tktb2tdmuah36zya
396 mrbamboo.i2p tmpmkx6wlbbrgsnexrqlrib7laoegpbfeop7bnyezegii7hecpxa
397 mrflibble.i2p u7k2qcmkrril6yvudvwxjqz7k3dzgp3jdejjjeapej7liselj3eq
398 mrplod.i2p fjn5hxtybxyfyvdf6u5v5seg2sjd47hb5by6sa6ais4w3xnrxwyq
399 mtn.i2p xisk3h6sku3iqj52uriogaajmnku7pwjux7wa4omx2zloamuw6eq
400 mtn.i2p-projekt.i2p f52x5fp6uhq53f5zle5d6rq5un34xgmxgazvilvmzcby37xcmsfa
401 mtn.i2p2.i2p l6kuhtmgvbp57d7jwalj5nksi6nr4gfzbz4oit62lxgipb3llt5a
402 mtn.meeh.i2p h7ylrsuzzynrxp3jql7anoozyqblavj7eqces6o3wngvuuxhs2la
403 mudgaard.i2p yz32lk42gtoesknesfolq3tt4erxxcejcote5pontaeqev3bj2kq
404 mush.zeit.i2p dk3sg23kljawxqp3cb6xz5mnzjlyckzvq5jhqs5gnvdsv7wqn6ha
405 music.i2p akamh76yi6p7xxbvl3qv3yhaockne57yfuh77acogbgpjmwypvia
406 mysterious.i2p p66g2a4nzfkvidd3l7nwphcnfa3ttyu5kiolcb4czec2rn2kvwsq
407 mywastedlife.i2p ceumy3puvvsrru5bmfmtgsajsx5qyehqac7l7a23xpwtfs2bvcgq
408 nacl.i2p bm2fib3tumer72lopjh4nmqomwvqu2sdfyb2hmr6lnk7jbw3vvia
409 nano.i2p ex5ssv7s3hj6jp7hvadxfw3wvbjbvnczxr4pbk7qw26ihiorjmba
410 nassai.i2p v653cocvn3i6bgjdm3ciwbdnu32supglv6gn4fh23bohemsp545q
411 neodome.i2p 5hkhjehj3ct2pvcah7dcylwef2oti3xij5myxbv3pd7rocio5vkq
412 news-i2pn.i2p wwcqkwfo5yhe6uribv5tzylk25j5hkdk6gdnyftzd3k7dawlzwca
413 news.neodome.i2p trhwcnygfkeqjj6g4xhmrdp4gsjqsye47lsxshbmwbten4ywt5oq
414 news.underscore.i2p rl7t3kspoktuatjcu7gf7xleu7y6biibs4fspzo24kll6n7hbq4q
415 newsbyte.i2p gsk3rgsejxxrfabjxu5w5plplxsu47aoeoke22vvhlwwllzosnxq
416 nibble.i2p jmdxcpdzqafedn3clc4y7u6o56qocfiffrzbzncmtggqtio5qjpa
417 nic.i2p vzu5ymab6klevpcdudv4ypisjqaznmt44e6lcg7dwiuza4saibxq
418 nickster.i2p zkwsa6kvq2wdhovw5g5wqakpb7rlaylyhfriwmurots5pvwbqauq
419 nickster2.i2p eofzi7npzpk4p5gb4qper4hmwgxo6kepo3dheeblakewedxj2bwq
420 nickyb.i2p gmpxk4tje7mnud32kg2kjmf36f6cpwqakzc2dxuzjnnz4qr5w4sa
421 nightblade.i2p p4gkon7ytswxrbwkl7vruw6mg7kfw5aofovqjgt4c7tnqmbq6lha
422 ninja.i2p q6dg6hlb3egzdqz352ri5rc4fx4gcrdeu3tpiyfxlv73yfjgrhya
423 nm.i2p 3itdpqzyn3ii7sivppo4sxxwhvgtpskzkbokrdibim6gqpvlw5ya
424 nntp.baffled.i2p kc6muo2tih5mttbpzecteegvtonuysjidk3emcy4cm4yifzild2a
425 nntp.duck.i2p gvzzor4utsqxswvf6jaglfks7yxudlz2s326ftrk56i4lpd2s47q
426 nntp.fr.i2p npoztnqadfnu4vrokoh6rusoi3yne47s6jurc3lzhcrzzia5eqva
427 nntp.i2p wwdzmeyler4djegvyt2bxmkwrckfgg3epkkwowyb75s47he6df6q
428 no.i2p lpsg4x4gdrf7antxcdy47cl6abcqei5ommgzt55retq7go5ku3ba
429 noname56.i2p oiyoslismzyxuw7ehxoigmtkdj35idim6flmlplddxuiiif6msfa
430 nop.i2p ssag45lathm4gqp46si7c4w4tioyvjpcza5uvz5x2zuljnplylca
431 normal.i2p j5fex634r2altzb3kjvu35qekt2r3hgsqzg5qxoy7dp53heu5pma
432 normanabcd.i2p si2vh43gvxjnw2shwr24j76xyanow4oa6gbu4idookbraoxl3s3a
433 nothingburger.i2p tesfpn757ysc7nih7mxher2b3jstkc3l5fhfcyb5kxhzhvv52trq
434 nothingspecial.i2p wzrwqrp52bilqijrlboclynuev4kzpjzfzlvzl5aqxqt5fdnpbga
435 novospice.i2p ukqap24nwac4gns77s4zy7j5cagt7l7syb5zo7eukfg3zn5gg5qq
436 nsa.i2p nsetvbclpomqxfcit4mghn6z7vdhnza6jdzczby4crnto32uykga
437 nvspc.i2p anlncoi2fzbsadbujidqmtji7hshfw3nrkqvbgdleepbxx3d5xra
438 nxt-wallet.i2p 33pp74k4ivy67z332qpyl3qlcqmi6gxqumrow4bldkblxxlxqq5a
439 obmen.i2p vodkv54jaetjw7q2t2iethc4cbi4gjdrmw2ovfmr43mcybt7ekxa
440 obscuratus.i2p i4j37hcmfssokfb6w3npup77v6v4awdxzxa65ranu34urjs4cota
441 ogg.aum.i2p wchgsx6d6p3czloeqvna2db5jr7odw4v4kqrn4gr4qiipfyrbh5q
442 ogg.baffled.i2p tfbvj2xal6lcuxv3hzuw7cw4g3whguombcv2zuotzvul4qtrimgq
443 ol.i2p bnb46culzbssz6aipcjkuytanflz6dtndyhmlaxn3pfiv6zqrohq
444 onboard.i2p qwlgxrmv62mhdu6bgkh4ufnxowxsatfb6tbs2zr666qyunwqnecq
445 onelon.i2p irkvgdnlc6tidoqomre4qr7q4w4qcjfyvbovatgyolk6d4uvcyha
446 onhere.i2p vwjowg5exhxxsmt4uhjeumuecf5tvticndq2qilfnhzrdumcnuva
447 oniichan.i2p nnkikjorplul4dlytwfovkne66lwo7ln26xzuq33isvixw3wu3yq
448 onionforum.i2p yadam2bp6hccgy7uvcigf5cabknovj5hrplcqxnufcu4ey33pu5q
449 ooo.i2p iqp5wt326fyai5jajsa3vkkk5uk56ofn4anocgpe5iwlpisq6l7a
450 opal.i2p li5kue3hfaqhhvaoxiw2ollhhkw765myhwcijgock5rs4erdqdaa
451 open4you.i2p ice6ax5qrzwfwzsy64bctffj6zlzpuzdr5np65zsxlbt7hztyc6a
452 opendiftracker.i2p bikpeyxci4zuyy36eau5ycw665dplun4yxamn7vmsastejdqtfoq
453 openforums.i2p lho7cvuuzddql24utu7x6mzfsdmxqq7virxp5bcqsxzry2vmwj5q
454 opentracker.dg2.i2p w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa
455 orion.i2p 5vntdqqckjex274sma3uqckwqep2czxs5zew25zlntwoofxk3sga
456 orz.i2p oxomqkekybmyk6befjlouesit5mhstonzvzd2xnvsk7i6uyrqsfq
457 os3.i2p s7x4ww5osrrfein3xgwyq67wnk6lgliw4mzt7shtu66wrb2zdojq
458 osiristomb.i2p t3slf77axkv3qm7c3gzpv3jgmkraoqqe2bojr6h66eipibofsyzq
459 ot.knotwork.i2p cxhvvfkbp2qbv5qojph7zb46molpe2ffanghnerjag3xdmy6ltxq
460 outproxy-tor.meeh.i2p 77igjr2pbg73ox5ngqy5ohzvrnur3ezqcogtl4vpuqtrcl3irsqq
461 outproxy.h2ik.i2p nwgvfpfarpnyjjl4pwsxr2zdsppcx5we3kos2vlwicbiukopgaza
462 outproxyng.h2ik.i2p v32zse2zczzgegelwxbx7n5i2lm2xhh2avltg76h6fz5tb53sfxq
463 overchan.oniichan.i2p g7c54d4b7yva4ktpbaabqeu2yx6axalh4gevb44afpbwm23xuuya
464 p4bl0.i2p lkgdfm4w6e2kkjhcdzr4ahhz26s3aunhrn6t2or436o73qh4z7ga
465 pants.i2p xez3clscjfafkqwk6f473ccp3yvac4kh6rdp6dptwxa2lhixizgq
466 papel.i2p mxskjqntn2d34q4ovsnd5mud7cgde734tdjldd3lt4hczh2645zq
467 pasta-nojs.i2p dkkl3ab6iovxfqnp44wsjgqaabznvu7u3hugpzyagbeqlxgvx3la
468 paste.crypthost.i2p 2zaj4u4s4l3lgas2h5p6c6pvzr2dckylkrh5ngabursj4oh25ozq
469 paste.i2p2.i2p b2gizskfea4sjxlw6ru2tb6kdrj47dsjc77cijsf5mzh4ogbmfvq
470 paste.r4sas.i2p csen43keji3qiw6uobsgzysxyjd225g6446ylq5uuz6ur2glkzaa
471 pastebin.i2p mnicncxrg2qqi55qftigiitaheugnj4rpysbk7zabdrirgktelqa
472 pastethis.i2p erkqiwnjl7vtysqd3wvddv6tfvnhswarqkbn4blhdlhfxn7cf2ha
473 pdforge.i2p wzeg3ehf6d2mqjqji3sd3rns776thvhe2vam2r6gjlmsqis2dctq
474 perv.i2p f3k3wm4ae7t7ottfjd4hu6is7zsls73izl2gm2qynzficxcdsiwq
475 pgp.duck.i2p wujajyxj3cgsfsbtr3g7g7npv5ft3de6pcstxlav26zq6cxdjmha
476 pharos.i2p vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
477 pharoz.i2p vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
478 phonebooth.i2p noxia7rv6uvamoy2fkcgyj4ssjpdt4io6lzgx6jl6wujpufxedrq
479 photo.i2p fqhuy77ugd5htnubzkyy5guvwboqn6goahtmn2g7feewvdj7k3iq
480 piespy.i2p vzusfjzcu5ntnvobcvyzc4dcu4j6ommtnpmba2puk3kexgdzrl7a
481 pisekot.i2p 7yzdwhy723fodqz4onp6k3nyvixra2sa6dl45tcblhmyoa7i36nq
482 pizdabol.i2p 5vik2232yfwyltuwzq7ht2yocla46q76ioacin2bfofgy63hz6wa
483 planet.i2p y45f23mb2apgywmftrjmfg35oynzfwjed7rxs2mh76pbdeh4fatq
484 plugins.i2p wwgtflbaa7od2fxbw4u7q7uugmdclxf56alddvizugwcz5edjgia
485 polecat.i2p het5jrdn35nhkanxmom5mjyggyvmn2wdj2agyqlrv4mhzhtmavwq
486 politguy.i2p 6dkkh3wnlwlr6k7wnlp4dbtf7pebjrph5afra2vqgfjnbihdglkq
487 pomoyka.i2p omt56v4jxa4hurbwk44vqbbcwn3eavuynyc24c25cy7grucjh24q
488 pool.gostcoin.i2p m4f4k3eeaj7otbc254ccj7d5hivguqgnohwelkibr4ddk43qhywa
489 pop.mail.i2p bup6pmac7adgzkb5r6eknk2juczkxigolkwqkbmenawkes5s5qfq
490 pop.postman.i2p ipkiowj7x4yjj7jc35yay3c6gauynkkl64gzzyxra3wmyhtfxlya
491 pravtor.i2p 2sr27o5x2v2pyqro7wl5nl6krrsbizwrzsky5y7pkohwh24gn6xq
492 pris.i2p ahiwycgzuutdxvfqu3wseqffdnhy675nes57s4it2uysy5pxmz6a
493 project-future.i2p ivqynpfwxzl746gxf376lxqvgktql2lqshzwnwjk2twut6xq7xta
494 projectmayhem2012-086.i2p ehkjj4ptsagxlo27wpv4a5dk4zxqf4kg4p6fh35xrlz4y6mhe4eq
495 protokol.i2p f4xre35ehc5l6ianjvt3zcktxkjlyp2iwdje65qnu2j6vurhy6nq
496 proxynet.i2p 7gar5a3n4hzvsgi73iizo65mjza4kujf7feopfxuwu5p6wtwog5a
497 psi.i2p avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a
498 psy.i2p s3elzoj3wo6v6wqu5ehd56vevpz2vrhhjc5m6mxoazicrl43y62q
499 psyco.i2p eoilbrgyaiikxzdtmk2zeoalteupjrvcu3ui23p4wvfqo25bb73q
500 pt.hiddenanswers.i2p o5jlxbbnx3byzgmihqye3kysop5jgl3unsrkmurbtr2nrnl2y74a
501 ptm.i2p 7dna5745ynxgogpjermnq26hwrqyjdlsibpjfmjxlwig247bjisa
502 ptt.i2p q7r32j7lc3xgrcw2ym33wv4lfgqbez7vtm4lts7n34qfe3iygeha
503 pull.git.repo.i2p 3so7htzxzz6h46qvjm3fbd735zl3lrblerlj2xxybhobublcv67q
504 push.git.repo.i2p jef4g5vxnqybm4zpouum3lzbl6ti6456q57nbyj5kfyldkempm3a
505 pycache.awup.i2p w45lkxdnqhil4sgzanmxce62sv3q4szeowcjb2e72a5y5vbhm4ra
506 r4sas.i2p 2gafixvoztrndawkmhfxamci5lgd3urwnilxqmlo6ittu552cndq
507 radio.r4sas.i2p cv72xsje5ihg6e24atitmhyk2cbml6eggi6b6fjfh2vgw62gdpla
508 ragnarok.i2p jpzw6kbuzz3ll2mfi3emcaan4gidyt7ysdhu62r5k5xawrva7kca
509 ransack.i2p mqamk4cfykdvhw5kjez2gnvse56gmnqxn7vkvvbuor4k4j2lbbnq
510 rasputin-sucks.i2p fdozdbyak4rul4jwpqfisbkcx4xbrkuvf2o5r6fd3xryyrjgvjiq
511 rebel.i2p nch2arl45crkyk6bklyk2hrdwjf5nztyxdtoshy6llhwqgxho5jq
512 red.i2p fzbdltgsg7jrpz7gmjfvhpcdnw5yrglwspnxqp4zoym3bglntzfa
513 redpanda.i2p 3wcnp6afz4cikqzdu2ktb5wfz7hb3ejdbpn7ocpy7fmeqyzbaiea
514 redzara.i2p ty7bt62rw5ryvk44dd3v5sua6c7wnbpxxqb6v4dohajmwmezi7va
515 reefer.i2p 4cde25mrrnt5n4nvp5tl62gej33nekfvq2viubmx4xdakhm5pfaa
516 relatelist.i2p utrer5zgnou72hs4eztmk37pmzdtfw3d6s23wwl7nk3lkqpzbdiq
517 repo.i2p uxe3lqueuuyklel23sf5h25zwgqgjwsofrqchhnptd5y6pedzbxa
518 repo.r4sas.i2p ymzx5zgt6qzdg6nhxnecdgbqjd34ery6mpqolnbyo5kcwxadnodq
519 reseed.i2p j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq
520 retrobbs-nntp.i2p fkyzl24oxcxvjzkx74t3533x7qjketzmvzk6bwn3d6hj5t7hlw6q
521 retrobbs.i2p mnn77stihntxdoade3ca2vcf456w6vhhvdsfepdvq5qggikvprxq
522 retrobbs2.i2p ejff7jtyaus37slkwgeqrrcmyhpj26carp7n27f5h6s5vlbeiy6q
523 revo-ua.i2p hpojpumki22xjwhmhe6zkiy44oanyn7u4ctcfe3in2ibwm5l32hq
524 riaa.i2p lfbezn7amkzhswnx7lb4lxihyggl2kuqo5c7vwkcv6bwqmr4cuoa
525 rideronthestorm.i2p xrdc2qc7quhumhglpbcuiqxr42nuffv4xj4a73jbr4ygepitibqq
526 romster.i2p eaf2stdqdbepylt53egvixdi34g2usvgi7a4oixsja6atkran43a
527 rootd.i2p mzbe5wofwn7eaqq4yefrmxizqaxoslwqxrv5qcv2opx5lnhg64dq
528 rospravosudie.i2p z55khrnlj6bzhs5zielutm6ae6t2bbhfuiujwlrp3teubqyc4w7q
529 rotten.i2p j4bm3rvezlejnb44elniagi5v2gazh7jaqrzhbod2pbxmgeb2frq
530 rpi.i2p 56p5qxsrvo5ereibevetw2qbj5bronmos7wxunku27g2s4kpbnlq
531 rslight.i2p bitag46q3465nylvzuikfwjcj7ewi4gjkjtvuxhn73f6vsxffyiq
532 rsync.thetower.i2p w4brpcdod7wnfqhwqrxyt4sbf2acouqfk5wyosfpq4mxq4s35kqa
533 ru.hiddenanswers.i2p o6rmndvggfwnuvxwyq54y667fmmurgveerlzufyrhub6w3vkagva
534 ru.i2p m7fqktjgtmsb3x7bvfrdx4tf7htnhytnz5qi2ujjcnph33u3hnja
535 rufurus.i2p 7msryymfdta3ssyz34qur6gi4jyfkvca5iyfmnceviipwu7g2wca
536 rus.i2p gh6655arkncnbrzq5tmq4xpn36734d4tdza6flbw5xppye2dt6ga
537 ruslibgen.i2p kk566cv37hivbjafiij5ryoui2ebxnm7b25gb3troniixopaj6nq
538 rutor.i2p tro5tvvtd2qg34naxhvqp4236it36jjaipbda5vnjmggp55navdq
539 salt.i2p 6aflphlze6btsbez5cm4x53ydrmwhqrkxsud535d3qjh4wq62rxq
540 sasquotch.i2p p6535uyfk2y6etc3t47vd3oqxydznqior5jxcvq5bdxe5kw5th6q
541 schwarzwald.i2p 4gokilzy73mmudufy3pohgatm42fcstx7uzg5hjvnfyphxpnphuq
542 sciencebooks.i2p ypftjpgck75swz3bnsu4nw7rmrlr2vqsn4mwivwt3zcc3rxln5cq
543 scp.duck.i2p ghbpsolpnveizxu4wbs7jbs2vj3kntnsexfcdleyhpqdhfpxleda
544 search.i2p nz4qj6xaw5fda3rsmsax6yjthqy4c7uak2j3dzcehtkgyso4q46q
545 secretchat.i2p cl3j2zxhpw6u6jevny45i557ojhwfxn4g375nnuqhy6lp27mry2q
546 secure.thetinhat.i2p 4q3qyzgz3ub5npbmt3vqqege5lg4zy62rhbgage4lpvnujwfpala
547 seeker.i2p ipll7sit24oyhnwawpvokz5u7dabq6klveuqpx3sbi6o5qemy2bq
548 seomon.i2p 5mvpsy4h45w4fx7upen7ay3vkrs5klphz5nptmtcqvc3fsajsm4q
549 septu.i2p 5lqvih7yzbqacfi63hwnmih57dxopu5g2o5o4e2aorq7bt4ooyra
550 serien.i2p 3z5k3anbbk32thinvwcy4g5al7dmb75fagcm3zgh4rzrt3maphda
551 ses.i2p 5qfoz6qfgbo7z5sdi26naxstpi2xiltamkcdbhmj6y6q2bo4inja
552 shiftfox.i2p wpvnuzslu7hjy4gujvnphtyckchdoxccrlhbyomsmjizykczyseq
553 shoieq3.i2p 3fjk4nfk3mccch4hdreghnyijcvovsi3yucjz3qzj5sxngqk5j6q
554 shoronil.i2p 7shqzgmb6tabiwrnwlasruq7pswy2d3emvfhaitehkqgod7i62sa
555 short.i2p z5mt5rvnanlex6r3x3jnjhzzfqpv36r4ylesynigytegjmebauba
556 sion.i2p lcbmmw2tvplvqh2dq5lmpxl3vnd5o4j3bdul5moa23deakjrso5q
557 sirup.i2p aohdp4yajnkitrtw7v2mo3sp7swuqhjfwlsi5xwd7dudzftumsma
558 site.games.i2p zeuczucfxeev3k7tvqlfcdpfbnqggheiknyyb5r2q4utn3d2auja
559 skank.i2p qiii4iqrj3fwv4ucaji2oykcvsob75jviycv3ghw7dhzxg2kq53q
560 slack.i2p gfcsh2yrb2tx7hyvmobriv52skz7qoobn7n7y7n6xaehhh4rpbja
561 slacker.i2p wq7m2wdguzweleb666ygv3bmfhha63zj74rub76vfesbyhsyk6iq
562 smeghead.i2p ojf4czveeuekxqkjvkszvv7eiop5dg7x2p6rgfzl4ng4xrjk6lja
563 smtp.mail.i2p kdn7zx7fgoe4bn5abaaj5cb3e4ql22fklb5veui5yajpj4cxapya
564 smtp.postman.i2p jj7pt6chsziz6oxxnzpqj7mzhxm2xfhcrbh7dl3tegifb577vx5q
565 socks1.tor.i2p sifawcdexgdmoc3krv46pvvz74nzd6fkju2vzykjxsx3egqsb6wq
566 sonax.i2p jmuxdhlok5ggojehesfjlit2e2q3fhzwwfxjndts7vzdshucbjjq
567 sponge.i2p o5hu7phy7udffuhts6w5wn5mw3sepwe3hyvw6kthti33wa2xn5tq
568 squid.i2p r4ll5zkbokgxlttqc2lrojvvey5yar4xr5prnndvnmggnqzjaeoq
569 squid2.i2p hum4wlwizbsckbudcklflei66qxhpxsdkyo4l2rn256smmjleila
570 sqz.i2p 3jvbwc7sy4lnhj25nj7yepx7omli4ulqirnawv3mz6qlhgokjgzq
571 ssh.i2p xpvdadaouc4qr75pteymyozc7mcsynjfkuqqkkla542lpcsqionq
572 stasher.i2p 6ilgpudnba4kroleunc2weh5txgoxys5yucij5gla6pjyki4oewa
573 stats.i2p 7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq
574 status.str4d.i2p ycyyjo3psqbo45nuz243xvgvwnmzlanzqbzxv3kh6gyjztv7425q
575 sto-man.i2p rg4eilfpe24ws6nctix63qw2dlvd2tqgwdcgdxzji6l5bc4dc7aa
576 str4d.i2p wrrwzdgsppwl2g2bdohhajz3dh45ui6u3y7yuop5ivvfzxtwnipa
577 stream.i2p prmbv3xm63ksoetnhbzqg4nzu2lhqdnqytgsydb7u3quxfrg7rna
578 streams.darkrealm.i2p ud3gcmvysjch4lbjr2khmhqpf7r2x5if4q43xkqdptl4k7lc4muq
579 striker.i2p 4gswsrfpbd44hwjoj33jbqfbwzxfkwpuplb3ydq5zm7nfu2pxvdq
580 subrosa.i2p g3lnglrnoual7wyabnwwv37uwhadgbxiqz36pf3f5cwfuxsx4mxq
581 subterra.i2p vdmhe4u26unzgd7ysq6w36ubjncms5wzbhzr2gq576sq4xut5zwq
582 sugadude.i2p yzjn76iyqard64wgggfrnywkxi7tbfkw7mjhpviqz3p2dguey4yq
583 suicidal.i2p yfamynllow5xiqbbca7eh5xn733wtnuti5bi4ovc7dwycntqmiuq
584 sungo.i2p h67s3jw56rwfyoxqxj3fngrluybsgxc2meendngkehzqowxnpj3q
585 surrender.adab.i2p jgz7xglgfgnjfklrytyn427np2ubipztlm5bxrtbiucayglukrta
586 susi.i2p qc6g2qfi2ccw7vjwpst6rwuofgzbeoewsb2usv7rubutf4gzqveq
587 syncline.i2p 5kcqmhislu3lmr7llgmdl72yu3efhyriljdc6wp774ftpwlcs5ra
588 syndie-project.i2p xa63tpfoaqt3zru2ehxjjfbpadwj4ha6qsdvtcqtyr3b7hmt4iaq
589 syndie.echelon.i2p vwrl2qmcif722fdkn3ldxcgz76df5cq4qypbndzthxwgmykyewta
590 syndie.i2p 7lm3yzpuejhpl4tt4l7o4ndqlu7hgijohofh7oaydx7q7kelenbq
591 syndiemedia.i2p 4lrbbblclodhobn3jadt5bf2yab2pxzoz4ey4a2cvrl44tdv3jma
592 tabak.i2p y5o2vwb6kart7ivpnbpk4yte3i7kf2dsx7fy3i6w7htqtxhmbzia
593 tahoeserve.i2p yhs7tsjeznxdenmdho5gjmk755wtredfzipb5t272oi5otipfkoa
594 tc.i2p qkv2yk6rof3rh7n3eelg5niujae6cmdzcpqbv3wsttedxtqqqj7a
595 telegram.i2p i6jow7hymogz2s42xq62gqgej2zdm4xtnmpc6vjcwktdxpdoupja
596 templar.i2p zxeralsujowfpyi2ynyjooxy222pzz4apc2qcwrfx5ikhf64et7q
597 terror.i2p wsijm6aqz4qtuyn2jedpx6imar5uq4yuhjdgtfqumxbqww47vbnq
598 thebland.i2p oiviukgwapzxsrwxsoucpqa47s3wt6nfuhfjxvgbqsyrze2mwrda
599 thebreton.i2p woutbsflcrlgppx4y7ag2kawlqijyenvlwrhbbvbkoaksuhf2hkq
600 thedarkside.i2p fxt3z33nzkrg5kjrk7bp5vvmu7w2vsn4i6jo6cily3hsm6u664ca
601 theland.i2p 26ppxbseda6xmim37ksarccdb4q5ctdagfmt2u5aba6xjh452zsa
602 thetower.i2p 3xqa5nype64y6fxgqjq6r5w2qpiqftoraj2niebumseat4cj654a
603 thornworld.i2p vinz4ygmodxarocntyjlfwk2wjpvzndlf4hxss2w2t3fk52oplva
604 tino.i2p e4bfnhvaofu4s67ztcgiskos2mqyhskid64dvlqexxs2c2bno3iq
605 tinyurl.i2p mc4oxv3v7dnyzpvok7v5qxkwtgjprgyz6w7x3tag4fipsen6rdwa
606 tome.i2p qktkxwawgixrm5lzofnj5n24zspbnzxy4pvjm7uvaxvmgwrsuvgq
607 tor-gw.meeh.i2p ounrqi7cfemnt66yhnhigt2u27fkctbvct527cp2522ozy3btjza
608 tor-www-proxy.i2p xov45rvjks5fe4ofmpblkj23bnwxgslbypbgvchbr7yul2ujej2q
609 torapa.i2p eejqjtpko6mdd4opvntbpsuandstrebxpbymfhix7avp5obrw5ta
610 torrentfinder.i2p mpc73okj7wq2xl6clofl64cn6v7vrvhpmi6d524nrsvbeuvjxalq
611 torrfreedom.i2p nfrjvknwcw47itotkzmk6mdlxmxfxsxhbhlr5ozhlsuavcogv4hq
612 trac.i2p kyioa2lgdi2za2fwfwajnb3ljz6zwlx7yzjdpnxnch5uw3iqn6ca
613 trac.i2p2.i2p i43xzkihpdq34f2jlmtgiyyay5quafg5rebog7tk7xil2c6kbyoa
614 tracker-fr.i2p qfrvqrfoqkistgzo2oxpfduz4ktkhtqopleozs3emblmm36fepea
615 tracker.awup.i2p dl47cno335ltvqm6noi5zcij5hpvbj7vjkzuofu262efvu6yp6cq
616 tracker.crypthost.i2p ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq
617 tracker.fr.i2p rzwqr7pfibq5wlcq4a7akm6ohfyhz7hchmy4wz5t55lhd7dwao5q
618 tracker.i2p lsjcplya2b4hhmezz2jy5gqh6zlk3nskisjkhhwapy3jjly4ds5q
619 tracker.lodikon.i2p q2a7tqlyddbyhxhtuia4bmtqpohpp266wsnrkm6cgoahdqrjo3ra
620 tracker.mastertracker.i2p tiwurhqvaaguwpz2shdahqmcfze5ejre52ed2rmoadnjkkilskda
621 tracker.postman.i2p jfcylf4j3gfmqogkltwy7v5m47wp4h7ffrnfsva6grfdavdn7ueq
622 tracker.psi.i2p vmow3h54yljn7zvzbqepdddt5fmygijujycod2q6yznpy2rrzuwa
623 tracker.thebland.i2p s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq
624 tracker.welterde.i2p cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa
625 tracker2.postman.i2p ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna
626 traditio.i2p wkpjjloylf6jopu2itgpktr45t2xvpjijxilxd5tq4i7wkqgwhhq
627 trevorreznik.i2p wc2z6o5fxm2saqzpfcawr63lejwccvzkysmgtfudkrigqopzfdma
628 true.i2p pdilhl5vmefyzrrnmak5bnmxqxk2pmw7rpy4f7wbaeppqu2vvugq
629 trwcln.i2p evml6jiiujhulsgxkdu3wcmkwbokxlv4is6w5qj46tp3ajz3hqzq
630 trypanom.i2p tgv5acj4khwvr6t44cmryohybd2e5o2kndysnzae6qwcr4hzda3q
631 ts.i2p nebcjgfx3f7q4wzihqmguwcdeopaf7f6wyk2dojw4bcuku472zxq
632 ttc.i2p wb4tsfyvfv4idgrultsq6o7inza4fxkc7dijsfpncbx7zko4cdlq
633 ttp.i2p uuczclxejmetohwf2vqewovx3qcumdfh5zecjb3xkcdmk6e5j72a
634 tumbach.i2p u6pciacxnpbsq7nwc3tgutywochfd6aysgayijr7jxzoysgxklvq
635 tutorials.i2p zy37tq6ynucp3ufoyeegswqjaeofmj57cpm5ecd7nbanh2h6f2ja
636 ugha.i2p z3f3owc72awbywk4p6qb5l2mxgitvs6ejztggbpn2a3ddmymfjda
637 uk.i2p vydbychnep3mzkzhg43ptewp242issy47whamfbxodc4ma6wc63a
638 underground.i2p dlnuthb6tpw3kchlb7xoztyspy4ehlggjhl44l64vbcrulrfeica
639 underscore.i2p 3gmezyig6gvsjbpkq2kihoskpuqpkfrajmhhm7hpyrjuvtasgepa
640 unqueued.i2p 3gvn4kwd7z74jxc2sn4ucx52dpvpscxbzjluux3ul4t3eu5g64xq
641 up.i2p 25it5olgdo7pht25z6buzd32sw7jvc65oziqeuocfozfhgua655q
642 update.dg.i2p iqj6ysfh3wl26m4buvyna73yhduifv523l7bwuexxak4mgldexja
643 update.killyourtv.i2p gqdfg25jlqtm35qnmt4b7r53d6u2vep4ob23fwd42iyy4j6cvdqq
644 update.postman.i2p u5rbu6yohfafplp6lgbbmmcuip34s7g3zqdd63cp27dl3nbd7gtq
645 utansans.i2p u2oyre7ygqv4qs5xjjijfg3x7ddwtod6nqwgbomuuzljzvnq4rda
646 v2mail.i2p 4gg7fykcqe7oaqt4w5fmlarnia7vtmwkv3h45zzgoj6o6crryg5a
647 vadino.i2p aalttzlt3z25ktokesceweabm5yyhhvml2z3rfotndgpfyh6myra
648 visibility.i2p pwgma3snbsgkddxgb54mrxxkt3l4jzchrtp52vxmw7rbkjygylxq
649 volatile.i2p q6rve733tvhgyys57jfw4fymqf3xsnza6dqailcdjcq7w4fa5m3a
650 vpnbest.i2p ov5f74ndsy5rfkuyps56waf42vxncufqu5rzm3vsnxkdtogccaea
651 vudu.i2p 3zlwci7pvgep2igygzyjej24ue7mjsktlhaff6crpsr75yquak2q
652 w.i2p j2xorlcb3qxubnthzqu7lt4fvxqn63it4ikwmze55yjkzeeampuq
653 wa11ed.city.i2p 7mxwtmala3ycg2sybjwwfil7s6dqck2fbemeutghhwu73rznmqoa
654 wahoo.i2p vqe5vkpe5wbda7lwekcd2jaj44ar3rawgv54u5rcolezbg5f5vwa
655 wallet.gostcoin.i2p reuvum7lgetglafn72chypesvto773oy53zumagrpigkckybrwda
656 wallsgetbombed.i2p tzhea5d65fllm4263wztghgw4ijdgibsca5xsecp6lk4xlsbdeuq
657 web.telegram.i2p re6cgwg2yrkgaixlqvt5ufajbb3w42fsldlq7k5brpvnd5gp6x5a
658 wiht.i2p yojmpj3sh76g3i6ogzgsf7eouipdgdij5o2blcpdgmu5oyjk5xca
659 wiki.fr.i2p lrqa7hw52uxjb5q3pedmjs6hzos5zrod4y6a4e25hu7vcjhohvxq
660 wiki.ilita.i2p r233yskmowqe4od4he4b37wydr5fqzvj3z77v5fdei2etp2kg34a
661 wintermute.i2p 4gvlfrdy2rkmem33c342tjntpvqik65wekcvm4275qbkuwotoila
662 wspucktracker.i2p ubd2txda3kllumx7ftg4unzgqy536cn6dd2ax6mlhodczfas7rgq
663 www.aum.i2p 3xolizygkzkqrldncjqsb734szznw2u36lliceuacqnbs2n65aeq
664 www.baffled.i2p lqrsfslwu4xnubkk2hofhmuvvr4dia2zevxefinbzdsjurvehtqq
665 www.fr.i2p rmkgvlfwo3vkb3xrr6epoypxasdzzuilv3sckcqbo6c4os5jo2ea
666 www.i2p ojxyenivrrqvycgbxbm3phgisu5abspzq4g2us4fjlwz4tx222va
667 www.i2p2.i2p rjxwbsw4zjhv4zsplma6jmf5nr24e4ymvvbycd3swgiinbvg7oga
668 www.imule.i2p 657xcllunctawyjtar5kgh3wpt6z4l7ba6mmam5rf7hev5w2lsvq
669 www.infoserver.i2p fq7xhxkdcauhwn4loufcadiiy24zbei25elnup33a3gfrdzrtlyq
670 www.janonymous.i2p vosqx5qw22hwrzcgsm4ib7hymf5ryovsbtaexqrzmnzshy5bhakq
671 www.mail.i2p nctas6ioo7aaekfstv3o45yh6ywzwa3vznrdae52ouupzke5pyba
672 www.nntp.i2p kly3o7zmetuwyz7xonnhttw4lj2244pkbibjz26uflyfte3b3dka
673 www.postman.i2p rb3srw2gaooyw63q62cp4udrxxa6molr2irbkgrloveylpkkblhq
674 www.syndie.i2p vojgy5ep4wffmtpjmpnbpa4gq64bgn4yicuw6qmhbm6nqa2ysrva
675 www1.squid.i2p vbh3bltd2duwbukafgj6f6vfi6aigwso7snucp5zohnf66a2hkpa
676 xc.i2p mt45a2z3sb2iyy2mwauj4rwa2lwu4peanfy6gx6ybidwnbasusyq
677 xeha.i2p oartgetziabrdemxctowp7bbeggc7ktmj7tr4qgk5y5jcz4prbtq
678 xilog.i2p eoc5i5q52hutnmsmq56edvooulutaxfikddgdz27otmgtsxmiloq
679 xmpp.crypthost.i2p ittkqpjuliwsdewdugkhvgzstejr2jp5tzou7p332lxx4xw7srba
680 xmpp.rpi.i2p 3yv65pfwiwfuv4ciwtx34clqps6o2mc3vtyltcbqdkcki6untbca
681 xn--l2bl5aw.i2p d2epikjh5crt2l5xjmtceqw2ho44hzp6x3u7hgjrd4mi4wywikwa
682 xolotl.i2p rwr6rrlmrotxfkxt22mah42cycliy2g5k7hgxyxkpcyyxkd2bgwq
683 xotc.i2p gqgvzum3xdgtaahkjfw3layb33vjrucmw5btyhrppm463cz3c5oq
684 z-lab.i2p s6g2pz3mrwzsl4ts65ox3scqawfj7mzvd7hn2ekiiycawopkriba
685 zab.i2p n4xen5sohufgjhv327ex4qra77f4tpqohlcyoa3atoboknzqazeq
686 zcash.i2p zcashmliuw3yd2ptfyd5sadatcpyxj4ldiqahtjzg73cgoevxp4q
687 zener.i2p mcbyglflte3dhwhqyafsfpnqtcapqkv2sepqd62wzd7fo2dzz4ca
688 zerobin.i2p 3564erslxzaoucqasxsjerk4jz2xril7j2cbzd4p7flpb4ut67hq
689 zeroman.i2p gq77fmto535koofcd53f6yzcc5y57ccrxg3pb6twhcodc7v5dutq
690 zeronet.i2p fe6pk5sibhkr64veqxkfochdfptehyxrrbs3edwjs5ckjbjn4bna
691 znc.i2p uw2yt6njjl676fupd72hiezwmd4ouuywowrph6fvhkzhlnvp7jwa
692 znc.str4d.i2p ufkajv3stxpxlwgwwb2ae6oixdjircnbwog77qxpxv7nt67rpcxq
693 zzz.i2p ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq

1
android/assets/certificates Symbolic link
View File

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

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

@ -0,0 +1,90 @@
## Configuration file for a typical i2pd user
## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
## for more options you can use in this file.
#logfile = /sdcard/i2pd/i2pd.log
loglevel = none
#tunnelsdir = /sdcard/i2pd/tunnels.d
# host = 1.2.3.4
# port = 4567
ipv4 = true
ipv6 = false
# ntcp = true
# ntcpproxy = http://127.0.0.1:8118
# ssu = true
bandwidth = L
# share = 100
# notransit = true
# floodfill = true
[ntcp2]
enabled = true
[http]
enabled = true
address = 127.0.0.1
port = 7070
# auth = true
# user = i2pd
# pass = changeme
[httpproxy]
enabled = true
address = 127.0.0.1
port = 4444
inbound.length = 1
inbound.quantity = 5
outbound.length = 1
outbound.quantity = 5
signaturetype=7
keys = proxy-keys.dat
# addresshelper = true
# outproxy = http://false.i2p
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc.
[socksproxy]
enabled = true
address = 127.0.0.1
port = 4447
keys = proxy-keys.dat
# outproxy.enabled = false
# outproxy = 127.0.0.1
# outproxyport = 9050
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
[sam]
enabled = false
# address = 127.0.0.1
# port = 7656
[precomputation]
elgamal = true
[upnp]
enabled = true
# name = I2Pd
[reseed]
verify = true
## Path to local reseed data file (.su3) for manual reseeding
# file = /path/to/i2pseeds.su3
## or HTTPS URL to reseed from
# file = https://legit-website.com/i2pseeds.su3
## Path to local ZIP file or HTTPS URL to reseed from
# zipfile = /path/to/netDb.zip
## If you run i2pd behind a proxy server, set proxy server for reseeding here
## Should be http://address:port or socks://address:port
# proxy = http://127.0.0.1:8118
## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default
# threshold = 25
[limits]
transittunnels = 50
[persist]
profiles = false

View File

@ -0,0 +1,3 @@
http://inr.i2p/export/alive-hosts.txt
http://stats.i2p/cgi-bin/newhosts.txt
http://i2p-projekt.i2p/hosts.txt

View File

@ -0,0 +1,33 @@
[IRC-IRC2P]
#type = client
#address = 127.0.0.1
#port = 6668
#destination = irc.postman.i2p
#destinationport = 6667
#keys = irc-keys.dat
#[IRC-ILITA]
#type = client
#address = 127.0.0.1
#port = 6669
#destination = irc.ilita.i2p
#destinationport = 6667
#keys = irc-keys.dat
#[SMTP]
#type = client
#address = 127.0.0.1
#port = 7659
#destination = smtp.postman.i2p
#destinationport = 25
#keys = smtp-keys.dat
#[POP3]
#type = client
#address = 127.0.0.1
#port = 7660
#destination = pop.postman.i2p
#destinationport = 110
#keys = pop3-keys.dat
# see more examples at https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/

1
android/assets/tunnels.d Symbolic link
View File

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

89
android/build.gradle Normal file
View File

@ -0,0 +1,89 @@
buildscript {
repositories {
mavenCentral()
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
}
}
apply plugin: 'com.android.application'
repositories {
jcenter()
maven {
url 'https://maven.google.com'
}
google()
}
dependencies {
implementation 'androidx.core:core:1.0.2'
}
android {
compileSdkVersion 29
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "org.purplei2p.i2pd"
targetSdkVersion 29
minSdkVersion 14
versionCode 2280
versionName "2.28.0"
ndk {
abiFilters 'armeabi-v7a'
abiFilters 'x86'
//abiFilters 'arm64-v8a'
//abiFilters 'x86_64'
}
externalNativeBuild {
ndkBuild {
arguments "-j3"
}
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
jniLibs.srcDirs = ['libs']
assets.srcDirs = ['assets']
}
}
splits {
abi {
// change that to true if you need splitted apk
enable false
reset()
include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
universalApk true
}
}
signingConfigs {
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'
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}

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>

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